@vellumai/assistant 0.8.5 → 0.8.7
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 +33 -1
- package/ARCHITECTURE.md +1 -1
- package/Dockerfile +1 -0
- package/bun.lock +11 -2
- package/bunfig.toml +6 -1
- package/docker-entrypoint.sh +8 -6
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +67 -31
- package/examples/plugins/echo/register.ts +4 -7
- 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 +15 -17
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +10 -3
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +5585 -469
- package/package.json +7 -3
- package/scripts/generate-openapi.ts +20 -13
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
- package/src/__tests__/agent-loop-exit-reason.test.ts +336 -42
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +21 -33
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +6 -4
- package/src/__tests__/agent-loop-thinking.test.ts +17 -12
- package/src/__tests__/agent-loop.test.ts +207 -341
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +5 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +23 -40
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/annotate-risk-options.test.ts +1 -0
- package/src/__tests__/anthropic-provider.test.ts +201 -55
- package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
- package/src/__tests__/app-control-flow.test.ts +5 -0
- package/src/__tests__/approval-cascade.test.ts +5 -11
- package/src/__tests__/approval-routes-http.test.ts +13 -15
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-event.test.ts +15 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -27
- package/src/__tests__/audit-log-rotation.test.ts +2 -2
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- 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 +5 -8
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +10 -14
- package/src/__tests__/call-controller.test.ts +3 -2
- 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 +51 -22
- package/src/__tests__/channel-approvals.test.ts +3 -1
- package/src/__tests__/channel-guardian.test.ts +3 -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 +170 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +388 -79
- package/src/__tests__/checker.test.ts +12 -12
- package/src/__tests__/circuit-breaker-pipeline.test.ts +3 -3
- package/src/__tests__/clawhub-files.test.ts +1 -0
- package/src/__tests__/compaction-events.test.ts +6 -17
- package/src/__tests__/compaction-pipeline.test.ts +1 -1
- package/src/__tests__/compaction-timeout-recovery.test.ts +37 -48
- package/src/__tests__/compaction-trail-store.test.ts +186 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +1 -0
- package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +7 -5
- package/src/__tests__/computer-use-tools.test.ts +14 -16
- package/src/__tests__/config-loader-backfill.test.ts +13 -28
- package/src/__tests__/config-loader-corrupt.test.ts +5 -5
- package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
- package/src/__tests__/config-schema.test.ts +10 -10
- package/src/__tests__/config-watcher.test.ts +28 -0
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-search-agent-runner.test.ts +6 -3
- package/src/__tests__/context-token-estimator.test.ts +56 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +19 -7
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +4 -2
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -27
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +464 -90
- package/src/__tests__/conversation-agent-loop.test.ts +1069 -64
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -3
- package/src/__tests__/conversation-app-control-instantiation.test.ts +29 -19
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +2 -1
- package/src/__tests__/conversation-attention-store.test.ts +101 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
- package/src/__tests__/conversation-clear-safety.test.ts +20 -10
- package/src/__tests__/conversation-confirmation-signals.test.ts +16 -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-error.test.ts +30 -0
- package/src/__tests__/conversation-fork-crud.test.ts +132 -157
- package/src/__tests__/conversation-fork-route.test.ts +19 -16
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
- package/src/__tests__/conversation-lifecycle.test.ts +4 -2
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +5 -3
- package/src/__tests__/conversation-load-history-stripped.test.ts +2 -1
- package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
- package/src/__tests__/conversation-pairing.test.ts +87 -4
- package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +30 -7
- package/src/__tests__/conversation-process-callsite.test.ts +28 -30
- package/src/__tests__/conversation-provider-retry-repair.test.ts +58 -44
- package/src/__tests__/conversation-queue.test.ts +603 -455
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -20
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +35 -10
- package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -4
- package/src/__tests__/conversation-runtime-assembly.test.ts +98 -22
- package/src/__tests__/conversation-runtime-workspace.test.ts +19 -1
- package/src/__tests__/conversation-skill-tools.test.ts +38 -142
- package/src/__tests__/conversation-slash-queue.test.ts +120 -62
- package/src/__tests__/conversation-slash-unknown.test.ts +18 -15
- package/src/__tests__/conversation-speed-override.test.ts +9 -22
- package/src/__tests__/conversation-stream-state.test.ts +484 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +52 -15
- package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
- package/src/__tests__/conversation-surfaces-table-action.test.ts +13 -32
- package/src/__tests__/conversation-sync-tags.test.ts +128 -12
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +53 -11
- package/src/__tests__/conversation-unread-route.test.ts +14 -2
- package/src/__tests__/conversation-usage.test.ts +1 -2
- package/src/__tests__/conversation-wipe.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +4 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +53 -22
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +32 -7
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +10 -12
- package/src/__tests__/credential-execution-tools.test.ts +1 -2
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/credential-vault-unit.test.ts +19 -19
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +61 -3
- package/src/__tests__/cu-unified-flow.test.ts +26 -1
- package/src/__tests__/db-connection-isolation.test.ts +7 -6
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
- package/src/__tests__/db-schedule-syntax-migration.test.ts +11 -0
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +119 -36
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +9 -35
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +33 -42
- package/src/__tests__/document-create-dedupe.test.ts +189 -0
- package/src/__tests__/document-find-replace.test.ts +3 -2
- package/src/__tests__/document-tool-security.test.ts +81 -2
- package/src/__tests__/dynamic-page-surface.test.ts +68 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/edit-propagation.test.ts +1 -2
- package/src/__tests__/empty-response-pipeline.test.ts +127 -5
- package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
- package/src/__tests__/encrypted-store.test.ts +11 -9
- package/src/__tests__/feature-flag-test-helpers.ts +53 -0
- package/src/__tests__/filing-service.test.ts +3 -2
- package/src/__tests__/first-greeting.test.ts +103 -12
- package/src/__tests__/gateway-flag-listener.test.ts +0 -1
- package/src/__tests__/gemini-inline-media.test.ts +78 -0
- package/src/__tests__/gemini-provider.test.ts +375 -26
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-outbound-http.test.ts +3 -2
- package/src/__tests__/guardian-routing-state.test.ts +60 -71
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +10 -7
- package/src/__tests__/heartbeat-disk-pressure.test.ts +2 -0
- package/src/__tests__/heartbeat-service.test.ts +3 -1
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/history-repair-hook.test.ts +161 -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-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-proxy.test.ts +2 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- 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-routes-targeted.test.ts +1 -0
- 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 +11 -5
- package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +31 -9
- package/src/__tests__/identity-intro-cache.test.ts +154 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +51 -74
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/injector-background-turn.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-disk-pressure.test.ts +4 -18
- package/src/__tests__/injector-document-comments.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
- package/src/__tests__/injector-v3-suppression.test.ts +220 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-attachments.test.ts +7 -8
- package/src/__tests__/list-messages-hidden-metadata.test.ts +93 -11
- package/src/__tests__/list-messages-page-latest.test.ts +0 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +36 -6
- package/src/__tests__/llm-call-pipeline.test.ts +21 -15
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
- package/src/__tests__/llm-resolver.test.ts +346 -39
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/llm-usage-store.test.ts +45 -0
- package/src/__tests__/log-export-routes.test.ts +59 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +14 -0
- package/src/__tests__/mcp-auth-routes.test.ts +15 -10
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/mcp-health-check.test.ts +18 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +1 -1
- package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +9 -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-from-url.test.ts +3 -3
- package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +3 -3
- package/src/__tests__/native-web-search.test.ts +44 -22
- package/src/__tests__/notification-decision-identity.test.ts +9 -18
- package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/oauth-commands-routes.test.ts +38 -1
- package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
- package/src/__tests__/oauth-store.test.ts +3 -2
- package/src/__tests__/onboarding-template-contract.test.ts +13 -2
- package/src/__tests__/openai-provider.test.ts +74 -79
- package/src/__tests__/openai-responses-provider.test.ts +90 -86
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +48 -2
- package/src/__tests__/overflow-reduce-pipeline.test.ts +2 -4
- package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
- package/src/__tests__/persistence-pipeline.test.ts +154 -27
- package/src/__tests__/persistence-secret-redaction.test.ts +85 -13
- package/src/__tests__/pipeline-runner.test.ts +2 -3
- package/src/__tests__/plugin-bootstrap.test.ts +60 -36
- 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 +51 -64
- package/src/__tests__/plugin-types.test.ts +7 -14
- package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
- package/src/__tests__/process-message-background-slack.test.ts +38 -32
- package/src/__tests__/process-message-display-content.test.ts +49 -64
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- 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 +215 -8
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- 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__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +82 -76
- package/src/__tests__/relay-server.test.ts +30 -23
- 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-attachment-metadata.test.ts +3 -2
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +353 -0
- package/src/__tests__/schedule-routes.test.ts +80 -10
- package/src/__tests__/schedule-store.test.ts +83 -1
- package/src/__tests__/schedule-tools.test.ts +125 -0
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +7 -3
- 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__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +83 -43
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/shell-observability.test.ts +249 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +19 -21
- package/src/__tests__/skill-feature-flags.test.ts +20 -22
- package/src/__tests__/skill-load-feature-flag.test.ts +15 -15
- package/src/__tests__/skill-projection-feature-flag.test.ts +44 -30
- package/src/__tests__/skill-projection.benchmark.test.ts +5 -7
- package/src/__tests__/skill-tool-factory.test.ts +96 -95
- package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
- package/src/__tests__/skillssh-files.test.ts +1 -0
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- 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 +13 -5
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +5 -4
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +4 -3
- package/src/__tests__/sync-message-contract.test.ts +19 -16
- package/src/__tests__/system-prompt.test.ts +92 -0
- package/src/__tests__/terminal-tools.test.ts +3 -24
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/thread-backfill.test.ts +4 -9
- package/src/__tests__/title-generate-pipeline.test.ts +1 -1
- package/src/__tests__/token-estimate-pipeline.test.ts +2 -4
- package/src/__tests__/tool-error-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execute-pipeline.test.ts +1 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +20 -7
- package/src/__tests__/tool-executor.test.ts +55 -10
- package/src/__tests__/tool-preview-lifecycle.test.ts +14 -11
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +9 -12
- package/src/__tests__/tool-result-truncation.test.ts +3 -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__/twilio-routes.test.ts +3 -2
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +10 -7
- package/src/__tests__/voice-session-bridge.test.ts +50 -35
- package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
- package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
- package/src/acp/prepare-agent-env.ts +52 -11
- package/src/acp/session-manager.ts +5 -6
- package/src/agent/compaction-circuit.ts +140 -0
- package/src/agent/loop.ts +489 -85
- package/src/api/README.md +126 -2
- package/src/api/constants/call-sites.ts +27 -0
- 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 +49 -0
- package/src/api/events/assistant-text-delta.ts +30 -0
- package/src/api/events/assistant-turn-start.ts +31 -0
- 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 +44 -0
- package/src/api/events/document-comment-deleted.ts +22 -0
- package/src/api/events/document-comment-reopened.ts +23 -0
- package/src/api/events/document-comment-resolved.ts +25 -0
- 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 +22 -0
- package/src/api/events/generation-handoff.ts +39 -0
- 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 +40 -0
- 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 +28 -0
- package/src/api/events/question-request.ts +67 -0
- package/src/{events → api/events}/relationship-state-updated.ts +6 -8
- 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-result.ts +129 -0
- package/src/api/events/tool-use-start.ts +30 -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 +482 -3
- package/src/api/requests/dictation.ts +45 -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 +41 -0
- package/src/api/responses/llm-request-log-entry.ts +93 -0
- package/src/api/responses/memory-recall-log.ts +65 -0
- package/src/api/responses/memory-v2-activation-log.ts +78 -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 +6 -9
- package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
- package/src/avatar/__tests__/avatar-store.test.ts +193 -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/background-wake-routes.test.ts +687 -52
- package/src/background-wake/next-wake.test.ts +31 -1
- package/src/background-wake/next-wake.ts +4 -1
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +2 -2
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/call-conversation-messages.ts +6 -4
- package/src/calls/guardian-action-sweep.ts +6 -4
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/relay-server.ts +12 -8
- package/src/calls/voice-session-bridge.ts +17 -31
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/avatar.ts +17 -11
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- 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 +168 -203
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/cli-colors.ts +24 -6
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +6 -5
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/assistant-feature-flags.ts +25 -44
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -3
- package/src/config/bundled-skills/document-editor/SKILL.md +5 -1
- package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +2 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +10 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/call-site-defaults.ts +3 -8
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +42 -26
- package/src/config/llm-context-resolution.ts +10 -1
- package/src/config/llm-resolver.ts +121 -15
- package/src/config/loader.ts +4 -5
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -211
- package/src/config/schemas/call-site-catalog.ts +8 -15
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +92 -4
- package/src/config/schemas/memory-lifecycle.ts +24 -0
- package/src/config/schemas/memory-v2.ts +0 -227
- package/src/config/schemas/memory-v3.ts +39 -0
- package/src/config/schemas/memory.ts +6 -1
- package/src/config/schemas/services.ts +6 -2
- package/src/config/schemas/timeouts.ts +3 -1
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/compactor.ts +54 -31
- package/src/context/token-estimator.ts +29 -5
- package/src/context/tool-result-truncation.ts +1 -43
- package/src/context/window-manager.ts +138 -20
- package/src/credential-execution/executable-discovery.ts +40 -0
- package/src/credential-execution/process-manager.ts +6 -2
- package/src/credential-health/credential-health-service.ts +125 -40
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +15 -17
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -2
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +11 -6
- package/src/daemon/approval-generators.ts +4 -4
- package/src/daemon/config-watcher.ts +7 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +613 -155
- package/src/daemon/conversation-agent-loop.ts +409 -605
- package/src/daemon/conversation-error.ts +40 -12
- package/src/daemon/conversation-history.ts +22 -6
- package/src/daemon/conversation-launch.ts +4 -8
- package/src/daemon/conversation-lifecycle.ts +10 -38
- package/src/daemon/conversation-messaging.ts +83 -44
- package/src/daemon/conversation-notifiers.ts +7 -5
- package/src/daemon/conversation-process.ts +174 -116
- package/src/daemon/conversation-runtime-assembly.ts +76 -30
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-store.ts +6 -5
- package/src/daemon/conversation-surfaces.ts +124 -103
- package/src/daemon/conversation-tool-setup.ts +36 -48
- package/src/daemon/conversation.ts +111 -166
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +7 -4
- package/src/daemon/disk-pressure-guard.ts +54 -50
- package/src/daemon/external-plugins-bootstrap.ts +46 -24
- package/src/daemon/first-greeting.ts +53 -13
- package/src/daemon/guardian-action-generators.ts +2 -2
- package/src/daemon/handlers/conversations.ts +6 -22
- package/src/daemon/handlers/shared.ts +10 -1
- package/src/daemon/handlers/skills.ts +15 -14
- 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 +40 -67
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +10 -17
- package/src/daemon/message-protocol.ts +2 -3
- package/src/daemon/message-provenance.ts +49 -0
- package/src/daemon/message-types/contacts.ts +3 -20
- package/src/daemon/message-types/conversations.ts +25 -125
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/documents.ts +3 -9
- package/src/daemon/message-types/home.ts +5 -18
- package/src/daemon/message-types/integrations.ts +4 -13
- package/src/daemon/message-types/messages.ts +47 -377
- 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 +2 -0
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/sync.ts +12 -25
- package/src/daemon/message-types/workspace.ts +3 -11
- package/src/daemon/process-message.ts +58 -55
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +28 -0
- package/src/daemon/switch-inference-profile-tool.ts +13 -3
- package/src/daemon/tool-setup-types.ts +0 -6
- package/src/daemon/tool-side-effects.ts +10 -7
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +21 -1
- package/src/documents/document-store.ts +38 -0
- package/src/export/__tests__/transcript-formatter.test.ts +1 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +31 -0
- package/src/heartbeat/heartbeat-run-store.ts +31 -0
- package/src/heartbeat/heartbeat-service.ts +79 -0
- package/src/home/__tests__/feed-writer.test.ts +161 -0
- package/src/home/__tests__/post-connect-feed.test.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +55 -59
- package/src/home/feature-gate.ts +22 -0
- package/src/home/feed-types.ts +36 -221
- package/src/home/feed-writer.ts +146 -7
- package/src/home/suggested-prompts.ts +27 -145
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/__tests__/email-ipc.test.ts +0 -9
- package/src/ipc/gateway-client.test.ts +4 -1
- 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 +19 -9
- package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
- package/src/ipc/skill-routes/__tests__/registries.test.ts +59 -20
- package/src/ipc/skill-routes/memory.ts +27 -13
- package/src/ipc/skill-routes/providers.ts +5 -6
- package/src/ipc/skill-routes/registries.ts +39 -88
- package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
- 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-enqueue-gate.test.ts +1 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +11 -6
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
- package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
- package/src/memory/context-search/agent-runner.ts +2 -4
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +386 -115
- package/src/memory/conversation-queries.ts +78 -22
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +12 -0
- package/src/memory/db-maintenance.ts +18 -2
- package/src/memory/db-singleton.ts +77 -0
- package/src/memory/delivery-channels.ts +82 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
- package/src/memory/graph/consolidation.ts +8 -11
- package/src/memory/graph/conversation-graph-memory.ts +41 -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.test.ts +3 -3
- package/src/memory/graph/retriever.ts +20 -26
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/job-handlers/conversation-starters.ts +32 -32
- package/src/memory/job-handlers/embedding.test.ts +3 -2
- package/src/memory/job-handlers/summarization.ts +1 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs-store.ts +3 -1
- package/src/memory/jobs-worker.ts +63 -40
- package/src/memory/llm-request-log-source-clickhouse.ts +55 -1
- package/src/memory/llm-request-log-source-local.ts +13 -0
- package/src/memory/llm-request-log-source.ts +21 -6
- package/src/memory/llm-request-log-store.ts +147 -3
- package/src/memory/llm-usage-store.ts +10 -0
- 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 +13 -1
- package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- 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/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/schema/conversations.ts +9 -1
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/schema/infrastructure.ts +11 -0
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/consolidation-job.test.ts +124 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +9 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +9 -4
- package/src/memory/v2/__tests__/harness-runner.test.ts +26 -0
- 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 +9 -5
- package/src/memory/v2/backfill-jobs.ts +6 -0
- package/src/memory/v2/consolidation-job.ts +89 -9
- package/src/memory/v2/harness/metrics.ts +5 -1
- package/src/memory/v2/harness/replay-input.ts +19 -3
- package/src/memory/v2/harness/runner.ts +6 -0
- package/src/memory/v2/harness/trace.ts +6 -0
- 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/memory/v3/__tests__/assign.test.ts +242 -0
- package/src/memory/v3/__tests__/capabilities.test.ts +118 -0
- package/src/memory/v3/__tests__/core.test.ts +39 -0
- package/src/memory/v3/__tests__/fixtures/eval-turns.json +36 -0
- package/src/memory/v3/__tests__/fixtures/live-turns.json +37 -0
- package/src/memory/v3/__tests__/health.test.ts +203 -0
- package/src/memory/v3/__tests__/live-integration.test.ts +330 -0
- package/src/memory/v3/__tests__/maintain-job.test.ts +288 -0
- package/src/memory/v3/__tests__/needle.test.ts +107 -0
- package/src/memory/v3/__tests__/orchestrate.test.ts +400 -0
- package/src/memory/v3/__tests__/reconcile.test.ts +274 -0
- package/src/memory/v3/__tests__/render-injection.test.ts +61 -0
- package/src/memory/v3/__tests__/router.test.ts +260 -0
- package/src/memory/v3/__tests__/selection-log-store.test.ts +179 -0
- package/src/memory/v3/__tests__/selector.test.ts +404 -0
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +414 -0
- package/src/memory/v3/__tests__/snapshot.test.ts +168 -0
- package/src/memory/v3/__tests__/tree.test.ts +192 -0
- package/src/memory/v3/__tests__/types.test.ts +54 -0
- package/src/memory/v3/__tests__/working-set-eviction.test.ts +106 -0
- package/src/memory/v3/__tests__/working-set-skeleton.test.ts +44 -0
- package/src/memory/v3/assign.ts +268 -0
- package/src/memory/v3/capabilities.ts +124 -0
- package/src/memory/v3/core.ts +26 -0
- package/src/memory/v3/data/README.md +84 -0
- package/src/memory/v3/data/assignments.json +5 -0
- package/src/memory/v3/data/core.json +1 -0
- package/src/memory/v3/data/leaves/domain-a/topic-x.md +9 -0
- package/src/memory/v3/data/leaves/domain-a/topic-y.md +9 -0
- package/src/memory/v3/data/leaves/domain-b/topic-z.md +9 -0
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +314 -0
- package/src/memory/v3/needle.ts +115 -0
- package/src/memory/v3/orchestrate.ts +114 -0
- package/src/memory/v3/page-content.ts +34 -0
- package/src/memory/v3/provider-blocks.ts +16 -0
- package/src/memory/v3/reconcile.ts +523 -0
- package/src/memory/v3/render-injection.ts +32 -0
- package/src/memory/v3/router.ts +184 -0
- package/src/memory/v3/selection-log-store.ts +84 -0
- package/src/memory/v3/selector.ts +211 -0
- package/src/memory/v3/shadow-plugin.ts +379 -0
- package/src/memory/v3/snapshot.ts +209 -0
- package/src/memory/v3/tree.ts +174 -0
- package/src/memory/v3/types.ts +46 -60
- package/src/memory/v3/working-set.ts +88 -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/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +30 -8
- package/src/notifications/decision-engine.ts +10 -13
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +11 -1
- package/src/notifications/preference-extractor.ts +11 -14
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +37 -0
- package/src/oauth/byo-connection.test.ts +67 -3
- package/src/oauth/byo-connection.ts +32 -5
- package/src/oauth/connect-orchestrator.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +76 -0
- package/src/oauth/connection-resolver.ts +49 -10
- package/src/oauth/manual-token-connection.ts +51 -3
- package/src/oauth/seed-providers.ts +3 -0
- package/src/permissions/approval-policy.test.ts +19 -5
- package/src/permissions/approval-policy.ts +14 -3
- package/src/permissions/checker.ts +21 -8
- package/src/permissions/prompter.ts +42 -36
- package/src/permissions/question-prompter.test.ts +35 -26
- package/src/permissions/question-prompter.ts +6 -10
- package/src/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- package/src/plugin-api/index.ts +2 -0
- package/src/plugin-api/types.ts +25 -3
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
- package/src/plugins/defaults/circuit-breaker/package.json +15 -0
- package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
- package/src/plugins/defaults/compaction/package.json +15 -0
- package/src/plugins/defaults/compaction/register.ts +35 -0
- package/src/plugins/defaults/compaction/terminal.ts +73 -0
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +22 -0
- package/src/plugins/defaults/empty-response/package.json +15 -0
- package/src/plugins/defaults/empty-response/register.ts +28 -0
- package/src/plugins/defaults/empty-response/terminal.ts +106 -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 +29 -40
- package/src/plugins/defaults/injectors/package.json +15 -0
- package/src/plugins/defaults/{injectors.ts → injectors/register.ts} +16 -46
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +17 -0
- package/src/plugins/defaults/llm-call/package.json +15 -0
- package/src/plugins/defaults/{llm-call.ts → llm-call/register.ts} +6 -38
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +17 -0
- package/src/plugins/defaults/memory-retrieval/package.json +15 -0
- package/src/plugins/defaults/{memory-retrieval.ts → memory-retrieval/register.ts} +10 -48
- package/src/plugins/defaults/{overflow-reduce.ts → overflow-reduce/middlewares/overflowReduce.ts} +18 -77
- package/src/plugins/defaults/overflow-reduce/package.json +15 -0
- package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
- package/src/plugins/defaults/persistence/middlewares/persistence.ts +19 -0
- package/src/plugins/defaults/persistence/package.json +15 -0
- package/src/plugins/defaults/persistence/register.ts +38 -0
- package/src/plugins/defaults/persistence/terminal.ts +83 -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/title-generate/terminal.ts +31 -0
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +23 -0
- package/src/plugins/defaults/token-estimate/package.json +15 -0
- package/src/plugins/defaults/token-estimate/register.ts +34 -0
- package/src/plugins/defaults/token-estimate/terminal.ts +40 -0
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +21 -0
- package/src/plugins/defaults/tool-error/package.json +15 -0
- package/src/plugins/defaults/tool-error/register.ts +35 -0
- package/src/plugins/defaults/tool-error/terminal.ts +47 -0
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +23 -0
- package/src/plugins/defaults/tool-execute/package.json +15 -0
- package/src/plugins/defaults/{tool-execute.ts → tool-execute/register.ts} +8 -46
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +23 -0
- package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +35 -0
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +113 -0
- package/src/plugins/defaults/tool-result-truncate/types.ts +22 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/pipeline.ts +0 -12
- package/src/plugins/types.ts +107 -102
- package/src/plugins/user-loader.ts +4 -3
- package/src/proactive-artifact/aux-message-injector.ts +0 -1
- package/src/proactive-artifact/job.test.ts +21 -8
- package/src/proactive-artifact/job.ts +3 -1
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/sections.ts +20 -7
- package/src/prompts/system-prompt.ts +38 -40
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
- package/src/prompts/templates/BOOTSTRAP.md +10 -10
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/prompts/templates/system-sections.ts +6 -0
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -4
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -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 +24 -5
- package/src/providers/call-site-routing.ts +34 -18
- package/src/providers/connection-model-compat.ts +23 -0
- package/src/providers/connection-resolution.ts +39 -20
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +176 -37
- package/src/providers/gemini/inline-media.ts +74 -0
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/model-catalog.ts +35 -1
- package/src/providers/model-intents.ts +3 -3
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -7
- package/src/providers/openai/chat-completions-provider.ts +111 -16
- package/src/providers/openai/codex-models.ts +2 -0
- package/src/providers/openai/responses-provider.ts +54 -57
- package/src/providers/openrouter/client.ts +14 -14
- package/src/providers/provider-send-message.ts +23 -14
- package/src/providers/ratelimit.ts +1 -9
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +16 -9
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/types.ts +20 -2
- package/src/providers/usage-tracking.ts +1 -9
- package/src/runtime/__tests__/agent-wake.test.ts +132 -26
- package/src/runtime/__tests__/background-job-runner.test.ts +2 -3
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/agent-wake.ts +93 -18
- package/src/runtime/assistant-event-hub.ts +2 -2
- 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 -1069
- package/src/runtime/background-job-runner.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -1
- package/src/runtime/channel-approvals.ts +3 -14
- package/src/runtime/channel-invite-transport.ts +5 -6
- package/src/runtime/channel-readiness-service.ts +70 -5
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +59 -30
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/conversation-stream-state.ts +294 -0
- package/src/runtime/http-router.ts +19 -22
- package/src/runtime/http-types.ts +12 -6
- package/src/runtime/invite-instruction-generator.ts +3 -3
- package/src/runtime/migrations/vbundle-builder.ts +3 -2
- package/src/runtime/pending-interactions.ts +2 -2
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +436 -0
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +26 -72
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +58 -5
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- 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-content-routes.test.ts +294 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
- package/src/runtime/routes/__tests__/tts-routes.test.ts +3 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/acp-routes.test.ts +97 -75
- package/src/runtime/routes/acp-routes.ts +29 -6
- package/src/runtime/routes/app-management-routes.ts +208 -28
- package/src/runtime/routes/app-routes.ts +25 -5
- package/src/runtime/routes/approval-routes.ts +16 -4
- package/src/runtime/routes/attachment-routes.ts +25 -1
- 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 +238 -59
- package/src/runtime/routes/background-tool-routes.ts +9 -0
- package/src/runtime/routes/background-wake-routes.ts +201 -23
- 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 +5 -0
- package/src/runtime/routes/browser-tabs-routes.ts +5 -0
- package/src/runtime/routes/btw-routes.ts +9 -5
- 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 +13 -5
- 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 +11 -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 +292 -0
- package/src/runtime/routes/conversation-list-routes.ts +225 -9
- package/src/runtime/routes/conversation-management-routes.ts +96 -28
- package/src/runtime/routes/conversation-query-routes.ts +148 -51
- package/src/runtime/routes/conversation-routes.ts +259 -158
- package/src/runtime/routes/conversation-starter-routes.ts +22 -13
- package/src/runtime/routes/conversations-import-routes.ts +25 -7
- 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 +31 -11
- package/src/runtime/routes/domain-routes.ts +61 -28
- package/src/runtime/routes/email-routes.ts +33 -0
- package/src/runtime/routes/events-routes.ts +114 -9
- package/src/runtime/routes/filing-routes.ts +9 -4
- package/src/runtime/routes/gateway-log-routes.ts +5 -0
- package/src/runtime/routes/global-search-routes.ts +53 -50
- package/src/runtime/routes/group-routes.ts +32 -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 +25 -9
- package/src/runtime/routes/home-feed-routes.ts +149 -16
- package/src/runtime/routes/home-state-routes.ts +8 -40
- package/src/runtime/routes/host-app-control-routes.ts +5 -0
- 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 +5 -0
- 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 +72 -16
- package/src/runtime/routes/identity-routes.ts +42 -11
- package/src/runtime/routes/image-generation-routes.ts +5 -0
- package/src/runtime/routes/inbound-message-handler.ts +15 -11
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +524 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +72 -27
- 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 +26 -31
- package/src/runtime/routes/inference-send-routes.ts +11 -11
- package/src/runtime/routes/integrations/a2a.ts +30 -7
- package/src/runtime/routes/integrations/slack/channel.ts +19 -3
- package/src/runtime/routes/integrations/slack/share.ts +9 -2
- package/src/runtime/routes/integrations/telegram.ts +28 -9
- package/src/runtime/routes/integrations/twilio.ts +35 -7
- package/src/runtime/routes/integrations/vercel.ts +18 -3
- package/src/runtime/routes/internal-oauth-routes.ts +5 -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/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/log-export-routes.ts +28 -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 +90 -36
- package/src/runtime/routes/memory-v3-routes.ts +283 -259
- package/src/runtime/routes/migration-rollback-routes.ts +5 -1
- package/src/runtime/routes/migration-routes.ts +49 -13
- package/src/runtime/routes/notification-routes.ts +80 -2
- package/src/runtime/routes/oauth-apps.ts +33 -11
- package/src/runtime/routes/oauth-commands-routes.ts +43 -15
- 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 +35 -10
- package/src/runtime/routes/platform-routes.ts +21 -0
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +3 -2
- 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 +1 -1
- package/src/runtime/routes/playground/helpers.ts +0 -1
- 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 +5 -0
- package/src/runtime/routes/sanity-routes.ts +9 -2
- package/src/runtime/routes/schedule-routes.ts +137 -47
- package/src/runtime/routes/secret-routes.ts +17 -4
- 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 +133 -69
- 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 +10 -38
- package/src/runtime/routes/surface-content-routes.ts +21 -6
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/task-routes.ts +37 -0
- package/src/runtime/routes/telemetry-routes.ts +9 -0
- package/src/runtime/routes/trace-event-routes.ts +42 -1
- package/src/runtime/routes/trust-rules-routes.ts +5 -0
- package/src/runtime/routes/tts-routes.ts +13 -6
- package/src/runtime/routes/types.ts +17 -8
- 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 +71 -3
- 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 +9 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +8 -0
- package/src/runtime/routes/work-items-routes.ts +47 -19
- 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 +120 -9
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +4 -4
- package/src/runtime/services/analyze-conversation.ts +3 -6
- package/src/runtime/services/conversation-serializer.ts +24 -2
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- package/src/runtime/sync/resource-sync-events.ts +17 -3
- package/src/runtime/sync/sync-publisher.ts +2 -2
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- package/src/schedule/run-script.ts +28 -3
- package/src/schedule/schedule-store.ts +16 -1
- package/src/schedule/scheduler.ts +114 -16
- package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
- package/src/security/encrypted-store.ts +7 -16
- package/src/security/store-path-override.ts +61 -0
- package/src/signals/user-message.ts +10 -16
- package/src/skills/catalog-files.ts +4 -1
- package/src/skills/clawhub-files.ts +2 -0
- package/src/skills/skillssh-files.ts +2 -0
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +16 -19
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -2
- package/src/telemetry/types.ts +26 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +138 -1
- package/src/telemetry/usage-telemetry-reporter.ts +31 -0
- package/src/tools/acp/spawn.test.ts +88 -38
- package/src/tools/apps/definitions.ts +42 -24
- 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/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/computer-use/definitions.ts +295 -289
- 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/document/document-tool.ts +131 -8
- package/src/tools/execution-target.ts +3 -6
- package/src/tools/execution-timeout.ts +3 -4
- package/src/tools/executor.ts +18 -55
- 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 +34 -31
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/edit.ts +44 -42
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/read.ts +49 -35
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/transfer.ts +121 -108
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/host-filesystem/write.ts +33 -31
- package/src/tools/host-terminal/host-shell.ts +50 -48
- package/src/tools/mcp/mcp-tool-factory.ts +0 -2
- package/src/tools/memory/register.ts +23 -24
- package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
- package/src/tools/network/__tests__/web-search.test.ts +211 -3
- package/src/tools/network/managed-search-proxy.ts +183 -0
- package/src/tools/network/web-fetch.ts +49 -46
- package/src/tools/network/web-search.ts +215 -57
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +184 -118
- package/src/tools/schedule/create.ts +12 -1
- 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/skills/skill-tool-factory.ts +17 -36
- package/src/tools/subagent/notify-parent.ts +35 -32
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/system/avatar-generator.ts +13 -22
- package/src/tools/system/request-permission.ts +30 -27
- package/src/tools/terminal/shell.ts +190 -61
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-defaults.ts +20 -9
- package/src/tools/tool-manifest.ts +4 -4
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +86 -33
- package/src/tools/ui-surface/definitions.ts +166 -94
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/usage/types.ts +10 -0
- package/src/util/browser.ts +7 -2
- package/src/util/errors.ts +2 -2
- package/src/util/map-limit.ts +27 -0
- package/src/util/platform.ts +15 -12
- package/src/work-items/work-item-runner.ts +7 -2
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
- package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
- package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
- 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/__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 +10 -0
- package/src/workspace/provider-commit-message-generator.ts +15 -17
- package/tsconfig.json +4 -1
- package/src/__tests__/history-repair-pipeline.test.ts +0 -396
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
- package/src/cli/commands/memory-v3-render.ts +0 -344
- package/src/daemon/message-types/disk-pressure.ts +0 -9
- package/src/email/feature-gate.ts +0 -23
- package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
- package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -468
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
- package/src/memory/v3/__tests__/edges.test.ts +0 -563
- package/src/memory/v3/__tests__/filter.test.ts +0 -512
- package/src/memory/v3/__tests__/gate.test.ts +0 -574
- package/src/memory/v3/__tests__/index-composition.test.ts +0 -233
- package/src/memory/v3/__tests__/loop.test.ts +0 -530
- package/src/memory/v3/__tests__/retriever.test.ts +0 -226
- package/src/memory/v3/__tests__/scouts.test.ts +0 -440
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -312
- package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
- package/src/memory/v3/__tests__/traversal.test.ts +0 -469
- 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 -707
- package/src/memory/v3/__tests__/validate.test.ts +0 -245
- 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/edge-learning-job.ts +0 -160
- package/src/memory/v3/edges.ts +0 -249
- package/src/memory/v3/filter.ts +0 -281
- package/src/memory/v3/gate.ts +0 -334
- package/src/memory/v3/index-composition.ts +0 -113
- package/src/memory/v3/llm-capture.ts +0 -46
- package/src/memory/v3/loop.ts +0 -382
- 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 -420
- package/src/memory/v3/shadow-middleware.ts +0 -305
- package/src/memory/v3/traversal.ts +0 -206
- 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 -351
- package/src/memory/v3/validate.ts +0 -300
- 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/persistence.ts +0 -127
- 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-result-truncate.ts +0 -84
package/src/agent/loop.ts
CHANGED
|
@@ -7,23 +7,34 @@ import {
|
|
|
7
7
|
getCalibrationProviderKey,
|
|
8
8
|
} from "../context/token-estimator.js";
|
|
9
9
|
import { calculateMaxToolResultChars } from "../context/tool-result-truncation.js";
|
|
10
|
+
import type { ContextWindowResult } from "../context/window-manager.js";
|
|
10
11
|
import type { ToolActivityMetadata } from "../daemon/message-types/web-activity.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { defaultCompactionTerminal } from "../plugins/defaults/compaction/terminal.js";
|
|
13
|
+
import { defaultEmptyResponseTerminal } from "../plugins/defaults/empty-response/terminal.js";
|
|
14
|
+
import { defaultTokenEstimateTerminal } from "../plugins/defaults/token-estimate/terminal.js";
|
|
15
|
+
import { defaultToolErrorTerminal } from "../plugins/defaults/tool-error/terminal.js";
|
|
16
|
+
import { defaultToolResultTruncateTerminal } from "../plugins/defaults/tool-result-truncate/terminal.js";
|
|
17
|
+
import type {
|
|
18
|
+
ToolResultTruncateArgs,
|
|
19
|
+
ToolResultTruncateResult,
|
|
20
|
+
} from "../plugins/defaults/tool-result-truncate/types.js";
|
|
14
21
|
import { DEFAULT_TIMEOUTS, runPipeline } from "../plugins/pipeline.js";
|
|
15
22
|
import { getMiddlewaresFor } from "../plugins/registry.js";
|
|
16
23
|
import type {
|
|
24
|
+
CompactionArgs,
|
|
25
|
+
CompactionCircuitEvent,
|
|
26
|
+
CompactionResult,
|
|
17
27
|
EmptyResponseArgs,
|
|
18
28
|
EmptyResponseDecision,
|
|
29
|
+
EstimateArgs,
|
|
30
|
+
EstimateResult,
|
|
19
31
|
LLMCallArgs,
|
|
20
32
|
LLMCallResult,
|
|
21
33
|
ToolErrorArgs,
|
|
22
34
|
ToolErrorDecision,
|
|
23
|
-
ToolResultTruncateArgs,
|
|
24
|
-
ToolResultTruncateResult,
|
|
25
35
|
TurnContext,
|
|
26
36
|
} from "../plugins/types.js";
|
|
37
|
+
import { PluginTimeoutError } from "../plugins/types.js";
|
|
27
38
|
import { normalizeThinkingConfigForWire } from "../providers/thinking-config.js";
|
|
28
39
|
import type {
|
|
29
40
|
ContentBlock,
|
|
@@ -40,9 +51,17 @@ import {
|
|
|
40
51
|
import { AssistantError, ErrorCode, ProviderError } from "../util/errors.js";
|
|
41
52
|
import { getLogger } from "../util/logger.js";
|
|
42
53
|
import { isRetryableNetworkError } from "../util/retry.js";
|
|
54
|
+
import { CompactionCircuit } from "./compaction-circuit.js";
|
|
43
55
|
|
|
44
56
|
const log = getLogger("agent-loop");
|
|
45
57
|
|
|
58
|
+
/** Fraction of the preflight budget at which a checkpoint triggers mid-loop compaction. */
|
|
59
|
+
const MID_LOOP_YIELD_THRESHOLD_RATIO = 0.85;
|
|
60
|
+
|
|
61
|
+
/** In-context message count above which the budget gate raises the safety-margin floor. */
|
|
62
|
+
const LONG_HISTORY_MESSAGE_THRESHOLD = 50;
|
|
63
|
+
const LONG_HISTORY_SAFETY_MARGIN_FLOOR = 0.15;
|
|
64
|
+
|
|
46
65
|
export interface AgentLoopConfig {
|
|
47
66
|
maxTokens: number;
|
|
48
67
|
maxInputTokens?: number; // context window size for tool result truncation
|
|
@@ -66,7 +85,28 @@ export interface CheckpointInfo {
|
|
|
66
85
|
history: Message[]; // current history snapshot for token estimation
|
|
67
86
|
}
|
|
68
87
|
|
|
69
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Why a checkpoint paused the loop. Surfaced back to the caller via
|
|
90
|
+
* {@link AgentLoopRunResult.exitReason} so the orchestrator reacts to
|
|
91
|
+
* the loop's own signal (hand off to a queued message vs. compact and
|
|
92
|
+
* re-enter) instead of the checkpoint callback mutating orchestrator state.
|
|
93
|
+
*/
|
|
94
|
+
export type ExitReason = "handoff" | "budget";
|
|
95
|
+
|
|
96
|
+
export type CheckpointDecision = "continue" | ExitReason;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Result of {@link AgentLoop.run}.
|
|
100
|
+
*
|
|
101
|
+
* `exitReason` carries the reason the loop paused at a checkpoint so the
|
|
102
|
+
* orchestrator reads the loop's own signal instead of inferring it from
|
|
103
|
+
* callback side-effects. It is `null` whenever the loop reached a terminal
|
|
104
|
+
* stop (completion, error, abort, or a tool-requested yield-to-user).
|
|
105
|
+
*/
|
|
106
|
+
export interface AgentLoopRunResult {
|
|
107
|
+
history: Message[];
|
|
108
|
+
exitReason: ExitReason | null;
|
|
109
|
+
}
|
|
70
110
|
|
|
71
111
|
/**
|
|
72
112
|
* Why an agent turn reached a terminal state.
|
|
@@ -111,6 +151,8 @@ export type AgentLoopExitReason =
|
|
|
111
151
|
* leaving `agent_loop_exit_reason` NULL.
|
|
112
152
|
*/
|
|
113
153
|
| "budget_yield_unrecovered"
|
|
154
|
+
/** Provider stopped because the configured output-token limit was reached. */
|
|
155
|
+
| "max_tokens_reached"
|
|
114
156
|
/** User cancellation landed after a non-terminal checkpoint yield. */
|
|
115
157
|
| "aborted_after_checkpoint"
|
|
116
158
|
/** Signal aborted while the catch handler was synthesizing an error turn. */
|
|
@@ -119,9 +161,19 @@ export type AgentLoopExitReason =
|
|
|
119
161
|
| "error";
|
|
120
162
|
|
|
121
163
|
export type AgentEvent =
|
|
164
|
+
/**
|
|
165
|
+
* Emitted once per LLM call inside the loop, immediately before the
|
|
166
|
+
* `provider.sendMessage` invocation. Carries the optional `callSite` tag so
|
|
167
|
+
* downstream handlers (the daemon's persistence pipeline) can decide
|
|
168
|
+
* whether to reserve a row for this call. One `llm_call_started` precedes
|
|
169
|
+
* every `message_complete` for the same call; multi-call agent turns emit
|
|
170
|
+
* one pair per call.
|
|
171
|
+
*/
|
|
172
|
+
| { type: "llm_call_started"; callSite?: LLMCallSite }
|
|
122
173
|
| { type: "text_delta"; text: string }
|
|
123
174
|
| { type: "thinking_delta"; thinking: string }
|
|
124
175
|
| { type: "message_complete"; message: Message }
|
|
176
|
+
| { type: "max_tokens_reached"; stopReason: string }
|
|
125
177
|
| {
|
|
126
178
|
type: "tool_use";
|
|
127
179
|
id: string;
|
|
@@ -234,6 +286,24 @@ export type AgentEvent =
|
|
|
234
286
|
*/
|
|
235
287
|
estimatedInputTokens?: number;
|
|
236
288
|
}
|
|
289
|
+
| {
|
|
290
|
+
/**
|
|
291
|
+
* Emitted when the loop begins compacting the running history because
|
|
292
|
+
* the mid-loop budget gate tripped. The daemon's event dispatcher
|
|
293
|
+
* translates it into a "compacting context" activity state so clients
|
|
294
|
+
* surface that the turn paused to summarize context.
|
|
295
|
+
*/
|
|
296
|
+
type: "context_compacting";
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Circuit-breaker transitions emitted when auto-compaction is paused
|
|
300
|
+
* (`compaction_circuit_open`, after three consecutive summary-LLM
|
|
301
|
+
* failures) or resumed (`compaction_circuit_closed`). These are already
|
|
302
|
+
* in wire-contract shape; the daemon's event dispatcher forwards them to
|
|
303
|
+
* the client unchanged so the "auto-compaction paused" banner shows and
|
|
304
|
+
* dismisses.
|
|
305
|
+
*/
|
|
306
|
+
| CompactionCircuitEvent
|
|
237
307
|
| {
|
|
238
308
|
/**
|
|
239
309
|
* Emitted when an agent turn reaches a terminal state. Checkpoint
|
|
@@ -256,6 +326,18 @@ const DEFAULT_CONFIG: AgentLoopConfig = {
|
|
|
256
326
|
|
|
257
327
|
const MAX_CONSECUTIVE_ERROR_NUDGES = 3;
|
|
258
328
|
const MAX_EMPTY_RESPONSE_RETRIES = 1;
|
|
329
|
+
const MAX_TOKENS_STOP_REASONS = new Set([
|
|
330
|
+
"length",
|
|
331
|
+
"max_output_tokens",
|
|
332
|
+
"max_tokens",
|
|
333
|
+
]);
|
|
334
|
+
|
|
335
|
+
export function isMaxTokensStopReason(
|
|
336
|
+
stopReason: string | null | undefined,
|
|
337
|
+
): boolean {
|
|
338
|
+
if (!stopReason) return false;
|
|
339
|
+
return MAX_TOKENS_STOP_REASONS.has(stopReason.trim().toLowerCase());
|
|
340
|
+
}
|
|
259
341
|
|
|
260
342
|
/**
|
|
261
343
|
* Build a minimal {@link TurnContext} for pipeline invocations inside the
|
|
@@ -354,6 +436,86 @@ export interface ResolvedSystemPrompt {
|
|
|
354
436
|
model?: string;
|
|
355
437
|
}
|
|
356
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Orchestrator-supplied hooks the loop invokes when the mid-loop budget gate
|
|
441
|
+
* trips and inline compaction runs. The loop owns the trigger, the
|
|
442
|
+
* `compaction` pipeline call, the result interpretation (circuit-breaker
|
|
443
|
+
* bookkeeping + the exhaustion decision), and the inline continue; these hooks
|
|
444
|
+
* bridge the durable / injection state the loop is intentionally blind to.
|
|
445
|
+
* Durable persistence ({@link applyResult}) and re-injection
|
|
446
|
+
* ({@link reinject}) remain orchestrator-supplied for now and are expected to
|
|
447
|
+
* move into the loop in a future change.
|
|
448
|
+
*/
|
|
449
|
+
export interface MidLoopCompaction {
|
|
450
|
+
/** Strip runtime injections, commit stripped messages, and resolve pipeline options. */
|
|
451
|
+
prepare: (history: Message[]) => {
|
|
452
|
+
rawHistory: Message[];
|
|
453
|
+
options: CompactionArgs["options"];
|
|
454
|
+
};
|
|
455
|
+
/** Commit a successful compaction result to durable state. */
|
|
456
|
+
applyResult: (
|
|
457
|
+
result: ContextWindowResult,
|
|
458
|
+
rawHistory: Message[],
|
|
459
|
+
) => Promise<void>;
|
|
460
|
+
/** Re-apply runtime injections and return the history to continue from. */
|
|
461
|
+
reinject: () => Promise<Message[]>;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export interface AgentLoopRunOptions {
|
|
465
|
+
signal?: AbortSignal;
|
|
466
|
+
requestId?: string;
|
|
467
|
+
onCheckpoint?: (
|
|
468
|
+
checkpoint: CheckpointInfo,
|
|
469
|
+
) => CheckpointDecision | Promise<CheckpointDecision>;
|
|
470
|
+
callSite?: LLMCallSite;
|
|
471
|
+
/**
|
|
472
|
+
* Per-turn context supplied by the orchestrator. Every pipeline
|
|
473
|
+
* invocation inside the loop clones from this value (overwriting only
|
|
474
|
+
* `turnIndex`/`requestId`) so middleware sees the real conversation
|
|
475
|
+
* identity, trust class, and `contextWindowManager` rather than the
|
|
476
|
+
* `"agent-loop"` sentinel used when the loop is instantiated standalone
|
|
477
|
+
* in unit tests.
|
|
478
|
+
*/
|
|
479
|
+
turnContext?: TurnContext;
|
|
480
|
+
/**
|
|
481
|
+
* Ad-hoc inference-profile override applied to every LLM call the loop
|
|
482
|
+
* issues. When set, each `SendMessageOptions.config` carries
|
|
483
|
+
* `overrideProfile = <name>` so the provider's resolver layers
|
|
484
|
+
* `llm.profiles[<name>]` between the workspace `activeProfile` and any
|
|
485
|
+
* call-site named profile. Missing profile names silently fall through.
|
|
486
|
+
*/
|
|
487
|
+
overrideProfile?: string;
|
|
488
|
+
resolveOverrideProfile?: () => string | undefined;
|
|
489
|
+
/**
|
|
490
|
+
* Resolves the orchestrator's effective context window for this turn: the
|
|
491
|
+
* provider max-input-token ceiling (read by tool-result truncation) plus the
|
|
492
|
+
* `overflowRecovery` config that drives the mid-loop budget gate. Resolved
|
|
493
|
+
* fresh per checkpoint so a mid-turn profile change is reflected. Absent →
|
|
494
|
+
* truncation falls back to `this.config.maxInputTokens` and the budget gate
|
|
495
|
+
* is skipped (agent wakes pass `overflowRecovery.enabled = false`).
|
|
496
|
+
*/
|
|
497
|
+
resolveContextWindow?: () => {
|
|
498
|
+
maxInputTokens: number;
|
|
499
|
+
overflowRecovery: { enabled: boolean; safetyMarginRatio: number };
|
|
500
|
+
};
|
|
501
|
+
/**
|
|
502
|
+
* Hooks for inline mid-loop compaction. When supplied and the budget gate
|
|
503
|
+
* trips, the loop compacts in place and continues instead of yielding
|
|
504
|
+
* `exitReason = "budget"`. Callers without a compaction path (agent wakes,
|
|
505
|
+
* convergence/auto-compress reruns) omit this and keep yielding for budget.
|
|
506
|
+
*/
|
|
507
|
+
compaction?: MidLoopCompaction;
|
|
508
|
+
/**
|
|
509
|
+
* When true, the latest user message carries a volatile per-turn block
|
|
510
|
+
* (e.g. a memory-v3 `<memory>` injection) that varies across otherwise
|
|
511
|
+
* identical turns. Forwarded to each `SendMessageOptions.config` so the
|
|
512
|
+
* provider anchors its long-TTL cache breakpoint on the most recent STABLE
|
|
513
|
+
* user message instead of the volatile latest one, keeping the cached
|
|
514
|
+
* prefix reusable. Default unset → existing behavior.
|
|
515
|
+
*/
|
|
516
|
+
mutableLatestUserMessage?: boolean;
|
|
517
|
+
}
|
|
518
|
+
|
|
357
519
|
/**
|
|
358
520
|
* Callback shape the loop uses to execute a tool invocation.
|
|
359
521
|
*
|
|
@@ -401,6 +563,20 @@ export type LoopToolExecutor = (
|
|
|
401
563
|
activityMetadata?: ToolActivityMetadata;
|
|
402
564
|
}>;
|
|
403
565
|
|
|
566
|
+
export interface AgentLoopConstructorOptions {
|
|
567
|
+
config?: Partial<AgentLoopConfig>;
|
|
568
|
+
tools?: ToolDefinition[];
|
|
569
|
+
toolExecutor?: LoopToolExecutor;
|
|
570
|
+
resolveTools?: (history: Message[]) => ToolDefinition[];
|
|
571
|
+
resolveSystemPrompt?: (history: Message[]) => ResolvedSystemPrompt;
|
|
572
|
+
/**
|
|
573
|
+
* Conversation this loop drives. Used to scope the loop-held compaction
|
|
574
|
+
* circuit breaker; defaults to an empty key for test loops that never
|
|
575
|
+
* exercise compaction.
|
|
576
|
+
*/
|
|
577
|
+
conversationId?: string;
|
|
578
|
+
}
|
|
579
|
+
|
|
404
580
|
export class AgentLoop {
|
|
405
581
|
private provider: Provider;
|
|
406
582
|
private systemPrompt: string;
|
|
@@ -412,15 +588,28 @@ export class AgentLoop {
|
|
|
412
588
|
| null;
|
|
413
589
|
private toolExecutor: LoopToolExecutor | null;
|
|
414
590
|
|
|
591
|
+
/**
|
|
592
|
+
* Loop-held compaction circuit breaker. The loop has a 1:1 lifetime with its
|
|
593
|
+
* conversation, so it is the source of truth for the cross-turn failure
|
|
594
|
+
* counter and cooldown deadline. Non-loop callers (the orchestrator's
|
|
595
|
+
* compaction paths, `Conversation.forceCompact`, and the dev-only playground
|
|
596
|
+
* routes) reach it via `agentLoop.compactionCircuit`.
|
|
597
|
+
*/
|
|
598
|
+
readonly compactionCircuit: CompactionCircuit;
|
|
599
|
+
|
|
415
600
|
constructor(
|
|
416
601
|
provider: Provider,
|
|
417
602
|
systemPrompt: string,
|
|
418
|
-
|
|
419
|
-
tools?: ToolDefinition[],
|
|
420
|
-
toolExecutor?: LoopToolExecutor,
|
|
421
|
-
resolveTools?: (history: Message[]) => ToolDefinition[],
|
|
422
|
-
resolveSystemPrompt?: (history: Message[]) => ResolvedSystemPrompt,
|
|
603
|
+
options?: AgentLoopConstructorOptions,
|
|
423
604
|
) {
|
|
605
|
+
const {
|
|
606
|
+
config,
|
|
607
|
+
tools,
|
|
608
|
+
toolExecutor,
|
|
609
|
+
resolveTools,
|
|
610
|
+
resolveSystemPrompt,
|
|
611
|
+
conversationId,
|
|
612
|
+
} = options ?? {};
|
|
424
613
|
this.provider = provider;
|
|
425
614
|
this.systemPrompt = systemPrompt;
|
|
426
615
|
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
@@ -428,6 +617,7 @@ export class AgentLoop {
|
|
|
428
617
|
this.resolveTools = resolveTools ?? null;
|
|
429
618
|
this.resolveSystemPrompt = resolveSystemPrompt ?? null;
|
|
430
619
|
this.toolExecutor = toolExecutor ?? null;
|
|
620
|
+
this.compactionCircuit = new CompactionCircuit(conversationId ?? "");
|
|
431
621
|
}
|
|
432
622
|
|
|
433
623
|
/**
|
|
@@ -457,44 +647,148 @@ export class AgentLoop {
|
|
|
457
647
|
return estimateToolsTokens(this.getResolvedTools(history));
|
|
458
648
|
}
|
|
459
649
|
|
|
650
|
+
/**
|
|
651
|
+
* Estimate total prompt tokens for `history` via the `tokenEstimate`
|
|
652
|
+
* pipeline. Args are shallow-frozen so a mutating middleware cannot strip
|
|
653
|
+
* context from the loop's live `history`.
|
|
654
|
+
*/
|
|
655
|
+
private estimateTokens(
|
|
656
|
+
history: Message[],
|
|
657
|
+
turnContext: TurnContext,
|
|
658
|
+
): Promise<EstimateResult> {
|
|
659
|
+
return runPipeline<EstimateArgs, EstimateResult>(
|
|
660
|
+
"tokenEstimate",
|
|
661
|
+
getMiddlewaresFor("tokenEstimate"),
|
|
662
|
+
defaultTokenEstimateTerminal,
|
|
663
|
+
{
|
|
664
|
+
history: Object.freeze([...history]) as Message[],
|
|
665
|
+
systemPrompt: this.systemPrompt,
|
|
666
|
+
tools: Object.freeze([
|
|
667
|
+
...this.getResolvedTools(history),
|
|
668
|
+
]) as ToolDefinition[],
|
|
669
|
+
providerName: getCalibrationProviderKey(this.provider),
|
|
670
|
+
},
|
|
671
|
+
turnContext,
|
|
672
|
+
DEFAULT_TIMEOUTS.tokenEstimate,
|
|
673
|
+
);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Record a compaction outcome against the loop's circuit breaker. Three
|
|
678
|
+
* consecutive failures trip a cooldown that suspends auto-compaction; a
|
|
679
|
+
* success resets the counter. Any open/closed transition is emitted on the
|
|
680
|
+
* loop's own event channel via `onEvent`.
|
|
681
|
+
*
|
|
682
|
+
* Bookkeeping is best-effort — a failure here must not turn a recoverable
|
|
683
|
+
* compaction outcome into a user-visible turn failure.
|
|
684
|
+
*/
|
|
685
|
+
private async recordCompactionOutcome(
|
|
686
|
+
turnContext: TurnContext,
|
|
687
|
+
summaryFailed: boolean,
|
|
688
|
+
onEvent: (event: AgentEvent) => void | Promise<void>,
|
|
689
|
+
): Promise<void> {
|
|
690
|
+
try {
|
|
691
|
+
await this.compactionCircuit.recordOutcome(
|
|
692
|
+
{
|
|
693
|
+
currentRequestId: turnContext.requestId,
|
|
694
|
+
currentTurnTrustContext: turnContext.trust,
|
|
695
|
+
turnCount: turnContext.turnIndex,
|
|
696
|
+
},
|
|
697
|
+
summaryFailed,
|
|
698
|
+
onEvent,
|
|
699
|
+
);
|
|
700
|
+
} catch (recordError) {
|
|
701
|
+
log.error(
|
|
702
|
+
{ err: recordError, requestId: turnContext.requestId },
|
|
703
|
+
"Recording a compaction outcome against the circuit breaker failed; suppressing to keep the agent loop alive",
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Compact the running history in place when the mid-loop budget gate trips.
|
|
710
|
+
*
|
|
711
|
+
* Runs the `compaction` pipeline natively (like {@link estimateTokens}) on
|
|
712
|
+
* the stripped history, then re-applies injections via the supplied hooks.
|
|
713
|
+
* Returns the history to continue from, or `null` when the compactor timed
|
|
714
|
+
* out or exhausted its retry budget so the caller yields
|
|
715
|
+
* `exitReason = "budget"` and the orchestrator escalates.
|
|
716
|
+
*/
|
|
717
|
+
private async compact(
|
|
718
|
+
history: Message[],
|
|
719
|
+
turnContext: TurnContext,
|
|
720
|
+
compaction: MidLoopCompaction,
|
|
721
|
+
signal: AbortSignal | undefined,
|
|
722
|
+
onEvent: (event: AgentEvent) => void | Promise<void>,
|
|
723
|
+
): Promise<Message[] | null> {
|
|
724
|
+
await onEvent({ type: "context_compacting" });
|
|
725
|
+
const { rawHistory, options } = compaction.prepare(history);
|
|
726
|
+
let result: CompactionResult;
|
|
727
|
+
try {
|
|
728
|
+
result = await runPipeline<CompactionArgs, CompactionResult>(
|
|
729
|
+
"compaction",
|
|
730
|
+
getMiddlewaresFor("compaction"),
|
|
731
|
+
(args) => defaultCompactionTerminal(args, turnContext),
|
|
732
|
+
{ messages: rawHistory, signal, options },
|
|
733
|
+
turnContext,
|
|
734
|
+
DEFAULT_TIMEOUTS.compaction,
|
|
735
|
+
);
|
|
736
|
+
} catch (error) {
|
|
737
|
+
if (error instanceof PluginTimeoutError) {
|
|
738
|
+
// A timeout counts as a compaction failure against the circuit breaker.
|
|
739
|
+
await this.recordCompactionOutcome(turnContext, true, onEvent);
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
throw error;
|
|
743
|
+
}
|
|
744
|
+
// `CompactionResult` is intentionally `unknown` at the plugin boundary so
|
|
745
|
+
// plugin consumers don't import the window manager; the loop ran the
|
|
746
|
+
// pipeline, so it interprets the concrete result here.
|
|
747
|
+
const compactResult = result as ContextWindowResult;
|
|
748
|
+
// `force: true` bypasses the cooldown/threshold gates, but early returns
|
|
749
|
+
// for "no eligible messages" / "insufficient messages" still leave
|
|
750
|
+
// `summaryFailed` undefined. Only record an outcome when the summary LLM
|
|
751
|
+
// actually ran.
|
|
752
|
+
if (compactResult.summaryFailed !== undefined) {
|
|
753
|
+
await this.recordCompactionOutcome(
|
|
754
|
+
turnContext,
|
|
755
|
+
compactResult.summaryFailed,
|
|
756
|
+
onEvent,
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
if (compactResult.compacted) {
|
|
760
|
+
await compaction.applyResult(compactResult, rawHistory);
|
|
761
|
+
}
|
|
762
|
+
if (compactResult.exhausted ?? false) {
|
|
763
|
+
return null;
|
|
764
|
+
}
|
|
765
|
+
return compaction.reinject();
|
|
766
|
+
}
|
|
767
|
+
|
|
460
768
|
async run(
|
|
461
769
|
messages: Message[],
|
|
462
770
|
onEvent: (event: AgentEvent) => void | Promise<void>,
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
* Optional ad-hoc inference-profile override applied to every LLM call
|
|
480
|
-
* the loop issues. When set, each `SendMessageOptions.config` carries
|
|
481
|
-
* `overrideProfile = <name>` so the provider's resolver layers
|
|
482
|
-
* `llm.profiles[<name>]` between the workspace `activeProfile` and any
|
|
483
|
-
* call-site named profile. Missing profile names silently fall through.
|
|
484
|
-
* Used by per-conversation pinned profiles to override the workspace
|
|
485
|
-
* default for the lifetime of an agent loop run.
|
|
486
|
-
*/
|
|
487
|
-
overrideProfile?: string,
|
|
488
|
-
effectiveMaxInputTokens?: number,
|
|
489
|
-
resolveOverrideProfile?: () => string | undefined,
|
|
490
|
-
resolveEffectiveMaxInputTokens?: () => number | undefined,
|
|
491
|
-
): Promise<Message[]> {
|
|
492
|
-
const history = [...messages];
|
|
493
|
-
const initialHistoryLength = messages.length;
|
|
771
|
+
options?: AgentLoopRunOptions,
|
|
772
|
+
): Promise<AgentLoopRunResult> {
|
|
773
|
+
const {
|
|
774
|
+
signal,
|
|
775
|
+
requestId,
|
|
776
|
+
onCheckpoint,
|
|
777
|
+
callSite,
|
|
778
|
+
turnContext,
|
|
779
|
+
overrideProfile,
|
|
780
|
+
resolveOverrideProfile,
|
|
781
|
+
resolveContextWindow,
|
|
782
|
+
compaction,
|
|
783
|
+
mutableLatestUserMessage,
|
|
784
|
+
} = options ?? {};
|
|
785
|
+
let history = [...messages];
|
|
786
|
+
let producedVisibleTextThisRun = false;
|
|
494
787
|
let toolUseTurns = 0;
|
|
495
788
|
let consecutiveErrorTurns = 0;
|
|
496
789
|
let emptyResponseRetries = 0;
|
|
497
790
|
let lastLlmCallTime = 0;
|
|
791
|
+
let exitReason: ExitReason | null = null;
|
|
498
792
|
const rlog = requestId ? log.child({ requestId }) : log;
|
|
499
793
|
|
|
500
794
|
// Per-run substitution map for sensitive output placeholders.
|
|
@@ -593,6 +887,15 @@ export class AgentLoop {
|
|
|
593
887
|
providerConfig.cacheTtl = this.config.cacheTtl;
|
|
594
888
|
}
|
|
595
889
|
|
|
890
|
+
// Cache-anchor signal for volatile latest-user-message turns (e.g.
|
|
891
|
+
// memory-v3 injects its `<memory>` block into the latest user
|
|
892
|
+
// message). Not part of the call-site schema, so it is always sourced
|
|
893
|
+
// from the per-run option regardless of `callSite`. Only set when true
|
|
894
|
+
// so the wire/config stays byte-identical when off.
|
|
895
|
+
if (mutableLatestUserMessage) {
|
|
896
|
+
providerConfig.mutableLatestUserMessage = true;
|
|
897
|
+
}
|
|
898
|
+
|
|
596
899
|
// Per-call LLM call-site identifier. Surfaces on the per-call
|
|
597
900
|
// `config.callSite` so `RetryProvider.normalizeSendMessageOptions`
|
|
598
901
|
// can route through `resolveCallSiteConfig` against
|
|
@@ -603,6 +906,16 @@ export class AgentLoop {
|
|
|
603
906
|
if (callSite) {
|
|
604
907
|
providerConfig.callSite = callSite;
|
|
605
908
|
providerConfig.usageTracking = "manual";
|
|
909
|
+
// Per-conversation seed for deterministic `mix`-profile expansion.
|
|
910
|
+
// Sourced from the orchestrator-supplied turn context's
|
|
911
|
+
// conversationId so every LLM call in a conversation resolves the
|
|
912
|
+
// same mix arm (stable across turns and retries, and across daemon
|
|
913
|
+
// restarts since the seed is the durable conversation id). Absent
|
|
914
|
+
// for standalone `AgentLoop` instances (unit tests / no turnContext)
|
|
915
|
+
// — those fall back to per-call random mix selection.
|
|
916
|
+
if (turnContext?.conversationId) {
|
|
917
|
+
providerConfig.selectionSeed = turnContext.conversationId;
|
|
918
|
+
}
|
|
606
919
|
}
|
|
607
920
|
|
|
608
921
|
// Per-call inference-profile override. The resolver layers
|
|
@@ -658,7 +971,7 @@ export class AgentLoop {
|
|
|
658
971
|
// Also strip old AX tree snapshots to keep TTFT from growing
|
|
659
972
|
// linearly with step count in computer-use sessions.
|
|
660
973
|
const providerHistory = compactAxTreeHistory(
|
|
661
|
-
|
|
974
|
+
stripOldMediaBlocks(history),
|
|
662
975
|
);
|
|
663
976
|
|
|
664
977
|
// Wrap the provider call in the `llmCall` pipeline so middleware
|
|
@@ -677,9 +990,9 @@ export class AgentLoop {
|
|
|
677
990
|
const llmCallArgs: LLMCallArgs = {
|
|
678
991
|
provider: this.provider,
|
|
679
992
|
messages: providerHistory,
|
|
680
|
-
tools: currentTools.length > 0 ? currentTools : undefined,
|
|
681
|
-
systemPrompt: turnSystemPrompt,
|
|
682
993
|
options: {
|
|
994
|
+
tools: currentTools.length > 0 ? currentTools : undefined,
|
|
995
|
+
systemPrompt: turnSystemPrompt,
|
|
683
996
|
config: providerConfig,
|
|
684
997
|
onEvent: (event) => {
|
|
685
998
|
if (event.type === "text_delta") {
|
|
@@ -751,6 +1064,18 @@ export class AgentLoop {
|
|
|
751
1064
|
toolUseTurns,
|
|
752
1065
|
);
|
|
753
1066
|
|
|
1067
|
+
// Announce the LLM-call boundary so downstream handlers (the
|
|
1068
|
+
// daemon's persistence pipeline) can reserve an empty assistant row
|
|
1069
|
+
// and stamp the resulting `messageId` onto every streaming event the
|
|
1070
|
+
// call emits. Emit as late as possible — after history stripping,
|
|
1071
|
+
// arg construction, and turn-context resolution — so the gap
|
|
1072
|
+
// between "we said the call started" and the actual provider HTTP
|
|
1073
|
+
// call is minimized. Awaited so the row is created and the
|
|
1074
|
+
// `assistant_turn_start` wire event reaches the client BEFORE the
|
|
1075
|
+
// provider starts streaming deltas — the deltas downstream will
|
|
1076
|
+
// carry the freshly-reserved id.
|
|
1077
|
+
await onEvent({ type: "llm_call_started", callSite });
|
|
1078
|
+
|
|
754
1079
|
// Inner try/catch narrows error-recording scope to the provider
|
|
755
1080
|
// call itself. The outer agent-loop catch (below) wraps the entire
|
|
756
1081
|
// turn body (tool execution, plugin pipelines, checkpoints), so
|
|
@@ -765,13 +1090,7 @@ export class AgentLoop {
|
|
|
765
1090
|
response = await runPipeline<LLMCallArgs, LLMCallResult>(
|
|
766
1091
|
"llmCall",
|
|
767
1092
|
getMiddlewaresFor("llmCall"),
|
|
768
|
-
(args) =>
|
|
769
|
-
args.provider.sendMessage(
|
|
770
|
-
args.messages,
|
|
771
|
-
args.tools,
|
|
772
|
-
args.systemPrompt,
|
|
773
|
-
args.options,
|
|
774
|
-
),
|
|
1093
|
+
(args) => args.provider.sendMessage(args.messages, args.options),
|
|
775
1094
|
llmCallArgs,
|
|
776
1095
|
turnCtx,
|
|
777
1096
|
DEFAULT_TIMEOUTS.llmCall,
|
|
@@ -793,8 +1112,8 @@ export class AgentLoop {
|
|
|
793
1112
|
const rawRequest = {
|
|
794
1113
|
provider: this.provider.name,
|
|
795
1114
|
messages: llmCallArgs.messages,
|
|
796
|
-
tools: llmCallArgs.tools,
|
|
797
|
-
systemPrompt: llmCallArgs.systemPrompt,
|
|
1115
|
+
tools: llmCallArgs.options?.tools,
|
|
1116
|
+
systemPrompt: llmCallArgs.options?.systemPrompt,
|
|
798
1117
|
config: llmCallArgs.options?.config,
|
|
799
1118
|
};
|
|
800
1119
|
onEvent({
|
|
@@ -862,6 +1181,40 @@ export class AgentLoop {
|
|
|
862
1181
|
"LLM call complete",
|
|
863
1182
|
);
|
|
864
1183
|
|
|
1184
|
+
if (isMaxTokensStopReason(response.stopReason)) {
|
|
1185
|
+
const safeContent = response.content.filter(
|
|
1186
|
+
(block) =>
|
|
1187
|
+
block.type !== "tool_use" &&
|
|
1188
|
+
block.type !== "server_tool_use" &&
|
|
1189
|
+
block.type !== "web_search_tool_result",
|
|
1190
|
+
);
|
|
1191
|
+
const safeAssistantMessage: Message = {
|
|
1192
|
+
role: "assistant",
|
|
1193
|
+
content: safeContent,
|
|
1194
|
+
};
|
|
1195
|
+
rlog.warn(
|
|
1196
|
+
{
|
|
1197
|
+
turn: toolUseTurns,
|
|
1198
|
+
stopReason: response.stopReason,
|
|
1199
|
+
contentBlocks: response.content.length,
|
|
1200
|
+
safeContentBlocks: safeContent.length,
|
|
1201
|
+
toolUseCount: toolUseBlocks.length,
|
|
1202
|
+
},
|
|
1203
|
+
"LLM response reached output token limit",
|
|
1204
|
+
);
|
|
1205
|
+
history.push(safeAssistantMessage);
|
|
1206
|
+
await onEvent({
|
|
1207
|
+
type: "max_tokens_reached",
|
|
1208
|
+
stopReason: response.stopReason,
|
|
1209
|
+
});
|
|
1210
|
+
await onEvent({
|
|
1211
|
+
type: "message_complete",
|
|
1212
|
+
message: safeAssistantMessage,
|
|
1213
|
+
});
|
|
1214
|
+
await emitExit("max_tokens_reached");
|
|
1215
|
+
break;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
865
1218
|
// Detect empty responses: no user-visible text and no tool calls.
|
|
866
1219
|
// This can happen when the model fails to produce output after
|
|
867
1220
|
// receiving a large tool result. Retry once with a nudge before
|
|
@@ -892,25 +1245,20 @@ export class AgentLoop {
|
|
|
892
1245
|
// The actual decision (nudge vs. accept vs. error) is delegated to
|
|
893
1246
|
// the `emptyResponse` plugin pipeline. The pipeline returns a
|
|
894
1247
|
// decision; the loop carries out the side-effect (pushing the nudge
|
|
895
|
-
// or surfacing the error). See `plugins/defaults/empty-response.ts`
|
|
1248
|
+
// or surfacing the error). See `plugins/defaults/empty-response/register.ts`
|
|
896
1249
|
// for the default decision logic.
|
|
897
1250
|
const hasVisibleText = response.content.some(
|
|
898
1251
|
(block) => block.type === "text" && block.text.trim().length > 0,
|
|
899
1252
|
);
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
);
|
|
910
|
-
if (hasText) return true;
|
|
911
|
-
}
|
|
912
|
-
return false;
|
|
913
|
-
})();
|
|
1253
|
+
// Track whether the model produced visible text earlier in this
|
|
1254
|
+
// run() invocation. Run-scoped rather than derived from `history` so
|
|
1255
|
+
// it survives inline compaction rewriting the message array: an empty
|
|
1256
|
+
// completion after a compaction must not be nudged into re-sending
|
|
1257
|
+
// text the user already saw.
|
|
1258
|
+
const priorAssistantHadVisibleText = producedVisibleTextThisRun;
|
|
1259
|
+
if (hasVisibleText) {
|
|
1260
|
+
producedVisibleTextThisRun = true;
|
|
1261
|
+
}
|
|
914
1262
|
|
|
915
1263
|
const emptyResponseArgs: EmptyResponseArgs = {
|
|
916
1264
|
responseContent: response.content,
|
|
@@ -919,6 +1267,7 @@ export class AgentLoop {
|
|
|
919
1267
|
emptyResponseRetries,
|
|
920
1268
|
maxEmptyResponseRetries: MAX_EMPTY_RESPONSE_RETRIES,
|
|
921
1269
|
priorAssistantHadVisibleText,
|
|
1270
|
+
stopReason: response.stopReason,
|
|
922
1271
|
};
|
|
923
1272
|
const emptyResponseCtx = resolveLoopTurnContext(
|
|
924
1273
|
turnContext,
|
|
@@ -1121,8 +1470,7 @@ export class AgentLoop {
|
|
|
1121
1470
|
// truncation strategy (e.g. a summariser) while the default
|
|
1122
1471
|
// middleware preserves the historical tail-drop behaviour.
|
|
1123
1472
|
const contextWindowTokens =
|
|
1124
|
-
|
|
1125
|
-
effectiveMaxInputTokens ??
|
|
1473
|
+
resolveContextWindow?.().maxInputTokens ??
|
|
1126
1474
|
this.config.maxInputTokens ??
|
|
1127
1475
|
180_000;
|
|
1128
1476
|
const maxChars = calculateMaxToolResultChars(contextWindowTokens);
|
|
@@ -1272,8 +1620,8 @@ export class AgentLoop {
|
|
|
1272
1620
|
history.push({ role: "user", content: resultBlocks });
|
|
1273
1621
|
|
|
1274
1622
|
// Invoke checkpoint callback after tool results are in history.
|
|
1275
|
-
//
|
|
1276
|
-
//
|
|
1623
|
+
// Handoff is offered first so a queued message takes precedence over
|
|
1624
|
+
// the mid-loop budget yield below.
|
|
1277
1625
|
if (onCheckpoint) {
|
|
1278
1626
|
const decision = await onCheckpoint({
|
|
1279
1627
|
turnIndex: toolUseTurns - 1, // 0-based (toolUseTurns was already incremented)
|
|
@@ -1281,7 +1629,60 @@ export class AgentLoop {
|
|
|
1281
1629
|
hasToolUse: true,
|
|
1282
1630
|
history,
|
|
1283
1631
|
});
|
|
1284
|
-
if (decision
|
|
1632
|
+
if (decision !== "continue") {
|
|
1633
|
+
exitReason = decision;
|
|
1634
|
+
break;
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
// Mid-loop budget gate: when overflow recovery is enabled, estimate
|
|
1639
|
+
// the running context size as it approaches the preflight budget.
|
|
1640
|
+
// With a `compaction` hook the loop compacts in place and continues;
|
|
1641
|
+
// without one it yields (`exitReason = "budget"`) so the orchestrator
|
|
1642
|
+
// can recover before the next provider call risks a hard
|
|
1643
|
+
// context-too-large rejection. Keyed off the loop's own
|
|
1644
|
+
// `history.length` (the messages actually in context this turn,
|
|
1645
|
+
// including tool iterations) rather than the durable conversation
|
|
1646
|
+
// count.
|
|
1647
|
+
const contextWindow = resolveContextWindow?.();
|
|
1648
|
+
if (contextWindow?.overflowRecovery.enabled) {
|
|
1649
|
+
const { maxInputTokens, overflowRecovery } = contextWindow;
|
|
1650
|
+
const safetyMargin =
|
|
1651
|
+
history.length > LONG_HISTORY_MESSAGE_THRESHOLD
|
|
1652
|
+
? Math.max(
|
|
1653
|
+
overflowRecovery.safetyMarginRatio,
|
|
1654
|
+
LONG_HISTORY_SAFETY_MARGIN_FLOOR,
|
|
1655
|
+
)
|
|
1656
|
+
: overflowRecovery.safetyMarginRatio;
|
|
1657
|
+
const preflightBudget = Math.floor(
|
|
1658
|
+
maxInputTokens * (1 - safetyMargin),
|
|
1659
|
+
);
|
|
1660
|
+
const midLoopThreshold =
|
|
1661
|
+
preflightBudget * MID_LOOP_YIELD_THRESHOLD_RATIO;
|
|
1662
|
+
const estimated = await this.estimateTokens(history, turnCtx);
|
|
1663
|
+
if (estimated > midLoopThreshold) {
|
|
1664
|
+
if (compaction) {
|
|
1665
|
+
rlog.info(
|
|
1666
|
+
{ phase: "mid-loop", estimated, threshold: midLoopThreshold },
|
|
1667
|
+
"Token estimate approaching budget — compacting in place",
|
|
1668
|
+
);
|
|
1669
|
+
const compacted = await this.compact(
|
|
1670
|
+
history,
|
|
1671
|
+
turnCtx,
|
|
1672
|
+
compaction,
|
|
1673
|
+
signal,
|
|
1674
|
+
onEvent,
|
|
1675
|
+
);
|
|
1676
|
+
if (compacted) {
|
|
1677
|
+
history = compacted;
|
|
1678
|
+
continue;
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
rlog.warn(
|
|
1682
|
+
{ phase: "mid-loop", estimated, threshold: midLoopThreshold },
|
|
1683
|
+
"Token estimate approaching budget — yielding for compaction",
|
|
1684
|
+
);
|
|
1685
|
+
exitReason = "budget";
|
|
1285
1686
|
break;
|
|
1286
1687
|
}
|
|
1287
1688
|
}
|
|
@@ -1332,7 +1733,7 @@ export class AgentLoop {
|
|
|
1332
1733
|
"Agent loop exited",
|
|
1333
1734
|
);
|
|
1334
1735
|
|
|
1335
|
-
return history;
|
|
1736
|
+
return { history, exitReason };
|
|
1336
1737
|
}
|
|
1337
1738
|
}
|
|
1338
1739
|
|
|
@@ -1433,7 +1834,7 @@ export function compactAxTreeHistory(messages: Message[]): Message[] {
|
|
|
1433
1834
|
* turn. Using the last user message unconditionally would leave the most
|
|
1434
1835
|
* recent tool screenshots unprotected from stripping.
|
|
1435
1836
|
*/
|
|
1436
|
-
function
|
|
1837
|
+
function stripOldMediaBlocks(history: Message[]): Message[] {
|
|
1437
1838
|
// Find the last user message that contains tool_result blocks.
|
|
1438
1839
|
let lastToolResultUserIdx = -1;
|
|
1439
1840
|
for (let i = history.length - 1; i >= 0; i--) {
|
|
@@ -1450,29 +1851,32 @@ function stripOldImageBlocks(history: Message[]): Message[] {
|
|
|
1450
1851
|
// Keep the most recent tool-result user message intact (current turn)
|
|
1451
1852
|
if (idx === lastToolResultUserIdx || msg.role !== "user") return msg;
|
|
1452
1853
|
|
|
1453
|
-
// Check if any tool_result blocks
|
|
1454
|
-
const
|
|
1854
|
+
// Check if any tool_result blocks carry embedded media (image or audio).
|
|
1855
|
+
const isMedia = (cb: ContentBlock) =>
|
|
1856
|
+
cb.type === "image" || cb.type === "file";
|
|
1857
|
+
const hasMedia = msg.content.some(
|
|
1455
1858
|
(b) =>
|
|
1456
1859
|
b.type === "tool_result" &&
|
|
1457
|
-
(b as ToolResultContent).contentBlocks?.some(
|
|
1458
|
-
(cb) => cb.type === "image",
|
|
1459
|
-
),
|
|
1860
|
+
(b as ToolResultContent).contentBlocks?.some(isMedia),
|
|
1460
1861
|
);
|
|
1461
|
-
if (!
|
|
1862
|
+
if (!hasMedia) return msg;
|
|
1462
1863
|
|
|
1463
|
-
// Strip
|
|
1864
|
+
// Strip media from tool_result blocks, replacing with a text marker. The
|
|
1865
|
+
// model already saw/heard the media in the turn it was captured; resending
|
|
1866
|
+
// the bytes every turn (a 12 MB audio clip isn't optimized like images)
|
|
1867
|
+
// bloats the request until compaction.
|
|
1464
1868
|
return {
|
|
1465
1869
|
...msg,
|
|
1466
1870
|
content: msg.content.map((b) => {
|
|
1467
1871
|
if (b.type !== "tool_result") return b;
|
|
1468
1872
|
const tr = b as ToolResultContent;
|
|
1469
|
-
if (!tr.contentBlocks?.some(
|
|
1873
|
+
if (!tr.contentBlocks?.some(isMedia)) return b;
|
|
1470
1874
|
return {
|
|
1471
1875
|
...tr,
|
|
1472
1876
|
contentBlocks: undefined,
|
|
1473
1877
|
content:
|
|
1474
1878
|
(tr.content || "") +
|
|
1475
|
-
"\n[
|
|
1879
|
+
"\n[Media (image/audio) was captured and shown previously — binary data removed to save context.]",
|
|
1476
1880
|
};
|
|
1477
1881
|
}),
|
|
1478
1882
|
};
|