@vellumai/assistant 0.8.6 → 0.8.7-dev.202606052118.34cd356
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/AGENTS.md +4 -4
- package/Dockerfile +21 -4
- package/bun.lock +13 -4
- package/docker-entrypoint.sh +12 -8
- package/docker-init-apt-root.sh +3 -1
- package/docker-kata-apt-env.sh +3 -1
- package/docker-kata-runtime-family.sh +12 -0
- package/docs/architecture/memory.md +1 -1
- package/docs/plugins.md +110 -83
- package/examples/plugins/echo/README.md +13 -12
- package/examples/plugins/echo/register.ts +0 -54
- package/knip.json +1 -0
- package/node_modules/@vellumai/environments/bun.lock +24 -0
- package/node_modules/@vellumai/environments/package.json +18 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
- package/node_modules/@vellumai/environments/src/index.ts +11 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
- package/node_modules/@vellumai/environments/src/types.ts +70 -0
- package/node_modules/@vellumai/environments/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +3 -4
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +3 -3
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +13 -8
- package/openapi.yaml +6964 -539
- package/package.json +8 -4
- package/scripts/generate-openapi.ts +88 -54
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
- package/src/__tests__/agent-loop-exit-reason.test.ts +188 -45
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +19 -32
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +7 -5
- package/src/__tests__/agent-loop-thinking.test.ts +17 -12
- package/src/__tests__/agent-loop.test.ts +238 -422
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +6 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +22 -40
- package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -3
- package/src/__tests__/anthropic-provider.test.ts +296 -57
- package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
- package/src/__tests__/app-control-flow.test.ts +6 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/approval-cascade.test.ts +4 -11
- package/src/__tests__/approval-routes-http.test.ts +8 -3
- package/src/__tests__/assistant-event-hub.test.ts +25 -0
- package/src/__tests__/assistant-event.test.ts +15 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/assistant-stream-state.test.ts +645 -0
- package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
- package/src/__tests__/avatar-e2e.test.ts +7 -37
- package/src/__tests__/avatar-generator.test.ts +12 -42
- package/src/__tests__/avatar-identity-sync.test.ts +28 -3
- package/src/__tests__/background-shell-bash.test.ts +3 -7
- package/src/__tests__/background-workers-disk-pressure.test.ts +6 -0
- package/src/__tests__/btw-routes.test.ts +69 -15
- package/src/__tests__/build-persisted-content.test.ts +184 -0
- package/src/__tests__/call-pointer-messages.test.ts +5 -3
- package/src/__tests__/call-site-routing-provider.test.ts +22 -40
- package/src/__tests__/catalog-files.test.ts +1 -0
- package/src/__tests__/channel-approval-routes.test.ts +49 -21
- package/src/__tests__/channel-approvals.test.ts +4 -2
- package/src/__tests__/channel-invite-transport.test.ts +1 -5
- package/src/__tests__/channel-readiness-routes.test.ts +0 -4
- package/src/__tests__/channel-readiness-slack-remote.test.ts +2 -7
- package/src/__tests__/channel-retry-sweep.test.ts +71 -79
- package/src/__tests__/clawhub-files.test.ts +1 -0
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +132 -0
- package/src/__tests__/compaction-events.test.ts +5 -17
- package/src/__tests__/compaction-trail-store.test.ts +1 -79
- package/src/__tests__/compaction.benchmark.test.ts +0 -30
- package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
- package/src/__tests__/computer-use-tools.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +28 -0
- package/src/__tests__/context-search-agent-runner.test.ts +6 -3
- package/src/__tests__/context-token-estimator.test.ts +34 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +70 -25
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +9 -7
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -34
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +476 -963
- package/src/__tests__/conversation-agent-loop.test.ts +823 -1321
- package/src/__tests__/conversation-analysis-routes.test.ts +7 -3
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-clear-safety.test.ts +20 -10
- package/src/__tests__/conversation-confirmation-signals.test.ts +15 -45
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-disk-view.test.ts +10 -17
- package/src/__tests__/conversation-fork-crud.test.ts +86 -172
- package/src/__tests__/conversation-fork-route.test.ts +16 -14
- package/src/__tests__/conversation-history-web-search.test.ts +11 -1
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
- package/src/__tests__/conversation-lifecycle.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +3 -2
- package/src/__tests__/conversation-load-history-stripped.test.ts +1 -1
- package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
- package/src/__tests__/conversation-pairing.test.ts +10 -7
- package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +10 -0
- package/src/__tests__/conversation-process-callsite.test.ts +27 -30
- package/src/__tests__/conversation-provider-retry-repair.test.ts +80 -51
- package/src/__tests__/conversation-queue.test.ts +272 -164
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +8 -7
- package/src/__tests__/conversation-runtime-assembly.test.ts +317 -313
- package/src/__tests__/conversation-runtime-workspace.test.ts +114 -36
- package/src/__tests__/conversation-slash-commands.test.ts +8 -42
- package/src/__tests__/conversation-slash-queue.test.ts +42 -31
- package/src/__tests__/conversation-slash-unknown.test.ts +13 -15
- package/src/__tests__/conversation-speed-override.test.ts +8 -22
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +90 -15
- package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
- package/src/__tests__/conversation-surfaces-state-update.test.ts +5 -2
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -15
- package/src/__tests__/conversation-sync-tags.test.ts +27 -15
- package/src/__tests__/conversation-title-service.test.ts +135 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +23 -11
- package/src/__tests__/conversation-unread-route.test.ts +14 -2
- package/src/__tests__/conversation-usage.test.ts +0 -2
- package/src/__tests__/conversation-wipe.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +20 -17
- package/src/__tests__/conversation-workspace-injection.test.ts +114 -23
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +34 -13
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/credential-execution-tools.test.ts +1 -2
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/cross-provider-web-search.test.ts +220 -3
- package/src/__tests__/cu-unified-flow.test.ts +26 -1
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -0
- package/src/__tests__/disk-pressure-guard.test.ts +66 -0
- package/src/__tests__/disk-pressure-routes.test.ts +9 -2
- package/src/__tests__/dm-persistence.test.ts +12 -3
- package/src/__tests__/dynamic-page-surface.test.ts +99 -0
- package/src/__tests__/edit-propagation.test.ts +1 -2
- package/src/__tests__/empty-response-hook.test.ts +304 -0
- package/src/__tests__/feature-flag-test-helpers.ts +2 -2
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/filing-service.test.ts +2 -2
- package/src/__tests__/first-greeting.test.ts +55 -14
- package/src/__tests__/gemini-image-service.test.ts +13 -0
- package/src/__tests__/gemini-inline-media.test.ts +78 -0
- package/src/__tests__/gemini-provider.test.ts +351 -28
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
- package/src/__tests__/guardian-routing-state.test.ts +60 -71
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +10 -8
- package/src/__tests__/heartbeat-disk-pressure.test.ts +2 -0
- package/src/__tests__/heartbeat-service.test.ts +3 -1
- package/src/__tests__/helpers/mock-provider.ts +110 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
- package/src/__tests__/history-repair-hook.test.ts +162 -0
- package/src/__tests__/history-repair-observability.test.ts +1 -1
- package/src/__tests__/history-repair.test.ts +2 -1
- package/src/__tests__/host-app-control-proxy.test.ts +2 -0
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-proxy.test.ts +2 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/host-file-edit-tool.test.ts +4 -2
- package/src/__tests__/host-file-proxy.test.ts +31 -0
- package/src/__tests__/host-file-read-tool.test.ts +4 -2
- package/src/__tests__/host-file-write-tool.test.ts +9 -3
- package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
- package/src/__tests__/host-shell-tool.test.ts +9 -4
- package/src/__tests__/http-user-message-parity.test.ts +2 -2
- package/src/__tests__/identity-intro-cache.test.ts +47 -114
- package/src/__tests__/identity-routes.test.ts +248 -7
- package/src/__tests__/inbound-slack-persistence.test.ts +12 -3
- package/src/__tests__/injector-background-turn.test.ts +3 -9
- package/src/__tests__/injector-chain.test.ts +139 -275
- package/src/__tests__/injector-disk-pressure.test.ts +75 -41
- package/src/__tests__/injector-document-comments.test.ts +3 -3
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
- package/src/__tests__/injector-v3-suppression.test.ts +214 -0
- package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
- package/src/__tests__/list-messages-attachments.test.ts +7 -8
- package/src/__tests__/list-messages-hidden-metadata.test.ts +55 -15
- package/src/__tests__/list-messages-page-latest.test.ts +60 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +56 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
- package/src/__tests__/llm-resolver.test.ts +23 -47
- package/src/__tests__/llm-usage-store.test.ts +268 -1
- package/src/__tests__/log-export-routes.test.ts +59 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
- package/src/__tests__/mcp-auth-routes.test.ts +15 -10
- package/src/__tests__/mcp-health-check.test.ts +18 -13
- package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
- package/src/__tests__/messaging-send-tool.test.ts +8 -4
- package/src/__tests__/migration-export-http.test.ts +12 -12
- package/src/__tests__/migration-import-commit-http.test.ts +8 -8
- package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/native-web-search.test.ts +205 -20
- package/src/__tests__/notification-decision-identity.test.ts +9 -18
- package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
- package/src/__tests__/oauth-commands-routes.test.ts +1 -1
- package/src/__tests__/onboarding-template-contract.test.ts +12 -0
- package/src/__tests__/openai-image-service.test.ts +17 -0
- package/src/__tests__/openai-provider.test.ts +97 -71
- package/src/__tests__/openai-responses-provider.test.ts +21 -77
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -1
- package/src/__tests__/{overflow-reduce-pipeline.test.ts → overflow-reduction-loop.test.ts} +64 -286
- package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
- package/src/__tests__/persist-unsendable-image.test.ts +215 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +3 -1
- package/src/__tests__/pipeline-runner.test.ts +31 -43
- package/src/__tests__/pkb-autoinject.test.ts +2 -5
- package/src/__tests__/plugin-bootstrap.test.ts +62 -51
- package/src/__tests__/plugin-registry.test.ts +0 -27
- package/src/__tests__/plugin-route-contribution.test.ts +6 -16
- package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
- package/src/__tests__/plugin-tool-contribution.test.ts +10 -26
- package/src/__tests__/plugin-types.test.ts +8 -173
- package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
- package/src/__tests__/process-message-background-slack.test.ts +17 -16
- package/src/__tests__/process-message-display-content.test.ts +36 -44
- package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
- package/src/__tests__/provider-error-scenarios.test.ts +7 -6
- package/src/__tests__/provider-platform-proxy-integration.test.ts +3 -8
- package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
- package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
- package/src/__tests__/provider-usage-tracking.test.ts +0 -6
- package/src/__tests__/ratelimit.test.ts +9 -4
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +5 -1
- package/src/__tests__/relay-server.test.ts +20 -13
- package/src/__tests__/resolve-trust-class.test.ts +4 -4
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
- package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
- package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +390 -0
- package/src/__tests__/schedule-routes.test.ts +683 -12
- package/src/__tests__/schedule-store.test.ts +108 -0
- package/src/__tests__/schedule-tools.test.ts +160 -0
- package/src/__tests__/secret-ingress-http.test.ts +2 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
- package/src/__tests__/secret-response-routing.test.ts +13 -11
- package/src/__tests__/send-endpoint-busy.test.ts +6 -2
- package/src/__tests__/server-history-render.test.ts +314 -1
- package/src/__tests__/shell-observability.test.ts +249 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +44 -11
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +10 -10
- package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
- package/src/__tests__/skillssh-files.test.ts +1 -0
- package/src/__tests__/starter-task-flow.test.ts +6 -6
- package/src/__tests__/strip-memory-injections.test.ts +102 -14
- package/src/__tests__/subagent-call-site-routing.test.ts +3 -3
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +1 -3
- package/src/__tests__/subagent-notify-parent.test.ts +1 -3
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +19 -16
- package/src/__tests__/system-prompt.test.ts +74 -0
- package/src/__tests__/task-scheduler.test.ts +162 -1
- package/src/__tests__/terminal-tools.test.ts +9 -25
- package/src/__tests__/thread-backfill.test.ts +4 -9
- package/src/__tests__/title-generate-hook.test.ts +319 -0
- package/src/__tests__/tool-error-hook.test.ts +278 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +481 -16
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
- package/src/__tests__/tool-result-truncation.test.ts +1 -1
- package/src/__tests__/tools-audio-read.test.ts +113 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
- package/src/__tests__/turn-events-store.test.ts +11 -7
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
- package/src/__tests__/ui-work-result-surface.test.ts +159 -0
- package/src/__tests__/usage-routes.test.ts +285 -1
- package/src/__tests__/user-plugin-loader.test.ts +2 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +8 -6
- package/src/__tests__/voice-session-bridge.test.ts +19 -10
- package/src/__tests__/web-search-backend-failure.test.ts +166 -0
- package/src/acp/__tests__/agent-process.test.ts +161 -0
- package/src/acp/__tests__/client-handler.test.ts +40 -0
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +695 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +125 -0
- package/src/acp/auto-install.ts +174 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/feature-gate.test.ts +48 -0
- package/src/acp/feature-gate.ts +34 -0
- package/src/acp/prepare-agent-env.ts +52 -11
- package/src/acp/resolve-agent.test.ts +147 -6
- package/src/acp/resolve-agent.ts +81 -7
- package/src/acp/resume-hint.ts +22 -0
- package/src/acp/session-manager.ts +487 -71
- package/src/agent/compaction-circuit.ts +98 -0
- package/src/agent/loop.ts +651 -450
- package/src/api/README.md +19 -17
- package/src/api/constants/tool-execution.ts +21 -0
- package/src/api/events/assistant-activity-state.ts +75 -0
- package/src/api/events/assistant-outbound-attachment.ts +25 -27
- package/src/api/events/assistant-text-delta.ts +6 -8
- package/src/api/events/assistant-thinking-delta.ts +33 -0
- package/src/api/events/assistant-turn-start.ts +5 -7
- package/src/api/events/avatar-updated.ts +24 -0
- package/src/api/events/compaction-circuit-closed.ts +26 -0
- package/src/api/events/compaction-circuit-open.ts +28 -0
- package/src/api/events/confirmation-request.ts +114 -0
- package/src/api/events/contact-request.ts +33 -0
- package/src/api/events/conversation-error.ts +77 -0
- package/src/api/events/conversation-list-invalidated.ts +38 -0
- package/src/api/events/conversation-title-updated.ts +24 -0
- package/src/api/events/disk-pressure-status-changed.ts +61 -0
- package/src/api/events/document-comment-created.ts +24 -28
- package/src/api/events/document-comment-deleted.ts +6 -8
- package/src/api/events/document-comment-reopened.ts +6 -8
- package/src/api/events/document-comment-resolved.ts +8 -10
- package/src/api/events/document-editor-update.ts +27 -0
- package/src/api/events/error.ts +32 -0
- package/src/api/events/generation-cancelled.ts +4 -6
- package/src/api/events/generation-handoff.ts +13 -15
- package/src/api/events/home-feed-updated.ts +26 -0
- package/src/api/events/identity-changed.ts +32 -0
- package/src/api/events/interaction-resolved.ts +50 -0
- package/src/api/events/message-complete.ts +10 -12
- package/src/api/events/message-dequeued.ts +21 -0
- package/src/api/events/message-queued-deleted.ts +23 -0
- package/src/api/events/message-queued.ts +22 -0
- package/src/api/events/message-request-complete.ts +29 -0
- package/src/api/events/navigate-settings.ts +20 -0
- package/src/api/events/notification-intent.ts +33 -0
- package/src/api/events/open-url.ts +6 -8
- package/src/api/events/question-request.ts +67 -0
- package/src/api/events/relationship-state-updated.ts +4 -6
- package/src/api/events/secret-request.ts +42 -0
- package/src/api/events/subagent-event.ts +79 -0
- package/src/api/events/subagent-spawned.ts +40 -0
- package/src/api/events/subagent-status-changed.ts +65 -0
- package/src/api/events/sync-changed.ts +29 -0
- package/src/api/events/tool-output-chunk.ts +45 -0
- package/src/api/events/tool-result.ts +129 -0
- package/src/api/events/tool-use-preview-start.ts +32 -0
- package/src/api/events/tool-use-start.ts +8 -10
- package/src/api/events/trace-event.ts +69 -0
- package/src/api/events/turn-profile-auto-routed.ts +28 -0
- package/src/api/events/ui-surface-complete.ts +30 -0
- package/src/api/events/ui-surface-dismiss.ts +22 -0
- package/src/api/events/ui-surface-show.ts +67 -0
- package/src/api/events/ui-surface-update.ts +26 -0
- package/src/api/events/usage-update.ts +34 -0
- package/src/api/events/user-message-echo.ts +35 -0
- package/src/api/index.ts +389 -0
- package/src/api/requests/dictation.ts +45 -0
- package/src/api/responses/conversation-message.ts +374 -0
- package/src/api/responses/disk-pressure-status.ts +26 -0
- package/src/api/responses/home.ts +217 -0
- package/src/api/responses/llm-context-response.ts +2 -0
- package/src/api/responses/memory-v3-selection-log.ts +50 -0
- package/src/api/responses/subagent-detail.ts +48 -0
- package/src/approvals/guardian-decision-primitive.ts +7 -15
- package/src/approvals/guardian-request-resolvers.ts +7 -10
- package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
- package/src/avatar/__tests__/avatar-store.test.ts +198 -0
- package/src/avatar/avatar-manifest.ts +195 -0
- package/src/avatar/avatar-store.ts +113 -0
- package/src/avatar/traits-png-sync.ts +8 -2
- package/src/background-wake/next-wake.test.ts +31 -1
- package/src/background-wake/next-wake.ts +5 -1
- package/src/calls/call-conversation-messages.ts +6 -4
- package/src/calls/guardian-action-sweep.ts +6 -4
- package/src/calls/relay-server.ts +12 -8
- package/src/calls/voice-session-bridge.ts +13 -27
- package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
- package/src/cli/commands/__tests__/notifications.test.ts +58 -14
- package/src/cli/commands/avatar.ts +17 -11
- package/src/cli/commands/conversations.ts +15 -1
- package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
- package/src/cli/commands/db/__tests__/status.test.ts +253 -0
- package/src/cli/commands/db/format.ts +48 -0
- package/src/cli/commands/db/index.ts +29 -0
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
- package/src/cli/commands/db/repair-step-integrity.ts +146 -0
- package/src/cli/commands/db/repair-steps.ts +164 -0
- package/src/cli/commands/db/repair.ts +141 -0
- package/src/cli/commands/db/status.ts +366 -0
- package/src/cli/commands/memory-v3.ts +159 -445
- package/src/cli/commands/notifications.ts +112 -60
- package/src/cli/lib/cli-colors.ts +24 -6
- package/src/cli/program.ts +4 -5
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +4 -4
- package/src/config/acp-defaults.test.ts +10 -0
- package/src/config/acp-defaults.ts +6 -0
- package/src/config/assistant-feature-flags.ts +24 -13
- package/src/config/bundled-skills/acp/SKILL.md +64 -30
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -387
- package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
- package/src/config/bundled-skills/app-builder/references/examples/README.md +17 -0
- package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
- package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
- package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
- package/src/config/bundled-skills/messaging/SKILL.md +0 -7
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +2 -7
- package/src/config/feature-flag-cache.ts +3 -3
- package/src/config/feature-flag-registry.json +68 -12
- package/src/config/schemas/__tests__/memory-v2.test.ts +2 -226
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
- package/src/config/schemas/call-site-catalog.ts +8 -15
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +3 -3
- package/src/config/schemas/memory-lifecycle.ts +24 -0
- package/src/config/schemas/memory-v2.ts +8 -253
- package/src/config/schemas/memory-v3.ts +47 -0
- package/src/config/schemas/memory.ts +6 -1
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/timeouts.ts +3 -1
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills.ts +13 -0
- package/src/context/compactor.ts +55 -32
- package/src/context/strip-injections.ts +128 -0
- package/src/context/token-estimator.ts +42 -0
- package/src/context/tool-result-truncation.ts +1 -66
- package/src/context/window-manager.ts +141 -26
- package/src/credential-execution/executable-discovery.ts +16 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +6 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +2 -2
- package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +10 -8
- package/src/daemon/__tests__/web-search-status-text.test.ts +10 -6
- package/src/daemon/approval-generators.ts +4 -4
- package/src/daemon/assistant-attachments.ts +1 -1
- package/src/daemon/config-watcher.ts +7 -1
- package/src/daemon/context-overflow-reducer.ts +0 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +793 -215
- package/src/daemon/conversation-agent-loop.ts +487 -1478
- package/src/daemon/conversation-error.ts +7 -7
- package/src/daemon/conversation-history.ts +27 -10
- package/src/daemon/conversation-launch.ts +4 -8
- package/src/daemon/conversation-lifecycle.ts +13 -42
- package/src/daemon/conversation-messaging.ts +8 -9
- package/src/daemon/conversation-notifiers.ts +7 -5
- package/src/daemon/conversation-process.ts +109 -93
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +209 -382
- package/src/daemon/conversation-slash.ts +6 -25
- package/src/daemon/conversation-store.ts +15 -95
- package/src/daemon/conversation-surfaces.ts +277 -73
- package/src/daemon/conversation-tool-setup.ts +5 -29
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +123 -146
- package/src/daemon/daemon-skill-host.ts +2 -6
- package/src/daemon/disk-pressure-guard.ts +35 -29
- package/src/daemon/external-plugins-bootstrap.ts +53 -32
- package/src/daemon/first-greeting.ts +26 -4
- package/src/daemon/guardian-action-generators.ts +2 -2
- package/src/daemon/handlers/config-a2a.ts +51 -36
- package/src/daemon/handlers/config-slack-channel.ts +20 -14
- package/src/daemon/handlers/config-telegram.ts +16 -2
- package/src/daemon/handlers/conversations.ts +9 -23
- package/src/daemon/handlers/shared.ts +158 -82
- package/src/daemon/handlers/skills.ts +53 -20
- package/src/daemon/host-app-control-proxy.ts +54 -1
- package/src/daemon/host-cu-proxy.ts +46 -22
- package/src/daemon/host-file-proxy.ts +25 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -6
- package/src/daemon/lifecycle.ts +53 -55
- package/src/daemon/message-protocol.ts +2 -3
- package/src/daemon/message-provenance.ts +49 -0
- package/src/daemon/message-types/apps.ts +1 -29
- package/src/daemon/message-types/contacts.ts +3 -20
- package/src/daemon/message-types/conversations.ts +13 -111
- package/src/daemon/message-types/documents.ts +3 -9
- package/src/daemon/message-types/home.ts +4 -17
- package/src/daemon/message-types/integrations.ts +2 -6
- package/src/daemon/message-types/messages.ts +37 -400
- package/src/daemon/message-types/notifications.ts +2 -32
- package/src/daemon/message-types/settings.ts +3 -8
- package/src/daemon/message-types/skills.ts +4 -0
- package/src/daemon/message-types/surfaces.ts +138 -3
- package/src/daemon/message-types/sync.ts +12 -25
- package/src/daemon/message-types/workspace.ts +3 -11
- package/src/daemon/now-scratchpad.ts +21 -0
- package/src/daemon/orphan-reaper.test.ts +210 -0
- package/src/daemon/orphan-reaper.ts +240 -0
- package/src/daemon/overflow-reduction-loop.ts +230 -0
- package/src/daemon/persist-unsendable-image.ts +117 -0
- package/src/daemon/process-message.ts +50 -49
- package/src/daemon/server.ts +14 -0
- package/src/daemon/tool-side-effects.ts +10 -7
- package/src/daemon/trace-emitter.ts +6 -4
- package/src/daemon/trust-context.ts +32 -0
- package/src/daemon/wake-target-adapter.ts +14 -2
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +6 -1
- package/src/heartbeat/heartbeat-run-store.ts +54 -1
- package/src/heartbeat/heartbeat-service.ts +42 -0
- package/src/home/feed-types.ts +36 -221
- package/src/home/home-greeting-cache.ts +24 -1
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/email-ipc.test.ts +0 -9
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/gateway-client.test.ts +2 -2
- package/src/ipc/gateway-client.ts +3 -3
- package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
- package/src/ipc/routes/route-adapter.ts +45 -6
- package/src/ipc/skill-routes/__tests__/memory.test.ts +33 -9
- package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
- package/src/ipc/skill-routes/__tests__/registries.test.ts +28 -18
- package/src/ipc/skill-routes/memory.ts +29 -14
- package/src/ipc/skill-routes/providers.ts +5 -6
- package/src/ipc/skill-routes/registries.ts +13 -61
- package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
- package/src/media/gemini-image-service.ts +15 -0
- package/src/media/openai-image-service.ts +14 -0
- package/src/media/types.ts +34 -0
- package/src/memory/__tests__/conversation-queries.test.ts +192 -8
- package/src/memory/__tests__/db-maintenance.test.ts +128 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +56 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +10 -6
- package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
- package/src/memory/auth-fallback-events-store.ts +94 -0
- package/src/memory/context-search/agent-runner.ts +2 -4
- package/src/memory/conversation-crud.ts +39 -8
- package/src/memory/conversation-queries.ts +78 -22
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/conversation-title-service.ts +65 -41
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +18 -2
- package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
- package/src/memory/graph/consolidation.ts +8 -11
- package/src/memory/graph/conversation-graph-memory.ts +106 -8
- package/src/memory/graph/extraction.ts +6 -9
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.ts +20 -26
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/job-handlers/conversation-starters.ts +45 -34
- package/src/memory/job-handlers/summarization.ts +1 -2
- package/src/memory/jobs-store.ts +36 -1
- package/src/memory/jobs-worker.ts +82 -43
- package/src/memory/llm-request-log-source-clickhouse.ts +5 -31
- package/src/memory/llm-request-log-source-local.ts +0 -11
- package/src/memory/llm-request-log-source.ts +9 -25
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +234 -50
- package/src/memory/memory-marker.ts +17 -0
- package/src/memory/memory-retrospective-job.ts +6 -2
- package/src/memory/memory-v2-activation-log-store.ts +1 -83
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
- package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
- package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
- package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
- package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
- package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
- package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/pkb/autoinject.ts +61 -0
- package/src/memory/pkb/context.ts +50 -0
- package/src/memory/pkb/types.ts +14 -0
- package/src/memory/schedule-attribution-sql.ts +104 -0
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +27 -0
- package/src/memory/usage-grouped-buckets.ts +6 -1
- package/src/memory/v2/__tests__/consolidation-job.test.ts +125 -1
- package/src/memory/v2/__tests__/migration.test.ts +11 -3
- package/src/memory/v2/__tests__/page-index.test.ts +37 -1
- package/src/memory/v2/__tests__/router.test.ts +14 -4
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -5
- package/src/memory/v2/backfill-jobs.ts +6 -0
- package/src/memory/v2/consolidation-job.ts +99 -10
- package/src/memory/v2/migration.ts +5 -3
- package/src/memory/v2/page-index.ts +11 -0
- package/src/memory/v2/router.ts +8 -11
- package/src/memory/v2/sweep-job.ts +8 -11
- package/src/memory/v2/types.ts +1 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
- package/src/messaging/providers/slack/render-transcript.ts +2 -2
- package/src/messaging/style-analyzer.ts +8 -11
- package/src/notifications/conversation-pairing.ts +8 -13
- package/src/notifications/decision-engine.ts +16 -16
- package/src/notifications/home-feed-side-effect.ts +12 -1
- package/src/notifications/preference-extractor.ts +11 -14
- package/src/permissions/prompter.ts +46 -36
- package/src/permissions/question-prompter.test.ts +35 -26
- package/src/permissions/question-prompter.ts +6 -10
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +10 -1
- package/src/plugin-api/types.ts +176 -4
- package/src/plugins/defaults/compaction/compact.ts +59 -0
- package/src/plugins/defaults/compaction/package.json +15 -0
- package/src/plugins/defaults/compaction/register.ts +24 -0
- package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
- package/src/plugins/defaults/empty-response/package.json +15 -0
- package/src/plugins/defaults/empty-response/register.ts +23 -0
- package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/history-repair/package.json +15 -0
- package/src/plugins/defaults/history-repair/register.ts +24 -0
- package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
- package/src/plugins/defaults/index.ts +22 -49
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +95 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
- package/src/plugins/defaults/{injectors.ts → memory-retrieval/injectors.ts} +295 -112
- package/src/plugins/defaults/memory-v3-shadow/__tests__/assign.test.ts +242 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +118 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/core.test.ts +39 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +36 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +37 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/health.test.ts +219 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +330 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +288 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/needle.test.ts +107 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +436 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/provider-blocks.test.ts +13 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/reconcile.test.ts +274 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +61 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/router.test.ts +332 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +179 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selector.test.ts +470 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +432 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/snapshot.test.ts +168 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/tree.test.ts +192 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +54 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +106 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +44 -0
- package/src/plugins/defaults/memory-v3-shadow/assign.ts +268 -0
- package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +124 -0
- package/src/plugins/defaults/memory-v3-shadow/core.ts +26 -0
- package/src/plugins/defaults/memory-v3-shadow/data/README.md +84 -0
- package/src/plugins/defaults/memory-v3-shadow/data/assignments.json +5 -0
- package/src/plugins/defaults/memory-v3-shadow/data/core.json +1 -0
- package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-a/topic-x.md +9 -0
- package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-a/topic-y.md +9 -0
- package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-b/topic-z.md +9 -0
- package/src/plugins/defaults/memory-v3-shadow/health.ts +0 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
- package/src/plugins/defaults/memory-v3-shadow/llm-retry.ts +32 -0
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +314 -0
- package/src/plugins/defaults/memory-v3-shadow/needle.ts +115 -0
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +126 -0
- package/src/plugins/defaults/memory-v3-shadow/package.json +15 -0
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +34 -0
- package/src/plugins/defaults/memory-v3-shadow/provider-blocks.ts +26 -0
- package/src/plugins/defaults/memory-v3-shadow/reconcile.ts +523 -0
- package/src/plugins/defaults/memory-v3-shadow/register.ts +26 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +32 -0
- package/src/plugins/defaults/memory-v3-shadow/router.ts +190 -0
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +84 -0
- package/src/plugins/defaults/memory-v3-shadow/selector.ts +226 -0
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +349 -0
- package/src/plugins/defaults/memory-v3-shadow/snapshot.ts +209 -0
- package/src/plugins/defaults/memory-v3-shadow/tree.ts +174 -0
- package/src/plugins/defaults/memory-v3-shadow/types.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +88 -0
- package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/title-generate/package.json +15 -0
- package/src/plugins/defaults/title-generate/register.ts +35 -0
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
- package/src/plugins/defaults/tool-error/package.json +15 -0
- package/src/plugins/defaults/tool-error/register.ts +23 -0
- package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
- package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +24 -0
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +132 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/pipeline.ts +8 -35
- package/src/plugins/registry.ts +8 -25
- package/src/plugins/types.ts +62 -721
- package/src/plugins/user-loader.ts +4 -3
- package/src/proactive-artifact/aux-message-injector.ts +4 -5
- package/src/proactive-artifact/job.test.ts +28 -21
- package/src/proactive-artifact/job.ts +3 -1
- package/src/prompts/__tests__/system-prompt.test.ts +42 -0
- package/src/prompts/sections.ts +20 -7
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +64 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
- package/src/prompts/templates/BOOTSTRAP.md +7 -3
- package/src/prompts/templates/system-sections.ts +21 -0
- package/src/providers/__tests__/retry-callsite.test.ts +25 -25
- package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
- package/src/providers/anthropic/client.ts +61 -34
- package/src/providers/call-site-routing.ts +1 -9
- package/src/providers/gemini/client.ts +152 -34
- package/src/providers/gemini/inline-media.ts +74 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -2
- package/src/providers/openai/chat-completions-provider.ts +45 -4
- package/src/providers/openai/responses-provider.ts +1 -4
- package/src/providers/openrouter/client.ts +2 -6
- package/src/providers/placeholder-sentinels.ts +35 -0
- package/src/providers/provider-send-message.ts +6 -6
- package/src/providers/ratelimit.ts +1 -9
- package/src/providers/retry.ts +0 -5
- package/src/providers/types.ts +11 -2
- package/src/providers/usage-tracking.ts +1 -9
- package/src/runtime/__tests__/agent-wake.test.ts +141 -32
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -3
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +95 -23
- package/src/runtime/assistant-event-hub.ts +38 -8
- package/src/runtime/assistant-stream-state.ts +368 -0
- package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
- package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
- package/src/runtime/auth/route-policy.ts +42 -1079
- package/src/runtime/background-job-runner.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -1
- package/src/runtime/channel-approvals.ts +4 -15
- package/src/runtime/channel-invite-transport.ts +5 -6
- package/src/runtime/channel-readiness-service.ts +2 -5
- package/src/runtime/channel-retry-sweep.ts +12 -16
- package/src/runtime/http-router.ts +35 -43
- package/src/runtime/http-types.ts +23 -71
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/invite-instruction-generator.ts +3 -3
- package/src/runtime/pending-interactions.ts +3 -2
- package/src/runtime/routes/__tests__/acp-routes.test.ts +253 -55
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +62 -32
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +31 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -22
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +7 -2
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
- package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
- package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -2
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
- package/src/runtime/routes/__tests__/tts-routes.test.ts +9 -5
- package/src/runtime/routes/acp-routes.test.ts +186 -100
- package/src/runtime/routes/acp-routes.ts +110 -35
- package/src/runtime/routes/app-management-routes.ts +93 -131
- package/src/runtime/routes/app-routes.ts +38 -20
- package/src/runtime/routes/approval-routes.ts +17 -5
- package/src/runtime/routes/attachment-routes.ts +51 -16
- package/src/runtime/routes/audio-routes.ts +1 -0
- package/src/runtime/routes/audit-routes.ts +5 -0
- package/src/runtime/routes/auth-routes.ts +5 -0
- package/src/runtime/routes/avatar-routes.ts +264 -59
- package/src/runtime/routes/background-tool-routes.ts +9 -0
- package/src/runtime/routes/background-wake-routes.ts +13 -3
- package/src/runtime/routes/backup-routes.ts +45 -0
- package/src/runtime/routes/bookmark-routes.ts +13 -0
- package/src/runtime/routes/brain-graph-routes.ts +9 -0
- package/src/runtime/routes/browser-routes.ts +6 -1
- package/src/runtime/routes/browser-tabs-routes.ts +11 -10
- package/src/runtime/routes/btw-routes.ts +34 -24
- package/src/runtime/routes/cache-routes.ts +13 -0
- package/src/runtime/routes/call-routes.ts +21 -10
- package/src/runtime/routes/channel-availability-routes.ts +5 -1
- package/src/runtime/routes/channel-readiness-routes.ts +37 -4
- package/src/runtime/routes/channel-route-definitions.ts +21 -0
- package/src/runtime/routes/channel-verification-routes.ts +21 -0
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
- package/src/runtime/routes/client-routes.ts +9 -0
- package/src/runtime/routes/consolidation-routes.ts +133 -25
- package/src/runtime/routes/contact-prompt-routes.ts +9 -0
- package/src/runtime/routes/contact-routes.ts +90 -23
- package/src/runtime/routes/content-source-routes.ts +5 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +5 -1
- package/src/runtime/routes/conversation-attention-routes.ts +5 -0
- package/src/runtime/routes/conversation-cli-routes.ts +54 -7
- package/src/runtime/routes/conversation-compaction-routes.ts +54 -25
- package/src/runtime/routes/conversation-list-routes.ts +81 -12
- package/src/runtime/routes/conversation-management-routes.ts +57 -14
- package/src/runtime/routes/conversation-query-routes.ts +90 -41
- package/src/runtime/routes/conversation-routes.ts +446 -204
- package/src/runtime/routes/conversation-starter-routes.ts +35 -20
- package/src/runtime/routes/conversations-import-routes.ts +30 -8
- package/src/runtime/routes/credential-prompt-routes.ts +5 -0
- package/src/runtime/routes/credential-routes.ts +25 -6
- package/src/runtime/routes/debug-bash-routes.ts +5 -0
- package/src/runtime/routes/debug-routes.ts +11 -2
- package/src/runtime/routes/defer-routes.ts +13 -0
- package/src/runtime/routes/diagnostics-routes.ts +37 -46
- package/src/runtime/routes/disk-pressure-routes.ts +17 -31
- package/src/runtime/routes/document-comments-routes.ts +46 -27
- package/src/runtime/routes/documents-routes.ts +25 -10
- package/src/runtime/routes/domain-routes.ts +98 -51
- package/src/runtime/routes/email-routes.ts +33 -0
- package/src/runtime/routes/epoch-millis-range.ts +34 -0
- package/src/runtime/routes/events-routes.ts +107 -8
- package/src/runtime/routes/filing-routes.ts +9 -4
- package/src/runtime/routes/gateway-log-routes.ts +31 -4
- package/src/runtime/routes/global-search-routes.ts +53 -50
- package/src/runtime/routes/group-routes.ts +21 -5
- package/src/runtime/routes/guardian-action-routes.ts +9 -0
- package/src/runtime/routes/guardian-approval-interception.ts +0 -31
- package/src/runtime/routes/heartbeat-routes.ts +57 -21
- package/src/runtime/routes/home-feed-routes.ts +23 -19
- package/src/runtime/routes/home-state-routes.ts +8 -40
- package/src/runtime/routes/host-app-control-routes.ts +6 -1
- package/src/runtime/routes/host-bash-routes.ts +5 -0
- package/src/runtime/routes/host-browser-routes.ts +13 -0
- package/src/runtime/routes/host-cu-routes.ts +6 -1
- package/src/runtime/routes/host-file-routes.ts +26 -6
- package/src/runtime/routes/host-transfer-routes.ts +13 -2
- package/src/runtime/routes/http-adapter.ts +1 -2
- package/src/runtime/routes/identity-intro-cache.ts +28 -40
- package/src/runtime/routes/identity-routes.ts +236 -20
- package/src/runtime/routes/image-generation-routes.ts +45 -2
- package/src/runtime/routes/inbound-message-handler.ts +16 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +0 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +15 -19
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
- package/src/runtime/routes/inference-provider-connection-routes.ts +21 -5
- package/src/runtime/routes/inference-send-routes.ts +11 -11
- package/src/runtime/routes/integrations/a2a.ts +32 -7
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
- package/src/runtime/routes/integrations/slack/channel.ts +23 -3
- package/src/runtime/routes/integrations/slack/share.ts +36 -8
- package/src/runtime/routes/integrations/telegram.ts +34 -9
- package/src/runtime/routes/integrations/twilio.ts +77 -7
- package/src/runtime/routes/integrations/vercel.ts +3 -3
- package/src/runtime/routes/internal-oauth-routes.ts +5 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
- package/src/runtime/routes/internal-twilio-routes.ts +13 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
- package/src/runtime/routes/log-export-routes.ts +36 -10
- package/src/runtime/routes/mcp-auth-routes.ts +25 -0
- package/src/runtime/routes/memory-item-routes.ts +21 -10
- package/src/runtime/routes/memory-v2-routes.ts +105 -44
- package/src/runtime/routes/memory-v3-routes.ts +306 -408
- package/src/runtime/routes/migration-rollback-routes.ts +5 -1
- package/src/runtime/routes/migration-routes.ts +29 -0
- package/src/runtime/routes/notification-routes.ts +17 -1
- package/src/runtime/routes/oauth-apps.ts +99 -23
- package/src/runtime/routes/oauth-commands-routes.ts +37 -14
- package/src/runtime/routes/oauth-connect-routes.ts +9 -0
- package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
- package/src/runtime/routes/oauth-providers.ts +79 -15
- package/src/runtime/routes/platform-routes.ts +102 -5
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +9 -6
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
- package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
- package/src/runtime/routes/playground/force-compact.ts +2 -2
- package/src/runtime/routes/playground/helpers.ts +1 -2
- package/src/runtime/routes/playground/inject-failures.ts +13 -8
- package/src/runtime/routes/playground/reset-circuit.ts +14 -9
- package/src/runtime/routes/playground/seed-conversation.ts +1 -1
- package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
- package/src/runtime/routes/playground/state.ts +4 -3
- package/src/runtime/routes/plugins-routes.ts +22 -19
- package/src/runtime/routes/profiler-routes.ts +17 -4
- package/src/runtime/routes/ps-routes.ts +5 -0
- package/src/runtime/routes/publish-routes.ts +13 -3
- package/src/runtime/routes/question-routes.ts +5 -0
- package/src/runtime/routes/recording-routes.ts +25 -12
- package/src/runtime/routes/rename-conversation-routes.ts +10 -0
- package/src/runtime/routes/sanity-routes.ts +9 -2
- package/src/runtime/routes/schedule-routes.ts +288 -88
- package/src/runtime/routes/secret-routes.ts +31 -6
- package/src/runtime/routes/sequence-routes.ts +33 -0
- package/src/runtime/routes/settings-routes.ts +65 -19
- package/src/runtime/routes/skills-routes.ts +166 -73
- package/src/runtime/routes/slack-channel-routes.ts +5 -0
- package/src/runtime/routes/stt-routes.ts +13 -6
- package/src/runtime/routes/subagents-routes.ts +24 -18
- package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
- package/src/runtime/routes/surface-action-routes.ts +9 -0
- package/src/runtime/routes/surface-content-routes.ts +10 -2
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/task-routes.ts +37 -0
- package/src/runtime/routes/telemetry-routes.ts +9 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
- package/src/runtime/routes/trace-event-routes.ts +42 -1
- package/src/runtime/routes/trust-rules-routes.ts +31 -2
- package/src/runtime/routes/tts-routes.ts +48 -6
- package/src/runtime/routes/types.ts +83 -16
- package/src/runtime/routes/ui-request-routes.ts +5 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
- package/src/runtime/routes/usage-routes.ts +118 -42
- package/src/runtime/routes/user-routes-cli.ts +9 -0
- package/src/runtime/routes/user-routes.ts +5 -1
- package/src/runtime/routes/wake-conversation-routes.ts +5 -0
- package/src/runtime/routes/watcher-routes.ts +21 -0
- package/src/runtime/routes/webhook-routes.ts +50 -2
- package/src/runtime/routes/wipe-conversation-routes.ts +5 -0
- package/src/runtime/routes/work-items-routes.ts +49 -23
- package/src/runtime/routes/workspace-commit-routes.ts +5 -0
- package/src/runtime/routes/workspace-routes.test.ts +42 -0
- package/src/runtime/routes/workspace-routes.ts +124 -9
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +8 -4
- package/src/runtime/services/analyze-conversation.ts +5 -8
- package/src/runtime/services/conversation-serializer.ts +24 -2
- package/src/runtime/sync/resource-sync-events.ts +16 -2
- package/src/runtime/sync/sync-publisher.ts +2 -2
- package/src/schedule/run-script.ts +28 -3
- package/src/schedule/schedule-store.ts +28 -1
- package/src/schedule/schedule-usage-store.ts +83 -0
- package/src/schedule/scheduler.ts +15 -6
- package/src/signals/cancel.ts +2 -4
- package/src/signals/user-message.ts +5 -8
- package/src/skills/catalog-files.ts +4 -1
- package/src/skills/catalog-install.ts +3 -0
- package/src/skills/categories-cache.ts +118 -0
- package/src/skills/clawhub-files.ts +1 -0
- package/src/skills/skillssh-files.ts +1 -0
- package/src/subagent/manager.ts +20 -11
- package/src/telemetry/types.ts +55 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +250 -4
- package/src/telemetry/usage-telemetry-reporter.ts +88 -2
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +7 -1
- package/src/tools/acp/spawn.test.ts +198 -93
- package/src/tools/acp/spawn.ts +32 -70
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/definitions.ts +8 -4
- package/src/tools/apps/executors.ts +13 -8
- package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
- package/src/tools/ask-question/ask-question-tool.ts +85 -90
- package/src/tools/computer-use/definitions.ts +28 -24
- package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
- package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
- package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
- package/src/tools/credentials/vault.ts +112 -111
- package/src/tools/execution-target.ts +1 -1
- package/src/tools/execution-timeout.ts +3 -4
- package/src/tools/executor.ts +1 -53
- package/src/tools/filesystem/edit.ts +45 -42
- package/src/tools/filesystem/list.ts +33 -30
- package/src/tools/filesystem/read.ts +54 -35
- package/src/tools/filesystem/write.ts +69 -32
- package/src/tools/host-filesystem/edit.ts +44 -42
- package/src/tools/host-filesystem/read.ts +49 -35
- package/src/tools/host-filesystem/transfer.ts +121 -108
- package/src/tools/host-filesystem/write.ts +33 -31
- package/src/tools/host-terminal/host-shell.ts +50 -48
- package/src/tools/memory/register.ts +23 -24
- package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
- package/src/tools/network/__tests__/web-search.test.ts +11 -3
- package/src/tools/network/web-fetch.ts +49 -46
- package/src/tools/network/web-search-error.test.ts +248 -0
- package/src/tools/network/web-search-error.ts +267 -0
- package/src/tools/network/web-search.ts +223 -61
- package/src/tools/registry.ts +39 -16
- package/src/tools/schedule/create.ts +13 -0
- package/src/tools/schedule/update.ts +16 -0
- package/src/tools/shared/filesystem/audio-read.ts +122 -0
- package/src/tools/shared/filesystem/image-read.ts +1 -1
- package/src/tools/skills/execute.ts +34 -31
- package/src/tools/skills/load.ts +29 -23
- package/src/tools/subagent/notify-parent.ts +35 -32
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/system/avatar-generator.ts +13 -22
- package/src/tools/system/request-permission.ts +30 -27
- package/src/tools/terminal/safe-env.ts +10 -1
- package/src/tools/terminal/shell.ts +190 -61
- package/src/tools/tool-defaults.ts +20 -9
- package/src/tools/tool-manifest.ts +4 -4
- package/src/tools/types.ts +74 -23
- package/src/tools/ui-surface/definitions.ts +99 -10
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
- package/src/tts/provider-catalog.ts +76 -1
- package/src/usage/types.ts +10 -0
- package/src/util/errors.ts +2 -2
- package/src/util/map-limit.ts +27 -0
- package/src/util/mutex.ts +47 -0
- package/src/util/platform.ts +15 -12
- package/src/work-items/work-item-runner.ts +7 -2
- package/src/workspace/git-service.ts +1 -42
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
- package/src/workspace/migrations/092-backfill-v3-leaves.ts +169 -0
- package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
- package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
- package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
- package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +117 -0
- package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
- package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
- package/src/workspace/migrations/registry.ts +12 -0
- package/src/workspace/provider-commit-message-generator.ts +15 -17
- package/tsconfig.json +4 -1
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
- package/src/__tests__/compaction-pipeline.test.ts +0 -210
- package/src/__tests__/compaction-timeout-recovery.test.ts +0 -262
- package/src/__tests__/empty-response-pipeline.test.ts +0 -301
- package/src/__tests__/history-repair-pipeline.test.ts +0 -396
- package/src/__tests__/llm-call-pipeline.test.ts +0 -281
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
- package/src/__tests__/persistence-pipeline.test.ts +0 -514
- package/src/__tests__/title-generate-pipeline.test.ts +0 -211
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -481
- package/src/__tests__/tool-error-pipeline.test.ts +0 -241
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -344
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
- package/src/cli/commands/memory-v3-render.ts +0 -491
- package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
- package/src/daemon/message-types/disk-pressure.ts +0 -9
- package/src/email/feature-gate.ts +0 -23
- package/src/gallery/default-gallery.ts +0 -1359
- package/src/gallery/gallery-manifest.ts +0 -28
- package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
- package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -466
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +0 -270
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
- package/src/memory/v3/__tests__/edges.test.ts +0 -706
- package/src/memory/v3/__tests__/filter.test.ts +0 -560
- package/src/memory/v3/__tests__/gate.test.ts +0 -637
- package/src/memory/v3/__tests__/index-composition.test.ts +0 -291
- package/src/memory/v3/__tests__/loop.test.ts +0 -775
- package/src/memory/v3/__tests__/retriever.test.ts +0 -226
- package/src/memory/v3/__tests__/scouts.test.ts +0 -489
- package/src/memory/v3/__tests__/shadow-diff.test.ts +0 -225
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -398
- package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
- package/src/memory/v3/__tests__/traversal.test.ts +0 -508
- package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
- package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
- package/src/memory/v3/__tests__/tree-walk.test.ts +0 -784
- package/src/memory/v3/__tests__/validate.test.ts +0 -277
- package/src/memory/v3/auto-edges.ts +0 -223
- package/src/memory/v3/coactivation-store.ts +0 -124
- package/src/memory/v3/consolidation-job.ts +0 -323
- package/src/memory/v3/coretrieval-seed.ts +0 -240
- package/src/memory/v3/edge-learning-job.ts +0 -160
- package/src/memory/v3/edges.ts +0 -286
- package/src/memory/v3/filter.ts +0 -286
- package/src/memory/v3/gate.ts +0 -349
- package/src/memory/v3/index-composition.ts +0 -126
- package/src/memory/v3/llm-capture.ts +0 -46
- package/src/memory/v3/loop.ts +0 -430
- package/src/memory/v3/maintenance.ts +0 -144
- package/src/memory/v3/prompt-context.ts +0 -33
- package/src/memory/v3/prompts/consolidation.ts +0 -458
- package/src/memory/v3/prompts/system-prompts.ts +0 -196
- package/src/memory/v3/retriever.ts +0 -33
- package/src/memory/v3/scouts.ts +0 -431
- package/src/memory/v3/shadow-diff.ts +0 -287
- package/src/memory/v3/shadow-middleware.ts +0 -347
- package/src/memory/v3/traversal.ts +0 -211
- package/src/memory/v3/tree-index.ts +0 -237
- package/src/memory/v3/tree-store.ts +0 -394
- package/src/memory/v3/tree-walk.ts +0 -356
- package/src/memory/v3/types.ts +0 -65
- package/src/memory/v3/validate.ts +0 -323
- package/src/plugins/defaults/circuit-breaker.ts +0 -141
- package/src/plugins/defaults/compaction.ts +0 -141
- package/src/plugins/defaults/empty-response.ts +0 -124
- package/src/plugins/defaults/history-repair.ts +0 -83
- package/src/plugins/defaults/llm-call.ts +0 -77
- package/src/plugins/defaults/memory-retrieval.ts +0 -219
- package/src/plugins/defaults/overflow-reduce.ts +0 -185
- package/src/plugins/defaults/persistence.ts +0 -146
- package/src/plugins/defaults/title-generate.ts +0 -90
- package/src/plugins/defaults/token-estimate.ts +0 -101
- package/src/plugins/defaults/tool-error.ts +0 -119
- package/src/plugins/defaults/tool-execute.ts +0 -87
- package/src/plugins/defaults/tool-result-truncate.ts +0 -84
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +0 -35
- package/src/skills/category-inference.ts +0 -111
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
1
|
+
import { beforeEach, describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
4
|
AgentEvent,
|
|
@@ -6,87 +6,24 @@ import type {
|
|
|
6
6
|
CheckpointInfo,
|
|
7
7
|
} from "../agent/loop.js";
|
|
8
8
|
import { AgentLoop } from "../agent/loop.js";
|
|
9
|
+
import { resetPluginRegistryAndRegisterDefaults } from "../plugins/defaults/index.js";
|
|
9
10
|
import type {
|
|
10
11
|
ContentBlock,
|
|
11
12
|
Message,
|
|
12
13
|
Provider,
|
|
13
14
|
ProviderResponse,
|
|
14
|
-
SendMessageOptions,
|
|
15
15
|
ToolDefinition,
|
|
16
16
|
} from "../providers/types.js";
|
|
17
|
+
import {
|
|
18
|
+
createMockProvider,
|
|
19
|
+
textResponse,
|
|
20
|
+
toolUseResponse,
|
|
21
|
+
} from "./helpers/mock-provider.js";
|
|
17
22
|
|
|
18
23
|
// ---------------------------------------------------------------------------
|
|
19
24
|
// Helpers
|
|
20
25
|
// ---------------------------------------------------------------------------
|
|
21
26
|
|
|
22
|
-
/** A mock provider that returns pre-configured responses in sequence. */
|
|
23
|
-
function createMockProvider(responses: ProviderResponse[]): {
|
|
24
|
-
provider: Provider;
|
|
25
|
-
calls: {
|
|
26
|
-
messages: Message[];
|
|
27
|
-
tools?: ToolDefinition[];
|
|
28
|
-
systemPrompt?: string;
|
|
29
|
-
options?: SendMessageOptions;
|
|
30
|
-
}[];
|
|
31
|
-
} {
|
|
32
|
-
const calls: {
|
|
33
|
-
messages: Message[];
|
|
34
|
-
tools?: ToolDefinition[];
|
|
35
|
-
systemPrompt?: string;
|
|
36
|
-
options?: SendMessageOptions;
|
|
37
|
-
}[] = [];
|
|
38
|
-
let callIndex = 0;
|
|
39
|
-
|
|
40
|
-
const provider: Provider = {
|
|
41
|
-
name: "mock",
|
|
42
|
-
async sendMessage(
|
|
43
|
-
messages: Message[],
|
|
44
|
-
tools?: ToolDefinition[],
|
|
45
|
-
systemPrompt?: string,
|
|
46
|
-
options?: SendMessageOptions,
|
|
47
|
-
): Promise<ProviderResponse> {
|
|
48
|
-
calls.push({ messages: [...messages], tools, systemPrompt, options });
|
|
49
|
-
const response = responses[callIndex] ?? responses[responses.length - 1];
|
|
50
|
-
callIndex++;
|
|
51
|
-
|
|
52
|
-
// Emit streaming events if the response has text blocks
|
|
53
|
-
if (options?.onEvent) {
|
|
54
|
-
for (const block of response.content) {
|
|
55
|
-
if (block.type === "text") {
|
|
56
|
-
options.onEvent({ type: "text_delta", text: block.text });
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return response;
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
return { provider, calls };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function textResponse(text: string): ProviderResponse {
|
|
69
|
-
return {
|
|
70
|
-
content: [{ type: "text", text }],
|
|
71
|
-
model: "mock-model",
|
|
72
|
-
usage: { inputTokens: 10, outputTokens: 5 },
|
|
73
|
-
stopReason: "end_turn",
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function toolUseResponse(
|
|
78
|
-
id: string,
|
|
79
|
-
name: string,
|
|
80
|
-
input: Record<string, unknown>,
|
|
81
|
-
): ProviderResponse {
|
|
82
|
-
return {
|
|
83
|
-
content: [{ type: "tool_use", id, name, input }],
|
|
84
|
-
model: "mock-model",
|
|
85
|
-
usage: { inputTokens: 10, outputTokens: 5 },
|
|
86
|
-
stopReason: "tool_use",
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
27
|
const dummyTools: ToolDefinition[] = [
|
|
91
28
|
{
|
|
92
29
|
name: "read_file",
|
|
@@ -109,13 +46,20 @@ function collectEvents(events: AgentEvent[]): (event: AgentEvent) => void {
|
|
|
109
46
|
// ---------------------------------------------------------------------------
|
|
110
47
|
|
|
111
48
|
describe("AgentLoop", () => {
|
|
49
|
+
// The agent loop fires the `post-tool-use` hook for tool-result
|
|
50
|
+
// truncation, which only runs when the default plugin is registered.
|
|
51
|
+
// Register the defaults so the loop behaves as it does in production.
|
|
52
|
+
beforeEach(() => {
|
|
53
|
+
resetPluginRegistryAndRegisterDefaults();
|
|
54
|
+
});
|
|
55
|
+
|
|
112
56
|
// 1. Basic text response
|
|
113
57
|
test("returns history with assistant message for simple text response", async () => {
|
|
114
58
|
const { provider } = createMockProvider([textResponse("Hi there!")]);
|
|
115
59
|
const loop = new AgentLoop(provider, "system prompt");
|
|
116
60
|
|
|
117
61
|
const events: AgentEvent[] = [];
|
|
118
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
62
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
119
63
|
|
|
120
64
|
// History should contain original user message + assistant response
|
|
121
65
|
expect(history).toHaveLength(2);
|
|
@@ -141,15 +85,12 @@ describe("AgentLoop", () => {
|
|
|
141
85
|
return { content: "file data here", isError: false };
|
|
142
86
|
};
|
|
143
87
|
|
|
144
|
-
const loop = new AgentLoop(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
dummyTools,
|
|
149
|
-
toolExecutor,
|
|
150
|
-
);
|
|
88
|
+
const loop = new AgentLoop(provider, "system", {
|
|
89
|
+
tools: dummyTools,
|
|
90
|
+
toolExecutor: toolExecutor,
|
|
91
|
+
});
|
|
151
92
|
const events: AgentEvent[] = [];
|
|
152
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
93
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
153
94
|
|
|
154
95
|
// Tool executor was called with correct args
|
|
155
96
|
expect(toolCalls).toHaveLength(1);
|
|
@@ -193,26 +134,16 @@ describe("AgentLoop", () => {
|
|
|
193
134
|
overrideProfile = "quality-optimized";
|
|
194
135
|
return { content: "ok", isError: false };
|
|
195
136
|
};
|
|
196
|
-
const loop = new AgentLoop(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
dummyTools,
|
|
201
|
-
toolExecutor,
|
|
202
|
-
);
|
|
137
|
+
const loop = new AgentLoop(provider, "system", {
|
|
138
|
+
tools: dummyTools,
|
|
139
|
+
toolExecutor: toolExecutor,
|
|
140
|
+
});
|
|
203
141
|
|
|
204
|
-
await loop.run(
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
undefined,
|
|
210
|
-
"mainAgent",
|
|
211
|
-
undefined,
|
|
212
|
-
undefined,
|
|
213
|
-
undefined,
|
|
214
|
-
() => overrideProfile,
|
|
215
|
-
);
|
|
142
|
+
await loop.run([userMessage], collectEvents([]), {
|
|
143
|
+
requestId: "req-1",
|
|
144
|
+
callSite: "mainAgent",
|
|
145
|
+
resolveOverrideProfile: () => overrideProfile,
|
|
146
|
+
});
|
|
216
147
|
|
|
217
148
|
expect(calls).toHaveLength(2);
|
|
218
149
|
expect(calls[0].options?.config?.overrideProfile).toBeUndefined();
|
|
@@ -232,27 +163,19 @@ describe("AgentLoop", () => {
|
|
|
232
163
|
maxInputTokens = 10_000;
|
|
233
164
|
return { content: toolOutput, isError: false };
|
|
234
165
|
};
|
|
235
|
-
const loop = new AgentLoop(
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
dummyTools,
|
|
240
|
-
toolExecutor,
|
|
241
|
-
);
|
|
166
|
+
const loop = new AgentLoop(provider, "system", {
|
|
167
|
+
tools: dummyTools,
|
|
168
|
+
toolExecutor: toolExecutor,
|
|
169
|
+
});
|
|
242
170
|
|
|
243
|
-
await loop.run(
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
undefined,
|
|
252
|
-
1_000,
|
|
253
|
-
undefined,
|
|
254
|
-
() => maxInputTokens,
|
|
255
|
-
);
|
|
171
|
+
await loop.run([userMessage], collectEvents([]), {
|
|
172
|
+
requestId: "req-1",
|
|
173
|
+
callSite: "mainAgent",
|
|
174
|
+
resolveContextWindow: () => ({
|
|
175
|
+
maxInputTokens,
|
|
176
|
+
overflowRecovery: { enabled: false, safetyMarginRatio: 0 },
|
|
177
|
+
}),
|
|
178
|
+
});
|
|
256
179
|
|
|
257
180
|
const secondCallMessages = calls[1].messages;
|
|
258
181
|
const lastMsg = secondCallMessages[secondCallMessages.length - 1];
|
|
@@ -281,14 +204,11 @@ describe("AgentLoop", () => {
|
|
|
281
204
|
};
|
|
282
205
|
};
|
|
283
206
|
|
|
284
|
-
const loop = new AgentLoop(
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
toolExecutor,
|
|
290
|
-
);
|
|
291
|
-
const history = await loop.run([userMessage], () => {});
|
|
207
|
+
const loop = new AgentLoop(provider, "system", {
|
|
208
|
+
tools: dummyTools,
|
|
209
|
+
toolExecutor: toolExecutor,
|
|
210
|
+
});
|
|
211
|
+
const { history } = await loop.run([userMessage], () => {});
|
|
292
212
|
|
|
293
213
|
// Provider called 3 times (two tool rounds + final text)
|
|
294
214
|
expect(calls).toHaveLength(3);
|
|
@@ -307,8 +227,8 @@ describe("AgentLoop", () => {
|
|
|
307
227
|
]);
|
|
308
228
|
|
|
309
229
|
// No tool executor provided
|
|
310
|
-
const loop = new AgentLoop(provider, "system", {
|
|
311
|
-
const history = await loop.run([userMessage], () => {});
|
|
230
|
+
const loop = new AgentLoop(provider, "system", { tools: dummyTools });
|
|
231
|
+
const { history } = await loop.run([userMessage], () => {});
|
|
312
232
|
|
|
313
233
|
// Should stop after first response (no executor to handle tool use)
|
|
314
234
|
expect(history).toHaveLength(2);
|
|
@@ -327,7 +247,7 @@ describe("AgentLoop", () => {
|
|
|
327
247
|
|
|
328
248
|
const loop = new AgentLoop(provider, "system");
|
|
329
249
|
const events: AgentEvent[] = [];
|
|
330
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
250
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
331
251
|
|
|
332
252
|
// Only the original message remains (no assistant message added on error)
|
|
333
253
|
expect(history).toHaveLength(1);
|
|
@@ -347,7 +267,9 @@ describe("AgentLoop", () => {
|
|
|
347
267
|
|
|
348
268
|
const { provider } = createMockProvider([textResponse("Should not reach")]);
|
|
349
269
|
const loop = new AgentLoop(provider, "system");
|
|
350
|
-
const history = await loop.run([userMessage], () => {},
|
|
270
|
+
const { history } = await loop.run([userMessage], () => {}, {
|
|
271
|
+
signal: controller.signal,
|
|
272
|
+
});
|
|
351
273
|
|
|
352
274
|
// Loop should exit immediately, returning only original messages
|
|
353
275
|
expect(history).toHaveLength(1);
|
|
@@ -372,14 +294,13 @@ describe("AgentLoop", () => {
|
|
|
372
294
|
return { content: "data", isError: false };
|
|
373
295
|
};
|
|
374
296
|
|
|
375
|
-
const loop = new AgentLoop(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
);
|
|
382
|
-
const history = await loop.run([userMessage], () => {}, controller.signal);
|
|
297
|
+
const loop = new AgentLoop(provider, "system", {
|
|
298
|
+
tools: dummyTools,
|
|
299
|
+
toolExecutor: toolExecutor,
|
|
300
|
+
});
|
|
301
|
+
const { history } = await loop.run([userMessage], () => {}, {
|
|
302
|
+
signal: controller.signal,
|
|
303
|
+
});
|
|
383
304
|
|
|
384
305
|
// After the first tool turn, abort fires. The while loop checks signal at the
|
|
385
306
|
// top and breaks. History: user, assistant(t1), user(result1)
|
|
@@ -419,15 +340,14 @@ describe("AgentLoop", () => {
|
|
|
419
340
|
return { content: "should never return", isError: false };
|
|
420
341
|
};
|
|
421
342
|
|
|
422
|
-
const loop = new AgentLoop(
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
dummyTools,
|
|
427
|
-
toolExecutor,
|
|
428
|
-
);
|
|
343
|
+
const loop = new AgentLoop(provider, "system", {
|
|
344
|
+
tools: dummyTools,
|
|
345
|
+
toolExecutor: toolExecutor,
|
|
346
|
+
});
|
|
429
347
|
const start = Date.now();
|
|
430
|
-
const history = await loop.run([userMessage], () => {},
|
|
348
|
+
const { history } = await loop.run([userMessage], () => {}, {
|
|
349
|
+
signal: controller.signal,
|
|
350
|
+
});
|
|
431
351
|
const elapsed = Date.now() - start;
|
|
432
352
|
|
|
433
353
|
// The loop should exit quickly (~50ms for abort), not wait 10s for the tool
|
|
@@ -516,13 +436,10 @@ describe("AgentLoop", () => {
|
|
|
516
436
|
]);
|
|
517
437
|
|
|
518
438
|
const toolExecutor = async () => ({ content: "file data", isError: false });
|
|
519
|
-
const loop = new AgentLoop(
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
dummyTools,
|
|
524
|
-
toolExecutor,
|
|
525
|
-
);
|
|
439
|
+
const loop = new AgentLoop(provider, "system", {
|
|
440
|
+
tools: dummyTools,
|
|
441
|
+
toolExecutor: toolExecutor,
|
|
442
|
+
});
|
|
526
443
|
|
|
527
444
|
const events: AgentEvent[] = [];
|
|
528
445
|
await loop.run([userMessage], collectEvents(events));
|
|
@@ -563,13 +480,10 @@ describe("AgentLoop", () => {
|
|
|
563
480
|
content: "ENOENT: file not found",
|
|
564
481
|
isError: true,
|
|
565
482
|
});
|
|
566
|
-
const loop = new AgentLoop(
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
dummyTools,
|
|
571
|
-
toolExecutor,
|
|
572
|
-
);
|
|
483
|
+
const loop = new AgentLoop(provider, "system", {
|
|
484
|
+
tools: dummyTools,
|
|
485
|
+
toolExecutor: toolExecutor,
|
|
486
|
+
});
|
|
573
487
|
|
|
574
488
|
await loop.run([userMessage], () => {});
|
|
575
489
|
|
|
@@ -601,13 +515,10 @@ describe("AgentLoop", () => {
|
|
|
601
515
|
return { content: "full output", isError: false };
|
|
602
516
|
};
|
|
603
517
|
|
|
604
|
-
const loop = new AgentLoop(
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
dummyTools,
|
|
609
|
-
toolExecutor,
|
|
610
|
-
);
|
|
518
|
+
const loop = new AgentLoop(provider, "system", {
|
|
519
|
+
tools: dummyTools,
|
|
520
|
+
toolExecutor: toolExecutor,
|
|
521
|
+
});
|
|
611
522
|
const events: AgentEvent[] = [];
|
|
612
523
|
await loop.run([userMessage], collectEvents(events));
|
|
613
524
|
|
|
@@ -626,7 +537,9 @@ describe("AgentLoop", () => {
|
|
|
626
537
|
// 11. System prompt and tools are passed to provider
|
|
627
538
|
test("passes system prompt and tools to provider", async () => {
|
|
628
539
|
const { provider, calls } = createMockProvider([textResponse("Hi")]);
|
|
629
|
-
const loop = new AgentLoop(provider, "My system prompt", {
|
|
540
|
+
const loop = new AgentLoop(provider, "My system prompt", {
|
|
541
|
+
tools: dummyTools,
|
|
542
|
+
});
|
|
630
543
|
|
|
631
544
|
await loop.run([userMessage], () => {});
|
|
632
545
|
|
|
@@ -692,15 +605,12 @@ describe("AgentLoop", () => {
|
|
|
692
605
|
};
|
|
693
606
|
};
|
|
694
607
|
|
|
695
|
-
const loop = new AgentLoop(
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
dummyTools,
|
|
700
|
-
toolExecutor,
|
|
701
|
-
);
|
|
608
|
+
const loop = new AgentLoop(provider, "system", {
|
|
609
|
+
tools: dummyTools,
|
|
610
|
+
toolExecutor: toolExecutor,
|
|
611
|
+
});
|
|
702
612
|
const events: AgentEvent[] = [];
|
|
703
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
613
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
704
614
|
|
|
705
615
|
// All 3 tools should have been called
|
|
706
616
|
expect(executionLog).toHaveLength(3);
|
|
@@ -789,19 +699,14 @@ describe("AgentLoop", () => {
|
|
|
789
699
|
return { content: "data", isError: false };
|
|
790
700
|
};
|
|
791
701
|
|
|
792
|
-
const loop = new AgentLoop(
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
dummyTools,
|
|
797
|
-
toolExecutor,
|
|
798
|
-
);
|
|
702
|
+
const loop = new AgentLoop(provider, "system", {
|
|
703
|
+
tools: dummyTools,
|
|
704
|
+
toolExecutor: toolExecutor,
|
|
705
|
+
});
|
|
799
706
|
const events: AgentEvent[] = [];
|
|
800
|
-
const history = await loop.run(
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
controller.signal,
|
|
804
|
-
);
|
|
707
|
+
const { history } = await loop.run([userMessage], collectEvents(events), {
|
|
708
|
+
signal: controller.signal,
|
|
709
|
+
});
|
|
805
710
|
|
|
806
711
|
// No tools should have been executed
|
|
807
712
|
expect(toolCalls).toHaveLength(0);
|
|
@@ -868,13 +773,10 @@ describe("AgentLoop", () => {
|
|
|
868
773
|
return { content: `contents of ${path}`, isError: false };
|
|
869
774
|
};
|
|
870
775
|
|
|
871
|
-
const loop = new AgentLoop(
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
dummyTools,
|
|
876
|
-
toolExecutor,
|
|
877
|
-
);
|
|
776
|
+
const loop = new AgentLoop(provider, "system", {
|
|
777
|
+
tools: dummyTools,
|
|
778
|
+
toolExecutor: toolExecutor,
|
|
779
|
+
});
|
|
878
780
|
const events: AgentEvent[] = [];
|
|
879
781
|
await loop.run([userMessage], collectEvents(events));
|
|
880
782
|
|
|
@@ -903,13 +805,10 @@ describe("AgentLoop", () => {
|
|
|
903
805
|
]);
|
|
904
806
|
|
|
905
807
|
const toolExecutor = async () => ({ content: "file data", isError: false });
|
|
906
|
-
const loop = new AgentLoop(
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
dummyTools,
|
|
911
|
-
toolExecutor,
|
|
912
|
-
);
|
|
808
|
+
const loop = new AgentLoop(provider, "system", {
|
|
809
|
+
tools: dummyTools,
|
|
810
|
+
toolExecutor: toolExecutor,
|
|
811
|
+
});
|
|
913
812
|
|
|
914
813
|
const checkpoints: CheckpointInfo[] = [];
|
|
915
814
|
const onCheckpoint = (checkpoint: CheckpointInfo): CheckpointDecision => {
|
|
@@ -917,7 +816,7 @@ describe("AgentLoop", () => {
|
|
|
917
816
|
return "continue";
|
|
918
817
|
};
|
|
919
818
|
|
|
920
|
-
await loop.run([userMessage], () => {},
|
|
819
|
+
await loop.run([userMessage], () => {}, { onCheckpoint });
|
|
921
820
|
|
|
922
821
|
expect(checkpoints).toHaveLength(1);
|
|
923
822
|
expect(checkpoints[0]).toMatchObject({
|
|
@@ -938,23 +837,16 @@ describe("AgentLoop", () => {
|
|
|
938
837
|
]);
|
|
939
838
|
|
|
940
839
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
941
|
-
const loop = new AgentLoop(
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
dummyTools,
|
|
946
|
-
toolExecutor,
|
|
947
|
-
);
|
|
840
|
+
const loop = new AgentLoop(provider, "system", {
|
|
841
|
+
tools: dummyTools,
|
|
842
|
+
toolExecutor: toolExecutor,
|
|
843
|
+
});
|
|
948
844
|
|
|
949
845
|
const onCheckpoint = (): CheckpointDecision => "continue";
|
|
950
846
|
|
|
951
|
-
const history = await loop.run(
|
|
952
|
-
[userMessage],
|
|
953
|
-
() => {},
|
|
954
|
-
undefined,
|
|
955
|
-
undefined,
|
|
847
|
+
const { history } = await loop.run([userMessage], () => {}, {
|
|
956
848
|
onCheckpoint,
|
|
957
|
-
);
|
|
849
|
+
});
|
|
958
850
|
|
|
959
851
|
// All 3 provider calls should happen (2 tool turns + final text)
|
|
960
852
|
expect(calls).toHaveLength(3);
|
|
@@ -972,23 +864,16 @@ describe("AgentLoop", () => {
|
|
|
972
864
|
]);
|
|
973
865
|
|
|
974
866
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
975
|
-
const loop = new AgentLoop(
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
dummyTools,
|
|
980
|
-
toolExecutor,
|
|
981
|
-
);
|
|
867
|
+
const loop = new AgentLoop(provider, "system", {
|
|
868
|
+
tools: dummyTools,
|
|
869
|
+
toolExecutor: toolExecutor,
|
|
870
|
+
});
|
|
982
871
|
|
|
983
|
-
const onCheckpoint = (): CheckpointDecision => "
|
|
872
|
+
const onCheckpoint = (): CheckpointDecision => "budget";
|
|
984
873
|
|
|
985
|
-
const history = await loop.run(
|
|
986
|
-
[userMessage],
|
|
987
|
-
() => {},
|
|
988
|
-
undefined,
|
|
989
|
-
undefined,
|
|
874
|
+
const { history } = await loop.run([userMessage], () => {}, {
|
|
990
875
|
onCheckpoint,
|
|
991
|
-
);
|
|
876
|
+
});
|
|
992
877
|
|
|
993
878
|
// Only 1 provider call should happen — loop yields after first tool turn
|
|
994
879
|
expect(calls).toHaveLength(1);
|
|
@@ -1006,15 +891,12 @@ describe("AgentLoop", () => {
|
|
|
1006
891
|
]);
|
|
1007
892
|
|
|
1008
893
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
1009
|
-
const loop = new AgentLoop(
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
dummyTools,
|
|
1014
|
-
toolExecutor,
|
|
1015
|
-
);
|
|
894
|
+
const loop = new AgentLoop(provider, "system", {
|
|
895
|
+
tools: dummyTools,
|
|
896
|
+
toolExecutor: toolExecutor,
|
|
897
|
+
});
|
|
1016
898
|
|
|
1017
|
-
const history = await loop.run([userMessage], () => {});
|
|
899
|
+
const { history } = await loop.run([userMessage], () => {});
|
|
1018
900
|
|
|
1019
901
|
// Normal behavior: 2 provider calls, full history
|
|
1020
902
|
expect(calls).toHaveLength(2);
|
|
@@ -1032,13 +914,10 @@ describe("AgentLoop", () => {
|
|
|
1032
914
|
]);
|
|
1033
915
|
|
|
1034
916
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
1035
|
-
const loop = new AgentLoop(
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
dummyTools,
|
|
1040
|
-
toolExecutor,
|
|
1041
|
-
);
|
|
917
|
+
const loop = new AgentLoop(provider, "system", {
|
|
918
|
+
tools: dummyTools,
|
|
919
|
+
toolExecutor: toolExecutor,
|
|
920
|
+
});
|
|
1042
921
|
|
|
1043
922
|
const checkpoints: CheckpointInfo[] = [];
|
|
1044
923
|
const onCheckpoint = (checkpoint: CheckpointInfo): CheckpointDecision => {
|
|
@@ -1046,7 +925,7 @@ describe("AgentLoop", () => {
|
|
|
1046
925
|
return "continue";
|
|
1047
926
|
};
|
|
1048
927
|
|
|
1049
|
-
await loop.run([userMessage], () => {},
|
|
928
|
+
await loop.run([userMessage], () => {}, { onCheckpoint });
|
|
1050
929
|
|
|
1051
930
|
expect(checkpoints).toHaveLength(3);
|
|
1052
931
|
expect(checkpoints[0].turnIndex).toBe(0);
|
|
@@ -1059,7 +938,7 @@ describe("AgentLoop", () => {
|
|
|
1059
938
|
const { provider } = createMockProvider([
|
|
1060
939
|
textResponse("Just a text response"),
|
|
1061
940
|
]);
|
|
1062
|
-
const loop = new AgentLoop(provider, "system", {
|
|
941
|
+
const loop = new AgentLoop(provider, "system", { tools: dummyTools });
|
|
1063
942
|
|
|
1064
943
|
const checkpoints: CheckpointInfo[] = [];
|
|
1065
944
|
const onCheckpoint = (checkpoint: CheckpointInfo): CheckpointDecision => {
|
|
@@ -1067,13 +946,9 @@ describe("AgentLoop", () => {
|
|
|
1067
946
|
return "continue";
|
|
1068
947
|
};
|
|
1069
948
|
|
|
1070
|
-
const history = await loop.run(
|
|
1071
|
-
[userMessage],
|
|
1072
|
-
() => {},
|
|
1073
|
-
undefined,
|
|
1074
|
-
undefined,
|
|
949
|
+
const { history } = await loop.run([userMessage], () => {}, {
|
|
1075
950
|
onCheckpoint,
|
|
1076
|
-
);
|
|
951
|
+
});
|
|
1077
952
|
|
|
1078
953
|
// Checkpoint should never be called for a text-only response
|
|
1079
954
|
expect(checkpoints).toHaveLength(0);
|
|
@@ -1116,13 +991,10 @@ describe("AgentLoop", () => {
|
|
|
1116
991
|
]);
|
|
1117
992
|
|
|
1118
993
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
1119
|
-
const loop = new AgentLoop(
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
dummyTools,
|
|
1124
|
-
toolExecutor,
|
|
1125
|
-
);
|
|
994
|
+
const loop = new AgentLoop(provider, "system", {
|
|
995
|
+
tools: dummyTools,
|
|
996
|
+
toolExecutor: toolExecutor,
|
|
997
|
+
});
|
|
1126
998
|
|
|
1127
999
|
const checkpoints: CheckpointInfo[] = [];
|
|
1128
1000
|
const onCheckpoint = (checkpoint: CheckpointInfo): CheckpointDecision => {
|
|
@@ -1130,7 +1002,7 @@ describe("AgentLoop", () => {
|
|
|
1130
1002
|
return "continue";
|
|
1131
1003
|
};
|
|
1132
1004
|
|
|
1133
|
-
await loop.run([userMessage], () => {},
|
|
1005
|
+
await loop.run([userMessage], () => {}, { onCheckpoint });
|
|
1134
1006
|
|
|
1135
1007
|
expect(checkpoints).toHaveLength(1);
|
|
1136
1008
|
expect(checkpoints[0].toolCount).toBe(3);
|
|
@@ -1150,29 +1022,22 @@ describe("AgentLoop", () => {
|
|
|
1150
1022
|
|
|
1151
1023
|
const { provider, calls } = createMockProvider(responses);
|
|
1152
1024
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
1153
|
-
const loop = new AgentLoop(
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
dummyTools,
|
|
1158
|
-
toolExecutor,
|
|
1159
|
-
);
|
|
1025
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1026
|
+
tools: dummyTools,
|
|
1027
|
+
toolExecutor: toolExecutor,
|
|
1028
|
+
});
|
|
1160
1029
|
|
|
1161
1030
|
const checkpoints: CheckpointInfo[] = [];
|
|
1162
1031
|
const onCheckpoint = (checkpoint: CheckpointInfo): CheckpointDecision => {
|
|
1163
1032
|
checkpoints.push(checkpoint);
|
|
1164
1033
|
// Yield on turn 3 (0-indexed)
|
|
1165
|
-
return checkpoint.turnIndex === 3 ? "
|
|
1034
|
+
return checkpoint.turnIndex === 3 ? "budget" : "continue";
|
|
1166
1035
|
};
|
|
1167
1036
|
|
|
1168
1037
|
const events: AgentEvent[] = [];
|
|
1169
|
-
const history = await loop.run(
|
|
1170
|
-
[userMessage],
|
|
1171
|
-
collectEvents(events),
|
|
1172
|
-
undefined,
|
|
1173
|
-
undefined,
|
|
1038
|
+
const { history } = await loop.run([userMessage], collectEvents(events), {
|
|
1174
1039
|
onCheckpoint,
|
|
1175
|
-
);
|
|
1040
|
+
});
|
|
1176
1041
|
|
|
1177
1042
|
// Turns 0, 1, 2, 3 execute (4 provider calls). Turn 3 yields, so turns 4+ never execute.
|
|
1178
1043
|
expect(calls).toHaveLength(4);
|
|
@@ -1226,26 +1091,19 @@ describe("AgentLoop", () => {
|
|
|
1226
1091
|
]);
|
|
1227
1092
|
|
|
1228
1093
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
1229
|
-
const loop = new AgentLoop(
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
dummyTools,
|
|
1234
|
-
toolExecutor,
|
|
1235
|
-
);
|
|
1094
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1095
|
+
tools: dummyTools,
|
|
1096
|
+
toolExecutor: toolExecutor,
|
|
1097
|
+
});
|
|
1236
1098
|
|
|
1237
1099
|
const onCheckpoint = (checkpoint: CheckpointInfo): CheckpointDecision => {
|
|
1238
1100
|
// Yield on the second turn (turnIndex 1)
|
|
1239
|
-
return checkpoint.turnIndex === 1 ? "
|
|
1101
|
+
return checkpoint.turnIndex === 1 ? "budget" : "continue";
|
|
1240
1102
|
};
|
|
1241
1103
|
|
|
1242
|
-
const history = await loop.run(
|
|
1243
|
-
[userMessage],
|
|
1244
|
-
() => {},
|
|
1245
|
-
undefined,
|
|
1246
|
-
undefined,
|
|
1104
|
+
const { history } = await loop.run([userMessage], () => {}, {
|
|
1247
1105
|
onCheckpoint,
|
|
1248
|
-
);
|
|
1106
|
+
});
|
|
1249
1107
|
|
|
1250
1108
|
// 2 provider calls: first tool turn + second tool turn (yield after second)
|
|
1251
1109
|
expect(calls).toHaveLength(2);
|
|
@@ -1260,7 +1118,7 @@ describe("AgentLoop", () => {
|
|
|
1260
1118
|
// 25. Without resolveTools, static tools are used
|
|
1261
1119
|
test("without resolveTools, static tools are passed to provider", async () => {
|
|
1262
1120
|
const { provider, calls } = createMockProvider([textResponse("Hi")]);
|
|
1263
|
-
const loop = new AgentLoop(provider, "system", {
|
|
1121
|
+
const loop = new AgentLoop(provider, "system", { tools: dummyTools });
|
|
1264
1122
|
|
|
1265
1123
|
await loop.run([userMessage], () => {});
|
|
1266
1124
|
|
|
@@ -1293,14 +1151,10 @@ describe("AgentLoop", () => {
|
|
|
1293
1151
|
return resolvedTools;
|
|
1294
1152
|
};
|
|
1295
1153
|
|
|
1296
|
-
const loop = new AgentLoop(
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
[],
|
|
1301
|
-
toolExecutor,
|
|
1302
|
-
resolveTools,
|
|
1303
|
-
);
|
|
1154
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1155
|
+
toolExecutor: toolExecutor,
|
|
1156
|
+
resolveTools: resolveTools,
|
|
1157
|
+
});
|
|
1304
1158
|
await loop.run([userMessage], () => {});
|
|
1305
1159
|
|
|
1306
1160
|
// resolveTools should be called once per provider turn (2 turns total)
|
|
@@ -1329,14 +1183,10 @@ describe("AgentLoop", () => {
|
|
|
1329
1183
|
const resolveTools = (): ToolDefinition[] => dynamicTools;
|
|
1330
1184
|
|
|
1331
1185
|
// Pass different static tools to verify they are overridden
|
|
1332
|
-
const loop = new AgentLoop(
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
dummyTools,
|
|
1337
|
-
undefined,
|
|
1338
|
-
resolveTools,
|
|
1339
|
-
);
|
|
1186
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1187
|
+
tools: dummyTools,
|
|
1188
|
+
resolveTools: resolveTools,
|
|
1189
|
+
});
|
|
1340
1190
|
await loop.run([userMessage], () => {});
|
|
1341
1191
|
|
|
1342
1192
|
// Provider should receive the dynamically resolved tools, not the static ones
|
|
@@ -1390,14 +1240,10 @@ describe("AgentLoop", () => {
|
|
|
1390
1240
|
]);
|
|
1391
1241
|
|
|
1392
1242
|
const toolExecutor = async () => ({ content: "ok", isError: false });
|
|
1393
|
-
const loop = new AgentLoop(
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
[],
|
|
1398
|
-
toolExecutor,
|
|
1399
|
-
resolveTools,
|
|
1400
|
-
);
|
|
1243
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1244
|
+
toolExecutor: toolExecutor,
|
|
1245
|
+
resolveTools: resolveTools,
|
|
1246
|
+
});
|
|
1401
1247
|
await loop.run([userMessage], () => {});
|
|
1402
1248
|
|
|
1403
1249
|
// Provider should have been called 3 times
|
|
@@ -1417,14 +1263,10 @@ describe("AgentLoop", () => {
|
|
|
1417
1263
|
textResponse("No tools available"),
|
|
1418
1264
|
]);
|
|
1419
1265
|
|
|
1420
|
-
const loop = new AgentLoop(
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
dummyTools,
|
|
1425
|
-
undefined,
|
|
1426
|
-
resolveTools,
|
|
1427
|
-
);
|
|
1266
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1267
|
+
tools: dummyTools,
|
|
1268
|
+
resolveTools: resolveTools,
|
|
1269
|
+
});
|
|
1428
1270
|
await loop.run([userMessage], () => {});
|
|
1429
1271
|
|
|
1430
1272
|
// Empty array should result in undefined tools (same as no-tools behavior)
|
|
@@ -1449,15 +1291,13 @@ describe("AgentLoop", () => {
|
|
|
1449
1291
|
return { content: largeContent, isError: false };
|
|
1450
1292
|
};
|
|
1451
1293
|
|
|
1452
|
-
const loop = new AgentLoop(
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
toolExecutor,
|
|
1458
|
-
);
|
|
1294
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1295
|
+
config: { maxInputTokens: 180_000 },
|
|
1296
|
+
tools: dummyTools,
|
|
1297
|
+
toolExecutor: toolExecutor,
|
|
1298
|
+
});
|
|
1459
1299
|
const events: AgentEvent[] = [];
|
|
1460
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
1300
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
1461
1301
|
|
|
1462
1302
|
// The tool result user message is at index 2 in history
|
|
1463
1303
|
const toolResultMsg = history[2];
|
|
@@ -1500,15 +1340,13 @@ describe("AgentLoop", () => {
|
|
|
1500
1340
|
return { content: smallContent, isError: false };
|
|
1501
1341
|
};
|
|
1502
1342
|
|
|
1503
|
-
const loop = new AgentLoop(
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
toolExecutor,
|
|
1509
|
-
);
|
|
1343
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1344
|
+
config: { maxInputTokens: 180_000 },
|
|
1345
|
+
tools: dummyTools,
|
|
1346
|
+
toolExecutor: toolExecutor,
|
|
1347
|
+
});
|
|
1510
1348
|
const events: AgentEvent[] = [];
|
|
1511
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
1349
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
1512
1350
|
|
|
1513
1351
|
// The tool result user message is at index 2 in history
|
|
1514
1352
|
const toolResultMsg = history[2];
|
|
@@ -1560,15 +1398,12 @@ describe("AgentLoop", () => {
|
|
|
1560
1398
|
],
|
|
1561
1399
|
});
|
|
1562
1400
|
|
|
1563
|
-
const loop = new AgentLoop(
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
dummyTools,
|
|
1568
|
-
toolExecutor,
|
|
1569
|
-
);
|
|
1401
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1402
|
+
tools: dummyTools,
|
|
1403
|
+
toolExecutor: toolExecutor,
|
|
1404
|
+
});
|
|
1570
1405
|
const events: AgentEvent[] = [];
|
|
1571
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
1406
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
1572
1407
|
|
|
1573
1408
|
// The final assistant message in HISTORY should retain placeholders
|
|
1574
1409
|
// (so the model never sees real values on subsequent turns)
|
|
@@ -1629,13 +1464,10 @@ describe("AgentLoop", () => {
|
|
|
1629
1464
|
],
|
|
1630
1465
|
});
|
|
1631
1466
|
|
|
1632
|
-
const loop = new AgentLoop(
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
dummyTools,
|
|
1637
|
-
toolExecutor,
|
|
1638
|
-
);
|
|
1467
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1468
|
+
tools: dummyTools,
|
|
1469
|
+
toolExecutor: toolExecutor,
|
|
1470
|
+
});
|
|
1639
1471
|
const events: AgentEvent[] = [];
|
|
1640
1472
|
await loop.run([userMessage], collectEvents(events));
|
|
1641
1473
|
|
|
@@ -1664,15 +1496,12 @@ describe("AgentLoop", () => {
|
|
|
1664
1496
|
// No sensitiveBindings
|
|
1665
1497
|
});
|
|
1666
1498
|
|
|
1667
|
-
const loop = new AgentLoop(
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
dummyTools,
|
|
1672
|
-
toolExecutor,
|
|
1673
|
-
);
|
|
1499
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1500
|
+
tools: dummyTools,
|
|
1501
|
+
toolExecutor: toolExecutor,
|
|
1502
|
+
});
|
|
1674
1503
|
const events: AgentEvent[] = [];
|
|
1675
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
1504
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
1676
1505
|
|
|
1677
1506
|
const lastAssistant = history[history.length - 1];
|
|
1678
1507
|
const textBlock = lastAssistant.content.find(
|
|
@@ -1681,9 +1510,11 @@ describe("AgentLoop", () => {
|
|
|
1681
1510
|
expect(textBlock!.text).toBe("Normal response with no placeholders.");
|
|
1682
1511
|
});
|
|
1683
1512
|
|
|
1684
|
-
// Tool error retry
|
|
1685
|
-
//
|
|
1686
|
-
|
|
1513
|
+
// Tool error retry coaching — when a tool returns isError: true, the coaching
|
|
1514
|
+
// notice is appended as a separate text block in the tool-result user message
|
|
1515
|
+
// (not into the tool_result content), nudging the LLM to retry instead of
|
|
1516
|
+
// ending the turn while keeping the tool's actual output clean.
|
|
1517
|
+
test("appends retry coaching as a separate block when a tool returns an error", async () => {
|
|
1687
1518
|
const { provider, calls } = createMockProvider([
|
|
1688
1519
|
// First turn: LLM calls a tool that errors
|
|
1689
1520
|
toolUseResponse("t1", "read_file", { path: "/missing.txt" }),
|
|
@@ -1709,19 +1540,17 @@ describe("AgentLoop", () => {
|
|
|
1709
1540
|
return { content: "file contents", isError: false };
|
|
1710
1541
|
};
|
|
1711
1542
|
|
|
1712
|
-
const loop = new AgentLoop(
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
dummyTools,
|
|
1717
|
-
toolExecutor,
|
|
1718
|
-
);
|
|
1543
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1544
|
+
tools: dummyTools,
|
|
1545
|
+
toolExecutor: toolExecutor,
|
|
1546
|
+
});
|
|
1719
1547
|
await loop.run([userMessage], () => {});
|
|
1720
1548
|
|
|
1721
1549
|
// Provider should have been called 3 times (error -> retry -> final text)
|
|
1722
1550
|
expect(calls).toHaveLength(3);
|
|
1723
1551
|
|
|
1724
|
-
// The second call's messages should
|
|
1552
|
+
// The second call's messages should carry the retry coaching as a separate
|
|
1553
|
+
// text block, with the tool_result's own content left untouched.
|
|
1725
1554
|
const secondCallMessages = calls[1].messages;
|
|
1726
1555
|
const toolResultMessage = secondCallMessages[secondCallMessages.length - 1];
|
|
1727
1556
|
expect(toolResultMessage.role).toBe("user");
|
|
@@ -1732,7 +1561,14 @@ describe("AgentLoop", () => {
|
|
|
1732
1561
|
);
|
|
1733
1562
|
expect(retryNudge).toBeDefined();
|
|
1734
1563
|
|
|
1735
|
-
// The
|
|
1564
|
+
// The errored tool_result itself stays the tool's actual output.
|
|
1565
|
+
const erroredToolResult = toolResultMessage.content.find(
|
|
1566
|
+
(b): b is Extract<ContentBlock, { type: "tool_result" }> =>
|
|
1567
|
+
b.type === "tool_result",
|
|
1568
|
+
);
|
|
1569
|
+
expect(erroredToolResult?.content).not.toContain("looks recoverable");
|
|
1570
|
+
|
|
1571
|
+
// The third call should NOT have the retry coaching (successful tool result)
|
|
1736
1572
|
const thirdCallMessages = calls[2].messages;
|
|
1737
1573
|
const thirdToolResultMessage =
|
|
1738
1574
|
thirdCallMessages[thirdCallMessages.length - 1];
|
|
@@ -1743,8 +1579,9 @@ describe("AgentLoop", () => {
|
|
|
1743
1579
|
expect(noRetryNudge).toBeUndefined();
|
|
1744
1580
|
});
|
|
1745
1581
|
|
|
1746
|
-
// Retry
|
|
1747
|
-
|
|
1582
|
+
// Retry coaching stops after a tool fails 3 times in a row — past that the
|
|
1583
|
+
// error is likely unrecoverable and further coaching only burns tokens.
|
|
1584
|
+
test("stops appending retry coaching after 3 consecutive failures of a tool", async () => {
|
|
1748
1585
|
const { provider, calls } = createMockProvider([
|
|
1749
1586
|
// 4 consecutive error turns, then final text
|
|
1750
1587
|
toolUseResponse("t1", "read_file", { path: "/a" }),
|
|
@@ -1761,34 +1598,29 @@ describe("AgentLoop", () => {
|
|
|
1761
1598
|
return { content: "service unavailable", isError: true };
|
|
1762
1599
|
};
|
|
1763
1600
|
|
|
1764
|
-
const loop = new AgentLoop(
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
dummyTools,
|
|
1769
|
-
toolExecutor,
|
|
1770
|
-
);
|
|
1601
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1602
|
+
tools: dummyTools,
|
|
1603
|
+
toolExecutor: toolExecutor,
|
|
1604
|
+
});
|
|
1771
1605
|
await loop.run([userMessage], () => {});
|
|
1772
1606
|
|
|
1773
1607
|
expect(calls).toHaveLength(5);
|
|
1774
1608
|
|
|
1775
|
-
// Helper to check if a call's last user message has the retry
|
|
1609
|
+
// Helper to check if a call's last user message has the retry coaching
|
|
1610
|
+
// (a separate text block, not part of the tool_result content).
|
|
1776
1611
|
const hasRetryNudge = (callIndex: number): boolean => {
|
|
1777
1612
|
const msgs = calls[callIndex].messages;
|
|
1778
1613
|
const lastMsg = msgs[msgs.length - 1];
|
|
1779
1614
|
return lastMsg.content.some(
|
|
1780
|
-
(b) =>
|
|
1781
|
-
b.type === "text" &&
|
|
1782
|
-
"text" in b &&
|
|
1783
|
-
(b as { text: string }).text.includes("looks recoverable"),
|
|
1615
|
+
(b) => b.type === "text" && b.text.includes("looks recoverable"),
|
|
1784
1616
|
);
|
|
1785
1617
|
};
|
|
1786
1618
|
|
|
1787
|
-
// Turns 1-3 should have the
|
|
1619
|
+
// Turns 1-3 should have the coaching
|
|
1788
1620
|
expect(hasRetryNudge(1)).toBe(true);
|
|
1789
1621
|
expect(hasRetryNudge(2)).toBe(true);
|
|
1790
1622
|
expect(hasRetryNudge(3)).toBe(true);
|
|
1791
|
-
// Turn 4 should NOT have the
|
|
1623
|
+
// Turn 4 should NOT have the coaching (exceeded limit)
|
|
1792
1624
|
expect(hasRetryNudge(4)).toBe(false);
|
|
1793
1625
|
});
|
|
1794
1626
|
|
|
@@ -1812,15 +1644,12 @@ describe("AgentLoop", () => {
|
|
|
1812
1644
|
isError: false,
|
|
1813
1645
|
});
|
|
1814
1646
|
|
|
1815
|
-
const loop = new AgentLoop(
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
dummyTools,
|
|
1820
|
-
toolExecutor,
|
|
1821
|
-
);
|
|
1647
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1648
|
+
tools: dummyTools,
|
|
1649
|
+
toolExecutor: toolExecutor,
|
|
1650
|
+
});
|
|
1822
1651
|
const events: AgentEvent[] = [];
|
|
1823
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
1652
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
1824
1653
|
|
|
1825
1654
|
// Provider should be called 3 times: initial, empty response, retry
|
|
1826
1655
|
expect(calls).toHaveLength(3);
|
|
@@ -1890,15 +1719,12 @@ describe("AgentLoop", () => {
|
|
|
1890
1719
|
isError: false,
|
|
1891
1720
|
});
|
|
1892
1721
|
|
|
1893
|
-
const loop = new AgentLoop(
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
dummyTools,
|
|
1898
|
-
toolExecutor,
|
|
1899
|
-
);
|
|
1722
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1723
|
+
tools: dummyTools,
|
|
1724
|
+
toolExecutor: toolExecutor,
|
|
1725
|
+
});
|
|
1900
1726
|
const events: AgentEvent[] = [];
|
|
1901
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
1727
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
1902
1728
|
|
|
1903
1729
|
// Provider called exactly 2 times: initial [text+tool_use], then empty.
|
|
1904
1730
|
// No third (retry) call because the prior turn had visible text.
|
|
@@ -1952,15 +1778,12 @@ describe("AgentLoop", () => {
|
|
|
1952
1778
|
isError: false,
|
|
1953
1779
|
});
|
|
1954
1780
|
|
|
1955
|
-
const loop = new AgentLoop(
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
dummyTools,
|
|
1960
|
-
toolExecutor,
|
|
1961
|
-
);
|
|
1781
|
+
const loop = new AgentLoop(provider, "system", {
|
|
1782
|
+
tools: dummyTools,
|
|
1783
|
+
toolExecutor: toolExecutor,
|
|
1784
|
+
});
|
|
1962
1785
|
const events: AgentEvent[] = [];
|
|
1963
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
1786
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
1964
1787
|
|
|
1965
1788
|
// Provider called 3 times: initial, empty, retry (also empty)
|
|
1966
1789
|
expect(calls).toHaveLength(3);
|
|
@@ -1991,7 +1814,7 @@ describe("AgentLoop", () => {
|
|
|
1991
1814
|
|
|
1992
1815
|
const loop = new AgentLoop(provider, "system");
|
|
1993
1816
|
const events: AgentEvent[] = [];
|
|
1994
|
-
const history = await loop.run([userMessage], collectEvents(events));
|
|
1817
|
+
const { history } = await loop.run([userMessage], collectEvents(events));
|
|
1995
1818
|
|
|
1996
1819
|
// Should NOT retry — this is the first turn with no tool use history
|
|
1997
1820
|
expect(calls).toHaveLength(1);
|
|
@@ -2005,14 +1828,7 @@ describe("AgentLoop", () => {
|
|
|
2005
1828
|
const { provider, calls } = createMockProvider([textResponse("ok")]);
|
|
2006
1829
|
|
|
2007
1830
|
const loop = new AgentLoop(provider, "system");
|
|
2008
|
-
await loop.run(
|
|
2009
|
-
[userMessage],
|
|
2010
|
-
() => {},
|
|
2011
|
-
undefined, // signal
|
|
2012
|
-
undefined, // requestId
|
|
2013
|
-
undefined, // onCheckpoint
|
|
2014
|
-
"heartbeatAgent",
|
|
2015
|
-
);
|
|
1831
|
+
await loop.run([userMessage], () => {}, { callSite: "heartbeatAgent" });
|
|
2016
1832
|
|
|
2017
1833
|
expect(calls).toHaveLength(1);
|
|
2018
1834
|
expect(calls[0].options?.config?.callSite).toBe("heartbeatAgent");
|