@vellumai/assistant 0.11.2 → 0.11.3-staging.2
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/ARCHITECTURE.md +58 -3
- package/docs/trusted-contact-access.md +9 -5
- package/docs/vellum-doctor.md +195 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/ces-client/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +19 -2
- package/node_modules/@vellumai/environments/package.json +2 -1
- package/node_modules/@vellumai/environments/src/__tests__/cloud-assistant-hub-url.test.ts +38 -0
- package/node_modules/@vellumai/environments/src/__tests__/install-layout.test.ts +98 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +5 -5
- package/node_modules/@vellumai/environments/src/index.ts +17 -6
- package/node_modules/@vellumai/environments/src/install-layout.ts +49 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +29 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +4 -0
- package/node_modules/@vellumai/gateway-client/src/verification-session-contract.ts +91 -6
- package/node_modules/@vellumai/ipc-server-utils/src/endpoint.test.ts +36 -0
- package/node_modules/@vellumai/ipc-server-utils/src/endpoint.ts +142 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +2 -0
- package/node_modules/@vellumai/ipc-server-utils/src/listen-options.ts +3 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +15 -1
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +17 -2
- package/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +16 -2
- package/openapi.yaml +589 -30
- package/package.json +1 -1
- package/src/__tests__/agent-image-optimize.test.ts +4 -4
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +113 -66
- package/src/__tests__/agent-loop-override-profile.test.ts +38 -48
- package/src/__tests__/agent-loop-subagent-billing-headers.test.ts +166 -0
- 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__/answered-question-persistence.test.ts +240 -0
- package/src/__tests__/anthropic-provider.test.ts +165 -30
- package/src/__tests__/app-control-flow.test.ts +9 -8
- package/src/__tests__/assistant-event-hub.test.ts +48 -0
- package/src/__tests__/attachments-store-heic-normalize.test.ts +16 -12
- package/src/__tests__/attachments-store.test.ts +130 -68
- package/src/__tests__/attachments.test.ts +36 -36
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/call-start-guardian-guard.test.ts +18 -4
- package/src/__tests__/canned-reply-release.test.ts +86 -0
- package/src/__tests__/channel-guardian.test.ts +59 -29
- package/src/__tests__/channel-readiness-telegram-remote.test.ts +154 -0
- package/src/__tests__/channel-setup-panel-ack.test.ts +6 -5
- package/src/__tests__/client-os-metadata-persistence.test.ts +103 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
- package/src/__tests__/consult-deadline.test.ts +65 -0
- package/src/__tests__/conversation-agent-loop.test.ts +438 -2
- package/src/__tests__/conversation-disk-view-integration.test.ts +5 -1
- package/src/__tests__/conversation-disk-view.test.ts +4 -4
- package/src/__tests__/conversation-error.test.ts +22 -3
- package/src/__tests__/conversation-fork-crud.test.ts +5 -1
- package/src/__tests__/conversation-fork-referential.test.ts +352 -0
- package/src/__tests__/conversation-fork-retrospective.test.ts +5 -1
- package/src/__tests__/conversation-group-tools.test.ts +32 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +27 -1
- package/src/__tests__/conversation-initial-prompt.test.ts +51 -22
- package/src/__tests__/conversation-key-store-bootstrap-cleanup.test.ts +119 -0
- package/src/__tests__/conversation-key-store-origin.test.ts +105 -0
- package/src/__tests__/conversation-list-recency-ordering.test.ts +104 -0
- package/src/__tests__/conversation-origin-at-creation.test.ts +153 -0
- package/src/__tests__/conversation-origin-channel-filter.test.ts +95 -0
- package/src/__tests__/conversation-placement-promotion.test.ts +172 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +123 -0
- package/src/__tests__/conversation-queue.test.ts +433 -1
- package/src/__tests__/conversation-retry-route.test.ts +3 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +64 -1
- package/src/__tests__/conversation-store-ephemeral.test.ts +4 -0
- package/src/__tests__/conversation-store.test.ts +26 -10
- package/src/__tests__/conversation-summarize-route.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +15 -6
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -5
- package/src/__tests__/conversation-surfaces-app-control.test.ts +12 -11
- package/src/__tests__/conversation-surfaces-app-open.test.ts +11 -5
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +5 -4
- package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +967 -0
- package/src/__tests__/conversation-surfaces-persisted-info.test.ts +312 -0
- package/src/__tests__/conversation-surfaces-queued-emit.test.ts +6 -5
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -8
- package/src/__tests__/conversation-surfaces-standalone.test.ts +21 -11
- package/src/__tests__/conversation-surfaces-state-update.test.ts +7 -11
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -6
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +11 -6
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +9 -6
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +70 -7
- package/src/__tests__/conversation-wait-for-idle.test.ts +6 -11
- package/src/__tests__/credential-prompt-route.test.ts +57 -7
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +89 -28
- package/src/__tests__/custom-group-listing-visibility.test.ts +1 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +4 -1
- package/src/__tests__/discord-access-request-privacy.test.ts +366 -0
- package/src/__tests__/discord-requester-notice-privacy.test.ts +87 -0
- package/src/__tests__/disk-pressure-guard.test.ts +55 -55
- package/src/__tests__/disk-pressure-routes.test.ts +10 -10
- package/src/__tests__/disk-pressure-tools.test.ts +2 -2
- package/src/__tests__/disk-usage.test.ts +35 -20
- package/src/__tests__/document-sync-tags.test.ts +379 -0
- package/src/__tests__/document-update-default-surface.test.ts +28 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +2 -2
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -4
- package/src/__tests__/ensure-conversation-exists.test.ts +8 -5
- package/src/__tests__/events-dev-bypass-actor.test.ts +183 -1
- package/src/__tests__/evict-conversations-for-reload.test.ts +90 -0
- package/src/__tests__/file-list-tool.test.ts +12 -10
- package/src/__tests__/file-ops-service.test.ts +151 -44
- package/src/__tests__/file-read-container-boundary.test.ts +137 -0
- package/src/__tests__/file-read-tool.test.ts +21 -9
- package/src/__tests__/file-url-path-guard.test.ts +83 -0
- package/src/__tests__/filesystem-tools.test.ts +82 -66
- package/src/__tests__/guardian-outbound-http.test.ts +8 -8
- package/src/__tests__/helpers/gateway-verification-sessions-stub.ts +14 -1
- package/src/__tests__/helpers/hub-clients.ts +42 -0
- package/src/__tests__/helpers/mock-conversation.ts +46 -0
- package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +61 -57
- package/src/__tests__/history-repair.test.ts +112 -12
- package/src/__tests__/host-bash-proxy.test.ts +10 -5
- package/src/__tests__/host-bash-routes.test.ts +67 -0
- package/src/__tests__/host-browser-proxy.test.ts +2 -2
- package/src/__tests__/host-cu-proxy.test.ts +3 -7
- package/src/__tests__/host-file-proxy.test.ts +3 -7
- package/src/__tests__/host-file-read-tool.test.ts +5 -1
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +6 -4
- package/src/__tests__/http-conversation-lineage.test.ts +2 -5
- package/src/__tests__/http-user-message-parity.test.ts +44 -0
- package/src/__tests__/identity-routes.test.ts +13 -13
- package/src/__tests__/image-conversion.test.ts +29 -26
- package/src/__tests__/image-source-path-reinject.test.ts +2 -2
- package/src/__tests__/inference-profile-session-handler.test.ts +95 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +25 -0
- package/src/__tests__/introduction-card-resolver.test.ts +6 -1
- package/src/__tests__/list-messages-attachments.test.ts +56 -32
- package/src/__tests__/list-messages-background-tool-completion.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +2 -2
- package/src/__tests__/list-messages-hidden-metadata.test.ts +16 -16
- package/src/__tests__/list-messages-page-latest.test.ts +61 -61
- package/src/__tests__/list-messages-provider-error.test.ts +6 -6
- package/src/__tests__/list-messages-queued.test.ts +49 -6
- package/src/__tests__/list-messages-system-card.test.ts +4 -4
- package/src/__tests__/list-messages-tool-merge.test.ts +9 -9
- package/src/__tests__/llm-resolver-override-or-default.test.ts +141 -0
- package/src/__tests__/llm-usage-store.test.ts +55 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +45 -0
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +133 -0
- package/src/__tests__/media-stream-server-integration.test.ts +36 -0
- package/src/__tests__/migration-export-http.test.ts +1 -1
- package/src/__tests__/migration-import-commit-http.test.ts +1 -1
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -1
- package/src/__tests__/migration-validate-http.test.ts +1 -1
- package/src/__tests__/mtime-cache.test.ts +65 -3
- package/src/__tests__/notification-platform-adapter.test.ts +104 -0
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
- package/src/__tests__/oauth-provider-profiles.test.ts +4 -2
- package/src/__tests__/oauth-provider-seed-logos.test.ts +65 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +17 -0
- package/src/__tests__/oauth-providers-routes.test.ts +1 -0
- package/src/__tests__/openai-responses-prompt-cache.test.ts +5 -2
- package/src/__tests__/path-policy.test.ts +164 -1
- package/src/__tests__/persist-media-references.test.ts +2 -2
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +5 -5
- package/src/__tests__/persist-unsendable-image.test.ts +23 -23
- package/src/__tests__/persona-resolver.test.ts +154 -0
- package/src/__tests__/plugin-api-webhook-url.test.ts +170 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +6 -0
- package/src/__tests__/processing-flag-persist-failure.test.ts +15 -10
- package/src/__tests__/profile-availability-incomplete.test.ts +113 -0
- package/src/__tests__/profiler-routes.test.ts +13 -13
- package/src/__tests__/prompt-cache-cross-turn-stability.test.ts +593 -0
- package/src/__tests__/proxy-approval-callback.test.ts +3 -3
- package/src/__tests__/queued-message-cancel-and-steer.test.ts +189 -0
- package/src/__tests__/queued-message-steer-actor-scoping.test.ts +164 -0
- package/src/__tests__/resolve-trust-class.test.ts +20 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +1 -1
- package/src/__tests__/run-due-schedules.test.ts +174 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +15 -7
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +166 -0
- package/src/__tests__/schedule-routes.test.ts +730 -8
- package/src/__tests__/schedule-store.test.ts +540 -0
- package/src/__tests__/schedule-tools.test.ts +103 -0
- package/src/__tests__/scheduler-wake.test.ts +5 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +29 -1
- package/src/__tests__/secure-keys.test.ts +91 -0
- package/src/__tests__/server-history-render.test.ts +97 -7
- package/src/__tests__/size-guard.test.ts +8 -8
- package/src/__tests__/skill-docs-sync-guard.test.ts +3 -2
- package/src/__tests__/skill-tool-factory.test.ts +247 -0
- package/src/__tests__/skills-install-staging.test.ts +15 -6
- package/src/__tests__/slack-edit-ordering-characterization.test.ts +103 -0
- package/src/__tests__/slack-inbound-verification.test.ts +4 -1
- package/src/__tests__/slack-mention-binding-invariance.test.ts +103 -0
- package/src/__tests__/slack-mention-provider-leak-audit.test.ts +135 -0
- package/src/__tests__/starter-task-flow.test.ts +5 -4
- package/src/__tests__/steer-on-enqueue-question.test.ts +3 -2
- package/src/__tests__/stt-language-catalog-parity.test.ts +38 -0
- package/src/__tests__/subagent-allowlist-validation.test.ts +26 -4
- package/src/__tests__/subagent-cron-run-attribution.test.ts +301 -0
- package/src/__tests__/subagent-disposal.test.ts +10 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +10 -0
- package/src/__tests__/subagent-fork-prompt-role.test.ts +85 -11
- package/src/__tests__/subagent-fork-spawn.test.ts +15 -7
- package/src/__tests__/subagent-manager-notify.test.ts +148 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/subagent-persistence.test.ts +141 -0
- package/src/__tests__/subagent-role-registry.test.ts +172 -63
- package/src/__tests__/subagent-role-resolution.test.ts +88 -0
- package/src/__tests__/subagent-spawn-and-await.test.ts +48 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +111 -10
- package/src/__tests__/subagent-terminal-message.test.ts +88 -1
- package/src/__tests__/subagent-tool-gate-mode.test.ts +225 -10
- package/src/__tests__/subagent-tools.test.ts +1901 -108
- package/src/__tests__/surface-completion-compaction-boundary.test.ts +124 -0
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +298 -0
- package/src/__tests__/system-prompt.test.ts +82 -7
- package/src/__tests__/tool-grant-request-escalation.test.ts +40 -1
- package/src/__tests__/tool-result-spool.test.ts +74 -18
- package/src/__tests__/tool-side-effects-documents.test.ts +174 -0
- package/src/__tests__/tool-side-effects-hook-failures.test.ts +129 -0
- package/src/__tests__/tools-audio-read.test.ts +10 -10
- package/src/__tests__/tools-get-route.test.ts +85 -12
- package/src/__tests__/tools-list-cli.test.ts +171 -0
- package/src/__tests__/top-level-renderer.test.ts +54 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +68 -1
- package/src/__tests__/trusted-contact-multichannel.test.ts +4 -1
- package/src/__tests__/turn-tail-chain.test.ts +135 -0
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +6 -4
- package/src/__tests__/ui-visual-surface.test.ts +5 -4
- package/src/__tests__/ui-work-result-surface.test.ts +5 -4
- package/src/__tests__/unified-turn-context-visible-app.test.ts +7 -8
- package/src/__tests__/usage-routes.test.ts +62 -0
- package/src/__tests__/verification-outbound-delivery.test.ts +176 -0
- package/src/__tests__/visible-app-context.test.ts +20 -4
- package/src/__tests__/web-search-history.test.ts +96 -0
- package/src/__tests__/workspace-migration-139-clear-renamed-cost-profile-label.test.ts +6 -6
- package/src/__tests__/workspace-migration-140-repair-seed-pinned-memory-v3-live.test.ts +330 -0
- package/src/acp/failure-error.ts +3 -5
- package/src/agent/attachments.ts +26 -24
- package/src/agent/history-repair/history-repair.ts +27 -26
- package/src/agent/image-optimize.ts +6 -6
- package/src/agent/loop.ts +40 -22
- package/src/agent/message-types.ts +3 -3
- package/src/api/constants/document-tools.ts +55 -0
- package/src/api/events/question-answered.ts +53 -0
- package/src/api/events/tool-result.ts +7 -0
- package/src/api/index.ts +13 -0
- package/src/api/responses/conversation-message.ts +11 -0
- package/src/api/surfaces-oauth-connect.test.ts +96 -0
- package/src/api/surfaces.ts +36 -8
- package/src/approvals/guardian-channel-delivery.ts +83 -0
- package/src/approvals/guardian-expiry-notifier.ts +13 -11
- package/src/approvals/guardian-request-resolvers.ts +222 -135
- package/src/calls/__tests__/voice-session-bridge.test.ts +50 -0
- package/src/calls/media-stream-server.ts +9 -1
- package/src/calls/voice-session-bridge.ts +38 -0
- package/src/channels/__tests__/gateway-verification-sessions.test.ts +3 -3
- package/src/channels/config.ts +7 -2
- package/src/channels/gateway-verification-sessions.ts +7 -2
- package/src/channels/types.ts +7 -1
- package/src/cli/commands/__tests__/cache.test.ts +7 -4
- package/src/cli/commands/__tests__/cli-test-harness.ts +82 -0
- package/src/cli/commands/__tests__/conversations-wake.test.ts +51 -6
- package/src/cli/commands/__tests__/inference-models.test.ts +14 -0
- package/src/cli/commands/__tests__/inference-profiles.test.ts +44 -1
- package/src/cli/commands/__tests__/inference-providers.test.ts +7 -0
- package/src/cli/commands/__tests__/plugins.test.ts +692 -0
- package/src/cli/commands/__tests__/schedules.test.ts +136 -37
- package/src/cli/commands/conversations.ts +7 -3
- package/src/cli/commands/credentials.help.ts +7 -0
- package/src/cli/commands/inference-profiles.ts +9 -3
- package/src/cli/commands/inference.help.ts +16 -2
- package/src/cli/commands/mcp.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +18 -0
- package/src/cli/commands/notifications.ts +3 -6
- package/src/cli/commands/oauth/connect-surface-guidance.test.ts +16 -0
- package/src/cli/commands/oauth/connect-surface-guidance.ts +25 -7
- package/src/cli/commands/oauth/connect.test.ts +26 -1
- package/src/cli/commands/oauth/connect.ts +4 -1
- package/src/cli/commands/oauth/index.help.ts +3 -1
- package/src/cli/commands/oauth/providers.ts +3 -0
- package/src/cli/commands/plugins.help.ts +25 -2
- package/src/cli/commands/plugins.ts +289 -10
- package/src/cli/commands/schedules.help.ts +14 -12
- package/src/cli/commands/schedules.ts +19 -5
- package/src/cli/commands/tools.help.ts +4 -2
- package/src/cli/commands/tools.ts +38 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +1 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +79 -0
- package/src/cli/lib/__tests__/install-from-platform.test.ts +47 -1
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +86 -7
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +122 -0
- package/src/cli/lib/install-from-github.ts +61 -0
- package/src/cli/lib/install-from-platform.ts +13 -2
- package/src/cli/lib/plugin-surfaces.ts +124 -4
- package/src/cli/lib/upgrade-plugin.ts +18 -0
- package/src/cli.ts +1 -1
- package/src/config/__tests__/deployment-context-defaults.test.ts +73 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +40 -0
- package/src/config/__tests__/plugin-updates-schema.test.ts +43 -0
- package/src/config/__tests__/profile-tool-support.test.ts +131 -0
- package/src/config/bundled-skills/AGENTS.md +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +3 -3
- package/src/config/bundled-skills/schedule/SKILL.md +5 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +1 -0
- package/src/config/bundled-skills/subagent/SKILL.md +53 -22
- package/src/config/bundled-skills/subagent/TOOLS.json +14 -13
- package/src/config/bundled-skills/visualize/SKILL.md +1 -1
- package/src/config/default-profile-catalog.ts +6 -2
- package/src/config/feature-flag-registry.json +25 -17
- package/src/config/llm-resolver.ts +45 -15
- package/src/config/loader.ts +70 -1
- package/src/config/profile-tool-support.ts +110 -0
- package/src/config/sanitize-for-transfer.ts +11 -0
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/stt.test.ts +20 -5
- package/src/config/schemas/channels.ts +13 -0
- package/src/config/schemas/memory-retrospective.ts +25 -0
- package/src/config/schemas/plugin-updates.ts +55 -0
- package/src/config/schemas/services.ts +8 -4
- package/src/config/schemas/stt.ts +17 -5
- package/src/config/schemas/timeouts.ts +1 -1
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +16 -0
- package/src/contacts/guardian-delivery-reader.ts +29 -2
- package/src/context/compactor.ts +4 -4
- package/src/context/post-turn-tool-result-truncation.ts +32 -16
- package/src/context/strip-injections.ts +42 -0
- package/src/context/tool-result-spool.ts +32 -18
- package/src/credential-execution/ces-runtime.ts +3 -0
- package/src/credential-execution/client.ts +22 -1
- package/src/credential-execution/process-manager.test.ts +99 -0
- package/src/credential-execution/process-manager.ts +62 -16
- package/src/daemon/__tests__/abort-null-controller.test.ts +141 -5
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +8 -12
- package/src/daemon/__tests__/install-assistant-command.test.ts +234 -0
- package/src/daemon/__tests__/turn-tail-assistant-reply-notify.test.ts +2 -4
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +20 -29
- package/src/daemon/channel-ui-capability.ts +4 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +117 -61
- package/src/daemon/conversation-agent-loop.ts +318 -148
- package/src/daemon/conversation-attachments.ts +1 -1
- package/src/daemon/conversation-error.ts +8 -1
- package/src/daemon/conversation-initial-prompt.ts +16 -38
- package/src/daemon/conversation-lifecycle.ts +154 -32
- package/src/daemon/conversation-messaging.ts +106 -43
- package/src/daemon/conversation-process.ts +131 -33
- package/src/daemon/conversation-queue-manager.ts +10 -0
- package/src/daemon/conversation-runtime-assembly.ts +9 -4
- package/src/daemon/conversation-store.ts +52 -3
- package/src/daemon/conversation-surface-state.ts +9 -0
- package/src/daemon/conversation-surfaces.ts +403 -210
- package/src/daemon/conversation-tool-setup.ts +56 -7
- package/src/daemon/conversation-turn-finalize.ts +134 -89
- package/src/daemon/conversation.ts +111 -27
- package/src/daemon/disk-pressure-guard-lifecycle.ts +2 -2
- package/src/daemon/disk-pressure-guard.ts +3 -3
- package/src/daemon/doordash-steps.ts +5 -5
- package/src/daemon/external-plugins-bootstrap.ts +7 -1
- package/src/daemon/handlers/config-channels.ts +48 -5
- package/src/daemon/handlers/conversation-history.ts +1 -1
- package/src/daemon/handlers/conversations.ts +62 -17
- package/src/daemon/handlers/shared.ts +12 -0
- package/src/daemon/handlers/skills.ts +11 -1
- package/src/daemon/identity-helpers.ts +38 -10
- package/src/daemon/install-assistant-command.ts +322 -0
- package/src/daemon/lifecycle.ts +14 -3
- package/src/daemon/message-types/conversations.ts +6 -7
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/persist-media-references.ts +23 -14
- package/src/daemon/process-message.ts +6 -6
- package/src/daemon/tool-setup-types.ts +19 -122
- package/src/daemon/tool-side-effects.ts +17 -94
- package/src/daemon/trust-context-types.ts +39 -0
- package/src/daemon/trust-context.ts +14 -6
- package/src/daemon/turn-tail-chain.ts +73 -0
- package/src/daemon/web-search-history.ts +47 -33
- package/src/heartbeat/heartbeat-service.ts +6 -6
- package/src/ipc/__tests__/socket-path.test.ts +21 -0
- package/src/ipc/assistant-server.ts +17 -10
- package/src/ipc/cli-client.ts +10 -1
- package/src/ipc/routes/__tests__/documents-sync-ipc-routes.test.ts +56 -0
- package/src/ipc/routes/documents-sync-ipc-routes.ts +42 -0
- package/src/ipc/socket-cleanup.ts +9 -7
- package/src/ipc/socket-path.ts +4 -96
- package/src/live-voice/__tests__/live-voice-archive.test.ts +16 -16
- package/src/live-voice/__tests__/live-voice-attach-image.test.ts +209 -0
- package/src/live-voice/__tests__/live-voice-connection.test.ts +20 -0
- package/src/live-voice/__tests__/live-voice-integration.test.ts +7 -5
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +265 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +6 -1
- package/src/live-voice/__tests__/live-voice-vad.test.ts +35 -15
- package/src/live-voice/__tests__/protocol.test.ts +52 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +3 -0
- package/src/live-voice/live-voice-archive.ts +13 -13
- package/src/live-voice/live-voice-connection.ts +7 -1
- package/src/live-voice/live-voice-photo.ts +169 -0
- package/src/live-voice/live-voice-session.ts +108 -4
- package/src/live-voice/protocol.ts +89 -1
- package/src/mcp/client.ts +10 -0
- package/src/messaging/providers/__tests__/callback-routing.test.ts +5 -1
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +66 -4
- package/src/messaging/providers/callback-routing.ts +1 -0
- package/src/messaging/providers/discord/api.ts +312 -0
- package/src/messaging/providers/discord/dm-delivery.test.ts +204 -0
- package/src/messaging/providers/discord/render.test.ts +204 -0
- package/src/messaging/providers/discord/render.ts +195 -0
- package/src/messaging/providers/discord/send.test.ts +179 -0
- package/src/messaging/providers/discord/send.ts +212 -0
- package/src/messaging/providers/discord/transport.ts +81 -0
- package/src/messaging/providers/index.ts +3 -1
- package/src/messaging/providers/retry-policy.test.ts +247 -0
- package/src/messaging/providers/retry-policy.ts +206 -0
- package/src/messaging/providers/slack/mention-source.test.ts +285 -0
- package/src/messaging/providers/slack/mention-source.ts +287 -0
- package/src/messaging/providers/telegram-bot/api.ts +47 -130
- package/src/messaging/providers/whatsapp/api.ts +47 -136
- package/src/monitoring/__tests__/db-integrity-sample.test.ts +4 -1
- package/src/monitoring/__tests__/plugin-auto-update.test.ts +332 -0
- package/src/monitoring/db-integrity-sample.ts +6 -1
- package/src/monitoring/plugin-auto-update.ts +359 -0
- package/src/monitoring/resource-sampler.ts +21 -5
- package/src/monitoring/worker.ts +13 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +375 -2
- package/src/notifications/__tests__/broadcaster.test.ts +37 -1
- package/src/notifications/__tests__/copy-composer.test.ts +165 -0
- package/src/notifications/__tests__/emit-signal-pipeline-failure.test.ts +205 -0
- package/src/notifications/__tests__/notification-utils.test.ts +249 -0
- package/src/notifications/adapters/platform.ts +31 -2
- package/src/notifications/assistant-reply-producer.ts +79 -32
- package/src/notifications/broadcaster.ts +30 -10
- package/src/notifications/copy-composer.ts +69 -0
- package/src/notifications/emit-signal.ts +82 -15
- package/src/notifications/events-store.ts +10 -2
- package/src/notifications/home-feed-side-effect.ts +6 -3
- package/src/notifications/notification-utils.ts +173 -5
- package/src/notifications/signal.ts +12 -0
- package/src/oauth/AGENTS.md +4 -2
- package/src/oauth/byo-connection.ts +6 -1
- package/src/oauth/credential-token-resolver.ts +3 -10
- package/src/oauth/manual-token-connection.ts +29 -64
- package/src/oauth/manual-token-providers.ts +62 -0
- package/src/oauth/provider-serializer.ts +13 -0
- package/src/oauth/seed-providers.ts +62 -11
- package/src/onboarding/onboarding-events-store.ts +91 -1
- package/src/permissions/question-prompter.test.ts +4 -0
- package/src/permissions/question-prompter.ts +21 -4
- package/src/persistence/__tests__/conversation-lineage.test.ts +248 -0
- package/src/persistence/attachments-store.ts +15 -15
- package/src/persistence/conversation-attention-store.ts +30 -10
- package/src/persistence/conversation-bootstrap.ts +17 -0
- package/src/persistence/conversation-crud.ts +363 -97
- package/src/persistence/conversation-group-migration.ts +1 -1
- package/src/persistence/conversation-key-store.ts +38 -10
- package/src/persistence/conversation-lineage.ts +226 -0
- package/src/persistence/conversation-plugin-facade.ts +28 -3
- package/src/persistence/conversation-queries.ts +207 -33
- package/src/persistence/conversation-types.ts +107 -1
- package/src/persistence/jobs-store.ts +32 -8
- package/src/persistence/llm-usage-store.ts +22 -0
- package/src/persistence/migrations/361-normalize-managed-connection-rows.test.ts +168 -0
- package/src/persistence/migrations/361-normalize-managed-connection-rows.ts +76 -0
- package/src/persistence/migrations/362-add-conversation-subagent-kind.test.ts +187 -0
- package/src/persistence/migrations/362-add-conversation-subagent-kind.ts +93 -0
- package/src/persistence/migrations/363-backfill-schedule-inference-profile.test.ts +229 -0
- package/src/persistence/migrations/363-backfill-schedule-inference-profile.ts +127 -0
- package/src/persistence/migrations/364-add-schedule-source-key.test.ts +120 -0
- package/src/persistence/migrations/364-add-schedule-source-key.ts +43 -0
- package/src/persistence/migrations/365-add-conversation-fork-strategy.ts +27 -0
- package/src/persistence/schema/conversations.ts +32 -0
- package/src/persistence/schema/infrastructure.ts +3 -0
- package/src/persistence/steps.ts +30 -0
- package/src/persistence/subagent-store.ts +148 -6
- package/src/platform/managed-speech.test.ts +20 -0
- package/src/platform/managed-speech.ts +9 -0
- package/src/plugin-api/index.ts +8 -0
- package/src/plugin-api/webhook-url.ts +151 -0
- package/src/plugins/__tests__/installed-plugin-dirs.test.ts +82 -0
- package/src/plugins/__tests__/source-fingerprint.test.ts +5 -1
- package/src/plugins/collect-source-versions.ts +4 -27
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +5 -5
- package/src/plugins/defaults/exploration-drift/package.json +1 -1
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +4 -2
- package/src/plugins/defaults/image-recovery/recover.ts +67 -57
- package/src/plugins/defaults/index.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +64 -18
- package/src/plugins/defaults/memory/__tests__/jobs-worker-outcome-contract.test.ts +242 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-retrospective-sweep.test.ts +24 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +48 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +511 -19
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +39 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +493 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +5 -4
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +5 -1
- package/src/plugins/defaults/memory/job-handlers.ts +87 -5
- package/src/plugins/defaults/memory/jobs-worker.ts +60 -6
- package/src/plugins/defaults/memory/memory-retrospective-constants.ts +11 -0
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +29 -0
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +342 -60
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +23 -3
- package/src/plugins/defaults/memory/substrate/consolidation-lock.ts +9 -4
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +7 -0
- package/src/plugins/defaults/memory/v1/graph/injection.ts +1 -1
- package/src/plugins/defaults/memory/v2/router.ts +8 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +1 -2
- package/src/plugins/external-plugin-loader.ts +17 -8
- package/src/plugins/installed-plugin-dirs.ts +101 -0
- package/src/plugins/mtime-cache.ts +34 -22
- package/src/plugins/types.ts +69 -8
- package/src/prompts/persona-resolver.ts +6 -2
- package/src/prompts/system-prompt.ts +72 -17
- package/src/providers/__tests__/inference.test.ts +40 -0
- package/src/providers/__tests__/preflight-resolved-config.test.ts +58 -1
- package/src/providers/__tests__/retry-callsite.test.ts +67 -0
- package/src/providers/__tests__/vellum-connection-routing.test.ts +42 -11
- package/src/providers/anthropic/client.ts +112 -95
- package/src/providers/connection-resolution.ts +35 -1
- package/src/providers/gemini/client.ts +5 -5
- package/src/providers/inference/adapter-factory.ts +16 -10
- package/src/providers/inference/auth.ts +16 -0
- package/src/providers/inference/connection-availability.ts +164 -12
- package/src/providers/inference/connections.ts +25 -1
- package/src/providers/media-resolve.ts +21 -11
- package/src/providers/model-catalog.ts +15 -0
- package/src/providers/openai/chat-completions-provider.ts +4 -4
- package/src/providers/openai/responses-provider.ts +12 -25
- package/src/providers/registry.ts +9 -4
- package/src/providers/retry.ts +25 -0
- package/src/providers/server-tool-pairing.ts +134 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +187 -6
- package/src/providers/speech-to-text/deepgram.ts +1 -0
- package/src/providers/speech-to-text/resolve.ts +80 -10
- package/src/providers/speech-to-text/vellum-managed.ts +7 -1
- package/src/providers/speech-to-text/vellum-speech-relay-connection.ts +3 -1
- package/src/providers/types.ts +26 -6
- package/src/providers/vellum-model-routing.ts +6 -7
- package/src/runtime/AGENTS.md +2 -0
- package/src/runtime/__tests__/agent-wake.test.ts +16 -16
- package/src/runtime/__tests__/background-job-runner.test.ts +0 -144
- package/src/runtime/__tests__/desktop-presence.test.ts +162 -0
- package/src/runtime/agent-wake.ts +63 -24
- package/src/runtime/assistant-event-hub.ts +87 -12
- package/src/runtime/auth/__tests__/guard-tests.test.ts +2 -0
- package/src/runtime/auth/__tests__/scopes.test.ts +20 -0
- package/src/runtime/auth/same-actor.ts +56 -8
- package/src/runtime/auth/scopes.ts +12 -0
- package/src/runtime/auth/types.ts +2 -0
- package/src/runtime/background-job-runner.ts +5 -27
- package/src/runtime/channel-readiness-service.ts +59 -3
- package/src/runtime/channel-readiness-types.ts +18 -0
- package/src/runtime/desktop-presence.ts +69 -0
- package/src/runtime/http-server.ts +12 -0
- package/src/runtime/local-actor-identity.ts +11 -9
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/client-routes.test.ts +186 -14
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +547 -1
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +162 -7
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +14 -10
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +340 -3
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +28 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +173 -1
- package/src/runtime/routes/__tests__/question-routes.test.ts +64 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +20 -0
- package/src/runtime/routes/__tests__/skill-history-route.test.ts +116 -0
- package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +60 -2
- package/src/runtime/routes/archive-utils.ts +16 -12
- package/src/runtime/routes/attachment-routes.ts +13 -6
- package/src/runtime/routes/canned-reply-release.ts +54 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -27
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +5 -0
- package/src/runtime/routes/client-routes.ts +114 -2
- package/src/runtime/routes/conversation-cli-routes.ts +10 -12
- package/src/runtime/routes/conversation-list-routes.ts +59 -10
- package/src/runtime/routes/conversation-management-routes.ts +47 -18
- package/src/runtime/routes/conversation-query-routes.ts +32 -53
- package/src/runtime/routes/conversation-routes.ts +360 -293
- package/src/runtime/routes/credential-prompt-routes.ts +23 -2
- package/src/runtime/routes/debug-routes.ts +4 -1
- package/src/runtime/routes/default-provider-routes.ts +7 -11
- package/src/runtime/routes/documents-routes.ts +44 -1
- package/src/runtime/routes/events-routes.ts +28 -1
- package/src/runtime/routes/host-app-control-routes.ts +2 -0
- package/src/runtime/routes/host-bash-routes.ts +2 -0
- package/src/runtime/routes/host-browser-routes.ts +2 -0
- package/src/runtime/routes/host-cu-routes.ts +2 -0
- package/src/runtime/routes/host-file-routes.ts +2 -0
- package/src/runtime/routes/host-transfer-routes.ts +4 -0
- package/src/runtime/routes/identity-routes.ts +6 -6
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +7 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +14 -0
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +14 -11
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -17
- package/src/runtime/routes/inference-profile-availability-guard.ts +171 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +26 -2
- package/src/runtime/routes/inference-profile-session-routes.ts +2 -1
- package/src/runtime/routes/inference-profiles-routes.ts +152 -73
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -16
- package/src/runtime/routes/llm-call-sites-routes.ts +13 -0
- package/src/runtime/routes/log-export-routes.ts +1 -1
- package/src/runtime/routes/notification-routes.ts +0 -14
- package/src/runtime/routes/oauth-providers.ts +1 -0
- package/src/runtime/routes/plugins-routes.ts +106 -1
- package/src/runtime/routes/profiler-routes.ts +4 -2
- package/src/runtime/routes/question-routes.ts +28 -10
- package/src/runtime/routes/retrospective-routes.ts +9 -3
- package/src/runtime/routes/schedule-routes.ts +210 -12
- package/src/runtime/routes/secret-routes.ts +40 -23
- package/src/runtime/routes/settings-routes.ts +41 -13
- package/src/runtime/routes/skills-routes.ts +79 -0
- package/src/runtime/routes/ui-snapshot-routes.ts +1 -0
- package/src/runtime/routes/wake-conversation-routes.ts +23 -0
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +1 -0
- package/src/runtime/services/conversation-serializer.ts +24 -9
- package/src/runtime/sync/documents-sidecar-publish.test.ts +101 -0
- package/src/runtime/sync/resource-sync-events.ts +79 -1
- package/src/runtime/sync/worker-daemon-notify.test.ts +34 -0
- package/src/runtime/sync/worker-daemon-notify.ts +44 -6
- package/src/runtime/verification-outbound-actions.ts +250 -222
- package/src/runtime/verification-templates.ts +41 -30
- package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +614 -0
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1066 -0
- package/src/schedule/inference-profile.ts +64 -3
- package/src/schedule/plugin-schedule-declarations.ts +518 -0
- package/src/schedule/plugin-schedule-reconciler.ts +605 -0
- package/src/schedule/plugin-schedules-gate.ts +23 -0
- package/src/schedule/schedule-store.ts +520 -26
- package/src/schedule/scheduler.ts +38 -0
- package/src/security/credential-backend.ts +51 -4
- package/src/security/encrypted-store.ts +64 -42
- package/src/security/secure-keys.ts +55 -7
- package/src/skills/catalog-install.ts +20 -7
- package/src/skills/inline-command-runner.ts +2 -7
- package/src/skills/skill-history.test.ts +269 -0
- package/src/skills/skill-history.ts +250 -0
- package/src/skills/skillssh-registry.ts +1 -1
- package/src/stt/daemon-batch-transcriber.ts +8 -6
- package/src/subagent/__tests__/consult-prompt.test.ts +25 -0
- package/src/subagent/consult-prompt.ts +3 -1
- package/src/subagent/consult-transcript.ts +1 -1
- package/src/subagent/manager.ts +304 -44
- package/src/subagent/progress-events.ts +35 -0
- package/src/subagent/role-resolution.ts +88 -0
- package/src/subagent/types.ts +302 -67
- package/src/subagent/validate-allowlists.ts +3 -4
- package/src/telegram/__tests__/webhook-health.test.ts +73 -1
- package/src/telegram/webhook-health.ts +101 -3
- package/src/telemetry/__tests__/telemetry-event-fixtures.ts +2 -0
- package/src/telemetry/activation-funnel.ts +6 -1
- package/src/telemetry/live-voice-funnel.ts +75 -0
- package/src/telemetry/telemetry-event-sources.ts +6 -0
- package/src/telemetry/telemetry-wire-source.json +1 -1
- package/src/telemetry/telemetry-wire.generated.ts +2 -0
- package/src/telemetry/types.ts +23 -4
- package/src/telemetry/usage-telemetry-reporter.test.ts +4 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +1 -1
- package/src/tools/ask-question/ask-question-tool.test.ts +118 -3
- package/src/tools/ask-question/ask-question-tool.ts +56 -2
- package/src/tools/browser/browser-execution.ts +1 -1
- package/src/tools/calls/call-start.ts +8 -5
- package/src/tools/conversation-groups/move_to_group.ts +10 -12
- package/src/tools/document/document-tool.ts +11 -4
- package/src/tools/execution-timeout.ts +9 -2
- package/src/tools/executor.ts +7 -6
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +7 -13
- package/src/tools/filesystem/search.ts +23 -21
- package/src/tools/filesystem/write.ts +4 -1
- package/src/tools/host-filesystem/edit.ts +7 -2
- package/src/tools/host-filesystem/read.ts +21 -8
- package/src/tools/host-filesystem/write.ts +10 -2
- package/src/tools/host-terminal/host-shell.ts +2 -2
- package/src/tools/mcp/mcp-tool-factory.ts +25 -1
- package/src/tools/permission-checker.ts +8 -3
- package/src/tools/schedule/delete.ts +13 -1
- package/src/tools/schedule/list.ts +14 -3
- package/src/tools/schedule/update.ts +56 -33
- package/src/tools/shared/filesystem/audio-read.ts +6 -4
- package/src/tools/shared/filesystem/file-ops-service.ts +176 -116
- package/src/tools/shared/filesystem/image-read.ts +12 -12
- package/src/tools/shared/filesystem/path-policy.ts +70 -5
- package/src/tools/shared/filesystem/size-guard.ts +6 -6
- package/src/tools/shared/input-misuse.ts +72 -0
- package/src/tools/skills/scaffold-managed.ts +82 -0
- package/src/tools/skills/skill-tool-factory.ts +14 -1
- package/src/tools/subagent/consult-deadline.ts +12 -7
- package/src/tools/subagent/message.ts +3 -1
- package/src/tools/subagent/read.ts +66 -4
- package/src/tools/subagent/spawn.ts +500 -78
- package/src/tools/tool-approval-handler.ts +45 -4
- package/src/tools/types.ts +22 -3
- package/src/tools/ui-surface/surface-shape-docs.ts +1 -1
- package/src/tools/ui-surface/visual-validation.ts +2 -0
- package/src/usage/__tests__/subagent-attribution.test.ts +109 -0
- package/src/usage/subagent-attribution.ts +108 -0
- package/src/util/__tests__/sqlite-retry.test.ts +112 -0
- package/src/util/abort-reasons.ts +16 -0
- package/src/util/ansi.ts +44 -0
- package/src/util/disk-usage.ts +17 -13
- package/src/util/image-conversion.ts +20 -13
- package/src/util/schedule-source-key.ts +23 -0
- package/src/util/worker-process.ts +7 -1
- package/src/workspace/git-service.ts +33 -9
- package/src/workspace/migrations/140-repair-seed-pinned-memory-v3-live.ts +260 -0
- package/src/workspace/migrations/141-stt-english-default-to-multilingual.ts +111 -0
- package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +126 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/workspace/top-level-renderer.ts +15 -2
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +0 -357
- package/src/daemon/install-symlink.ts +0 -207
- package/src/notifications/deferred-emit.ts +0 -147
|
@@ -1,36 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared availability computation for a (provider, connection) pair: whether
|
|
3
3
|
* the connection exists, carries a usable credential, and can actually serve
|
|
4
|
-
* the provider.
|
|
4
|
+
* the provider.
|
|
5
|
+
*
|
|
6
|
+
* On read paths the status is reported, not enforced — a dangling or
|
|
5
7
|
* uncredentialed connection is a valid persisted state that surfaces an
|
|
6
|
-
* explainable error at dispatch time.
|
|
8
|
+
* explainable error at dispatch time. The dedicated inference-profile write
|
|
9
|
+
* routes (create / update / set-active / conversation-scoped pin) are the
|
|
10
|
+
* exception: they refuse to persist a selection that provably cannot dispatch,
|
|
11
|
+
* because those writes are what a chat turn resolves through. Generic
|
|
12
|
+
* `config set` writes and dispatch itself stay report-only.
|
|
7
13
|
*
|
|
8
14
|
* Consumed by the default-provider status route (`llm.defaultProvider`) and
|
|
9
|
-
* the inference-profile
|
|
10
|
-
*
|
|
15
|
+
* the inference-profile routes (per-profile availability) so the two never
|
|
16
|
+
* drift.
|
|
11
17
|
*/
|
|
12
18
|
|
|
13
19
|
import { getDb } from "../../persistence/db-connection.js";
|
|
14
20
|
import { credentialKey } from "../../security/credential-key.js";
|
|
15
21
|
import { getSecureKeyResultAsync } from "../../security/secure-keys.js";
|
|
22
|
+
import {
|
|
23
|
+
describeSubscriptionModelIncompatibility,
|
|
24
|
+
isConnectionCompatibleWithModel,
|
|
25
|
+
} from "../connection-model-compat.js";
|
|
16
26
|
import { PROVIDER_CATALOG } from "../model-catalog.js";
|
|
17
27
|
import { resolveManagedProxyContext } from "../platform-proxy/context.js";
|
|
28
|
+
import {
|
|
29
|
+
ConnectionResolutionError,
|
|
30
|
+
resolveRoutingIdentity,
|
|
31
|
+
} from "../routing-identity.js";
|
|
18
32
|
import {
|
|
19
33
|
isVellumManagedConnection,
|
|
20
34
|
MANAGED_ROUTABLE_PROVIDERS,
|
|
21
35
|
VELLUM_MANAGED_CONNECTION_NAME,
|
|
22
36
|
VELLUM_MANAGED_PROVIDER,
|
|
23
37
|
} from "../vellum-model-routing.js";
|
|
24
|
-
import {
|
|
38
|
+
import { ROUTING_IDENTITY_PROVIDERS } from "./auth.js";
|
|
39
|
+
import { getConnection, listConnections } from "./connections.js";
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Every availability verdict, in one place. Route schemas build their zod
|
|
43
|
+
* enums from this rather than restating it, so a new status reaches the wire
|
|
44
|
+
* for every surface at once instead of drifting between them.
|
|
45
|
+
*/
|
|
46
|
+
export const CONNECTION_AVAILABILITY_STATUSES = [
|
|
47
|
+
"ok",
|
|
48
|
+
"incomplete",
|
|
49
|
+
"missing_connection",
|
|
50
|
+
"missing_credential",
|
|
51
|
+
"provider_mismatch",
|
|
52
|
+
"unsupported_auth",
|
|
53
|
+
"vellum_unauthenticated",
|
|
54
|
+
"unknown",
|
|
55
|
+
] as const;
|
|
25
56
|
|
|
26
57
|
export type ConnectionAvailabilityStatus =
|
|
27
|
-
|
|
28
|
-
| "missing_connection"
|
|
29
|
-
| "missing_credential"
|
|
30
|
-
| "provider_mismatch"
|
|
31
|
-
| "unsupported_auth"
|
|
32
|
-
| "vellum_unauthenticated"
|
|
33
|
-
| "unknown";
|
|
58
|
+
(typeof CONNECTION_AVAILABILITY_STATUSES)[number];
|
|
34
59
|
|
|
35
60
|
export interface ConnectionAvailability {
|
|
36
61
|
status: ConnectionAvailabilityStatus;
|
|
@@ -204,3 +229,130 @@ export async function computeConnectionAvailability(
|
|
|
204
229
|
}
|
|
205
230
|
}
|
|
206
231
|
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Statuses that mean a profile provably cannot serve a request. `unknown` is
|
|
235
|
+
* excluded on purpose: it means the credential store could not be reached, not
|
|
236
|
+
* that the credential is absent, and treating a CES outage as a broken profile
|
|
237
|
+
* would block writes that are actually fine.
|
|
238
|
+
*/
|
|
239
|
+
const UNAVAILABLE_STATUSES: ReadonlySet<ConnectionAvailabilityStatus> = new Set(
|
|
240
|
+
[
|
|
241
|
+
// A profile with no provider and model of its own is skipped by the
|
|
242
|
+
// resolver on every turn, so it provably cannot serve a request. It
|
|
243
|
+
// belongs here for the same reason the connection failures do: pinning
|
|
244
|
+
// one silently runs a different profile than the user selected.
|
|
245
|
+
"incomplete",
|
|
246
|
+
"missing_connection",
|
|
247
|
+
"missing_credential",
|
|
248
|
+
"provider_mismatch",
|
|
249
|
+
"unsupported_auth",
|
|
250
|
+
"vellum_unauthenticated",
|
|
251
|
+
],
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
/** Whether an availability verdict means dispatch would provably fail. */
|
|
255
|
+
export function isUnavailable(
|
|
256
|
+
availability: ConnectionAvailability | null,
|
|
257
|
+
): boolean {
|
|
258
|
+
return availability !== null && UNAVAILABLE_STATUSES.has(availability.status);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Availability of a whole effective profile entry, judged the way dispatch
|
|
263
|
+
* judges it:
|
|
264
|
+
*
|
|
265
|
+
* - routing identities (`vellum`, `chatgpt`) resolve to their canonical row
|
|
266
|
+
* and derived upstream;
|
|
267
|
+
* - a pinned `provider_connection` is judged directly;
|
|
268
|
+
* - a provider with no pinned connection is judged against the connection
|
|
269
|
+
* dispatch would auto-resolve (an active, model-compatible row for that
|
|
270
|
+
* provider) — with no such row, the profile cannot serve requests.
|
|
271
|
+
*
|
|
272
|
+
* Returns null when there is nothing to judge: a mix carries no provider or
|
|
273
|
+
* model of its own, because the resolver expands it to a seeded arm and
|
|
274
|
+
* judges that arm instead.
|
|
275
|
+
*/
|
|
276
|
+
export async function computeProfileAvailability(
|
|
277
|
+
entry: Record<string, unknown>,
|
|
278
|
+
): Promise<ConnectionAvailability | null> {
|
|
279
|
+
const provider = entry.provider;
|
|
280
|
+
const model = typeof entry.model === "string" ? entry.model : undefined;
|
|
281
|
+
|
|
282
|
+
// A rung only wins if its profile carries BOTH a provider and a model (see
|
|
283
|
+
// `usableEntry` in config/llm-resolver.ts); one without them is skipped as
|
|
284
|
+
// "incomplete" and the call site quietly resolves elsewhere. Report that so
|
|
285
|
+
// clients can show it rather than presenting the profile as healthy.
|
|
286
|
+
if (typeof provider !== "string" || model === undefined) {
|
|
287
|
+
if (entry.mix != null) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
const missing =
|
|
291
|
+
typeof provider !== "string"
|
|
292
|
+
? model === undefined
|
|
293
|
+
? "a provider and a model"
|
|
294
|
+
: "a provider"
|
|
295
|
+
: "a model";
|
|
296
|
+
// Which profile a call site falls back to depends on the call site (its
|
|
297
|
+
// shipped intent, then the balanced anchor), so this names the effect
|
|
298
|
+
// without claiming a destination it cannot know.
|
|
299
|
+
return {
|
|
300
|
+
status: "incomplete",
|
|
301
|
+
message: `Missing ${missing}, so actions using it fall back to another profile.`,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Routing-identity profiles carry no provider_connection. A model the
|
|
306
|
+
// identity cannot route reports as a mismatch rather than throwing —
|
|
307
|
+
// availability annotates, it must not fail the profiles read.
|
|
308
|
+
if (ROUTING_IDENTITY_PROVIDERS.has(provider)) {
|
|
309
|
+
try {
|
|
310
|
+
const identity = resolveRoutingIdentity(provider, model);
|
|
311
|
+
if (!identity) {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
return await computeConnectionAvailability(
|
|
315
|
+
identity.expectedProvider,
|
|
316
|
+
identity.connectionName,
|
|
317
|
+
);
|
|
318
|
+
} catch (err) {
|
|
319
|
+
return {
|
|
320
|
+
status: "provider_mismatch",
|
|
321
|
+
message:
|
|
322
|
+
err instanceof ConnectionResolutionError
|
|
323
|
+
? err.message
|
|
324
|
+
: `Model "${model ?? "<unset>"}" cannot be routed by provider "${provider}".`,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const pinned = entry.provider_connection;
|
|
330
|
+
if (typeof pinned === "string") {
|
|
331
|
+
return computeConnectionAvailability(provider, pinned);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Mirror the dispatch-time auto-resolve (`resolveConfiguredProvider`): with
|
|
335
|
+
// no pinned connection, the first active model-compatible row for the
|
|
336
|
+
// provider serves the request, and none means dispatch returns no provider.
|
|
337
|
+
let candidates;
|
|
338
|
+
try {
|
|
339
|
+
candidates = listConnections(getDb(), { provider });
|
|
340
|
+
} catch {
|
|
341
|
+
return {
|
|
342
|
+
status: "unknown",
|
|
343
|
+
message: `Connections for provider "${provider}" could not be looked up. Try again shortly.`,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
const active = candidates.find((candidate) =>
|
|
347
|
+
isConnectionCompatibleWithModel(candidate, model),
|
|
348
|
+
);
|
|
349
|
+
if (active) {
|
|
350
|
+
return computeConnectionAvailability(provider, active.name);
|
|
351
|
+
}
|
|
352
|
+
return {
|
|
353
|
+
status: "missing_connection",
|
|
354
|
+
message:
|
|
355
|
+
describeSubscriptionModelIncompatibility(candidates, model) ??
|
|
356
|
+
`Provider "${provider}" is a valid provider id, but no ${provider} connection/API key is configured, so this profile cannot serve requests.`,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
@@ -163,6 +163,14 @@ export type CreateConnectionInput = {
|
|
|
163
163
|
|
|
164
164
|
export type UpdateConnectionInput = {
|
|
165
165
|
auth: Auth;
|
|
166
|
+
/**
|
|
167
|
+
* Optional provider correction. The HTTP PATCH route never passes this
|
|
168
|
+
* (provider is immutable there); it exists for owners of well-known rows
|
|
169
|
+
* to keep the provider truthful when they rewrite the auth, e.g. the
|
|
170
|
+
* ChatGPT sign-in flow stamping "openai" on the subscription row so a
|
|
171
|
+
* claiming row with a different provider cannot strand the fresh token.
|
|
172
|
+
*/
|
|
173
|
+
provider?: string;
|
|
166
174
|
label?: string | null;
|
|
167
175
|
baseUrl?: string | null;
|
|
168
176
|
models?: ConnectionModel[] | null;
|
|
@@ -178,6 +186,7 @@ export type ConnectionCreateError =
|
|
|
178
186
|
export type ConnectionUpdateError =
|
|
179
187
|
| { code: "not_found" }
|
|
180
188
|
| { code: "invalid_auth" }
|
|
189
|
+
| { code: "invalid_provider"; provider: string }
|
|
181
190
|
| { code: "base_url_required" }
|
|
182
191
|
| { code: "models_required" };
|
|
183
192
|
|
|
@@ -278,12 +287,23 @@ export function updateConnection(
|
|
|
278
287
|
return { ok: false, error: { code: "invalid_auth" } };
|
|
279
288
|
}
|
|
280
289
|
|
|
290
|
+
if (
|
|
291
|
+
input.provider !== undefined &&
|
|
292
|
+
!VALID_CONNECTION_PROVIDERS.includes(input.provider as never)
|
|
293
|
+
) {
|
|
294
|
+
return {
|
|
295
|
+
ok: false,
|
|
296
|
+
error: { code: "invalid_provider", provider: input.provider },
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
const nextProvider = input.provider ?? existing.provider;
|
|
300
|
+
|
|
281
301
|
const nextBaseUrl =
|
|
282
302
|
input.baseUrl !== undefined ? input.baseUrl : existing.baseUrl;
|
|
283
303
|
const nextModels =
|
|
284
304
|
input.models !== undefined ? input.models : existing.models;
|
|
285
305
|
|
|
286
|
-
if (PROVIDERS_REQUIRING_BASE_URL_AND_MODELS.has(
|
|
306
|
+
if (PROVIDERS_REQUIRING_BASE_URL_AND_MODELS.has(nextProvider)) {
|
|
287
307
|
if (!nextBaseUrl) {
|
|
288
308
|
return { ok: false, error: { code: "base_url_required" } };
|
|
289
309
|
}
|
|
@@ -296,10 +316,14 @@ export function updateConnection(
|
|
|
296
316
|
const setClause: {
|
|
297
317
|
auth: string;
|
|
298
318
|
updatedAt: number;
|
|
319
|
+
provider?: string;
|
|
299
320
|
label?: string | null;
|
|
300
321
|
baseUrl?: string | null;
|
|
301
322
|
models?: string | null;
|
|
302
323
|
} = { auth: JSON.stringify(auth), updatedAt: now };
|
|
324
|
+
if (input.provider !== undefined) {
|
|
325
|
+
setClause.provider = input.provider;
|
|
326
|
+
}
|
|
303
327
|
if (input.label !== undefined) {
|
|
304
328
|
setClause.label = input.label;
|
|
305
329
|
}
|
|
@@ -96,7 +96,7 @@ export function resolveMediaSourceData(
|
|
|
96
96
|
return { data: bytes.toString("base64"), media_type: source.media_type };
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
function resolveImageBlock(block: ImageContent): ContentBlock {
|
|
99
|
+
async function resolveImageBlock(block: ImageContent): Promise<ContentBlock> {
|
|
100
100
|
if (block.source.type === "base64") {
|
|
101
101
|
return block;
|
|
102
102
|
}
|
|
@@ -113,7 +113,7 @@ function resolveImageBlock(block: ImageContent): ContentBlock {
|
|
|
113
113
|
}
|
|
114
114
|
// Apply the same transport optimization the inline-base64 path used, so a
|
|
115
115
|
// reloaded (reference) turn sends the model the same bytes a live turn would.
|
|
116
|
-
const { data, mediaType } = optimizeImageForTransport(
|
|
116
|
+
const { data, mediaType } = await optimizeImageForTransport(
|
|
117
117
|
bytes.toString("base64"),
|
|
118
118
|
block.source.media_type,
|
|
119
119
|
);
|
|
@@ -161,7 +161,7 @@ function resolveFileBlock(block: FileContent): ContentBlock {
|
|
|
161
161
|
};
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
function resolveBlock(block: ContentBlock): ContentBlock {
|
|
164
|
+
async function resolveBlock(block: ContentBlock): Promise<ContentBlock> {
|
|
165
165
|
switch (block.type) {
|
|
166
166
|
case "image":
|
|
167
167
|
return resolveImageBlock(block);
|
|
@@ -172,7 +172,10 @@ function resolveBlock(block: ContentBlock): ContentBlock {
|
|
|
172
172
|
if (!block.contentBlocks?.length) {
|
|
173
173
|
return block;
|
|
174
174
|
}
|
|
175
|
-
return {
|
|
175
|
+
return {
|
|
176
|
+
...block,
|
|
177
|
+
contentBlocks: await Promise.all(block.contentBlocks.map(resolveBlock)),
|
|
178
|
+
};
|
|
176
179
|
}
|
|
177
180
|
default:
|
|
178
181
|
return block;
|
|
@@ -197,11 +200,18 @@ function contentHasReference(content: ContentBlock[]): boolean {
|
|
|
197
200
|
* (same object reference) so the common all-base64 live turn does no allocation
|
|
198
201
|
* or disk I/O.
|
|
199
202
|
*/
|
|
200
|
-
export function resolveMediaReferences(
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
203
|
+
export function resolveMediaReferences(
|
|
204
|
+
messages: Message[],
|
|
205
|
+
): Promise<Message[]> {
|
|
206
|
+
return Promise.all(
|
|
207
|
+
messages.map(async (message) => {
|
|
208
|
+
if (!contentHasReference(message.content)) {
|
|
209
|
+
return message;
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
...message,
|
|
213
|
+
content: await Promise.all(message.content.map(resolveBlock)),
|
|
214
|
+
};
|
|
215
|
+
}),
|
|
216
|
+
);
|
|
207
217
|
}
|
|
@@ -2233,6 +2233,21 @@ export function getCatalogProviderForModel(
|
|
|
2233
2233
|
?.id;
|
|
2234
2234
|
}
|
|
2235
2235
|
|
|
2236
|
+
/**
|
|
2237
|
+
* Human-readable display name for a model id, from the first catalog entry
|
|
2238
|
+
* that serves it (a model carries the same display name under every provider
|
|
2239
|
+
* that offers it). Undefined for uncataloged ids.
|
|
2240
|
+
*/
|
|
2241
|
+
export function getModelDisplayName(modelId: string): string | undefined {
|
|
2242
|
+
for (const provider of PROVIDER_CATALOG) {
|
|
2243
|
+
const match = provider.models.find((m) => m.id === modelId);
|
|
2244
|
+
if (match) {
|
|
2245
|
+
return match.displayName;
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
return undefined;
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2236
2251
|
/**
|
|
2237
2252
|
* Whether the given model only supports adaptive (always-on) thinking, driven
|
|
2238
2253
|
* by the `adaptiveThinkingOnly` capability in the catalog. Matches the model ID
|
|
@@ -383,7 +383,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
383
383
|
const coercedObjectKeys = new Map<string, string[]>();
|
|
384
384
|
|
|
385
385
|
try {
|
|
386
|
-
const openaiMessages = this.toOpenAIMessages(
|
|
386
|
+
const openaiMessages = await this.toOpenAIMessages(
|
|
387
387
|
messages,
|
|
388
388
|
systemPrompt,
|
|
389
389
|
modelSupportsAudioInput(modelOverride ?? this.model),
|
|
@@ -940,14 +940,14 @@ export class OpenAIChatCompletionsProvider implements Provider {
|
|
|
940
940
|
}
|
|
941
941
|
|
|
942
942
|
/** Convert neutral messages + system prompt to OpenAI message format. */
|
|
943
|
-
private toOpenAIMessages(
|
|
943
|
+
private async toOpenAIMessages(
|
|
944
944
|
messages: Message[],
|
|
945
945
|
systemPrompt?: string,
|
|
946
946
|
audioInputEnabled = false,
|
|
947
|
-
): OpenAI.Chat.Completions.ChatCompletionMessageParam[] {
|
|
947
|
+
): Promise<OpenAI.Chat.Completions.ChatCompletionMessageParam[]> {
|
|
948
948
|
// Swap any persisted attachment references back to inline base64 before
|
|
949
949
|
// serializing, so the block transforms below can read `source.data`.
|
|
950
|
-
messages = resolveMediaReferences(messages);
|
|
950
|
+
messages = await resolveMediaReferences(messages);
|
|
951
951
|
const result: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [];
|
|
952
952
|
|
|
953
953
|
if (systemPrompt) {
|
|
@@ -231,8 +231,6 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
231
231
|
const usageAttributionHeaders = configObj?.usageAttributionHeaders as
|
|
232
232
|
| Record<string, string>
|
|
233
233
|
| undefined;
|
|
234
|
-
const mutableLatestUserMessage =
|
|
235
|
-
configObj?.mutableLatestUserMessage === true;
|
|
236
234
|
const disableCache = configObj?.disableCache === true;
|
|
237
235
|
const disableTurnStartCache = configObj?.disableTurnStartCache === true;
|
|
238
236
|
const promptCacheKey =
|
|
@@ -244,7 +242,7 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
244
242
|
try {
|
|
245
243
|
const effectiveModel = modelOverride ?? this.model;
|
|
246
244
|
recordProviderRequestDiagnostics({ model_id: effectiveModel });
|
|
247
|
-
const input = this.toResponsesInput(messages);
|
|
245
|
+
const input = await this.toResponsesInput(messages);
|
|
248
246
|
|
|
249
247
|
const params: Record<string, unknown> = {
|
|
250
248
|
model: effectiveModel,
|
|
@@ -273,8 +271,8 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
273
271
|
|
|
274
272
|
// Explicit prompt-cache mode (GPT-5.6+ semantics, direct API only).
|
|
275
273
|
// Explicit mode disables the implicit latest-message breakpoint — under
|
|
276
|
-
// implicit mode a volatile latest user message
|
|
277
|
-
//
|
|
274
|
+
// implicit mode a volatile latest user message makes every cached entry
|
|
275
|
+
// end at content that never recurs across turns: zero reads
|
|
278
276
|
// plus a full-prompt 1.25x write per turn. With explicit markers we
|
|
279
277
|
// choose the stable boundaries ourselves. Under `disableCache` we still
|
|
280
278
|
// send explicit mode but stamp no markers: a request with no explicit
|
|
@@ -288,10 +286,7 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
288
286
|
) {
|
|
289
287
|
params.prompt_cache_options = { mode: "explicit" };
|
|
290
288
|
if (!disableCache) {
|
|
291
|
-
this.applyPromptCacheBreakpoints(input, {
|
|
292
|
-
mutableLatestUserMessage,
|
|
293
|
-
disableTurnStartCache,
|
|
294
|
-
});
|
|
289
|
+
this.applyPromptCacheBreakpoints(input, { disableTurnStartCache });
|
|
295
290
|
}
|
|
296
291
|
}
|
|
297
292
|
|
|
@@ -753,10 +748,10 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
753
748
|
*
|
|
754
749
|
* System prompt is NOT included here — it goes into the `instructions` param.
|
|
755
750
|
*/
|
|
756
|
-
private toResponsesInput(messages: Message[]): unknown[] {
|
|
751
|
+
private async toResponsesInput(messages: Message[]): Promise<unknown[]> {
|
|
757
752
|
// Swap any persisted attachment references back to inline base64 before
|
|
758
753
|
// serializing, so the block transforms below can read `source.data`.
|
|
759
|
-
messages = resolveMediaReferences(messages);
|
|
754
|
+
messages = await resolveMediaReferences(messages);
|
|
760
755
|
const result: unknown[] = [];
|
|
761
756
|
|
|
762
757
|
// `call_id`s emitted as `function_call` items earlier in this request.
|
|
@@ -788,8 +783,11 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
788
783
|
* historical user-message boundaries makes the newest still-matching one
|
|
789
784
|
* the read point; in the volatile-latest-message flow that is typically
|
|
790
785
|
* the previous turn's user message once it re-renders without its
|
|
791
|
-
* injected block.
|
|
792
|
-
*
|
|
786
|
+
* injected block. Every markable item is marked, including a volatile
|
|
787
|
+
* latest user message that is the only one on a first turn: a volatile
|
|
788
|
+
* message is still fixed within its own turn, so marking it prepays one
|
|
789
|
+
* write that every in-turn tool-loop iteration reads back, and cross-turn
|
|
790
|
+
* the ladder re-marks whichever boundaries recur. The ladder is
|
|
793
791
|
* cost-safe: OpenAI writes at most the latest four unmatched marked
|
|
794
792
|
* boundaries per request and considers up to the latest 50 markers for
|
|
795
793
|
* reads. All breakpoints share the fixed 30m TTL (no `ttl` field is
|
|
@@ -811,7 +809,7 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
811
809
|
*/
|
|
812
810
|
private applyPromptCacheBreakpoints(
|
|
813
811
|
input: unknown[],
|
|
814
|
-
opts: {
|
|
812
|
+
opts: { disableTurnStartCache: boolean },
|
|
815
813
|
): void {
|
|
816
814
|
const items = input as ResponsesMessageItem[];
|
|
817
815
|
|
|
@@ -866,17 +864,6 @@ export class OpenAIResponsesProvider implements Provider {
|
|
|
866
864
|
return;
|
|
867
865
|
}
|
|
868
866
|
|
|
869
|
-
// A volatile latest user message with no prior user message to anchor
|
|
870
|
-
// on: every marker would be a write whose prefix never recurs across
|
|
871
|
-
// turns — skip caching entirely for this request.
|
|
872
|
-
if (
|
|
873
|
-
opts.mutableLatestUserMessage &&
|
|
874
|
-
candidates.length === 1 &&
|
|
875
|
-
candidates[0] === items.length - 1
|
|
876
|
-
) {
|
|
877
|
-
return;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
867
|
for (const idx of candidates) {
|
|
881
868
|
// `disableTurnStartCache` suppresses the marker on the turn-start
|
|
882
869
|
// (newest user) item — one-shot call sites whose prompts never
|
|
@@ -17,7 +17,10 @@ import {
|
|
|
17
17
|
// Per-connection provider cache (mix-and-match support)
|
|
18
18
|
// ---------------------------------------------------------------------------
|
|
19
19
|
import type { ProviderConnection } from "./inference/auth.js";
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
effectiveConnectionAuth,
|
|
22
|
+
ROUTING_IDENTITY_PROVIDERS,
|
|
23
|
+
} from "./inference/auth.js";
|
|
21
24
|
import { resolveAuth } from "./inference/resolve-auth.js";
|
|
22
25
|
import { isModelInCatalog, PROVIDER_CATALOG } from "./model-catalog.js";
|
|
23
26
|
import { getProviderDefaultModel } from "./model-intents.js";
|
|
@@ -333,9 +336,11 @@ export async function resolveProviderFromConnection(
|
|
|
333
336
|
// re-read from the store below, so a key rotated since the entry was cached
|
|
334
337
|
// is picked up here rather than served stale forever.
|
|
335
338
|
|
|
336
|
-
const authResult = await resolveAuth(
|
|
337
|
-
|
|
338
|
-
|
|
339
|
+
const authResult = await resolveAuth(
|
|
340
|
+
effectiveConnectionAuth(connection),
|
|
341
|
+
effectiveProvider,
|
|
342
|
+
{ baseUrl: connection.baseUrl },
|
|
343
|
+
);
|
|
339
344
|
if (!authResult.ok) {
|
|
340
345
|
const err = authResult.error;
|
|
341
346
|
if (err.code === "not_implemented") {
|
package/src/providers/retry.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
resolveUsageAttribution,
|
|
5
5
|
sanitizeUsageMetadataValue,
|
|
6
6
|
} from "../usage/attribution.js";
|
|
7
|
+
import { resolveSubagentAttribution } from "../usage/subagent-attribution.js";
|
|
7
8
|
import {
|
|
8
9
|
type ProviderCredentialSource,
|
|
9
10
|
ProviderError,
|
|
@@ -49,6 +50,12 @@ const USAGE_ATTRIBUTION_HEADER_NAMES = {
|
|
|
49
50
|
resolvedProvider: "X-Vellum-Resolved-Provider",
|
|
50
51
|
resolvedModel: "X-Vellum-Resolved-Model",
|
|
51
52
|
resolvedMixArm: "X-Vellum-Resolved-Mix-Arm",
|
|
53
|
+
// Delegated-work attribution. Every subagent variety shares
|
|
54
|
+
// `llm_call_site = "subagentSpawn"`, so on the authoritative billing path
|
|
55
|
+
// these two orthogonal dimensions are the only way to tell an advisor
|
|
56
|
+
// consult from a fork from a regular spawn.
|
|
57
|
+
subagentRole: "X-Vellum-Subagent-Role",
|
|
58
|
+
subagentSpawnMode: "X-Vellum-Subagent-Spawn-Mode",
|
|
52
59
|
} as const;
|
|
53
60
|
|
|
54
61
|
/** Providers whose transports consume `promptCacheKey` (OpenAI Responses
|
|
@@ -422,6 +429,10 @@ function normalizeSendMessageOptions(
|
|
|
422
429
|
// downstream as a wire-format field.
|
|
423
430
|
delete nextConfig.callSite;
|
|
424
431
|
if (normalizeOptions.forwardUsageAttributionHeaders === true) {
|
|
432
|
+
// Read from the conversation row rather than the live SubagentManager:
|
|
433
|
+
// the row is durable and the lookup is a memoized primary-key read that
|
|
434
|
+
// can never throw, so billing attribution cannot destabilize dispatch.
|
|
435
|
+
const subagent = resolveSubagentAttribution(config.conversationId);
|
|
425
436
|
const usageAttributionHeaders = buildUsageAttributionHeaders({
|
|
426
437
|
callSite: attribution.callSite,
|
|
427
438
|
appliedProfile: attribution.appliedProfile,
|
|
@@ -429,6 +440,8 @@ function normalizeSendMessageOptions(
|
|
|
429
440
|
resolvedProvider: attribution.resolvedProvider,
|
|
430
441
|
resolvedModel: attribution.resolvedModel,
|
|
431
442
|
resolvedMixArm: attribution.resolvedMixArm,
|
|
443
|
+
subagentRole: subagent.subagentRole,
|
|
444
|
+
subagentSpawnMode: subagent.subagentSpawnMode,
|
|
432
445
|
});
|
|
433
446
|
if (Object.keys(usageAttributionHeaders).length > 0) {
|
|
434
447
|
nextConfig.usageAttributionHeaders = usageAttributionHeaders;
|
|
@@ -769,6 +782,8 @@ function buildUsageAttributionHeaders(input: {
|
|
|
769
782
|
resolvedProvider: string;
|
|
770
783
|
resolvedModel: string;
|
|
771
784
|
resolvedMixArm: string | null;
|
|
785
|
+
subagentRole: string | null;
|
|
786
|
+
subagentSpawnMode: string | null;
|
|
772
787
|
}): Record<string, string> {
|
|
773
788
|
const headers: Record<string, string> = {};
|
|
774
789
|
addSanitizedHeader(
|
|
@@ -803,6 +818,16 @@ function buildUsageAttributionHeaders(input: {
|
|
|
803
818
|
USAGE_ATTRIBUTION_HEADER_NAMES.resolvedMixArm,
|
|
804
819
|
input.resolvedMixArm,
|
|
805
820
|
);
|
|
821
|
+
addSanitizedHeader(
|
|
822
|
+
headers,
|
|
823
|
+
USAGE_ATTRIBUTION_HEADER_NAMES.subagentRole,
|
|
824
|
+
input.subagentRole,
|
|
825
|
+
);
|
|
826
|
+
addSanitizedHeader(
|
|
827
|
+
headers,
|
|
828
|
+
USAGE_ATTRIBUTION_HEADER_NAMES.subagentSpawnMode,
|
|
829
|
+
input.subagentSpawnMode,
|
|
830
|
+
);
|
|
806
831
|
return headers;
|
|
807
832
|
}
|
|
808
833
|
|