@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
|
@@ -425,7 +425,7 @@ describe("RetryProvider — callSite resolution", () => {
|
|
|
425
425
|
expect(config.temperature).toBe(0.5);
|
|
426
426
|
});
|
|
427
427
|
|
|
428
|
-
test("strips effort/speed
|
|
428
|
+
test("strips effort/speed for providers that don't support them (e.g. fireworks)", async () => {
|
|
429
429
|
setLlmConfig({
|
|
430
430
|
default: {
|
|
431
431
|
provider: "anthropic",
|
|
@@ -434,14 +434,14 @@ describe("RetryProvider — callSite resolution", () => {
|
|
|
434
434
|
speed: "fast",
|
|
435
435
|
},
|
|
436
436
|
callSites: {
|
|
437
|
-
memoryRetrieval: { thinking: { enabled:
|
|
437
|
+
memoryRetrieval: { thinking: { enabled: false } },
|
|
438
438
|
},
|
|
439
439
|
});
|
|
440
440
|
|
|
441
441
|
let seen: SendMessageOptions | undefined;
|
|
442
|
-
//
|
|
442
|
+
// fireworks does not support speed or thinking — they must be stripped.
|
|
443
443
|
const wrapped = new RetryProvider(
|
|
444
|
-
makeProvider("
|
|
444
|
+
makeProvider("fireworks", (options) => {
|
|
445
445
|
seen = options;
|
|
446
446
|
}),
|
|
447
447
|
);
|
|
@@ -451,13 +451,93 @@ describe("RetryProvider — callSite resolution", () => {
|
|
|
451
451
|
});
|
|
452
452
|
|
|
453
453
|
const config = seen?.config as Record<string, unknown>;
|
|
454
|
-
expect(config.effort).toBeUndefined();
|
|
455
454
|
expect(config.speed).toBeUndefined();
|
|
456
455
|
expect(config.thinking).toBeUndefined();
|
|
457
456
|
// Model still comes through.
|
|
458
457
|
expect(config.model).toBe("claude-opus-4-7");
|
|
459
458
|
});
|
|
460
459
|
|
|
460
|
+
test("preserves thinking + level for Gemini provider", async () => {
|
|
461
|
+
setLlmConfig({
|
|
462
|
+
default: {
|
|
463
|
+
provider: "gemini",
|
|
464
|
+
model: "gemini-3.5-flash",
|
|
465
|
+
thinking: { enabled: true, streamThinking: true, level: "high" },
|
|
466
|
+
},
|
|
467
|
+
callSites: { mainAgent: {} },
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
let seen: SendMessageOptions | undefined;
|
|
471
|
+
const wrapped = new RetryProvider(
|
|
472
|
+
makeProvider("gemini", (options) => {
|
|
473
|
+
seen = options;
|
|
474
|
+
}),
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
await wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
|
|
478
|
+
config: { callSite: "mainAgent" },
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
const config = seen?.config as Record<string, unknown>;
|
|
482
|
+
expect(config.thinking).toEqual({
|
|
483
|
+
type: "adaptive",
|
|
484
|
+
level: "high",
|
|
485
|
+
streamThinking: true,
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
test("Gemini disabled thinking carries the wire `disabled` discriminator", async () => {
|
|
490
|
+
setLlmConfig({
|
|
491
|
+
default: {
|
|
492
|
+
provider: "gemini",
|
|
493
|
+
model: "gemini-3.5-flash",
|
|
494
|
+
thinking: { enabled: false, streamThinking: false },
|
|
495
|
+
},
|
|
496
|
+
callSites: { mainAgent: {} },
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
let seen: SendMessageOptions | undefined;
|
|
500
|
+
const wrapped = new RetryProvider(
|
|
501
|
+
makeProvider("gemini", (options) => {
|
|
502
|
+
seen = options;
|
|
503
|
+
}),
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
await wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
|
|
507
|
+
config: { callSite: "mainAgent" },
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
const config = seen?.config as Record<string, unknown>;
|
|
511
|
+
expect(config.thinking).toEqual({ type: "disabled" });
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
test("scrubs Gemini-only thinking extras (level, streamThinking) for Anthropic", async () => {
|
|
515
|
+
setLlmConfig({
|
|
516
|
+
default: {
|
|
517
|
+
provider: "anthropic",
|
|
518
|
+
model: "claude-opus-4-7",
|
|
519
|
+
thinking: { enabled: true, streamThinking: true, level: "high" },
|
|
520
|
+
},
|
|
521
|
+
callSites: { mainAgent: {} },
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
let seen: SendMessageOptions | undefined;
|
|
525
|
+
const wrapped = new RetryProvider(
|
|
526
|
+
makeProvider("anthropic", (options) => {
|
|
527
|
+
seen = options;
|
|
528
|
+
}),
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
await wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
|
|
532
|
+
config: { callSite: "mainAgent" },
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
const config = seen?.config as Record<string, unknown>;
|
|
536
|
+
// Anthropic's SDK rejects unknown keys inside the `thinking` object with
|
|
537
|
+
// "Extra inputs are not permitted" — must be exactly `{ type }`.
|
|
538
|
+
expect(config.thinking).toEqual({ type: "adaptive" });
|
|
539
|
+
});
|
|
540
|
+
|
|
461
541
|
test("explicit per-call config.model wins over resolved callSite model", async () => {
|
|
462
542
|
setLlmConfig({
|
|
463
543
|
default: { provider: "anthropic", model: "resolved-model" },
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import Anthropic from "@anthropic-ai/sdk";
|
|
2
2
|
|
|
3
|
-
import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "../../prompts/system-prompt.js";
|
|
4
3
|
import { isAbortReason } from "../../util/abort-reasons.js";
|
|
5
4
|
import { ProviderError } from "../../util/errors.js";
|
|
6
5
|
import { getLogger } from "../../util/logger.js";
|
|
@@ -819,6 +818,15 @@ export class AnthropicProvider implements Provider {
|
|
|
819
818
|
((config as Record<string, unknown> | undefined)?.cacheTtl as
|
|
820
819
|
| "5m"
|
|
821
820
|
| "1h") ?? "1h";
|
|
821
|
+
// Opt-out for callers (e.g. the memory router) that send a single
|
|
822
|
+
// user message per call with content that changes every time. The
|
|
823
|
+
// turn-start cache breakpoint below is only useful when the same
|
|
824
|
+
// prefix is re-sent on a subsequent call (typical for the main agent
|
|
825
|
+
// loop's tool-use iterations); one-shot callers pay cache_creation
|
|
826
|
+
// cost without a future hit.
|
|
827
|
+
const disableTurnStartCache =
|
|
828
|
+
(config as Record<string, unknown> | undefined)?.disableTurnStartCache ===
|
|
829
|
+
true;
|
|
822
830
|
let sentMessages: Anthropic.MessageParam[] | undefined;
|
|
823
831
|
const startedAt = Date.now();
|
|
824
832
|
// Hoisted so the catch block can distinguish our inner stream timeout
|
|
@@ -980,14 +988,11 @@ export class AnthropicProvider implements Provider {
|
|
|
980
988
|
// followed by user tool_result). Replaying stale thinking blocks from
|
|
981
989
|
// earlier turns causes 400 errors when the signature is no longer
|
|
982
990
|
// valid (e.g. after a provider/model/profile switch).
|
|
983
|
-
const activeToolUseStart =
|
|
984
|
-
findActiveToolUseContinuationStart(formatted);
|
|
991
|
+
const activeToolUseStart = findActiveToolUseContinuationStart(formatted);
|
|
985
992
|
for (let i = 0; i < activeToolUseStart; i++) {
|
|
986
993
|
const msg = formatted[i];
|
|
987
994
|
if (msg.role !== "assistant" || !Array.isArray(msg.content)) continue;
|
|
988
|
-
const stripped = (
|
|
989
|
-
msg.content as Anthropic.ContentBlockParam[]
|
|
990
|
-
).filter(
|
|
995
|
+
const stripped = (msg.content as Anthropic.ContentBlockParam[]).filter(
|
|
991
996
|
(b) =>
|
|
992
997
|
typeof b === "string" ||
|
|
993
998
|
(b.type !== "thinking" && b.type !== "redacted_thinking"),
|
|
@@ -1009,6 +1014,7 @@ export class AnthropicProvider implements Provider {
|
|
|
1009
1014
|
speed,
|
|
1010
1015
|
output_config,
|
|
1011
1016
|
cacheTtl: _cacheTtl,
|
|
1017
|
+
disableTurnStartCache: _disableTurnStartCache,
|
|
1012
1018
|
max_tokens: callerMaxTokens,
|
|
1013
1019
|
usageAttributionHeaders,
|
|
1014
1020
|
...restConfig
|
|
@@ -1065,38 +1071,17 @@ export class AnthropicProvider implements Provider {
|
|
|
1065
1071
|
};
|
|
1066
1072
|
|
|
1067
1073
|
if (systemPrompt) {
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
boundaryIdx + SYSTEM_PROMPT_CACHE_BOUNDARY.length,
|
|
1080
|
-
);
|
|
1081
|
-
const systemBlocks = [staticBlock, dynamicBlock]
|
|
1082
|
-
.filter((text) => text.length > 0)
|
|
1083
|
-
.map((text) => ({
|
|
1084
|
-
type: "text" as const,
|
|
1085
|
-
text,
|
|
1086
|
-
cache_control: cacheControl,
|
|
1087
|
-
}));
|
|
1088
|
-
if (systemBlocks.length > 0) {
|
|
1089
|
-
params.system = systemBlocks;
|
|
1090
|
-
}
|
|
1091
|
-
} else {
|
|
1092
|
-
params.system = [
|
|
1093
|
-
{
|
|
1094
|
-
type: "text" as const,
|
|
1095
|
-
text: systemPrompt,
|
|
1096
|
-
cache_control: cacheControl,
|
|
1097
|
-
},
|
|
1098
|
-
];
|
|
1099
|
-
}
|
|
1074
|
+
// The whole system prompt is rendered as a single cached
|
|
1075
|
+
// block. A 1-hour cache TTL is used (when supported by the
|
|
1076
|
+
// model) so the breakpoint survives turn gaps that exceed the
|
|
1077
|
+
// default 5-minute window.
|
|
1078
|
+
params.system = [
|
|
1079
|
+
{
|
|
1080
|
+
type: "text" as const,
|
|
1081
|
+
text: systemPrompt,
|
|
1082
|
+
cache_control: cacheControl,
|
|
1083
|
+
},
|
|
1084
|
+
];
|
|
1100
1085
|
}
|
|
1101
1086
|
|
|
1102
1087
|
if (tools && tools.length > 0) {
|
|
@@ -1160,7 +1145,9 @@ export class AnthropicProvider implements Provider {
|
|
|
1160
1145
|
}
|
|
1161
1146
|
};
|
|
1162
1147
|
const turnStartIdx = findUserTextMsgIdx(msgs.length - 1);
|
|
1163
|
-
if (turnStartIdx >= 0)
|
|
1148
|
+
if (turnStartIdx >= 0 && !disableTurnStartCache) {
|
|
1149
|
+
applyCacheControlToLastBlock(turnStartIdx);
|
|
1150
|
+
}
|
|
1164
1151
|
|
|
1165
1152
|
// Previous-turn anchor: when this request is the first of a new turn
|
|
1166
1153
|
// (turn-start is the very last message — no tool-use loop yet), also
|
|
@@ -1172,9 +1159,8 @@ export class AnthropicProvider implements Provider {
|
|
|
1172
1159
|
// cache_creation tokens per new turn). Skipped during tool-use loops
|
|
1173
1160
|
// where the current turn-start already covers the same prefix and a
|
|
1174
1161
|
// second anchor would blow the 4-breakpoint budget.
|
|
1175
|
-
let prevTurnAnchorIdx = -1;
|
|
1176
1162
|
if (turnStartIdx === msgs.length - 1 && turnStartIdx > 0) {
|
|
1177
|
-
prevTurnAnchorIdx = findUserTextMsgIdx(turnStartIdx - 1);
|
|
1163
|
+
const prevTurnAnchorIdx = findUserTextMsgIdx(turnStartIdx - 1);
|
|
1178
1164
|
if (prevTurnAnchorIdx >= 0)
|
|
1179
1165
|
applyCacheControlToLastBlock(prevTurnAnchorIdx);
|
|
1180
1166
|
}
|
|
@@ -1185,7 +1171,6 @@ export class AnthropicProvider implements Provider {
|
|
|
1185
1171
|
// cheaply without conflicting with the 1h breakpoints above.
|
|
1186
1172
|
// Skip thinking/redacted_thinking blocks — Anthropic doesn't allow
|
|
1187
1173
|
// cache_control on those types.
|
|
1188
|
-
let tailBreakpointApplied = false;
|
|
1189
1174
|
if (turnStartIdx >= 0 && turnStartIdx < sentMessages.length - 1) {
|
|
1190
1175
|
const lastMsg = sentMessages[sentMessages.length - 1];
|
|
1191
1176
|
if (Array.isArray(lastMsg.content) && lastMsg.content.length > 0) {
|
|
@@ -1207,34 +1192,15 @@ export class AnthropicProvider implements Provider {
|
|
|
1207
1192
|
if (tailBlock && typeof tailBlock !== "string") {
|
|
1208
1193
|
(tailBlock as unknown as Record<string, unknown>).cache_control =
|
|
1209
1194
|
tailCacheControl;
|
|
1210
|
-
tailBreakpointApplied = true;
|
|
1211
1195
|
}
|
|
1212
1196
|
}
|
|
1213
1197
|
}
|
|
1214
1198
|
|
|
1215
|
-
//
|
|
1216
|
-
//
|
|
1217
|
-
//
|
|
1218
|
-
//
|
|
1219
|
-
//
|
|
1220
|
-
// block (workspace context) rarely changes mid-session and
|
|
1221
|
-
// benefits more from caching. Tail and prev-turn-anchor are
|
|
1222
|
-
// mutually exclusive (prev-turn-anchor only fires when turn-start
|
|
1223
|
-
// is the last message, which is the exact condition that suppresses
|
|
1224
|
-
// the tail), so we never exceed 5.
|
|
1225
|
-
const hasToolCacheBreakpoint =
|
|
1226
|
-
params.tools?.some(
|
|
1227
|
-
(t) => "cache_control" in t && t.cache_control != null,
|
|
1228
|
-
) ?? false;
|
|
1229
|
-
if (
|
|
1230
|
-
(tailBreakpointApplied || prevTurnAnchorIdx >= 0) &&
|
|
1231
|
-
Array.isArray(params.system) &&
|
|
1232
|
-
params.system.length === 2 &&
|
|
1233
|
-
hasToolCacheBreakpoint
|
|
1234
|
-
) {
|
|
1235
|
-
delete (params.system[0] as unknown as Record<string, unknown>)
|
|
1236
|
-
.cache_control;
|
|
1237
|
-
}
|
|
1199
|
+
// Cache-breakpoint accounting: system(1) + tools(1) + turn-start(1) +
|
|
1200
|
+
// (tail OR prev-turn-anchor)(1) = 4 — exactly Anthropic's per-request
|
|
1201
|
+
// cap. Tail and prev-turn-anchor are mutually exclusive (the latter
|
|
1202
|
+
// only fires when turn-start is the last message, which suppresses
|
|
1203
|
+
// the tail), so the total can't drift past 4.
|
|
1238
1204
|
|
|
1239
1205
|
// Strip orphaned UTF-16 surrogates so the Anthropic JSON parser never
|
|
1240
1206
|
// sees invalid strings produced by upstream surrogate-splitting `.slice()` calls.
|
|
@@ -24,6 +24,10 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
24
24
|
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
25
25
|
import { getConfig } from "../config/loader.js";
|
|
26
26
|
import { getDb } from "../memory/db-connection.js";
|
|
27
|
+
import {
|
|
28
|
+
describeSubscriptionModelIncompatibility,
|
|
29
|
+
isConnectionCompatibleWithModel,
|
|
30
|
+
} from "./connection-model-compat.js";
|
|
27
31
|
import {
|
|
28
32
|
ConnectionResolutionError,
|
|
29
33
|
tryResolveProviderForConnectionName,
|
|
@@ -73,10 +77,15 @@ export class CallSiteRoutingProvider implements Provider {
|
|
|
73
77
|
* `expectedProvider` is the provider name the resolved profile
|
|
74
78
|
* declared. The hook verifies the connection's provider matches
|
|
75
79
|
* and throws on mismatch.
|
|
80
|
+
*
|
|
81
|
+
* `model` is the resolved call-site model, threaded through so the
|
|
82
|
+
* connection lookup can gate `oauth_subscription` (Codex) connections
|
|
83
|
+
* by model compatibility.
|
|
76
84
|
*/
|
|
77
85
|
private readonly resolveByConnection: (
|
|
78
86
|
connectionName: string,
|
|
79
87
|
expectedProvider: string,
|
|
88
|
+
model: string | undefined,
|
|
80
89
|
) => Promise<Provider | null>,
|
|
81
90
|
) {
|
|
82
91
|
this.tokenEstimationProvider = defaultProvider.tokenEstimationProvider;
|
|
@@ -140,22 +149,33 @@ export class CallSiteRoutingProvider implements Provider {
|
|
|
140
149
|
if (!callSite) return this.defaultProvider;
|
|
141
150
|
|
|
142
151
|
const overrideProfile = options?.config?.overrideProfile;
|
|
152
|
+
// Forward the per-conversation mix seed so transport selection picks the
|
|
153
|
+
// same mix arm as wire-param normalization in `retry.ts` — otherwise a mix
|
|
154
|
+
// spanning providers could route the transport to a different arm than the
|
|
155
|
+
// request params.
|
|
156
|
+
const selectionSeed = options?.config?.selectionSeed;
|
|
143
157
|
const resolved = resolveCallSiteConfig(callSite, getConfig().llm, {
|
|
144
158
|
overrideProfile,
|
|
159
|
+
selectionSeed,
|
|
145
160
|
});
|
|
146
161
|
|
|
147
162
|
let connectionName = resolved.provider_connection;
|
|
148
163
|
|
|
149
164
|
// When no connection is set and the provider differs from the default,
|
|
150
|
-
// auto-resolve
|
|
151
|
-
//
|
|
152
|
-
//
|
|
165
|
+
// auto-resolve a connection for the provider (handles the case where the
|
|
166
|
+
// profile set provider but not provider_connection, and the merge didn't
|
|
167
|
+
// inherit one).
|
|
168
|
+
let autoResolveCandidates:
|
|
169
|
+
| import("./inference/auth.js").ProviderConnection[]
|
|
170
|
+
| undefined;
|
|
153
171
|
if (!connectionName && resolved.provider !== this.defaultProvider.name) {
|
|
154
172
|
try {
|
|
155
|
-
|
|
173
|
+
autoResolveCandidates = listConnections(getDb(), {
|
|
156
174
|
provider: resolved.provider,
|
|
157
175
|
});
|
|
158
|
-
const active =
|
|
176
|
+
const active = autoResolveCandidates.find((c) =>
|
|
177
|
+
isConnectionCompatibleWithModel(c, resolved.model),
|
|
178
|
+
);
|
|
159
179
|
if (active) {
|
|
160
180
|
connectionName = active.name;
|
|
161
181
|
}
|
|
@@ -168,6 +188,7 @@ export class CallSiteRoutingProvider implements Provider {
|
|
|
168
188
|
const connectionProvider = await this.resolveByConnection(
|
|
169
189
|
connectionName,
|
|
170
190
|
resolved.provider,
|
|
191
|
+
resolved.model,
|
|
171
192
|
);
|
|
172
193
|
if (connectionProvider) return connectionProvider;
|
|
173
194
|
return this.defaultProvider;
|
|
@@ -177,6 +198,20 @@ export class CallSiteRoutingProvider implements Provider {
|
|
|
177
198
|
return this.defaultProvider;
|
|
178
199
|
}
|
|
179
200
|
|
|
201
|
+
if (autoResolveCandidates) {
|
|
202
|
+
const incompatMsg = describeSubscriptionModelIncompatibility(
|
|
203
|
+
autoResolveCandidates,
|
|
204
|
+
resolved.model,
|
|
205
|
+
);
|
|
206
|
+
if (incompatMsg) {
|
|
207
|
+
throw new ConnectionResolutionError(
|
|
208
|
+
"<resolved-callsite>",
|
|
209
|
+
"model_incompatible",
|
|
210
|
+
incompatMsg,
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
180
215
|
throw new ConnectionResolutionError(
|
|
181
216
|
"<resolved-callsite>",
|
|
182
217
|
"missing_connection",
|
|
@@ -200,11 +235,12 @@ export function wrapWithCallSiteRouting(
|
|
|
200
235
|
): Provider {
|
|
201
236
|
return new CallSiteRoutingProvider(
|
|
202
237
|
base,
|
|
203
|
-
(connectionName, expectedProvider) =>
|
|
238
|
+
(connectionName, expectedProvider, model) =>
|
|
204
239
|
tryResolveProviderForConnectionName(
|
|
205
240
|
connectionName,
|
|
206
241
|
config,
|
|
207
242
|
expectedProvider,
|
|
243
|
+
model,
|
|
208
244
|
),
|
|
209
245
|
);
|
|
210
246
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-compatibility gate for auto-resolved provider connections.
|
|
3
|
+
*
|
|
4
|
+
* When a profile uses "Any active <provider> connection" (no
|
|
5
|
+
* `provider_connection` pinned), the daemon auto-picks an active connection
|
|
6
|
+
* for the provider. `oauth_subscription` connections (ChatGPT Codex) hard-
|
|
7
|
+
* route every request to the Codex endpoint, which rejects non-Codex models
|
|
8
|
+
* with HTTP 400. This helper lets the auto-resolution sites skip such a
|
|
9
|
+
* connection when the requested model is not Codex-compatible.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { ProviderConnection } from "./inference/auth.js";
|
|
13
|
+
import { isCodexSubscriptionModel } from "./openai/codex-models.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Whether `connection` can serve a request for `model` during
|
|
17
|
+
* auto-resolution.
|
|
18
|
+
*
|
|
19
|
+
* `oauth_subscription` connections route through the ChatGPT Codex endpoint,
|
|
20
|
+
* so they are only compatible with Codex models. Every other auth type
|
|
21
|
+
* imposes no model restriction and is always compatible.
|
|
22
|
+
*
|
|
23
|
+
* `model` may be undefined when the call site has no resolved model; in that
|
|
24
|
+
* case no model gating is applied (returns true) so resolution behaviour is
|
|
25
|
+
* unchanged.
|
|
26
|
+
*
|
|
27
|
+
* This gate applies to auto-resolution only — an explicitly pinned
|
|
28
|
+
* `provider_connection` bypasses connection selection entirely and is used
|
|
29
|
+
* regardless of model.
|
|
30
|
+
*/
|
|
31
|
+
export function isConnectionCompatibleWithModel(
|
|
32
|
+
connection: Pick<ProviderConnection, "auth">,
|
|
33
|
+
model: string | undefined,
|
|
34
|
+
): boolean {
|
|
35
|
+
if (connection.auth.type !== "oauth_subscription") return true;
|
|
36
|
+
if (!model) return true;
|
|
37
|
+
return isCodexSubscriptionModel(model);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* When auto-resolution found candidates but none were model-compatible,
|
|
42
|
+
* return a user-facing explanation if the incompatibility is specifically
|
|
43
|
+
* due to all candidates being `oauth_subscription` (ChatGPT) connections.
|
|
44
|
+
*
|
|
45
|
+
* Returns `null` when the incompatibility has a different cause (callers
|
|
46
|
+
* should fall through to their existing generic error).
|
|
47
|
+
*/
|
|
48
|
+
export function describeSubscriptionModelIncompatibility(
|
|
49
|
+
candidates: Pick<ProviderConnection, "auth">[],
|
|
50
|
+
model: string | undefined,
|
|
51
|
+
): string | null {
|
|
52
|
+
if (!model || candidates.length === 0) return null;
|
|
53
|
+
if (candidates.some((c) => isConnectionCompatibleWithModel(c, model))) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const allSubscription = candidates.every(
|
|
57
|
+
(c) => c.auth.type === "oauth_subscription",
|
|
58
|
+
);
|
|
59
|
+
if (!allSubscription) return null;
|
|
60
|
+
return `Model "${model}" isn't available through your ChatGPT subscription. Select a supported model or add an OpenAI API key connection.`;
|
|
61
|
+
}
|
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
31
31
|
import { getDb } from "../memory/db-connection.js";
|
|
32
32
|
import { getLogger } from "../util/logger.js";
|
|
33
|
+
import {
|
|
34
|
+
describeSubscriptionModelIncompatibility,
|
|
35
|
+
isConnectionCompatibleWithModel,
|
|
36
|
+
} from "./connection-model-compat.js";
|
|
33
37
|
import { getConnection, listConnections } from "./inference/connections.js";
|
|
34
38
|
import type { ProvidersConfig } from "./registry.js";
|
|
35
39
|
import { resolveProviderFromConnection } from "./registry.js";
|
|
@@ -51,7 +55,8 @@ export class ConnectionResolutionError extends Error {
|
|
|
51
55
|
| "lookup_failed"
|
|
52
56
|
| "not_found"
|
|
53
57
|
| "provider_mismatch"
|
|
54
|
-
| "missing_connection"
|
|
58
|
+
| "missing_connection"
|
|
59
|
+
| "model_incompatible",
|
|
55
60
|
message: string,
|
|
56
61
|
public readonly cause?: unknown,
|
|
57
62
|
) {
|
|
@@ -79,11 +84,16 @@ export class ConnectionResolutionError extends Error {
|
|
|
79
84
|
* `expectedProvider` is the provider name the resolving profile declared.
|
|
80
85
|
* Pass `undefined` to skip the mismatch check (callers that don't yet
|
|
81
86
|
* know the expected provider).
|
|
87
|
+
*
|
|
88
|
+
* `model` is the resolved call-site model. It gates the `provider_mismatch`
|
|
89
|
+
* auto-recovery below so a non-Codex model is never rerouted onto an
|
|
90
|
+
* `oauth_subscription` (ChatGPT Codex) connection.
|
|
82
91
|
*/
|
|
83
92
|
export async function tryResolveProviderForConnectionName(
|
|
84
93
|
connectionName: string,
|
|
85
94
|
config: ProvidersConfig,
|
|
86
95
|
expectedProvider?: string,
|
|
96
|
+
model?: string,
|
|
87
97
|
): Promise<Provider | null> {
|
|
88
98
|
let connection;
|
|
89
99
|
try {
|
|
@@ -110,10 +120,13 @@ export async function tryResolveProviderForConnectionName(
|
|
|
110
120
|
// "anthropic-managed" leaked through). Try to find an active connection
|
|
111
121
|
// for the expected provider before giving up.
|
|
112
122
|
let resolved = false;
|
|
123
|
+
let mismatchCandidates: import("./inference/auth.js").ProviderConnection[] | undefined;
|
|
113
124
|
try {
|
|
114
125
|
const db = getDb();
|
|
115
|
-
|
|
116
|
-
const active =
|
|
126
|
+
mismatchCandidates = listConnections(db, { provider: expectedProvider });
|
|
127
|
+
const active = mismatchCandidates.find((c) =>
|
|
128
|
+
isConnectionCompatibleWithModel(c, model),
|
|
129
|
+
);
|
|
117
130
|
if (active) {
|
|
118
131
|
log.info(
|
|
119
132
|
{
|
|
@@ -121,7 +134,7 @@ export async function tryResolveProviderForConnectionName(
|
|
|
121
134
|
resolvedConnection: active.name,
|
|
122
135
|
expectedProvider,
|
|
123
136
|
},
|
|
124
|
-
"Auto-resolved stale provider_connection to matching
|
|
137
|
+
"Auto-resolved stale provider_connection to matching connection",
|
|
125
138
|
);
|
|
126
139
|
connection = active;
|
|
127
140
|
resolved = true;
|
|
@@ -130,6 +143,16 @@ export async function tryResolveProviderForConnectionName(
|
|
|
130
143
|
// DB not available — fall through to the original error.
|
|
131
144
|
}
|
|
132
145
|
if (!resolved) {
|
|
146
|
+
const incompatMsg = mismatchCandidates
|
|
147
|
+
? describeSubscriptionModelIncompatibility(mismatchCandidates, model)
|
|
148
|
+
: null;
|
|
149
|
+
if (incompatMsg) {
|
|
150
|
+
throw new ConnectionResolutionError(
|
|
151
|
+
connectionName,
|
|
152
|
+
"model_incompatible",
|
|
153
|
+
incompatMsg,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
133
156
|
throw new ConnectionResolutionError(
|
|
134
157
|
connectionName,
|
|
135
158
|
"provider_mismatch",
|
|
@@ -137,13 +160,6 @@ export async function tryResolveProviderForConnectionName(
|
|
|
137
160
|
);
|
|
138
161
|
}
|
|
139
162
|
}
|
|
140
|
-
if (connection.status === "disabled") {
|
|
141
|
-
log.debug(
|
|
142
|
-
{ connectionName, provider: connection.provider },
|
|
143
|
-
"provider_connection is disabled — returning null",
|
|
144
|
-
);
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
163
|
// `resolveProviderFromConnection` reaches into auth resolution (credential
|
|
148
164
|
// reads, managed-proxy context). A transient failure there is a soft
|
|
149
165
|
// miss — log and return null so the caller can treat it the same as
|
|
@@ -151,7 +167,7 @@ export async function tryResolveProviderForConnectionName(
|
|
|
151
167
|
// catch is specifically for in-flight failures that should not take
|
|
152
168
|
// dispatch offline.
|
|
153
169
|
try {
|
|
154
|
-
return await resolveProviderFromConnection(connection, config);
|
|
170
|
+
return await resolveProviderFromConnection(connection, config, { model });
|
|
155
171
|
} catch (err) {
|
|
156
172
|
log.warn(
|
|
157
173
|
{ err, connectionName },
|
|
@@ -187,12 +203,15 @@ export async function resolveDefaultProvider(
|
|
|
187
203
|
// provider without a connection ("Any active" selection), and the merge
|
|
188
204
|
// cleared or failed to inherit one. Try to find an active connection
|
|
189
205
|
// for the provider before giving up.
|
|
206
|
+
let autoResolveCandidates: import("./inference/auth.js").ProviderConnection[] | undefined;
|
|
190
207
|
if (resolved.provider) {
|
|
191
208
|
try {
|
|
192
|
-
|
|
209
|
+
autoResolveCandidates = listConnections(getDb(), {
|
|
193
210
|
provider: resolved.provider,
|
|
194
211
|
});
|
|
195
|
-
const active =
|
|
212
|
+
const active = autoResolveCandidates.find((c) =>
|
|
213
|
+
isConnectionCompatibleWithModel(c, resolved.model),
|
|
214
|
+
);
|
|
196
215
|
if (active) {
|
|
197
216
|
log.info(
|
|
198
217
|
{ provider: resolved.provider, resolvedConnection: active.name },
|
|
@@ -205,6 +224,19 @@ export async function resolveDefaultProvider(
|
|
|
205
224
|
}
|
|
206
225
|
}
|
|
207
226
|
if (!connectionName) {
|
|
227
|
+
const incompatMsg = autoResolveCandidates
|
|
228
|
+
? describeSubscriptionModelIncompatibility(
|
|
229
|
+
autoResolveCandidates,
|
|
230
|
+
resolved.model,
|
|
231
|
+
)
|
|
232
|
+
: null;
|
|
233
|
+
if (incompatMsg) {
|
|
234
|
+
throw new ConnectionResolutionError(
|
|
235
|
+
"<llm.default>",
|
|
236
|
+
"model_incompatible",
|
|
237
|
+
incompatMsg,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
208
240
|
throw new ConnectionResolutionError(
|
|
209
241
|
"<llm.default>",
|
|
210
242
|
"missing_connection",
|
|
@@ -216,5 +248,6 @@ export async function resolveDefaultProvider(
|
|
|
216
248
|
connectionName,
|
|
217
249
|
config,
|
|
218
250
|
resolved.provider,
|
|
251
|
+
resolved.model,
|
|
219
252
|
);
|
|
220
253
|
}
|