@vellumai/assistant 0.6.4 → 0.6.6
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/AGENTS.md +9 -1
- package/ARCHITECTURE.md +43 -49
- package/Dockerfile +17 -3
- package/README.md +3 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
- package/bun.lock +8 -3
- package/docs/architecture/integrations.md +33 -59
- package/docs/architecture/memory.md +25 -30
- package/docs/architecture/security.md +19 -18
- package/docs/browser-use-architecture-phase2.md +63 -20
- package/docs/error-handling.md +111 -0
- package/docs/plugins.md +761 -0
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +2 -1
- package/examples/plugins/echo/README.md +132 -0
- package/examples/plugins/echo/package.json +17 -0
- package/examples/plugins/echo/register.ts +187 -0
- package/knip.json +9 -2
- package/node_modules/@vellumai/ces-contracts/package.json +2 -1
- 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/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
- package/openapi.yaml +334 -78
- package/package.json +6 -3
- package/scripts/generate-openapi.ts +50 -11
- 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 +112 -1
- package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
- package/src/__tests__/anthropic-provider.test.ts +171 -2
- package/src/__tests__/app-compiler.test.ts +57 -0
- package/src/__tests__/approval-cascade.test.ts +36 -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 +1 -0
- package/src/__tests__/avatar-generator.test.ts +4 -2
- package/src/__tests__/browser-fill-credential.test.ts +1 -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 +51 -182
- package/src/__tests__/btw-routes.test.ts +47 -1
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/call-controller.test.ts +1 -2
- package/src/__tests__/call-site-routing-provider.test.ts +214 -0
- package/src/__tests__/catalog-cache.test.ts +96 -4
- package/src/__tests__/channel-approval-routes.test.ts +4 -4
- package/src/__tests__/channel-reply-delivery.test.ts +300 -2
- package/src/__tests__/checker.test.ts +870 -655
- package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
- package/src/__tests__/compaction-events.test.ts +501 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/config-analysis.test.ts +11 -28
- 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-model-image-provider.test.ts +110 -0
- package/src/__tests__/config-schema-cmd.test.ts +11 -5
- package/src/__tests__/config-schema.test.ts +440 -114
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
- package/src/__tests__/config-watcher.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +72 -73
- package/src/__tests__/contacts-tools.test.ts +26 -0
- package/src/__tests__/contacts-write.test.ts +4 -4
- package/src/__tests__/context-overflow-policy.test.ts +7 -7
- package/src/__tests__/context-token-estimator.test.ts +191 -1
- package/src/__tests__/context-window-manager.test.ts +883 -4
- package/src/__tests__/conversation-abort-tool-results.test.ts +32 -15
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +86 -46
- package/src/__tests__/conversation-agent-loop.test.ts +435 -216
- package/src/__tests__/conversation-attachments.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +36 -10
- package/src/__tests__/conversation-error.test.ts +37 -6
- package/src/__tests__/conversation-history-web-search.test.ts +7 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +34 -12
- package/src/__tests__/conversation-lifecycle.test.ts +336 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
- package/src/__tests__/conversation-pairing.test.ts +174 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +32 -15
- package/src/__tests__/conversation-process-callsite.test.ts +309 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +44 -21
- package/src/__tests__/conversation-queue.test.ts +68 -38
- package/src/__tests__/conversation-routes-disk-view.test.ts +36 -7
- package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
- package/src/__tests__/conversation-runtime-assembly.test.ts +2877 -152
- package/src/__tests__/conversation-runtime-workspace.test.ts +35 -50
- package/src/__tests__/conversation-seed-composer.test.ts +2 -2
- package/src/__tests__/conversation-skill-tools.test.ts +12 -146
- package/src/__tests__/conversation-slash-queue.test.ts +39 -19
- package/src/__tests__/conversation-slash-unknown.test.ts +53 -16
- package/src/__tests__/conversation-speed-override.test.ts +36 -12
- 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 +118 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +1 -1
- package/src/__tests__/conversation-unread-route.test.ts +2 -2
- package/src/__tests__/conversation-usage.test.ts +4 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +33 -9
- package/src/__tests__/conversation-workspace-injection.test.ts +46 -15
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +46 -15
- package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
- package/src/__tests__/credential-health-service.test.ts +78 -9
- package/src/__tests__/credential-security-invariants.test.ts +5 -2
- 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 +135 -19
- package/src/__tests__/credentials-cli.test.ts +1 -9
- package/src/__tests__/cross-provider-web-search.test.ts +84 -0
- package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
- package/src/__tests__/delete-propagation.test.ts +437 -0
- package/src/__tests__/dm-backfill.test.ts +417 -0
- package/src/__tests__/dm-persistence.test.ts +227 -0
- package/src/__tests__/edit-propagation.test.ts +280 -0
- package/src/__tests__/empty-response-pipeline.test.ts +305 -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 +29 -10
- package/src/__tests__/file-write-tool.test.ts +151 -1
- package/src/__tests__/filing-service.test.ts +255 -0
- package/src/__tests__/first-greeting.test.ts +247 -5
- package/src/__tests__/gemini-provider.test.ts +0 -3
- package/src/__tests__/guardian-grant-minting.test.ts +8 -0
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/headless-browser-mode.test.ts +57 -0
- package/src/__tests__/heartbeat-service.test.ts +96 -15
- package/src/__tests__/history-repair-pipeline.test.ts +399 -0
- package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
- package/src/__tests__/host-proxy-interface.test.ts +36 -2
- package/src/__tests__/host-shell-tool.test.ts +124 -18
- package/src/__tests__/http-user-message-parity.test.ts +29 -1
- package/src/__tests__/image-credentials.test.ts +137 -0
- package/src/__tests__/image-service-dispatcher.test.ts +186 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
- package/src/__tests__/injector-chain.test.ts +526 -0
- package/src/__tests__/intent-routing.test.ts +1 -66
- package/src/__tests__/llm-call-pipeline.test.ts +285 -0
- package/src/__tests__/llm-catalog-parity.test.ts +174 -0
- package/src/__tests__/llm-context-normalization.test.ts +121 -0
- package/src/__tests__/llm-resolver.test.ts +214 -0
- package/src/__tests__/llm-schema.test.ts +223 -0
- package/src/__tests__/managed-proxy-context.test.ts +6 -2
- package/src/__tests__/media-generate-image.test.ts +119 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
- package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
- package/src/__tests__/messaging-skill-split.test.ts +3 -34
- package/src/__tests__/migration-import-from-url.test.ts +621 -0
- package/src/__tests__/model-intents.test.ts +11 -83
- package/src/__tests__/notification-broadcaster.test.ts +3 -3
- 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__/notification-decision-strategy.test.ts +0 -11
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
- package/src/__tests__/oauth-apps-routes.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +14 -12
- package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
- package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
- package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
- package/src/__tests__/oauth-providers-routes.test.ts +3 -2
- package/src/__tests__/oauth-store.test.ts +46 -78
- package/src/__tests__/oauth2-gateway-transport.test.ts +8 -3
- package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
- package/src/__tests__/onboarding-template-contract.test.ts +16 -64
- package/src/__tests__/openai-image-service.test.ts +368 -0
- package/src/__tests__/openai-provider.test.ts +7 -0
- package/src/__tests__/openai-responses-provider.test.ts +396 -0
- package/src/__tests__/openrouter-provider-only.test.ts +135 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
- package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +1 -25
- package/src/__tests__/permission-mode.test.ts +16 -0
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
- package/src/__tests__/persistence-pipeline.test.ts +377 -0
- package/src/__tests__/persona-resolver.test.ts +13 -13
- package/src/__tests__/pipeline-runner.test.ts +565 -0
- package/src/__tests__/pkb-autoinject.test.ts +37 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
- package/src/__tests__/platform.test.ts +5 -2
- package/src/__tests__/plugin-bootstrap.test.ts +483 -0
- package/src/__tests__/plugin-registry.test.ts +273 -0
- package/src/__tests__/plugin-route-contribution.test.ts +288 -0
- package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
- package/src/__tests__/plugin-types.test.ts +320 -0
- package/src/__tests__/pricing.test.ts +93 -14
- 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 +69 -9
- package/src/__tests__/reaction-persistence.test.ts +561 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +0 -2
- package/src/__tests__/relay-server.test.ts +1 -1
- 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__/schedule-routes.test.ts +131 -1
- package/src/__tests__/scheduler-recurrence.test.ts +14 -70
- package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
- package/src/__tests__/secret-detection-handler.test.ts +0 -10
- 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 +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +29 -1
- package/src/__tests__/server-history-render.test.ts +31 -0
- package/src/__tests__/shell-identity.test.ts +0 -134
- package/src/__tests__/shell-parser-property.test.ts +13 -13
- package/src/__tests__/skill-cache-store.test.ts +182 -0
- package/src/__tests__/skills.test.ts +19 -33
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-skill.test.ts +3 -8
- package/src/__tests__/starter-bundle.test.ts +35 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
- package/src/__tests__/suggestion-routes.test.ts +259 -3
- package/src/__tests__/system-prompt.test.ts +22 -35
- package/src/__tests__/task-memory-cleanup.test.ts +1 -0
- package/src/__tests__/task-runner.test.ts +3 -1
- package/src/__tests__/task-scheduler.test.ts +3 -15
- package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/test-preload.ts +11 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +2 -52
- package/src/__tests__/thread-backfill.test.ts +941 -0
- package/src/__tests__/title-generate-pipeline.test.ts +224 -0
- package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
- package/src/__tests__/tool-error-pipeline.test.ts +244 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -8
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
- package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
- package/src/__tests__/tool-executor.test.ts +201 -94
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -110
- package/src/__tests__/trust-store.test.ts +442 -109
- package/src/__tests__/update-bulletin-job.test.ts +389 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
- package/src/__tests__/user-plugin-loader.test.ts +191 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -22
- 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-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-046-seed-conversation-starters-callsite.test.ts +185 -0
- package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
- package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
- package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +11 -11
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
- package/src/__tests__/workspace-policy.test.ts +22 -16
- package/src/acp/client-handler.ts +1 -2
- package/src/agent/loop.ts +545 -115
- package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
- package/src/approvals/guardian-request-resolvers.ts +80 -0
- 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-worker.test.ts +2 -13
- package/src/backup/backup-worker.ts +3 -15
- 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/app-compiler.ts +84 -1
- package/src/calls/call-state.ts +2 -2
- package/src/calls/guardian-question-copy.ts +2 -2
- package/src/calls/telephony-stt-routing.ts +1 -1
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/channels/__tests__/types.test.ts +3 -3
- package/src/channels/types.ts +6 -4
- package/src/cli/AGENTS.md +1 -1
- package/src/cli/__tests__/notifications.test.ts +87 -211
- package/src/cli/commands/__tests__/attachment.test.ts +438 -0
- package/src/cli/commands/__tests__/backup.test.ts +1 -1
- 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__/email-list.test.ts +6 -0
- package/src/cli/commands/__tests__/email-send.test.ts +93 -1
- package/src/cli/commands/__tests__/image-generation.test.ts +886 -0
- package/src/cli/commands/__tests__/inference-send.test.ts +463 -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 +606 -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 +2 -2
- package/src/cli/commands/browser.ts +350 -0
- package/src/cli/commands/cache.ts +341 -0
- package/src/cli/commands/clients.ts +138 -0
- package/src/cli/commands/completions.ts +2 -12
- package/src/cli/commands/config.ts +6 -6
- package/src/cli/commands/conversations-import.ts +347 -0
- package/src/cli/commands/conversations.ts +69 -8
- package/src/cli/commands/email.ts +234 -194
- package/src/cli/commands/image-generation.ts +299 -0
- package/src/cli/commands/inference.ts +200 -0
- package/src/cli/commands/memory.ts +127 -17
- package/src/cli/commands/notifications.ts +68 -103
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +2 -2
- package/src/cli/commands/oauth/providers.ts +176 -8
- package/src/cli/commands/oauth/status.ts +46 -36
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +0 -1
- package/src/cli/commands/skills.ts +3 -4
- 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 +39 -24
- package/src/cli.ts +0 -37
- package/src/config/__tests__/backup-schema.test.ts +7 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
- package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
- 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/__tests__/messaging-feed-events.test.ts +207 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +20 -1
- 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 +69 -12
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -8
- package/src/config/bundled-skills/schedule/SKILL.md +8 -3
- package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
- package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-tool-registry.ts +0 -190
- package/src/config/env.ts +7 -2
- package/src/config/feature-flag-registry.json +42 -10
- package/src/config/llm-resolver.ts +128 -0
- package/src/config/loader.ts +194 -10
- package/src/config/raw-config-utils.ts +30 -2
- package/src/config/sanitize-for-transfer.ts +35 -0
- package/src/config/schema.ts +49 -41
- package/src/config/schemas/analysis.ts +3 -22
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/calls.ts +0 -4
- package/src/config/schemas/conversations.ts +16 -0
- package/src/config/schemas/filing.ts +2 -7
- package/src/config/schemas/heartbeat.ts +0 -5
- package/src/config/schemas/inference.ts +3 -23
- package/src/config/schemas/llm.ts +317 -0
- 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 +9 -4
- package/src/config/schemas/stt.ts +1 -0
- package/src/config/schemas/tts.ts +64 -0
- package/src/config/schemas/updates.ts +1 -1
- package/src/config/schemas/workspace-git.ts +3 -40
- package/src/config/skill-state.ts +6 -2
- package/src/config/skills.ts +96 -7
- package/src/context/__tests__/compact-prompt.test.ts +63 -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/prompts/compact.md +26 -0
- package/src/context/token-estimator.ts +61 -3
- package/src/context/tool-result-truncation.ts +3 -63
- package/src/context/window-manager.ts +417 -39
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/executable-discovery.ts +19 -8
- package/src/credential-execution/process-manager.test.ts +109 -0
- package/src/credential-execution/process-manager.ts +65 -2
- package/src/credential-health/credential-health-service.ts +19 -6
- package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
- 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 +0 -3
- package/src/daemon/context-overflow-policy.ts +4 -13
- package/src/daemon/context-overflow-reducer.ts +4 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +162 -34
- package/src/daemon/conversation-agent-loop.ts +1282 -599
- package/src/daemon/conversation-attachments.ts +2 -6
- package/src/daemon/conversation-error.ts +36 -1
- package/src/daemon/conversation-history.ts +10 -19
- package/src/daemon/conversation-lifecycle.ts +59 -17
- package/src/daemon/conversation-messaging.ts +73 -4
- package/src/daemon/conversation-notifiers.ts +2 -110
- package/src/daemon/conversation-process.ts +24 -11
- package/src/daemon/conversation-queue-manager.ts +3 -0
- package/src/daemon/conversation-runtime-assembly.ts +1063 -211
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +389 -1
- package/src/daemon/conversation-tool-setup.ts +51 -9
- package/src/daemon/conversation-usage.ts +1 -1
- package/src/daemon/conversation.ts +197 -64
- package/src/daemon/external-plugins-bootstrap.ts +478 -0
- package/src/daemon/external-skills-bootstrap.ts +41 -0
- package/src/daemon/first-greeting.ts +191 -14
- 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 +65 -12
- package/src/daemon/handlers/conversations.ts +9 -2
- package/src/daemon/handlers/shared.ts +39 -11
- package/src/daemon/handlers/skills.ts +7 -3
- package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
- package/src/daemon/lifecycle.ts +109 -82
- package/src/daemon/message-types/computer-use.ts +2 -34
- package/src/daemon/message-types/conversations.ts +63 -0
- package/src/daemon/message-types/messages.ts +21 -1
- 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 +122 -12
- package/src/daemon/shutdown-handlers.ts +2 -12
- package/src/daemon/tool-side-effects.ts +14 -65
- package/src/daemon/web-search-history.ts +126 -0
- package/src/events/domain-events.ts +0 -1
- package/src/filing/filing-service.ts +9 -10
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
- package/src/heartbeat/heartbeat-service.ts +99 -28
- package/src/home/__tests__/feed-population-integration.test.ts +312 -0
- package/src/home/__tests__/feed-scheduler.test.ts +39 -11
- package/src/home/__tests__/rollup-producer.test.ts +44 -0
- package/src/home/assistant-feed-authoring.ts +4 -0
- package/src/home/emit-feed-event.ts +11 -0
- package/src/home/feed-scheduler.ts +20 -4
- package/src/home/feed-types.ts +97 -4
- package/src/home/relationship-state-writer.ts +2 -2
- package/src/home/rewrite-command-preview.ts +66 -0
- package/src/home/rollup-producer.ts +34 -5
- package/src/home/suggested-prompts.ts +101 -0
- 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__/socket-path.test.ts +34 -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 +2 -1
- package/src/ipc/cli-server.ts +26 -8
- package/src/ipc/gateway-client.ts +6 -3
- package/src/ipc/routes/attachment.ts +114 -0
- package/src/ipc/routes/browser-context.ts +63 -0
- package/src/ipc/routes/browser.ts +97 -0
- package/src/ipc/routes/cache.ts +96 -0
- package/src/ipc/routes/get-contact.ts +16 -0
- package/src/ipc/routes/index.ts +31 -1
- package/src/ipc/routes/list-clients.ts +31 -0
- package/src/ipc/routes/merge-contacts.ts +17 -0
- package/src/ipc/routes/notification.ts +133 -0
- package/src/ipc/routes/rename-conversation.ts +59 -0
- package/src/ipc/routes/search-contacts.ts +19 -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/upsert-contact.ts +25 -0
- package/src/ipc/routes/watcher.ts +203 -0
- package/src/ipc/socket-path.ts +76 -0
- package/src/media/app-icon-generator.ts +23 -46
- package/src/media/avatar-router.ts +26 -41
- package/src/media/gemini-image-service.ts +8 -41
- package/src/media/image-credentials.ts +73 -0
- package/src/media/image-service.ts +85 -0
- package/src/media/openai-image-service.ts +131 -0
- package/src/media/types.ts +46 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +9 -8
- package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
- package/src/memory/admin.ts +18 -0
- package/src/memory/conversation-analyze-job.ts +14 -13
- package/src/memory/conversation-attention-store.ts +13 -6
- package/src/memory/conversation-crud.ts +133 -3
- package/src/memory/conversation-group-migration.ts +38 -6
- package/src/memory/conversation-queries.ts +57 -4
- package/src/memory/conversation-title-service.ts +32 -4
- package/src/memory/db-init.ts +10 -0
- package/src/memory/embedding-backend.ts +1 -1
- package/src/memory/embedding-gemini.test.ts +41 -2
- package/src/memory/embedding-gemini.ts +6 -1
- package/src/memory/graph/bootstrap.test.ts +282 -0
- package/src/memory/graph/bootstrap.ts +8 -5
- package/src/memory/graph/compaction.ts +299 -0
- package/src/memory/graph/consolidation.ts +4 -4
- package/src/memory/graph/conversation-graph-memory.ts +89 -29
- package/src/memory/graph/extraction.test.ts +272 -2
- package/src/memory/graph/extraction.ts +183 -53
- package/src/memory/graph/graph-search.test.ts +93 -0
- package/src/memory/graph/graph-search.ts +4 -1
- package/src/memory/graph/inspect.ts +2 -2
- 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 +237 -48
- 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/indexer.ts +5 -5
- package/src/memory/job-handlers/conversation-starters.ts +23 -20
- 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 +44 -3
- package/src/memory/jobs-worker.ts +4 -0
- package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
- package/src/memory/migrations/149-oauth-tables.ts +1 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +2 -2
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
- package/src/memory/migrations/223-schedule-script-column.ts +11 -0
- package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
- package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/pkb/pkb-index.test.ts +369 -0
- package/src/memory/pkb/pkb-index.ts +255 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +252 -0
- package/src/memory/pkb/pkb-reconcile.ts +148 -0
- package/src/memory/pkb/pkb-search.test.ts +499 -0
- package/src/memory/pkb/pkb-search.ts +159 -0
- package/src/memory/pkb/types.ts +53 -0
- package/src/memory/qdrant-client.test.ts +60 -0
- package/src/memory/qdrant-client.ts +147 -1
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/schema/oauth.ts +4 -1
- package/src/memory/slack-thread-store.ts +37 -0
- package/src/messaging/providers/gmail/adapter.ts +6 -16
- package/src/messaging/providers/gmail/client.ts +22 -0
- package/src/messaging/providers/gmail/types.ts +7 -0
- package/src/messaging/providers/slack/adapter.ts +14 -2
- package/src/messaging/providers/slack/backfill.test.ts +257 -0
- package/src/messaging/providers/slack/backfill.ts +101 -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 +1421 -0
- package/src/messaging/providers/slack/render-transcript.ts +501 -0
- package/src/messaging/style-analyzer.ts +5 -2
- package/src/notifications/README.md +9 -5
- package/src/notifications/conversation-pairing.ts +78 -19
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/decision-engine.ts +3 -9
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/preference-extractor.ts +2 -6
- package/src/notifications/signal.ts +1 -2
- package/src/oauth/AGENTS.md +1 -1
- package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
- package/src/oauth/connect-orchestrator.ts +8 -34
- package/src/oauth/connect-types.ts +6 -10
- package/src/oauth/manual-token-connection.ts +23 -0
- package/src/oauth/oauth-store.ts +31 -14
- package/src/oauth/platform-connection.test.ts +47 -0
- package/src/oauth/platform-connection.ts +15 -5
- package/src/oauth/provider-serializer.ts +6 -1
- package/src/oauth/seed-providers.ts +56 -106
- package/src/outbound-proxy/http-forwarder.ts +9 -0
- package/src/permissions/approval-policy.test.ts +1223 -0
- package/src/permissions/approval-policy.ts +309 -0
- package/src/permissions/arg-parser.test.ts +161 -0
- package/src/permissions/arg-parser.ts +141 -0
- package/src/permissions/bash-risk-classifier.test.ts +1620 -0
- package/src/permissions/bash-risk-classifier.ts +950 -0
- package/src/permissions/checker.ts +348 -711
- package/src/permissions/command-registry.test.ts +774 -0
- package/src/permissions/command-registry.ts +1005 -0
- package/src/permissions/defaults.ts +28 -79
- package/src/permissions/file-risk-classifier.test.ts +535 -0
- package/src/permissions/file-risk-classifier.ts +274 -0
- package/src/permissions/gateway-threshold-reader.ts +196 -0
- package/src/permissions/prompter.ts +4 -0
- package/src/permissions/risk-types.ts +262 -0
- package/src/permissions/schedule-risk-classifier.test.ts +129 -0
- package/src/permissions/schedule-risk-classifier.ts +85 -0
- package/src/permissions/secret-prompter.ts +53 -2
- package/src/permissions/shell-identity.ts +2 -42
- 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 +161 -62
- package/src/permissions/types.ts +25 -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 +9 -19
- package/src/platform/client.ts +19 -1
- package/src/plugins/defaults/circuit-breaker.ts +146 -0
- package/src/plugins/defaults/compaction.ts +145 -0
- package/src/plugins/defaults/empty-response.ts +126 -0
- package/src/plugins/defaults/history-repair.ts +85 -0
- package/src/plugins/defaults/index.ts +116 -0
- package/src/plugins/defaults/injectors.ts +491 -0
- package/src/plugins/defaults/llm-call.ts +82 -0
- package/src/plugins/defaults/memory-retrieval.ts +226 -0
- package/src/plugins/defaults/overflow-reduce.ts +181 -0
- package/src/plugins/defaults/persistence.ts +129 -0
- package/src/plugins/defaults/title-generate.ts +95 -0
- package/src/plugins/defaults/token-estimate.ts +104 -0
- package/src/plugins/defaults/tool-error.ts +126 -0
- package/src/plugins/defaults/tool-execute.ts +89 -0
- package/src/plugins/defaults/tool-result-truncate.ts +88 -0
- package/src/plugins/pipeline.ts +316 -0
- package/src/plugins/plugin-skill-contributions.ts +292 -0
- package/src/plugins/registry.ts +241 -0
- package/src/plugins/types.ts +1134 -0
- package/src/plugins/user-loader.ts +177 -0
- package/src/prompts/persona-resolver.ts +3 -3
- package/src/prompts/system-prompt.ts +19 -20
- package/src/prompts/templates/BOOTSTRAP.md +27 -77
- package/src/prompts/templates/SOUL.md +2 -2
- package/src/prompts/update-bulletin-job.ts +190 -0
- 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__/retry-callsite.test.ts +424 -0
- package/src/providers/anthropic/client.ts +183 -14
- package/src/providers/call-site-routing.ts +71 -0
- package/src/providers/gemini/client.ts +65 -2
- package/src/providers/managed-proxy/constants.ts +2 -1
- package/src/providers/model-catalog.ts +524 -33
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/chat-completions-provider.ts +57 -1
- package/src/providers/openai/responses-provider.ts +86 -9
- package/src/providers/openrouter/client.ts +80 -9
- package/src/providers/provider-env-vars.ts +56 -0
- package/src/providers/provider-send-message.ts +22 -5
- package/src/providers/ratelimit.ts +4 -0
- package/src/providers/registry.ts +19 -8
- package/src/providers/retry.ts +174 -39
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +55 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +4 -4
- package/src/providers/speech-to-text/provider-catalog.ts +17 -0
- package/src/providers/speech-to-text/resolve.ts +7 -0
- package/src/providers/speech-to-text/xai-realtime.test.ts +646 -0
- package/src/providers/speech-to-text/xai-realtime.ts +821 -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 +93 -3
- package/src/runtime/AGENTS.md +27 -18
- package/src/runtime/__tests__/agent-wake.test.ts +43 -2
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
- package/src/runtime/__tests__/client-registry.test.ts +293 -0
- package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
- package/src/runtime/agent-wake.ts +63 -22
- package/src/runtime/auth/route-policy.ts +4 -0
- package/src/runtime/btw-sidechain.ts +13 -3
- package/src/runtime/channel-reply-delivery.ts +106 -2
- package/src/runtime/client-registry.ts +261 -0
- 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 +129 -9
- package/src/runtime/http-types.ts +23 -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-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/vbundle-builder.ts +1 -22
- package/src/runtime/migrations/vbundle-importer.ts +154 -9
- 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/routes/__tests__/home-feed-routes.test.ts +111 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +114 -75
- package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +78 -0
- package/src/runtime/routes/approval-routes.ts +29 -17
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
- package/src/runtime/routes/avatar-routes.ts +20 -4
- package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
- package/src/runtime/routes/btw-routes.ts +1 -4
- package/src/runtime/routes/conversation-management-routes.ts +20 -2
- package/src/runtime/routes/conversation-routes.ts +351 -138
- 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/guardian-approval-interception.ts +33 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
- package/src/runtime/routes/home-feed-routes.ts +120 -2
- package/src/runtime/routes/inbound-message-handler.ts +987 -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/integrations/slack/channel.ts +25 -3
- package/src/runtime/routes/llm-context-normalization.ts +23 -1
- package/src/runtime/routes/memory-item-routes.test.ts +1 -0
- package/src/runtime/routes/migration-routes.ts +720 -127
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
- package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
- package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
- package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
- package/src/runtime/routes/playground/deps.ts +56 -0
- package/src/runtime/routes/playground/force-compact.ts +73 -0
- package/src/runtime/routes/playground/guard.ts +37 -0
- package/src/runtime/routes/playground/index.ts +28 -0
- package/src/runtime/routes/playground/inject-failures.ts +159 -0
- package/src/runtime/routes/playground/reset-circuit.ts +115 -0
- package/src/runtime/routes/playground/seed-conversation.ts +139 -0
- package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
- package/src/runtime/routes/playground/state.ts +78 -0
- package/src/runtime/routes/schedule-routes.ts +89 -8
- package/src/runtime/routes/settings-routes.ts +4 -2
- package/src/runtime/routes/trust-rules-routes.ts +30 -14
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +3 -2
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +25 -43
- package/src/runtime/services/analyze-conversation.ts +12 -16
- package/src/runtime/skill-route-registry.ts +97 -15
- package/src/schedule/run-script.ts +68 -0
- package/src/schedule/schedule-store.ts +7 -1
- package/src/schedule/scheduler.ts +56 -8
- 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 +98 -35
- package/src/security/secure-keys.ts +7 -8
- package/src/security/token-manager.ts +27 -13
- package/src/security/untrusted-content.ts +102 -0
- package/src/skills/catalog-cache.ts +35 -9
- package/src/skills/catalog-install.ts +31 -3
- package/src/skills/skill-cache-store.ts +97 -0
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +76 -0
- package/src/stt/daemon-batch-transcriber.ts +33 -0
- package/src/stt/stt-stream-session.ts +8 -1
- package/src/stt/types.ts +5 -1
- package/src/subagent/manager.ts +41 -13
- package/src/tasks/ephemeral-permissions.ts +9 -4
- package/src/telemetry/usage-telemetry-reporter.ts +27 -5
- package/src/tools/browser/__tests__/browser-status.test.ts +234 -2
- package/src/tools/browser/browser-execution.ts +150 -54
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
- package/src/tools/browser/cdp-client/factory.ts +15 -4
- package/src/tools/credentials/tool-policy.ts +39 -5
- package/src/tools/credentials/vault.ts +9 -4
- package/src/tools/executor.ts +129 -73
- 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/script-proxy/session-manager.ts +37 -1
- package/src/tools/network/web-fetch.ts +20 -10
- package/src/tools/network/web-search.ts +19 -4
- package/src/tools/permission-checker.ts +116 -46
- package/src/tools/policy-context.ts +29 -8
- package/src/tools/registry.ts +195 -6
- package/src/tools/schedule/create.ts +23 -8
- package/src/tools/schedule/update.ts +3 -1
- package/src/tools/secret-detection-handler.ts +0 -51
- package/src/tools/side-effects.ts +0 -11
- package/src/tools/skills/execute.ts +2 -2
- package/src/tools/skills/sandbox-runner.ts +5 -2
- package/src/tools/system/avatar-generator.ts +6 -2
- package/src/tools/terminal/backends/native.ts +51 -2
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +1 -0
- package/src/tools/tool-manifest.ts +6 -21
- package/src/tools/types.ts +40 -5
- package/src/tools/verification-control-plane-policy.ts +1 -1
- package/src/tts/__tests__/provider-adapters.test.ts +240 -13
- package/src/tts/provider-catalog.ts +18 -0
- package/src/tts/providers/index.ts +2 -0
- package/src/tts/providers/xai-provider.ts +224 -0
- package/src/tts/types.ts +46 -0
- package/src/types/tar-stream.d.ts +66 -0
- package/src/util/json.ts +17 -0
- package/src/util/platform.ts +9 -4
- package/src/util/pricing.ts +41 -8
- package/src/watcher/engine.ts +1 -1
- package/src/watcher/providers/google-calendar.ts +134 -8
- package/src/watcher/providers/outlook-calendar.ts +42 -2
- package/src/workspace/git-service.ts +23 -4
- package/src/workspace/migrations/006-services-config.ts +2 -4
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
- 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 +56 -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/046-seed-conversation-starters-callsite.ts +108 -0
- package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
- package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/registry.ts +28 -0
- package/src/workspace/provider-commit-message-generator.ts +19 -38
- package/tsconfig.json +1 -1
- package/hook-templates/debug-prompt-logger/hook.json +0 -7
- package/hook-templates/debug-prompt-logger/run.sh +0 -66
- package/src/__tests__/context-overflow-approval.test.ts +0 -156
- package/src/__tests__/gmail-archive-fallback.test.ts +0 -193
- package/src/__tests__/gmail-archive-gate.test.ts +0 -246
- package/src/__tests__/gmail-preferences.test.ts +0 -117
- package/src/__tests__/hooks-blocking.test.ts +0 -178
- package/src/__tests__/hooks-cli.test.ts +0 -182
- package/src/__tests__/hooks-config.test.ts +0 -108
- package/src/__tests__/hooks-discovery.test.ts +0 -211
- package/src/__tests__/hooks-integration.test.ts +0 -196
- package/src/__tests__/hooks-manager.test.ts +0 -226
- package/src/__tests__/hooks-runner.test.ts +0 -175
- package/src/__tests__/hooks-settings.test.ts +0 -160
- package/src/__tests__/hooks-templates.test.ts +0 -169
- package/src/__tests__/hooks-ts-runner.test.ts +0 -170
- package/src/__tests__/hooks-watch.test.ts +0 -112
- package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
- package/src/__tests__/oauth-scope-policy.test.ts +0 -180
- 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 -279
- package/src/__tests__/send-notification-tool.test.ts +0 -83
- package/src/__tests__/update-bulletin-format.test.ts +0 -181
- package/src/__tests__/update-bulletin-state.test.ts +0 -135
- package/src/__tests__/update-bulletin.test.ts +0 -478
- package/src/__tests__/update-template-contract.test.ts +0 -29
- package/src/cli/commands/doctor.ts +0 -341
- package/src/cli/commands/shotgun.ts +0 -266
- package/src/config/bundled-skills/browser/SKILL.md +0 -88
- package/src/config/bundled-skills/browser/TOOLS.json +0 -516
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +0 -12
- 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-detach.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-status.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 -49
- 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/conversations/SKILL.md +0 -20
- package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -66
- package/src/config/bundled-skills/gmail/SKILL.md +0 -221
- package/src/config/bundled-skills/gmail/TOOLS.json +0 -588
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -256
- 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 -347
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +0 -59
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +0 -82
- 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 -347
- 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/heartbeat/SKILL.md +0 -43
- package/src/config/bundled-skills/notifications/SKILL.md +0 -40
- package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
- package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
- 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/screen-watch/SKILL.md +0 -27
- package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
- package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
- package/src/config/bundled-skills/slack/SKILL.md +0 -108
- 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/daemon/context-overflow-approval.ts +0 -52
- package/src/daemon/watch-handler.ts +0 -399
- package/src/hooks/cli.ts +0 -253
- package/src/hooks/config.ts +0 -100
- package/src/hooks/discovery.ts +0 -135
- package/src/hooks/manager.ts +0 -179
- package/src/hooks/runner.ts +0 -117
- package/src/hooks/templates.ts +0 -77
- package/src/hooks/types.ts +0 -75
- package/src/oauth/scope-policy.ts +0 -89
- package/src/prompts/templates/UPDATES.md +0 -50
- package/src/prompts/update-bulletin-format.ts +0 -85
- 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 -139
- package/src/runtime/gateway-internal-client.ts +0 -94
- package/src/runtime/routes/watch-routes.ts +0 -156
- package/src/shared/provider-env-vars.ts +0 -19
- package/src/signals/shotgun.ts +0 -203
- package/src/tools/watch/screen-watch.ts +0 -144
- package/src/tools/watch/watch-state.ts +0 -142
- 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
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
1
4
|
import type { ContextWindowConfig } from "../config/types.js";
|
|
2
5
|
import type {
|
|
3
6
|
ContentBlock,
|
|
@@ -5,6 +8,7 @@ import type {
|
|
|
5
8
|
Message,
|
|
6
9
|
Provider,
|
|
7
10
|
} from "../providers/types.js";
|
|
11
|
+
import { resolveBundledDir } from "../util/bundled-asset.js";
|
|
8
12
|
import { getLogger } from "../util/logger.js";
|
|
9
13
|
import { safeStringSlice } from "../util/unicode.js";
|
|
10
14
|
import {
|
|
@@ -26,20 +30,204 @@ const COMPACTION_TOOL_RESULT_MAX_CHARS = 6_000;
|
|
|
26
30
|
const MIN_COMPACTABLE_PERSISTED_MESSAGES = 2;
|
|
27
31
|
const INTERNAL_CONTEXT_SUMMARY_MESSAGES = new WeakSet<Message>();
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
/**
|
|
34
|
+
* When the existing summary is this fraction or more of the per-summary
|
|
35
|
+
* token budget, inject a "compress older content aggressively" instruction
|
|
36
|
+
* so incremental-update passes don't let the summary grow unboundedly.
|
|
37
|
+
*/
|
|
38
|
+
const SUMMARY_COMPRESSION_PRESSURE_RATIO = 0.6;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Text-block prefixes that persist in live history (for prefix-caching
|
|
42
|
+
* stability and model grounding) but pollute the summarizer's view of the
|
|
43
|
+
* actual conversation. These blocks are system-metadata attached to user
|
|
44
|
+
* turns — memory injections, turn context, workspace hints, etc. They are
|
|
45
|
+
* stripped ONLY from the messages fed to the summarization LLM call. Live
|
|
46
|
+
* history is never mutated, so prefix caching is preserved.
|
|
47
|
+
*
|
|
48
|
+
* This list intentionally overlaps with `RUNTIME_INJECTION_PREFIXES` in
|
|
49
|
+
* `conversation-runtime-assembly.ts`. That list governs in-flight turn
|
|
50
|
+
* assembly via pure prefix matching; this one governs compaction input.
|
|
51
|
+
* Keep the two lists in sync when a new injection type is added.
|
|
52
|
+
*
|
|
53
|
+
* Compaction strip coverage is two-tier: this prefix list catches
|
|
54
|
+
* internal-vocabulary tags and any tag carrying the `__injected`
|
|
55
|
+
* attribute, while `COMPACTION_ONLY_WRAPPED_STRIP_TAGS` below matches
|
|
56
|
+
* ambiguous bare-tag blocks that are shaped like a runtime-emitted
|
|
57
|
+
* open/close wrap. A new ambiguous tag added upstream needs to be
|
|
58
|
+
* evaluated against both tiers — internal-vocabulary names go here,
|
|
59
|
+
* and names whose bare form collides with ordinary English
|
|
60
|
+
* (`<memory>`, `<workspace>`, `<knowledge_base>`, `<pkb>`,
|
|
61
|
+
* `<system_reminder>`) go in the wrapped-strip list so user prose
|
|
62
|
+
* mentioning the tag is preserved.
|
|
63
|
+
*/
|
|
64
|
+
const COMPACTION_ONLY_STRIP_PREFIXES = [
|
|
65
|
+
"<memory __injected>",
|
|
66
|
+
"<memory_image __injected>",
|
|
67
|
+
"</memory_image>",
|
|
68
|
+
"<memory_context __injected>",
|
|
69
|
+
"<turn_context>",
|
|
70
|
+
"<channel_turn_context>",
|
|
71
|
+
"<guardian_context>",
|
|
72
|
+
"<inbound_actor_context>",
|
|
73
|
+
"<interface_turn_context>",
|
|
74
|
+
"<workspace_top_level>",
|
|
75
|
+
"<now_scratchpad>",
|
|
76
|
+
"<NOW.md Always keep this up to date",
|
|
77
|
+
"<active_thread>",
|
|
78
|
+
"<active_subagents>",
|
|
79
|
+
"<active_workspace>",
|
|
80
|
+
"<active_dynamic_page>",
|
|
81
|
+
"<channel_capabilities>",
|
|
82
|
+
"<channel_command_context>",
|
|
83
|
+
"<voice_call_control>",
|
|
84
|
+
"<transport_hints>",
|
|
85
|
+
"<system_notice>",
|
|
86
|
+
"<non_interactive_context>",
|
|
87
|
+
"<temporal_context>",
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Tags whose bare form (`<tag>`) is common English vocabulary or markup a
|
|
92
|
+
* user might legitimately type in prose. For these we only strip a text
|
|
93
|
+
* block if it is shaped exactly like a runtime injection: starts with
|
|
94
|
+
* `<tag>\n` and ends with `</tag>`. This bare-tag wrapped shape
|
|
95
|
+
* (e.g. `<memory>\n...\n</memory>`) appears in persisted history
|
|
96
|
+
* alongside the `__injected`-attributed variants, which the prefix list
|
|
97
|
+
* above already catches via `<memory __injected>`. A user who mentions
|
|
98
|
+
* `<memory>` in a sentence or inlines `<workspace>...</workspace>` within
|
|
99
|
+
* other prose will not match this shape.
|
|
100
|
+
*/
|
|
101
|
+
const COMPACTION_ONLY_WRAPPED_STRIP_TAGS = [
|
|
102
|
+
"memory",
|
|
103
|
+
"memory_context",
|
|
104
|
+
"workspace",
|
|
105
|
+
"knowledge_base",
|
|
106
|
+
"pkb",
|
|
107
|
+
"system_reminder",
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
function isCompactionInjectedBlock(text: string): boolean {
|
|
111
|
+
if (COMPACTION_ONLY_STRIP_PREFIXES.some((p) => text.startsWith(p))) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
return COMPACTION_ONLY_WRAPPED_STRIP_TAGS.some(
|
|
115
|
+
(tag) => text.startsWith(`<${tag}>\n`) && text.endsWith(`</${tag}>`),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Remove text blocks that look like runtime injections from user messages.
|
|
121
|
+
* Non-text blocks (images, tool_use, tool_result, etc.) are untouched.
|
|
122
|
+
* Empty messages (every block filtered out) are dropped from the output.
|
|
123
|
+
*
|
|
124
|
+
* Used only on the `compactableMessages` slice right before it is
|
|
125
|
+
* serialized for the summarization LLM — the caller's original message
|
|
126
|
+
* array is never mutated.
|
|
127
|
+
*/
|
|
128
|
+
export function stripCompactionOnlyInjections(messages: Message[]): Message[] {
|
|
129
|
+
return messages
|
|
130
|
+
.map((message) => {
|
|
131
|
+
if (message.role !== "user") return message;
|
|
132
|
+
const nextContent = message.content.filter((block) => {
|
|
133
|
+
if (block.type !== "text") return true;
|
|
134
|
+
return !isCompactionInjectedBlock(block.text);
|
|
135
|
+
});
|
|
136
|
+
if (nextContent.length === message.content.length) return message;
|
|
137
|
+
if (nextContent.length === 0) return null;
|
|
138
|
+
return { ...message, content: nextContent };
|
|
139
|
+
})
|
|
140
|
+
.filter(
|
|
141
|
+
(message): message is NonNullable<typeof message> => message != null,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Load the compaction summary system prompt from the bundled markdown asset.
|
|
147
|
+
*
|
|
148
|
+
* `resolveBundledDir` handles the compiled-binary case where the caller path
|
|
149
|
+
* points to `/$bunfs/` and the asset lives next to the executable (macOS app
|
|
150
|
+
* bundle `Contents/Resources/` or sibling dir). In source mode it falls back
|
|
151
|
+
* to the sibling `prompts/` directory.
|
|
152
|
+
*/
|
|
153
|
+
export function loadCompactPrompt(): string {
|
|
154
|
+
const callerDir = import.meta.dirname ?? __dirname;
|
|
155
|
+
const promptsDir = resolveBundledDir(callerDir, "prompts", "compact-prompts");
|
|
156
|
+
const promptPath = join(promptsDir, "compact.md");
|
|
157
|
+
const contents = readFileSync(promptPath, "utf-8");
|
|
158
|
+
if (contents.length === 0) {
|
|
159
|
+
throw new Error(
|
|
160
|
+
`compact.md at ${promptPath} is empty — compaction summary prompt missing`,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
return contents;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Hardcoded fallback prompt used when the bundled `compact.md` asset is
|
|
168
|
+
* missing or unreadable, so the daemon can still compact conversations
|
|
169
|
+
* rather than failing module import at startup.
|
|
170
|
+
*/
|
|
171
|
+
const SUMMARY_PROMPT_FALLBACK = [
|
|
172
|
+
"You are summarizing a long conversation so that the assistant can keep working with it after older messages are dropped. Your summary will REPLACE those messages — the assistant's only access to what was said earlier will be what you write here.",
|
|
173
|
+
"",
|
|
174
|
+
"Be thorough. Capture what happened, why it mattered, what's unresolved, and what was felt. Do not compress away emotional tone, relationship context, or nuance. Keep specific details (names, numbers, file paths, commands, URLs, exact phrasings) when they might matter later.",
|
|
175
|
+
"",
|
|
176
|
+
"Target length: aim for 1500–4000 tokens. Use the upper end when the conversation is rich in decisions, relationships, emotional content, or threads that are still open. Use the lower end for short or simple task execution.",
|
|
177
|
+
"",
|
|
178
|
+
"Open with a 1–2 paragraph narrative describing what the conversation is about and where it currently stands. Then use `## ` section headers. Use these when they apply; skip sections that have nothing to say; add your own headers when something doesn't fit:",
|
|
179
|
+
"- `## What We're Working On`",
|
|
180
|
+
"- `## Decisions & Commitments`",
|
|
181
|
+
"- `## Facts Worth Remembering`",
|
|
182
|
+
"- `## Open Threads`",
|
|
183
|
+
"- `## Emotional Arc / Relationship Notes` (include when relevant)",
|
|
184
|
+
"- `## Artifacts & References`",
|
|
185
|
+
"",
|
|
186
|
+
"If an existing summary is provided, update it: merge new information in, prefer the most recent and explicit detail on conflicts, and preserve anything still unresolved or still true. Do not restart from scratch.",
|
|
187
|
+
"",
|
|
188
|
+
"Never include in the summary: content inside `<memory __injected>`, `<memory>`, `<turn_context>`, `<workspace>`, `<knowledge_base>`, `<system_reminder>`, `<now_scratchpad>`, `<NOW.md …>`, `<active_thread>`, `<channel_capabilities>`, `<transport_hints>`, `<system_notice>`, or any other angle-bracket-tagged system blocks. Tool-call boilerplate (retries, failed attempts the assistant recovered from, routine status updates) — summarize the outcome instead. Repetitive chit-chat that adds nothing.",
|
|
189
|
+
"",
|
|
190
|
+
'Thread anchors (Slack only): if the input includes a "Retained Thread References" section, each listed reply cites its parent via `→ Mxxxxxx`. If that parent appears in the Transcript, preserve its text verbatim. Omit when absent.',
|
|
191
|
+
"",
|
|
192
|
+
"Return only the summary itself in markdown — no preamble, no meta-commentary.",
|
|
41
193
|
].join("\n");
|
|
42
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Load the compact prompt with graceful fallback. If `loader` throws (missing
|
|
197
|
+
* or unreadable bundled asset, partial deployment, filesystem corruption),
|
|
198
|
+
* logs a warning and returns the hardcoded fallback string so module import
|
|
199
|
+
* never fails. The loader is injectable for testability.
|
|
200
|
+
*/
|
|
201
|
+
export function loadCompactPromptOrFallback(
|
|
202
|
+
loader: () => string = loadCompactPrompt,
|
|
203
|
+
): string {
|
|
204
|
+
try {
|
|
205
|
+
return loader();
|
|
206
|
+
} catch (err) {
|
|
207
|
+
log.warn(
|
|
208
|
+
{ err },
|
|
209
|
+
"Failed to load compact.md from bundle; using inline fallback prompt. The bundled asset may be missing or unreadable.",
|
|
210
|
+
);
|
|
211
|
+
return SUMMARY_PROMPT_FALLBACK;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const SUMMARY_SYSTEM_PROMPT = loadCompactPromptOrFallback();
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Pattern matching a Slack-style reply tag-line's parent-alias reference.
|
|
219
|
+
* The chronological renderer emits reply lines as
|
|
220
|
+
* `[MM/DD/YY HH:MM @sender → Mxxxxxx]: body`, or, for edited replies,
|
|
221
|
+
* `[MM/DD/YY HH:MM @sender → Mxxxxxx, edited MM/DD/YY HH:MM]: body`. The
|
|
222
|
+
* character after the 6-hex parent alias is therefore `]` for a plain reply
|
|
223
|
+
* or `,` for an edited one — the regex accepts either. `Mxxxxxx` is the
|
|
224
|
+
* first 6 hex chars of sha256(threadTs). A retained-tail text block that
|
|
225
|
+
* contains this pattern is carrying a live reference to a parent that may
|
|
226
|
+
* still live in the compactable region — the summarizer needs to know about
|
|
227
|
+
* it to act on the Thread-anchors clause of SUMMARY_SYSTEM_PROMPT.
|
|
228
|
+
*/
|
|
229
|
+
const THREAD_REPLY_REFERENCE_PATTERN = /→ M[0-9a-f]{6}[,\]]/;
|
|
230
|
+
|
|
43
231
|
export interface ContextWindowResult {
|
|
44
232
|
messages: Message[];
|
|
45
233
|
compacted: boolean;
|
|
@@ -58,6 +246,13 @@ export interface ContextWindowResult {
|
|
|
58
246
|
summaryRawResponses?: unknown[];
|
|
59
247
|
summaryText: string;
|
|
60
248
|
reason?: string;
|
|
249
|
+
/**
|
|
250
|
+
* True when the summary LLM call threw and the local fallback produced the
|
|
251
|
+
* summary. Callers use this to distinguish provider-side summary failures
|
|
252
|
+
* from successful compactions so they can apply circuit-breaker logic
|
|
253
|
+
* without losing the fallback-compacted messages.
|
|
254
|
+
*/
|
|
255
|
+
summaryFailed?: boolean;
|
|
61
256
|
}
|
|
62
257
|
|
|
63
258
|
export interface ShouldCompactResult {
|
|
@@ -73,13 +268,22 @@ export interface ContextWindowCompactOptions {
|
|
|
73
268
|
* Override the minimum number of recent user turns to preserve.
|
|
74
269
|
* Set to `0` for emergency recovery that can compact the entire history
|
|
75
270
|
* (except the summary message itself). When omitted, the default floor
|
|
76
|
-
*
|
|
271
|
+
* is `1` (or `8` when `conversationOriginChannel === "slack"`).
|
|
77
272
|
*/
|
|
78
273
|
minKeepRecentUserTurns?: number;
|
|
274
|
+
/**
|
|
275
|
+
* Origin channel hint used when `minKeepRecentUserTurns` is omitted.
|
|
276
|
+
* Slack-originated conversations bump the default keep floor so multi-turn
|
|
277
|
+
* thread context (replies, quoted messages) is not summarized away too
|
|
278
|
+
* aggressively. Explicit `minKeepRecentUserTurns` overrides this hint.
|
|
279
|
+
*/
|
|
280
|
+
conversationOriginChannel?: string;
|
|
79
281
|
/**
|
|
80
282
|
* Override the target input token budget used for keep-boundary
|
|
81
|
-
* projected-fit checks.
|
|
82
|
-
*
|
|
283
|
+
* projected-fit checks. Clamped to no looser than `config.targetInputTokens`
|
|
284
|
+
* — i.e. the override may only demand a *stricter* fit. Passing a looser
|
|
285
|
+
* value has no effect. Intended for forced recovery paths that need a
|
|
286
|
+
* tighter target than the default.
|
|
83
287
|
*/
|
|
84
288
|
targetInputTokensOverride?: number;
|
|
85
289
|
/**
|
|
@@ -274,6 +478,8 @@ export class ContextWindowManager {
|
|
|
274
478
|
const keepPlan = this.pickKeepBoundary(messages, userTurnStarts, {
|
|
275
479
|
minKeepRecentUserTurns: options?.minKeepRecentUserTurns,
|
|
276
480
|
targetInputTokensOverride: options?.targetInputTokensOverride,
|
|
481
|
+
conversationOriginChannel: options?.conversationOriginChannel,
|
|
482
|
+
force: options?.force,
|
|
277
483
|
});
|
|
278
484
|
if (keepPlan.keepFromIndex <= summaryOffset) {
|
|
279
485
|
// All turns fit after truncation projection, but the real in-memory
|
|
@@ -447,13 +653,24 @@ export class ContextWindowManager {
|
|
|
447
653
|
};
|
|
448
654
|
}
|
|
449
655
|
|
|
656
|
+
const retainedThreadRefs = collectRetainedThreadReferences(
|
|
657
|
+
messages.slice(keepPlan.keepFromIndex),
|
|
658
|
+
);
|
|
659
|
+
// Strip runtime injections (memory, turn context, workspace hints, etc.)
|
|
660
|
+
// from the messages fed to the summarizer. These blocks are system
|
|
661
|
+
// metadata; leaving them in causes the summary to echo rotating memory
|
|
662
|
+
// content instead of the actual conversation. The caller's live message
|
|
663
|
+
// array is untouched so prefix caching stays intact.
|
|
664
|
+
const transcriptSource = stripCompactionOnlyInjections(compactableMessages);
|
|
450
665
|
const transcriptBlocks = this.capTranscriptBlocksToTokenBudget(
|
|
451
|
-
serializeMessagesToContentBlocks(
|
|
666
|
+
serializeMessagesToContentBlocks(transcriptSource),
|
|
452
667
|
existingSummary ?? "No previous summary.",
|
|
668
|
+
retainedThreadRefs,
|
|
453
669
|
);
|
|
454
670
|
const summaryUpdate = await this.updateSummary(
|
|
455
671
|
existingSummary ?? "No previous summary.",
|
|
456
672
|
transcriptBlocks,
|
|
673
|
+
retainedThreadRefs,
|
|
457
674
|
signal,
|
|
458
675
|
);
|
|
459
676
|
const summary = summaryUpdate.summary;
|
|
@@ -463,6 +680,7 @@ export class ContextWindowManager {
|
|
|
463
680
|
const summaryCacheCreationInputTokens =
|
|
464
681
|
summaryUpdate.cacheCreationInputTokens;
|
|
465
682
|
const summaryCacheReadInputTokens = summaryUpdate.cacheReadInputTokens;
|
|
683
|
+
const summaryFailed = summaryUpdate.failed;
|
|
466
684
|
const summaryRawResponses: unknown[] = [];
|
|
467
685
|
if (Array.isArray(summaryUpdate.rawResponse)) {
|
|
468
686
|
summaryRawResponses.push(...summaryUpdate.rawResponse);
|
|
@@ -499,7 +717,9 @@ export class ContextWindowManager {
|
|
|
499
717
|
// the summary at index 0 as child-owned.
|
|
500
718
|
this.nonPersistedPrefixCount = Math.max(
|
|
501
719
|
0,
|
|
502
|
-
this.nonPersistedPrefixCount -
|
|
720
|
+
this.nonPersistedPrefixCount -
|
|
721
|
+
injectedInCompactable -
|
|
722
|
+
injectedSummaryOffset,
|
|
503
723
|
);
|
|
504
724
|
this.summaryIsInjected = false;
|
|
505
725
|
|
|
@@ -532,6 +752,7 @@ export class ContextWindowManager {
|
|
|
532
752
|
summaryCacheReadInputTokens,
|
|
533
753
|
summaryRawResponses,
|
|
534
754
|
summaryText: summary,
|
|
755
|
+
summaryFailed,
|
|
535
756
|
};
|
|
536
757
|
}
|
|
537
758
|
|
|
@@ -548,14 +769,24 @@ export class ContextWindowManager {
|
|
|
548
769
|
opts?: {
|
|
549
770
|
minKeepRecentUserTurns?: number;
|
|
550
771
|
targetInputTokensOverride?: number;
|
|
772
|
+
conversationOriginChannel?: string;
|
|
773
|
+
force?: boolean;
|
|
551
774
|
},
|
|
552
775
|
): { keepFromIndex: number; keepTurns: number } {
|
|
776
|
+
// Slack-originated conversations rely on multi-turn thread context
|
|
777
|
+
// (reply chains, quoted messages, contextual references). Bump the
|
|
778
|
+
// default keep floor for them so compaction does not summarize away
|
|
779
|
+
// recent turns that the next reply may directly cite. Explicit
|
|
780
|
+
// `minKeepRecentUserTurns` (including emergency `0`) wins.
|
|
781
|
+
const defaultTurns = opts?.conversationOriginChannel === "slack" ? 8 : 1;
|
|
553
782
|
const minFloor = Math.min(
|
|
554
|
-
Math.max(0, Math.floor(opts?.minKeepRecentUserTurns ??
|
|
783
|
+
Math.max(0, Math.floor(opts?.minKeepRecentUserTurns ?? defaultTurns)),
|
|
555
784
|
userTurnStarts.length,
|
|
556
785
|
);
|
|
557
|
-
const targetTokens =
|
|
558
|
-
opts?.targetInputTokensOverride ?? this.targetInputTokens
|
|
786
|
+
const targetTokens = Math.min(
|
|
787
|
+
opts?.targetInputTokensOverride ?? this.targetInputTokens,
|
|
788
|
+
this.targetInputTokens,
|
|
789
|
+
);
|
|
559
790
|
|
|
560
791
|
// Binary search for the maximum keepTurns whose projected tokens fit
|
|
561
792
|
// within the budget. Token count is monotonically non-decreasing with
|
|
@@ -597,6 +828,32 @@ export class ContextWindowManager {
|
|
|
597
828
|
lo = hi;
|
|
598
829
|
}
|
|
599
830
|
|
|
831
|
+
// Under forced compaction with only the implicit default floor in play,
|
|
832
|
+
// that floor stops being an absolute override when the kept region still
|
|
833
|
+
// exceeds the target. Walk keepTurns below the floor — down to 0 if
|
|
834
|
+
// needed — so /compact can always drive the conversation toward target,
|
|
835
|
+
// even when the floor turn itself is oversized (e.g. a huge paste in the
|
|
836
|
+
// last user message). Exceptions that still treat the floor as hard:
|
|
837
|
+
// - Explicit `minKeepRecentUserTurns` (the caller opted in to that
|
|
838
|
+
// floor; emergency recovery already passes 0 when it wants to go all
|
|
839
|
+
// the way down).
|
|
840
|
+
// - Slack origin (the bumped 8-turn floor protects thread reply chains
|
|
841
|
+
// and quoted-message context that the next reply may directly cite).
|
|
842
|
+
// Automatic mid-loop compaction (force !== true) always honors the floor
|
|
843
|
+
// so the in-flight agent turn isn't summarized away.
|
|
844
|
+
const floorIsImplicitDefault =
|
|
845
|
+
opts?.minKeepRecentUserTurns === undefined &&
|
|
846
|
+
opts?.conversationOriginChannel !== "slack";
|
|
847
|
+
if (
|
|
848
|
+
opts?.force &&
|
|
849
|
+
floorIsImplicitDefault &&
|
|
850
|
+
projectedTokensForKeep(lo) > targetTokens
|
|
851
|
+
) {
|
|
852
|
+
while (lo > 0 && projectedTokensForKeep(lo) > targetTokens) {
|
|
853
|
+
lo--;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
600
857
|
const keepTurns = lo;
|
|
601
858
|
const rawKeepFromIndex =
|
|
602
859
|
keepTurns === 0
|
|
@@ -628,10 +885,13 @@ export class ContextWindowManager {
|
|
|
628
885
|
private capTranscriptBlocksToTokenBudget(
|
|
629
886
|
blocks: ContentBlock[],
|
|
630
887
|
currentSummary: string,
|
|
888
|
+
retainedThreadRefs: string[],
|
|
631
889
|
): ContentBlock[] {
|
|
890
|
+
const retainedRefsText = retainedThreadRefs.join("\n");
|
|
632
891
|
const overheadTokens =
|
|
633
892
|
estimateTextTokens(SUMMARY_SYSTEM_PROMPT) +
|
|
634
893
|
estimateTextTokens(currentSummary) +
|
|
894
|
+
estimateTextTokens(retainedRefsText) +
|
|
635
895
|
// Scaffolding text in buildSummaryContentBlocks ("Update the summary...",
|
|
636
896
|
// section headers, etc.) — generous fixed estimate.
|
|
637
897
|
200 +
|
|
@@ -643,7 +903,9 @@ export class ContextWindowManager {
|
|
|
643
903
|
);
|
|
644
904
|
|
|
645
905
|
const estimateBlockTokens = (b: ContentBlock): number =>
|
|
646
|
-
estimateContentBlockTokens(b, {
|
|
906
|
+
estimateContentBlockTokens(b, {
|
|
907
|
+
providerName: this.estimationProviderName,
|
|
908
|
+
});
|
|
647
909
|
|
|
648
910
|
let totalTokens = 0;
|
|
649
911
|
for (const block of blocks) {
|
|
@@ -656,7 +918,11 @@ export class ContextWindowManager {
|
|
|
656
918
|
// images to drop. Images are high-cost and their text context (message
|
|
657
919
|
// headers, surrounding tool_use/tool_result serializations) is preserved.
|
|
658
920
|
const result = [...blocks];
|
|
659
|
-
for (
|
|
921
|
+
for (
|
|
922
|
+
let i = 0;
|
|
923
|
+
i < result.length && totalTokens > maxTranscriptTokens;
|
|
924
|
+
i++
|
|
925
|
+
) {
|
|
660
926
|
if (result[i].type === "image") {
|
|
661
927
|
totalTokens -= estimateBlockTokens(result[i]);
|
|
662
928
|
const stub: ContentBlock = {
|
|
@@ -674,7 +940,11 @@ export class ContextWindowManager {
|
|
|
674
940
|
// than dropping it entirely so the summarizer always has content to work with.
|
|
675
941
|
let dropUntil = 0;
|
|
676
942
|
let droppedTokens = 0;
|
|
677
|
-
for (
|
|
943
|
+
for (
|
|
944
|
+
let i = 0;
|
|
945
|
+
i < result.length && totalTokens > maxTranscriptTokens;
|
|
946
|
+
i++
|
|
947
|
+
) {
|
|
678
948
|
const blockTokens = estimateBlockTokens(result[i]);
|
|
679
949
|
const excess = totalTokens - maxTranscriptTokens;
|
|
680
950
|
if (blockTokens > excess && result[i].type === "text") {
|
|
@@ -722,6 +992,7 @@ export class ContextWindowManager {
|
|
|
722
992
|
private async updateSummary(
|
|
723
993
|
currentSummary: string,
|
|
724
994
|
transcriptBlocks: ContentBlock[],
|
|
995
|
+
retainedThreadRefs: string[],
|
|
725
996
|
signal?: AbortSignal,
|
|
726
997
|
): Promise<{
|
|
727
998
|
summary: string;
|
|
@@ -731,19 +1002,38 @@ export class ContextWindowManager {
|
|
|
731
1002
|
cacheCreationInputTokens: number;
|
|
732
1003
|
cacheReadInputTokens: number;
|
|
733
1004
|
rawResponse?: unknown;
|
|
1005
|
+
/**
|
|
1006
|
+
* True when the provider.sendMessage call threw and the local fallback
|
|
1007
|
+
* was used. Callers (the agent loop) use this to drive circuit-breaker
|
|
1008
|
+
* state without having to reimplement the fallback themselves.
|
|
1009
|
+
*/
|
|
1010
|
+
failed: boolean;
|
|
734
1011
|
}> {
|
|
1012
|
+
// When the existing summary is already consuming most of its budget,
|
|
1013
|
+
// nudge the model to compress older durable content aggressively so
|
|
1014
|
+
// incremental-update passes don't let the summary grow unboundedly.
|
|
1015
|
+
const existingSummaryTokens = estimateTextTokens(currentSummary);
|
|
1016
|
+
const compressionPressure =
|
|
1017
|
+
existingSummaryTokens >=
|
|
1018
|
+
this.summaryMaxTokens * SUMMARY_COMPRESSION_PRESSURE_RATIO;
|
|
735
1019
|
const contentBlocks = buildSummaryContentBlocks(
|
|
736
1020
|
currentSummary,
|
|
737
1021
|
transcriptBlocks,
|
|
1022
|
+
retainedThreadRefs,
|
|
1023
|
+
{ compressionPressure },
|
|
738
1024
|
);
|
|
739
1025
|
const summaryMessage: Message = { role: "user", content: contentBlocks };
|
|
1026
|
+
let failed = false;
|
|
740
1027
|
try {
|
|
741
1028
|
const response = await this.provider.sendMessage(
|
|
742
1029
|
[summaryMessage],
|
|
743
1030
|
undefined,
|
|
744
1031
|
SUMMARY_SYSTEM_PROMPT,
|
|
745
1032
|
{
|
|
746
|
-
config: {
|
|
1033
|
+
config: {
|
|
1034
|
+
callSite: "conversationSummarization" as const,
|
|
1035
|
+
max_tokens: this.summaryMaxTokens,
|
|
1036
|
+
},
|
|
747
1037
|
signal,
|
|
748
1038
|
},
|
|
749
1039
|
);
|
|
@@ -759,15 +1049,19 @@ export class ContextWindowManager {
|
|
|
759
1049
|
response.usage.cacheCreationInputTokens ?? 0,
|
|
760
1050
|
cacheReadInputTokens: response.usage.cacheReadInputTokens ?? 0,
|
|
761
1051
|
rawResponse: response.rawResponse,
|
|
1052
|
+
failed: false,
|
|
762
1053
|
};
|
|
763
1054
|
}
|
|
764
1055
|
} catch (err) {
|
|
1056
|
+
failed = true;
|
|
765
1057
|
log.warn({ err }, "Summary generation failed, using local fallback");
|
|
766
1058
|
}
|
|
767
1059
|
|
|
768
1060
|
// Fallback: extract text-only transcript for local summary generation.
|
|
769
1061
|
const textTranscript = transcriptBlocks
|
|
770
|
-
.filter(
|
|
1062
|
+
.filter(
|
|
1063
|
+
(b): b is Extract<ContentBlock, { type: "text" }> => b.type === "text",
|
|
1064
|
+
)
|
|
771
1065
|
.map((b) => b.text)
|
|
772
1066
|
.join("\n\n");
|
|
773
1067
|
|
|
@@ -778,6 +1072,7 @@ export class ContextWindowManager {
|
|
|
778
1072
|
model: "",
|
|
779
1073
|
cacheCreationInputTokens: 0,
|
|
780
1074
|
cacheReadInputTokens: 0,
|
|
1075
|
+
failed,
|
|
781
1076
|
};
|
|
782
1077
|
}
|
|
783
1078
|
|
|
@@ -785,10 +1080,38 @@ export class ContextWindowManager {
|
|
|
785
1080
|
// Budget in tokens → approximate char limit (4 chars ≈ 1 token).
|
|
786
1081
|
const maxChars = this.summaryMaxTokens * 4;
|
|
787
1082
|
if (summary.length <= maxChars) return summary;
|
|
788
|
-
return
|
|
1083
|
+
return clampSummaryAtSectionBoundary(summary, maxChars);
|
|
789
1084
|
}
|
|
790
1085
|
}
|
|
791
1086
|
|
|
1087
|
+
/**
|
|
1088
|
+
* Truncate a markdown summary that exceeds `maxChars`, preferring a
|
|
1089
|
+
* section boundary (`\n## `) so we never cut a heading mid-text. Falls
|
|
1090
|
+
* back to a hard character slice when no boundary exists in the safe
|
|
1091
|
+
* region (first half of the budget).
|
|
1092
|
+
*/
|
|
1093
|
+
export function clampSummaryAtSectionBoundary(
|
|
1094
|
+
summary: string,
|
|
1095
|
+
maxChars: number,
|
|
1096
|
+
): string {
|
|
1097
|
+
if (summary.length <= maxChars) return summary;
|
|
1098
|
+
const ELLIPSIS = "...";
|
|
1099
|
+
// Hard limit we must stay under, leaving room for the ellipsis suffix.
|
|
1100
|
+
const cutoff = maxChars - ELLIPSIS.length;
|
|
1101
|
+
if (cutoff <= 0) return ELLIPSIS;
|
|
1102
|
+
const head = safeStringSlice(summary, 0, cutoff);
|
|
1103
|
+
// Find the last `## ` heading at a line start. Require it to be past the
|
|
1104
|
+
// midpoint of the allowed region so we don't drop most of the summary
|
|
1105
|
+
// just to hit a boundary — better to cut mid-section late than to keep
|
|
1106
|
+
// almost nothing.
|
|
1107
|
+
const halfway = Math.floor(cutoff / 2);
|
|
1108
|
+
const boundary = head.lastIndexOf("\n## ");
|
|
1109
|
+
if (boundary >= halfway) {
|
|
1110
|
+
return `${head.slice(0, boundary).trimEnd()}\n${ELLIPSIS}`;
|
|
1111
|
+
}
|
|
1112
|
+
return `${head}${ELLIPSIS}`;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
792
1115
|
function collectUserTurnStartIndexes(messages: Message[]): number[] {
|
|
793
1116
|
const starts: number[] = [];
|
|
794
1117
|
for (let i = 0; i < messages.length; i++) {
|
|
@@ -854,7 +1177,11 @@ function adjustForToolPairs(
|
|
|
854
1177
|
// Collect tool_use_ids referenced by tool_results in this user message
|
|
855
1178
|
const referencedIds = new Set<string>();
|
|
856
1179
|
for (const block of msg.content) {
|
|
857
|
-
if (
|
|
1180
|
+
if (
|
|
1181
|
+
(block.type === "tool_result" ||
|
|
1182
|
+
block.type === "web_search_tool_result") &&
|
|
1183
|
+
"tool_use_id" in block
|
|
1184
|
+
) {
|
|
858
1185
|
referencedIds.add((block as { tool_use_id: string }).tool_use_id);
|
|
859
1186
|
}
|
|
860
1187
|
}
|
|
@@ -930,26 +1257,76 @@ export function createContextSummaryMessage(summary: string): Message {
|
|
|
930
1257
|
function buildSummaryContentBlocks(
|
|
931
1258
|
currentSummary: string,
|
|
932
1259
|
transcriptBlocks: ContentBlock[],
|
|
1260
|
+
retainedThreadRefs: string[],
|
|
1261
|
+
options: { compressionPressure: boolean } = { compressionPressure: false },
|
|
933
1262
|
): ContentBlock[] {
|
|
1263
|
+
const lines = [
|
|
1264
|
+
"Update the summary with new transcript data.",
|
|
1265
|
+
"If new information conflicts with older notes, keep the most recent and explicit detail.",
|
|
1266
|
+
"Keep all unresolved asks and next steps.",
|
|
1267
|
+
"For any images included below, describe their visual content in the summary so the information is preserved after compaction.",
|
|
1268
|
+
];
|
|
1269
|
+
if (options.compressionPressure) {
|
|
1270
|
+
lines.push(
|
|
1271
|
+
"The existing summary is approaching its token budget. Compress older durable content aggressively (drop detail that is no longer load-bearing, merge bullets, tighten prose) while preserving the most recent turns' nuance.",
|
|
1272
|
+
);
|
|
1273
|
+
}
|
|
1274
|
+
lines.push(
|
|
1275
|
+
"",
|
|
1276
|
+
"### Existing Summary",
|
|
1277
|
+
currentSummary.trim().length > 0 ? currentSummary.trim() : "None.",
|
|
1278
|
+
"",
|
|
1279
|
+
);
|
|
1280
|
+
if (retainedThreadRefs.length > 0) {
|
|
1281
|
+
lines.push(
|
|
1282
|
+
"### Retained Thread References",
|
|
1283
|
+
"These reply tag lines remain in the live context after compaction. Each `→ Mxxxxxx` cites a parent message by alias; if that parent appears in the Transcript below, preserve its text verbatim.",
|
|
1284
|
+
...retainedThreadRefs.map((ref) => `- ${ref}`),
|
|
1285
|
+
"",
|
|
1286
|
+
);
|
|
1287
|
+
}
|
|
1288
|
+
lines.push("### Transcript");
|
|
934
1289
|
return [
|
|
935
1290
|
{
|
|
936
1291
|
type: "text",
|
|
937
|
-
text:
|
|
938
|
-
"Update the summary with new transcript data.",
|
|
939
|
-
"If new information conflicts with older notes, keep the most recent and explicit detail.",
|
|
940
|
-
"Keep all unresolved asks and next steps.",
|
|
941
|
-
"For any images included below, describe their visual content in the summary so the information is preserved after compaction.",
|
|
942
|
-
"",
|
|
943
|
-
"### Existing Summary",
|
|
944
|
-
currentSummary.trim().length > 0 ? currentSummary.trim() : "None.",
|
|
945
|
-
"",
|
|
946
|
-
"### Transcript",
|
|
947
|
-
].join("\n"),
|
|
1292
|
+
text: lines.join("\n"),
|
|
948
1293
|
} as ContentBlock,
|
|
949
1294
|
...transcriptBlocks,
|
|
950
1295
|
];
|
|
951
1296
|
}
|
|
952
1297
|
|
|
1298
|
+
/**
|
|
1299
|
+
* Scan retained-tail messages for Slack-style reply tag lines that cite a
|
|
1300
|
+
* thread parent via the `→ Mxxxxxx` alias convention. Returns the full tag
|
|
1301
|
+
* line for each match (de-duplicated, order-preserved) so the summarizer
|
|
1302
|
+
* has a concrete list of parents whose text must be preserved verbatim.
|
|
1303
|
+
*
|
|
1304
|
+
* Non-slack conversations and retained tails without any reply markers
|
|
1305
|
+
* produce an empty list — in that case the summarizer is told explicitly
|
|
1306
|
+
* that no verbatim preservation is required.
|
|
1307
|
+
*/
|
|
1308
|
+
function collectRetainedThreadReferences(
|
|
1309
|
+
retainedMessages: Message[],
|
|
1310
|
+
): string[] {
|
|
1311
|
+
const seen = new Set<string>();
|
|
1312
|
+
const out: string[] = [];
|
|
1313
|
+
for (const msg of retainedMessages) {
|
|
1314
|
+
for (const block of msg.content) {
|
|
1315
|
+
if (block.type !== "text") continue;
|
|
1316
|
+
const text = (block as { text: string }).text;
|
|
1317
|
+
for (const line of text.split("\n")) {
|
|
1318
|
+
if (!THREAD_REPLY_REFERENCE_PATTERN.test(line)) continue;
|
|
1319
|
+
const trimmed = line.trim();
|
|
1320
|
+
if (trimmed.length === 0) continue;
|
|
1321
|
+
if (seen.has(trimmed)) continue;
|
|
1322
|
+
seen.add(trimmed);
|
|
1323
|
+
out.push(trimmed);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
return out;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
953
1330
|
/**
|
|
954
1331
|
* Serialize messages into a sequence of content blocks. Text-based content
|
|
955
1332
|
* (tool calls, tool results, thinking, etc.) is serialized into text blocks.
|
|
@@ -970,7 +1347,8 @@ function serializeMessagesToContentBlocks(messages: Message[]): ContentBlock[] {
|
|
|
970
1347
|
textLines.length = 0;
|
|
971
1348
|
}
|
|
972
1349
|
blocks.push(block);
|
|
973
|
-
} else if (block.type === "tool_result") {
|
|
1350
|
+
} else if (block.type === "tool_result") {
|
|
1351
|
+
// guard:allow-tool-result-only — web_search_tool_result handled by serializeBlock via else branch
|
|
974
1352
|
// Extract images from tool_result contentBlocks before serializing.
|
|
975
1353
|
const collectedImages: ImageContent[] = [];
|
|
976
1354
|
textLines.push(serializeToolResultBlock(block, collectedImages));
|