@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
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
2
|
|
|
3
|
-
import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "../../prompts/cache-boundary.js";
|
|
4
3
|
import { isAbortReason } from "../../util/abort-reasons.js";
|
|
5
4
|
import { ProviderError } from "../../util/errors.js";
|
|
6
5
|
import { extractRetryAfterMs } from "../../util/retry.js";
|
|
@@ -55,6 +54,81 @@ export function detectOpenAICompatibleContextOverflow(
|
|
|
55
54
|
return extractOverflowTokensFromMessage(message);
|
|
56
55
|
}
|
|
57
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Build the human-readable error string surfaced from an
|
|
59
|
+
* `OpenAI.APIError`. The SDK's `error.message` is typically a one-line
|
|
60
|
+
* summary like `"400 Provider returned error"` — useless when the
|
|
61
|
+
* upstream is OpenRouter (which wraps the real downstream error on
|
|
62
|
+
* `error.error.metadata.raw`) or any provider that returns nested
|
|
63
|
+
* structured details.
|
|
64
|
+
*
|
|
65
|
+
* Returns `{ detail, requestId }` where `detail` includes the JSON body
|
|
66
|
+
* (truncated) and `requestId` is the upstream correlation header when
|
|
67
|
+
* present. Callers fold these into the thrown `ProviderError` so log
|
|
68
|
+
* lines actually identify the failure without re-running the request.
|
|
69
|
+
*
|
|
70
|
+
* Exported for tests.
|
|
71
|
+
*/
|
|
72
|
+
export function extractApiErrorDetail(
|
|
73
|
+
error: InstanceType<typeof OpenAI.APIError>,
|
|
74
|
+
): { detail: string; requestId: string | undefined } {
|
|
75
|
+
const body = (error as { error?: unknown }).error;
|
|
76
|
+
let detail = "";
|
|
77
|
+
if (body !== undefined && body !== null) {
|
|
78
|
+
try {
|
|
79
|
+
const serialized = typeof body === "string" ? body : JSON.stringify(body);
|
|
80
|
+
if (serialized && serialized !== "{}") {
|
|
81
|
+
detail =
|
|
82
|
+
serialized.length > MAX_API_ERROR_DETAIL_CHARS
|
|
83
|
+
? `${serialized.slice(0, MAX_API_ERROR_DETAIL_CHARS)}…`
|
|
84
|
+
: serialized;
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
// Body had a cycle or threw on toJSON — fall through with empty detail.
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const requestId = readHeader(error.headers, [
|
|
91
|
+
"x-request-id",
|
|
92
|
+
"x-openrouter-request-id",
|
|
93
|
+
"openai-request-id",
|
|
94
|
+
"x-amzn-requestid",
|
|
95
|
+
]);
|
|
96
|
+
return { detail, requestId };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Cap on the inline-rendered body to keep log lines readable while still
|
|
100
|
+
* surfacing the meaningful upstream payload. Tuned to comfortably hold
|
|
101
|
+
* OpenRouter's `error.metadata.raw` strings, which are typically <1KB. */
|
|
102
|
+
const MAX_API_ERROR_DETAIL_CHARS = 2000;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Read the first matching header from an SDK error's headers object,
|
|
106
|
+
* tolerating both Map-like (`Headers.get()`) and plain-object shapes.
|
|
107
|
+
* Mirrors the shape-tolerance already in `extractRetryAfterMs`.
|
|
108
|
+
*/
|
|
109
|
+
function readHeader(
|
|
110
|
+
headers: unknown,
|
|
111
|
+
names: readonly string[],
|
|
112
|
+
): string | undefined {
|
|
113
|
+
if (!headers) return undefined;
|
|
114
|
+
const getter =
|
|
115
|
+
typeof (headers as { get?: unknown }).get === "function"
|
|
116
|
+
? (headers as { get(name: string): string | null }).get.bind(headers)
|
|
117
|
+
: undefined;
|
|
118
|
+
for (const name of names) {
|
|
119
|
+
let value: string | null | undefined;
|
|
120
|
+
if (getter) {
|
|
121
|
+
value = getter(name);
|
|
122
|
+
} else if (typeof headers === "object") {
|
|
123
|
+
const record = headers as Record<string, unknown>;
|
|
124
|
+
const raw = record[name] ?? record[name.toLowerCase()];
|
|
125
|
+
value = typeof raw === "string" ? raw : undefined;
|
|
126
|
+
}
|
|
127
|
+
if (typeof value === "string" && value.length > 0) return value;
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
58
132
|
export interface OpenAIChatCompletionsProviderOptions {
|
|
59
133
|
baseURL?: string;
|
|
60
134
|
providerName?: string;
|
|
@@ -76,6 +150,10 @@ export interface OpenAIChatCompletionsProviderOptions {
|
|
|
76
150
|
* blocks. MiniMax and similar providers embed reasoning inside XML-style
|
|
77
151
|
* tags in the regular content field rather than using `reasoning_content`. */
|
|
78
152
|
parseThinkTags?: boolean;
|
|
153
|
+
/** Wire field used to replay prior assistant thinking on multi-turn requests.
|
|
154
|
+
* DeepSeek/Fireworks use `"reasoning_content"`; OpenRouter uses `"reasoning"`.
|
|
155
|
+
* When unset, thinking blocks are dropped from outbound assistant messages. */
|
|
156
|
+
assistantReasoningField?: "reasoning" | "reasoning_content";
|
|
79
157
|
}
|
|
80
158
|
|
|
81
159
|
/** Wire-level reasoning_effort values. The OpenAI SDK type doesn't include
|
|
@@ -147,6 +225,10 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
147
225
|
private maxReasoningEffort: "high" | "xhigh" | "max";
|
|
148
226
|
private requestHeaders: Record<string, string>;
|
|
149
227
|
private parseThinkTags: boolean;
|
|
228
|
+
private assistantReasoningField:
|
|
229
|
+
| "reasoning"
|
|
230
|
+
| "reasoning_content"
|
|
231
|
+
| undefined;
|
|
150
232
|
|
|
151
233
|
constructor(
|
|
152
234
|
apiKey: string,
|
|
@@ -155,16 +237,21 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
155
237
|
) {
|
|
156
238
|
this.name = options.providerName ?? "openai";
|
|
157
239
|
this.providerLabel = options.providerLabel ?? "OpenAI";
|
|
240
|
+
this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
|
|
241
|
+
// Keep the SDK deadline behind our provider stream timeout so
|
|
242
|
+
// createStreamTimeout owns the user-facing timeout error.
|
|
243
|
+
const sdkTimeoutMs = this.streamTimeoutMs + 60_000;
|
|
158
244
|
this.client = new OpenAI({
|
|
159
245
|
apiKey,
|
|
160
246
|
baseURL: options.baseURL,
|
|
247
|
+
timeout: sdkTimeoutMs,
|
|
161
248
|
});
|
|
162
249
|
this.model = model;
|
|
163
|
-
this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
|
|
164
250
|
this.extraCreateParams = options.extraCreateParams ?? {};
|
|
165
251
|
this.maxReasoningEffort = options.maxReasoningEffort ?? "xhigh";
|
|
166
252
|
this.requestHeaders = options.requestHeaders ?? {};
|
|
167
253
|
this.parseThinkTags = options.parseThinkTags ?? false;
|
|
254
|
+
this.assistantReasoningField = options.assistantReasoningField;
|
|
168
255
|
}
|
|
169
256
|
|
|
170
257
|
async sendMessage(
|
|
@@ -521,18 +608,18 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
521
608
|
? signal.reason
|
|
522
609
|
: undefined;
|
|
523
610
|
if (error instanceof OpenAI.APIError) {
|
|
611
|
+
const { detail, requestId } = extractApiErrorDetail(error);
|
|
612
|
+
const detailSuffix = detail ? ` ${detail}` : "";
|
|
613
|
+
const requestIdSuffix = requestId ? ` [request_id=${requestId}]` : "";
|
|
614
|
+
const formattedMessage = `${this.providerLabel} API error (${error.status}): ${error.message}${detailSuffix}${requestIdSuffix}`;
|
|
524
615
|
const overflow = detectOpenAICompatibleContextOverflow(error);
|
|
525
616
|
if (overflow) {
|
|
526
|
-
throw new ContextOverflowError(
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
statusCode: error.status,
|
|
533
|
-
cause: error,
|
|
534
|
-
},
|
|
535
|
-
);
|
|
617
|
+
throw new ContextOverflowError(formattedMessage, this.name, {
|
|
618
|
+
actualTokens: overflow.actualTokens,
|
|
619
|
+
maxTokens: overflow.maxTokens,
|
|
620
|
+
statusCode: error.status,
|
|
621
|
+
cause: error,
|
|
622
|
+
});
|
|
536
623
|
}
|
|
537
624
|
const retryAfterMs = extractRetryAfterMs(error.headers);
|
|
538
625
|
const errorOptions: {
|
|
@@ -543,7 +630,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
543
630
|
errorOptions.retryAfterMs = retryAfterMs;
|
|
544
631
|
if (abortReason) errorOptions.abortReason = abortReason;
|
|
545
632
|
throw new ProviderError(
|
|
546
|
-
|
|
633
|
+
formattedMessage,
|
|
547
634
|
this.name,
|
|
548
635
|
error.status,
|
|
549
636
|
Object.keys(errorOptions).length > 0 ? errorOptions : undefined,
|
|
@@ -593,7 +680,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
593
680
|
if (systemPrompt) {
|
|
594
681
|
result.push({
|
|
595
682
|
role: "system",
|
|
596
|
-
content: systemPrompt
|
|
683
|
+
content: systemPrompt,
|
|
597
684
|
});
|
|
598
685
|
}
|
|
599
686
|
|
|
@@ -658,6 +745,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
658
745
|
msg: Message,
|
|
659
746
|
): OpenAI.Chat.Completions.ChatCompletionAssistantMessageParam {
|
|
660
747
|
const textParts: string[] = [];
|
|
748
|
+
const reasoningParts: string[] = [];
|
|
661
749
|
const toolCalls: OpenAI.Chat.Completions.ChatCompletionMessageToolCall[] =
|
|
662
750
|
[];
|
|
663
751
|
|
|
@@ -666,6 +754,10 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
666
754
|
case "text":
|
|
667
755
|
textParts.push(block.text);
|
|
668
756
|
break;
|
|
757
|
+
case "thinking":
|
|
758
|
+
// Anthropic thinking blocks carry signatures — skip those.
|
|
759
|
+
if (!block.signature) reasoningParts.push(block.thinking);
|
|
760
|
+
break;
|
|
669
761
|
case "tool_use":
|
|
670
762
|
toolCalls.push({
|
|
671
763
|
id: block.id,
|
|
@@ -682,7 +774,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
682
774
|
case "web_search_tool_result":
|
|
683
775
|
textParts.push("[Web search results]");
|
|
684
776
|
break;
|
|
685
|
-
//
|
|
777
|
+
// redacted_thinking, image — not applicable for OpenAI assistant messages
|
|
686
778
|
}
|
|
687
779
|
}
|
|
688
780
|
|
|
@@ -692,6 +784,15 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
692
784
|
content: textParts.length > 0 ? textParts.join("") : null,
|
|
693
785
|
};
|
|
694
786
|
|
|
787
|
+
if (reasoningParts.length > 0 && this.assistantReasoningField) {
|
|
788
|
+
(
|
|
789
|
+
result as OpenAI.Chat.Completions.ChatCompletionAssistantMessageParam & {
|
|
790
|
+
reasoning?: string;
|
|
791
|
+
reasoning_content?: string;
|
|
792
|
+
}
|
|
793
|
+
)[this.assistantReasoningField] = reasoningParts.join("");
|
|
794
|
+
}
|
|
795
|
+
|
|
695
796
|
if (toolCalls.length > 0) {
|
|
696
797
|
result.tool_calls = toolCalls;
|
|
697
798
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model IDs accepted by the ChatGPT Codex subscription endpoint
|
|
3
|
+
* (`https://chatgpt.com/backend-api/codex`).
|
|
4
|
+
*
|
|
5
|
+
* `oauth_subscription` OpenAI connections hard-route every request to that
|
|
6
|
+
* endpoint, which rejects any model outside this set with HTTP 400. The set
|
|
7
|
+
* gates whether such a connection may serve a given model during auto-
|
|
8
|
+
* resolution of an "Any active OpenAI connection" profile.
|
|
9
|
+
*/
|
|
10
|
+
export const CODEX_SUBSCRIPTION_MODEL_IDS: ReadonlySet<string> = new Set([
|
|
11
|
+
"gpt-5.5",
|
|
12
|
+
"gpt-5.4",
|
|
13
|
+
"gpt-5.4-mini",
|
|
14
|
+
"gpt-5.3-codex",
|
|
15
|
+
]);
|
|
16
|
+
|
|
17
|
+
/** True when `model` is accepted by the Codex subscription endpoint. */
|
|
18
|
+
export function isCodexSubscriptionModel(model: string): boolean {
|
|
19
|
+
return CODEX_SUBSCRIPTION_MODEL_IDS.has(model);
|
|
20
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
2
|
|
|
3
|
-
import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "../../prompts/cache-boundary.js";
|
|
4
3
|
import { isAbortReason } from "../../util/abort-reasons.js";
|
|
5
4
|
import { ProviderError } from "../../util/errors.js";
|
|
5
|
+
import { getLogger } from "../../util/logger.js";
|
|
6
6
|
import { extractRetryAfterMs } from "../../util/retry.js";
|
|
7
7
|
import { escapeXmlAttr } from "../../util/xml.js";
|
|
8
8
|
import { createStreamTimeout } from "../stream-timeout.js";
|
|
@@ -17,6 +17,8 @@ import type {
|
|
|
17
17
|
import { ContextOverflowError } from "../types.js";
|
|
18
18
|
import { detectOpenAICompatibleContextOverflow } from "./chat-completions-provider.js";
|
|
19
19
|
|
|
20
|
+
const log = getLogger("openai-responses");
|
|
21
|
+
|
|
20
22
|
export interface OpenAIResponsesProviderOptions {
|
|
21
23
|
baseURL?: string;
|
|
22
24
|
providerName?: string;
|
|
@@ -24,7 +26,7 @@ export interface OpenAIResponsesProviderOptions {
|
|
|
24
26
|
streamTimeoutMs?: number;
|
|
25
27
|
useNativeWebSearch?: boolean;
|
|
26
28
|
/** When true, target the Codex subscription endpoint and strip fields it
|
|
27
|
-
* rejects (`max_output_tokens
|
|
29
|
+
* rejects (`max_output_tokens`). */
|
|
28
30
|
codexSubscription?: boolean;
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -72,6 +74,9 @@ interface ResponsesStreamEvent {
|
|
|
72
74
|
response?: {
|
|
73
75
|
model?: string;
|
|
74
76
|
status?: string;
|
|
77
|
+
incomplete_details?: {
|
|
78
|
+
reason?: "max_output_tokens" | "content_filter";
|
|
79
|
+
} | null;
|
|
75
80
|
/** Full output items array — preserved as part of rawResponse for the
|
|
76
81
|
* LLM context normalizer, which uses its presence to detect Responses
|
|
77
82
|
* API payloads in stored diagnostics. */
|
|
@@ -107,6 +112,7 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
107
112
|
private streamTimeoutMs: number;
|
|
108
113
|
private useNativeWebSearch: boolean;
|
|
109
114
|
private codexSubscription: boolean;
|
|
115
|
+
private lastCodexErrorBody: string | undefined;
|
|
110
116
|
|
|
111
117
|
constructor(
|
|
112
118
|
apiKey: string,
|
|
@@ -116,14 +122,39 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
116
122
|
this.name = options.providerName ?? "openai";
|
|
117
123
|
this.providerLabel = options.providerLabel ?? "OpenAI";
|
|
118
124
|
this.codexSubscription = options.codexSubscription ?? false;
|
|
125
|
+
this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
|
|
126
|
+
// Keep the SDK deadline behind our provider stream timeout so
|
|
127
|
+
// createStreamTimeout owns the user-facing timeout error.
|
|
128
|
+
const sdkTimeoutMs = this.streamTimeoutMs + 60_000;
|
|
119
129
|
this.client = new OpenAI({
|
|
120
130
|
apiKey,
|
|
121
131
|
baseURL: this.codexSubscription
|
|
122
132
|
? "https://chatgpt.com/backend-api/codex"
|
|
123
133
|
: options.baseURL,
|
|
134
|
+
timeout: sdkTimeoutMs,
|
|
135
|
+
...(this.codexSubscription
|
|
136
|
+
? {
|
|
137
|
+
fetch: async (url: RequestInfo | URL, init?: RequestInit) => {
|
|
138
|
+
const res = await globalThis.fetch(url, init);
|
|
139
|
+
if (!res.ok) {
|
|
140
|
+
const body = await res.text();
|
|
141
|
+
this.lastCodexErrorBody = body;
|
|
142
|
+
log.warn(
|
|
143
|
+
{ status: res.status, body, url: String(url) },
|
|
144
|
+
"Codex endpoint raw error response",
|
|
145
|
+
);
|
|
146
|
+
return new Response(body, {
|
|
147
|
+
status: res.status,
|
|
148
|
+
statusText: res.statusText,
|
|
149
|
+
headers: res.headers,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return res;
|
|
153
|
+
},
|
|
154
|
+
}
|
|
155
|
+
: {}),
|
|
124
156
|
});
|
|
125
157
|
this.model = model;
|
|
126
|
-
this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
|
|
127
158
|
this.useNativeWebSearch = options.useNativeWebSearch ?? false;
|
|
128
159
|
}
|
|
129
160
|
|
|
@@ -149,13 +180,11 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
149
180
|
const params: Record<string, unknown> = {
|
|
150
181
|
model: modelOverride ?? this.model,
|
|
151
182
|
input,
|
|
183
|
+
...(this.codexSubscription ? { store: false } : {}),
|
|
152
184
|
};
|
|
153
185
|
|
|
154
186
|
if (systemPrompt) {
|
|
155
|
-
params.instructions = systemPrompt
|
|
156
|
-
SYSTEM_PROMPT_CACHE_BOUNDARY,
|
|
157
|
-
"\n",
|
|
158
|
-
);
|
|
187
|
+
params.instructions = systemPrompt;
|
|
159
188
|
}
|
|
160
189
|
|
|
161
190
|
if (maxTokens && !this.codexSubscription) {
|
|
@@ -190,9 +219,9 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
190
219
|
parameters: t.input_schema,
|
|
191
220
|
strict: null,
|
|
192
221
|
}));
|
|
193
|
-
const webSearchTool =
|
|
194
|
-
type: "
|
|
195
|
-
|
|
222
|
+
const webSearchTool = this.codexSubscription
|
|
223
|
+
? { type: "web_search" as const, external_web_access: false }
|
|
224
|
+
: { type: "web_search_preview" as const };
|
|
196
225
|
params.tools = [...mappedOther, webSearchTool];
|
|
197
226
|
} else {
|
|
198
227
|
params.tools = tools.map((t) => ({
|
|
@@ -228,20 +257,26 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
228
257
|
let rawFinalResponse: unknown = undefined;
|
|
229
258
|
|
|
230
259
|
try {
|
|
231
|
-
//
|
|
232
|
-
// `
|
|
260
|
+
// Use `create()` with `stream: true` instead of the higher-level
|
|
261
|
+
// `stream()` helper. The `stream()` helper wraps the response in a
|
|
262
|
+
// `ResponseStream` that runs `maybeParseResponse()` after iteration,
|
|
263
|
+
// which crashes when the Codex subscription endpoint omits `output`
|
|
264
|
+
// from the `response.completed` event payload.
|
|
233
265
|
const responsesApi = this.client.responses as unknown as {
|
|
234
|
-
|
|
266
|
+
create(
|
|
235
267
|
p: Record<string, unknown>,
|
|
236
|
-
o
|
|
237
|
-
): AsyncIterable<ResponsesStreamEvent
|
|
268
|
+
o?: { signal?: AbortSignal; headers?: Record<string, string> },
|
|
269
|
+
): Promise<AsyncIterable<ResponsesStreamEvent>>;
|
|
238
270
|
};
|
|
239
|
-
const stream = responsesApi.
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
271
|
+
const stream = await responsesApi.create(
|
|
272
|
+
{ ...params, stream: true },
|
|
273
|
+
{
|
|
274
|
+
signal: timeoutSignal,
|
|
275
|
+
...(usageAttributionHeaders
|
|
276
|
+
? { headers: usageAttributionHeaders }
|
|
277
|
+
: {}),
|
|
278
|
+
},
|
|
279
|
+
);
|
|
245
280
|
|
|
246
281
|
for await (const event of stream) {
|
|
247
282
|
switch (event.type) {
|
|
@@ -313,7 +348,8 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
313
348
|
break;
|
|
314
349
|
}
|
|
315
350
|
|
|
316
|
-
case "response.completed":
|
|
351
|
+
case "response.completed":
|
|
352
|
+
case "response.incomplete": {
|
|
317
353
|
const response = event.response;
|
|
318
354
|
if (response) {
|
|
319
355
|
rawFinalResponse = response;
|
|
@@ -328,15 +364,22 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
328
364
|
cachedInputTokens =
|
|
329
365
|
response.usage.input_tokens_details?.cached_tokens ?? 0;
|
|
330
366
|
}
|
|
331
|
-
finishReason =
|
|
367
|
+
finishReason =
|
|
368
|
+
response.incomplete_details?.reason ??
|
|
369
|
+
response.status ??
|
|
370
|
+
(event.type === "response.incomplete"
|
|
371
|
+
? "incomplete"
|
|
372
|
+
: "completed");
|
|
332
373
|
}
|
|
333
374
|
// Emit server_tool_complete for any web search calls that were started.
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
375
|
+
if (event.type === "response.completed") {
|
|
376
|
+
for (const toolUseId of webSearchCallIds) {
|
|
377
|
+
onEvent?.({
|
|
378
|
+
type: "server_tool_complete",
|
|
379
|
+
toolUseId,
|
|
380
|
+
isError: false,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
340
383
|
}
|
|
341
384
|
break;
|
|
342
385
|
}
|
|
@@ -431,8 +474,22 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
431
474
|
if (retryAfterMs !== undefined)
|
|
432
475
|
errorOptions.retryAfterMs = retryAfterMs;
|
|
433
476
|
if (abortReason) errorOptions.abortReason = abortReason;
|
|
477
|
+
let errorDetail = error.message;
|
|
478
|
+
if (this.lastCodexErrorBody) {
|
|
479
|
+
try {
|
|
480
|
+
const parsed = JSON.parse(this.lastCodexErrorBody);
|
|
481
|
+
if (parsed.detail) errorDetail = parsed.detail;
|
|
482
|
+
} catch {
|
|
483
|
+
errorDetail = this.lastCodexErrorBody.slice(0, 200);
|
|
484
|
+
}
|
|
485
|
+
this.lastCodexErrorBody = undefined;
|
|
486
|
+
}
|
|
487
|
+
const extras = [error.code, error.type, error.param]
|
|
488
|
+
.filter(Boolean)
|
|
489
|
+
.join(", ");
|
|
490
|
+
const extraSuffix = extras ? ` [${extras}]` : "";
|
|
434
491
|
throw new ProviderError(
|
|
435
|
-
`${this.providerLabel} API error (${error.status}): ${
|
|
492
|
+
`${this.providerLabel} API error (${error.status}): ${errorDetail}${extraSuffix}`,
|
|
436
493
|
this.name,
|
|
437
494
|
error.status,
|
|
438
495
|
Object.keys(errorOptions).length > 0 ? errorOptions : undefined,
|
|
@@ -122,6 +122,7 @@ export class OpenRouterProvider extends OpenAIChatCompletionsProvider {
|
|
|
122
122
|
providerLabel: "OpenRouter",
|
|
123
123
|
streamTimeoutMs: options.streamTimeoutMs,
|
|
124
124
|
requestHeaders: OPENROUTER_APP_ATTRIBUTION_HEADERS,
|
|
125
|
+
assistantReasoningField: "reasoning",
|
|
125
126
|
});
|
|
126
127
|
this.openRouterApiKey = apiKey;
|
|
127
128
|
this.defaultModel = model;
|
|
@@ -199,17 +200,21 @@ export class OpenRouterProvider extends OpenAIChatCompletionsProvider {
|
|
|
199
200
|
? EFFORT_TO_REASONING_EFFORT[effort]
|
|
200
201
|
: undefined;
|
|
201
202
|
const summaryOverride = extractReasoningSummaryOverride(config);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
this.resolveMaxReasoningEffort(this.resolveEffectiveModel(options)),
|
|
207
|
-
);
|
|
208
|
-
}
|
|
203
|
+
// Only send `reasoning` when explicitly enabling thinking. Omitting the
|
|
204
|
+
// field lets OpenRouter use the model's natural default, which avoids 400s
|
|
205
|
+
// from reasoning-only models (e.g. DeepSeek R1) that reject `enabled: false`.
|
|
206
|
+
const extras: Record<string, unknown> = {};
|
|
209
207
|
if (thinkingEnabled) {
|
|
208
|
+
const reasoning: Record<string, unknown> = { enabled: true };
|
|
209
|
+
if (mappedEffort) {
|
|
210
|
+
reasoning.effort = clampReasoningEffort(
|
|
211
|
+
mappedEffort,
|
|
212
|
+
this.resolveMaxReasoningEffort(this.resolveEffectiveModel(options)),
|
|
213
|
+
);
|
|
214
|
+
}
|
|
210
215
|
reasoning.summary = summaryOverride ?? "detailed";
|
|
216
|
+
extras.reasoning = reasoning;
|
|
211
217
|
}
|
|
212
|
-
const extras: Record<string, unknown> = { reasoning };
|
|
213
218
|
const only = extractOnlyList(config);
|
|
214
219
|
if (only.length > 0) {
|
|
215
220
|
const existingProvider = (config?.provider ?? {}) as Record<
|
|
@@ -9,6 +9,10 @@ import { getConfig } from "../config/loader.js";
|
|
|
9
9
|
import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
10
10
|
import { getDb } from "../memory/db-connection.js";
|
|
11
11
|
import { getLogger } from "../util/logger.js";
|
|
12
|
+
import {
|
|
13
|
+
describeSubscriptionModelIncompatibility,
|
|
14
|
+
isConnectionCompatibleWithModel,
|
|
15
|
+
} from "./connection-model-compat.js";
|
|
12
16
|
import { tryResolveProviderForConnectionName } from "./connection-resolution.js";
|
|
13
17
|
import { listConnections } from "./inference/connections.js";
|
|
14
18
|
import { initializeProviders, listProviders } from "./registry.js";
|
|
@@ -116,19 +120,29 @@ export async function resolveConfiguredProvider(
|
|
|
116
120
|
|
|
117
121
|
// Connection-aware path: every dispatch goes through `provider_connection`.
|
|
118
122
|
// The boot-time backfill ensures every profile has one in production.
|
|
119
|
-
// When unset (profile set provider
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
+
// When unset (profile set provider without a connection, test envs that
|
|
124
|
+
// skip backfill, freshly-installed configs not yet backfilled, or users
|
|
125
|
+
// who manually cleared the field), try to auto-resolve from the provider
|
|
126
|
+
// before falling back to null.
|
|
123
127
|
if (!connectionName) {
|
|
124
128
|
if (inferenceProvider) {
|
|
125
129
|
try {
|
|
126
130
|
const candidates = listConnections(getDb(), {
|
|
127
131
|
provider: inferenceProvider,
|
|
128
132
|
});
|
|
129
|
-
const active = candidates.find((c) =>
|
|
133
|
+
const active = candidates.find((c) =>
|
|
134
|
+
isConnectionCompatibleWithModel(c, resolved.model),
|
|
135
|
+
);
|
|
130
136
|
if (active) {
|
|
131
137
|
connectionName = active.name;
|
|
138
|
+
} else {
|
|
139
|
+
const incompatMsg = describeSubscriptionModelIncompatibility(
|
|
140
|
+
candidates,
|
|
141
|
+
resolved.model,
|
|
142
|
+
);
|
|
143
|
+
if (incompatMsg) {
|
|
144
|
+
log.warn({ callSite, inferenceProvider, model: resolved.model }, incompatMsg);
|
|
145
|
+
}
|
|
132
146
|
}
|
|
133
147
|
} catch {
|
|
134
148
|
// DB not available — fall through to the existing null-return path.
|
|
@@ -147,6 +161,7 @@ export async function resolveConfiguredProvider(
|
|
|
147
161
|
connectionName,
|
|
148
162
|
config,
|
|
149
163
|
inferenceProvider,
|
|
164
|
+
resolved.model,
|
|
150
165
|
);
|
|
151
166
|
if (!connectionProvider) {
|
|
152
167
|
// Soft credential failure — the connection resolved to no usable
|
|
@@ -29,10 +29,18 @@ const log = getLogger("provider-registry");
|
|
|
29
29
|
const providers = new Map<string, Provider>();
|
|
30
30
|
const routingSources = new Map<string, "user-key" | "managed-proxy">();
|
|
31
31
|
const OPENAI_COMPATIBLE_ENDPOINTS_FLAG = "openai-compatible-endpoints";
|
|
32
|
+
const NATIVE_WEB_SEARCH_PROVIDER_IDS = new Set(["anthropic", "openai"]);
|
|
32
33
|
|
|
33
|
-
/** Per-connection provider cache, keyed by connection name. */
|
|
34
|
+
/** Per-connection provider cache, keyed by connection name and model. */
|
|
34
35
|
const connectionProviders = new Map<string, Provider>();
|
|
35
36
|
|
|
37
|
+
function getConnectionProviderCacheKey(
|
|
38
|
+
connection: ProviderConnection,
|
|
39
|
+
model: string,
|
|
40
|
+
): string {
|
|
41
|
+
return `${connection.name}\u0000${model}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
function registerProvider(name: string, provider: Provider): void {
|
|
37
45
|
providers.set(name, new UsageTrackingProvider(provider));
|
|
38
46
|
}
|
|
@@ -98,6 +106,30 @@ function resolveModel(config: ProvidersConfig, providerName: string): string {
|
|
|
98
106
|
return getProviderDefaultModel(providerName);
|
|
99
107
|
}
|
|
100
108
|
|
|
109
|
+
export function isNativeWebSearchCapableProvider(
|
|
110
|
+
providerName: string,
|
|
111
|
+
model: string,
|
|
112
|
+
): boolean {
|
|
113
|
+
if (NATIVE_WEB_SEARCH_PROVIDER_IDS.has(providerName)) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (providerName === "openrouter" && model.startsWith("anthropic/")) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function shouldUseNativeWebSearch(
|
|
123
|
+
config: ProvidersConfig,
|
|
124
|
+
providerName: string,
|
|
125
|
+
model: string,
|
|
126
|
+
): boolean {
|
|
127
|
+
return (
|
|
128
|
+
config.services["web-search"].provider === "inference-provider-native" &&
|
|
129
|
+
isNativeWebSearchCapableProvider(providerName, model)
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
101
133
|
/**
|
|
102
134
|
* Resolve provider credentials. User key takes precedence; managed proxy is
|
|
103
135
|
* used as a fallback when platform prerequisites are available.
|
|
@@ -135,8 +167,6 @@ export async function initializeProviders(
|
|
|
135
167
|
|
|
136
168
|
const streamTimeoutMs =
|
|
137
169
|
(config.timeouts?.providerStreamTimeoutSec ?? 1800) * 1000;
|
|
138
|
-
const useNativeWebSearch =
|
|
139
|
-
config.services["web-search"].provider === "inference-provider-native";
|
|
140
170
|
const mainAgentProvider = resolveCallSiteConfig(
|
|
141
171
|
"mainAgent",
|
|
142
172
|
config.llm,
|
|
@@ -174,6 +204,11 @@ export async function initializeProviders(
|
|
|
174
204
|
}
|
|
175
205
|
|
|
176
206
|
const model = resolveModel(config, entry.id);
|
|
207
|
+
const useNativeWebSearch = shouldUseNativeWebSearch(
|
|
208
|
+
config,
|
|
209
|
+
entry.id,
|
|
210
|
+
model,
|
|
211
|
+
);
|
|
177
212
|
const adapter = buildProviderAdapter(entry.id, {
|
|
178
213
|
apiKey,
|
|
179
214
|
model,
|
|
@@ -221,6 +256,7 @@ export async function initializeProviders(
|
|
|
221
256
|
export async function resolveProviderFromConnection(
|
|
222
257
|
connection: ProviderConnection,
|
|
223
258
|
config: ProvidersConfig,
|
|
259
|
+
opts: { model?: string } = {},
|
|
224
260
|
): Promise<Provider | null> {
|
|
225
261
|
if (
|
|
226
262
|
connection.provider === "openai-compatible" &&
|
|
@@ -229,7 +265,9 @@ export async function resolveProviderFromConnection(
|
|
|
229
265
|
return null;
|
|
230
266
|
}
|
|
231
267
|
|
|
232
|
-
const
|
|
268
|
+
const model = opts.model ?? resolveModel(config, connection.provider);
|
|
269
|
+
const cacheKey = getConnectionProviderCacheKey(connection, model);
|
|
270
|
+
const cached = connectionProviders.get(cacheKey);
|
|
233
271
|
if (cached) return cached;
|
|
234
272
|
|
|
235
273
|
const authResult = await resolveAuth(connection.auth, connection.provider, {
|
|
@@ -259,9 +297,11 @@ export async function resolveProviderFromConnection(
|
|
|
259
297
|
|
|
260
298
|
const streamTimeoutMs =
|
|
261
299
|
(config.timeouts?.providerStreamTimeoutSec ?? 1800) * 1000;
|
|
262
|
-
const useNativeWebSearch =
|
|
263
|
-
config
|
|
264
|
-
|
|
300
|
+
const useNativeWebSearch = shouldUseNativeWebSearch(
|
|
301
|
+
config,
|
|
302
|
+
connection.provider,
|
|
303
|
+
model,
|
|
304
|
+
);
|
|
265
305
|
|
|
266
306
|
const provider = createAdapterFromConnection(
|
|
267
307
|
connection,
|
|
@@ -274,7 +314,7 @@ export async function resolveProviderFromConnection(
|
|
|
274
314
|
);
|
|
275
315
|
|
|
276
316
|
if (provider) {
|
|
277
|
-
connectionProviders.set(
|
|
317
|
+
connectionProviders.set(cacheKey, provider);
|
|
278
318
|
}
|
|
279
319
|
|
|
280
320
|
return provider;
|