( session: Session, event: AgentEvent, ask: (question: string) => Promise<string>, )
| 32 | } |
| 33 | |
| 34 | async function confirmFromCli( |
| 35 | session: Session, |
| 36 | event: AgentEvent, |
| 37 | ask: (question: string) => Promise<string>, |
| 38 | ): Promise<void> { |
| 39 | const pending = await pendingByToolId(session, event.toolId); |
| 40 | const data = eventData(event); |
| 41 | const toolId = pending?.toolId ?? event.toolId; |
| 42 | |
| 43 | if (!toolId) { |
| 44 | console.warn('[hitl] confirmation_required event has no tool id; skipping'); |
| 45 | return; |
| 46 | } |
| 47 | |
| 48 | const toolName = pending?.toolName ?? event.toolName ?? 'unknown'; |
| 49 | const args = pending?.args ?? data.args ?? {}; |
| 50 | const remainingMs = pending?.remainingMs ?? data.timeout_ms; |
| 51 | |
| 52 | console.log('\n[hitl] Tool requires confirmation'); |
| 53 | console.log(`tool: ${toolName}`); |
| 54 | console.log(`toolId: ${toolId}`); |
| 55 | if (remainingMs !== undefined) console.log(`remainingMs: ${remainingMs}`); |
| 56 | console.log(JSON.stringify(args, null, 2)); |
| 57 | |
| 58 | const autoApprove = process.env.A3S_CODE_HITL_AUTO_APPROVE === '1'; |
| 59 | const answer = autoApprove ? 'y' : await ask('Approve this tool call? [y/N] '); |
| 60 | const approved = answer.trim().toLowerCase().startsWith('y'); |
| 61 | |
| 62 | const completed = await session.confirmToolUse( |
| 63 | toolId, |
| 64 | approved, |
| 65 | approved ? 'Approved from Node HITL example' : 'Rejected from Node HITL example', |
| 66 | ); |
| 67 | console.log(`[hitl] confirmation ${completed ? 'resolved' : 'not found'} (${approved ? 'approved' : 'rejected'})`); |
| 68 | } |
| 69 | |
| 70 | async function main(): Promise<void> { |
| 71 | const configPath = process.env.A3S_CONFIG_FILE ?? process.argv[2]; |
no test coverage detected