@vellumai/assistant 0.8.4 → 0.8.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/AGENTS.md +33 -1
- package/ARCHITECTURE.md +3 -3
- package/bunfig.toml +6 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +2748 -216
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
- package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/annotate-risk-options.test.ts +1 -0
- package/src/__tests__/anthropic-provider.test.ts +34 -37
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +9 -13
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
- package/src/__tests__/audit-log-rotation.test.ts +72 -18
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +5 -5
- package/src/__tests__/call-controller.test.ts +3 -3
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +6 -5
- package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +320 -3
- package/src/__tests__/checker.test.ts +18 -27
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
- package/src/__tests__/computer-use-tools.test.ts +14 -18
- package/src/__tests__/config-loader-backfill.test.ts +13 -28
- package/src/__tests__/config-loader-corrupt.test.ts +5 -5
- package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
- package/src/__tests__/config-schema.test.ts +10 -10
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-token-estimator.test.ts +22 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
- package/src/__tests__/conversation-agent-loop.test.ts +581 -54
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-attention-store.test.ts +101 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +61 -0
- package/src/__tests__/conversation-fork-crud.test.ts +239 -15
- package/src/__tests__/conversation-fork-route.test.ts +3 -2
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
- package/src/__tests__/conversation-lifecycle.test.ts +53 -11
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
- package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
- package/src/__tests__/conversation-pairing.test.ts +53 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +40 -147
- package/src/__tests__/conversation-slash-queue.test.ts +84 -32
- package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
- package/src/__tests__/conversation-sync-tags.test.ts +218 -35
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
- package/src/__tests__/conversation-usage.test.ts +1 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +6 -5
- package/src/__tests__/credential-vault-unit.test.ts +21 -21
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +56 -2
- package/src/__tests__/db-connection-isolation.test.ts +7 -6
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +58 -41
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +0 -33
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +26 -40
- package/src/__tests__/document-create-dedupe.test.ts +189 -0
- package/src/__tests__/document-find-replace.test.ts +3 -2
- package/src/__tests__/document-tool-security.test.ts +81 -2
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
- package/src/__tests__/encrypted-store.test.ts +11 -9
- package/src/__tests__/feature-flag-test-helpers.ts +53 -0
- package/src/__tests__/filing-service.test.ts +1 -0
- package/src/__tests__/first-greeting.test.ts +62 -12
- package/src/__tests__/gateway-flag-listener.test.ts +236 -0
- package/src/__tests__/gemini-provider.test.ts +104 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +10 -7
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
- package/src/__tests__/heartbeat-service.test.ts +5 -0
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/host-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-shell-tool.test.ts +6 -5
- package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +29 -7
- package/src/__tests__/identity-intro-cache.test.ts +133 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-disk-pressure.test.ts +3 -17
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +408 -9
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +16 -2
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/messaging-send-tool.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +4 -6
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/oauth-commands-routes.test.ts +37 -0
- package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
- package/src/__tests__/oauth-store.test.ts +3 -2
- package/src/__tests__/onboarding-template-contract.test.ts +4 -3
- package/src/__tests__/openai-provider.test.ts +54 -9
- package/src/__tests__/openai-responses-provider.test.ts +176 -14
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -2
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +11 -13
- package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +21 -16
- package/src/__tests__/process-message-display-content.test.ts +19 -22
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +84 -84
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/schedule-store.test.ts +16 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +81 -42
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +16 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
- package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
- package/src/__tests__/skill-tool-factory.test.ts +97 -96
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +6 -5
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +183 -131
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
- package/src/__tests__/tool-executor.test.ts +64 -72
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +3 -2
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
- package/src/__tests__/voice-session-bridge.test.ts +37 -28
- package/src/__tests__/workspace-git-service.test.ts +6 -5
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
- package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +6 -7
- package/src/agent/loop.ts +88 -0
- package/src/api/README.md +127 -0
- package/src/api/constants/call-sites.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +51 -0
- package/src/api/events/assistant-text-delta.ts +32 -0
- package/src/api/events/assistant-turn-start.ts +33 -0
- package/src/api/events/document-comment-created.ts +48 -0
- package/src/api/events/document-comment-deleted.ts +24 -0
- package/src/api/events/document-comment-reopened.ts +25 -0
- package/src/api/events/document-comment-resolved.ts +27 -0
- package/src/api/events/generation-cancelled.ts +24 -0
- package/src/api/events/generation-handoff.ts +41 -0
- package/src/api/events/message-complete.ts +42 -0
- package/src/api/events/open-url.ts +30 -0
- package/src/api/events/relationship-state-updated.ts +25 -0
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +129 -0
- package/src/api/package.json +10 -0
- package/src/api/responses/llm-context-response.ts +39 -0
- package/src/api/responses/llm-request-log-entry.ts +93 -0
- package/src/api/responses/memory-recall-log.ts +65 -0
- package/src/api/responses/memory-v2-activation-log.ts +78 -0
- package/src/background-wake/background-wake-routes.test.ts +868 -0
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/voice-session-bridge.ts +4 -4
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +176 -1
- package/src/cli/commands/memory-v3-render.ts +491 -0
- package/src/cli/commands/memory-v3.ts +567 -0
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +4 -0
- package/src/config/assistant-feature-flags.ts +39 -46
- package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +8 -7
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +33 -17
- package/src/config/llm-context-resolution.ts +10 -1
- package/src/config/llm-resolver.ts +121 -15
- package/src/config/loader.ts +4 -5
- package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
- package/src/config/schemas/call-site-catalog.ts +21 -7
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +102 -2
- package/src/config/schemas/memory-v2.ts +272 -0
- package/src/config/schemas/memory.ts +2 -1
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/compactor.ts +52 -0
- package/src/context/token-estimator.ts +10 -5
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-execution/executable-discovery.ts +40 -0
- package/src/credential-execution/process-manager.ts +6 -2
- package/src/credential-health/credential-health-service.ts +125 -40
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
- package/src/daemon/conversation-agent-loop.ts +244 -90
- package/src/daemon/conversation-error.ts +64 -6
- package/src/daemon/conversation-lifecycle.ts +27 -22
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +38 -17
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +77 -32
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +40 -75
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +39 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +11 -3
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +4 -4
- package/src/daemon/host-file-proxy.ts +4 -4
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +10 -10
- package/src/daemon/lifecycle.ts +29 -26
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +11 -24
- package/src/daemon/message-types/conversations.ts +22 -27
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -14
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +25 -48
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/process-message.ts +9 -9
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +16 -0
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +62 -0
- package/src/daemon/tool-setup-types.ts +7 -0
- package/src/daemon/wake-target-adapter.ts +10 -0
- package/src/documents/document-store.ts +38 -0
- package/src/export/__tests__/transcript-formatter.test.ts +1 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
- package/src/heartbeat/heartbeat-service.ts +63 -0
- package/src/home/__tests__/feed-writer.test.ts +161 -0
- package/src/home/__tests__/post-connect-feed.test.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +55 -59
- package/src/home/feed-writer.ts +146 -7
- package/src/home/home-greeting.ts +0 -9
- package/src/home/suggested-prompts.ts +27 -154
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
- package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
- package/src/ipc/skill-routes/memory.ts +4 -3
- package/src/ipc/skill-routes/registries.ts +35 -40
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +423 -182
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/db-singleton.ts +77 -0
- package/src/memory/delivery-channels.ts +82 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/graph/retriever.test.ts +3 -3
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/job-handlers/embedding.test.ts +3 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +66 -22
- package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
- package/src/memory/llm-request-log-source-local.ts +31 -0
- package/src/memory/llm-request-log-source.ts +40 -2
- package/src/memory/llm-request-log-store.ts +228 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-enqueue.ts +8 -1
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/memory-v2-activation-log-store.ts +110 -7
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- package/src/memory/migrations/index.ts +19 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/schema/conversations.ts +10 -2
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/schema/infrastructure.ts +21 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
- package/src/memory/v2/__tests__/injection.test.ts +127 -98
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +171 -3
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +128 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +240 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +112 -0
- package/src/memory/v2/harness/trace.ts +64 -0
- package/src/memory/v2/injection.ts +21 -15
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +171 -18
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +706 -0
- package/src/memory/v3/__tests__/filter.test.ts +560 -0
- package/src/memory/v3/__tests__/gate.test.ts +637 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
- package/src/memory/v3/__tests__/loop.test.ts +775 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +489 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +508 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
- package/src/memory/v3/__tests__/validate.test.ts +277 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +286 -0
- package/src/memory/v3/filter.ts +286 -0
- package/src/memory/v3/gate.ts +349 -0
- package/src/memory/v3/index-composition.ts +126 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +430 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +431 -0
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +347 -0
- package/src/memory/v3/traversal.ts +211 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +356 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +323 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +23 -3
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +40 -50
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +37 -0
- package/src/oauth/byo-connection.test.ts +67 -3
- package/src/oauth/byo-connection.ts +32 -5
- package/src/oauth/connect-orchestrator.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +76 -0
- package/src/oauth/connection-resolver.ts +49 -10
- package/src/oauth/manual-token-connection.ts +51 -3
- package/src/oauth/seed-providers.ts +3 -0
- package/src/permissions/approval-policy.test.ts +19 -5
- package/src/permissions/approval-policy.ts +14 -3
- package/src/permissions/checker.ts +21 -8
- package/src/permissions/prompter.ts +3 -3
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +2 -2
- package/src/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +20 -19
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +68 -29
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +39 -7
- package/src/prompts/system-prompt.ts +84 -221
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +9 -13
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/prompts/templates/system-sections.ts +230 -8
- package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +32 -66
- package/src/providers/call-site-routing.ts +42 -6
- package/src/providers/connection-model-compat.ts +61 -0
- package/src/providers/connection-resolution.ts +47 -14
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +70 -6
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +78 -1
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
- package/src/providers/openai/chat-completions-provider.ts +116 -15
- package/src/providers/openai/codex-models.ts +20 -0
- package/src/providers/openai/responses-provider.ts +87 -30
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +20 -5
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +50 -7
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +9 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +1 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/agent-wake.ts +1 -0
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +46 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-readiness-service.ts +68 -0
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +47 -14
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +12 -4
- package/src/runtime/pending-interactions.ts +0 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/app-management-routes.ts +111 -4
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +356 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +4 -10
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +159 -4
- package/src/runtime/routes/conversation-management-routes.ts +108 -26
- package/src/runtime/routes/conversation-query-routes.ts +200 -44
- package/src/runtime/routes/conversation-routes.ts +409 -521
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/documents-routes.ts +10 -1
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +35 -8
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- package/src/runtime/routes/host-browser-routes.ts +10 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-intro-cache.ts +61 -16
- package/src/runtime/routes/identity-routes.ts +30 -9
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
- package/src/runtime/routes/index.ts +10 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
- package/src/runtime/routes/integrations/vercel.ts +15 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +215 -5
- package/src/runtime/routes/memory-v3-routes.ts +474 -0
- package/src/runtime/routes/migration-routes.ts +32 -28
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +5 -4
- package/src/runtime/routes/surface-action-routes.ts +1 -38
- package/src/runtime/routes/surface-content-routes.ts +12 -5
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/schedule-store.ts +8 -1
- package/src/schedule/scheduler.ts +111 -15
- package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
- package/src/security/encrypted-store.ts +7 -16
- package/src/security/store-path-override.ts +61 -0
- package/src/signals/user-message.ts +5 -8
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +13 -13
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +36 -28
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
- package/src/tools/browser/browser-execution.ts +16 -3
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
- package/src/tools/browser/cdp-client/factory.ts +100 -17
- package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
- package/src/tools/browser/cdp-client/types.ts +65 -0
- package/src/tools/browser/pinned-tabs.ts +96 -40
- package/src/tools/computer-use/definitions.ts +282 -336
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-tool.ts +189 -7
- package/src/tools/execution-target.ts +18 -23
- package/src/tools/executor.ts +24 -56
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -10
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
- package/src/tools/network/__tests__/web-search.test.ts +211 -3
- package/src/tools/network/managed-search-proxy.ts +183 -0
- package/src/tools/network/web-fetch.ts +3 -9
- package/src/tools/network/web-search.ts +224 -76
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +150 -123
- package/src/tools/schedule/create.ts +1 -1
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +18 -44
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +32 -101
- package/src/tools/ui-surface/definitions.ts +104 -108
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/browser.ts +7 -2
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -2
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
- package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/daemon/query-complexity-router.ts +0 -75
- package/src/prompts/cache-boundary.ts +0 -8
|
@@ -26,7 +26,6 @@ import type {
|
|
|
26
26
|
TurnChannelContext,
|
|
27
27
|
TurnInterfaceContext,
|
|
28
28
|
} from "../channels/types.js";
|
|
29
|
-
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
30
29
|
import {
|
|
31
30
|
contextWindowConfigFromEffective,
|
|
32
31
|
type EffectiveContextWindow,
|
|
@@ -60,7 +59,7 @@ import { commitAppTurnChanges } from "../memory/app-git-service.js";
|
|
|
60
59
|
import { getApp, listAppFiles, resolveAppDir } from "../memory/app-store.js";
|
|
61
60
|
import { enqueueAutoAnalysisOnCompaction } from "../memory/auto-analysis-enqueue.js";
|
|
62
61
|
import {
|
|
63
|
-
|
|
62
|
+
deleteMessageById,
|
|
64
63
|
getConversation,
|
|
65
64
|
getConversationOriginChannel,
|
|
66
65
|
getConversationOriginInterface,
|
|
@@ -68,6 +67,7 @@ import {
|
|
|
68
67
|
getLastUserTimestampBefore,
|
|
69
68
|
getMessageById,
|
|
70
69
|
provenanceFromTrustContext,
|
|
70
|
+
setConversationHistoryStrippedAt,
|
|
71
71
|
setLastNotifiedInferenceProfile,
|
|
72
72
|
updateConversationContextWindow,
|
|
73
73
|
updateConversationSlackContextWatermark,
|
|
@@ -80,7 +80,10 @@ import {
|
|
|
80
80
|
} from "../memory/conversation-title-service.js";
|
|
81
81
|
import { isBackgroundConversationType } from "../memory/conversation-types.js";
|
|
82
82
|
import type { ConversationGraphMemory } from "../memory/graph/conversation-graph-memory.js";
|
|
83
|
-
import {
|
|
83
|
+
import {
|
|
84
|
+
backfillMessageIdOnLogs,
|
|
85
|
+
recordSyntheticAgentErrorMessageLog,
|
|
86
|
+
} from "../memory/llm-request-log-store.js";
|
|
84
87
|
import { recordMemoryRecallLog } from "../memory/memory-recall-log-store.js";
|
|
85
88
|
import { enqueueMemoryRetrospectiveOnCompaction } from "../memory/memory-retrospective-enqueue.js";
|
|
86
89
|
import { PKB_WORKSPACE_SCOPE } from "../memory/pkb/types.js";
|
|
@@ -163,13 +166,13 @@ import {
|
|
|
163
166
|
createEventHandlerState,
|
|
164
167
|
dispatchAgentEvent,
|
|
165
168
|
type EventHandlerDeps,
|
|
166
|
-
getClientDisplayMessageId,
|
|
167
169
|
} from "./conversation-agent-loop-handlers.js";
|
|
168
170
|
import {
|
|
169
171
|
approveHostAttachmentRead,
|
|
170
172
|
resolveAssistantAttachments,
|
|
171
173
|
} from "./conversation-attachments.js";
|
|
172
174
|
import {
|
|
175
|
+
budgetYieldUnrecoveredClassification,
|
|
173
176
|
buildConversationErrorMessage,
|
|
174
177
|
classifyConversationError,
|
|
175
178
|
isUserCancellation,
|
|
@@ -217,20 +220,37 @@ import type {
|
|
|
217
220
|
} from "./message-protocol.js";
|
|
218
221
|
import type { MemoryRecalled } from "./message-types/memory.js";
|
|
219
222
|
import type { ConfirmationStateChanged } from "./message-types/messages.js";
|
|
220
|
-
import {
|
|
221
|
-
conversationMetadataSyncTag,
|
|
222
|
-
SYNC_TAGS,
|
|
223
|
-
} from "./message-types/sync.js";
|
|
223
|
+
import { conversationMetadataSyncTag } from "./message-types/sync.js";
|
|
224
224
|
import { parseActualTokensFromError } from "./parse-actual-tokens-from-error.js";
|
|
225
|
-
import {
|
|
226
|
-
classifyQueryComplexity,
|
|
227
|
-
complexityTierToProfileKey,
|
|
228
|
-
} from "./query-complexity-router.js";
|
|
229
225
|
import type { TraceEmitter } from "./trace-emitter.js";
|
|
230
226
|
import type { TrustContext } from "./trust-context.js";
|
|
231
227
|
import { stripHistoricalWebSearchResults } from "./web-search-history.js";
|
|
232
228
|
|
|
233
229
|
const log = getLogger("conversation-agent-loop");
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Best-effort persistence of the history-stripped marker after an
|
|
233
|
+
* injection-strip event (compaction / overflow recovery). The marker is a
|
|
234
|
+
* durability hint, not turn-critical state — a transient SQLite write failure
|
|
235
|
+
* (SQLITE_BUSY, disk-full, read-only FS) must not abort the turn. Logs a
|
|
236
|
+
* warning and continues on failure, preserving the long-standing non-fatal
|
|
237
|
+
* contract for this metadata write.
|
|
238
|
+
*/
|
|
239
|
+
function markHistoryStrippedBestEffort(
|
|
240
|
+
conversationId: string,
|
|
241
|
+
strippedAt: number,
|
|
242
|
+
logger: ReturnType<typeof getLogger>,
|
|
243
|
+
): void {
|
|
244
|
+
try {
|
|
245
|
+
setConversationHistoryStrippedAt(conversationId, strippedAt);
|
|
246
|
+
} catch (err) {
|
|
247
|
+
logger.warn(
|
|
248
|
+
{ err },
|
|
249
|
+
"Failed to persist history-stripped marker after compaction strip (non-fatal)",
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
234
254
|
const DISK_PRESSURE_ERROR_CODE = "DISK_SPACE_CRITICAL" as const;
|
|
235
255
|
const DISK_PRESSURE_ERROR_CATEGORY = "disk_pressure";
|
|
236
256
|
|
|
@@ -518,7 +538,12 @@ export interface AgentLoopConversationContext {
|
|
|
518
538
|
surfaceType: SurfaceType;
|
|
519
539
|
title?: string;
|
|
520
540
|
data: SurfaceData;
|
|
521
|
-
actions?: Array<{
|
|
541
|
+
actions?: Array<{
|
|
542
|
+
id: string;
|
|
543
|
+
label: string;
|
|
544
|
+
style?: string;
|
|
545
|
+
data?: Record<string, unknown>;
|
|
546
|
+
}>;
|
|
522
547
|
display?: string;
|
|
523
548
|
persistent?: boolean;
|
|
524
549
|
}>;
|
|
@@ -539,6 +564,13 @@ export interface AgentLoopConversationContext {
|
|
|
539
564
|
* is inherited by later tool executions and nested subagents.
|
|
540
565
|
*/
|
|
541
566
|
currentTurnOverrideProfile?: string;
|
|
567
|
+
/**
|
|
568
|
+
* Set by the `switch_inference_profile` tool when the model self-selects a
|
|
569
|
+
* different profile mid-turn. Read by `readCurrentOverrideProfile` in the
|
|
570
|
+
* agent loop so the next LLM call uses the switched profile. Reset at
|
|
571
|
+
* turn start.
|
|
572
|
+
*/
|
|
573
|
+
toolRoutedProfile?: string;
|
|
542
574
|
commandIntent?: { type: string; payload?: string; languageCode?: string };
|
|
543
575
|
trustContext?: TrustContext;
|
|
544
576
|
/** Task-run scope for the current turn. Cleared at turn end so queued/drained turns don't inherit it. */
|
|
@@ -681,6 +713,13 @@ export async function runAgentLoopImpl(
|
|
|
681
713
|
let yieldedForHandoff = false;
|
|
682
714
|
let yieldedForBudget = false;
|
|
683
715
|
let pendingCheckpointYield: "budget" | "handoff" | null = null;
|
|
716
|
+
// Captured when the auto_compress_latest_turn rerun yields at the mid-loop
|
|
717
|
+
// budget checkpoint. SSE emission happens immediately at the detection site;
|
|
718
|
+
// assistant-row persistence is deferred until after the pendingToolResults
|
|
719
|
+
// flush so we don't orphan tool_use/tool_result pairs in the durable history.
|
|
720
|
+
let budgetYieldClassification: ReturnType<
|
|
721
|
+
typeof budgetYieldUnrecoveredClassification
|
|
722
|
+
> | null = null;
|
|
684
723
|
let emitTerminalExit:
|
|
685
724
|
| ((reason: AgentLoopExitReason) => Promise<void>)
|
|
686
725
|
| null = null;
|
|
@@ -711,61 +750,32 @@ export async function runAgentLoopImpl(
|
|
|
711
750
|
|
|
712
751
|
const config = getConfig();
|
|
713
752
|
|
|
714
|
-
//
|
|
715
|
-
//
|
|
716
|
-
//
|
|
717
|
-
|
|
718
|
-
if (
|
|
719
|
-
!userExplicitOverride &&
|
|
720
|
-
turnCallSite === "mainAgent" &&
|
|
721
|
-
isAssistantFeatureFlagEnabled("query-complexity-routing", config)
|
|
722
|
-
) {
|
|
723
|
-
const tier = await classifyQueryComplexity(content);
|
|
724
|
-
if (tier && tier !== "balanced") {
|
|
725
|
-
const routedProfile = complexityTierToProfileKey(tier);
|
|
726
|
-
if (config.llm.profiles?.[routedProfile]) {
|
|
727
|
-
turnOverrideProfile = routedProfile;
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
}
|
|
753
|
+
// Tool-based auto-routing: the switch_inference_profile tool lets the model
|
|
754
|
+
// self-select a different profile mid-turn. Reset the per-turn slot so a
|
|
755
|
+
// stale selection from a previous turn doesn't leak forward.
|
|
756
|
+
ctx.toolRoutedProfile = undefined;
|
|
731
757
|
|
|
732
|
-
|
|
733
|
-
if (turnOverrideProfile && turnOverrideProfile !== userExplicitOverride) {
|
|
734
|
-
const profileEntry = config.llm.profiles?.[turnOverrideProfile];
|
|
735
|
-
const label = profileEntry?.label ?? turnOverrideProfile;
|
|
736
|
-
broadcastMessage({
|
|
737
|
-
type: "turn_profile_auto_routed",
|
|
738
|
-
conversationId: ctx.conversationId,
|
|
739
|
-
profile: turnOverrideProfile,
|
|
740
|
-
profileLabel: label,
|
|
741
|
-
});
|
|
742
|
-
}
|
|
758
|
+
const turnOverrideProfile = userExplicitOverride;
|
|
743
759
|
|
|
744
|
-
// Only use the complexity-routed profile as a fallback — not the initial
|
|
745
|
-
// explicit override. If a mid-turn session expiry clears the conversation
|
|
746
|
-
// override, the old behavior (return undefined → revert to workspace
|
|
747
|
-
// defaults) must be preserved for non-routed turns.
|
|
748
|
-
const complexityRoutedProfile =
|
|
749
|
-
turnOverrideProfile !== userExplicitOverride
|
|
750
|
-
? turnOverrideProfile
|
|
751
|
-
: undefined;
|
|
752
760
|
const readCurrentOverrideProfile = (): string | undefined =>
|
|
753
761
|
options?.overrideProfile ??
|
|
754
762
|
getConversationOverrideProfileFromRow(
|
|
755
763
|
getConversation(ctx.conversationId),
|
|
756
764
|
) ??
|
|
757
|
-
|
|
765
|
+
ctx.toolRoutedProfile;
|
|
758
766
|
|
|
759
767
|
const effectiveContextWindow = resolveEffectiveContextWindow({
|
|
760
768
|
llm: config.llm,
|
|
761
769
|
callSite: turnCallSite,
|
|
762
770
|
overrideProfile: turnOverrideProfile ?? undefined,
|
|
771
|
+
selectionSeed: ctx.conversationId,
|
|
763
772
|
});
|
|
764
773
|
let currentEffectiveContextWindow: EffectiveContextWindow =
|
|
765
774
|
effectiveContextWindow;
|
|
766
775
|
let currentContextWindowConfig = contextWindowConfigFromEffective(
|
|
767
776
|
resolveCallSiteConfig(turnCallSite, config.llm, {
|
|
768
777
|
overrideProfile: turnOverrideProfile ?? undefined,
|
|
778
|
+
selectionSeed: ctx.conversationId,
|
|
769
779
|
}).contextWindow,
|
|
770
780
|
currentEffectiveContextWindow,
|
|
771
781
|
);
|
|
@@ -776,6 +786,7 @@ export async function runAgentLoopImpl(
|
|
|
776
786
|
contextWindowManager.updateConfig?.(currentContextWindowConfig);
|
|
777
787
|
|
|
778
788
|
let appliedOverrideProfile = turnOverrideProfile;
|
|
789
|
+
let emittedToolRoutedProfile: string | undefined;
|
|
779
790
|
const refreshCurrentProfileState = (): string | undefined => {
|
|
780
791
|
const currentOverrideProfile = readCurrentOverrideProfile();
|
|
781
792
|
if (currentOverrideProfile !== appliedOverrideProfile) {
|
|
@@ -783,10 +794,12 @@ export async function runAgentLoopImpl(
|
|
|
783
794
|
llm: config.llm,
|
|
784
795
|
callSite: turnCallSite,
|
|
785
796
|
overrideProfile: currentOverrideProfile,
|
|
797
|
+
selectionSeed: ctx.conversationId,
|
|
786
798
|
});
|
|
787
799
|
currentContextWindowConfig = contextWindowConfigFromEffective(
|
|
788
800
|
resolveCallSiteConfig(turnCallSite, config.llm, {
|
|
789
801
|
overrideProfile: currentOverrideProfile,
|
|
802
|
+
selectionSeed: ctx.conversationId,
|
|
790
803
|
}).contextWindow,
|
|
791
804
|
currentEffectiveContextWindow,
|
|
792
805
|
);
|
|
@@ -797,6 +810,24 @@ export async function runAgentLoopImpl(
|
|
|
797
810
|
"Turn inference profile changed mid-loop",
|
|
798
811
|
);
|
|
799
812
|
}
|
|
813
|
+
|
|
814
|
+
// Emit turn_profile_auto_routed when the tool-based router selects a
|
|
815
|
+
// new profile. Deduplicated so the event fires at most once per profile.
|
|
816
|
+
if (
|
|
817
|
+
ctx.toolRoutedProfile &&
|
|
818
|
+
ctx.toolRoutedProfile !== emittedToolRoutedProfile
|
|
819
|
+
) {
|
|
820
|
+
emittedToolRoutedProfile = ctx.toolRoutedProfile;
|
|
821
|
+
const profileEntry = config.llm.profiles?.[ctx.toolRoutedProfile];
|
|
822
|
+
const label = profileEntry?.label ?? ctx.toolRoutedProfile;
|
|
823
|
+
broadcastMessage({
|
|
824
|
+
type: "turn_profile_auto_routed",
|
|
825
|
+
conversationId: ctx.conversationId,
|
|
826
|
+
profile: ctx.toolRoutedProfile,
|
|
827
|
+
profileLabel: label,
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
|
|
800
831
|
ctx.currentTurnOverrideProfile = currentOverrideProfile;
|
|
801
832
|
return currentOverrideProfile;
|
|
802
833
|
};
|
|
@@ -1023,10 +1054,7 @@ export async function runAgentLoopImpl(
|
|
|
1023
1054
|
});
|
|
1024
1055
|
onEvent({
|
|
1025
1056
|
type: "sync_changed",
|
|
1026
|
-
tags: [
|
|
1027
|
-
SYNC_TAGS.conversationsList,
|
|
1028
|
-
conversationMetadataSyncTag(ctx.conversationId),
|
|
1029
|
-
],
|
|
1057
|
+
tags: [conversationMetadataSyncTag(ctx.conversationId)],
|
|
1030
1058
|
});
|
|
1031
1059
|
},
|
|
1032
1060
|
};
|
|
@@ -1645,7 +1673,7 @@ export async function runAgentLoopImpl(
|
|
|
1645
1673
|
// V2 static memory block (essentials/threads/recent/buffer).
|
|
1646
1674
|
// `currentMemoryV2Static` is the trust-gated content reused by every
|
|
1647
1675
|
// re-injection path — it stays non-null on non-full-mode turns so
|
|
1648
|
-
// that mid-turn reducer compaction (which strips the prior `<
|
|
1676
|
+
// that mid-turn reducer compaction (which strips the prior `<info>`
|
|
1649
1677
|
// block) can restore the freshest content. `memoryV2Static` is the
|
|
1650
1678
|
// first-turn / post-compaction cadence-gated value for initial
|
|
1651
1679
|
// injection only. `readMemoryV2StaticContent` self-gates on the v2
|
|
@@ -2307,14 +2335,7 @@ export async function runAgentLoopImpl(
|
|
|
2307
2335
|
// so we compact the "raw" persistent messages.
|
|
2308
2336
|
const rawHistory = stripInjectionsForCompaction(updatedHistory);
|
|
2309
2337
|
ctx.messages = rawHistory;
|
|
2310
|
-
|
|
2311
|
-
clearStrippedInjectionMetadataForConversation(ctx.conversationId);
|
|
2312
|
-
} catch (err) {
|
|
2313
|
-
rlog.warn(
|
|
2314
|
-
{ err },
|
|
2315
|
-
"Failed to clear stripped-injection metadata after compaction strip (non-fatal)",
|
|
2316
|
-
);
|
|
2317
|
-
}
|
|
2338
|
+
markHistoryStrippedBestEffort(ctx.conversationId, Date.now(), rlog);
|
|
2318
2339
|
|
|
2319
2340
|
ctx.emitActivityState(
|
|
2320
2341
|
"thinking",
|
|
@@ -2598,14 +2619,7 @@ export async function runAgentLoopImpl(
|
|
|
2598
2619
|
|
|
2599
2620
|
if (updatedHistory.length > preRunHistoryLength) {
|
|
2600
2621
|
ctx.messages = stripInjectionsForCompaction(updatedHistory);
|
|
2601
|
-
|
|
2602
|
-
clearStrippedInjectionMetadataForConversation(ctx.conversationId);
|
|
2603
|
-
} catch (err) {
|
|
2604
|
-
rlog.warn(
|
|
2605
|
-
{ err },
|
|
2606
|
-
"Failed to clear stripped-injection metadata after compaction strip (non-fatal)",
|
|
2607
|
-
);
|
|
2608
|
-
}
|
|
2622
|
+
markHistoryStrippedBestEffort(ctx.conversationId, Date.now(), rlog);
|
|
2609
2623
|
convergenceStripped = true;
|
|
2610
2624
|
preRepairMessages = updatedHistory;
|
|
2611
2625
|
preRunHistoryLength = updatedHistory.length;
|
|
@@ -2850,14 +2864,7 @@ export async function runAgentLoopImpl(
|
|
|
2850
2864
|
// pre-rerun messages.
|
|
2851
2865
|
if (updatedHistory.length > preRunHistoryLength) {
|
|
2852
2866
|
ctx.messages = stripInjectionsForCompaction(updatedHistory);
|
|
2853
|
-
|
|
2854
|
-
clearStrippedInjectionMetadataForConversation(ctx.conversationId);
|
|
2855
|
-
} catch (err) {
|
|
2856
|
-
rlog.warn(
|
|
2857
|
-
{ err },
|
|
2858
|
-
"Failed to clear stripped-injection metadata after compaction strip (non-fatal)",
|
|
2859
|
-
);
|
|
2860
|
-
}
|
|
2867
|
+
markHistoryStrippedBestEffort(ctx.conversationId, Date.now(), rlog);
|
|
2861
2868
|
convergenceStripped = true;
|
|
2862
2869
|
preRepairMessages = updatedHistory;
|
|
2863
2870
|
preRunHistoryLength = updatedHistory.length;
|
|
@@ -3006,6 +3013,32 @@ export async function runAgentLoopImpl(
|
|
|
3006
3013
|
await emitTerminalExit?.("context_too_large");
|
|
3007
3014
|
pendingCheckpointYield = null;
|
|
3008
3015
|
onEvent(buildConversationErrorMessage(ctx.conversationId, classified));
|
|
3016
|
+
} else if (yieldedForBudget && !abortController.signal.aborted) {
|
|
3017
|
+
// The auto_compress_latest_turn rerun (action === "auto_compress_latest_turn"
|
|
3018
|
+
// above) reset `contextTooLargeDetected` to false before its final
|
|
3019
|
+
// `agentLoop.run`, so the context-too-large branch above won't fire
|
|
3020
|
+
// even when that rerun yields at the mid-loop budget checkpoint with
|
|
3021
|
+
// no further recovery layer to re-enter. Without surfacing this here,
|
|
3022
|
+
// the turn terminates silently — the inspector sees `agent_loop_exit_reason
|
|
3023
|
+
// = NULL` and the user sees no message at all (just a "ghost" turn).
|
|
3024
|
+
//
|
|
3025
|
+
// Unlike provider-error persistence at L3091 — which only fires when
|
|
3026
|
+
// the loop produced NO assistant output — budget_yield_unrecovered
|
|
3027
|
+
// typically yields AFTER one or more successful tool-use iterations,
|
|
3028
|
+
// so `hasAssistantResponse` is true and that path would skip us. We
|
|
3029
|
+
// capture the classification here so the live SSE event fires
|
|
3030
|
+
// immediately, and persist a dedicated notice row below — after the
|
|
3031
|
+
// pendingToolResults flush — so the transcript reads as: tool-use →
|
|
3032
|
+
// tool results → "I couldn't fit the next step…" notice. Persisting
|
|
3033
|
+
// earlier would orphan an assistant(tool_use) from its user(tool_result),
|
|
3034
|
+
// breaking provider adjacency on replay.
|
|
3035
|
+
budgetYieldClassification = budgetYieldUnrecoveredClassification();
|
|
3036
|
+
onEvent(
|
|
3037
|
+
buildConversationErrorMessage(
|
|
3038
|
+
ctx.conversationId,
|
|
3039
|
+
budgetYieldClassification,
|
|
3040
|
+
),
|
|
3041
|
+
);
|
|
3009
3042
|
}
|
|
3010
3043
|
}
|
|
3011
3044
|
|
|
@@ -3081,6 +3114,99 @@ export async function runAgentLoopImpl(
|
|
|
3081
3114
|
state.pendingToolResults.clear();
|
|
3082
3115
|
}
|
|
3083
3116
|
|
|
3117
|
+
// Persist the budget_yield_unrecovered notice now that any pending
|
|
3118
|
+
// tool_results have flushed. The SSE event already fired upstream; this
|
|
3119
|
+
// makes the row durable in the right position: tool-use → tool-results →
|
|
3120
|
+
// notice. Doing it earlier (e.g. at the detection site) would land the
|
|
3121
|
+
// assistant row between a tool_use and its tool_result and break provider
|
|
3122
|
+
// adjacency on replay.
|
|
3123
|
+
if (budgetYieldClassification && !abortController.signal.aborted) {
|
|
3124
|
+
const yieldNoticeMessage = createAssistantMessage(
|
|
3125
|
+
budgetYieldClassification.userMessage,
|
|
3126
|
+
);
|
|
3127
|
+
const yieldNoticeMetadata = {
|
|
3128
|
+
...provenanceFromTrustContext(ctx.trustContext),
|
|
3129
|
+
userMessageChannel: capturedTurnChannelContext.userMessageChannel,
|
|
3130
|
+
assistantMessageChannel:
|
|
3131
|
+
capturedTurnChannelContext.assistantMessageChannel,
|
|
3132
|
+
userMessageInterface: capturedTurnInterfaceContext.userMessageInterface,
|
|
3133
|
+
assistantMessageInterface:
|
|
3134
|
+
capturedTurnInterfaceContext.assistantMessageInterface,
|
|
3135
|
+
};
|
|
3136
|
+
let yieldNoticePersistedId: string | null = null;
|
|
3137
|
+
try {
|
|
3138
|
+
const yieldPersistResult = (await runPipeline<
|
|
3139
|
+
PersistArgs,
|
|
3140
|
+
PersistResult
|
|
3141
|
+
>(
|
|
3142
|
+
"persistence",
|
|
3143
|
+
getMiddlewaresFor("persistence"),
|
|
3144
|
+
defaultPersistenceTerminal,
|
|
3145
|
+
{
|
|
3146
|
+
op: "add",
|
|
3147
|
+
conversationId: ctx.conversationId,
|
|
3148
|
+
role: "assistant",
|
|
3149
|
+
content: JSON.stringify(yieldNoticeMessage.content),
|
|
3150
|
+
metadata: yieldNoticeMetadata,
|
|
3151
|
+
},
|
|
3152
|
+
buildPluginTurnContext(ctx, reqId),
|
|
3153
|
+
DEFAULT_TIMEOUTS.persistence,
|
|
3154
|
+
)) as PersistAddResult;
|
|
3155
|
+
yieldNoticePersistedId = yieldPersistResult.message.id;
|
|
3156
|
+
} catch (err) {
|
|
3157
|
+
// Non-fatal — a DB hiccup must not escalate a budget-yield exit into
|
|
3158
|
+
// a turn-level throw. The live SSE event was already emitted, so the
|
|
3159
|
+
// user still sees the notice this turn even if the durable row missed.
|
|
3160
|
+
rlog.warn(
|
|
3161
|
+
{ err },
|
|
3162
|
+
"Failed to persist budget_yield_unrecovered notice (non-fatal)",
|
|
3163
|
+
);
|
|
3164
|
+
}
|
|
3165
|
+
// Record a synthetic `llm_request_logs` row for the yield so the
|
|
3166
|
+
// inspector's call rail surfaces a clickable, distinctly-rendered
|
|
3167
|
+
// entry for the failure itself. Without this row, the loop yields
|
|
3168
|
+
// silently — the user sees the notice in chat but the inspector
|
|
3169
|
+
// call list ends at the last actual LLM call with no way to scope
|
|
3170
|
+
// the "what compactions led to this failure?" question to the
|
|
3171
|
+
// yield event.
|
|
3172
|
+
//
|
|
3173
|
+
// Recorded *before* emitTerminalExit so the synthetic row exists
|
|
3174
|
+
// by the time the dispatcher's post-loop hook runs. The row
|
|
3175
|
+
// already carries `agent_loop_exit_reason` at insert time, so
|
|
3176
|
+
// `setAgentLoopExitReasonOnLatestLog`'s IS NULL guard skips it
|
|
3177
|
+
// and stamps the prior real mainAgent call instead — preserving
|
|
3178
|
+
// the existing "latest LLM call carries the exit reason"
|
|
3179
|
+
// invariant other consumers depend on.
|
|
3180
|
+
//
|
|
3181
|
+
// `preparedRequest` snapshots the best-known LLM request state
|
|
3182
|
+
// at yield time — `updatedHistory` (the conversation state the
|
|
3183
|
+
// next call would have been built from) plus the input-token
|
|
3184
|
+
// budget that just failed. Mirrors the role of `request_payload`
|
|
3185
|
+
// on real LLM-call rows; the notice text lives on
|
|
3186
|
+
// `response_payload`.
|
|
3187
|
+
if (yieldNoticePersistedId !== null && budgetYieldClassification) {
|
|
3188
|
+
try {
|
|
3189
|
+
recordSyntheticAgentErrorMessageLog({
|
|
3190
|
+
conversationId: ctx.conversationId,
|
|
3191
|
+
messageId: yieldNoticePersistedId,
|
|
3192
|
+
exitReason: "budget_yield_unrecovered",
|
|
3193
|
+
noticeText: budgetYieldClassification.userMessage,
|
|
3194
|
+
preparedRequest: {
|
|
3195
|
+
messages: updatedHistory,
|
|
3196
|
+
maxInputTokensBudget: resolveCurrentMaxInputTokens() ?? null,
|
|
3197
|
+
},
|
|
3198
|
+
createdAt: Date.now(),
|
|
3199
|
+
});
|
|
3200
|
+
} catch (err) {
|
|
3201
|
+
rlog.warn(
|
|
3202
|
+
{ err },
|
|
3203
|
+
"Failed to record budget_yield_unrecovered synthetic call log (non-fatal)",
|
|
3204
|
+
);
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
await emitTerminalExit?.("budget_yield_unrecovered");
|
|
3208
|
+
}
|
|
3209
|
+
|
|
3084
3210
|
// Reconstruct history
|
|
3085
3211
|
const newMessages = updatedHistory.slice(preRunHistoryLength).map((msg) => {
|
|
3086
3212
|
if (msg.role !== "assistant") return msg;
|
|
@@ -3098,6 +3224,34 @@ export async function runAgentLoopImpl(
|
|
|
3098
3224
|
!abortController.signal.aborted &&
|
|
3099
3225
|
!yieldedForHandoff
|
|
3100
3226
|
) {
|
|
3227
|
+
// Drop any reservation stranded by the failed LLM call before
|
|
3228
|
+
// inserting the synthetic error message. The B3 pre-allocation
|
|
3229
|
+
// path reserves an empty assistant row at `llm_call_started`;
|
|
3230
|
+
// when the call exits through the provider-error branch (no
|
|
3231
|
+
// `message_complete`), `assistantRowAwaitingFinalization` stays
|
|
3232
|
+
// true. Without this delete the transcript would carry both the
|
|
3233
|
+
// empty reserved row AND the error message — and downstream sync
|
|
3234
|
+
// (`syncLastAssistantMessageToDisk`) would mis-target the empty
|
|
3235
|
+
// row. After delete we set `lastAssistantMessageId` to the new
|
|
3236
|
+
// error row's id so the post-loop emission paths still point at
|
|
3237
|
+
// a real message.
|
|
3238
|
+
if (
|
|
3239
|
+
state.assistantRowAwaitingFinalization &&
|
|
3240
|
+
state.lastAssistantMessageId
|
|
3241
|
+
) {
|
|
3242
|
+
// Direct `deleteMessageById` (not via the `persistence` pipeline):
|
|
3243
|
+
// see the same rationale on the matching cleanup in
|
|
3244
|
+
// `handleLlmCallStarted` — an unfinalized reservation has no
|
|
3245
|
+
// observable history for plugins.
|
|
3246
|
+
try {
|
|
3247
|
+
deleteMessageById(state.lastAssistantMessageId);
|
|
3248
|
+
} catch (err) {
|
|
3249
|
+
rlog.warn(
|
|
3250
|
+
{ err, messageId: state.lastAssistantMessageId },
|
|
3251
|
+
"Failed to clean up stranded reserved assistant row on provider-error path (non-fatal)",
|
|
3252
|
+
);
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3101
3255
|
const errChannelMeta = {
|
|
3102
3256
|
...provenanceFromTrustContext(ctx.trustContext),
|
|
3103
3257
|
userMessageChannel: capturedTurnChannelContext.userMessageChannel,
|
|
@@ -3125,6 +3279,15 @@ export async function runAgentLoopImpl(
|
|
|
3125
3279
|
DEFAULT_TIMEOUTS.persistence,
|
|
3126
3280
|
)) as PersistAddResult;
|
|
3127
3281
|
persistedErrorAssistantMessage = true;
|
|
3282
|
+
// Repoint `lastAssistantMessageId` at the synthetic error row so the
|
|
3283
|
+
// post-loop sync, attachment resolution, and `message_complete`/
|
|
3284
|
+
// `generation_handoff` emissions all reference a real, persisted
|
|
3285
|
+
// message id. The previous reservation (if any) was already deleted
|
|
3286
|
+
// above. Mark finalization complete so the next LLM call in this run
|
|
3287
|
+
// (or a downstream handler) doesn't try to clean up an id that
|
|
3288
|
+
// already corresponds to a finalized row.
|
|
3289
|
+
state.lastAssistantMessageId = errorPersistResult.message.id;
|
|
3290
|
+
state.assistantRowAwaitingFinalization = false;
|
|
3128
3291
|
newMessages.push(errorAssistantMessage);
|
|
3129
3292
|
// Pipe the just-assigned message id into any orphaned LLM request log
|
|
3130
3293
|
// row(s) for this turn. The success path links rows via
|
|
@@ -3263,7 +3426,6 @@ export async function runAgentLoopImpl(
|
|
|
3263
3426
|
ctx.lastAssistantAttachments = assistantAttachments;
|
|
3264
3427
|
ctx.lastAttachmentWarnings = attachmentResult.directiveWarnings;
|
|
3265
3428
|
syncLastAssistantMessageToDisk();
|
|
3266
|
-
const clientDisplayMessageId = getClientDisplayMessageId(state);
|
|
3267
3429
|
|
|
3268
3430
|
// Re-check: the user may have cancelled during attachment resolution
|
|
3269
3431
|
if (abortController.signal.aborted) {
|
|
@@ -3309,9 +3471,6 @@ export async function runAgentLoopImpl(
|
|
|
3309
3471
|
...(state.lastAssistantMessageId
|
|
3310
3472
|
? { messageId: state.lastAssistantMessageId }
|
|
3311
3473
|
: {}),
|
|
3312
|
-
...(clientDisplayMessageId
|
|
3313
|
-
? { displayMessageId: clientDisplayMessageId }
|
|
3314
|
-
: {}),
|
|
3315
3474
|
});
|
|
3316
3475
|
publishLoopMessagesChanged();
|
|
3317
3476
|
} else {
|
|
@@ -3336,9 +3495,6 @@ export async function runAgentLoopImpl(
|
|
|
3336
3495
|
...(state.lastAssistantMessageId
|
|
3337
3496
|
? { messageId: state.lastAssistantMessageId }
|
|
3338
3497
|
: {}),
|
|
3339
|
-
...(clientDisplayMessageId
|
|
3340
|
-
? { displayMessageId: clientDisplayMessageId }
|
|
3341
|
-
: {}),
|
|
3342
3498
|
});
|
|
3343
3499
|
publishLoopMessagesChanged();
|
|
3344
3500
|
|
|
@@ -3397,10 +3553,7 @@ export async function runAgentLoopImpl(
|
|
|
3397
3553
|
});
|
|
3398
3554
|
onEvent({
|
|
3399
3555
|
type: "sync_changed",
|
|
3400
|
-
tags: [
|
|
3401
|
-
SYNC_TAGS.conversationsList,
|
|
3402
|
-
conversationMetadataSyncTag(ctx.conversationId),
|
|
3403
|
-
],
|
|
3556
|
+
tags: [conversationMetadataSyncTag(ctx.conversationId)],
|
|
3404
3557
|
});
|
|
3405
3558
|
},
|
|
3406
3559
|
signal: abortController.signal,
|
|
@@ -3645,6 +3798,7 @@ export async function applyCompactionResult(
|
|
|
3645
3798
|
result.summaryText,
|
|
3646
3799
|
ctx.contextCompactedMessageCount,
|
|
3647
3800
|
);
|
|
3801
|
+
markHistoryStrippedBestEffort(ctx.conversationId, compactedAt, log);
|
|
3648
3802
|
if (options.slackContextCompactionWatermarkTs) {
|
|
3649
3803
|
updateConversationSlackContextWatermark(
|
|
3650
3804
|
ctx.conversationId,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ConnectionResolutionError } from "../providers/connection-resolution.js";
|
|
1
2
|
import { getProviderRoutingSource } from "../providers/registry.js";
|
|
2
3
|
import { isAbortReason } from "../util/abort-reasons.js";
|
|
3
4
|
import { ProviderError, ProviderNotConfiguredError } from "../util/errors.js";
|
|
@@ -251,14 +252,28 @@ export function classifyConversationError(
|
|
|
251
252
|
if (error instanceof ProviderNotConfiguredError) {
|
|
252
253
|
return {
|
|
253
254
|
...providerNotConfiguredClassification({
|
|
254
|
-
connectionName:
|
|
255
|
-
error.connectionName ?? attribution.connectionName,
|
|
255
|
+
connectionName: error.connectionName ?? attribution.connectionName,
|
|
256
256
|
profileName: error.profileName ?? attribution.profileName,
|
|
257
257
|
}),
|
|
258
258
|
debugDetails,
|
|
259
259
|
};
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
if (error instanceof ConnectionResolutionError) {
|
|
263
|
+
return {
|
|
264
|
+
code: "PROVIDER_NOT_CONFIGURED",
|
|
265
|
+
userMessage:
|
|
266
|
+
"No compatible provider connection found for this profile. Check your provider connections in Settings.",
|
|
267
|
+
retryable: true,
|
|
268
|
+
debugDetails,
|
|
269
|
+
errorCategory: "provider_not_configured",
|
|
270
|
+
...(error.connectionName ? { connectionName: error.connectionName } : {}),
|
|
271
|
+
...(attribution.profileName
|
|
272
|
+
? { profileName: attribution.profileName }
|
|
273
|
+
: {}),
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
262
277
|
// Phase-specific overrides
|
|
263
278
|
if (ctx.phase === "regenerate") {
|
|
264
279
|
const base = classifyCore(error, message, attribution);
|
|
@@ -437,9 +452,15 @@ function classifyCore(
|
|
|
437
452
|
errorCategory: "image_dimensions_too_large",
|
|
438
453
|
};
|
|
439
454
|
}
|
|
455
|
+
// Extract the provider detail after "API error (NNN): " prefix
|
|
456
|
+
const detailMatch = message.match(/API error \(\d+\):\s*(.+)/i);
|
|
457
|
+
const detail = detailMatch?.[1];
|
|
458
|
+
const suffix = detail
|
|
459
|
+
? `: ${detail.length > 200 ? detail.slice(0, 200) + "…" : detail}`
|
|
460
|
+
: "";
|
|
440
461
|
return {
|
|
441
462
|
code: "PROVIDER_API",
|
|
442
|
-
userMessage:
|
|
463
|
+
userMessage: `The AI provider rejected the request (HTTP ${error.statusCode})${suffix}`,
|
|
443
464
|
retryable: true,
|
|
444
465
|
errorCategory: "provider_api_error",
|
|
445
466
|
};
|
|
@@ -760,6 +781,45 @@ function classifyByMessage(
|
|
|
760
781
|
};
|
|
761
782
|
}
|
|
762
783
|
|
|
784
|
+
/**
|
|
785
|
+
* Classify a `budget_yield_unrecovered` terminal exit.
|
|
786
|
+
*
|
|
787
|
+
* Emitted when the agent loop's `auto_compress_latest_turn` rerun
|
|
788
|
+
* (the last layer of the overflow-recovery ladder) still yields at
|
|
789
|
+
* the mid-loop preflight budget checkpoint. The turn cannot proceed,
|
|
790
|
+
* but it is not a provider rejection — every compaction the loop ran
|
|
791
|
+
* has already been applied to the conversation, so the user's next
|
|
792
|
+
* message starts from the compacted history and typically succeeds.
|
|
793
|
+
*
|
|
794
|
+
* The returned `userMessage` is persisted as a `role="assistant"` row
|
|
795
|
+
* by the same path that already persists `PROVIDER_BILLING` etc., so
|
|
796
|
+
* the notice is durable across reload (not just a transient banner).
|
|
797
|
+
*/
|
|
798
|
+
export function budgetYieldUnrecoveredClassification(): ClassifiedConversationError {
|
|
799
|
+
return {
|
|
800
|
+
code: "BUDGET_YIELD_UNRECOVERED",
|
|
801
|
+
userMessage:
|
|
802
|
+
"I tried to compact this conversation but couldn't fit the next step into the model's context window. Send another message to continue — the compaction I did run has been saved, so your next turn starts from a smaller history.",
|
|
803
|
+
retryable: true,
|
|
804
|
+
errorCategory: "budget_yield_unrecovered",
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Classify a model response that stopped because the output-token limit was
|
|
810
|
+
* reached. The turn may have produced useful partial text, so the recovery is
|
|
811
|
+
* a follow-up user turn rather than a retry of the same request.
|
|
812
|
+
*/
|
|
813
|
+
export function maxTokensReachedClassification(): ClassifiedConversationError {
|
|
814
|
+
return {
|
|
815
|
+
code: "MAX_TOKENS_REACHED",
|
|
816
|
+
userMessage:
|
|
817
|
+
"I hit the response limit before I could finish. Continue and I'll pick up from where I stopped.",
|
|
818
|
+
retryable: true,
|
|
819
|
+
errorCategory: "max_tokens_reached",
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
|
|
763
823
|
/**
|
|
764
824
|
* Build a `conversation_error` server message from a classified error.
|
|
765
825
|
*/
|
|
@@ -781,8 +841,6 @@ export function buildConversationErrorMessage(
|
|
|
781
841
|
...(classified.connectionName
|
|
782
842
|
? { connectionName: classified.connectionName }
|
|
783
843
|
: {}),
|
|
784
|
-
...(classified.profileName
|
|
785
|
-
? { profileName: classified.profileName }
|
|
786
|
-
: {}),
|
|
844
|
+
...(classified.profileName ? { profileName: classified.profileName } : {}),
|
|
787
845
|
};
|
|
788
846
|
}
|