Skip to content

Commit 78becb3

Browse files
committed
feat(node-sdk): add HITL confirmation policy support to SessionOptions
Add ConfirmationPolicy configuration to Node.js SDK to enable Human-in-the-Loop confirmation for tool execution. Changes: - Add ConfirmationPolicy type with enabled, defaultTimeoutMs, timeoutAction - Add confirmation_policy field to SessionOptions - Import hitl module types (ConfirmationPolicy, TimeoutAction) - Convert JS ConfirmationPolicy to Rust ConfirmationPolicy in js_session_options_to_rust - Pass confirmation policy to session via with_confirmation_policy() This fixes the "Tool requires confirmation but no HITL confirmation manager is configured" error by allowing users to configure HITL confirmation policy when creating sessions. Usage: ```js agent.session('.', { confirmationPolicy: { enabled: true, defaultTimeoutMs: 30000, timeoutAction: 'reject' } }); ``` When enabled, tools that require confirmation will emit ConfirmationRequired events and wait for user approval before executing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d00ba33 commit 78becb3

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

sdk/node/src/lib.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ use a3s_code_core::config::{
2626
SearchConfig as RustSearchConfig, SearchEngineConfig as RustSearchEngineConfig,
2727
SearchHealthConfig as RustSearchHealthConfig,
2828
};
29+
use a3s_code_core::hitl::{
30+
ConfirmationManager as RustConfirmationManager,
31+
ConfirmationPolicy as RustConfirmationPolicy, TimeoutAction as RustTimeoutAction,
32+
};
2933
use a3s_code_core::hooks::{
3034
Hook as RustHook, HookConfig as RustHookConfig, HookEvent as RustHookEvent,
3135
HookEventType as RustHookEventType, HookHandler as RustHookHandler,
@@ -1258,6 +1262,20 @@ pub struct PermissionPolicy {
12581262
pub enabled: Option<bool>,
12591263
}
12601264

1265+
/// HITL confirmation policy configuration.
1266+
///
1267+
/// Controls the runtime behavior of Human-in-the-Loop confirmation flow.
1268+
#[napi(object)]
1269+
#[derive(Default)]
1270+
pub struct ConfirmationPolicy {
1271+
/// Whether HITL is enabled (default: false, all tools auto-approved).
1272+
pub enabled: Option<bool>,
1273+
/// Default timeout in milliseconds (default: 30000 = 30s).
1274+
pub default_timeout_ms: Option<u32>,
1275+
/// Action to take on timeout: "reject" or "auto_approve" (default: "reject").
1276+
pub timeout_action: Option<String>,
1277+
}
1278+
12611279
#[napi(object)]
12621280
#[derive(Default)]
12631281
pub struct SessionOptions {
@@ -1377,6 +1395,22 @@ pub struct SessionOptions {
13771395
/// agent.session('.', { ahpTransport: new UnixSocketTransport('/tmp/ahp.sock') });
13781396
/// ```
13791397
pub ahp_transport: Option<JsAhpTransport>,
1398+
/// HITL confirmation policy configuration.
1399+
///
1400+
/// Pass a confirmation policy to enable Human-in-the-Loop confirmation for tool execution.
1401+
/// When enabled, tools that require confirmation will emit ConfirmationRequired events
1402+
/// and wait for user approval before executing.
1403+
///
1404+
/// ```js
1405+
/// agent.session('.', {
1406+
/// confirmationPolicy: {
1407+
/// enabled: true,
1408+
/// defaultTimeoutMs: 30000,
1409+
/// timeoutAction: 'reject'
1410+
/// }
1411+
/// });
1412+
/// ```
1413+
pub confirmation_policy: Option<ConfirmationPolicy>,
13801414
}
13811415

13821416
/// A single message in conversation history.
@@ -1672,6 +1706,30 @@ fn js_session_options_to_rust(options: Option<SessionOptions>) -> RustSessionOpt
16721706
opts = opts.with_max_continuation_turns(turns);
16731707
}
16741708

1709+
// HITL confirmation policy configuration
1710+
if let Some(policy) = o.confirmation_policy {
1711+
let mut rust_policy = RustConfirmationPolicy::default();
1712+
1713+
if let Some(enabled) = policy.enabled {
1714+
if enabled {
1715+
rust_policy = RustConfirmationPolicy::enabled();
1716+
}
1717+
}
1718+
1719+
if let Some(timeout_ms) = policy.default_timeout_ms {
1720+
let timeout_action = match policy.timeout_action.as_deref() {
1721+
Some("auto_approve") => RustTimeoutAction::AutoApprove,
1722+
_ => RustTimeoutAction::Reject,
1723+
};
1724+
rust_policy = rust_policy.with_timeout(timeout_ms as u64, timeout_action);
1725+
}
1726+
1727+
// Create confirmation manager with the policy
1728+
// Note: We need access to event_tx from the session, so we'll set this up
1729+
// in the Agent's session creation logic instead
1730+
opts = opts.with_confirmation_policy(rust_policy);
1731+
}
1732+
16751733
// AHP transport configuration
16761734
#[cfg(feature = "ahp")]
16771735
if let Some(ref transport) = o.ahp_transport {

0 commit comments

Comments
 (0)