@vellumai/assistant 0.6.3 → 0.6.5
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/.prettierignore +5 -0
- package/ARCHITECTURE.md +298 -39
- package/Dockerfile +14 -3
- package/README.md +3 -4
- package/bun.lock +13 -16
- package/docs/architecture/integrations.md +1 -20
- package/docs/architecture/security.md +16 -16
- package/docs/backup-troubleshooting.md +52 -0
- package/docs/browser-use-architecture-phase2.md +174 -0
- package/docs/error-handling.md +111 -0
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +121 -0
- package/knip.json +20 -3
- package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
- package/node_modules/@vellumai/ces-contracts/package.json +5 -4
- package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
- package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
- package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
- package/node_modules/@vellumai/credential-storage/package.json +2 -2
- package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
- package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
- package/node_modules/@vellumai/egress-proxy/package.json +2 -2
- package/openapi.yaml +1094 -72
- package/package.json +9 -8
- package/scripts/generate-openapi.ts +50 -12
- package/scripts/test.sh +73 -18
- package/src/__tests__/agent-image-optimize.test.ts +28 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
- package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
- package/src/__tests__/agent-loop.test.ts +235 -1
- package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
- package/src/__tests__/anthropic-provider.test.ts +434 -12
- package/src/__tests__/approval-cascade.test.ts +31 -10
- package/src/__tests__/approval-routes-http.test.ts +134 -10
- package/src/__tests__/assistant-attachments.test.ts +44 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
- package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
- package/src/__tests__/browser-fill-credential.test.ts +12 -1
- package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
- package/src/__tests__/browser-skill-endstate.test.ts +52 -159
- package/src/__tests__/btw-routes.test.ts +54 -1
- package/src/__tests__/call-controller.test.ts +582 -22
- package/src/__tests__/call-site-routing-provider.test.ts +214 -0
- package/src/__tests__/catalog-cache.test.ts +27 -4
- package/src/__tests__/catalog-files.test.ts +138 -0
- package/src/__tests__/channel-approval-routes.test.ts +4 -4
- package/src/__tests__/channel-invite-transport.test.ts +2 -2
- package/src/__tests__/channel-readiness-routes.test.ts +16 -20
- package/src/__tests__/channel-readiness-service.test.ts +12 -7
- package/src/__tests__/channel-reply-delivery.test.ts +300 -2
- package/src/__tests__/checker.test.ts +576 -502
- package/src/__tests__/clawhub-files.test.ts +347 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
- package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
- package/src/__tests__/compaction-circuit-breaker.test.ts +336 -0
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/config-analysis.test.ts +83 -0
- package/src/__tests__/config-loader-backfill.test.ts +174 -0
- package/src/__tests__/config-loader-corrupt.test.ts +183 -0
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
- package/src/__tests__/config-schema-cmd.test.ts +11 -5
- package/src/__tests__/config-schema.test.ts +1458 -198
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +45 -10
- package/src/__tests__/contact-store-user-file.test.ts +511 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-token-estimator.test.ts +191 -1
- package/src/__tests__/context-window-manager.test.ts +618 -2
- package/src/__tests__/conversation-abort-tool-results.test.ts +32 -16
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +62 -17
- package/src/__tests__/conversation-agent-loop.test.ts +510 -84
- package/src/__tests__/conversation-attachments.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +165 -9
- package/src/__tests__/conversation-error.test.ts +102 -1
- package/src/__tests__/conversation-history-web-search.test.ts +17 -4
- package/src/__tests__/conversation-init.benchmark.test.ts +42 -1
- package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
- package/src/__tests__/conversation-lifecycle.test.ts +336 -0
- package/src/__tests__/conversation-list-source.test.ts +145 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +32 -16
- package/src/__tests__/conversation-process-callsite.test.ts +306 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +32 -16
- package/src/__tests__/conversation-queue.test.ts +932 -76
- package/src/__tests__/conversation-routes-disk-view.test.ts +299 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
- package/src/__tests__/conversation-runtime-assembly.test.ts +2790 -55
- package/src/__tests__/conversation-runtime-workspace.test.ts +12 -12
- package/src/__tests__/conversation-skill-tools.test.ts +12 -143
- package/src/__tests__/conversation-slash-commands.test.ts +33 -0
- package/src/__tests__/conversation-slash-queue.test.ts +120 -34
- package/src/__tests__/conversation-slash-unknown.test.ts +32 -16
- package/src/__tests__/conversation-speed-override.test.ts +30 -11
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
- package/src/__tests__/conversation-title-service.test.ts +2 -2
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-unread-route.test.ts +2 -2
- package/src/__tests__/conversation-usage.test.ts +3 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +31 -10
- package/src/__tests__/conversation-workspace-injection.test.ts +45 -15
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +46 -16
- package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +8 -3
- package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
- package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
- package/src/__tests__/credential-vault-unit.test.ts +495 -3
- package/src/__tests__/credentials-cli.test.ts +32 -16
- package/src/__tests__/cross-provider-web-search.test.ts +230 -35
- package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
- package/src/__tests__/delete-propagation.test.ts +437 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
- package/src/__tests__/device-id.test.ts +112 -0
- package/src/__tests__/dm-backfill.test.ts +417 -0
- package/src/__tests__/dm-persistence.test.ts +227 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
- package/src/__tests__/edit-propagation.test.ts +280 -0
- package/src/__tests__/email-html-renderer.test.ts +71 -0
- package/src/__tests__/email-invite-adapter.test.ts +36 -32
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/ephemeral-permissions.test.ts +93 -3
- package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
- package/src/__tests__/estimator-calibration.test.ts +213 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +101 -15
- package/src/__tests__/file-write-tool.test.ts +151 -1
- package/src/__tests__/filing-service.test.ts +255 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +11 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/gemini-provider.test.ts +64 -3
- package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
- package/src/__tests__/guardian-grant-minting.test.ts +8 -0
- package/src/__tests__/headless-browser-interactions.test.ts +44 -1
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +142 -5
- package/src/__tests__/headless-browser-read-tools.test.ts +11 -0
- package/src/__tests__/headless-browser-snapshot.test.ts +10 -0
- package/src/__tests__/heartbeat-service.test.ts +166 -32
- package/src/__tests__/home-state-routes.test.ts +162 -0
- package/src/__tests__/host-bash-proxy.test.ts +0 -5
- package/src/__tests__/host-browser-e2e-cloud.test.ts +138 -4
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +4 -4
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +103 -0
- package/src/__tests__/host-cu-proxy.test.ts +0 -5
- package/src/__tests__/host-shell-tool.test.ts +124 -18
- package/src/__tests__/http-user-message-parity.test.ts +29 -1
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/intent-routing.test.ts +1 -40
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/llm-catalog-parity.test.ts +174 -0
- package/src/__tests__/llm-context-normalization.test.ts +609 -0
- package/src/__tests__/llm-context-route-provider.test.ts +86 -5
- package/src/__tests__/llm-resolver.test.ts +214 -0
- package/src/__tests__/llm-schema.test.ts +223 -0
- package/src/__tests__/llm-usage-store.test.ts +363 -0
- package/src/__tests__/managed-proxy-context.test.ts +6 -2
- package/src/__tests__/media-stream-output.test.ts +555 -0
- package/src/__tests__/media-stream-parser.test.ts +374 -0
- package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
- package/src/__tests__/media-stream-stt-session.test.ts +588 -0
- package/src/__tests__/media-turn-detector.test.ts +440 -0
- package/src/__tests__/message-queue.test.ts +125 -0
- package/src/__tests__/messaging-skill-split.test.ts +3 -34
- package/src/__tests__/migration-export-http.test.ts +6 -6
- package/src/__tests__/migration-import-commit-http.test.ts +8 -6
- package/src/__tests__/migration-import-from-url.test.ts +684 -0
- package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +151 -0
- package/src/__tests__/model-intents.test.ts +10 -84
- package/src/__tests__/notification-decision-fallback.test.ts +0 -10
- package/src/__tests__/notification-decision-identity.test.ts +0 -9
- package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
- package/src/__tests__/oauth-apps-routes.test.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +2 -0
- package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +1 -0
- package/src/__tests__/oauth-providers-routes.test.ts +2 -0
- package/src/__tests__/oauth-store.test.ts +95 -7
- package/src/__tests__/oauth2-gateway-transport.test.ts +257 -9
- package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
- package/src/__tests__/onboarding-template-contract.test.ts +6 -13
- package/src/__tests__/openai-provider.test.ts +183 -0
- package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
- package/src/__tests__/openai-responses-provider.test.ts +1501 -0
- package/src/__tests__/openrouter-provider-only.test.ts +135 -0
- package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +1 -1
- package/src/__tests__/permission-mode.test.ts +16 -0
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/pkb-autoinject.test.ts +37 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -1
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +224 -3
- package/src/__tests__/profiler-routes.test.ts +1 -1
- package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
- package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
- package/src/__tests__/provider-error-scenarios.test.ts +135 -6
- package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
- package/src/__tests__/provider-registry-ollama.test.ts +1 -2
- package/src/__tests__/proxy-approval-callback.test.ts +0 -1
- package/src/__tests__/qdrant-manager.test.ts +29 -8
- package/src/__tests__/reaction-persistence.test.ts +560 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
- package/src/__tests__/relationship-state-contract.test.ts +175 -0
- package/src/__tests__/relay-server.test.ts +424 -6
- package/src/__tests__/require-fresh-approval.test.ts +1 -1
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
- package/src/__tests__/risk-classifier-parity.test.ts +230 -0
- package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-ingress-http.test.ts +28 -0
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
- package/src/__tests__/secret-scanner-executor.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +107 -0
- package/src/__tests__/send-endpoint-busy.test.ts +34 -2
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +80 -0
- package/src/__tests__/settings-routes.test.ts +201 -0
- package/src/__tests__/shell-parser-property.test.ts +13 -13
- package/src/__tests__/skill-cache-store.test.ts +182 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +276 -145
- package/src/__tests__/skills-files-catalog-fallback.test.ts +381 -93
- package/src/__tests__/skills.test.ts +19 -30
- package/src/__tests__/skillssh-files.test.ts +446 -0
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-block-formatting.test.ts +110 -0
- package/src/__tests__/slack-channel-config.test.ts +564 -1
- package/src/__tests__/slack-skill.test.ts +3 -8
- package/src/__tests__/starter-bundle.test.ts +35 -0
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
- package/src/__tests__/suggestion-routes.test.ts +160 -3
- package/src/__tests__/system-prompt.test.ts +126 -53
- package/src/__tests__/task-runner.test.ts +3 -1
- package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +26 -7
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +2 -49
- package/src/__tests__/thread-backfill.test.ts +941 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -2
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +10 -6
- package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +88 -113
- package/src/__tests__/tool-result-truncation.test.ts +36 -0
- package/src/__tests__/trust-store.test.ts +442 -103
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +345 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
- package/src/__tests__/twilio-routes.test.ts +376 -0
- package/src/__tests__/unicode.test.ts +293 -0
- package/src/__tests__/update-bulletin-job.test.ts +389 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
- package/src/__tests__/usage-routes.test.ts +25 -4
- package/src/__tests__/user-reference.test.ts +46 -61
- package/src/__tests__/verification-control-plane-policy.test.ts +5 -22
- package/src/__tests__/voice-config-update.test.ts +403 -0
- package/src/__tests__/voice-quality.test.ts +434 -19
- package/src/__tests__/voice-session-bridge.test.ts +39 -0
- package/src/__tests__/volume-security-guard.test.ts +3 -2
- package/src/__tests__/web-search-history.test.ts +337 -0
- package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
- package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
- package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
- package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
- package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
- package/src/__tests__/workspace-migration-meets.test.ts +244 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
- package/src/__tests__/workspace-policy.test.ts +1 -11
- package/src/acp/client-handler.ts +1 -2
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +251 -19
- package/src/avatar/resvg-lazy.test.ts +136 -0
- package/src/avatar/resvg-lazy.ts +82 -9
- package/src/avatar/traits-png-sync.ts +21 -1
- package/src/backup/__tests__/backup-key.test.ts +152 -0
- package/src/backup/__tests__/backup-worker.test.ts +767 -0
- package/src/backup/__tests__/list-snapshots.test.ts +87 -0
- package/src/backup/__tests__/local-writer.test.ts +218 -0
- package/src/backup/__tests__/offsite-writer.test.ts +641 -0
- package/src/backup/__tests__/paths.test.ts +300 -0
- package/src/backup/__tests__/restore.test.ts +498 -0
- package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
- package/src/backup/__tests__/stream-crypt.test.ts +228 -0
- package/src/backup/backup-key.ts +137 -0
- package/src/backup/backup-worker.ts +459 -0
- package/src/backup/list-snapshots.ts +147 -0
- package/src/backup/local-writer.ts +133 -0
- package/src/backup/offsite-writer.ts +222 -0
- package/src/backup/paths.ts +226 -0
- package/src/backup/restore.ts +322 -0
- package/src/backup/snapshot-lock.ts +431 -0
- package/src/backup/stream-crypt.ts +263 -0
- package/src/browser/__tests__/operations.test.ts +163 -0
- package/src/browser/identifiers.ts +51 -0
- package/src/browser/operations.ts +660 -0
- package/src/browser/types.ts +81 -0
- package/src/bundler/package-resolver.ts +4 -0
- package/src/calls/audio-store.ts +11 -5
- package/src/calls/call-controller.ts +226 -71
- package/src/calls/call-domain.ts +9 -0
- package/src/calls/call-speech-output.ts +190 -0
- package/src/calls/call-transport.ts +77 -0
- package/src/calls/guardian-question-copy.ts +2 -2
- package/src/calls/media-stream-audio-transcode.ts +173 -0
- package/src/calls/media-stream-output.ts +660 -0
- package/src/calls/media-stream-parser.ts +300 -0
- package/src/calls/media-stream-protocol.ts +166 -0
- package/src/calls/media-stream-server.ts +592 -0
- package/src/calls/media-stream-stt-session.ts +460 -0
- package/src/calls/media-turn-detector.ts +230 -0
- package/src/calls/relay-server.ts +90 -75
- package/src/calls/resolve-call-tts-provider.ts +136 -0
- package/src/calls/telephony-stt-routing.ts +145 -0
- package/src/calls/tts-call-strategy.ts +161 -0
- package/src/calls/tts-text-sanitizer.ts +32 -16
- package/src/calls/twilio-routes.ts +281 -17
- package/src/calls/voice-quality.ts +78 -35
- package/src/calls/voice-session-bridge.ts +9 -1
- package/src/channels/types.ts +16 -0
- package/src/cli/AGENTS.md +1 -1
- package/src/cli/__tests__/run-assistant-command.ts +11 -1
- package/src/cli/commands/__tests__/attachment.test.ts +438 -0
- package/src/cli/commands/__tests__/backup.test.ts +1165 -0
- package/src/cli/commands/__tests__/browser.test.ts +554 -0
- package/src/cli/commands/__tests__/cache.test.ts +623 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
- package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
- package/src/cli/commands/__tests__/email-download.test.ts +16 -1
- package/src/cli/commands/__tests__/email-list.test.ts +28 -4
- package/src/cli/commands/__tests__/email-register.test.ts +4 -4
- package/src/cli/commands/__tests__/email-send.test.ts +130 -5
- package/src/cli/commands/__tests__/email-status.test.ts +5 -1
- package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
- package/src/cli/commands/__tests__/image-generation.test.ts +666 -0
- package/src/cli/commands/__tests__/inference-send.test.ts +451 -0
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
- package/src/cli/commands/__tests__/task.test.ts +913 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +594 -0
- package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
- package/src/cli/commands/__tests__/ui.test.ts +1215 -0
- package/src/cli/commands/__tests__/watchers.test.ts +716 -0
- package/src/cli/commands/attachment.ts +182 -0
- package/src/cli/commands/backup.ts +993 -0
- package/src/cli/commands/browser.ts +350 -0
- package/src/cli/commands/cache.ts +341 -0
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/config.ts +6 -6
- package/src/cli/commands/conversations-import.ts +347 -0
- package/src/cli/commands/conversations.ts +90 -0
- package/src/cli/commands/credentials.ts +0 -1
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +308 -16
- package/src/cli/commands/image-generation.ts +300 -0
- package/src/cli/commands/inference.ts +200 -0
- package/src/cli/commands/memory.ts +127 -17
- package/src/cli/commands/oauth/__tests__/connect.test.ts +12 -0
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +1 -0
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -0
- package/src/cli/commands/oauth/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +15 -0
- package/src/cli/commands/oauth/shared.ts +2 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +4 -10
- package/src/cli/commands/platform/__tests__/connect.test.ts +6 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -2
- package/src/cli/commands/platform/__tests__/status.test.ts +6 -1
- package/src/cli/commands/stt.ts +339 -0
- package/src/cli/commands/task.ts +795 -0
- package/src/cli/commands/trust.ts +50 -19
- package/src/cli/commands/tts.ts +273 -0
- package/src/cli/commands/ui.ts +670 -0
- package/src/cli/commands/watchers.ts +509 -0
- package/src/cli/lib/daemon-credential-client.ts +0 -19
- package/src/cli/program.ts +53 -8
- package/src/cli.ts +0 -37
- package/src/config/__tests__/backup-schema.test.ts +134 -0
- package/src/config/assistant-feature-flags.ts +61 -62
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +37 -1
- package/src/config/bundled-skills/contacts/SKILL.md +2 -2
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +23 -1
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
- package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
- package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
- package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
- package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -2
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +11 -12
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +28 -18
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
- package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
- package/src/config/bundled-tool-registry.ts +0 -167
- package/src/config/env-registry.ts +24 -0
- package/src/config/env.ts +39 -10
- package/src/config/feature-flag-registry.json +63 -15
- package/src/config/llm-resolver.ts +128 -0
- package/src/config/loader.ts +220 -22
- package/src/config/raw-config-utils.ts +30 -2
- package/src/config/sanitize-for-transfer.ts +35 -0
- package/src/config/schema.ts +65 -51
- package/src/config/schemas/__tests__/stt.test.ts +43 -0
- package/src/config/schemas/analysis.ts +32 -0
- package/src/config/schemas/backup.ts +72 -0
- package/src/config/schemas/calls.ts +1 -30
- package/src/config/schemas/elevenlabs.ts +0 -59
- package/src/config/schemas/filing.ts +49 -14
- package/src/config/schemas/heartbeat.ts +27 -10
- package/src/config/schemas/host-browser.ts +47 -1
- package/src/config/schemas/inference.ts +3 -23
- package/src/config/schemas/llm.ts +318 -0
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/memory-processing.ts +1 -9
- package/src/config/schemas/notifications.ts +4 -11
- package/src/config/schemas/platform.ts +3 -9
- package/src/config/schemas/security.ts +33 -0
- package/src/config/schemas/services.ts +53 -4
- package/src/config/schemas/stt.ts +60 -0
- package/src/config/schemas/tts.ts +283 -0
- package/src/config/schemas/updates.ts +14 -0
- package/src/config/schemas/workspace-git.ts +3 -40
- package/src/config/skills.ts +6 -2
- package/src/config/types.ts +4 -0
- package/src/contacts/contact-store.ts +56 -11
- package/src/contacts/contacts-write.ts +38 -1
- package/src/context/__tests__/compact-prompt.test.ts +45 -0
- package/src/context/__tests__/microcompact.test.ts +805 -0
- package/src/context/estimator-calibration.ts +136 -0
- package/src/context/microcompact.ts +443 -0
- package/src/context/post-turn-tool-result-truncation.ts +3 -2
- package/src/context/prompts/compact.md +12 -0
- package/src/context/token-estimator.ts +61 -3
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +272 -35
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/executable-discovery.ts +23 -2
- package/src/credential-execution/process-manager.test.ts +109 -0
- package/src/credential-execution/process-manager.ts +96 -2
- package/src/credential-health/credential-health-service.ts +366 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +17 -8
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/approval-generators.ts +29 -4
- package/src/daemon/assistant-attachments.ts +24 -13
- package/src/daemon/classifier.ts +2 -2
- package/src/daemon/config-watcher.ts +99 -6
- package/src/daemon/context-overflow-reducer.ts +4 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +85 -12
- package/src/daemon/conversation-agent-loop.ts +563 -104
- package/src/daemon/conversation-attachments.ts +2 -6
- package/src/daemon/conversation-error.ts +46 -0
- package/src/daemon/conversation-history.ts +40 -6
- package/src/daemon/conversation-launch.ts +220 -0
- package/src/daemon/conversation-lifecycle.ts +85 -11
- package/src/daemon/conversation-messaging.ts +110 -7
- package/src/daemon/conversation-notifiers.ts +5 -0
- package/src/daemon/conversation-process.ts +591 -23
- package/src/daemon/conversation-queue-manager.ts +27 -0
- package/src/daemon/conversation-runtime-assembly.ts +769 -28
- package/src/daemon/conversation-slash.ts +38 -2
- package/src/daemon/conversation-surfaces.ts +483 -5
- package/src/daemon/conversation-tool-setup.ts +35 -5
- package/src/daemon/conversation-usage.ts +8 -5
- package/src/daemon/conversation.ts +193 -47
- package/src/daemon/external-skills-bootstrap.ts +41 -0
- package/src/daemon/guardian-action-generators.ts +34 -14
- package/src/daemon/handlers/config-model.test.ts +86 -0
- package/src/daemon/handlers/config-model.ts +54 -12
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +13 -3
- package/src/daemon/handlers/shared.ts +51 -1
- package/src/daemon/handlers/skills.ts +323 -79
- package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
- package/src/daemon/host-browser-proxy.ts +2 -1
- package/src/daemon/lifecycle.ts +185 -26
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/conversations.ts +48 -1
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +23 -1
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +16 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/trust.ts +0 -2
- package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
- package/src/daemon/pkb-context-tracker.test.ts +169 -0
- package/src/daemon/pkb-context-tracker.ts +125 -0
- package/src/daemon/pkb-reminder-builder.test.ts +70 -0
- package/src/daemon/pkb-reminder-builder.ts +31 -0
- package/src/daemon/providers-setup.ts +6 -0
- package/src/daemon/server.ts +463 -10
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +9 -9
- package/src/daemon/watch-handler.ts +4 -4
- package/src/daemon/web-search-history.ts +126 -0
- package/src/email/html-renderer.ts +76 -0
- package/src/events/domain-events.ts +0 -1
- package/src/filing/filing-service.ts +9 -10
- package/src/heartbeat/heartbeat-service.ts +156 -22
- package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
- package/src/home/__tests__/emit-feed-event.test.ts +169 -0
- package/src/home/__tests__/feed-scheduler.test.ts +222 -0
- package/src/home/__tests__/feed-types.test.ts +275 -0
- package/src/home/__tests__/feed-writer.test.ts +688 -0
- package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
- package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
- package/src/home/__tests__/progress-formula.test.ts +213 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
- package/src/home/__tests__/rollup-producer.test.ts +442 -0
- package/src/home/assistant-feed-authoring.ts +128 -0
- package/src/home/emit-feed-event.ts +162 -0
- package/src/home/feed-scheduler.ts +263 -0
- package/src/home/feed-types.ts +235 -0
- package/src/home/feed-writer.ts +469 -0
- package/src/home/platform-gmail-digest.ts +163 -0
- package/src/home/progress-formula.ts +86 -0
- package/src/home/relationship-state-writer.ts +824 -0
- package/src/home/relationship-state.ts +143 -0
- package/src/home/rollup-producer.ts +413 -0
- package/src/home/suggested-prompts.ts +101 -0
- package/src/hooks/runner.ts +7 -0
- package/src/inbound/platform-callback-registration.ts +12 -3
- package/src/inbound/public-ingress-urls.ts +12 -0
- package/src/instrument.ts +1 -1
- package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
- package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
- package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
- package/src/ipc/__tests__/socket-path.test.ts +73 -0
- package/src/ipc/__tests__/task-ipc.test.ts +577 -0
- package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
- package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
- package/src/ipc/cli-client.ts +152 -0
- package/src/ipc/cli-server.ts +252 -0
- package/src/ipc/gateway-client.ts +180 -0
- package/src/ipc/routes/attachment.ts +114 -0
- package/src/ipc/routes/browser-context.ts +61 -0
- package/src/ipc/routes/browser.ts +96 -0
- package/src/ipc/routes/cache.ts +96 -0
- package/src/ipc/routes/index.ts +21 -0
- package/src/ipc/routes/task-queue.ts +226 -0
- package/src/ipc/routes/task.ts +173 -0
- package/src/ipc/routes/ui-request.ts +50 -0
- package/src/ipc/routes/wake-conversation.ts +19 -0
- package/src/ipc/routes/watcher.ts +203 -0
- package/src/ipc/socket-path.ts +100 -0
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
- package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +233 -0
- package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
- package/src/memory/admin.ts +18 -0
- package/src/memory/app-store.ts +1 -1
- package/src/memory/attachments-store.ts +70 -0
- package/src/memory/auto-analysis-enqueue.ts +127 -0
- package/src/memory/auto-analysis-guard.ts +27 -0
- package/src/memory/cleanup-schedule-state.ts +37 -0
- package/src/memory/conversation-analyze-job.ts +74 -0
- package/src/memory/conversation-attention-store.ts +13 -6
- package/src/memory/conversation-crud.ts +199 -0
- package/src/memory/conversation-disk-view.ts +7 -0
- package/src/memory/conversation-group-migration.ts +65 -1
- package/src/memory/conversation-queries.ts +6 -5
- package/src/memory/conversation-title-service.ts +7 -4
- package/src/memory/db-init.ts +8 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/embedding-backend.ts +1 -1
- package/src/memory/graph/compaction.ts +299 -0
- package/src/memory/graph/consolidation.ts +4 -4
- package/src/memory/graph/conversation-graph-memory.ts +104 -29
- package/src/memory/graph/extraction.test.ts +295 -2
- package/src/memory/graph/extraction.ts +181 -51
- package/src/memory/graph/graph-search.test.ts +92 -0
- package/src/memory/graph/graph-search.ts +4 -1
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.test.ts +459 -0
- package/src/memory/graph/retriever.ts +257 -66
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/store.ts +41 -0
- package/src/memory/graph/tool-handlers.ts +27 -0
- package/src/memory/graph/tools.ts +6 -1
- package/src/memory/group-crud.ts +6 -1
- package/src/memory/indexer.ts +95 -16
- package/src/memory/job-handlers/cleanup.ts +11 -8
- package/src/memory/job-handlers/conversation-starters.ts +39 -30
- package/src/memory/job-handlers/summarization.ts +2 -2
- package/src/memory/job-utils.ts +7 -1
- package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
- package/src/memory/jobs/embed-pkb-file.ts +54 -0
- package/src/memory/jobs-store.ts +106 -5
- package/src/memory/jobs-worker.ts +26 -9
- package/src/memory/llm-usage-store.ts +92 -56
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
- package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
- package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-index.test.ts +368 -0
- package/src/memory/pkb/pkb-index.ts +255 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +251 -0
- package/src/memory/pkb/pkb-reconcile.ts +148 -0
- package/src/memory/pkb/pkb-search.test.ts +438 -0
- package/src/memory/pkb/pkb-search.ts +137 -0
- package/src/memory/pkb/types.ts +53 -0
- package/src/memory/qdrant-client.ts +122 -1
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/oauth.ts +3 -0
- package/src/memory/slack-thread-store.ts +37 -0
- package/src/memory/usage-buckets.ts +396 -0
- package/src/messaging/providers/gmail/adapter.ts +6 -16
- package/src/messaging/providers/gmail/client.ts +79 -6
- package/src/messaging/providers/gmail/types.ts +7 -0
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
- package/src/messaging/providers/slack/adapter.ts +155 -38
- package/src/messaging/providers/slack/backfill.test.ts +257 -0
- package/src/messaging/providers/slack/backfill.ts +101 -0
- package/src/messaging/providers/slack/client.ts +16 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
- package/src/messaging/providers/slack/message-metadata.ts +123 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1373 -0
- package/src/messaging/providers/slack/render-transcript.ts +443 -0
- package/src/messaging/providers/slack/types.ts +4 -0
- package/src/messaging/style-analyzer.ts +5 -2
- package/src/notifications/README.md +9 -5
- package/src/notifications/decision-engine.ts +6 -12
- package/src/notifications/preference-extractor.ts +2 -6
- package/src/notifications/signal.ts +5 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +1 -0
- package/src/oauth/byo-connection.test.ts +18 -1
- package/src/oauth/byo-connection.ts +3 -1
- package/src/oauth/connect-orchestrator.ts +2 -0
- package/src/oauth/connection-resolver.ts +6 -2
- package/src/oauth/connection.ts +2 -0
- package/src/oauth/oauth-store.ts +10 -0
- package/src/oauth/platform-connection.test.ts +145 -0
- package/src/oauth/platform-connection.ts +62 -31
- package/src/oauth/seed-providers.ts +10 -1
- package/src/permissions/approval-policy.test.ts +948 -0
- package/src/permissions/approval-policy.ts +257 -0
- package/src/permissions/bash-risk-classifier.test.ts +1208 -0
- package/src/permissions/bash-risk-classifier.ts +707 -0
- package/src/permissions/checker.ts +218 -699
- package/src/permissions/command-registry.test.ts +535 -0
- package/src/permissions/command-registry.ts +825 -0
- package/src/permissions/defaults.ts +71 -75
- package/src/permissions/file-risk-classifier.test.ts +535 -0
- package/src/permissions/file-risk-classifier.ts +274 -0
- package/src/permissions/risk-types.ts +205 -0
- package/src/permissions/secret-prompter.ts +53 -2
- package/src/permissions/skill-risk-classifier.test.ts +311 -0
- package/src/permissions/skill-risk-classifier.ts +214 -0
- package/src/permissions/trust-client.ts +52 -25
- package/src/permissions/trust-store-interface.ts +1 -6
- package/src/permissions/trust-store.ts +164 -65
- package/src/permissions/types.ts +23 -14
- package/src/permissions/web-risk-classifier.test.ts +170 -0
- package/src/permissions/web-risk-classifier.ts +89 -0
- package/src/permissions/workspace-policy.ts +1 -13
- package/src/platform/client.test.ts +10 -0
- package/src/platform/client.ts +19 -1
- package/src/platform/sync-identity.ts +129 -0
- package/src/prompts/persona-resolver.ts +127 -3
- package/src/prompts/system-prompt.ts +78 -38
- package/src/prompts/templates/BOOTSTRAP.md +5 -5
- package/src/prompts/templates/SOUL.md +5 -3
- package/src/prompts/templates/channels/slack.md +20 -0
- package/src/prompts/update-bulletin-job.ts +190 -0
- package/src/prompts/user-reference.ts +20 -17
- package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
- package/src/providers/__tests__/retry-callsite.test.ts +424 -0
- package/src/providers/anthropic/client.ts +335 -70
- package/src/providers/call-site-routing.ts +71 -0
- package/src/providers/fireworks/client.ts +2 -2
- package/src/providers/gemini/client.ts +74 -3
- package/src/providers/managed-proxy/constants.ts +2 -1
- package/src/providers/model-catalog.ts +502 -28
- package/src/providers/model-intents.ts +8 -8
- package/src/providers/ollama/client.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +530 -0
- package/src/providers/openai/client.ts +25 -440
- package/src/providers/openai/responses-provider.ts +579 -0
- package/src/providers/openrouter/client.ts +168 -4
- package/src/providers/provider-env-vars.ts +56 -0
- package/src/providers/provider-secret-catalog.ts +139 -0
- package/src/providers/provider-send-message.ts +22 -5
- package/src/providers/ratelimit.ts +4 -0
- package/src/providers/registry.ts +21 -10
- package/src/providers/retry.ts +185 -39
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +883 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
- package/src/providers/speech-to-text/deepgram.test.ts +332 -0
- package/src/providers/speech-to-text/deepgram.ts +115 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
- package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
- package/src/providers/speech-to-text/google-gemini.ts +101 -0
- package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
- package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
- package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
- package/src/providers/speech-to-text/openai-whisper.ts +63 -33
- package/src/providers/speech-to-text/provider-catalog.ts +323 -0
- package/src/providers/speech-to-text/resolve.ts +393 -6
- package/src/providers/speech-to-text/xai-realtime.test.ts +578 -0
- package/src/providers/speech-to-text/xai-realtime.ts +796 -0
- package/src/providers/speech-to-text/xai.test.ts +155 -0
- package/src/providers/speech-to-text/xai.ts +97 -0
- package/src/providers/types.ts +102 -3
- package/src/runtime/AGENTS.md +45 -3
- package/src/runtime/__tests__/agent-wake.test.ts +872 -0
- package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
- package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
- package/src/runtime/agent-wake.ts +553 -0
- package/src/runtime/auth/__tests__/route-policy.test.ts +40 -0
- package/src/runtime/auth/route-policy.ts +34 -5
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +15 -3
- package/src/runtime/capability-tokens.ts +10 -10
- package/src/runtime/channel-invite-transport.ts +1 -1
- package/src/runtime/channel-invite-transports/email.ts +14 -6
- package/src/runtime/channel-readiness-service.ts +12 -22
- package/src/runtime/channel-reply-delivery.ts +106 -2
- package/src/runtime/chrome-extension-registry.ts +38 -2
- package/src/runtime/decision-token.ts +116 -0
- package/src/runtime/gateway-client.ts +2 -2
- package/src/runtime/http-router.ts +32 -0
- package/src/runtime/http-server.ts +447 -11
- package/src/runtime/http-types.ts +29 -3
- package/src/runtime/interactive-ui.ts +362 -0
- package/src/runtime/invite-instruction-generator.ts +2 -2
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +36 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
- package/src/runtime/migrations/gcs-signed-url.ts +162 -0
- package/src/runtime/migrations/migration-transport.ts +1 -0
- package/src/runtime/migrations/migration-wizard.ts +1 -0
- package/src/runtime/migrations/vbundle-import-analyzer.ts +77 -1
- package/src/runtime/migrations/vbundle-importer.ts +187 -8
- package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
- package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
- package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
- package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
- package/src/runtime/migrations/vbundle-validator.ts +15 -6
- package/src/runtime/pending-interactions.ts +0 -11
- package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +618 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +247 -0
- package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
- package/src/runtime/routes/app-management-routes.ts +12 -18
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +58 -0
- package/src/runtime/routes/approval-routes.ts +12 -17
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
- package/src/runtime/routes/attachment-routes.test.ts +9 -3
- package/src/runtime/routes/attachment-routes.ts +216 -17
- package/src/runtime/routes/avatar-routes.ts +20 -4
- package/src/runtime/routes/backup-routes.ts +519 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +82 -23
- package/src/runtime/routes/btw-routes.ts +9 -10
- package/src/runtime/routes/contact-routes.test.ts +298 -0
- package/src/runtime/routes/contact-routes.ts +132 -5
- package/src/runtime/routes/conversation-analysis-routes.ts +22 -142
- package/src/runtime/routes/conversation-management-routes.ts +133 -0
- package/src/runtime/routes/conversation-routes.ts +487 -160
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/diagnostics-routes.ts +6 -4
- package/src/runtime/routes/events-routes.ts +16 -0
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/guardian-approval-interception.ts +33 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
- package/src/runtime/routes/home-feed-routes.ts +452 -0
- package/src/runtime/routes/home-state-routes.ts +138 -0
- package/src/runtime/routes/host-browser-routes.ts +3 -14
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +3 -17
- package/src/runtime/routes/inbound-message-handler.ts +912 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
- package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
- package/src/runtime/routes/integrations/slack/channel.ts +36 -6
- package/src/runtime/routes/integrations/slack/share.ts +45 -7
- package/src/runtime/routes/llm-context-normalization.ts +325 -0
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/migration-routes.ts +722 -91
- package/src/runtime/routes/settings-routes.ts +26 -7
- package/src/runtime/routes/skills-routes.ts +76 -7
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/surface-action-routes.ts +41 -2
- package/src/runtime/routes/trust-rules-routes.ts +30 -14
- package/src/runtime/routes/tts-routes.ts +108 -24
- package/src/runtime/routes/usage-routes.ts +30 -2
- package/src/runtime/routes/user-route-dispatcher.ts +50 -5
- package/src/runtime/routes/user-routes.ts +13 -1
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +11 -3
- package/src/runtime/runtime-mode.ts +33 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +426 -0
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
- package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
- package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
- package/src/runtime/services/analyze-conversation.ts +340 -0
- package/src/runtime/services/analyze-deps-singleton.ts +32 -0
- package/src/runtime/services/auto-analysis-prompt.ts +55 -0
- package/src/runtime/skill-route-registry.ts +71 -0
- package/src/runtime/slack-block-formatting.ts +437 -10
- package/src/schedule/scheduler.ts +58 -0
- package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
- package/src/security/__tests__/untrusted-content.test.ts +109 -0
- package/src/security/oauth2.ts +122 -37
- package/src/security/secure-keys.ts +32 -10
- package/src/security/token-manager.ts +35 -13
- package/src/security/untrusted-content.ts +102 -0
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-cache.ts +26 -7
- package/src/skills/catalog-files.ts +64 -2
- package/src/skills/catalog-install.ts +31 -3
- package/src/skills/category-inference.ts +122 -0
- package/src/skills/clawhub-files.ts +213 -0
- package/src/skills/clawhub.ts +84 -23
- package/src/skills/skill-cache-store.ts +97 -0
- package/src/skills/skill-file-provider.ts +40 -0
- package/src/skills/skillssh-files.ts +395 -0
- package/src/skills/skillssh-registry.ts +4 -4
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +468 -0
- package/src/stt/__tests__/types.test.ts +89 -0
- package/src/stt/daemon-batch-transcriber.ts +228 -0
- package/src/stt/stt-stream-session.ts +506 -0
- package/src/stt/types.ts +334 -0
- package/src/stt/wav-encoder.test.ts +373 -0
- package/src/stt/wav-encoder.ts +175 -0
- package/src/subagent/manager.ts +79 -27
- package/src/tasks/ephemeral-permissions.ts +9 -4
- package/src/telemetry/usage-telemetry-reporter.ts +27 -5
- package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
- package/src/tools/browser/__tests__/browser-status.test.ts +166 -0
- package/src/tools/browser/browser-execution.ts +1208 -41
- package/src/tools/browser/browser-manager.ts +45 -0
- package/src/tools/browser/browser-mode-constants.ts +12 -0
- package/src/tools/browser/browser-mode.ts +92 -0
- package/src/tools/browser/browser-status-constants.ts +33 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +393 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +29 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1648 -32
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +264 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +205 -17
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +254 -21
- package/src/tools/browser/cdp-client/errors.ts +15 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +39 -16
- package/src/tools/browser/cdp-client/factory.ts +797 -87
- package/src/tools/browser/cdp-client/index.ts +16 -2
- package/src/tools/browser/cdp-client/types.ts +68 -0
- package/src/tools/credentials/tool-policy.ts +39 -5
- package/src/tools/credentials/vault.ts +41 -7
- package/src/tools/executor.ts +4 -0
- package/src/tools/filesystem/write.ts +52 -0
- package/src/tools/host-terminal/host-shell.ts +45 -5
- package/src/tools/memory/register.test.ts +185 -0
- package/src/tools/memory/register.ts +3 -1
- package/src/tools/network/web-fetch.ts +25 -12
- package/src/tools/network/web-search.ts +20 -2
- package/src/tools/permission-checker.ts +36 -15
- package/src/tools/policy-context.ts +25 -8
- package/src/tools/registry.ts +55 -3
- package/src/tools/shared/shell-output.ts +3 -1
- package/src/tools/side-effects.ts +0 -9
- package/src/tools/skills/execute.ts +2 -2
- package/src/tools/skills/sandbox-runner.ts +6 -2
- package/src/tools/terminal/backends/native.ts +51 -2
- package/src/tools/terminal/safe-env.ts +11 -2
- package/src/tools/terminal/shell.ts +16 -4
- package/src/tools/tool-manifest.ts +6 -0
- package/src/tools/types.ts +29 -3
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tools/verification-control-plane-policy.ts +1 -1
- package/src/tts/__tests__/provider-adapters.test.ts +1061 -0
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
- package/src/tts/__tests__/provider-catalog.test.ts +183 -0
- package/src/tts/__tests__/provider-registry.test.ts +90 -0
- package/src/tts/provider-catalog.ts +219 -0
- package/src/tts/provider-registry.ts +73 -0
- package/src/tts/providers/deepgram-provider.ts +219 -0
- package/src/tts/providers/elevenlabs-provider.ts +211 -0
- package/src/tts/providers/fish-audio-provider.ts +183 -0
- package/src/tts/providers/index.ts +44 -0
- package/src/tts/providers/register-builtins.ts +130 -0
- package/src/tts/providers/xai-provider.ts +224 -0
- package/src/tts/synthesize-text.ts +110 -0
- package/src/tts/tts-config-resolver.ts +78 -0
- package/src/tts/types.ts +199 -0
- package/src/types/onboarding-context.ts +7 -0
- package/src/types/tar-stream.d.ts +66 -0
- package/src/util/abort-reasons.ts +58 -0
- package/src/util/device-id.ts +32 -16
- package/src/util/errors.ts +9 -1
- package/src/util/json.ts +17 -0
- package/src/util/platform.ts +56 -12
- package/src/util/pricing.ts +78 -5
- package/src/util/spawn.ts +1 -1
- package/src/util/truncate.ts +4 -2
- package/src/util/unicode.ts +201 -0
- package/src/version.ts +19 -24
- package/src/watcher/engine.ts +24 -1
- package/src/watcher/providers/google-calendar.ts +134 -8
- package/src/watcher/providers/outlook-calendar.ts +42 -2
- package/src/watcher/watcher-store.ts +31 -0
- package/src/workspace/git-service.ts +23 -4
- package/src/workspace/migrations/003-seed-device-id.ts +9 -3
- package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
- package/src/workspace/migrations/029-seed-pkb.ts +1 -1
- package/src/workspace/migrations/031-drop-user-md.ts +317 -0
- package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
- package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
- package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
- package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
- package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
- package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
- package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
- package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
- package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +57 -0
- package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
- package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
- package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
- package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/registry.ts +32 -0
- package/src/workspace/provider-commit-message-generator.ts +19 -38
- package/src/workspace/top-level-renderer.ts +13 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- package/src/__tests__/outlook-attachments.test.ts +0 -301
- package/src/__tests__/outlook-automation-tools.test.ts +0 -425
- package/src/__tests__/outlook-categories.test.ts +0 -212
- package/src/__tests__/outlook-compose-tools.test.ts +0 -325
- package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
- package/src/__tests__/outlook-follow-up.test.ts +0 -196
- package/src/__tests__/outlook-trash.test.ts +0 -77
- package/src/__tests__/outlook-unsubscribe.test.ts +0 -250
- package/src/__tests__/update-bulletin-format.test.ts +0 -122
- package/src/__tests__/update-bulletin-state.test.ts +0 -135
- package/src/__tests__/update-bulletin.test.ts +0 -277
- package/src/__tests__/update-template-contract.test.ts +0 -29
- package/src/cli/commands/browser-relay.ts +0 -466
- package/src/cli/commands/doctor.ts +0 -341
- package/src/config/bundled-skills/browser/SKILL.md +0 -63
- package/src/config/bundled-skills/browser/TOOLS.json +0 -393
- package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -32
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
- package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
- package/src/config/bundled-skills/gmail/SKILL.md +0 -175
- package/src/config/bundled-skills/gmail/TOOLS.json +0 -558
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -149
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -220
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -251
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
- package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
- package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
- package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/google-calendar/types.ts +0 -97
- package/src/config/bundled-skills/outlook/SKILL.md +0 -196
- package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
- package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
- package/src/config/bundled-skills/slack/SKILL.md +0 -107
- package/src/config/bundled-skills/tasks/SKILL.md +0 -37
- package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
- package/src/config/bundled-skills/tasks/icon.svg +0 -34
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
- package/src/config/bundled-skills/watcher/SKILL.md +0 -31
- package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
- package/src/email/guardrails.ts +0 -221
- package/src/email/provider.ts +0 -117
- package/src/email/providers/agentmail.ts +0 -361
- package/src/email/providers/index.ts +0 -65
- package/src/email/service.ts +0 -384
- package/src/email/types.ts +0 -126
- package/src/prompts/templates/UPDATES.md +0 -38
- package/src/prompts/templates/USER.md +0 -13
- package/src/prompts/update-bulletin-format.ts +0 -68
- package/src/prompts/update-bulletin-state.ts +0 -58
- package/src/prompts/update-bulletin-template-path.ts +0 -13
- package/src/prompts/update-bulletin.ts +0 -128
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/runtime/routes/browser-cdp-routes.ts +0 -229
- package/src/shared/provider-env-vars.ts +0 -19
- package/src/tools/watcher/create.ts +0 -86
- package/src/tools/watcher/delete.ts +0 -36
- package/src/tools/watcher/digest.ts +0 -54
- package/src/tools/watcher/list.ts +0 -83
- package/src/tools/watcher/update.ts +0 -71
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* runAgentLoop method here via the AgentLoopConversationContext interface.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
|
|
10
12
|
import { v4 as uuid } from "uuid";
|
|
11
13
|
|
|
12
14
|
import type {
|
|
@@ -24,10 +26,18 @@ import type {
|
|
|
24
26
|
} from "../channels/types.js";
|
|
25
27
|
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
26
28
|
import { getConfig } from "../config/loader.js";
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
+
import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
30
|
+
import {
|
|
31
|
+
derefToolResultReReads,
|
|
32
|
+
postTurnTruncateToolResults,
|
|
33
|
+
} from "../context/post-turn-tool-result-truncation.js";
|
|
34
|
+
import {
|
|
35
|
+
estimatePromptTokens,
|
|
36
|
+
getCalibrationProviderKey,
|
|
37
|
+
} from "../context/token-estimator.js";
|
|
29
38
|
import type { ContextWindowManager } from "../context/window-manager.js";
|
|
30
39
|
import type { ToolProfiler } from "../events/tool-profiling-listener.js";
|
|
40
|
+
import { writeRelationshipState } from "../home/relationship-state-writer.js";
|
|
31
41
|
import { getHookManager } from "../hooks/manager.js";
|
|
32
42
|
import {
|
|
33
43
|
clearSentryConversationContext,
|
|
@@ -35,12 +45,16 @@ import {
|
|
|
35
45
|
} from "../instrument.js";
|
|
36
46
|
import { commitAppTurnChanges } from "../memory/app-git-service.js";
|
|
37
47
|
import { getApp, listAppFiles, resolveAppDir } from "../memory/app-store.js";
|
|
48
|
+
import { enqueueAutoAnalysisOnCompaction } from "../memory/auto-analysis-enqueue.js";
|
|
38
49
|
import {
|
|
39
50
|
addMessage,
|
|
51
|
+
clearPkbSystemReminderMetadataForConversation,
|
|
40
52
|
deleteMessageById,
|
|
41
53
|
getConversation,
|
|
42
54
|
getConversationOriginChannel,
|
|
43
55
|
getConversationOriginInterface,
|
|
56
|
+
getLastUserTimestampBefore,
|
|
57
|
+
getMessageById,
|
|
44
58
|
provenanceFromTrustContext,
|
|
45
59
|
updateConversationContextWindow,
|
|
46
60
|
updateConversationTitle,
|
|
@@ -56,6 +70,7 @@ import {
|
|
|
56
70
|
} from "../memory/conversation-title-service.js";
|
|
57
71
|
import type { ConversationGraphMemory } from "../memory/graph/conversation-graph-memory.js";
|
|
58
72
|
import { recordMemoryRecallLog } from "../memory/memory-recall-log-store.js";
|
|
73
|
+
import { PKB_WORKSPACE_SCOPE } from "../memory/pkb/types.js";
|
|
59
74
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
60
75
|
import type { ContentBlock, Message } from "../providers/types.js";
|
|
61
76
|
import type { Provider } from "../providers/types.js";
|
|
@@ -64,6 +79,8 @@ import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
|
64
79
|
import { getSubagentManager } from "../subagent/index.js";
|
|
65
80
|
import type { UsageActor } from "../usage/actors.js";
|
|
66
81
|
import { getLogger } from "../util/logger.js";
|
|
82
|
+
import { getWorkspaceDir } from "../util/platform.js";
|
|
83
|
+
import { timeAgo } from "../util/time.js";
|
|
67
84
|
import { truncate } from "../util/truncate.js";
|
|
68
85
|
import { getWorkspaceGitService } from "../workspace/git-service.js";
|
|
69
86
|
import { commitTurnChanges } from "../workspace/turn-commit.js";
|
|
@@ -107,8 +124,11 @@ import {
|
|
|
107
124
|
buildSubagentStatusBlock,
|
|
108
125
|
buildUnifiedTurnContextBlock,
|
|
109
126
|
findLastInjectedNowContent,
|
|
127
|
+
getPkbAutoInjectList,
|
|
110
128
|
inboundActorContextFromTrust,
|
|
111
129
|
inboundActorContextFromTrustContext,
|
|
130
|
+
loadSlackActiveThreadFocusBlock,
|
|
131
|
+
loadSlackChronologicalMessages,
|
|
112
132
|
readNowScratchpad,
|
|
113
133
|
readPkbContext,
|
|
114
134
|
stripInjectionsForCompaction,
|
|
@@ -127,44 +147,12 @@ import type {
|
|
|
127
147
|
UsageStats,
|
|
128
148
|
} from "./message-protocol.js";
|
|
129
149
|
import type { MemoryRecalled } from "./message-types/memory.js";
|
|
150
|
+
import { parseActualTokensFromError } from "./parse-actual-tokens-from-error.js";
|
|
130
151
|
import type { TraceEmitter } from "./trace-emitter.js";
|
|
152
|
+
import { stripHistoricalWebSearchResults } from "./web-search-history.js";
|
|
131
153
|
|
|
132
154
|
const log = getLogger("conversation-agent-loop");
|
|
133
155
|
|
|
134
|
-
/**
|
|
135
|
-
* Parse the actual token count reported by the provider in a context-too-large
|
|
136
|
-
* error message. Providers typically include the prompt size, e.g.:
|
|
137
|
-
* "prompt is too long: 242201 tokens > 200000 maximum"
|
|
138
|
-
* "too many input tokens: 242201 > 200000"
|
|
139
|
-
*
|
|
140
|
-
* Returns the actual token count or null if it cannot be parsed.
|
|
141
|
-
*/
|
|
142
|
-
export function parseActualTokensFromError(
|
|
143
|
-
errorMessage: string | null,
|
|
144
|
-
): number | null {
|
|
145
|
-
if (!errorMessage) return null;
|
|
146
|
-
|
|
147
|
-
// Match patterns like "242201 tokens > 200000" or "242201 > 200000 maximum"
|
|
148
|
-
const match = errorMessage.match(
|
|
149
|
-
/(\d[\d,]*)\s*tokens?\s*[>≥]|:\s*(\d[\d,]*)\s*[>≥]/i,
|
|
150
|
-
);
|
|
151
|
-
if (match) {
|
|
152
|
-
const raw = (match[1] || match[2]).replace(/,/g, "");
|
|
153
|
-
const parsed = parseInt(raw, 10);
|
|
154
|
-
if (!isNaN(parsed) && parsed > 0) return parsed;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Fallback: match "too many input tokens: N > M"
|
|
158
|
-
const fallback = errorMessage.match(/(\d[\d,]*)\s*[>≥]\s*\d/);
|
|
159
|
-
if (fallback) {
|
|
160
|
-
const raw = fallback[1].replace(/,/g, "");
|
|
161
|
-
const parsed = parseInt(raw, 10);
|
|
162
|
-
if (!isNaN(parsed) && parsed > 0) return parsed;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
156
|
/** Title-cased friendly labels for tool names, used in confirmation chips. */
|
|
169
157
|
const TOOL_FRIENDLY_LABEL: Record<string, string> = {
|
|
170
158
|
bash: "Run Command",
|
|
@@ -173,12 +161,6 @@ const TOOL_FRIENDLY_LABEL: Record<string, string> = {
|
|
|
173
161
|
file_read: "Read File",
|
|
174
162
|
file_write: "Write File",
|
|
175
163
|
file_edit: "Edit File",
|
|
176
|
-
browser_navigate: "Browser",
|
|
177
|
-
browser_click: "Browser",
|
|
178
|
-
browser_type: "Browser",
|
|
179
|
-
browser_screenshot: "Browser",
|
|
180
|
-
browser_scroll: "Browser",
|
|
181
|
-
browser_wait: "Browser",
|
|
182
164
|
app_create: "Create App",
|
|
183
165
|
app_refresh: "Refresh App",
|
|
184
166
|
skill_load: "Load Skill",
|
|
@@ -189,6 +171,79 @@ type GitServiceInitializer = {
|
|
|
189
171
|
ensureInitialized(): Promise<void>;
|
|
190
172
|
};
|
|
191
173
|
|
|
174
|
+
// ── Compaction circuit-breaker constants ────────────────────────────
|
|
175
|
+
//
|
|
176
|
+
// The circuit opens after `COMPACTION_CIRCUIT_FAILURE_THRESHOLD` consecutive
|
|
177
|
+
// summary-LLM failures and stays open for `COMPACTION_CIRCUIT_COOLDOWN_MS`
|
|
178
|
+
// before auto-compaction is allowed to retry. User-initiated compaction
|
|
179
|
+
// (`force: true`) bypasses the breaker regardless of its state.
|
|
180
|
+
const COMPACTION_CIRCUIT_FAILURE_THRESHOLD = 3;
|
|
181
|
+
const COMPACTION_CIRCUIT_COOLDOWN_MS = 60 * 60 * 1000; // 1 hour
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Check whether the compaction circuit breaker is currently open for the
|
|
185
|
+
* given context. The breaker auto-closes once `compactionCircuitOpenUntil`
|
|
186
|
+
* has elapsed.
|
|
187
|
+
*/
|
|
188
|
+
export function isCompactionCircuitOpen(ctx: {
|
|
189
|
+
compactionCircuitOpenUntil: number | null;
|
|
190
|
+
}): boolean {
|
|
191
|
+
return (
|
|
192
|
+
ctx.compactionCircuitOpenUntil !== null &&
|
|
193
|
+
Date.now() < ctx.compactionCircuitOpenUntil
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Track the outcome of a `maybeCompact()` call against the circuit breaker.
|
|
199
|
+
*
|
|
200
|
+
* - When the summary LLM call failed (local fallback covered the result),
|
|
201
|
+
* increment the consecutive-failure counter. If the counter reaches the
|
|
202
|
+
* threshold, open the circuit for the cooldown window and emit
|
|
203
|
+
* `compaction_circuit_open` so clients can surface a notice.
|
|
204
|
+
* - When the call did not fail, reset the counter and clear any open circuit.
|
|
205
|
+
*
|
|
206
|
+
* This is called by every `maybeCompact()` site (including forced ones),
|
|
207
|
+
* because a run of three failures is a provider-health signal regardless of
|
|
208
|
+
* whether the caller bypassed the breaker.
|
|
209
|
+
*/
|
|
210
|
+
export function trackCompactionOutcome(
|
|
211
|
+
ctx: {
|
|
212
|
+
consecutiveCompactionFailures: number;
|
|
213
|
+
compactionCircuitOpenUntil: number | null;
|
|
214
|
+
},
|
|
215
|
+
summaryFailed: boolean | undefined,
|
|
216
|
+
onEvent: (msg: ServerMessage) => void,
|
|
217
|
+
): void {
|
|
218
|
+
if (summaryFailed) {
|
|
219
|
+
ctx.consecutiveCompactionFailures += 1;
|
|
220
|
+
// Treat a stale/expired open-until timestamp the same as null so a new
|
|
221
|
+
// 3-strike window can re-open the circuit after the prior cooldown
|
|
222
|
+
// elapses. Without this the second trip would no-op because
|
|
223
|
+
// `compactionCircuitOpenUntil` remains set to a past timestamp even
|
|
224
|
+
// though `isCompactionCircuitOpen()` correctly reports closed.
|
|
225
|
+
const circuitDormant =
|
|
226
|
+
ctx.compactionCircuitOpenUntil === null ||
|
|
227
|
+
Date.now() >= ctx.compactionCircuitOpenUntil;
|
|
228
|
+
if (
|
|
229
|
+
ctx.consecutiveCompactionFailures >=
|
|
230
|
+
COMPACTION_CIRCUIT_FAILURE_THRESHOLD &&
|
|
231
|
+
circuitDormant
|
|
232
|
+
) {
|
|
233
|
+
const openUntil = Date.now() + COMPACTION_CIRCUIT_COOLDOWN_MS;
|
|
234
|
+
ctx.compactionCircuitOpenUntil = openUntil;
|
|
235
|
+
onEvent({
|
|
236
|
+
type: "compaction_circuit_open",
|
|
237
|
+
reason: "3_consecutive_failures",
|
|
238
|
+
openUntil,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
} else {
|
|
242
|
+
ctx.consecutiveCompactionFailures = 0;
|
|
243
|
+
ctx.compactionCircuitOpenUntil = null;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
192
247
|
// ── Context Interface ────────────────────────────────────────────────
|
|
193
248
|
|
|
194
249
|
export interface AgentLoopConversationContext {
|
|
@@ -205,6 +260,10 @@ export interface AgentLoopConversationContext {
|
|
|
205
260
|
readonly contextWindowManager: ContextWindowManager;
|
|
206
261
|
contextCompactedMessageCount: number;
|
|
207
262
|
contextCompactedAt: number | null;
|
|
263
|
+
/** Tracks consecutive compaction failures (summary LLM call threw). */
|
|
264
|
+
consecutiveCompactionFailures: number;
|
|
265
|
+
/** Timestamp (ms since epoch) until which the circuit breaker is open. */
|
|
266
|
+
compactionCircuitOpenUntil: number | null;
|
|
208
267
|
|
|
209
268
|
readonly memoryPolicy: { scopeId: string; includeDefaultFallback: boolean };
|
|
210
269
|
readonly graphMemory: ConversationGraphMemory;
|
|
@@ -227,6 +286,7 @@ export interface AgentLoopConversationContext {
|
|
|
227
286
|
>;
|
|
228
287
|
pendingSurfaceActions: Map<string, { surfaceType: SurfaceType }>;
|
|
229
288
|
surfaceActionRequestIds: Set<string>;
|
|
289
|
+
approvedViaPromptThisTurn?: boolean;
|
|
230
290
|
currentTurnSurfaces: Array<{
|
|
231
291
|
surfaceId: string;
|
|
232
292
|
surfaceType: SurfaceType;
|
|
@@ -234,6 +294,7 @@ export interface AgentLoopConversationContext {
|
|
|
234
294
|
data: SurfaceData;
|
|
235
295
|
actions?: Array<{ id: string; label: string; style?: string }>;
|
|
236
296
|
display?: string;
|
|
297
|
+
persistent?: boolean;
|
|
237
298
|
}>;
|
|
238
299
|
|
|
239
300
|
workingDir: string;
|
|
@@ -246,6 +307,8 @@ export interface AgentLoopConversationContext {
|
|
|
246
307
|
currentTurnChannelCapabilities?: ChannelCapabilities;
|
|
247
308
|
commandIntent?: { type: string; payload?: string; languageCode?: string };
|
|
248
309
|
trustContext?: TrustContext;
|
|
310
|
+
/** Task-run scope for the current turn. Cleared at turn end so queued/drained turns don't inherit it. */
|
|
311
|
+
taskRunId?: string;
|
|
249
312
|
assistantId?: string;
|
|
250
313
|
voiceCallControlPrompt?: string;
|
|
251
314
|
transportHints?: string[];
|
|
@@ -345,6 +408,13 @@ export async function runAgentLoopImpl(
|
|
|
345
408
|
isInteractive?: boolean;
|
|
346
409
|
isUserMessage?: boolean;
|
|
347
410
|
titleText?: string;
|
|
411
|
+
/**
|
|
412
|
+
* LLM call-site identifier threaded into the per-call provider config.
|
|
413
|
+
* Adapter callers (heartbeat, filing, scheduler, etc.) pass their own
|
|
414
|
+
* call-site id so the resolver picks `llm.callSites.<id>`. When unset,
|
|
415
|
+
* the agent loop defaults to `'mainAgent'` for user-initiated turns.
|
|
416
|
+
*/
|
|
417
|
+
callSite?: LLMCallSite;
|
|
348
418
|
},
|
|
349
419
|
): Promise<void> {
|
|
350
420
|
if (!ctx.abortController) {
|
|
@@ -368,6 +438,13 @@ export async function runAgentLoopImpl(
|
|
|
368
438
|
});
|
|
369
439
|
let yieldedForHandoff = false;
|
|
370
440
|
|
|
441
|
+
// Default user-initiated turns to the `mainAgent` call site. Other
|
|
442
|
+
// invocation contexts (heartbeat, filing, analyze, etc.) pass their own
|
|
443
|
+
// `callSite`. The provider layer resolves provider/model/maxTokens via
|
|
444
|
+
// `resolveCallSiteConfig`, picking up any user overrides under
|
|
445
|
+
// `llm.callSites.mainAgent` (falling back to `llm.default` when absent).
|
|
446
|
+
const turnCallSite: LLMCallSite = options?.callSite ?? "mainAgent";
|
|
447
|
+
|
|
371
448
|
// Capture the turn channel context *before* any awaits so a second
|
|
372
449
|
// message from a different channel can't overwrite it mid-flight.
|
|
373
450
|
// When context is unavailable (e.g. regenerate after daemon restart),
|
|
@@ -513,7 +590,10 @@ export async function runAgentLoopImpl(
|
|
|
513
590
|
let compactedThisTurn = false;
|
|
514
591
|
|
|
515
592
|
const compactCheck = ctx.contextWindowManager.shouldCompact(ctx.messages);
|
|
516
|
-
|
|
593
|
+
// Skip auto-compaction while the circuit breaker is open. Force paths
|
|
594
|
+
// and user-initiated /compact bypass this check.
|
|
595
|
+
const autoCompactAllowed = !isCompactionCircuitOpen(ctx);
|
|
596
|
+
if (compactCheck.needed && autoCompactAllowed) {
|
|
517
597
|
ctx.emitActivityState(
|
|
518
598
|
"thinking",
|
|
519
599
|
"context_compacting",
|
|
@@ -521,15 +601,27 @@ export async function runAgentLoopImpl(
|
|
|
521
601
|
reqId,
|
|
522
602
|
);
|
|
523
603
|
}
|
|
524
|
-
const compacted =
|
|
525
|
-
ctx.
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
604
|
+
const compacted = autoCompactAllowed
|
|
605
|
+
? await ctx.contextWindowManager.maybeCompact(
|
|
606
|
+
ctx.messages,
|
|
607
|
+
abortController.signal,
|
|
608
|
+
{
|
|
609
|
+
lastCompactedAt: ctx.contextCompactedAt ?? undefined,
|
|
610
|
+
precomputedEstimate: compactCheck.estimatedTokens,
|
|
611
|
+
conversationOriginChannel:
|
|
612
|
+
getConversationOriginChannel(ctx.conversationId) ?? undefined,
|
|
613
|
+
},
|
|
614
|
+
)
|
|
615
|
+
: null;
|
|
616
|
+
// Only track circuit-breaker state when a summary LLM call actually ran.
|
|
617
|
+
// `summaryFailed` is `undefined` on early returns (compaction disabled,
|
|
618
|
+
// below threshold, cooldown active, no eligible messages, truncation-only
|
|
619
|
+
// path) — treating those as "successful" compactions would silently reset
|
|
620
|
+
// the 3-strike counter and break the invariant.
|
|
621
|
+
if (compacted && compacted.summaryFailed !== undefined) {
|
|
622
|
+
trackCompactionOutcome(ctx, compacted.summaryFailed, onEvent);
|
|
623
|
+
}
|
|
624
|
+
if (compacted?.compacted) {
|
|
533
625
|
ctx.messages = compacted.messages;
|
|
534
626
|
ctx.contextCompactedMessageCount += compacted.compactedPersistedMessages;
|
|
535
627
|
ctx.contextCompactedAt = Date.now();
|
|
@@ -541,6 +633,13 @@ export async function runAgentLoopImpl(
|
|
|
541
633
|
compacted.summaryText,
|
|
542
634
|
ctx.contextCompactedMessageCount,
|
|
543
635
|
);
|
|
636
|
+
// Fire auto-analysis on compaction so the reflective agent can
|
|
637
|
+
// crystallize anything worth remembering before the context window
|
|
638
|
+
// narrows further.
|
|
639
|
+
enqueueAutoAnalysisOnCompaction(
|
|
640
|
+
ctx.conversationId,
|
|
641
|
+
ctx.trustContext?.trustClass,
|
|
642
|
+
);
|
|
544
643
|
onEvent({
|
|
545
644
|
type: "context_compacted",
|
|
546
645
|
previousEstimatedInputTokens: compacted.previousEstimatedInputTokens,
|
|
@@ -613,7 +712,12 @@ export async function runAgentLoopImpl(
|
|
|
613
712
|
let runMessages = ctx.messages;
|
|
614
713
|
|
|
615
714
|
// Memory graph retrieval — dispatches to context-load / per-turn based on
|
|
616
|
-
// conversation state.
|
|
715
|
+
// conversation state. Keep the query vector around so the PKB reminder
|
|
716
|
+
// can reuse it for relevance-hint search (see `applyRuntimeInjections`).
|
|
717
|
+
let pkbQueryVector: number[] | undefined;
|
|
718
|
+
let pkbSparseVector:
|
|
719
|
+
| import("../memory/qdrant-client.js").QdrantSparseVector
|
|
720
|
+
| undefined;
|
|
617
721
|
const isTrustedActor = resolveTrustClass(ctx.trustContext) === "guardian";
|
|
618
722
|
if (isTrustedActor) {
|
|
619
723
|
const graphResult = await ctx.graphMemory.prepareMemory(
|
|
@@ -623,6 +727,22 @@ export async function runAgentLoopImpl(
|
|
|
623
727
|
onEvent,
|
|
624
728
|
);
|
|
625
729
|
runMessages = graphResult.runMessages;
|
|
730
|
+
// Select dense+sparse as a matched pair so RRF fusion combines two
|
|
731
|
+
// signals aligned to the same query text:
|
|
732
|
+
// 1. Context-load with a user query: user-query dense + user-query
|
|
733
|
+
// sparse — the cleanest pairing.
|
|
734
|
+
// 2. Otherwise (context-load without a user query, or per-turn):
|
|
735
|
+
// whatever `queryVector` / `sparseVector` the retriever produced,
|
|
736
|
+
// which are themselves co-aligned (both summary-derived in
|
|
737
|
+
// context-load, both user-last-message-derived in per-turn).
|
|
738
|
+
// Never pair a user-query dense with a summary-aligned sparse.
|
|
739
|
+
if (graphResult.userQueryVector) {
|
|
740
|
+
pkbQueryVector = graphResult.userQueryVector;
|
|
741
|
+
pkbSparseVector = graphResult.userQuerySparseVector;
|
|
742
|
+
} else {
|
|
743
|
+
pkbQueryVector = graphResult.queryVector;
|
|
744
|
+
pkbSparseVector = graphResult.sparseVector;
|
|
745
|
+
}
|
|
626
746
|
|
|
627
747
|
// Persist the injected block text in message metadata so it survives
|
|
628
748
|
// conversation reloads (eviction, restart, fork). loadFromDb re-injects
|
|
@@ -773,14 +893,35 @@ export async function runAgentLoopImpl(
|
|
|
773
893
|
const isGuardian =
|
|
774
894
|
resolvedInboundActorContext?.trustClass === "guardian" ||
|
|
775
895
|
!resolvedInboundActorContext;
|
|
896
|
+
|
|
897
|
+
// Surface long gaps between user messages so the model can acknowledge
|
|
898
|
+
// the absence naturally. Gated at >12h to avoid noisy injection during
|
|
899
|
+
// normal back-and-forth turns.
|
|
900
|
+
const TWELVE_HOURS_MS = 12 * 60 * 60 * 1000;
|
|
901
|
+
let timeSinceLastMessage: string | null = null;
|
|
902
|
+
const currentUserMessage = getMessageById(userMessageId);
|
|
903
|
+
if (currentUserMessage) {
|
|
904
|
+
const prevUserTs = getLastUserTimestampBefore(
|
|
905
|
+
ctx.conversationId,
|
|
906
|
+
currentUserMessage.createdAt,
|
|
907
|
+
);
|
|
908
|
+
if (
|
|
909
|
+
prevUserTs > 0 &&
|
|
910
|
+
currentUserMessage.createdAt - prevUserTs > TWELVE_HOURS_MS
|
|
911
|
+
) {
|
|
912
|
+
timeSinceLastMessage = timeAgo(prevUserTs);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
776
916
|
const unifiedTurnContextStr = buildUnifiedTurnContextBlock(
|
|
777
917
|
isGuardian
|
|
778
|
-
? { timestamp, interfaceName, channelName }
|
|
918
|
+
? { timestamp, interfaceName, channelName, timeSinceLastMessage }
|
|
779
919
|
: {
|
|
780
920
|
timestamp,
|
|
781
921
|
interfaceName,
|
|
782
922
|
channelName,
|
|
783
923
|
actorContext: resolvedInboundActorContext,
|
|
924
|
+
timeSinceLastMessage,
|
|
784
925
|
},
|
|
785
926
|
);
|
|
786
927
|
|
|
@@ -800,6 +941,21 @@ export async function runAgentLoopImpl(
|
|
|
800
941
|
const pkbContext = shouldInjectNowAndPkb ? currentPkbContent : null;
|
|
801
942
|
const pkbActive = currentPkbContent !== null;
|
|
802
943
|
|
|
944
|
+
// PKB relevance-hint inputs. Resolved once per turn and reused across
|
|
945
|
+
// re-injections so post-compaction rebuilds pick up fresh hints against
|
|
946
|
+
// the updated conversation history.
|
|
947
|
+
const pkbRoot = pkbActive ? join(getWorkspaceDir(), "pkb") : undefined;
|
|
948
|
+
const pkbAutoInjectList = pkbRoot
|
|
949
|
+
? getPkbAutoInjectList(pkbRoot)
|
|
950
|
+
: undefined;
|
|
951
|
+
// Pass `ctx` directly — `PkbContextConversation` is structural and
|
|
952
|
+
// `getInContextPkbPaths` re-reads `conversation.messages` on each call,
|
|
953
|
+
// so post-compaction re-injects see the updated history.
|
|
954
|
+
const pkbConversation = pkbActive ? ctx : undefined;
|
|
955
|
+
// PKB points live under a single workspace sentinel scope, not the
|
|
956
|
+
// conversation's memoryPolicy.scopeId. See `PKB_WORKSPACE_SCOPE` for why.
|
|
957
|
+
const pkbScopeId = pkbActive ? PKB_WORKSPACE_SCOPE : undefined;
|
|
958
|
+
|
|
803
959
|
// Subagent status injection — gives the parent LLM visibility into active/completed children.
|
|
804
960
|
// Skipped when this conversation IS a subagent (no nesting) or has no children.
|
|
805
961
|
const subagentStatusBlock = ctx.isSubagent
|
|
@@ -808,6 +964,43 @@ export async function runAgentLoopImpl(
|
|
|
808
964
|
getSubagentManager().getChildrenOf(ctx.conversationId),
|
|
809
965
|
);
|
|
810
966
|
|
|
967
|
+
// For any Slack conversation (channels and DMs alike), build a
|
|
968
|
+
// chronological transcript from the persisted message rows so the
|
|
969
|
+
// model sees one channel-wide view instead of the gateway's per-turn
|
|
970
|
+
// hints. DMs render as a flat sequence (no thread tags), channels
|
|
971
|
+
// include sibling threads.
|
|
972
|
+
const isSlackConversation = ctx.channelCapabilities?.channel === "slack";
|
|
973
|
+
const slackChronologicalMessages = isSlackConversation
|
|
974
|
+
? loadSlackChronologicalMessages(
|
|
975
|
+
ctx.conversationId,
|
|
976
|
+
ctx.channelCapabilities!,
|
|
977
|
+
{ trustClass: ctx.trustContext?.trustClass },
|
|
978
|
+
)
|
|
979
|
+
: null;
|
|
980
|
+
|
|
981
|
+
// Active-thread focus block: when the inbound user message belongs to
|
|
982
|
+
// a Slack thread, append a non-persisted `<active_thread>` tail block
|
|
983
|
+
// to the final user turn listing the thread's parent + replies. Helps
|
|
984
|
+
// the model orient when the channel transcript is long and
|
|
985
|
+
// interleaved. Replays strip the block via RUNTIME_INJECTION_PREFIXES.
|
|
986
|
+
// DMs short-circuit to null inside `loadSlackActiveThreadFocusBlock`
|
|
987
|
+
// since DMs do not have threads.
|
|
988
|
+
const slackActiveThreadFocusBlock = isSlackConversation
|
|
989
|
+
? loadSlackActiveThreadFocusBlock(
|
|
990
|
+
ctx.conversationId,
|
|
991
|
+
ctx.channelCapabilities!,
|
|
992
|
+
{ trustClass: ctx.trustContext?.trustClass },
|
|
993
|
+
)
|
|
994
|
+
: null;
|
|
995
|
+
|
|
996
|
+
// Guards the chronological-transcript override on re-injection after
|
|
997
|
+
// the reducer compacts `ctx.messages`. The captured transcript is the
|
|
998
|
+
// full persisted history; blindly replaying it on every re-inject would
|
|
999
|
+
// overwrite the reducer's compacted messages and undo compaction. Flip
|
|
1000
|
+
// to `true` after any compaction so subsequent re-injections fall back
|
|
1001
|
+
// to the reduced `ctx.messages`.
|
|
1002
|
+
let reducerCompacted = compactedThisTurn;
|
|
1003
|
+
|
|
811
1004
|
// Shared injection options — reused whenever we need to re-inject after reduction.
|
|
812
1005
|
const injectionOpts = {
|
|
813
1006
|
activeSurface,
|
|
@@ -819,27 +1012,66 @@ export async function runAgentLoopImpl(
|
|
|
819
1012
|
unifiedTurnContext: unifiedTurnContextStr,
|
|
820
1013
|
pkbContext,
|
|
821
1014
|
pkbActive,
|
|
1015
|
+
pkbQueryVector,
|
|
1016
|
+
pkbSparseVector,
|
|
1017
|
+
pkbScopeId,
|
|
1018
|
+
pkbConversation,
|
|
1019
|
+
pkbAutoInjectList,
|
|
1020
|
+
pkbRoot,
|
|
1021
|
+
pkbWorkingDir: pkbActive ? ctx.workingDir : undefined,
|
|
822
1022
|
nowScratchpad,
|
|
823
1023
|
voiceCallControlPrompt: ctx.voiceCallControlPrompt ?? null,
|
|
824
1024
|
transportHints: ctx.transportHints ?? null,
|
|
825
1025
|
isNonInteractive: !isInteractiveResolved,
|
|
826
1026
|
subagentStatusBlock,
|
|
1027
|
+
slackChronologicalMessages,
|
|
1028
|
+
slackActiveThreadFocusBlock,
|
|
827
1029
|
} as const;
|
|
828
1030
|
|
|
829
1031
|
let currentInjectionMode: InjectionMode = "full";
|
|
830
1032
|
|
|
831
|
-
|
|
1033
|
+
const injection = await applyRuntimeInjections(runMessages, {
|
|
832
1034
|
...injectionOpts,
|
|
1035
|
+
slackChronologicalMessages: reducerCompacted
|
|
1036
|
+
? null
|
|
1037
|
+
: injectionOpts.slackChronologicalMessages,
|
|
833
1038
|
mode: currentInjectionMode,
|
|
834
1039
|
});
|
|
1040
|
+
runMessages = injection.messages;
|
|
1041
|
+
|
|
1042
|
+
// Persist injected blocks in message metadata so they survive conversation
|
|
1043
|
+
// reloads (eviction, restart, fork). loadFromDb re-injects from metadata.
|
|
1044
|
+
// Only the first call site persists — the overflow-recovery re-entry sites
|
|
1045
|
+
// send identical bytes and the tail row may not correspond to
|
|
1046
|
+
// `userMessageId`. Both blocks are written in a single call to avoid
|
|
1047
|
+
// doubling SQLite SELECT+UPDATE work on every turn.
|
|
1048
|
+
if (
|
|
1049
|
+
injection.blocks.unifiedTurnContext ||
|
|
1050
|
+
injection.blocks.pkbSystemReminder
|
|
1051
|
+
) {
|
|
1052
|
+
try {
|
|
1053
|
+
const metadataUpdates: Record<string, unknown> = {};
|
|
1054
|
+
if (injection.blocks.unifiedTurnContext) {
|
|
1055
|
+
metadataUpdates.turnContextBlock =
|
|
1056
|
+
injection.blocks.unifiedTurnContext;
|
|
1057
|
+
}
|
|
1058
|
+
if (injection.blocks.pkbSystemReminder) {
|
|
1059
|
+
metadataUpdates.pkbSystemReminderBlock =
|
|
1060
|
+
injection.blocks.pkbSystemReminder;
|
|
1061
|
+
}
|
|
1062
|
+
updateMessageMetadata(userMessageId, metadataUpdates);
|
|
1063
|
+
} catch (err) {
|
|
1064
|
+
rlog.warn({ err }, "Failed to persist injection metadata (non-fatal)");
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
835
1067
|
|
|
836
1068
|
// ── Preflight budget evaluation ──────────────────────────────
|
|
837
1069
|
// After runtime injections are applied, estimate the prompt token count
|
|
838
1070
|
// and proactively invoke the reducer if already above budget. This avoids
|
|
839
1071
|
// a wasted provider round-trip that would just fail with context_too_large.
|
|
840
1072
|
const config = getConfig();
|
|
841
|
-
const overflowRecovery = config.contextWindow.overflowRecovery;
|
|
842
|
-
const providerMaxTokens = config.contextWindow.maxInputTokens;
|
|
1073
|
+
const overflowRecovery = config.llm.default.contextWindow.overflowRecovery;
|
|
1074
|
+
const providerMaxTokens = config.llm.default.contextWindow.maxInputTokens;
|
|
843
1075
|
// Widen safety margin for large conversations where estimation error
|
|
844
1076
|
// compounds across many messages with tool results.
|
|
845
1077
|
const baseSafetyMargin = overflowRecovery.safetyMarginRatio;
|
|
@@ -850,10 +1082,17 @@ export async function runAgentLoopImpl(
|
|
|
850
1082
|
let reducerState: ReducerState | undefined;
|
|
851
1083
|
|
|
852
1084
|
const toolTokenBudget = ctx.agentLoop.getToolTokenBudget(runMessages);
|
|
1085
|
+
// Canonical calibration key used at every `estimatePromptTokens` site in
|
|
1086
|
+
// this function. Matches the key recorded by `handleUsage` for wrapper
|
|
1087
|
+
// providers (OpenRouter routing to Anthropic → key is `"anthropic"`).
|
|
1088
|
+
const estimationProviderName = getCalibrationProviderKey(ctx.provider);
|
|
853
1089
|
const preflightTokens = estimatePromptTokens(
|
|
854
1090
|
runMessages,
|
|
855
1091
|
ctx.systemPrompt,
|
|
856
|
-
{
|
|
1092
|
+
{
|
|
1093
|
+
providerName: estimationProviderName,
|
|
1094
|
+
toolTokenBudget,
|
|
1095
|
+
},
|
|
857
1096
|
);
|
|
858
1097
|
|
|
859
1098
|
if (overflowRecovery.enabled && preflightTokens > preflightBudget) {
|
|
@@ -883,9 +1122,9 @@ export async function runAgentLoopImpl(
|
|
|
883
1122
|
const step = await reduceContextOverflow(
|
|
884
1123
|
ctx.messages,
|
|
885
1124
|
{
|
|
886
|
-
providerName:
|
|
1125
|
+
providerName: estimationProviderName,
|
|
887
1126
|
systemPrompt: ctx.systemPrompt,
|
|
888
|
-
contextWindow: config.contextWindow,
|
|
1127
|
+
contextWindow: config.llm.default.contextWindow,
|
|
889
1128
|
targetTokens: preflightBudget,
|
|
890
1129
|
toolTokenBudget,
|
|
891
1130
|
},
|
|
@@ -899,6 +1138,24 @@ export async function runAgentLoopImpl(
|
|
|
899
1138
|
ctx.messages = step.messages;
|
|
900
1139
|
currentInjectionMode = step.state.injectionMode;
|
|
901
1140
|
|
|
1141
|
+
// Track circuit-breaker state whenever the reducer invoked compaction.
|
|
1142
|
+
// The reducer's forced_compaction tier uses force:true, so it bypasses
|
|
1143
|
+
// the open-circuit check, but we still want failure tracking to detect
|
|
1144
|
+
// a run of broken summaries and clear the counter on success. Only
|
|
1145
|
+
// track when the summary LLM actually ran — `summaryFailed === undefined`
|
|
1146
|
+
// indicates an early return (no eligible messages, truncation-only
|
|
1147
|
+
// path, etc.) that shouldn't influence the breaker.
|
|
1148
|
+
if (
|
|
1149
|
+
step.compactionResult &&
|
|
1150
|
+
step.compactionResult.summaryFailed !== undefined
|
|
1151
|
+
) {
|
|
1152
|
+
trackCompactionOutcome(
|
|
1153
|
+
ctx,
|
|
1154
|
+
step.compactionResult.summaryFailed,
|
|
1155
|
+
onEvent,
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
902
1159
|
if (step.compactionResult?.compacted) {
|
|
903
1160
|
ctx.contextCompactedMessageCount +=
|
|
904
1161
|
step.compactionResult.compactedPersistedMessages;
|
|
@@ -908,6 +1165,11 @@ export async function runAgentLoopImpl(
|
|
|
908
1165
|
step.compactionResult.summaryText,
|
|
909
1166
|
ctx.contextCompactedMessageCount,
|
|
910
1167
|
);
|
|
1168
|
+
// Fire auto-analysis on compaction — see forceCompact() for rationale.
|
|
1169
|
+
enqueueAutoAnalysisOnCompaction(
|
|
1170
|
+
ctx.conversationId,
|
|
1171
|
+
ctx.trustContext?.trustClass,
|
|
1172
|
+
);
|
|
911
1173
|
onEvent({
|
|
912
1174
|
type: "context_compacted",
|
|
913
1175
|
previousEstimatedInputTokens:
|
|
@@ -937,21 +1199,34 @@ export async function runAgentLoopImpl(
|
|
|
937
1199
|
step.compactionResult.compactedPersistedMessages,
|
|
938
1200
|
);
|
|
939
1201
|
shouldInjectWorkspace = true;
|
|
1202
|
+
reducerCompacted = true;
|
|
940
1203
|
}
|
|
941
1204
|
|
|
942
1205
|
// Re-inject with potentially downgraded injection mode.
|
|
943
1206
|
// When compaction ran it strips existing NOW.md / PKB blocks, so we
|
|
944
1207
|
// must re-inject the current content. Otherwise rely on the deduplicated
|
|
945
1208
|
// value from injectionOpts to avoid duplicate injection.
|
|
946
|
-
|
|
1209
|
+
const injection = await applyRuntimeInjections(ctx.messages, {
|
|
947
1210
|
...injectionOpts,
|
|
948
|
-
...(step.compactionResult?.compacted && {
|
|
949
|
-
|
|
1211
|
+
...(step.compactionResult?.compacted && {
|
|
1212
|
+
pkbContext: currentPkbContent,
|
|
1213
|
+
}),
|
|
1214
|
+
...(step.compactionResult?.compacted && {
|
|
1215
|
+
nowScratchpad: currentNowContent,
|
|
1216
|
+
}),
|
|
950
1217
|
workspaceTopLevelContext: shouldInjectWorkspace
|
|
951
1218
|
? ctx.workspaceTopLevelContext
|
|
952
1219
|
: null,
|
|
1220
|
+
// Once the reducer has compacted `ctx.messages`, the captured
|
|
1221
|
+
// `slackChronologicalMessages` snapshot (built from the full
|
|
1222
|
+
// persisted transcript) would overwrite the compacted history
|
|
1223
|
+
// and undo compaction. Suppress the override from here on.
|
|
1224
|
+
slackChronologicalMessages: reducerCompacted
|
|
1225
|
+
? null
|
|
1226
|
+
: injectionOpts.slackChronologicalMessages,
|
|
953
1227
|
mode: currentInjectionMode,
|
|
954
1228
|
});
|
|
1229
|
+
runMessages = injection.messages;
|
|
955
1230
|
if (isTrustedActor && currentInjectionMode !== "minimal") {
|
|
956
1231
|
const memResult = ctx.graphMemory.reinjectCachedMemory(runMessages);
|
|
957
1232
|
runMessages = memResult.runMessages;
|
|
@@ -963,7 +1238,10 @@ export async function runAgentLoopImpl(
|
|
|
963
1238
|
const postInjectionTokens = estimatePromptTokens(
|
|
964
1239
|
runMessages,
|
|
965
1240
|
ctx.systemPrompt,
|
|
966
|
-
{
|
|
1241
|
+
{
|
|
1242
|
+
providerName: estimationProviderName,
|
|
1243
|
+
toolTokenBudget,
|
|
1244
|
+
},
|
|
967
1245
|
);
|
|
968
1246
|
|
|
969
1247
|
if (postInjectionTokens <= preflightBudget) break;
|
|
@@ -986,6 +1264,20 @@ export async function runAgentLoopImpl(
|
|
|
986
1264
|
runMessages = preRunRepair.messages;
|
|
987
1265
|
}
|
|
988
1266
|
|
|
1267
|
+
// Replace historical web_search_tool_result blocks with text summaries.
|
|
1268
|
+
// The opaque `encrypted_content` tokens Anthropic attaches to each result
|
|
1269
|
+
// expire / are route-scoped; replaying a stale token is rejected with
|
|
1270
|
+
// `Invalid encrypted_content in search_result block`. Titles + URLs
|
|
1271
|
+
// preserve enough context for the model on follow-up turns.
|
|
1272
|
+
const webSearchStrip = stripHistoricalWebSearchResults(runMessages);
|
|
1273
|
+
if (webSearchStrip.stats.blocksStripped > 0) {
|
|
1274
|
+
rlog.info(
|
|
1275
|
+
{ phase: "pre_run", ...webSearchStrip.stats },
|
|
1276
|
+
"Converted historical web_search_tool_result blocks to text summaries",
|
|
1277
|
+
);
|
|
1278
|
+
runMessages = webSearchStrip.messages;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
989
1281
|
let preRunHistoryLength = runMessages.length;
|
|
990
1282
|
|
|
991
1283
|
const shouldGenerateTitle = isReplaceableTitle(
|
|
@@ -1008,17 +1300,11 @@ export async function runAgentLoopImpl(
|
|
|
1008
1300
|
let yieldedForBudget = false;
|
|
1009
1301
|
|
|
1010
1302
|
const onCheckpoint = (checkpoint: CheckpointInfo): CheckpointDecision => {
|
|
1011
|
-
const turnTools = state.currentTurnToolNames;
|
|
1012
1303
|
state.currentTurnToolNames = [];
|
|
1013
1304
|
|
|
1014
1305
|
if (ctx.canHandoffAtCheckpoint()) {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
turnTools.every((n) => n.startsWith("browser_"));
|
|
1018
|
-
if (!inBrowserFlow) {
|
|
1019
|
-
yieldedForHandoff = true;
|
|
1020
|
-
return "yield";
|
|
1021
|
-
}
|
|
1306
|
+
yieldedForHandoff = true;
|
|
1307
|
+
return "yield";
|
|
1022
1308
|
}
|
|
1023
1309
|
|
|
1024
1310
|
// Mid-loop token budget check: estimate current context size and
|
|
@@ -1029,7 +1315,10 @@ export async function runAgentLoopImpl(
|
|
|
1029
1315
|
const estimated = estimatePromptTokens(
|
|
1030
1316
|
checkpoint.history,
|
|
1031
1317
|
ctx.systemPrompt,
|
|
1032
|
-
{
|
|
1318
|
+
{
|
|
1319
|
+
providerName: estimationProviderName,
|
|
1320
|
+
toolTokenBudget,
|
|
1321
|
+
},
|
|
1033
1322
|
);
|
|
1034
1323
|
if (estimated > midLoopThreshold) {
|
|
1035
1324
|
rlog.warn(
|
|
@@ -1048,12 +1337,20 @@ export async function runAgentLoopImpl(
|
|
|
1048
1337
|
|
|
1049
1338
|
let denyCompressionMessage: Message | null = null;
|
|
1050
1339
|
|
|
1340
|
+
rlog.info({ callSite: turnCallSite }, "Starting agent loop run");
|
|
1341
|
+
|
|
1051
1342
|
let updatedHistory = await ctx.agentLoop.run(
|
|
1052
1343
|
runMessages,
|
|
1053
1344
|
eventHandler,
|
|
1054
1345
|
abortController.signal,
|
|
1055
1346
|
reqId,
|
|
1056
1347
|
onCheckpoint,
|
|
1348
|
+
turnCallSite,
|
|
1349
|
+
);
|
|
1350
|
+
|
|
1351
|
+
rlog.info(
|
|
1352
|
+
{ resultMessageCount: updatedHistory.length },
|
|
1353
|
+
"Agent loop run completed",
|
|
1057
1354
|
);
|
|
1058
1355
|
|
|
1059
1356
|
// ── Proactive mid-loop compaction ───────────────────────────────
|
|
@@ -1081,6 +1378,14 @@ export async function runAgentLoopImpl(
|
|
|
1081
1378
|
// so we compact the "raw" persistent messages.
|
|
1082
1379
|
const rawHistory = stripInjectionsForCompaction(updatedHistory);
|
|
1083
1380
|
ctx.messages = rawHistory;
|
|
1381
|
+
try {
|
|
1382
|
+
clearPkbSystemReminderMetadataForConversation(ctx.conversationId);
|
|
1383
|
+
} catch (err) {
|
|
1384
|
+
rlog.warn(
|
|
1385
|
+
{ err },
|
|
1386
|
+
"Failed to clear pkbSystemReminderBlock metadata after compaction strip (non-fatal)",
|
|
1387
|
+
);
|
|
1388
|
+
}
|
|
1084
1389
|
|
|
1085
1390
|
ctx.emitActivityState(
|
|
1086
1391
|
"thinking",
|
|
@@ -1096,10 +1401,19 @@ export async function runAgentLoopImpl(
|
|
|
1096
1401
|
lastCompactedAt: ctx.contextCompactedAt ?? undefined,
|
|
1097
1402
|
force: true,
|
|
1098
1403
|
targetInputTokensOverride: preflightBudget,
|
|
1404
|
+
conversationOriginChannel:
|
|
1405
|
+
getConversationOriginChannel(ctx.conversationId) ?? undefined,
|
|
1099
1406
|
},
|
|
1100
1407
|
);
|
|
1408
|
+
// `force: true` bypasses the cooldown/threshold gates but early returns
|
|
1409
|
+
// for "no eligible messages" / "insufficient messages" still leave
|
|
1410
|
+
// `summaryFailed` undefined. Only track when the summary LLM actually ran.
|
|
1411
|
+
if (midLoopCompact.summaryFailed !== undefined) {
|
|
1412
|
+
trackCompactionOutcome(ctx, midLoopCompact.summaryFailed, onEvent);
|
|
1413
|
+
}
|
|
1101
1414
|
if (midLoopCompact.compacted) {
|
|
1102
1415
|
ctx.messages = midLoopCompact.messages;
|
|
1416
|
+
reducerCompacted = true;
|
|
1103
1417
|
ctx.contextCompactedMessageCount +=
|
|
1104
1418
|
midLoopCompact.compactedPersistedMessages;
|
|
1105
1419
|
ctx.contextCompactedAt = Date.now();
|
|
@@ -1108,6 +1422,11 @@ export async function runAgentLoopImpl(
|
|
|
1108
1422
|
midLoopCompact.summaryText,
|
|
1109
1423
|
ctx.contextCompactedMessageCount,
|
|
1110
1424
|
);
|
|
1425
|
+
// Fire auto-analysis on compaction — see forceCompact() for rationale.
|
|
1426
|
+
enqueueAutoAnalysisOnCompaction(
|
|
1427
|
+
ctx.conversationId,
|
|
1428
|
+
ctx.trustContext?.trustClass,
|
|
1429
|
+
);
|
|
1111
1430
|
onEvent({
|
|
1112
1431
|
type: "context_compacted",
|
|
1113
1432
|
previousEstimatedInputTokens:
|
|
@@ -1141,18 +1460,32 @@ export async function runAgentLoopImpl(
|
|
|
1141
1460
|
// stripInjectionsForCompaction() unconditionally removed the existing
|
|
1142
1461
|
// NOW.md block from ctx.messages above, so we must always re-inject
|
|
1143
1462
|
// the current content regardless of whether compaction actually ran.
|
|
1144
|
-
|
|
1463
|
+
const injection = await applyRuntimeInjections(ctx.messages, {
|
|
1145
1464
|
...injectionOpts,
|
|
1146
1465
|
pkbContext: currentPkbContent,
|
|
1147
1466
|
nowScratchpad: currentNowContent,
|
|
1148
1467
|
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1149
1468
|
? ctx.workspaceTopLevelContext
|
|
1150
1469
|
: null,
|
|
1470
|
+
// Suppress the chronological-transcript snapshot once the reducer
|
|
1471
|
+
// has collapsed `ctx.messages`; the captured snapshot reflects the
|
|
1472
|
+
// full persisted transcript and would overwrite compaction.
|
|
1473
|
+
slackChronologicalMessages: reducerCompacted
|
|
1474
|
+
? null
|
|
1475
|
+
: injectionOpts.slackChronologicalMessages,
|
|
1151
1476
|
mode: currentInjectionMode,
|
|
1152
1477
|
});
|
|
1478
|
+
runMessages = injection.messages;
|
|
1153
1479
|
if (isTrustedActor && currentInjectionMode !== "minimal") {
|
|
1154
|
-
|
|
1155
|
-
|
|
1480
|
+
ctx.graphMemory.retrackCachedNodes();
|
|
1481
|
+
}
|
|
1482
|
+
const midLoopCompactStrip = stripHistoricalWebSearchResults(runMessages);
|
|
1483
|
+
if (midLoopCompactStrip.stats.blocksStripped > 0) {
|
|
1484
|
+
rlog.info(
|
|
1485
|
+
{ phase: "mid-loop-compact", ...midLoopCompactStrip.stats },
|
|
1486
|
+
"Converted historical web_search_tool_result blocks to text summaries",
|
|
1487
|
+
);
|
|
1488
|
+
runMessages = midLoopCompactStrip.messages;
|
|
1156
1489
|
}
|
|
1157
1490
|
preRepairMessages = runMessages;
|
|
1158
1491
|
preRunHistoryLength = runMessages.length;
|
|
@@ -1163,6 +1496,7 @@ export async function runAgentLoopImpl(
|
|
|
1163
1496
|
abortController.signal,
|
|
1164
1497
|
reqId,
|
|
1165
1498
|
onCheckpoint,
|
|
1499
|
+
turnCallSite,
|
|
1166
1500
|
);
|
|
1167
1501
|
}
|
|
1168
1502
|
|
|
@@ -1194,7 +1528,9 @@ export async function runAgentLoopImpl(
|
|
|
1194
1528
|
);
|
|
1195
1529
|
const retryRepair = deepRepairHistory(runMessages);
|
|
1196
1530
|
runMessages = retryRepair.messages;
|
|
1197
|
-
|
|
1531
|
+
const retryStrip = stripHistoricalWebSearchResults(runMessages);
|
|
1532
|
+
runMessages = retryStrip.messages;
|
|
1533
|
+
preRepairMessages = runMessages;
|
|
1198
1534
|
preRunHistoryLength = runMessages.length;
|
|
1199
1535
|
state.orderingErrorDetected = false;
|
|
1200
1536
|
state.deferredOrderingError = null;
|
|
@@ -1205,6 +1541,7 @@ export async function runAgentLoopImpl(
|
|
|
1205
1541
|
abortController.signal,
|
|
1206
1542
|
reqId,
|
|
1207
1543
|
onCheckpoint,
|
|
1544
|
+
turnCallSite,
|
|
1208
1545
|
);
|
|
1209
1546
|
|
|
1210
1547
|
if (state.orderingErrorDetected) {
|
|
@@ -1234,6 +1571,14 @@ export async function runAgentLoopImpl(
|
|
|
1234
1571
|
|
|
1235
1572
|
if (updatedHistory.length > preRunHistoryLength) {
|
|
1236
1573
|
ctx.messages = stripInjectionsForCompaction(updatedHistory);
|
|
1574
|
+
try {
|
|
1575
|
+
clearPkbSystemReminderMetadataForConversation(ctx.conversationId);
|
|
1576
|
+
} catch (err) {
|
|
1577
|
+
rlog.warn(
|
|
1578
|
+
{ err },
|
|
1579
|
+
"Failed to clear pkbSystemReminderBlock metadata after compaction strip (non-fatal)",
|
|
1580
|
+
);
|
|
1581
|
+
}
|
|
1237
1582
|
convergenceStripped = true;
|
|
1238
1583
|
preRepairMessages = updatedHistory;
|
|
1239
1584
|
preRunHistoryLength = updatedHistory.length;
|
|
@@ -1246,14 +1591,19 @@ export async function runAgentLoopImpl(
|
|
|
1246
1591
|
// message (e.g. "242201 tokens > 200000"), use it to correct the
|
|
1247
1592
|
// compaction target. The estimator may significantly underestimate
|
|
1248
1593
|
// (e.g. estimated 185k but actual was 242k), so using the
|
|
1249
|
-
// uncorrected preflightBudget would still be too high.
|
|
1594
|
+
// uncorrected preflightBudget would still be too high. Passes the raw
|
|
1595
|
+
// error so ContextOverflowError.actualTokens can short-circuit the
|
|
1596
|
+
// string-regex path for proxy-rewrapped untyped errors.
|
|
1250
1597
|
const actualTokens = parseActualTokensFromError(
|
|
1251
|
-
state.
|
|
1598
|
+
state.contextTooLargeError,
|
|
1252
1599
|
);
|
|
1253
1600
|
const estimatedTokensAtOverflow = estimatePromptTokens(
|
|
1254
1601
|
ctx.messages,
|
|
1255
1602
|
ctx.systemPrompt,
|
|
1256
|
-
{
|
|
1603
|
+
{
|
|
1604
|
+
providerName: estimationProviderName,
|
|
1605
|
+
toolTokenBudget,
|
|
1606
|
+
},
|
|
1257
1607
|
);
|
|
1258
1608
|
let correctedTarget = preflightBudget;
|
|
1259
1609
|
if (actualTokens && estimatedTokensAtOverflow > 0) {
|
|
@@ -1301,9 +1651,9 @@ export async function runAgentLoopImpl(
|
|
|
1301
1651
|
const step = await reduceContextOverflow(
|
|
1302
1652
|
ctx.messages,
|
|
1303
1653
|
{
|
|
1304
|
-
providerName:
|
|
1654
|
+
providerName: estimationProviderName,
|
|
1305
1655
|
systemPrompt: ctx.systemPrompt,
|
|
1306
|
-
contextWindow: config.contextWindow,
|
|
1656
|
+
contextWindow: config.llm.default.contextWindow,
|
|
1307
1657
|
targetTokens: correctedTarget,
|
|
1308
1658
|
toolTokenBudget,
|
|
1309
1659
|
},
|
|
@@ -1317,6 +1667,21 @@ export async function runAgentLoopImpl(
|
|
|
1317
1667
|
ctx.messages = step.messages;
|
|
1318
1668
|
currentInjectionMode = step.state.injectionMode;
|
|
1319
1669
|
|
|
1670
|
+
// See the preflight reducer call above for rationale. Only track when
|
|
1671
|
+
// the summary LLM actually ran — `summaryFailed === undefined`
|
|
1672
|
+
// indicates the reducer's forced compaction took an early-return path
|
|
1673
|
+
// without calling the summary LLM.
|
|
1674
|
+
if (
|
|
1675
|
+
step.compactionResult &&
|
|
1676
|
+
step.compactionResult.summaryFailed !== undefined
|
|
1677
|
+
) {
|
|
1678
|
+
trackCompactionOutcome(
|
|
1679
|
+
ctx,
|
|
1680
|
+
step.compactionResult.summaryFailed,
|
|
1681
|
+
onEvent,
|
|
1682
|
+
);
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1320
1685
|
if (step.compactionResult?.compacted) {
|
|
1321
1686
|
ctx.contextCompactedMessageCount +=
|
|
1322
1687
|
step.compactionResult.compactedPersistedMessages;
|
|
@@ -1326,6 +1691,11 @@ export async function runAgentLoopImpl(
|
|
|
1326
1691
|
step.compactionResult.summaryText,
|
|
1327
1692
|
ctx.contextCompactedMessageCount,
|
|
1328
1693
|
);
|
|
1694
|
+
// Fire auto-analysis on compaction — see forceCompact() for rationale.
|
|
1695
|
+
enqueueAutoAnalysisOnCompaction(
|
|
1696
|
+
ctx.conversationId,
|
|
1697
|
+
ctx.trustContext?.trustClass,
|
|
1698
|
+
);
|
|
1329
1699
|
onEvent({
|
|
1330
1700
|
type: "context_compacted",
|
|
1331
1701
|
previousEstimatedInputTokens:
|
|
@@ -1355,23 +1725,35 @@ export async function runAgentLoopImpl(
|
|
|
1355
1725
|
step.compactionResult.compactedPersistedMessages,
|
|
1356
1726
|
);
|
|
1357
1727
|
shouldInjectWorkspace = true;
|
|
1728
|
+
reducerCompacted = true;
|
|
1358
1729
|
}
|
|
1359
1730
|
|
|
1360
1731
|
// Only re-inject NOW.md when ctx.messages was actually stripped;
|
|
1361
1732
|
// otherwise the existing NOW.md block is still present and
|
|
1362
1733
|
// re-injecting would duplicate it.
|
|
1363
|
-
|
|
1734
|
+
const injection = await applyRuntimeInjections(ctx.messages, {
|
|
1364
1735
|
...injectionOpts,
|
|
1365
1736
|
pkbContext: currentPkbContent,
|
|
1366
1737
|
nowScratchpad: convergenceStripped ? currentNowContent : null,
|
|
1367
1738
|
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1368
1739
|
? ctx.workspaceTopLevelContext
|
|
1369
1740
|
: null,
|
|
1741
|
+
slackChronologicalMessages: reducerCompacted
|
|
1742
|
+
? null
|
|
1743
|
+
: injectionOpts.slackChronologicalMessages,
|
|
1370
1744
|
mode: currentInjectionMode,
|
|
1371
1745
|
});
|
|
1746
|
+
runMessages = injection.messages;
|
|
1372
1747
|
if (isTrustedActor && currentInjectionMode !== "minimal") {
|
|
1373
|
-
|
|
1374
|
-
|
|
1748
|
+
ctx.graphMemory.retrackCachedNodes();
|
|
1749
|
+
}
|
|
1750
|
+
const convergenceStrip = stripHistoricalWebSearchResults(runMessages);
|
|
1751
|
+
if (convergenceStrip.stats.blocksStripped > 0) {
|
|
1752
|
+
rlog.info(
|
|
1753
|
+
{ phase: "convergence", ...convergenceStrip.stats },
|
|
1754
|
+
"Converted historical web_search_tool_result blocks to text summaries",
|
|
1755
|
+
);
|
|
1756
|
+
runMessages = convergenceStrip.messages;
|
|
1375
1757
|
}
|
|
1376
1758
|
preRepairMessages = runMessages;
|
|
1377
1759
|
preRunHistoryLength = runMessages.length;
|
|
@@ -1384,6 +1766,7 @@ export async function runAgentLoopImpl(
|
|
|
1384
1766
|
abortController.signal,
|
|
1385
1767
|
reqId,
|
|
1386
1768
|
onCheckpoint,
|
|
1769
|
+
turnCallSite,
|
|
1387
1770
|
);
|
|
1388
1771
|
|
|
1389
1772
|
// If the rerun still yields at checkpoint, the turn is still
|
|
@@ -1405,6 +1788,14 @@ export async function runAgentLoopImpl(
|
|
|
1405
1788
|
// pre-rerun messages.
|
|
1406
1789
|
if (updatedHistory.length > preRunHistoryLength) {
|
|
1407
1790
|
ctx.messages = stripInjectionsForCompaction(updatedHistory);
|
|
1791
|
+
try {
|
|
1792
|
+
clearPkbSystemReminderMetadataForConversation(ctx.conversationId);
|
|
1793
|
+
} catch (err) {
|
|
1794
|
+
rlog.warn(
|
|
1795
|
+
{ err },
|
|
1796
|
+
"Failed to clear pkbSystemReminderBlock metadata after compaction strip (non-fatal)",
|
|
1797
|
+
);
|
|
1798
|
+
}
|
|
1408
1799
|
convergenceStripped = true;
|
|
1409
1800
|
preRepairMessages = updatedHistory;
|
|
1410
1801
|
preRunHistoryLength = updatedHistory.length;
|
|
@@ -1440,8 +1831,18 @@ export async function runAgentLoopImpl(
|
|
|
1440
1831
|
targetInputTokensOverride: correctedTarget,
|
|
1441
1832
|
},
|
|
1442
1833
|
);
|
|
1834
|
+
// Only track when the summary LLM actually ran; `force: true`
|
|
1835
|
+
// bypasses the cooldown but not the early-return paths.
|
|
1836
|
+
if (emergencyCompact.summaryFailed !== undefined) {
|
|
1837
|
+
trackCompactionOutcome(
|
|
1838
|
+
ctx,
|
|
1839
|
+
emergencyCompact.summaryFailed,
|
|
1840
|
+
onEvent,
|
|
1841
|
+
);
|
|
1842
|
+
}
|
|
1443
1843
|
if (emergencyCompact.compacted) {
|
|
1444
1844
|
ctx.messages = emergencyCompact.messages;
|
|
1845
|
+
reducerCompacted = true;
|
|
1445
1846
|
ctx.contextCompactedMessageCount +=
|
|
1446
1847
|
emergencyCompact.compactedPersistedMessages;
|
|
1447
1848
|
ctx.contextCompactedAt = Date.now();
|
|
@@ -1450,6 +1851,11 @@ export async function runAgentLoopImpl(
|
|
|
1450
1851
|
emergencyCompact.summaryText,
|
|
1451
1852
|
ctx.contextCompactedMessageCount,
|
|
1452
1853
|
);
|
|
1854
|
+
// Fire auto-analysis on compaction — see forceCompact() for rationale.
|
|
1855
|
+
enqueueAutoAnalysisOnCompaction(
|
|
1856
|
+
ctx.conversationId,
|
|
1857
|
+
ctx.trustContext?.trustClass,
|
|
1858
|
+
);
|
|
1453
1859
|
onEvent({
|
|
1454
1860
|
type: "context_compacted",
|
|
1455
1861
|
previousEstimatedInputTokens:
|
|
@@ -1483,19 +1889,29 @@ export async function runAgentLoopImpl(
|
|
|
1483
1889
|
|
|
1484
1890
|
// Only re-inject NOW.md when ctx.messages was actually stripped;
|
|
1485
1891
|
// otherwise the existing block is still present.
|
|
1486
|
-
|
|
1892
|
+
const injection = await applyRuntimeInjections(ctx.messages, {
|
|
1487
1893
|
...injectionOpts,
|
|
1488
1894
|
pkbContext: currentPkbContent,
|
|
1489
1895
|
nowScratchpad: convergenceStripped ? currentNowContent : null,
|
|
1490
1896
|
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1491
1897
|
? ctx.workspaceTopLevelContext
|
|
1492
1898
|
: null,
|
|
1899
|
+
slackChronologicalMessages: reducerCompacted
|
|
1900
|
+
? null
|
|
1901
|
+
: injectionOpts.slackChronologicalMessages,
|
|
1493
1902
|
mode: currentInjectionMode,
|
|
1494
1903
|
});
|
|
1904
|
+
runMessages = injection.messages;
|
|
1495
1905
|
if (isTrustedActor && currentInjectionMode !== "minimal") {
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1906
|
+
ctx.graphMemory.retrackCachedNodes();
|
|
1907
|
+
}
|
|
1908
|
+
const emergencyStrip = stripHistoricalWebSearchResults(runMessages);
|
|
1909
|
+
if (emergencyStrip.stats.blocksStripped > 0) {
|
|
1910
|
+
rlog.info(
|
|
1911
|
+
{ phase: "emergency_compact", ...emergencyStrip.stats },
|
|
1912
|
+
"Converted historical web_search_tool_result blocks to text summaries",
|
|
1913
|
+
);
|
|
1914
|
+
runMessages = emergencyStrip.messages;
|
|
1499
1915
|
}
|
|
1500
1916
|
preRepairMessages = runMessages;
|
|
1501
1917
|
preRunHistoryLength = runMessages.length;
|
|
@@ -1507,6 +1923,7 @@ export async function runAgentLoopImpl(
|
|
|
1507
1923
|
abortController.signal,
|
|
1508
1924
|
reqId,
|
|
1509
1925
|
onCheckpoint,
|
|
1926
|
+
turnCallSite,
|
|
1510
1927
|
);
|
|
1511
1928
|
} else {
|
|
1512
1929
|
// User denied compression — emit a graceful assistant explanation
|
|
@@ -1560,8 +1977,18 @@ export async function runAgentLoopImpl(
|
|
|
1560
1977
|
targetInputTokensOverride: correctedTarget,
|
|
1561
1978
|
},
|
|
1562
1979
|
);
|
|
1980
|
+
// Only track when the summary LLM actually ran; `force: true`
|
|
1981
|
+
// bypasses the cooldown but not the early-return paths.
|
|
1982
|
+
if (emergencyCompact.summaryFailed !== undefined) {
|
|
1983
|
+
trackCompactionOutcome(
|
|
1984
|
+
ctx,
|
|
1985
|
+
emergencyCompact.summaryFailed,
|
|
1986
|
+
onEvent,
|
|
1987
|
+
);
|
|
1988
|
+
}
|
|
1563
1989
|
if (emergencyCompact.compacted) {
|
|
1564
1990
|
ctx.messages = emergencyCompact.messages;
|
|
1991
|
+
reducerCompacted = true;
|
|
1565
1992
|
ctx.contextCompactedMessageCount +=
|
|
1566
1993
|
emergencyCompact.compactedPersistedMessages;
|
|
1567
1994
|
ctx.contextCompactedAt = Date.now();
|
|
@@ -1570,6 +1997,11 @@ export async function runAgentLoopImpl(
|
|
|
1570
1997
|
emergencyCompact.summaryText,
|
|
1571
1998
|
ctx.contextCompactedMessageCount,
|
|
1572
1999
|
);
|
|
2000
|
+
// Fire auto-analysis on compaction — see forceCompact() for rationale.
|
|
2001
|
+
enqueueAutoAnalysisOnCompaction(
|
|
2002
|
+
ctx.conversationId,
|
|
2003
|
+
ctx.trustContext?.trustClass,
|
|
2004
|
+
);
|
|
1573
2005
|
onEvent({
|
|
1574
2006
|
type: "context_compacted",
|
|
1575
2007
|
previousEstimatedInputTokens:
|
|
@@ -1603,18 +2035,29 @@ export async function runAgentLoopImpl(
|
|
|
1603
2035
|
|
|
1604
2036
|
// Only re-inject NOW.md when ctx.messages was actually stripped;
|
|
1605
2037
|
// otherwise the existing block is still present.
|
|
1606
|
-
|
|
2038
|
+
const injection = await applyRuntimeInjections(ctx.messages, {
|
|
1607
2039
|
...injectionOpts,
|
|
1608
2040
|
pkbContext: currentPkbContent,
|
|
1609
2041
|
nowScratchpad: convergenceStripped ? currentNowContent : null,
|
|
1610
2042
|
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1611
2043
|
? ctx.workspaceTopLevelContext
|
|
1612
2044
|
: null,
|
|
2045
|
+
slackChronologicalMessages: reducerCompacted
|
|
2046
|
+
? null
|
|
2047
|
+
: injectionOpts.slackChronologicalMessages,
|
|
1613
2048
|
mode: currentInjectionMode,
|
|
1614
2049
|
});
|
|
2050
|
+
runMessages = injection.messages;
|
|
1615
2051
|
if (isTrustedActor && currentInjectionMode !== "minimal") {
|
|
1616
|
-
|
|
1617
|
-
|
|
2052
|
+
ctx.graphMemory.retrackCachedNodes();
|
|
2053
|
+
}
|
|
2054
|
+
const fallbackStrip = stripHistoricalWebSearchResults(runMessages);
|
|
2055
|
+
if (fallbackStrip.stats.blocksStripped > 0) {
|
|
2056
|
+
rlog.info(
|
|
2057
|
+
{ phase: "fail_gracefully_compact", ...fallbackStrip.stats },
|
|
2058
|
+
"Converted historical web_search_tool_result blocks to text summaries",
|
|
2059
|
+
);
|
|
2060
|
+
runMessages = fallbackStrip.messages;
|
|
1618
2061
|
}
|
|
1619
2062
|
preRepairMessages = runMessages;
|
|
1620
2063
|
preRunHistoryLength = runMessages.length;
|
|
@@ -1626,6 +2069,7 @@ export async function runAgentLoopImpl(
|
|
|
1626
2069
|
abortController.signal,
|
|
1627
2070
|
reqId,
|
|
1628
2071
|
onCheckpoint,
|
|
2072
|
+
turnCallSite,
|
|
1629
2073
|
);
|
|
1630
2074
|
}
|
|
1631
2075
|
// action === "fail_gracefully" falls through to the final error below
|
|
@@ -1753,9 +2197,16 @@ export async function runAgentLoopImpl(
|
|
|
1753
2197
|
try {
|
|
1754
2198
|
const conv = getConversation(ctx.conversationId);
|
|
1755
2199
|
if (conv) {
|
|
1756
|
-
const convDir = getResolvedConversationDirPath(
|
|
1757
|
-
|
|
1758
|
-
|
|
2200
|
+
const convDir = getResolvedConversationDirPath(
|
|
2201
|
+
ctx.conversationId,
|
|
2202
|
+
conv.createdAt,
|
|
2203
|
+
);
|
|
2204
|
+
const { messages: derefMessages, dereferencedCount } =
|
|
2205
|
+
derefToolResultReReads(restoredHistory);
|
|
2206
|
+
const { messages: truncatedMessages, truncatedCount } =
|
|
2207
|
+
postTurnTruncateToolResults(derefMessages, {
|
|
2208
|
+
conversationDir: convDir,
|
|
2209
|
+
});
|
|
1759
2210
|
if (truncatedCount > 0 || dereferencedCount > 0) {
|
|
1760
2211
|
rlog.info(
|
|
1761
2212
|
{ truncatedCount, dereferencedCount },
|
|
@@ -1765,16 +2216,13 @@ export async function runAgentLoopImpl(
|
|
|
1765
2216
|
restoredHistory = truncatedMessages;
|
|
1766
2217
|
}
|
|
1767
2218
|
} catch (err) {
|
|
1768
|
-
rlog.warn(
|
|
2219
|
+
rlog.warn(
|
|
2220
|
+
{ err },
|
|
2221
|
+
"Post-turn tool result truncation failed (non-fatal)",
|
|
2222
|
+
);
|
|
1769
2223
|
}
|
|
1770
2224
|
}
|
|
1771
2225
|
|
|
1772
|
-
const postLoopContextEstimate = estimatePromptTokens(
|
|
1773
|
-
restoredHistory,
|
|
1774
|
-
ctx.systemPrompt,
|
|
1775
|
-
{ providerName: ctx.provider.name, toolTokenBudget },
|
|
1776
|
-
);
|
|
1777
|
-
|
|
1778
2226
|
// Persist injections in history: runtime-injected context stays on
|
|
1779
2227
|
// historical user messages so the conversation prefix is stable for
|
|
1780
2228
|
// Anthropic's prefix caching. Stripping only happens during
|
|
@@ -1795,8 +2243,8 @@ export async function runAgentLoopImpl(
|
|
|
1795
2243
|
state.exchangeProviderName,
|
|
1796
2244
|
state.exchangeLlmCallCount,
|
|
1797
2245
|
{
|
|
1798
|
-
tokens:
|
|
1799
|
-
maxTokens: config.contextWindow.maxInputTokens,
|
|
2246
|
+
tokens: state.lastCallInputTokens,
|
|
2247
|
+
maxTokens: config.llm.default.contextWindow.maxInputTokens,
|
|
1800
2248
|
},
|
|
1801
2249
|
);
|
|
1802
2250
|
|
|
@@ -2014,6 +2462,12 @@ export async function runAgentLoopImpl(
|
|
|
2014
2462
|
|
|
2015
2463
|
// Commit app changes (fire-and-forget — apps repo is separate from workspace)
|
|
2016
2464
|
void commitAppTurnChanges(ctx.conversationId, ctx.turnCount);
|
|
2465
|
+
|
|
2466
|
+
// Recompute relationship-state.json at turn boundary (fire-and-forget).
|
|
2467
|
+
// The writer swallows its own errors, but we still guard with catch()
|
|
2468
|
+
// here so a regression in the writer can never bubble out of the
|
|
2469
|
+
// agent loop and reject an otherwise-complete turn.
|
|
2470
|
+
void writeRelationshipState().catch(() => {});
|
|
2017
2471
|
}
|
|
2018
2472
|
|
|
2019
2473
|
ctx.profiler.emitSummary(ctx.traceEmitter, reqId);
|
|
@@ -2022,6 +2476,7 @@ export async function runAgentLoopImpl(
|
|
|
2022
2476
|
ctx.processing = false;
|
|
2023
2477
|
ctx.onConfirmationOutcome = undefined;
|
|
2024
2478
|
ctx.surfaceActionRequestIds.delete(ctx.currentRequestId ?? "");
|
|
2479
|
+
ctx.approvedViaPromptThisTurn = false;
|
|
2025
2480
|
ctx.currentRequestId = undefined;
|
|
2026
2481
|
ctx.currentActiveSurfaceId = undefined;
|
|
2027
2482
|
ctx.allowedToolNames = undefined;
|
|
@@ -2029,6 +2484,10 @@ export async function runAgentLoopImpl(
|
|
|
2029
2484
|
// Channel command intents (e.g. Telegram /start) are single-turn metadata.
|
|
2030
2485
|
// Clear at turn end so they never leak into subsequent unrelated messages.
|
|
2031
2486
|
ctx.commandIntent = undefined;
|
|
2487
|
+
// taskRunId scopes ephemeral task-run permissions to a single turn. Clear
|
|
2488
|
+
// before drainQueue so queued/drained turns on a reused conversation can't
|
|
2489
|
+
// inherit stale in-task-run scope from the turn that just finished.
|
|
2490
|
+
ctx.taskRunId = undefined;
|
|
2032
2491
|
|
|
2033
2492
|
// Consolidation deferred to compaction: keeping assistant + tool_result
|
|
2034
2493
|
// messages unconsolidated preserves the exact message structure sent to
|