@qduc/term2 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +5 -3
- package/dist/agent.js.map +1 -1
- package/dist/app.d.ts +1 -5
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +31 -274
- package/dist/app.js.map +1 -1
- package/dist/app.parseInput.test.js +1 -9
- package/dist/app.parseInput.test.js.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/components/ApprovalPrompt.d.ts +2 -1
- package/dist/components/ApprovalPrompt.d.ts.map +1 -1
- package/dist/components/ApprovalPrompt.js +15 -0
- package/dist/components/ApprovalPrompt.js.map +1 -1
- package/dist/components/BottomArea.d.ts +1 -1
- package/dist/components/BottomArea.d.ts.map +1 -1
- package/dist/components/Input/determine-active-menu.d.ts +23 -0
- package/dist/components/Input/determine-active-menu.d.ts.map +1 -0
- package/dist/components/Input/determine-active-menu.js +57 -0
- package/dist/components/Input/determine-active-menu.js.map +1 -0
- package/dist/components/Input/input-width.d.ts +7 -0
- package/dist/components/Input/input-width.d.ts.map +1 -0
- package/dist/components/Input/input-width.js +20 -0
- package/dist/components/Input/input-width.js.map +1 -0
- package/dist/components/Input/insertions.d.ts +34 -0
- package/dist/components/Input/insertions.d.ts.map +1 -0
- package/dist/components/Input/insertions.js +52 -0
- package/dist/components/Input/insertions.js.map +1 -0
- package/dist/components/Input/popup-props.d.ts +18 -0
- package/dist/components/Input/popup-props.d.ts.map +1 -0
- package/dist/components/Input/popup-props.js +42 -0
- package/dist/components/Input/popup-props.js.map +1 -0
- package/dist/components/Input/triggers.d.ts +9 -0
- package/dist/components/Input/triggers.d.ts.map +1 -0
- package/dist/components/Input/triggers.js +25 -0
- package/dist/components/Input/triggers.js.map +1 -0
- package/dist/components/InputBox.d.ts +2 -6
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +118 -406
- package/dist/components/InputBox.js.map +1 -1
- package/dist/components/InputBox.menu-logic.test.js +82 -99
- package/dist/components/InputBox.menu-logic.test.js.map +1 -1
- package/dist/components/MarkdownRenderer.d.ts.map +1 -1
- package/dist/components/MarkdownRenderer.js +96 -23
- package/dist/components/MarkdownRenderer.js.map +1 -1
- package/dist/components/MessageList.d.ts +8 -0
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +25 -7
- package/dist/components/MessageList.js.map +1 -1
- package/dist/components/MessageList.test.js +48 -1
- package/dist/components/MessageList.test.js.map +1 -1
- package/dist/components/StatusBar.d.ts +1 -1
- package/dist/components/StatusBar.d.ts.map +1 -1
- package/dist/components/StatusBar.js +49 -38
- package/dist/components/StatusBar.js.map +1 -1
- package/dist/contracts/conversation.d.ts +9 -0
- package/dist/contracts/conversation.d.ts.map +1 -1
- package/dist/hooks/message-id.d.ts +3 -0
- package/dist/hooks/message-id.d.ts.map +1 -0
- package/dist/hooks/message-id.js +17 -0
- package/dist/hooks/message-id.js.map +1 -0
- package/dist/hooks/message-id.test.d.ts +2 -0
- package/dist/hooks/message-id.test.d.ts.map +1 -0
- package/dist/hooks/message-id.test.js +17 -0
- package/dist/hooks/message-id.test.js.map +1 -0
- package/dist/hooks/use-app-commands.d.ts +20 -0
- package/dist/hooks/use-app-commands.d.ts.map +1 -0
- package/dist/hooks/use-app-commands.js +197 -0
- package/dist/hooks/use-app-commands.js.map +1 -0
- package/dist/hooks/use-app-commands.test.d.ts +2 -0
- package/dist/hooks/use-app-commands.test.d.ts.map +1 -0
- package/dist/hooks/use-app-commands.test.js +34 -0
- package/dist/hooks/use-app-commands.test.js.map +1 -0
- package/dist/hooks/use-conversation.d.ts +11 -11
- package/dist/hooks/use-conversation.d.ts.map +1 -1
- package/dist/hooks/use-conversation.js +13 -10
- package/dist/hooks/use-conversation.js.map +1 -1
- package/dist/hooks/use-escape-key.d.ts +24 -0
- package/dist/hooks/use-escape-key.d.ts.map +1 -0
- package/dist/hooks/use-escape-key.js +60 -0
- package/dist/hooks/use-escape-key.js.map +1 -0
- package/dist/hooks/use-escape-key.test.d.ts +2 -0
- package/dist/hooks/use-escape-key.test.d.ts.map +1 -0
- package/dist/hooks/use-escape-key.test.js +49 -0
- package/dist/hooks/use-escape-key.test.js.map +1 -0
- package/dist/hooks/use-mode-handlers.d.ts +35 -0
- package/dist/hooks/use-mode-handlers.d.ts.map +1 -0
- package/dist/hooks/use-mode-handlers.js +79 -0
- package/dist/hooks/use-mode-handlers.js.map +1 -0
- package/dist/hooks/use-model-selection.d.ts +6 -3
- package/dist/hooks/use-model-selection.d.ts.map +1 -1
- package/dist/hooks/use-model-selection.js +19 -16
- package/dist/hooks/use-model-selection.js.map +1 -1
- package/dist/hooks/use-model-selection.test.d.ts.map +1 -1
- package/dist/hooks/use-model-selection.test.js +53 -22
- package/dist/hooks/use-model-selection.test.js.map +1 -1
- package/dist/hooks/use-path-completion.d.ts.map +1 -1
- package/dist/hooks/use-path-completion.js +5 -36
- package/dist/hooks/use-path-completion.js.map +1 -1
- package/dist/hooks/use-runtime-settings.d.ts +12 -0
- package/dist/hooks/use-runtime-settings.d.ts.map +1 -0
- package/dist/hooks/use-runtime-settings.js +68 -0
- package/dist/hooks/use-runtime-settings.js.map +1 -0
- package/dist/hooks/use-selection.d.ts +8 -0
- package/dist/hooks/use-selection.d.ts.map +1 -0
- package/dist/hooks/use-selection.js +31 -0
- package/dist/hooks/use-selection.js.map +1 -0
- package/dist/hooks/use-settings-completion.d.ts.map +1 -1
- package/dist/hooks/use-settings-completion.js +15 -30
- package/dist/hooks/use-settings-completion.js.map +1 -1
- package/dist/hooks/use-settings-completion.test.js +9 -9
- package/dist/hooks/use-settings-completion.test.js.map +1 -1
- package/dist/hooks/use-settings-value-completion.d.ts.map +1 -1
- package/dist/hooks/use-settings-value-completion.js +30 -28
- package/dist/hooks/use-settings-value-completion.js.map +1 -1
- package/dist/hooks/use-settings-value-completion.test.js +13 -0
- package/dist/hooks/use-settings-value-completion.test.js.map +1 -1
- package/dist/hooks/use-shell-mode.d.ts +31 -0
- package/dist/hooks/use-shell-mode.d.ts.map +1 -0
- package/dist/hooks/use-shell-mode.js +85 -0
- package/dist/hooks/use-shell-mode.js.map +1 -0
- package/dist/hooks/use-slash-commands.d.ts +1 -0
- package/dist/hooks/use-slash-commands.d.ts.map +1 -1
- package/dist/hooks/use-slash-commands.js +32 -23
- package/dist/hooks/use-slash-commands.js.map +1 -1
- package/dist/hooks/use-terminal-width.d.ts +7 -0
- package/dist/hooks/use-terminal-width.d.ts.map +1 -0
- package/dist/hooks/use-terminal-width.js +33 -0
- package/dist/hooks/use-terminal-width.js.map +1 -0
- package/dist/hooks/use-trigger-detection.d.ts +40 -0
- package/dist/hooks/use-trigger-detection.d.ts.map +1 -0
- package/dist/hooks/use-trigger-detection.js +45 -0
- package/dist/hooks/use-trigger-detection.js.map +1 -0
- package/dist/lib/editor-impl.js +6 -6
- package/dist/lib/editor-impl.js.map +1 -1
- package/dist/lib/openai-agent-client.d.ts +2 -0
- package/dist/lib/openai-agent-client.d.ts.map +1 -1
- package/dist/lib/openai-agent-client.js +187 -191
- package/dist/lib/openai-agent-client.js.map +1 -1
- package/dist/lib/openai-agent-client.public-methods.test.js +61 -13
- package/dist/lib/openai-agent-client.public-methods.test.js.map +1 -1
- package/dist/lib/retry-executor.d.ts +16 -0
- package/dist/lib/retry-executor.d.ts.map +1 -0
- package/dist/lib/retry-executor.js +71 -0
- package/dist/lib/retry-executor.js.map +1 -0
- package/dist/lib/retry-executor.test.d.ts +2 -0
- package/dist/lib/retry-executor.test.d.ts.map +1 -0
- package/dist/lib/retry-executor.test.js +178 -0
- package/dist/lib/retry-executor.test.js.map +1 -0
- package/dist/lib/tool-selection-policy.d.ts +14 -0
- package/dist/lib/tool-selection-policy.d.ts.map +1 -0
- package/dist/lib/tool-selection-policy.js +17 -0
- package/dist/lib/tool-selection-policy.js.map +1 -0
- package/dist/lib/tool-selection-policy.test.d.ts +2 -0
- package/dist/lib/tool-selection-policy.test.d.ts.map +1 -0
- package/dist/lib/tool-selection-policy.test.js +69 -0
- package/dist/lib/tool-selection-policy.test.js.map +1 -0
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/openai-compatible/model.d.ts.map +1 -1
- package/dist/providers/openai-compatible/model.js +68 -7
- package/dist/providers/openai-compatible/model.js.map +1 -1
- package/dist/providers/openai-compatible/reasoning-content.test.js +107 -6
- package/dist/providers/openai-compatible/reasoning-content.test.js.map +1 -1
- package/dist/providers/openai-compatible.provider.d.ts.map +1 -1
- package/dist/providers/openai-compatible.provider.js.map +1 -1
- package/dist/providers/openai.provider.js +2 -0
- package/dist/providers/openai.provider.js.map +1 -1
- package/dist/providers/openrouter/converters.d.ts.map +1 -1
- package/dist/providers/openrouter/converters.js +8 -6
- package/dist/providers/openrouter/converters.js.map +1 -1
- package/dist/providers/openrouter/converters.test.js +24 -0
- package/dist/providers/openrouter/converters.test.js.map +1 -1
- package/dist/providers/openrouter/model.d.ts.map +1 -1
- package/dist/providers/openrouter/model.js +13 -5
- package/dist/providers/openrouter/model.js.map +1 -1
- package/dist/providers/openrouter/reasoning-content.test.js +48 -2
- package/dist/providers/openrouter/reasoning-content.test.js.map +1 -1
- package/dist/providers/openrouter.provider.createRunner.test.js +17 -9
- package/dist/providers/openrouter.provider.createRunner.test.js.map +1 -1
- package/dist/providers/openrouter.provider.js.map +1 -1
- package/dist/providers/openrouter.test.js +0 -2
- package/dist/providers/openrouter.test.js.map +1 -1
- package/dist/providers/registry.d.ts +17 -8
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +9 -0
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/web-search/exa.provider.d.ts +15 -0
- package/dist/providers/web-search/exa.provider.d.ts.map +1 -0
- package/dist/providers/web-search/exa.provider.js +82 -0
- package/dist/providers/web-search/exa.provider.js.map +1 -0
- package/dist/providers/web-search/exa.provider.test.d.ts +2 -0
- package/dist/providers/web-search/exa.provider.test.d.ts.map +1 -0
- package/dist/providers/web-search/exa.provider.test.js +67 -0
- package/dist/providers/web-search/exa.provider.test.js.map +1 -0
- package/dist/providers/web-search/index.d.ts +1 -0
- package/dist/providers/web-search/index.d.ts.map +1 -1
- package/dist/providers/web-search/index.js +1 -0
- package/dist/providers/web-search/index.js.map +1 -1
- package/dist/scripts/eval-auto-approval/cache.d.ts +9 -0
- package/dist/scripts/eval-auto-approval/cache.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/cache.js +64 -0
- package/dist/scripts/eval-auto-approval/cache.js.map +1 -0
- package/dist/scripts/eval-auto-approval/dataset.d.ts +45 -0
- package/dist/scripts/eval-auto-approval/dataset.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/dataset.js +65 -0
- package/dist/scripts/eval-auto-approval/dataset.js.map +1 -0
- package/dist/scripts/eval-auto-approval/dataset.test.d.ts +2 -0
- package/dist/scripts/eval-auto-approval/dataset.test.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/dataset.test.js +88 -0
- package/dist/scripts/eval-auto-approval/dataset.test.js.map +1 -0
- package/dist/scripts/eval-auto-approval/leaderboard.d.ts +92 -0
- package/dist/scripts/eval-auto-approval/leaderboard.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/leaderboard.js +402 -0
- package/dist/scripts/eval-auto-approval/leaderboard.js.map +1 -0
- package/dist/scripts/eval-auto-approval/leaderboard.test.d.ts +2 -0
- package/dist/scripts/eval-auto-approval/leaderboard.test.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/leaderboard.test.js +689 -0
- package/dist/scripts/eval-auto-approval/leaderboard.test.js.map +1 -0
- package/dist/scripts/eval-auto-approval/metrics.d.ts +34 -0
- package/dist/scripts/eval-auto-approval/metrics.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/metrics.js +74 -0
- package/dist/scripts/eval-auto-approval/metrics.js.map +1 -0
- package/dist/scripts/eval-auto-approval/metrics.test.d.ts +2 -0
- package/dist/scripts/eval-auto-approval/metrics.test.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/metrics.test.js +79 -0
- package/dist/scripts/eval-auto-approval/metrics.test.js.map +1 -0
- package/dist/scripts/eval-auto-approval/report.d.ts +5 -0
- package/dist/scripts/eval-auto-approval/report.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/report.js +51 -0
- package/dist/scripts/eval-auto-approval/report.js.map +1 -0
- package/dist/scripts/eval-auto-approval/report.test.d.ts +2 -0
- package/dist/scripts/eval-auto-approval/report.test.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/report.test.js +23 -0
- package/dist/scripts/eval-auto-approval/report.test.js.map +1 -0
- package/dist/scripts/eval-auto-approval/runner-utils.d.ts +41 -0
- package/dist/scripts/eval-auto-approval/runner-utils.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/runner-utils.js +187 -0
- package/dist/scripts/eval-auto-approval/runner-utils.js.map +1 -0
- package/dist/scripts/eval-auto-approval/runner-utils.test.d.ts +2 -0
- package/dist/scripts/eval-auto-approval/runner-utils.test.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/runner-utils.test.js +135 -0
- package/dist/scripts/eval-auto-approval/runner-utils.test.js.map +1 -0
- package/dist/scripts/eval-auto-approval/runner.d.ts +2 -0
- package/dist/scripts/eval-auto-approval/runner.d.ts.map +1 -0
- package/dist/scripts/eval-auto-approval/runner.js +326 -0
- package/dist/scripts/eval-auto-approval/runner.js.map +1 -0
- package/dist/services/agent-stream.d.ts +11 -0
- package/dist/services/agent-stream.d.ts.map +1 -0
- package/dist/services/agent-stream.js +2 -0
- package/dist/services/agent-stream.js.map +1 -0
- package/dist/services/approval-flow-coordinator.d.ts +43 -0
- package/dist/services/approval-flow-coordinator.d.ts.map +1 -0
- package/dist/services/approval-flow-coordinator.js +120 -0
- package/dist/services/approval-flow-coordinator.js.map +1 -0
- package/dist/services/approval-flow-coordinator.test.d.ts +2 -0
- package/dist/services/approval-flow-coordinator.test.d.ts.map +1 -0
- package/dist/services/approval-flow-coordinator.test.js +168 -0
- package/dist/services/approval-flow-coordinator.test.js.map +1 -0
- package/dist/services/approval-rejection-interceptor.d.ts +16 -0
- package/dist/services/approval-rejection-interceptor.d.ts.map +1 -0
- package/dist/services/approval-rejection-interceptor.js +20 -0
- package/dist/services/approval-rejection-interceptor.js.map +1 -0
- package/dist/services/approval-rejection-interceptor.test.d.ts +2 -0
- package/dist/services/approval-rejection-interceptor.test.d.ts.map +1 -0
- package/dist/services/approval-rejection-interceptor.test.js +60 -0
- package/dist/services/approval-rejection-interceptor.test.js.map +1 -0
- package/dist/services/conversation-events.d.ts +4 -2
- package/dist/services/conversation-events.d.ts.map +1 -1
- package/dist/services/conversation-result-builder.d.ts +34 -34
- package/dist/services/conversation-result-builder.d.ts.map +1 -1
- package/dist/services/conversation-result-builder.js +64 -76
- package/dist/services/conversation-result-builder.js.map +1 -1
- package/dist/services/conversation-result-builder.test.js +145 -65
- package/dist/services/conversation-result-builder.test.js.map +1 -1
- package/dist/services/conversation-retry-policy.d.ts +37 -0
- package/dist/services/conversation-retry-policy.d.ts.map +1 -0
- package/dist/services/conversation-retry-policy.js +51 -0
- package/dist/services/conversation-retry-policy.js.map +1 -0
- package/dist/services/conversation-retry-policy.test.d.ts +2 -0
- package/dist/services/conversation-retry-policy.test.d.ts.map +1 -0
- package/dist/services/conversation-retry-policy.test.js +79 -0
- package/dist/services/conversation-retry-policy.test.js.map +1 -0
- package/dist/services/conversation-service.d.ts +2 -1
- package/dist/services/conversation-service.d.ts.map +1 -1
- package/dist/services/conversation-session.auto-approval.test.d.ts +2 -0
- package/dist/services/conversation-session.auto-approval.test.d.ts.map +1 -0
- package/dist/services/conversation-session.auto-approval.test.js +617 -0
- package/dist/services/conversation-session.auto-approval.test.js.map +1 -0
- package/dist/services/conversation-session.d.ts +6 -3
- package/dist/services/conversation-session.d.ts.map +1 -1
- package/dist/services/conversation-session.js +164 -696
- package/dist/services/conversation-session.js.map +1 -1
- package/dist/services/interruption-info.d.ts +13 -0
- package/dist/services/interruption-info.d.ts.map +1 -0
- package/dist/services/interruption-info.js +89 -0
- package/dist/services/interruption-info.js.map +1 -0
- package/dist/services/interruption-info.test.d.ts +2 -0
- package/dist/services/interruption-info.test.d.ts.map +1 -0
- package/dist/services/interruption-info.test.js +84 -0
- package/dist/services/interruption-info.test.js.map +1 -0
- package/dist/services/logging-contract.d.ts +1 -1
- package/dist/services/logging-service.d.ts +6 -2
- package/dist/services/logging-service.d.ts.map +1 -1
- package/dist/services/logging-service.js +48 -91
- package/dist/services/logging-service.js.map +1 -1
- package/dist/services/settings-env.d.ts.map +1 -1
- package/dist/services/settings-env.js +3 -0
- package/dist/services/settings-env.js.map +1 -1
- package/dist/services/settings-schema.d.ts +34 -0
- package/dist/services/settings-schema.d.ts.map +1 -1
- package/dist/services/settings-schema.js +37 -0
- package/dist/services/settings-schema.js.map +1 -1
- package/dist/services/settings-service.d.ts.map +1 -1
- package/dist/services/settings-service.js +12 -166
- package/dist/services/settings-service.js.map +1 -1
- package/dist/services/settings-sources.d.ts +5 -0
- package/dist/services/settings-sources.d.ts.map +1 -0
- package/dist/services/settings-sources.js +92 -0
- package/dist/services/settings-sources.js.map +1 -0
- package/dist/services/settings-sources.test.d.ts +2 -0
- package/dist/services/settings-sources.test.d.ts.map +1 -0
- package/dist/services/settings-sources.test.js +34 -0
- package/dist/services/settings-sources.test.js.map +1 -0
- package/dist/services/shell-auto-approval-evaluator.d.ts +19 -0
- package/dist/services/shell-auto-approval-evaluator.d.ts.map +1 -0
- package/dist/services/shell-auto-approval-evaluator.js +207 -0
- package/dist/services/shell-auto-approval-evaluator.js.map +1 -0
- package/dist/services/shell-auto-approval-evaluator.test.d.ts +2 -0
- package/dist/services/shell-auto-approval-evaluator.test.d.ts.map +1 -0
- package/dist/services/shell-auto-approval-evaluator.test.js +211 -0
- package/dist/services/shell-auto-approval-evaluator.test.js.map +1 -0
- package/dist/services/shell-auto-approval-resolver.d.ts +24 -0
- package/dist/services/shell-auto-approval-resolver.d.ts.map +1 -0
- package/dist/services/shell-auto-approval-resolver.js +59 -0
- package/dist/services/shell-auto-approval-resolver.js.map +1 -0
- package/dist/services/shell-auto-approval-resolver.test.d.ts +2 -0
- package/dist/services/shell-auto-approval-resolver.test.d.ts.map +1 -0
- package/dist/services/shell-auto-approval-resolver.test.js +110 -0
- package/dist/services/shell-auto-approval-resolver.test.js.map +1 -0
- package/dist/services/ssh-service.test.js +2 -2
- package/dist/services/ssh-service.test.js.map +1 -1
- package/dist/services/stream-event-processor.d.ts +18 -23
- package/dist/services/stream-event-processor.d.ts.map +1 -1
- package/dist/services/stream-event-processor.js +186 -325
- package/dist/services/stream-event-processor.js.map +1 -1
- package/dist/services/stream-event-processor.test.js +143 -90
- package/dist/services/stream-event-processor.test.js.map +1 -1
- package/dist/services/terminal-result-collector.d.ts +12 -0
- package/dist/services/terminal-result-collector.d.ts.map +1 -0
- package/dist/services/terminal-result-collector.js +64 -0
- package/dist/services/terminal-result-collector.js.map +1 -0
- package/dist/services/terminal-result-collector.test.d.ts +2 -0
- package/dist/services/terminal-result-collector.test.d.ts.map +1 -0
- package/dist/services/terminal-result-collector.test.js +93 -0
- package/dist/services/terminal-result-collector.test.js.map +1 -0
- package/dist/tools/apply-patch.js +5 -5
- package/dist/tools/apply-patch.js.map +1 -1
- package/dist/tools/create-file.js +2 -2
- package/dist/tools/create-file.js.map +1 -1
- package/dist/tools/edit-healing.d.ts.map +1 -1
- package/dist/tools/edit-healing.js +4 -1
- package/dist/tools/edit-healing.js.map +1 -1
- package/dist/tools/edit-healing.test.js +22 -0
- package/dist/tools/edit-healing.test.js.map +1 -1
- package/dist/tools/search-replace.d.ts.map +1 -1
- package/dist/tools/search-replace.js +114 -194
- package/dist/tools/search-replace.js.map +1 -1
- package/dist/tools/search-replace.test.js +38 -0
- package/dist/tools/search-replace.test.js.map +1 -1
- package/dist/tools/shell.js +2 -2
- package/dist/tools/shell.js.map +1 -1
- package/dist/tools/shell.test.js +0 -5
- package/dist/tools/shell.test.js.map +1 -1
- package/dist/tools/web-fetch.test.js +3 -3
- package/dist/tools/web-fetch.test.js.map +1 -1
- package/dist/utils/clipboard.d.ts +16 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +55 -0
- package/dist/utils/clipboard.js.map +1 -0
- package/dist/utils/clipboard.test.d.ts +2 -0
- package/dist/utils/clipboard.test.d.ts.map +1 -0
- package/dist/utils/clipboard.test.js +59 -0
- package/dist/utils/clipboard.test.js.map +1 -0
- package/dist/utils/command-safety/constants.d.ts.map +1 -1
- package/dist/utils/command-safety/constants.js +3 -21
- package/dist/utils/command-safety/constants.js.map +1 -1
- package/dist/utils/command-safety/find-helpers.d.ts.map +1 -1
- package/dist/utils/command-safety/find-helpers.js +13 -95
- package/dist/utils/command-safety/find-helpers.js.map +1 -1
- package/dist/utils/command-safety/handlers/sed-handler.d.ts.map +1 -1
- package/dist/utils/command-safety/handlers/sed-handler.js +2 -4
- package/dist/utils/command-safety/handlers/sed-handler.js.map +1 -1
- package/dist/utils/command-safety/index.d.ts +9 -0
- package/dist/utils/command-safety/index.d.ts.map +1 -1
- package/dist/utils/command-safety/index.js +12 -2
- package/dist/utils/command-safety/index.js.map +1 -1
- package/dist/utils/command-safety/path-analysis.d.ts.map +1 -1
- package/dist/utils/command-safety/path-analysis.js +7 -6
- package/dist/utils/command-safety/path-analysis.js.map +1 -1
- package/dist/utils/command-safety.find.test.js +56 -39
- package/dist/utils/command-safety.find.test.js.map +1 -1
- package/dist/utils/command-safety.path.test.js +7 -7
- package/dist/utils/command-safety.path.test.js.map +1 -1
- package/dist/utils/command-safety.red-yellow-policy.test.d.ts +2 -0
- package/dist/utils/command-safety.red-yellow-policy.test.d.ts.map +1 -0
- package/dist/utils/command-safety.red-yellow-policy.test.js +36 -0
- package/dist/utils/command-safety.red-yellow-policy.test.js.map +1 -0
- package/dist/utils/conversation-event-handler.d.ts +4 -3
- package/dist/utils/conversation-event-handler.d.ts.map +1 -1
- package/dist/utils/conversation-event-handler.js +15 -5
- package/dist/utils/conversation-event-handler.js.map +1 -1
- package/dist/utils/conversation-event-handler.test.js +24 -0
- package/dist/utils/conversation-event-handler.test.js.map +1 -1
- package/dist/utils/conversation-utils.d.ts +1 -1
- package/dist/utils/execute-shell.d.ts +10 -0
- package/dist/utils/execute-shell.d.ts.map +1 -1
- package/dist/utils/execute-shell.js +3 -3
- package/dist/utils/execute-shell.js.map +1 -1
- package/dist/utils/execute-shell.test.js +19 -3
- package/dist/utils/execute-shell.test.js.map +1 -1
- package/dist/utils/input-parser.d.ts +13 -0
- package/dist/utils/input-parser.d.ts.map +1 -0
- package/dist/utils/input-parser.js +10 -0
- package/dist/utils/input-parser.js.map +1 -0
- package/dist/utils/model-provider-arg.d.ts +5 -0
- package/dist/utils/model-provider-arg.d.ts.map +1 -0
- package/dist/utils/model-provider-arg.js +15 -0
- package/dist/utils/model-provider-arg.js.map +1 -0
- package/dist/utils/model-provider-arg.test.d.ts +2 -0
- package/dist/utils/model-provider-arg.test.d.ts.map +1 -0
- package/dist/utils/model-provider-arg.test.js +21 -0
- package/dist/utils/model-provider-arg.test.js.map +1 -0
- package/dist/utils/model-settings.d.ts +12 -0
- package/dist/utils/model-settings.d.ts.map +1 -0
- package/dist/utils/model-settings.js +35 -0
- package/dist/utils/model-settings.js.map +1 -0
- package/dist/utils/provider-traffic-extractor.d.ts +1 -0
- package/dist/utils/provider-traffic-extractor.d.ts.map +1 -1
- package/dist/utils/provider-traffic-extractor.js +90 -5
- package/dist/utils/provider-traffic-extractor.js.map +1 -1
- package/dist/utils/settings-command.d.ts.map +1 -1
- package/dist/utils/settings-command.js +10 -8
- package/dist/utils/settings-command.js.map +1 -1
- package/dist/utils/streaming-session-factory.d.ts +1 -1
- package/dist/utils/streaming-session-factory.d.ts.map +1 -1
- package/dist/utils/streaming-session-factory.js +5 -2
- package/dist/utils/streaming-session-factory.js.map +1 -1
- package/dist/utils/streaming-session-factory.test.js +2 -2
- package/dist/utils/streaming-session-factory.test.js.map +1 -1
- package/dist/utils/streaming-updater.d.ts +2 -1
- package/dist/utils/streaming-updater.d.ts.map +1 -1
- package/dist/utils/streaming-updater.js +2 -2
- package/dist/utils/streaming-updater.js.map +1 -1
- package/dist/utils/throttle.d.ts +6 -1
- package/dist/utils/throttle.d.ts.map +1 -1
- package/dist/utils/throttle.js +11 -6
- package/dist/utils/throttle.js.map +1 -1
- package/dist/utils/viewport.d.ts +6 -0
- package/dist/utils/viewport.d.ts.map +1 -0
- package/dist/utils/viewport.js +20 -0
- package/dist/utils/viewport.js.map +1 -0
- package/dist/utils/viewport.test.d.ts +2 -0
- package/dist/utils/viewport.test.d.ts.map +1 -0
- package/dist/utils/viewport.test.js +43 -0
- package/dist/utils/viewport.test.js.map +1 -0
- package/package.json +5 -4
- package/dist/app.model-command-feedback.test.d.ts +0 -2
- package/dist/app.model-command-feedback.test.d.ts.map +0 -1
- package/dist/app.model-command-feedback.test.js +0 -19
- package/dist/app.model-command-feedback.test.js.map +0 -1
- package/dist/components/MentorMode.test.d.ts +0 -2
- package/dist/components/MentorMode.test.d.ts.map +0 -1
- package/dist/components/MentorMode.test.js.map +0 -1
- package/dist/components/ModelSelectionMenu.error-tabs.test.d.ts +0 -2
- package/dist/components/ModelSelectionMenu.error-tabs.test.d.ts.map +0 -1
- package/dist/components/ModelSelectionMenu.error-tabs.test.js +0 -18
- package/dist/components/ModelSelectionMenu.error-tabs.test.js.map +0 -1
- package/dist/components/StatusBar.test.d.ts +0 -2
- package/dist/components/StatusBar.test.d.ts.map +0 -1
- package/dist/components/StatusBar.test.js +0 -19
- package/dist/components/StatusBar.test.js.map +0 -1
- package/dist/components/TextInput.d.ts +0 -42
- package/dist/components/TextInput.d.ts.map +0 -1
- package/dist/components/TextInput.js +0 -397
- package/dist/components/TextInput.js.map +0 -1
- package/dist/components/TextInput.test.d.ts +0 -2
- package/dist/components/TextInput.test.d.ts.map +0 -1
- package/dist/components/TextInput.test.js +0 -75
- package/dist/components/TextInput.test.js.map +0 -1
- package/dist/debug-schema.d.ts +0 -2
- package/dist/debug-schema.d.ts.map +0 -1
- package/dist/debug-schema.js +0 -22
- package/dist/debug-schema.js.map +0 -1
- package/dist/hooks/use-path-completion.test.d.ts +0 -2
- package/dist/hooks/use-path-completion.test.d.ts.map +0 -1
- package/dist/hooks/use-path-completion.test.js +0 -29
- package/dist/hooks/use-path-completion.test.js.map +0 -1
- package/dist/lib/mentor-client.d.ts +0 -41
- package/dist/lib/mentor-client.d.ts.map +0 -1
- package/dist/lib/mentor-client.js +0 -146
- package/dist/lib/mentor-client.js.map +0 -1
- package/dist/lib/mentor-client.test.d.ts +0 -2
- package/dist/lib/mentor-client.test.d.ts.map +0 -1
- package/dist/lib/mentor-client.test.js +0 -440
- package/dist/lib/mentor-client.test.js.map +0 -1
- package/dist/lib/retry-strategy.d.ts +0 -43
- package/dist/lib/retry-strategy.d.ts.map +0 -1
- package/dist/lib/retry-strategy.js +0 -93
- package/dist/lib/retry-strategy.js.map +0 -1
- package/dist/lib/retry-strategy.test.d.ts +0 -2
- package/dist/lib/retry-strategy.test.d.ts.map +0 -1
- package/dist/lib/retry-strategy.test.js +0 -200
- package/dist/lib/retry-strategy.test.js.map +0 -1
- package/dist/lib/shell.d.ts +0 -7
- package/dist/lib/shell.d.ts.map +0 -1
- package/dist/lib/shell.js +0 -56
- package/dist/lib/shell.js.map +0 -1
- package/dist/prompts/default.md.bak +0 -77
- package/dist/prompts/simple-mentor.md +0 -207
- package/dist/providers/github-copilot/converters.d.ts +0 -45
- package/dist/providers/github-copilot/converters.d.ts.map +0 -1
- package/dist/providers/github-copilot/converters.js +0 -118
- package/dist/providers/github-copilot/converters.js.map +0 -1
- package/dist/providers/github-copilot/converters.test.d.ts +0 -2
- package/dist/providers/github-copilot/converters.test.d.ts.map +0 -1
- package/dist/providers/github-copilot/converters.test.js +0 -162
- package/dist/providers/github-copilot/converters.test.js.map +0 -1
- package/dist/providers/github-copilot/github-copilot.provider.d.ts +0 -2
- package/dist/providers/github-copilot/github-copilot.provider.d.ts.map +0 -1
- package/dist/providers/github-copilot/github-copilot.provider.js +0 -75
- package/dist/providers/github-copilot/github-copilot.provider.js.map +0 -1
- package/dist/providers/github-copilot/github-copilot.provider.test.d.ts +0 -2
- package/dist/providers/github-copilot/github-copilot.provider.test.d.ts.map +0 -1
- package/dist/providers/github-copilot/github-copilot.provider.test.js +0 -26
- package/dist/providers/github-copilot/github-copilot.provider.test.js.map +0 -1
- package/dist/providers/github-copilot/index.d.ts +0 -4
- package/dist/providers/github-copilot/index.d.ts.map +0 -1
- package/dist/providers/github-copilot/index.js +0 -4
- package/dist/providers/github-copilot/index.js.map +0 -1
- package/dist/providers/github-copilot/model-direct.d.ts +0 -34
- package/dist/providers/github-copilot/model-direct.d.ts.map +0 -1
- package/dist/providers/github-copilot/model-direct.js +0 -443
- package/dist/providers/github-copilot/model-direct.js.map +0 -1
- package/dist/providers/github-copilot/model.d.ts +0 -24
- package/dist/providers/github-copilot/model.d.ts.map +0 -1
- package/dist/providers/github-copilot/model.delta.test.d.ts +0 -2
- package/dist/providers/github-copilot/model.delta.test.d.ts.map +0 -1
- package/dist/providers/github-copilot/model.delta.test.js +0 -15
- package/dist/providers/github-copilot/model.delta.test.js.map +0 -1
- package/dist/providers/github-copilot/model.js +0 -581
- package/dist/providers/github-copilot/model.js.map +0 -1
- package/dist/providers/github-copilot/provider.d.ts +0 -20
- package/dist/providers/github-copilot/provider.d.ts.map +0 -1
- package/dist/providers/github-copilot/provider.js +0 -30
- package/dist/providers/github-copilot/provider.js.map +0 -1
- package/dist/providers/github-copilot/provider.test.d.ts +0 -2
- package/dist/providers/github-copilot/provider.test.d.ts.map +0 -1
- package/dist/providers/github-copilot/provider.test.js +0 -52
- package/dist/providers/github-copilot/provider.test.js.map +0 -1
- package/dist/providers/github-copilot/utils.d.ts +0 -20
- package/dist/providers/github-copilot/utils.d.ts.map +0 -1
- package/dist/providers/github-copilot/utils.js +0 -142
- package/dist/providers/github-copilot/utils.js.map +0 -1
- package/dist/providers/github-copilot/utils.test.d.ts +0 -2
- package/dist/providers/github-copilot/utils.test.d.ts.map +0 -1
- package/dist/providers/github-copilot/utils.test.js +0 -21
- package/dist/providers/github-copilot/utils.test.js.map +0 -1
- package/dist/providers/openrouter/merge-messages.test.d.ts +0 -2
- package/dist/providers/openrouter/merge-messages.test.d.ts.map +0 -1
- package/dist/providers/openrouter/merge-messages.test.js +0 -83
- package/dist/providers/openrouter/merge-messages.test.js.map +0 -1
- package/dist/providers/openrouter.history.test.d.ts +0 -2
- package/dist/providers/openrouter.history.test.d.ts.map +0 -1
- package/dist/providers/openrouter.history.test.js +0 -533
- package/dist/providers/openrouter.history.test.js.map +0 -1
- package/dist/reproduce_issue.test.d.ts +0 -2
- package/dist/reproduce_issue.test.d.ts.map +0 -1
- package/dist/reproduce_issue.test.js +0 -31
- package/dist/reproduce_issue.test.js.map +0 -1
- package/dist/safety-checker.js +0 -57
- package/dist/services/conversation-service.test.js +0 -190
- package/dist/services/conversation-session.usage.test.d.ts +0 -2
- package/dist/services/conversation-session.usage.test.d.ts.map +0 -1
- package/dist/services/conversation-session.usage.test.js +0 -59
- package/dist/services/conversation-session.usage.test.js.map +0 -1
- package/dist/test-search-tool.d.ts +0 -2
- package/dist/test-search-tool.d.ts.map +0 -1
- package/dist/test-search-tool.js +0 -36
- package/dist/test-search-tool.js.map +0 -1
- package/dist/tools/bash.d.ts +0 -10
- package/dist/tools/bash.d.ts.map +0 -1
- package/dist/tools/bash.js +0 -55
- package/dist/tools/bash.js.map +0 -1
- package/dist/types/messages.d.ts +0 -29
- package/dist/types/messages.d.ts.map +0 -1
- package/dist/types/messages.js +0 -2
- package/dist/types/messages.js.map +0 -1
- package/dist/utils/command-safety.d.ts +0 -21
- package/dist/utils/command-safety.d.ts.map +0 -1
- package/dist/utils/command-safety.js +0 -702
- package/dist/utils/command-safety.js.map +0 -1
- package/dist/utils/extract-command-messages.repro.test.d.ts +0 -2
- package/dist/utils/extract-command-messages.repro.test.d.ts.map +0 -1
- package/dist/utils/extract-command-messages.repro.test.js +0 -31
- package/dist/utils/extract-command-messages.repro.test.js.map +0 -1
- package/dist/utils/extract-command-messages.test.js +0 -57
- package/dist/utils/message-utils.d.ts +0 -17
- package/dist/utils/message-utils.d.ts.map +0 -1
- package/dist/utils/message-utils.js +0 -52
- package/dist/utils/message-utils.js.map +0 -1
- package/dist/utils/message-utils.test.d.ts +0 -2
- package/dist/utils/message-utils.test.d.ts.map +0 -1
- package/dist/utils/message-utils.test.js +0 -48
- package/dist/utils/message-utils.test.js.map +0 -1
|
@@ -1,104 +1,13 @@
|
|
|
1
|
-
import { extractCommandMessages, markToolCallAsApprovalRejection } from '../utils/extract-command-messages.js';
|
|
2
1
|
import { ConversationStore } from './conversation-store.js';
|
|
3
|
-
import {
|
|
4
|
-
import { extractUsage } from '../utils/token-usage.js';
|
|
2
|
+
import { decideRetry, MAX_HALLUCINATION_RETRIES } from './conversation-retry-policy.js';
|
|
5
3
|
import { getProvider } from '../providers/index.js';
|
|
6
|
-
import { extractReasoningDelta, extractTextDelta } from './stream-event-parsing.js';
|
|
7
|
-
import { captureToolCallArguments, emitCommandMessagesFromItems } from './command-message-streaming.js';
|
|
8
4
|
import { ApprovalState } from './approval-state.js';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
15
|
-
const getMethod = (target, key) => {
|
|
16
|
-
const record = asRecord(target);
|
|
17
|
-
const candidate = record?.[key];
|
|
18
|
-
return typeof candidate === 'function' ? candidate : null;
|
|
19
|
-
};
|
|
20
|
-
const getCallIdFromObject = (value) => {
|
|
21
|
-
const record = asRecord(value);
|
|
22
|
-
const callId = getString(record, 'callId') ??
|
|
23
|
-
getString(record, 'call_id') ??
|
|
24
|
-
getString(record, 'tool_call_id') ??
|
|
25
|
-
getString(record, 'toolCallId') ??
|
|
26
|
-
getString(record, 'id');
|
|
27
|
-
if (callId) {
|
|
28
|
-
return callId;
|
|
29
|
-
}
|
|
30
|
-
const rawItem = asRecord(record?.rawItem);
|
|
31
|
-
return (getString(rawItem, 'callId') ??
|
|
32
|
-
getString(rawItem, 'call_id') ??
|
|
33
|
-
getString(rawItem, 'tool_call_id') ??
|
|
34
|
-
getString(rawItem, 'toolCallId') ??
|
|
35
|
-
getString(rawItem, 'id'));
|
|
36
|
-
};
|
|
37
|
-
const getCommandFromArgs = (args) => {
|
|
38
|
-
if (!args) {
|
|
39
|
-
return '';
|
|
40
|
-
}
|
|
41
|
-
if (typeof args === 'string') {
|
|
42
|
-
try {
|
|
43
|
-
const parsed = JSON.parse(args);
|
|
44
|
-
// Handle shell tool's command parameter
|
|
45
|
-
if (parsed?.command) {
|
|
46
|
-
return parsed.command;
|
|
47
|
-
}
|
|
48
|
-
// Fallback for old 'commands' array format
|
|
49
|
-
if (Array.isArray(parsed?.commands)) {
|
|
50
|
-
return parsed.commands.join('\n');
|
|
51
|
-
}
|
|
52
|
-
return JSON.stringify(parsed);
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
return args;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (typeof args === 'object') {
|
|
59
|
-
const argsRecord = asRecord(args);
|
|
60
|
-
// Handle shell tool's command parameter
|
|
61
|
-
const cmdFromObject = argsRecord?.command !== undefined ? String(argsRecord.command) : undefined;
|
|
62
|
-
// Fallback for old 'commands' array format
|
|
63
|
-
if (Array.isArray(argsRecord?.commands)) {
|
|
64
|
-
return argsRecord.commands.join('\n');
|
|
65
|
-
}
|
|
66
|
-
let argsFromObject;
|
|
67
|
-
if (argsRecord?.arguments !== undefined) {
|
|
68
|
-
const rawArguments = argsRecord.arguments;
|
|
69
|
-
if (typeof rawArguments === 'string') {
|
|
70
|
-
try {
|
|
71
|
-
argsFromObject = JSON.stringify(JSON.parse(rawArguments));
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
argsFromObject = String(rawArguments);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
else if (rawArguments !== undefined) {
|
|
78
|
-
argsFromObject = String(rawArguments);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return cmdFromObject ?? argsFromObject ?? JSON.stringify(args);
|
|
82
|
-
}
|
|
83
|
-
return String(args);
|
|
84
|
-
};
|
|
85
|
-
/**
|
|
86
|
-
* Maximum number of retries when the model hallucinates a tool
|
|
87
|
-
*/
|
|
88
|
-
const MAX_HALLUCINATION_RETRIES = 2;
|
|
89
|
-
/**
|
|
90
|
-
* Check if an error is a recoverable model behavior error (hallucination, parsing error, etc.)
|
|
91
|
-
*/
|
|
92
|
-
const isRecoverableModelError = (error) => {
|
|
93
|
-
if (!(error instanceof ModelBehaviorError)) {
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
const message = error.message.toLowerCase();
|
|
97
|
-
return ((message.includes('tool') && message.includes('not found')) || // Hallucination
|
|
98
|
-
message.includes('model did not produce a final response') || // Give up/exhausted
|
|
99
|
-
message.includes('parsing tool arguments') || // Bad JSON
|
|
100
|
-
message.includes('valid json'));
|
|
101
|
-
};
|
|
5
|
+
import { collectTerminalResult } from './terminal-result-collector.js';
|
|
6
|
+
import { getMethod } from './interruption-info.js';
|
|
7
|
+
import { createStreamAccumulator, processStreamEvents } from './stream-event-processor.js';
|
|
8
|
+
import { ShellAutoApprovalResolver } from './shell-auto-approval-resolver.js';
|
|
9
|
+
import { ApprovalFlowCoordinator } from './approval-flow-coordinator.js';
|
|
10
|
+
import { buildConversationResult, toTerminalEvent } from './conversation-result-builder.js';
|
|
102
11
|
const supportsConversationChaining = (providerId) => {
|
|
103
12
|
const providerDef = getProvider(providerId);
|
|
104
13
|
return providerDef?.capabilities?.supportsConversationChaining ?? false;
|
|
@@ -110,15 +19,29 @@ export class ConversationSession {
|
|
|
110
19
|
conversationStore;
|
|
111
20
|
previousResponseId = null;
|
|
112
21
|
approvalState = new ApprovalState();
|
|
113
|
-
textDeltaCount = 0;
|
|
114
|
-
reasoningDeltaCount = 0;
|
|
115
22
|
toolCallArgumentsById = new Map();
|
|
116
23
|
emittedInvalidToolCallPackets = new Set();
|
|
117
|
-
|
|
24
|
+
shellAutoApproval;
|
|
25
|
+
approvalFlow;
|
|
26
|
+
settingsService;
|
|
27
|
+
constructor(id, { agentClient, deps, }) {
|
|
118
28
|
this.id = id;
|
|
119
29
|
this.agentClient = agentClient;
|
|
120
30
|
this.logger = deps.logger;
|
|
31
|
+
this.settingsService = deps.settingsService;
|
|
121
32
|
this.conversationStore = new ConversationStore();
|
|
33
|
+
this.shellAutoApproval = new ShellAutoApprovalResolver({
|
|
34
|
+
conversationStore: this.conversationStore,
|
|
35
|
+
agentClient: this.agentClient,
|
|
36
|
+
logger: this.logger,
|
|
37
|
+
settingsService: this.settingsService,
|
|
38
|
+
});
|
|
39
|
+
this.approvalFlow = new ApprovalFlowCoordinator({
|
|
40
|
+
agentClient: this.agentClient,
|
|
41
|
+
approvalState: this.approvalState,
|
|
42
|
+
logger: this.logger,
|
|
43
|
+
sessionId: this.id,
|
|
44
|
+
});
|
|
122
45
|
}
|
|
123
46
|
reset() {
|
|
124
47
|
this.previousResponseId = null;
|
|
@@ -126,6 +49,7 @@ export class ConversationSession {
|
|
|
126
49
|
this.approvalState.clearPending();
|
|
127
50
|
this.approvalState.consumeAborted();
|
|
128
51
|
this.toolCallArgumentsById.clear();
|
|
52
|
+
this.shellAutoApproval.clearCache();
|
|
129
53
|
const clearConversations = getMethod(this.agentClient, 'clearConversations');
|
|
130
54
|
clearConversations?.call(this.agentClient);
|
|
131
55
|
}
|
|
@@ -156,17 +80,7 @@ export class ConversationSession {
|
|
|
156
80
|
* Abort the current running operation
|
|
157
81
|
*/
|
|
158
82
|
abort() {
|
|
159
|
-
this.
|
|
160
|
-
// Save pending approval context so we can handle it in the next message
|
|
161
|
-
if (this.approvalState.abortPending()) {
|
|
162
|
-
this.logger.debug('Aborted approval - will handle rejection on next message', {
|
|
163
|
-
eventType: 'approval.aborted',
|
|
164
|
-
category: 'approval',
|
|
165
|
-
phase: 'abort',
|
|
166
|
-
sessionId: this.id,
|
|
167
|
-
traceId: this.logger.getCorrelationId(),
|
|
168
|
-
});
|
|
169
|
-
}
|
|
83
|
+
this.approvalFlow.abort();
|
|
170
84
|
}
|
|
171
85
|
/**
|
|
172
86
|
* Phase 4: stream conversation events as an async iterator.
|
|
@@ -176,14 +90,14 @@ export class ConversationSession {
|
|
|
176
90
|
async *run(text, { hallucinationRetryCount = 0, skipUserMessage = false, } = {}) {
|
|
177
91
|
let stream = null;
|
|
178
92
|
try {
|
|
179
|
-
this.logger.
|
|
93
|
+
this.logger.debug('Conversation stream start', {
|
|
180
94
|
eventType: 'stream.started',
|
|
181
95
|
category: 'stream',
|
|
182
96
|
phase: 'request_start',
|
|
183
97
|
sessionId: this.id,
|
|
184
98
|
traceId: this.logger.getCorrelationId(),
|
|
185
99
|
});
|
|
186
|
-
const abortedContext = this.
|
|
100
|
+
const abortedContext = this.approvalFlow.consumeAborted();
|
|
187
101
|
const shouldAddUserMessage = !skipUserMessage && !abortedContext;
|
|
188
102
|
// Maintain canonical local history regardless of provider.
|
|
189
103
|
if (shouldAddUserMessage) {
|
|
@@ -195,56 +109,39 @@ export class ConversationSession {
|
|
|
195
109
|
this.logger.debug('Resolving aborted approval with fake execution', {
|
|
196
110
|
message: text,
|
|
197
111
|
});
|
|
198
|
-
const { state, interruption, emittedCommandIds, toolCallArgumentsById } = abortedContext;
|
|
199
|
-
const interruptionRecord = asRecord(interruption);
|
|
200
112
|
// Restore cached tool-call arguments captured before abort so continuation can attach them
|
|
201
113
|
this.toolCallArgumentsById.clear();
|
|
202
|
-
if (toolCallArgumentsById?.size) {
|
|
203
|
-
for (const [key, value] of toolCallArgumentsById.entries()) {
|
|
114
|
+
if (abortedContext.toolCallArgumentsById?.size) {
|
|
115
|
+
for (const [key, value] of abortedContext.toolCallArgumentsById.entries()) {
|
|
204
116
|
this.toolCallArgumentsById.set(key, value);
|
|
205
117
|
}
|
|
206
118
|
}
|
|
207
|
-
|
|
208
|
-
const toolName = getString(interruptionRecord, 'name') ?? 'unknown';
|
|
209
|
-
const expectedCallId = getCallIdFromObject(interruption);
|
|
210
|
-
const rejectionMessage = `Tool execution was not approved. User provided new input instead: ${text}`;
|
|
211
|
-
const removeInterceptor = this.agentClient.addToolInterceptor(async (name, _params, toolCallId) => {
|
|
212
|
-
// Match both tool name and call ID for stricter matching
|
|
213
|
-
if (name === toolName && (!expectedCallId || toolCallId === expectedCallId)) {
|
|
214
|
-
markToolCallAsApprovalRejection(toolCallId ?? expectedCallId);
|
|
215
|
-
return rejectionMessage;
|
|
216
|
-
}
|
|
217
|
-
return null;
|
|
218
|
-
});
|
|
219
|
-
const approve = getMethod(state, 'approve');
|
|
220
|
-
approve?.call(state, interruption);
|
|
119
|
+
const { removeInterceptor } = this.approvalFlow.prepareAbortResolution(abortedContext, text);
|
|
221
120
|
try {
|
|
222
|
-
const continuedStream = (await this.agentClient.continueRunStream(state, {
|
|
121
|
+
const continuedStream = (await this.agentClient.continueRunStream(abortedContext.state, {
|
|
223
122
|
previousResponseId: this.previousResponseId,
|
|
224
123
|
}));
|
|
225
|
-
const acc =
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
};
|
|
231
|
-
yield* this.#streamEvents(continuedStream, acc, {
|
|
124
|
+
const acc = createStreamAccumulator();
|
|
125
|
+
acc.emittedCommandIds = new Set(abortedContext.emittedCommandIds);
|
|
126
|
+
yield* processStreamEvents(continuedStream, acc, {
|
|
127
|
+
toolCallArgumentsById: this.toolCallArgumentsById,
|
|
128
|
+
emittedInvalidToolCallPackets: this.emittedInvalidToolCallPackets,
|
|
232
129
|
preserveExistingToolArgs: true,
|
|
233
|
-
});
|
|
130
|
+
}, { logger: this.logger, sessionId: this.id });
|
|
234
131
|
this.previousResponseId = continuedStream.lastResponseId ?? null;
|
|
235
132
|
this.conversationStore.updateFromResult(continuedStream);
|
|
236
133
|
// Check if another interruption occurred
|
|
237
134
|
if (continuedStream.interruptions && continuedStream.interruptions.length > 0) {
|
|
238
135
|
this.logger.warn('Another interruption occurred after fake execution - handling as approval');
|
|
239
136
|
// Let the normal flow handle this
|
|
240
|
-
const
|
|
241
|
-
yield
|
|
137
|
+
const resolvedResult = yield* this.#buildAndResolve(continuedStream, acc.finalOutput, acc.reasoningOutput, acc.emittedCommandIds, acc.latestUsage);
|
|
138
|
+
yield toTerminalEvent(resolvedResult);
|
|
242
139
|
return;
|
|
243
140
|
}
|
|
244
141
|
// Successfully resolved - agent should now have processed the fake rejection
|
|
245
142
|
this.logger.debug('Fake execution completed, agent received rejection message');
|
|
246
|
-
const
|
|
247
|
-
yield
|
|
143
|
+
const resolvedResult = yield* this.#buildAndResolve(continuedStream, acc.finalOutput, acc.reasoningOutput, acc.emittedCommandIds, acc.latestUsage);
|
|
144
|
+
yield toTerminalEvent(resolvedResult);
|
|
248
145
|
return;
|
|
249
146
|
}
|
|
250
147
|
catch (error) {
|
|
@@ -265,83 +162,57 @@ export class ConversationSession {
|
|
|
265
162
|
stream = (await this.agentClient.startStream(supportsChaining ? text : this.conversationStore.getHistory(), {
|
|
266
163
|
previousResponseId: this.previousResponseId,
|
|
267
164
|
}));
|
|
268
|
-
const acc =
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
latestUsage: undefined,
|
|
273
|
-
};
|
|
274
|
-
yield* this.#streamEvents(stream, acc, {
|
|
165
|
+
const acc = createStreamAccumulator();
|
|
166
|
+
yield* processStreamEvents(stream, acc, {
|
|
167
|
+
toolCallArgumentsById: this.toolCallArgumentsById,
|
|
168
|
+
emittedInvalidToolCallPackets: this.emittedInvalidToolCallPackets,
|
|
275
169
|
preserveExistingToolArgs: false,
|
|
276
|
-
});
|
|
170
|
+
}, { logger: this.logger, sessionId: this.id });
|
|
277
171
|
this.previousResponseId = stream.lastResponseId ?? null;
|
|
278
172
|
this.conversationStore.updateFromResult(stream);
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
this.logger.info('Tool approval required', {
|
|
173
|
+
const resolvedResult = yield* this.#buildAndResolve(stream, acc.finalOutput || undefined, acc.reasoningOutput || undefined, acc.emittedCommandIds, acc.latestUsage);
|
|
174
|
+
if (resolvedResult.type === 'approval_required') {
|
|
175
|
+
this.logger.debug('Tool approval required', {
|
|
283
176
|
eventType: 'approval.required',
|
|
284
177
|
category: 'approval',
|
|
285
178
|
phase: 'approval',
|
|
286
179
|
sessionId: this.id,
|
|
287
180
|
traceId: this.logger.getCorrelationId(),
|
|
288
|
-
toolName:
|
|
181
|
+
toolName: resolvedResult.approval.toolName,
|
|
289
182
|
});
|
|
290
|
-
yield
|
|
183
|
+
yield toTerminalEvent(resolvedResult);
|
|
291
184
|
return;
|
|
292
185
|
}
|
|
293
|
-
yield
|
|
186
|
+
yield toTerminalEvent(resolvedResult);
|
|
294
187
|
}
|
|
295
188
|
catch (error) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const isHallucination = message.toLowerCase().includes('not found');
|
|
300
|
-
const isParsingError = message.toLowerCase().includes('parsing tool arguments') || message.toLowerCase().includes('valid json');
|
|
301
|
-
const toolName = isHallucination ? message.match(/Tool (\S+) not found/)?.[1] || 'unknown' : 'unknown';
|
|
189
|
+
const streamHistoryLength = Array.isArray(stream?.history) ? stream.history.length : 0;
|
|
190
|
+
const decision = decideRetry(error, hallucinationRetryCount, Boolean(stream), streamHistoryLength);
|
|
191
|
+
if (decision.kind === 'retry') {
|
|
302
192
|
this.logger.warn('Recoverable model error detected, retrying', {
|
|
303
193
|
eventType: 'retry.model_error',
|
|
304
194
|
category: 'retry',
|
|
305
195
|
phase: 'retry',
|
|
306
|
-
toolName,
|
|
307
|
-
retryType:
|
|
308
|
-
retryAttempt:
|
|
309
|
-
attempt:
|
|
196
|
+
toolName: decision.logPayload.toolName,
|
|
197
|
+
retryType: decision.logPayload.retryType,
|
|
198
|
+
retryAttempt: decision.attempt,
|
|
199
|
+
attempt: decision.attempt,
|
|
310
200
|
maxRetries: MAX_HALLUCINATION_RETRIES,
|
|
311
201
|
sessionId: this.id,
|
|
312
202
|
traceId: this.logger.getCorrelationId(),
|
|
313
|
-
errorMessage: message,
|
|
203
|
+
errorMessage: decision.message,
|
|
314
204
|
});
|
|
315
|
-
yield
|
|
316
|
-
|
|
317
|
-
toolName: isHallucination ? toolName : 'model',
|
|
318
|
-
attempt: hallucinationRetryCount + 1,
|
|
319
|
-
maxRetries: MAX_HALLUCINATION_RETRIES,
|
|
320
|
-
errorMessage: message,
|
|
321
|
-
};
|
|
322
|
-
if (stream) {
|
|
323
|
-
// Update conversation store with partial results (including the parse error output if it was yielded)
|
|
205
|
+
yield decision.retryEvent;
|
|
206
|
+
if (decision.hadStream && stream) {
|
|
324
207
|
this.conversationStore.updateFromResult(stream);
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const streamHistory = Array.isArray(stream.history) ? stream.history : [];
|
|
328
|
-
if (streamHistory.length === 0) {
|
|
329
|
-
this.conversationStore.addErrorContext(`[System: Previous attempt failed with error: ${message}. Please retry with corrected output.]`);
|
|
208
|
+
if (decision.shouldInjectErrorContext) {
|
|
209
|
+
this.conversationStore.addErrorContext(decision.errorContextMessage);
|
|
330
210
|
}
|
|
331
|
-
// Retry from current state without re-adding user message
|
|
332
|
-
yield* this.run(text, {
|
|
333
|
-
hallucinationRetryCount: hallucinationRetryCount + 1,
|
|
334
|
-
skipUserMessage: true,
|
|
335
|
-
});
|
|
336
211
|
}
|
|
337
212
|
else {
|
|
338
|
-
// Failed to start stream at all - clean slate retry
|
|
339
213
|
this.conversationStore.removeLastUserMessage();
|
|
340
|
-
yield* this.run(text, {
|
|
341
|
-
hallucinationRetryCount: hallucinationRetryCount + 1,
|
|
342
|
-
// skipUserMessage defaults to false, so user message is re-added
|
|
343
|
-
});
|
|
344
214
|
}
|
|
215
|
+
yield* this.run(text, decision.nextRunOptions);
|
|
345
216
|
return;
|
|
346
217
|
}
|
|
347
218
|
yield {
|
|
@@ -365,58 +236,14 @@ export class ConversationSession {
|
|
|
365
236
|
* Named as a string-literal because `continue` is a keyword.
|
|
366
237
|
*/
|
|
367
238
|
async *['continue']({ answer, rejectionReason, }) {
|
|
368
|
-
const
|
|
369
|
-
if (!
|
|
239
|
+
const plan = this.approvalFlow.prepareContinuation(answer, rejectionReason);
|
|
240
|
+
if (!plan) {
|
|
370
241
|
return;
|
|
371
242
|
}
|
|
372
|
-
const { state,
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
if (answer === 'y') {
|
|
376
|
-
this.logger.info('Tool approval granted', {
|
|
377
|
-
eventType: 'approval.granted',
|
|
378
|
-
category: 'approval',
|
|
379
|
-
phase: 'approval',
|
|
380
|
-
sessionId: this.id,
|
|
381
|
-
traceId: this.logger.getCorrelationId(),
|
|
382
|
-
});
|
|
383
|
-
const approve = getMethod(state, 'approve');
|
|
384
|
-
approve?.call(state, interruption);
|
|
385
|
-
}
|
|
386
|
-
else {
|
|
387
|
-
const toolName = getString(interruptionRecord, 'name') ?? 'unknown';
|
|
388
|
-
const expectedCallId = getCallIdFromObject(interruption);
|
|
389
|
-
const rejectionMessage = rejectionReason
|
|
390
|
-
? `Tool execution was not approved. User's reason: ${rejectionReason}`
|
|
391
|
-
: 'Tool execution was not approved.';
|
|
392
|
-
if (typeof this.agentClient.addToolInterceptor === 'function') {
|
|
393
|
-
const removeInterceptor = this.agentClient.addToolInterceptor(async (name, _params, toolCallId) => {
|
|
394
|
-
if (name === toolName && (!expectedCallId || toolCallId === expectedCallId)) {
|
|
395
|
-
markToolCallAsApprovalRejection(toolCallId ?? expectedCallId);
|
|
396
|
-
return rejectionMessage;
|
|
397
|
-
}
|
|
398
|
-
return null;
|
|
399
|
-
});
|
|
400
|
-
// Approve to continue but interceptor will return rejection message
|
|
401
|
-
const approve = getMethod(state, 'approve');
|
|
402
|
-
approve?.call(state, interruption);
|
|
403
|
-
// Store interceptor cleanup for after stream
|
|
404
|
-
this.approvalState.setPendingRemoveInterceptor(removeInterceptor);
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
// Fallback for clients without tool interceptors
|
|
408
|
-
const reject = getMethod(state, 'reject');
|
|
409
|
-
reject?.call(state, interruption);
|
|
410
|
-
}
|
|
411
|
-
this.logger.info('Tool approval rejected', {
|
|
412
|
-
eventType: 'approval.rejected',
|
|
413
|
-
category: 'approval',
|
|
414
|
-
phase: 'approval',
|
|
415
|
-
sessionId: this.id,
|
|
416
|
-
traceId: this.logger.getCorrelationId(),
|
|
417
|
-
});
|
|
243
|
+
const { pendingApprovalContext: { state, toolCallArgumentsById, emittedCommandIds: previouslyEmittedIds }, toolStartedEvent, removeInterceptor, } = plan;
|
|
244
|
+
if (toolStartedEvent) {
|
|
245
|
+
yield toolStartedEvent;
|
|
418
246
|
}
|
|
419
|
-
removeInterceptor = this.approvalState.getPending()?.removeInterceptor ?? null;
|
|
420
247
|
// Restore cached tool-call arguments so continuation outputs can attach them
|
|
421
248
|
this.toolCallArgumentsById.clear();
|
|
422
249
|
if (toolCallArgumentsById?.size) {
|
|
@@ -428,34 +255,31 @@ export class ConversationSession {
|
|
|
428
255
|
const stream = (await this.agentClient.continueRunStream(state, {
|
|
429
256
|
previousResponseId: this.previousResponseId,
|
|
430
257
|
}));
|
|
431
|
-
const acc =
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
latestUsage: undefined,
|
|
436
|
-
};
|
|
437
|
-
yield* this.#streamEvents(stream, acc, {
|
|
258
|
+
const acc = createStreamAccumulator();
|
|
259
|
+
yield* processStreamEvents(stream, acc, {
|
|
260
|
+
toolCallArgumentsById: this.toolCallArgumentsById,
|
|
261
|
+
emittedInvalidToolCallPackets: this.emittedInvalidToolCallPackets,
|
|
438
262
|
preserveExistingToolArgs: true,
|
|
439
|
-
});
|
|
263
|
+
}, { logger: this.logger, sessionId: this.id });
|
|
440
264
|
this.previousResponseId = stream.lastResponseId ?? null;
|
|
441
265
|
this.conversationStore.updateFromResult(stream);
|
|
442
266
|
// Merge previously emitted command IDs with newly emitted ones
|
|
443
267
|
// This prevents duplicates when result.history contains commands from the initial stream
|
|
444
268
|
const allEmittedIds = new Set([...previouslyEmittedIds, ...acc.emittedCommandIds]);
|
|
445
|
-
const
|
|
446
|
-
if (
|
|
447
|
-
this.logger.
|
|
269
|
+
const resolvedResult = yield* this.#buildAndResolve(stream, acc.finalOutput || undefined, acc.reasoningOutput || undefined, allEmittedIds, acc.latestUsage);
|
|
270
|
+
if (resolvedResult.type === 'approval_required') {
|
|
271
|
+
this.logger.debug('Tool approval required', {
|
|
448
272
|
eventType: 'approval.required',
|
|
449
273
|
category: 'approval',
|
|
450
274
|
phase: 'approval',
|
|
451
275
|
sessionId: this.id,
|
|
452
276
|
traceId: this.logger.getCorrelationId(),
|
|
453
|
-
toolName:
|
|
277
|
+
toolName: resolvedResult.approval.toolName,
|
|
454
278
|
});
|
|
455
|
-
yield
|
|
279
|
+
yield toTerminalEvent(resolvedResult);
|
|
456
280
|
return;
|
|
457
281
|
}
|
|
458
|
-
yield
|
|
282
|
+
yield toTerminalEvent(resolvedResult);
|
|
459
283
|
}
|
|
460
284
|
catch (error) {
|
|
461
285
|
yield {
|
|
@@ -466,468 +290,112 @@ export class ConversationSession {
|
|
|
466
290
|
}
|
|
467
291
|
finally {
|
|
468
292
|
// Clean up interceptor if one was added for rejection reason
|
|
469
|
-
removeInterceptor
|
|
293
|
+
removeInterceptor();
|
|
470
294
|
}
|
|
471
295
|
}
|
|
472
296
|
async sendMessage(text, { onTextChunk, onReasoningChunk, onCommandMessage, onEvent, hallucinationRetryCount = 0, } = {}) {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
case 'reasoning_delta': {
|
|
487
|
-
const full = event.fullText ?? '';
|
|
488
|
-
onReasoningChunk?.(full, event.delta);
|
|
489
|
-
break;
|
|
490
|
-
}
|
|
491
|
-
case 'command_message': {
|
|
492
|
-
onCommandMessage?.(event.message);
|
|
493
|
-
break;
|
|
494
|
-
}
|
|
495
|
-
case 'approval_required': {
|
|
496
|
-
sawTerminalEvent = event;
|
|
497
|
-
// pendingApprovalContext is set inside #buildResult during run()
|
|
498
|
-
const rawInterruption = this.approvalState.getPending()?.interruption;
|
|
499
|
-
return {
|
|
500
|
-
type: 'approval_required',
|
|
501
|
-
approval: {
|
|
502
|
-
agentName: event.approval.agentName,
|
|
503
|
-
toolName: event.approval.toolName,
|
|
504
|
-
argumentsText: event.approval.argumentsText,
|
|
505
|
-
rawInterruption,
|
|
506
|
-
callId: event.approval.callId,
|
|
507
|
-
},
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
case 'final': {
|
|
511
|
-
sawTerminalEvent = event;
|
|
512
|
-
finalText = event.finalText;
|
|
513
|
-
reasoningText = event.reasoningText ?? '';
|
|
514
|
-
usage = event.usage;
|
|
515
|
-
this.logger.debug('sendMessage received final event', {
|
|
516
|
-
sessionId: this.id,
|
|
517
|
-
hasUsage: Boolean(event.usage),
|
|
518
|
-
usage: event.usage,
|
|
519
|
-
});
|
|
520
|
-
if (event.commandMessages?.length) {
|
|
521
|
-
for (const msg of event.commandMessages) {
|
|
522
|
-
commandMessages.push(msg);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
break;
|
|
526
|
-
}
|
|
527
|
-
case 'error': {
|
|
528
|
-
// Preserve legacy behavior (throwing) by throwing after the stream ends.
|
|
529
|
-
break;
|
|
530
|
-
}
|
|
531
|
-
default:
|
|
532
|
-
break;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
// If we didn't see a terminal event, fall back to the legacy default.
|
|
536
|
-
if (!sawTerminalEvent) {
|
|
537
|
-
finalText = finalText || 'Done.';
|
|
538
|
-
}
|
|
539
|
-
const response = {
|
|
540
|
-
type: 'response',
|
|
541
|
-
commandMessages,
|
|
542
|
-
finalText: finalText || 'Done.',
|
|
543
|
-
...(reasoningText ? { reasoningText } : {}),
|
|
544
|
-
...(usage ? { usage } : {}),
|
|
545
|
-
};
|
|
546
|
-
this.logger.debug('sendMessage returning response', {
|
|
547
|
-
sessionId: this.id,
|
|
548
|
-
hasUsage: Boolean(usage),
|
|
549
|
-
usage,
|
|
297
|
+
const result = await collectTerminalResult(this.run(text, { hallucinationRetryCount }), {
|
|
298
|
+
onTextChunk,
|
|
299
|
+
onReasoningChunk,
|
|
300
|
+
onCommandMessage,
|
|
301
|
+
onEvent,
|
|
302
|
+
getRawInterruption: () => this.approvalFlow.getPendingInterruption(),
|
|
303
|
+
onFinalEvent: (event) => {
|
|
304
|
+
this.logger.debug('sendMessage received final event', {
|
|
305
|
+
sessionId: this.id,
|
|
306
|
+
hasUsage: Boolean(event.usage),
|
|
307
|
+
usage: event.usage,
|
|
308
|
+
});
|
|
309
|
+
},
|
|
550
310
|
});
|
|
551
|
-
|
|
311
|
+
if (result.type === 'response') {
|
|
312
|
+
this.logger.debug('sendMessage returning response', {
|
|
313
|
+
sessionId: this.id,
|
|
314
|
+
hasUsage: Boolean(result.usage),
|
|
315
|
+
usage: result.usage,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
return result;
|
|
552
319
|
}
|
|
553
320
|
async handleApprovalDecision(answer, rejectionReason, { onTextChunk, onReasoningChunk, onCommandMessage, onEvent, } = {}) {
|
|
554
|
-
if (!this.
|
|
321
|
+
if (!this.approvalFlow.getPending()) {
|
|
555
322
|
return null;
|
|
556
323
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
onReasoningChunk?.(full, event.delta);
|
|
573
|
-
break;
|
|
574
|
-
}
|
|
575
|
-
case 'command_message': {
|
|
576
|
-
onCommandMessage?.(event.message);
|
|
577
|
-
break;
|
|
578
|
-
}
|
|
579
|
-
case 'approval_required': {
|
|
580
|
-
sawTerminalEvent = event;
|
|
581
|
-
const rawInterruption = this.approvalState.getPending()?.interruption;
|
|
582
|
-
return {
|
|
583
|
-
type: 'approval_required',
|
|
584
|
-
approval: {
|
|
585
|
-
agentName: event.approval.agentName,
|
|
586
|
-
toolName: event.approval.toolName,
|
|
587
|
-
argumentsText: event.approval.argumentsText,
|
|
588
|
-
rawInterruption,
|
|
589
|
-
callId: event.approval.callId,
|
|
590
|
-
},
|
|
591
|
-
};
|
|
592
|
-
}
|
|
593
|
-
case 'final': {
|
|
594
|
-
sawTerminalEvent = event;
|
|
595
|
-
finalText = event.finalText;
|
|
596
|
-
reasoningText = event.reasoningText ?? '';
|
|
597
|
-
usage = event.usage;
|
|
598
|
-
this.logger.debug('handleApprovalDecision received final event', {
|
|
599
|
-
sessionId: this.id,
|
|
600
|
-
hasUsage: Boolean(event.usage),
|
|
601
|
-
usage: event.usage,
|
|
602
|
-
});
|
|
603
|
-
if (event.commandMessages?.length) {
|
|
604
|
-
for (const msg of event.commandMessages) {
|
|
605
|
-
commandMessages.push(msg);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
break;
|
|
609
|
-
}
|
|
610
|
-
case 'error': {
|
|
611
|
-
break;
|
|
612
|
-
}
|
|
613
|
-
default:
|
|
614
|
-
break;
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
if (!sawTerminalEvent) {
|
|
618
|
-
const response = {
|
|
619
|
-
type: 'response',
|
|
620
|
-
commandMessages,
|
|
621
|
-
finalText: finalText || 'Done.',
|
|
622
|
-
...(reasoningText ? { reasoningText } : {}),
|
|
623
|
-
...(usage ? { usage } : {}),
|
|
624
|
-
};
|
|
324
|
+
const result = await collectTerminalResult(this['continue']({ answer, rejectionReason }), {
|
|
325
|
+
onTextChunk,
|
|
326
|
+
onReasoningChunk,
|
|
327
|
+
onCommandMessage,
|
|
328
|
+
onEvent,
|
|
329
|
+
getRawInterruption: () => this.approvalFlow.getPendingInterruption(),
|
|
330
|
+
onFinalEvent: (event) => {
|
|
331
|
+
this.logger.debug('handleApprovalDecision received final event', {
|
|
332
|
+
sessionId: this.id,
|
|
333
|
+
hasUsage: Boolean(event.usage),
|
|
334
|
+
usage: event.usage,
|
|
335
|
+
});
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
if (result.type === 'response') {
|
|
625
339
|
this.logger.debug('handleApprovalDecision returning response', {
|
|
626
340
|
sessionId: this.id,
|
|
627
|
-
hasUsage: Boolean(usage),
|
|
628
|
-
usage,
|
|
341
|
+
hasUsage: Boolean(result.usage),
|
|
342
|
+
usage: result.usage,
|
|
629
343
|
});
|
|
630
|
-
return response;
|
|
631
344
|
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
sessionId: this.id,
|
|
641
|
-
hasUsage: Boolean(usage),
|
|
345
|
+
return result;
|
|
346
|
+
}
|
|
347
|
+
async *#buildAndResolve(result, finalOutputOverride, reasoningOutputOverride, emittedCommandIds, usage) {
|
|
348
|
+
const outcome = await buildConversationResult({
|
|
349
|
+
result,
|
|
350
|
+
finalOutputOverride,
|
|
351
|
+
reasoningOutputOverride,
|
|
352
|
+
emittedCommandIds,
|
|
642
353
|
usage,
|
|
354
|
+
toolCallArgumentsById: this.toolCallArgumentsById,
|
|
355
|
+
}, {
|
|
356
|
+
approvalFlow: this.approvalFlow,
|
|
357
|
+
shellAutoApproval: this.shellAutoApproval,
|
|
358
|
+
logger: this.logger,
|
|
359
|
+
sessionId: this.id,
|
|
643
360
|
});
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
async *#streamEvents(stream, acc, { preserveExistingToolArgs }) {
|
|
647
|
-
const toolCallArgumentsById = this.toolCallArgumentsById;
|
|
648
|
-
if (!preserveExistingToolArgs) {
|
|
649
|
-
toolCallArgumentsById.clear();
|
|
361
|
+
if (outcome.kind !== 'auto_approve') {
|
|
362
|
+
return outcome.result;
|
|
650
363
|
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
const emitReasoning = (delta) => {
|
|
666
|
-
if (!delta || delta.replaceAll('\n', '') === '') {
|
|
667
|
-
return null;
|
|
668
|
-
}
|
|
669
|
-
acc.reasoningOutput += delta;
|
|
670
|
-
this.reasoningDeltaCount++;
|
|
671
|
-
return {
|
|
672
|
-
type: 'reasoning_delta',
|
|
673
|
-
delta,
|
|
674
|
-
fullText: acc.reasoningOutput,
|
|
675
|
-
};
|
|
676
|
-
};
|
|
677
|
-
for await (const rawEvent of stream) {
|
|
678
|
-
const event = asRecord(rawEvent);
|
|
679
|
-
const eventData = asRecord(event?.data);
|
|
680
|
-
const eventType = getString(event, 'type');
|
|
681
|
-
// Extract usage if present in any of the common locations.
|
|
682
|
-
// Check both the top-level event and event.data, since raw_model_stream_event
|
|
683
|
-
// nests response data (including usage) under .data (e.g. data.response.usage).
|
|
684
|
-
const usage = extractUsage(rawEvent) ?? (eventData ? extractUsage(eventData) : undefined);
|
|
685
|
-
if (usage) {
|
|
686
|
-
acc.latestUsage = usage;
|
|
687
|
-
this.logger.debug('Usage extracted from stream event', {
|
|
688
|
-
sessionId: this.id,
|
|
689
|
-
source: 'stream_event',
|
|
690
|
-
eventType: eventType ?? getString(eventData, 'type') ?? 'unknown',
|
|
691
|
-
usage,
|
|
692
|
-
});
|
|
693
|
-
// Emit usage update event for real-time token tracking
|
|
694
|
-
yield {
|
|
695
|
-
type: 'usage_update',
|
|
696
|
-
usage,
|
|
364
|
+
let finalText = '';
|
|
365
|
+
let reasoningText = '';
|
|
366
|
+
let finalUsage;
|
|
367
|
+
const commandMessages = [];
|
|
368
|
+
let approvalRequiredResult;
|
|
369
|
+
for await (const event of this['continue']({ answer: 'y' })) {
|
|
370
|
+
yield event;
|
|
371
|
+
if (event.type === 'approval_required') {
|
|
372
|
+
approvalRequiredResult = {
|
|
373
|
+
type: 'approval_required',
|
|
374
|
+
approval: {
|
|
375
|
+
...event.approval,
|
|
376
|
+
rawInterruption: this.approvalFlow.getPendingInterruption(),
|
|
377
|
+
},
|
|
697
378
|
};
|
|
698
379
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
if (
|
|
704
|
-
|
|
705
|
-
}
|
|
706
|
-
if (eventData) {
|
|
707
|
-
const delta2 = extractTextDelta(eventData);
|
|
708
|
-
if (delta2) {
|
|
709
|
-
const e = emitText(delta2);
|
|
710
|
-
if (e)
|
|
711
|
-
yield e;
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
// Handle reasoning items
|
|
715
|
-
const reasoningDelta = extractReasoningDelta(rawEvent);
|
|
716
|
-
if (reasoningDelta) {
|
|
717
|
-
const e = emitReasoning(reasoningDelta);
|
|
718
|
-
if (e)
|
|
719
|
-
yield e;
|
|
720
|
-
}
|
|
721
|
-
const maybeEmitCommandMessagesFromItems = (items) => emitCommandMessagesFromItems(items, {
|
|
722
|
-
toolCallArgumentsById,
|
|
723
|
-
emittedCommandIds: acc.emittedCommandIds,
|
|
724
|
-
});
|
|
725
|
-
if (eventType === 'run_item_stream_event') {
|
|
726
|
-
const eventItem = event?.item;
|
|
727
|
-
const eventItemRecord = asRecord(eventItem);
|
|
728
|
-
captureToolCallArguments(eventItem, toolCallArgumentsById);
|
|
729
|
-
// Emit tool_started event when a function_call is detected
|
|
730
|
-
const rawItem = asRecord(eventItemRecord?.rawItem) ?? eventItemRecord;
|
|
731
|
-
if (getString(rawItem, 'type') === 'function_call') {
|
|
732
|
-
const callId = getString(rawItem, 'callId') ??
|
|
733
|
-
getString(rawItem, 'call_id') ??
|
|
734
|
-
getString(rawItem, 'tool_call_id') ??
|
|
735
|
-
getString(rawItem, 'toolCallId') ??
|
|
736
|
-
getString(rawItem, 'id');
|
|
737
|
-
if (callId) {
|
|
738
|
-
const toolName = getString(rawItem, 'name') ?? getString(eventItemRecord, 'name');
|
|
739
|
-
const args = rawItem?.arguments ?? rawItem?.args ?? eventItemRecord?.arguments ?? eventItemRecord?.args;
|
|
740
|
-
// Providers sometimes surface arguments as a JSON string.
|
|
741
|
-
// Normalize here so downstream UI (pending/running display)
|
|
742
|
-
// can reliably render parameters.
|
|
743
|
-
const normalizedArgs = (() => {
|
|
744
|
-
if (typeof args !== 'string') {
|
|
745
|
-
return args;
|
|
746
|
-
}
|
|
747
|
-
const trimmed = args.trim();
|
|
748
|
-
if (!trimmed) {
|
|
749
|
-
return args;
|
|
750
|
-
}
|
|
751
|
-
try {
|
|
752
|
-
return JSON.parse(trimmed);
|
|
753
|
-
}
|
|
754
|
-
catch {
|
|
755
|
-
if ((trimmed.startsWith('{') || trimmed.startsWith('[')) &&
|
|
756
|
-
!this.emittedInvalidToolCallPackets.has(String(callId))) {
|
|
757
|
-
this.emittedInvalidToolCallPackets.add(String(callId));
|
|
758
|
-
const diagnostic = createInvalidToolCallDiagnostic({
|
|
759
|
-
toolName: toolName ?? 'unknown',
|
|
760
|
-
toolCallId: String(callId),
|
|
761
|
-
rawPayload: trimmed,
|
|
762
|
-
normalizedToolCall: {
|
|
763
|
-
toolName: toolName ?? 'unknown',
|
|
764
|
-
toolCallId: String(callId),
|
|
765
|
-
arguments: args,
|
|
766
|
-
},
|
|
767
|
-
validationErrors: ['arguments must be valid JSON'],
|
|
768
|
-
traceId: this.logger.getCorrelationId() ?? 'trace-unknown',
|
|
769
|
-
retryContext: {
|
|
770
|
-
sessionId: this.id,
|
|
771
|
-
},
|
|
772
|
-
});
|
|
773
|
-
this.logger.error('Invalid tool call argument payload', {
|
|
774
|
-
...diagnostic,
|
|
775
|
-
sessionId: this.id,
|
|
776
|
-
messageId: String(callId),
|
|
777
|
-
});
|
|
778
|
-
}
|
|
779
|
-
return args;
|
|
780
|
-
}
|
|
781
|
-
})();
|
|
782
|
-
yield {
|
|
783
|
-
type: 'tool_started',
|
|
784
|
-
toolCallId: callId,
|
|
785
|
-
toolName: toolName ?? 'unknown',
|
|
786
|
-
arguments: normalizedArgs,
|
|
787
|
-
};
|
|
788
|
-
this.logger.info('Tool execution started', {
|
|
789
|
-
eventType: 'tool_call.execution_started',
|
|
790
|
-
category: 'tool',
|
|
791
|
-
phase: 'execution',
|
|
792
|
-
sessionId: this.id,
|
|
793
|
-
traceId: this.logger.getCorrelationId(),
|
|
794
|
-
toolName: toolName ?? 'unknown',
|
|
795
|
-
toolCallId: String(callId),
|
|
796
|
-
messageId: String(callId),
|
|
797
|
-
});
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
for (const e of maybeEmitCommandMessagesFromItems([eventItem])) {
|
|
801
|
-
yield e;
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
else if (eventType === 'tool_call_output_item' ||
|
|
805
|
-
getString(asRecord(event?.rawItem), 'type') === 'function_call_output') {
|
|
806
|
-
captureToolCallArguments(rawEvent, toolCallArgumentsById);
|
|
807
|
-
for (const e of maybeEmitCommandMessagesFromItems([rawEvent])) {
|
|
808
|
-
yield e;
|
|
380
|
+
else if (event.type === 'final') {
|
|
381
|
+
finalText = event.finalText;
|
|
382
|
+
reasoningText = event.reasoningText ?? '';
|
|
383
|
+
finalUsage = event.usage;
|
|
384
|
+
if (event.commandMessages) {
|
|
385
|
+
commandMessages.push(...event.commandMessages);
|
|
809
386
|
}
|
|
810
387
|
}
|
|
811
388
|
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
let usageFromRawResponses;
|
|
815
|
-
for (let i = rawResponses.length - 1; i >= 0; i--) {
|
|
816
|
-
const candidate = extractUsage(rawResponses[i]);
|
|
817
|
-
if (candidate) {
|
|
818
|
-
usageFromRawResponses = candidate;
|
|
819
|
-
break;
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
const finalUsage = extractUsage(completedResult) || extractUsage(stream) || usageFromRawResponses;
|
|
823
|
-
if (finalUsage) {
|
|
824
|
-
acc.latestUsage = finalUsage;
|
|
825
|
-
const usageSource = extractUsage(completedResult)
|
|
826
|
-
? 'completed_result'
|
|
827
|
-
: extractUsage(stream)
|
|
828
|
-
? 'stream_object'
|
|
829
|
-
: 'stream_raw_responses';
|
|
830
|
-
this.logger.debug('Usage extracted from stream completion', {
|
|
831
|
-
sessionId: this.id,
|
|
832
|
-
source: 'stream_completed',
|
|
833
|
-
usageSource,
|
|
834
|
-
usage: finalUsage,
|
|
835
|
-
});
|
|
836
|
-
}
|
|
837
|
-
else {
|
|
838
|
-
const completedResultRecord = completedResult && typeof completedResult === 'object' && !Array.isArray(completedResult)
|
|
839
|
-
? completedResult
|
|
840
|
-
: undefined;
|
|
841
|
-
const streamRecord = stream && typeof stream === 'object' && !Array.isArray(stream)
|
|
842
|
-
? stream
|
|
843
|
-
: undefined;
|
|
844
|
-
this.logger.debug('No usage found in stream completion', {
|
|
845
|
-
sessionId: this.id,
|
|
846
|
-
source: 'stream_completed',
|
|
847
|
-
completedResultType: completedResult === null ? 'null' : Array.isArray(completedResult) ? 'array' : typeof completedResult,
|
|
848
|
-
completedResultKeys: completedResultRecord ? Object.keys(completedResultRecord) : [],
|
|
849
|
-
streamKeys: streamRecord ? Object.keys(streamRecord) : [],
|
|
850
|
-
completedResultHasUsagePath: {
|
|
851
|
-
usage: Boolean(completedResultRecord?.usage),
|
|
852
|
-
usageMetadata: Boolean(completedResultRecord?.usageMetadata),
|
|
853
|
-
usage_metadata: Boolean(completedResultRecord?.usage_metadata),
|
|
854
|
-
responseUsage: Boolean(asRecord(completedResultRecord?.response)?.usage),
|
|
855
|
-
},
|
|
856
|
-
});
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
#toTerminalEvent(result) {
|
|
860
|
-
if (result.type === 'approval_required') {
|
|
861
|
-
return {
|
|
862
|
-
type: 'approval_required',
|
|
863
|
-
approval: {
|
|
864
|
-
agentName: result.approval.agentName,
|
|
865
|
-
toolName: result.approval.toolName,
|
|
866
|
-
argumentsText: result.approval.argumentsText,
|
|
867
|
-
...(result.approval.callId ? { callId: result.approval.callId } : {}),
|
|
868
|
-
},
|
|
869
|
-
};
|
|
389
|
+
if (approvalRequiredResult) {
|
|
390
|
+
return approvalRequiredResult;
|
|
870
391
|
}
|
|
871
392
|
return {
|
|
872
|
-
type: 'final',
|
|
873
|
-
finalText: result.finalText,
|
|
874
|
-
...(result.reasoningText ? { reasoningText: result.reasoningText } : {}),
|
|
875
|
-
...(result.commandMessages?.length ? { commandMessages: result.commandMessages } : {}),
|
|
876
|
-
...(result.usage ? { usage: result.usage } : {}),
|
|
877
|
-
};
|
|
878
|
-
}
|
|
879
|
-
#buildResult(result, finalOutputOverride, reasoningOutputOverride, emittedCommandIds, usage) {
|
|
880
|
-
if (result.interruptions && result.interruptions.length > 0) {
|
|
881
|
-
const interruption = result.interruptions[0];
|
|
882
|
-
this.approvalState.setPending({
|
|
883
|
-
state: result.state,
|
|
884
|
-
interruption,
|
|
885
|
-
emittedCommandIds: emittedCommandIds ?? new Set(),
|
|
886
|
-
toolCallArgumentsById: new Map(this.toolCallArgumentsById),
|
|
887
|
-
});
|
|
888
|
-
let argumentsText = '';
|
|
889
|
-
const interruptionRecord = asRecord(interruption);
|
|
890
|
-
const toolName = getString(interruptionRecord, 'name');
|
|
891
|
-
// For shell_call (built-in shell tool), extract commands from action
|
|
892
|
-
// For function tools (bash, shell), extract from arguments
|
|
893
|
-
if (getString(interruptionRecord, 'type') === 'shell_call') {
|
|
894
|
-
const action = asRecord(interruptionRecord?.action);
|
|
895
|
-
const actionCommands = action?.commands;
|
|
896
|
-
if (actionCommands) {
|
|
897
|
-
argumentsText = Array.isArray(actionCommands) ? actionCommands.join('\n') : String(actionCommands);
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
else {
|
|
901
|
-
argumentsText = getCommandFromArgs(interruptionRecord?.arguments);
|
|
902
|
-
}
|
|
903
|
-
const agent = asRecord(interruptionRecord?.agent);
|
|
904
|
-
const callId = getCallIdFromObject(interruption);
|
|
905
|
-
return {
|
|
906
|
-
type: 'approval_required',
|
|
907
|
-
approval: {
|
|
908
|
-
agentName: getString(agent, 'name') ?? 'Agent',
|
|
909
|
-
toolName: toolName ?? 'Unknown Tool',
|
|
910
|
-
argumentsText,
|
|
911
|
-
rawInterruption: interruption,
|
|
912
|
-
...(callId ? { callId: String(callId) } : {}),
|
|
913
|
-
},
|
|
914
|
-
};
|
|
915
|
-
}
|
|
916
|
-
this.approvalState.clearPending();
|
|
917
|
-
const allCommandMessages = extractCommandMessages(result.newItems || result.history || []);
|
|
918
|
-
// Filter out commands that were already emitted in real-time
|
|
919
|
-
const commandMessages = emittedCommandIds
|
|
920
|
-
? allCommandMessages.filter((msg) => !emittedCommandIds.has(msg.id))
|
|
921
|
-
: allCommandMessages;
|
|
922
|
-
const visibleCommandMessages = commandMessages.filter((msg) => !msg.isApprovalRejection);
|
|
923
|
-
const response = {
|
|
924
393
|
type: 'response',
|
|
925
|
-
commandMessages
|
|
926
|
-
finalText:
|
|
927
|
-
reasoningText:
|
|
928
|
-
usage:
|
|
394
|
+
commandMessages,
|
|
395
|
+
finalText: finalText || 'Done.',
|
|
396
|
+
...(reasoningText ? { reasoningText } : {}),
|
|
397
|
+
...(finalUsage ? { usage: finalUsage } : {}),
|
|
929
398
|
};
|
|
930
|
-
return response;
|
|
931
399
|
}
|
|
932
400
|
}
|
|
933
401
|
//# sourceMappingURL=conversation-session.js.map
|