@vellumai/assistant 0.7.0 → 0.7.1
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 +6 -7
- package/Dockerfile +1 -0
- package/README.md +2 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
- package/bun.lock +3 -0
- package/docs/architecture/security.md +18 -16
- package/knip.json +1 -0
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
- package/node_modules/@vellumai/slack-text/bun.lock +24 -0
- package/node_modules/@vellumai/slack-text/package.json +18 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
- package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
- package/openapi.yaml +294 -107
- package/package.json +4 -2
- package/scripts/generate-openapi.ts +16 -111
- package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
- package/src/__tests__/anthropic-provider.test.ts +56 -13
- package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
- package/src/__tests__/app-conversation-ids.test.ts +151 -0
- package/src/__tests__/approval-cascade.test.ts +0 -15
- package/src/__tests__/approval-routes-http.test.ts +6 -17
- package/src/__tests__/assistant-event-hub.test.ts +126 -77
- package/src/__tests__/assistant-event.test.ts +0 -5
- package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
- package/src/__tests__/background-shell-host-bash.test.ts +34 -43
- package/src/__tests__/call-controller.test.ts +1 -1
- package/src/__tests__/call-site-routing-provider.test.ts +193 -0
- package/src/__tests__/channel-approval-routes.test.ts +10 -296
- package/src/__tests__/channel-approvals.test.ts +25 -17
- package/src/__tests__/channel-guardian.test.ts +100 -146
- package/src/__tests__/checker.test.ts +20 -34
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/config-schema.test.ts +6 -48
- package/src/__tests__/config-watcher.test.ts +12 -0
- package/src/__tests__/connection-policy.test.ts +1 -52
- package/src/__tests__/contacts-write.test.ts +2 -64
- package/src/__tests__/context-image-dimensions.test.ts +1 -1
- package/src/__tests__/context-search-memory-source.test.ts +120 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
- package/src/__tests__/context-search-pkb-source.test.ts +49 -0
- package/src/__tests__/context-search-workspace-source.test.ts +9 -22
- package/src/__tests__/context-window-manager.test.ts +46 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
- package/src/__tests__/conversation-agent-loop.test.ts +980 -13
- package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
- package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
- package/src/__tests__/conversation-history-web-search.test.ts +4 -3
- package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
- package/src/__tests__/conversation-lifecycle.test.ts +4 -4
- package/src/__tests__/conversation-process-callsite.test.ts +79 -2
- package/src/__tests__/conversation-queue.test.ts +3 -8
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
- package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
- package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
- package/src/__tests__/conversation-slash-commands.test.ts +24 -4
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-starter-routes.test.ts +79 -2
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
- package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
- package/src/__tests__/conversation-usage.test.ts +253 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
- package/src/__tests__/credential-health-service.test.ts +68 -0
- package/src/__tests__/credential-security-e2e.test.ts +4 -3
- package/src/__tests__/credential-security-invariants.test.ts +1 -5
- package/src/__tests__/credential-token-resolver.test.ts +180 -0
- package/src/__tests__/cu-unified-flow.test.ts +33 -16
- package/src/__tests__/daemon-assistant-events.test.ts +34 -21
- package/src/__tests__/daemon-credential-client.test.ts +4 -1
- package/src/__tests__/db-connection-isolation.test.ts +125 -0
- package/src/__tests__/db-migration-rollback.test.ts +101 -0
- package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
- package/src/__tests__/document-conversations.test.ts +332 -0
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
- package/src/__tests__/emit-event-signal.test.ts +4 -6
- package/src/__tests__/events-client-registration.test.ts +193 -49
- package/src/__tests__/filing-service.test.ts +58 -7
- package/src/__tests__/first-greeting.test.ts +156 -150
- package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
- package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -1
- package/src/__tests__/guardian-grant-minting.test.ts +7 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
- package/src/__tests__/guardian-routing-state.test.ts +1 -1
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
- package/src/__tests__/headless-browser-mode.test.ts +4 -9
- package/src/__tests__/headless-browser-navigate.test.ts +21 -20
- package/src/__tests__/heartbeat-service.test.ts +289 -7
- package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
- package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
- package/src/__tests__/host-bash-proxy.test.ts +46 -122
- package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
- package/src/__tests__/host-browser-proxy.test.ts +111 -185
- package/src/__tests__/host-browser-routes.test.ts +45 -75
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
- package/src/__tests__/host-cu-proxy.test.ts +56 -111
- package/src/__tests__/host-file-proxy.test.ts +44 -98
- package/src/__tests__/host-file-read-tool.test.ts +42 -21
- package/src/__tests__/host-shell-tool.test.ts +33 -68
- package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
- package/src/__tests__/host-transfer-proxy.test.ts +43 -53
- package/src/__tests__/http-user-message-parity.test.ts +0 -6
- package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
- package/src/__tests__/injector-chain.test.ts +10 -5
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -66
- package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
- package/src/__tests__/install-skill-routing.test.ts +1 -13
- package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
- package/src/__tests__/llm-catalog-parity.test.ts +90 -0
- package/src/__tests__/llm-context-resolution.test.ts +180 -0
- package/src/__tests__/llm-resolver.test.ts +80 -12
- package/src/__tests__/llm-usage-store.test.ts +269 -4
- package/src/__tests__/log-export-routes.test.ts +89 -0
- package/src/__tests__/managed-profile-guard.test.ts +225 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
- package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
- package/src/__tests__/migration-export-http.test.ts +33 -26
- package/src/__tests__/migration-export-streaming.test.ts +18 -10
- package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
- package/src/__tests__/migration-import-commit-http.test.ts +66 -21
- package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
- package/src/__tests__/migration-import-from-url.test.ts +20 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
- package/src/__tests__/migration-parity-persistence.test.ts +62 -25
- package/src/__tests__/migration-transport.test.ts +115 -23
- package/src/__tests__/migration-validate-http.test.ts +105 -80
- package/src/__tests__/migration-wizard.test.ts +133 -27
- package/src/__tests__/non-member-access-request.test.ts +1 -1
- package/src/__tests__/notification-guardian-path.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +19 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
- package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
- package/src/__tests__/pricing.test.ts +68 -4
- package/src/__tests__/process-message-background-slack.test.ts +331 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
- package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
- package/src/__tests__/provider-usage-tracking.test.ts +208 -0
- package/src/__tests__/reaction-persistence.test.ts +9 -6
- package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
- package/src/__tests__/recording-handler.test.ts +64 -81
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
- package/src/__tests__/relay-server.test.ts +18 -13
- package/src/__tests__/require-fresh-approval.test.ts +13 -22
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +3 -12
- package/src/__tests__/search-skills-unified.test.ts +9 -15
- package/src/__tests__/secret-ingress-cli.test.ts +2 -5
- package/src/__tests__/secret-ingress-http.test.ts +0 -4
- package/src/__tests__/secret-onetime-send.test.ts +4 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
- package/src/__tests__/secret-response-routing.test.ts +29 -15
- package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
- package/src/__tests__/secret-scanner.test.ts +2 -545
- package/src/__tests__/send-endpoint-busy.test.ts +9 -24
- package/src/__tests__/settings-routes.test.ts +1 -1
- package/src/__tests__/shell-credential-ref.test.ts +0 -8
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
- package/src/__tests__/skill-tool-factory.test.ts +97 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
- package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
- package/src/__tests__/slack-inbound-verification.test.ts +1 -62
- package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
- package/src/__tests__/subagent-manager-notify.test.ts +70 -70
- package/src/__tests__/subagent-notify-parent.test.ts +80 -83
- package/src/__tests__/system-prompt.test.ts +115 -13
- package/src/__tests__/terminal-tools.test.ts +0 -89
- package/src/__tests__/thread-backfill.test.ts +945 -31
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
- package/src/__tests__/tool-executor.test.ts +12 -19
- package/src/__tests__/tool-metrics-listener.test.ts +0 -35
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-trace-listener.test.ts +0 -17
- package/src/__tests__/transfer-progress-screen.test.ts +63 -26
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +16 -5
- package/src/__tests__/usage-attribution.test.ts +247 -0
- package/src/__tests__/usage-cli.test.ts +143 -0
- package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
- package/src/__tests__/usage-routes.test.ts +150 -0
- package/src/__tests__/validation-results-screen.test.ts +39 -16
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
- package/src/__tests__/voice-session-bridge.test.ts +5 -5
- package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
- package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
- package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
- package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
- package/src/acp/index.ts +0 -15
- package/src/acp/session-manager.ts +37 -34
- package/src/agent/loop.ts +16 -1
- package/src/approvals/AGENTS.md +4 -0
- package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
- package/src/approvals/guardian-request-resolvers.ts +10 -2
- package/src/backup/__tests__/backup-worker.test.ts +36 -8
- package/src/backup/__tests__/paths.test.ts +2 -2
- package/src/backup/__tests__/restore.test.ts +45 -28
- package/src/backup/backup-worker.ts +36 -2
- package/src/backup/paths.ts +9 -6
- package/src/browser-session/events.ts +0 -9
- package/src/calls/call-store.ts +1 -34
- package/src/calls/guardian-question-copy.ts +0 -108
- package/src/calls/relay-server.ts +0 -24
- package/src/calls/twilio-rest.ts +0 -38
- package/src/calls/twilio-routes.ts +1 -1
- package/src/calls/voice-session-bridge.ts +7 -38
- package/src/channels/types.ts +1 -36
- package/src/cli/commands/__tests__/cache.test.ts +152 -5
- package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
- package/src/cli/commands/__tests__/trust.test.ts +21 -387
- package/src/cli/commands/backup.ts +4 -4
- package/src/cli/commands/cache-fs.ts +8 -0
- package/src/cli/commands/cache.ts +153 -82
- package/src/cli/commands/clients.ts +63 -5
- package/src/cli/commands/completions.ts +3 -3
- package/src/cli/commands/contacts.ts +231 -76
- package/src/cli/commands/keys.ts +4 -1
- package/src/cli/commands/memory-v2.ts +24 -52
- package/src/cli/commands/oauth/shared.ts +2 -29
- package/src/cli/commands/pending.ts +102 -0
- package/src/cli/commands/skills.ts +77 -35
- package/src/cli/commands/trust.ts +70 -430
- package/src/cli/commands/usage.ts +25 -16
- package/src/cli/lib/daemon-credential-client.ts +14 -0
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +0 -21
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
- package/src/config/env-registry.ts +12 -2
- package/src/config/env.ts +3 -14
- package/src/config/feature-flag-registry.json +30 -30
- package/src/config/llm-callsite-catalog.ts +12 -0
- package/src/config/llm-context-resolution.ts +80 -0
- package/src/config/llm-resolver.ts +58 -22
- package/src/config/loader.ts +3 -3
- package/src/config/schema.ts +2 -158
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +271 -0
- package/src/config/schemas/calls.ts +5 -5
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/ingress.ts +1 -1
- package/src/config/schemas/llm.ts +31 -3
- package/src/config/schemas/memory-retrieval.ts +2 -2
- package/src/config/schemas/memory-v2.ts +9 -0
- package/src/config/schemas/security.ts +1 -42
- package/src/config/schemas/services.ts +6 -6
- package/src/config/schemas/skills.ts +5 -5
- package/src/config/schemas/tts.ts +1 -1
- package/src/config/seed-inference-profiles.ts +117 -0
- package/src/config/skills.ts +0 -90
- package/src/config/types.ts +3 -6
- package/src/contacts/contact-store.ts +0 -17
- package/src/contacts/contacts-write.ts +1 -105
- package/src/context/window-manager.ts +44 -5
- package/src/credential-execution/process-manager.ts +34 -10
- package/src/credential-health/credential-health-service.ts +21 -16
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
- package/src/daemon/connection-policy.ts +1 -26
- package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
- package/src/daemon/conversation-agent-loop.ts +277 -36
- package/src/daemon/conversation-history.ts +8 -8
- package/src/daemon/conversation-launch.ts +20 -135
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-messaging.ts +1 -0
- package/src/daemon/conversation-process.ts +83 -163
- package/src/daemon/conversation-runtime-assembly.ts +219 -76
- package/src/daemon/conversation-slash.ts +47 -5
- package/src/daemon/conversation-store.ts +7 -31
- package/src/daemon/conversation-surfaces.ts +22 -28
- package/src/daemon/conversation-tool-setup.ts +3 -33
- package/src/daemon/conversation-usage.ts +36 -0
- package/src/daemon/conversation.ts +117 -233
- package/src/daemon/daemon-control.ts +3 -71
- package/src/daemon/daemon-skill-host.ts +8 -11
- package/src/daemon/dictation-profile-store.ts +2 -26
- package/src/daemon/first-greeting.ts +44 -156
- package/src/daemon/handlers/config-channels.ts +12 -12
- package/src/daemon/handlers/config-ingress.ts +4 -165
- package/src/daemon/handlers/config-model.ts +1 -1
- package/src/daemon/handlers/config-voice.ts +0 -42
- package/src/daemon/handlers/conversations.ts +11 -190
- package/src/daemon/handlers/recording.ts +26 -158
- package/src/daemon/handlers/shared.ts +23 -71
- package/src/daemon/handlers/skills.ts +42 -93
- package/src/daemon/host-bash-proxy.ts +67 -45
- package/src/daemon/host-browser-proxy.ts +65 -27
- package/src/daemon/host-cu-proxy.ts +40 -39
- package/src/daemon/host-file-proxy.ts +58 -37
- package/src/daemon/host-transfer-proxy.ts +84 -46
- package/src/daemon/lifecycle.ts +49 -15
- package/src/daemon/message-types/conversations.ts +7 -0
- package/src/daemon/message-types/host-bash.ts +1 -0
- package/src/daemon/message-types/host-cu.ts +1 -0
- package/src/daemon/message-types/host-file.ts +1 -0
- package/src/daemon/message-types/host-transfer.ts +1 -0
- package/src/daemon/message-types/messages.ts +10 -9
- package/src/daemon/message-types/workspace.ts +1 -1
- package/src/daemon/process-message.ts +102 -239
- package/src/daemon/server.ts +13 -462
- package/src/daemon/shutdown-handlers.ts +2 -2
- package/src/daemon/tool-side-effects.ts +125 -107
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +4 -9
- package/src/events/domain-events.ts +0 -8
- package/src/events/tool-audit-listener.ts +3 -1
- package/src/events/tool-domain-event-publisher.ts +0 -10
- package/src/events/tool-metrics-listener.ts +0 -17
- package/src/events/tool-trace-listener.ts +0 -14
- package/src/filing/filing-service.ts +13 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
- package/src/heartbeat/heartbeat-service.ts +23 -5
- package/src/home/__tests__/feed-writer.test.ts +0 -4
- package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
- package/src/home/feed-writer.ts +1 -2
- package/src/home/relationship-state-writer.ts +16 -3
- package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
- package/src/ipc/assistant-server.ts +3 -10
- package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
- package/src/ipc/routes/route-adapter.ts +1 -1
- package/src/ipc/routes/trust-rules.test.ts +0 -95
- package/src/ipc/skill-ipc-types.ts +41 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
- package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
- package/src/ipc/skill-routes/events.ts +12 -23
- package/src/ipc/skill-routes/identity.ts +4 -17
- package/src/ipc/skill-routes/index.ts +1 -1
- package/src/ipc/skill-server.ts +6 -39
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
- package/src/live-voice/protocol.ts +4 -13
- package/src/mcp/manager.ts +0 -5
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
- package/src/memory/app-git-service.ts +0 -32
- package/src/memory/app-store.ts +154 -0
- package/src/memory/attachments-store.ts +6 -0
- package/src/memory/context-search/sources/memory-v2.ts +578 -0
- package/src/memory/context-search/sources/memory.ts +5 -0
- package/src/memory/context-search/sources/pkb.ts +10 -1
- package/src/memory/context-search/sources/workspace.ts +3 -2
- package/src/memory/conversation-crud.ts +29 -4
- package/src/memory/conversation-disk-view.ts +1 -5
- package/src/memory/conversation-starter-checkpoints.ts +63 -0
- package/src/memory/db-connection.ts +62 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +3 -21
- package/src/memory/embedding-gemini.ts +0 -2
- package/src/memory/embedding-local.ts +6 -6
- package/src/memory/embedding-ollama.ts +6 -6
- package/src/memory/embedding-openai.ts +6 -6
- package/src/memory/embedding-types.ts +21 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
- package/src/memory/graph/conversation-graph-memory.ts +35 -13
- package/src/memory/graph/injection.test.ts +2 -2
- package/src/memory/graph/injection.ts +1 -1
- package/src/memory/guardian-action-store.ts +0 -83
- package/src/memory/guardian-approvals.ts +0 -48
- package/src/memory/indexer.ts +1 -15
- package/src/memory/job-handlers/conversation-starters.ts +36 -53
- package/src/memory/job-utils.ts +0 -6
- package/src/memory/jobs-store.ts +0 -1
- package/src/memory/jobs-worker.ts +2 -16
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +129 -43
- package/src/memory/memory-v2-activation-log-store.ts +115 -0
- package/src/memory/migrations/233-document-conversations.ts +54 -0
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
- package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
- package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
- package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
- package/src/memory/migrations/index.ts +14 -0
- package/src/memory/migrations/registry.ts +24 -0
- package/src/memory/raw-query.ts +2 -68
- package/src/memory/schema/conversations.ts +7 -0
- package/src/memory/schema/infrastructure.ts +25 -0
- package/src/memory/search/semantic.ts +5 -16
- package/src/memory/tool-usage-store.ts +2 -0
- package/src/memory/usage-buckets.ts +40 -1
- package/src/memory/usage-grouped-buckets.ts +127 -0
- package/src/memory/v2/__tests__/activation.test.ts +289 -90
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
- package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
- package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
- package/src/memory/v2/__tests__/injection.test.ts +384 -15
- package/src/memory/v2/__tests__/migration.test.ts +64 -36
- package/src/memory/v2/__tests__/page-store.test.ts +191 -8
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
- package/src/memory/v2/__tests__/static-context.test.ts +153 -0
- package/src/memory/v2/activation.ts +168 -97
- package/src/memory/v2/backfill-jobs.ts +15 -100
- package/src/memory/v2/consolidation-job.ts +14 -12
- package/src/memory/v2/edge-index.ts +191 -0
- package/src/memory/v2/injection.ts +182 -58
- package/src/memory/v2/migration.ts +57 -64
- package/src/memory/v2/now-text.ts +2 -3
- package/src/memory/v2/page-store.ts +168 -31
- package/src/memory/v2/prompts/consolidation.ts +118 -42
- package/src/memory/v2/prompts/sweep.ts +3 -3
- package/src/memory/v2/skill-store.ts +55 -7
- package/src/memory/v2/static-context.ts +62 -0
- package/src/memory/v2/types.ts +10 -20
- package/src/memory/validation.ts +0 -11
- package/src/messaging/draft-store.ts +0 -6
- package/src/messaging/provider-types.ts +8 -0
- package/src/messaging/provider.ts +7 -0
- package/src/messaging/providers/gmail/client.ts +1 -121
- package/src/messaging/providers/outlook/client.ts +0 -73
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
- package/src/messaging/providers/slack/adapter.ts +122 -21
- package/src/messaging/providers/slack/backfill.test.ts +95 -6
- package/src/messaging/providers/slack/backfill.ts +89 -11
- package/src/messaging/providers/slack/client.ts +10 -124
- package/src/messaging/providers/slack/message-metadata.ts +12 -2
- package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
- package/src/messaging/providers/slack/render-transcript.ts +126 -25
- package/src/messaging/providers/slack/types.ts +1 -0
- package/src/oauth/connection-resolver.test.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -16
- package/src/oauth/credential-token-resolver.ts +97 -0
- package/src/oauth/manual-token-connection.ts +30 -34
- package/src/oauth/oauth-store.ts +6 -4
- package/src/outbound-proxy/certs.ts +0 -7
- package/src/outbound-proxy/config.ts +0 -74
- package/src/outbound-proxy/health.ts +0 -44
- package/src/outbound-proxy/index.ts +0 -22
- package/src/permissions/approval-provenance.test.ts +184 -0
- package/src/permissions/approval-provenance.ts +70 -0
- package/src/permissions/checker.ts +4 -1
- package/src/permissions/gateway-threshold-reader.ts +4 -1
- package/src/permissions/prompter.ts +9 -2
- package/src/permissions/secret-prompter.ts +21 -48
- package/src/permissions/types.ts +33 -0
- package/src/permissions/workspace-policy.ts +0 -5
- package/src/platform/sync-identity.ts +0 -8
- package/src/plugins/defaults/injectors.ts +69 -2
- package/src/plugins/defaults/overflow-reduce.ts +3 -2
- package/src/plugins/types.ts +8 -0
- package/src/prompts/system-prompt.ts +34 -70
- package/src/prompts/templates/BOOTSTRAP.md +52 -6
- package/src/prompts/update-bulletin-job.ts +2 -0
- package/src/providers/__tests__/retry-callsite.test.ts +138 -1
- package/src/providers/anthropic/client.ts +72 -33
- package/src/providers/call-site-routing.ts +42 -3
- package/src/providers/gemini/client.ts +18 -2
- package/src/providers/managed-proxy/context.ts +0 -5
- package/src/providers/model-catalog.ts +105 -19
- package/src/providers/openai/chat-completions-provider.ts +6 -0
- package/src/providers/openai/responses-provider.ts +7 -1
- package/src/providers/provider-send-message.ts +45 -2
- package/src/providers/ratelimit.ts +7 -2
- package/src/providers/registry.ts +14 -9
- package/src/providers/retry.ts +96 -8
- package/src/providers/types.ts +13 -0
- package/src/providers/usage-tracking.ts +96 -0
- package/src/runtime/AGENTS.md +10 -6
- package/src/runtime/__tests__/agent-wake.test.ts +89 -0
- package/src/runtime/agent-wake.ts +39 -2
- package/src/runtime/assistant-event-hub.ts +541 -45
- package/src/runtime/assistant-event.ts +1 -6
- package/src/runtime/auth/context.ts +0 -9
- package/src/runtime/auth/middleware.ts +1 -1
- package/src/runtime/auth/route-policy.ts +11 -9
- package/src/runtime/auth/token-service.ts +0 -11
- package/src/runtime/channel-approvals.ts +6 -2
- package/src/runtime/channel-verification-service.ts +3 -5
- package/src/runtime/http-errors.ts +0 -34
- package/src/runtime/http-router.ts +6 -3
- package/src/runtime/http-server.ts +22 -82
- package/src/runtime/http-types.ts +5 -0
- package/src/runtime/interactive-ui.ts +0 -1
- package/src/runtime/middleware/auth.ts +0 -20
- package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
- package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
- package/src/runtime/migrations/migration-transport.ts +46 -13
- package/src/runtime/migrations/migration-wizard.ts +2 -2
- package/src/runtime/migrations/origin-mode.ts +40 -0
- package/src/runtime/migrations/vbundle-builder.ts +133 -79
- package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
- package/src/runtime/migrations/vbundle-importer.ts +7 -7
- package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
- package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
- package/src/runtime/migrations/vbundle-validator.ts +214 -41
- package/src/runtime/pending-interactions.ts +13 -4
- package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
- package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
- package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
- package/src/runtime/routes/acp-routes.test.ts +0 -3
- package/src/runtime/routes/acp-routes.ts +3 -7
- package/src/runtime/routes/app-management-routes.ts +18 -9
- package/src/runtime/routes/approval-routes.ts +55 -14
- package/src/runtime/routes/avatar-routes.ts +3 -5
- package/src/runtime/routes/browser-routes.ts +1 -15
- package/src/runtime/routes/channel-guardian-routes.ts +1 -5
- package/src/runtime/routes/channel-readiness-routes.ts +3 -7
- package/src/runtime/routes/channel-route-shared.ts +2 -28
- package/src/runtime/routes/client-routes.ts +45 -12
- package/src/runtime/routes/consolidation-routes.ts +115 -0
- package/src/runtime/routes/conversation-list-routes.ts +12 -29
- package/src/runtime/routes/conversation-management-routes.ts +14 -51
- package/src/runtime/routes/conversation-query-routes.ts +120 -8
- package/src/runtime/routes/conversation-routes.ts +44 -528
- package/src/runtime/routes/conversation-starter-routes.ts +19 -40
- package/src/runtime/routes/documents-routes.ts +53 -18
- package/src/runtime/routes/events-routes.ts +59 -91
- package/src/runtime/routes/filing-routes.ts +18 -1
- package/src/runtime/routes/guardian-action-routes.ts +4 -9
- package/src/runtime/routes/host-bash-routes.ts +3 -2
- package/src/runtime/routes/host-browser-routes.ts +9 -33
- package/src/runtime/routes/host-cu-routes.ts +6 -1
- package/src/runtime/routes/host-file-routes.ts +3 -2
- package/src/runtime/routes/host-transfer-routes.ts +11 -15
- package/src/runtime/routes/identity-routes.ts +78 -6
- package/src/runtime/routes/inbound-message-handler.ts +580 -137
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
- package/src/runtime/routes/index.ts +4 -0
- package/src/runtime/routes/integrations/slack/channel.ts +0 -24
- package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
- package/src/runtime/routes/memory-v2-routes.ts +10 -15
- package/src/runtime/routes/migration-routes.ts +188 -31
- package/src/runtime/routes/playground/guard.ts +1 -1
- package/src/runtime/routes/playground/index.ts +0 -2
- package/src/runtime/routes/recording-routes.ts +4 -24
- package/src/runtime/routes/rename-conversation-routes.ts +2 -6
- package/src/runtime/routes/schedule-routes.ts +3 -6
- package/src/runtime/routes/secret-routes.ts +87 -18
- package/src/runtime/routes/settings-routes.ts +29 -28
- package/src/runtime/routes/skills-routes.ts +12 -31
- package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
- package/src/runtime/routes/task-routes.ts +6 -6
- package/src/runtime/routes/trust-rules-routes.ts +3 -94
- package/src/runtime/routes/types.ts +4 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
- package/src/runtime/routes/usage-routes.ts +87 -10
- package/src/runtime/routes/user-routes.ts +17 -31
- package/src/runtime/routes/work-items-routes.ts +1 -4
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
- package/src/runtime/services/analyze-conversation.ts +7 -17
- package/src/runtime/services/conversation-serializer.ts +2 -4
- package/src/runtime/verification-outbound-actions.ts +1 -1
- package/src/runtime/verification-rate-limiter.ts +1 -1
- package/src/schedule/schedule-store.ts +0 -16
- package/src/security/secret-scanner.ts +14 -547
- package/src/security/secure-keys.ts +31 -11
- package/src/security/token-manager.ts +7 -3
- package/src/signals/cancel.ts +16 -25
- package/src/signals/conversation-undo.ts +2 -27
- package/src/signals/emit-event.ts +1 -2
- package/src/signals/user-message.ts +108 -22
- package/src/skills/catalog-install.ts +1 -0
- package/src/skills/clawhub.ts +2 -2
- package/src/skills/inline-command-runner.ts +1 -7
- package/src/subagent/manager.ts +67 -84
- package/src/tasks/task-store.ts +1 -28
- package/src/telemetry/types.ts +6 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
- package/src/telemetry/usage-telemetry-reporter.ts +3 -5
- package/src/tools/acp/spawn.test.ts +1 -2
- package/src/tools/acp/steer.test.ts +1 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
- package/src/tools/browser/browser-execution.ts +31 -147
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
- package/src/tools/browser/cdp-client/factory.ts +48 -76
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/executor.ts +44 -31
- package/src/tools/host-filesystem/edit.ts +3 -2
- package/src/tools/host-filesystem/read.ts +3 -2
- package/src/tools/host-filesystem/transfer.test.ts +45 -42
- package/src/tools/host-filesystem/transfer.ts +4 -3
- package/src/tools/host-filesystem/write.ts +3 -2
- package/src/tools/host-terminal/host-shell.ts +4 -3
- package/src/tools/network/script-proxy/index.ts +1 -10
- package/src/tools/permission-checker.ts +66 -1
- package/src/tools/skills/sandbox-runner.ts +1 -6
- package/src/tools/skills/skill-tool-factory.ts +32 -0
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/terminal/shell.ts +2 -78
- package/src/tools/types.ts +12 -39
- package/src/tts/__tests__/provider-catalog.test.ts +2 -2
- package/src/tts/provider-catalog.ts +1 -1
- package/src/usage/actors.ts +2 -1
- package/src/usage/attribution.ts +185 -0
- package/src/usage/pricing.ts +166 -0
- package/src/usage/types.ts +14 -0
- package/src/util/json.ts +13 -0
- package/src/util/logger.ts +3 -3
- package/src/util/pricing.ts +50 -3
- package/src/work-items/work-item-runner.ts +15 -42
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
- package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
- package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
- package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
- package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
- package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/provider-commit-message-generator.ts +3 -3
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
- package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
- package/src/__tests__/secret-detection-handler.test.ts +0 -67
- package/src/__tests__/secret-scanner-executor.test.ts +0 -450
- package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
- package/src/__tests__/terminal-sandbox.test.ts +0 -374
- package/src/__tests__/tool-notification-listener.test.ts +0 -65
- package/src/context/__tests__/microcompact.test.ts +0 -805
- package/src/context/microcompact.ts +0 -443
- package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
- package/src/events/tool-notification-listener.ts +0 -17
- package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
- package/src/memory/v2/__tests__/edges.test.ts +0 -435
- package/src/memory/v2/edges.ts +0 -217
- package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
- package/src/runtime/__tests__/client-registry.test.ts +0 -271
- package/src/runtime/chrome-extension-registry.ts +0 -368
- package/src/runtime/client-registry.ts +0 -254
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
- package/src/tools/secret-detection-handler.ts +0 -269
- package/src/tools/terminal/backends/native.ts +0 -327
- package/src/tools/terminal/backends/types.ts +0 -37
- package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
- package/src/tools/terminal/sandbox.ts +0 -40
package/src/providers/retry.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
2
2
|
import { getConfig } from "../config/loader.js";
|
|
3
|
+
import {
|
|
4
|
+
resolveUsageAttribution,
|
|
5
|
+
sanitizeUsageMetadataValue,
|
|
6
|
+
} from "../usage/attribution.js";
|
|
3
7
|
import { ProviderError } from "../util/errors.js";
|
|
4
8
|
import { getLogger } from "../util/logger.js";
|
|
5
9
|
import {
|
|
@@ -24,6 +28,14 @@ import {
|
|
|
24
28
|
|
|
25
29
|
const log = getLogger("retry");
|
|
26
30
|
|
|
31
|
+
const USAGE_ATTRIBUTION_HEADER_NAMES = {
|
|
32
|
+
callSite: "X-Vellum-LLM-Call-Site",
|
|
33
|
+
inferenceProfile: "X-Vellum-Inference-Profile",
|
|
34
|
+
inferenceProfileSource: "X-Vellum-Inference-Profile-Source",
|
|
35
|
+
resolvedProvider: "X-Vellum-Resolved-Provider",
|
|
36
|
+
resolvedModel: "X-Vellum-Resolved-Model",
|
|
37
|
+
} as const;
|
|
38
|
+
|
|
27
39
|
/** Providers that support the `effort` config (extended thinking / reasoning). */
|
|
28
40
|
const EFFORT_SUPPORTED_PROVIDERS = new Set([
|
|
29
41
|
"anthropic",
|
|
@@ -118,12 +130,18 @@ function isRetryableError(error: unknown): boolean {
|
|
|
118
130
|
function normalizeSendMessageOptions(
|
|
119
131
|
providerName: string,
|
|
120
132
|
options?: SendMessageOptions,
|
|
133
|
+
normalizeOptions: { forwardUsageAttributionHeaders?: boolean } = {},
|
|
121
134
|
): SendMessageOptions | undefined {
|
|
122
135
|
const config = options?.config;
|
|
123
136
|
if (!config) return options;
|
|
124
137
|
|
|
125
138
|
const nextConfig: Record<string, unknown> = { ...config };
|
|
126
139
|
|
|
140
|
+
// Internal metadata must be derived here, not accepted from callers, and it
|
|
141
|
+
// must never leak into provider JSON request bodies.
|
|
142
|
+
delete nextConfig.usageAttributionHeaders;
|
|
143
|
+
delete nextConfig.usageTracking;
|
|
144
|
+
|
|
127
145
|
// `overrideProfile` is a routing/resolution-time concern (consumed by the
|
|
128
146
|
// resolver below and `CallSiteRoutingProvider`'s provider selection); it is
|
|
129
147
|
// not a wire-format field. Strip unconditionally so it never leaks into
|
|
@@ -134,6 +152,10 @@ function normalizeSendMessageOptions(
|
|
|
134
152
|
const resolved = resolveCallSiteConfig(config.callSite, getConfig().llm, {
|
|
135
153
|
overrideProfile: config.overrideProfile,
|
|
136
154
|
});
|
|
155
|
+
const attribution = resolveUsageAttribution({
|
|
156
|
+
callSite: config.callSite,
|
|
157
|
+
overrideProfile: config.overrideProfile,
|
|
158
|
+
});
|
|
137
159
|
|
|
138
160
|
const explicitModel =
|
|
139
161
|
typeof config.model === "string" && config.model.trim().length > 0
|
|
@@ -143,6 +165,18 @@ function normalizeSendMessageOptions(
|
|
|
143
165
|
// Routing key is consumed by the resolver above and must not leak
|
|
144
166
|
// downstream as a wire-format field.
|
|
145
167
|
delete nextConfig.callSite;
|
|
168
|
+
if (normalizeOptions.forwardUsageAttributionHeaders === true) {
|
|
169
|
+
const usageAttributionHeaders = buildUsageAttributionHeaders({
|
|
170
|
+
callSite: attribution.callSite,
|
|
171
|
+
appliedProfile: attribution.appliedProfile,
|
|
172
|
+
profileSource: attribution.profileSource,
|
|
173
|
+
resolvedProvider: attribution.resolvedProvider,
|
|
174
|
+
resolvedModel: attribution.resolvedModel,
|
|
175
|
+
});
|
|
176
|
+
if (Object.keys(usageAttributionHeaders).length > 0) {
|
|
177
|
+
nextConfig.usageAttributionHeaders = usageAttributionHeaders;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
146
180
|
|
|
147
181
|
// Apply resolved values, letting per-call explicit fields win where set.
|
|
148
182
|
nextConfig.model = explicitModel ?? resolved.model;
|
|
@@ -194,12 +228,11 @@ function normalizeSendMessageOptions(
|
|
|
194
228
|
nextConfig.openrouter = { only: resolved.openrouter.only };
|
|
195
229
|
}
|
|
196
230
|
// `contextWindow` and `provider` are server-side concerns, not provider
|
|
197
|
-
// request parameters:
|
|
198
|
-
//
|
|
199
|
-
// `
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
// (and other strict-schema clients) reject the request with
|
|
231
|
+
// request parameters: effective context is resolved per call site/profile
|
|
232
|
+
// by the agent/conversation path, while `provider` selection is handled by
|
|
233
|
+
// `CallSiteRoutingProvider` upstream. Forwarding them as per-call config
|
|
234
|
+
// leaks unknown fields into provider request bodies — Anthropic (and other
|
|
235
|
+
// strict-schema clients) reject the request with
|
|
203
236
|
// "Extra inputs are not permitted".
|
|
204
237
|
}
|
|
205
238
|
|
|
@@ -274,6 +307,55 @@ function normalizeSendMessageOptions(
|
|
|
274
307
|
};
|
|
275
308
|
}
|
|
276
309
|
|
|
310
|
+
function buildUsageAttributionHeaders(input: {
|
|
311
|
+
callSite: string | null;
|
|
312
|
+
appliedProfile: string | null;
|
|
313
|
+
profileSource: string;
|
|
314
|
+
resolvedProvider: string;
|
|
315
|
+
resolvedModel: string;
|
|
316
|
+
}): Record<string, string> {
|
|
317
|
+
const headers: Record<string, string> = {};
|
|
318
|
+
addSanitizedHeader(
|
|
319
|
+
headers,
|
|
320
|
+
USAGE_ATTRIBUTION_HEADER_NAMES.callSite,
|
|
321
|
+
input.callSite,
|
|
322
|
+
);
|
|
323
|
+
addSanitizedHeader(
|
|
324
|
+
headers,
|
|
325
|
+
USAGE_ATTRIBUTION_HEADER_NAMES.inferenceProfile,
|
|
326
|
+
input.appliedProfile,
|
|
327
|
+
);
|
|
328
|
+
if (input.appliedProfile) {
|
|
329
|
+
addSanitizedHeader(
|
|
330
|
+
headers,
|
|
331
|
+
USAGE_ATTRIBUTION_HEADER_NAMES.inferenceProfileSource,
|
|
332
|
+
input.profileSource,
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
addSanitizedHeader(
|
|
336
|
+
headers,
|
|
337
|
+
USAGE_ATTRIBUTION_HEADER_NAMES.resolvedProvider,
|
|
338
|
+
input.resolvedProvider,
|
|
339
|
+
);
|
|
340
|
+
addSanitizedHeader(
|
|
341
|
+
headers,
|
|
342
|
+
USAGE_ATTRIBUTION_HEADER_NAMES.resolvedModel,
|
|
343
|
+
input.resolvedModel,
|
|
344
|
+
);
|
|
345
|
+
return headers;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function addSanitizedHeader(
|
|
349
|
+
headers: Record<string, string>,
|
|
350
|
+
name: string,
|
|
351
|
+
value: unknown,
|
|
352
|
+
): void {
|
|
353
|
+
const sanitized = sanitizeUsageMetadataValue(value);
|
|
354
|
+
if (sanitized != null) {
|
|
355
|
+
headers[name] = sanitized;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
277
359
|
/**
|
|
278
360
|
* `RetryProvider` sets `retriesExhausted = true` on the final thrown error
|
|
279
361
|
* when the retry loop burned through all attempts against a retryable error
|
|
@@ -289,7 +371,10 @@ export class RetryProvider implements Provider {
|
|
|
289
371
|
return this.inner.tokenEstimationProvider;
|
|
290
372
|
}
|
|
291
373
|
|
|
292
|
-
constructor(
|
|
374
|
+
constructor(
|
|
375
|
+
private readonly inner: Provider,
|
|
376
|
+
private readonly options: { forwardUsageAttributionHeaders?: boolean } = {},
|
|
377
|
+
) {
|
|
293
378
|
this.name = inner.name;
|
|
294
379
|
}
|
|
295
380
|
|
|
@@ -302,7 +387,10 @@ export class RetryProvider implements Provider {
|
|
|
302
387
|
let lastError: unknown;
|
|
303
388
|
let didRetry = false;
|
|
304
389
|
|
|
305
|
-
const normalizedOptions = normalizeSendMessageOptions(this.name, options
|
|
390
|
+
const normalizedOptions = normalizeSendMessageOptions(this.name, options, {
|
|
391
|
+
forwardUsageAttributionHeaders:
|
|
392
|
+
this.options.forwardUsageAttributionHeaders === true,
|
|
393
|
+
});
|
|
306
394
|
|
|
307
395
|
for (let attempt = 0; attempt <= DEFAULT_MAX_RETRIES; attempt++) {
|
|
308
396
|
try {
|
package/src/providers/types.ts
CHANGED
|
@@ -156,6 +156,19 @@ export interface SendMessageConfig {
|
|
|
156
156
|
* silently fall through.
|
|
157
157
|
*/
|
|
158
158
|
overrideProfile?: string;
|
|
159
|
+
/**
|
|
160
|
+
* Internal per-request HTTP headers for managed-proxy usage attribution.
|
|
161
|
+
* Provider clients may pass these through SDK request options only when the
|
|
162
|
+
* transport is Vellum-managed, and must never include this object in provider
|
|
163
|
+
* JSON request bodies.
|
|
164
|
+
*/
|
|
165
|
+
usageAttributionHeaders?: Record<string, string>;
|
|
166
|
+
/**
|
|
167
|
+
* Controls local usage-ledger writes for attributed provider calls.
|
|
168
|
+
* Defaults to `auto`; conversation paths that aggregate usage separately
|
|
169
|
+
* set `manual` to avoid double-counting.
|
|
170
|
+
*/
|
|
171
|
+
usageTracking?: "auto" | "manual";
|
|
159
172
|
effort?: "none" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
160
173
|
speed?: "standard" | "fast";
|
|
161
174
|
verbosity?: "low" | "medium" | "high";
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { recordUsageEvent } from "../memory/llm-usage-store.js";
|
|
2
|
+
import { resolveUsageAttribution } from "../usage/attribution.js";
|
|
3
|
+
import {
|
|
4
|
+
buildPricingUsageFromResponse,
|
|
5
|
+
resolveStructuredPricing,
|
|
6
|
+
} from "../usage/pricing.js";
|
|
7
|
+
import { getLogger } from "../util/logger.js";
|
|
8
|
+
import type {
|
|
9
|
+
Message,
|
|
10
|
+
Provider,
|
|
11
|
+
ProviderResponse,
|
|
12
|
+
SendMessageOptions,
|
|
13
|
+
ToolDefinition,
|
|
14
|
+
} from "./types.js";
|
|
15
|
+
|
|
16
|
+
const log = getLogger("provider-usage-tracking");
|
|
17
|
+
|
|
18
|
+
export class UsageTrackingProvider implements Provider {
|
|
19
|
+
public readonly name: string;
|
|
20
|
+
public readonly tokenEstimationProvider?: string;
|
|
21
|
+
|
|
22
|
+
constructor(private readonly inner: Provider) {
|
|
23
|
+
this.name = inner.name;
|
|
24
|
+
this.tokenEstimationProvider = inner.tokenEstimationProvider;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async sendMessage(
|
|
28
|
+
messages: Message[],
|
|
29
|
+
tools?: ToolDefinition[],
|
|
30
|
+
systemPrompt?: string,
|
|
31
|
+
options?: SendMessageOptions,
|
|
32
|
+
): Promise<ProviderResponse> {
|
|
33
|
+
const response = await this.inner.sendMessage(
|
|
34
|
+
messages,
|
|
35
|
+
tools,
|
|
36
|
+
systemPrompt,
|
|
37
|
+
options,
|
|
38
|
+
);
|
|
39
|
+
this.recordUsage(response, options);
|
|
40
|
+
return response;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private recordUsage(
|
|
44
|
+
response: ProviderResponse,
|
|
45
|
+
options?: SendMessageOptions,
|
|
46
|
+
): void {
|
|
47
|
+
const config = options?.config;
|
|
48
|
+
if (!config?.callSite) return;
|
|
49
|
+
if (config.usageTracking === "manual") return;
|
|
50
|
+
if (response.usage.inputTokens <= 0 && response.usage.outputTokens <= 0) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const attribution = resolveUsageAttribution({
|
|
56
|
+
callSite: config.callSite,
|
|
57
|
+
overrideProfile: config.overrideProfile,
|
|
58
|
+
});
|
|
59
|
+
const providerName = response.actualProvider ?? this.inner.name;
|
|
60
|
+
const pricingUsage = buildPricingUsageFromResponse(
|
|
61
|
+
providerName,
|
|
62
|
+
response,
|
|
63
|
+
);
|
|
64
|
+
const pricing = resolveStructuredPricing(
|
|
65
|
+
providerName,
|
|
66
|
+
response.model,
|
|
67
|
+
pricingUsage,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
recordUsageEvent(
|
|
71
|
+
{
|
|
72
|
+
actor: "llm_call_site",
|
|
73
|
+
provider: providerName,
|
|
74
|
+
model: response.model,
|
|
75
|
+
inputTokens: pricingUsage.directInputTokens,
|
|
76
|
+
outputTokens: pricingUsage.outputTokens,
|
|
77
|
+
cacheCreationInputTokens: pricingUsage.cacheCreationInputTokens,
|
|
78
|
+
cacheReadInputTokens: pricingUsage.cacheReadInputTokens,
|
|
79
|
+
conversationId: null,
|
|
80
|
+
runId: null,
|
|
81
|
+
requestId: null,
|
|
82
|
+
callSite: attribution.callSite,
|
|
83
|
+
inferenceProfile: attribution.appliedProfile,
|
|
84
|
+
inferenceProfileSource: attribution.profileSource,
|
|
85
|
+
llmCallCount: 1,
|
|
86
|
+
},
|
|
87
|
+
pricing,
|
|
88
|
+
);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
log.warn(
|
|
91
|
+
{ err, callSite: config.callSite },
|
|
92
|
+
"Failed to auto-record provider usage event (non-fatal)",
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
package/src/runtime/AGENTS.md
CHANGED
|
@@ -12,6 +12,10 @@ The single HTTP send endpoint is `POST /v1/messages`. Key behaviors:
|
|
|
12
12
|
|
|
13
13
|
Do NOT add new send endpoints. All message ingress should go through `POST /v1/messages` (HTTP).
|
|
14
14
|
|
|
15
|
+
### GET handler idempotency
|
|
16
|
+
|
|
17
|
+
GET handlers must be safe and side-effect-free — they must not enqueue background jobs, mutate database state, or trigger writes. If a feature needs server-initiated work in response to a client request, use an explicit POST endpoint or a push-based flow (SSE event → client refetch). See [RFC 9110 §9.2.1 — Safe Methods](https://httpwg.org/specs/rfc9110.html#safe.methods).
|
|
18
|
+
|
|
15
19
|
### Approvals (confirmations, secrets, trust rules)
|
|
16
20
|
|
|
17
21
|
Approvals are **orthogonal to message sending**. The assistant asks for approval whenever it needs one — this is a separate concern from how a message enters the system.
|
|
@@ -65,11 +69,11 @@ Host browser allows the assistant to proxy CDP (Chrome DevTools Protocol) JSON-R
|
|
|
65
69
|
|
|
66
70
|
The `chrome-extension` interface in `INTERFACE_IDS` is a non-interactive transport that supports only the `host_browser` capability — it does NOT support `host_bash`, `host_file`, or `host_cu`. This is encoded in `supportsHostProxy(id, capability)`: passing a capability argument returns `true` for `chrome-extension` only when the capability is `host_browser`; the no-arg form returns `false` for `chrome-extension` (so legacy desktop-only call sites that assume full-desktop proxy availability continue to gate correctly).
|
|
67
71
|
|
|
68
|
-
For **self-hosted** deployments, `host_browser_request` frames are routed through the `ChromeExtensionRegistry` singleton (`runtime/chrome-extension-registry.ts`), which tracks active chrome-extension WebSocket connections keyed by `(guardianId, clientInstanceId)`. The registry is populated on WebSocket `open` and drained on `close` inside `http-server.ts`'s `/v1/browser-relay` handlers — see the `wsType === "browser-relay"` branches. For **cloud/platform-hosted** deployments, the chrome extension connects via SSE (`GET /v1/events` with `X-Vellum-Interface-Id: chrome-extension`) and `host_browser_request` frames travel through `assistantEventHub` to the SSE stream. The extension POSTs results back to `POST /v1/host-browser-result`. Transport selection is handled by `
|
|
72
|
+
For **self-hosted** deployments, `host_browser_request` frames are routed through the `ChromeExtensionRegistry` singleton (`runtime/chrome-extension-registry.ts`), which tracks active chrome-extension WebSocket connections keyed by `(guardianId, clientInstanceId)`. The registry is populated on WebSocket `open` and drained on `close` inside `http-server.ts`'s `/v1/browser-relay` handlers — see the `wsType === "browser-relay"` branches. For **cloud/platform-hosted** deployments, the chrome extension connects via SSE (`GET /v1/events` with `X-Vellum-Interface-Id: chrome-extension`) and `host_browser_request` frames travel through `assistantEventHub` to the SSE stream. The extension POSTs results back to `POST /v1/host-browser-result`. Transport selection is handled by `HostBrowserProxy`, which publishes events to the `assistantEventHub` with `targetCapability: "host_browser"` — the hub delivers to whichever subscriber (chrome-extension or macOS client) has the `host_browser` capability. For macOS, `host_browser_request` frames travel through `assistantEventHub` (SSE) by default; when the guardian also has an active extension connection, the registry-routed WebSocket sender takes precedence.
|
|
69
73
|
|
|
70
74
|
A single guardian may have multiple parallel extension installs connected at once (two Chrome profiles, two desktops sharing a sync identity). Each install generates a stable `clientInstanceId` on first run, persists it in `chrome.storage.local`, and sends it on every WebSocket handshake as a query param (`clientInstanceId=...`) or header (`x-client-instance-id`). The registry keys inner entries by that id so sibling installs don't evict each other on register/unregister. The default `send(guardianId, msg)` path routes to whichever instance has the most recent activity (`lastActiveAt`); `sendToInstance(guardianId, clientInstanceId, msg)` pins a specific install. Older extension builds that omit the id get a connection-scoped `legacy:<connectionId>` fallback key so they degrade gracefully to single-instance semantics.
|
|
71
75
|
|
|
72
|
-
`Conversation.hostBrowserSenderOverride` is the integration point between the turn layer and the
|
|
76
|
+
`Conversation.hostBrowserSenderOverride` is the integration point between the turn layer and the proxy. When any turn enters the routes layer and the guardian has an active extension connection in the `ChromeExtensionRegistry`, `conversation-routes.ts` resolves the registry entry and sets the override to a sender that writes to that WebSocket. This applies to chrome-extension turns (where the registry is the only transport) and macOS turns (where the extension connection lets browser tools route through the user's real Chrome session instead of cdp-inspect/local). `Conversation.restoreBrowserProxyAvailability()` re-threads the override on queue drain — without this, the drain path would clobber the registry-routed sender with the default `sendToClient` (pointed at the SSE hub) and `host_browser_request` frames would stop reaching the extension mid-queue.
|
|
73
77
|
|
|
74
78
|
Capability token bootstrap for self-hosted deployments is handled by the gateway (`gateway/src/http/routes/browser-extension-pair.ts`) which mints a guardian-bound HMAC capability token. The daemon delegates token verification to the gateway via IPC (`verify_capability_token`) — it must never read secrets from `GATEWAY_SECURITY_DIR` or any other gateway-owned directory. Cloud deployments issue guardian-bound JWTs via the gateway's WorkOS-backed flow.
|
|
75
79
|
|
|
@@ -81,7 +85,7 @@ On macOS-originated turns, the CDP factory (`tools/browser/cdp-client/factory.ts
|
|
|
81
85
|
|
|
82
86
|
| Priority | Backend | Condition | Transport |
|
|
83
87
|
| -------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
84
|
-
| 1 | **Extension / host proxy** | `hostBrowserProxy` present AND `isAvailable()` returns `true`. On macOS, the proxy is always provisioned. On other interfaces, requires an active
|
|
88
|
+
| 1 | **Extension / host proxy** | `hostBrowserProxy` present AND `isAvailable()` returns `true`. On macOS, the proxy is always provisioned. On other interfaces, requires an active hub subscriber with `host_browser` capability | WS via `ChromeExtensionRegistry` (self-hosted), SSE via `assistantEventHub` with `targetCapability: "host_browser"` (cloud extension or macOS) |
|
|
85
89
|
| 2 | **cdp-inspect** | (a) `hostBrowser.cdpInspect.enabled` is `true` in config, OR (b) `transportInterface === "macos"` AND `desktopAuto.enabled` is `true` (default) AND the cooldown from a prior failure is not active | Direct CDP WebSocket to `localhost:9222` |
|
|
86
90
|
| 3 | **Local** | Always present as the final fallback | In-process Playwright CDP via `browserManager` |
|
|
87
91
|
|
|
@@ -89,9 +93,9 @@ On macOS-originated turns, the CDP factory (`tools/browser/cdp-client/factory.ts
|
|
|
89
93
|
|
|
90
94
|
The "extension" backend label is a misnomer inherited from the original Phase 2 design where only the Chrome Extension provided host-browser access. In the current architecture, two transports can power this backend:
|
|
91
95
|
|
|
92
|
-
- **Extension WebSocket** (self-hosted): When the `ChromeExtensionRegistry` has an active entry for the guardian,
|
|
93
|
-
- **Extension SSE** (cloud/platform): When no WebSocket entry exists
|
|
94
|
-
- **macOS SSE bridge**: When the macOS desktop client is connected but no extension is present,
|
|
96
|
+
- **Extension WebSocket** (self-hosted): When the `ChromeExtensionRegistry` has an active entry for the guardian, the registry-routed sender delivers frames over the `/v1/browser-relay` WebSocket to the Chrome extension, which executes CDP commands via `chrome.debugger`.
|
|
97
|
+
- **Extension SSE** (cloud/platform): When no WebSocket entry exists, `HostBrowserProxy.send()` publishes to `assistantEventHub` with `targetCapability: "host_browser"`. The hub delivers the event to the chrome-extension subscriber (which registered with that capability via SSE). The extension POSTs results back to `/v1/host-browser-result`. This path is used for any `canServiceSseBrowser()` interface (`web`, `chrome-extension`, `macos`).
|
|
98
|
+
- **macOS SSE bridge**: When the macOS desktop client is connected but no extension is present, the same hub publish with `targetCapability: "host_browser"` delivers to the macOS subscriber (which has all host-proxy capabilities). The desktop client executes CDP commands against the local Chrome and POSTs results back to `/v1/host-browser-result`.
|
|
95
99
|
|
|
96
100
|
All three transports use the same `HostBrowserProxy` → `ExtensionCdpClient` pipeline. The `browser_status` output distinguishes the transport via the `details.transport` field: `"extension-ws"` or `"macos-sse"`.
|
|
97
101
|
|
|
@@ -402,6 +402,95 @@ describe("wakeAgentForOpportunity", () => {
|
|
|
402
402
|
expect(processing).toBe(false);
|
|
403
403
|
});
|
|
404
404
|
|
|
405
|
+
test("applies caller-supplied trustContext to the target before the agent loop runs", async () => {
|
|
406
|
+
// Background system jobs (memory consolidation, update-bulletin) need
|
|
407
|
+
// guardian trust to clear the side-effect approval gate. The wake must
|
|
408
|
+
// call setTrustContext BEFORE agentLoop.run so the per-turn snapshot
|
|
409
|
+
// captures the elevated trust.
|
|
410
|
+
const trustCalls: Array<{ ctx: unknown; before: number }> = [];
|
|
411
|
+
const runCalls: number[] = [];
|
|
412
|
+
let callOrder = 0;
|
|
413
|
+
|
|
414
|
+
const history: Message[] = [];
|
|
415
|
+
let processing = false;
|
|
416
|
+
const target: WakeTarget = {
|
|
417
|
+
conversationId: "conv-trust",
|
|
418
|
+
agentLoop: {
|
|
419
|
+
run: async (input) => {
|
|
420
|
+
runCalls.push(callOrder++);
|
|
421
|
+
return [...input];
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
getMessages: () => history,
|
|
425
|
+
pushMessage: () => {},
|
|
426
|
+
emitAgentEvent: () => {},
|
|
427
|
+
isProcessing: () => processing,
|
|
428
|
+
markProcessing: (on) => {
|
|
429
|
+
processing = on;
|
|
430
|
+
},
|
|
431
|
+
persistTailMessage: async () => {},
|
|
432
|
+
setTrustContext: (ctx) => {
|
|
433
|
+
trustCalls.push({ ctx, before: callOrder++ });
|
|
434
|
+
},
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
await wakeAgentForOpportunity(
|
|
438
|
+
{
|
|
439
|
+
conversationId: "conv-trust",
|
|
440
|
+
hint: "consolidate memory",
|
|
441
|
+
source: "memory_v2_consolidation",
|
|
442
|
+
trustContext: { sourceChannel: "vellum", trustClass: "guardian" },
|
|
443
|
+
},
|
|
444
|
+
{ resolveTarget: async () => target },
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
expect(trustCalls).toHaveLength(1);
|
|
448
|
+
expect(trustCalls[0]!.ctx).toEqual({
|
|
449
|
+
sourceChannel: "vellum",
|
|
450
|
+
trustClass: "guardian",
|
|
451
|
+
});
|
|
452
|
+
// setTrustContext fired strictly before agentLoop.run.
|
|
453
|
+
expect(runCalls).toHaveLength(1);
|
|
454
|
+
expect(trustCalls[0]!.before).toBeLessThan(runCalls[0]!);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
test("does not call setTrustContext when no trustContext is supplied", async () => {
|
|
458
|
+
const trustCalls: unknown[] = [];
|
|
459
|
+
const history: Message[] = [];
|
|
460
|
+
let processing = false;
|
|
461
|
+
const target: WakeTarget = {
|
|
462
|
+
conversationId: "conv-no-trust",
|
|
463
|
+
agentLoop: {
|
|
464
|
+
run: async (input) => [...input],
|
|
465
|
+
},
|
|
466
|
+
getMessages: () => history,
|
|
467
|
+
pushMessage: () => {},
|
|
468
|
+
emitAgentEvent: () => {},
|
|
469
|
+
isProcessing: () => processing,
|
|
470
|
+
markProcessing: (on) => {
|
|
471
|
+
processing = on;
|
|
472
|
+
},
|
|
473
|
+
persistTailMessage: async () => {},
|
|
474
|
+
setTrustContext: (ctx) => {
|
|
475
|
+
trustCalls.push(ctx);
|
|
476
|
+
},
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
await wakeAgentForOpportunity(
|
|
480
|
+
{
|
|
481
|
+
conversationId: "conv-no-trust",
|
|
482
|
+
hint: "x",
|
|
483
|
+
source: "t",
|
|
484
|
+
},
|
|
485
|
+
{ resolveTarget: async () => target },
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
// Inbound-message conversations populate trust via processMessage().
|
|
489
|
+
// Without an explicit opt-in from the caller, the wake must not
|
|
490
|
+
// overwrite whatever the conversation already holds.
|
|
491
|
+
expect(trustCalls).toHaveLength(0);
|
|
492
|
+
});
|
|
493
|
+
|
|
405
494
|
test("two concurrent wakes on the same conversation are serialized", async () => {
|
|
406
495
|
// Build a target whose agentLoop.run resolves only when we signal.
|
|
407
496
|
const gate1 = Promise.withResolvers<void>();
|
|
@@ -41,6 +41,9 @@
|
|
|
41
41
|
*/
|
|
42
42
|
|
|
43
43
|
import type { AgentEvent, AgentLoop } from "../agent/loop.js";
|
|
44
|
+
import { resolveEffectiveContextWindow } from "../config/llm-context-resolution.js";
|
|
45
|
+
import { getConfig } from "../config/loader.js";
|
|
46
|
+
import type { TrustContext } from "../daemon/trust-context.js";
|
|
44
47
|
import { getConversationOverrideProfile } from "../memory/conversation-crud.js";
|
|
45
48
|
import type { Message } from "../providers/types.js";
|
|
46
49
|
import { getLogger } from "../util/logger.js";
|
|
@@ -137,12 +140,30 @@ export interface WakeTarget {
|
|
|
137
140
|
* typically omit it.
|
|
138
141
|
*/
|
|
139
142
|
onWakeProducedOutput?(source: string, hint: string, surfaceId: string): void;
|
|
143
|
+
/**
|
|
144
|
+
* Apply a trust context to the underlying conversation before the agent
|
|
145
|
+
* loop runs. Internal background jobs (memory consolidation, update
|
|
146
|
+
* bulletin) use this to declare guardian trust so side-effect tools
|
|
147
|
+
* (file_edit, file_write, bash) clear the approval gate. Inbound message
|
|
148
|
+
* conversations populate trust via `processMessage()` and don't pass
|
|
149
|
+
* `trustContext` through the wake.
|
|
150
|
+
*/
|
|
151
|
+
setTrustContext?(ctx: TrustContext): void;
|
|
140
152
|
}
|
|
141
153
|
|
|
142
154
|
export interface WakeOptions {
|
|
143
155
|
conversationId: string;
|
|
144
156
|
hint: string;
|
|
145
157
|
source: string;
|
|
158
|
+
/**
|
|
159
|
+
* Optional trust context to apply to the conversation before the agent
|
|
160
|
+
* loop runs. Required for internal background jobs that need elevated
|
|
161
|
+
* trust to invoke side-effect tools — without it the loop falls back to
|
|
162
|
+
* `trustClass: "unknown"` and side-effect tools are blocked. Caller
|
|
163
|
+
* should pass `{ sourceChannel: "vellum", trustClass: "guardian" }` for
|
|
164
|
+
* assistant-self-maintenance jobs.
|
|
165
|
+
*/
|
|
166
|
+
trustContext?: TrustContext;
|
|
146
167
|
}
|
|
147
168
|
|
|
148
169
|
/**
|
|
@@ -370,6 +391,13 @@ export async function wakeAgentForOpportunity(
|
|
|
370
391
|
return { invoked: false, producedToolCalls: false, reason: "timeout" };
|
|
371
392
|
}
|
|
372
393
|
|
|
394
|
+
// Apply caller-supplied trust before the agent loop reads its per-turn
|
|
395
|
+
// snapshot. Background jobs without an inbound message use this to
|
|
396
|
+
// declare guardian trust so side-effect tools clear the approval gate.
|
|
397
|
+
if (opts.trustContext && target.setTrustContext) {
|
|
398
|
+
target.setTrustContext(opts.trustContext);
|
|
399
|
+
}
|
|
400
|
+
|
|
373
401
|
const baseline = target.getMessages();
|
|
374
402
|
const hintContent = `[opportunity:${source}] ${hint}`;
|
|
375
403
|
// Sandwich the hint as an assistant message between two hardcoded
|
|
@@ -409,10 +437,18 @@ export async function wakeAgentForOpportunity(
|
|
|
409
437
|
// Honor the conversation's pinned inference-profile override (if any).
|
|
410
438
|
// Without this, scheduled-task wakes and other opportunity wakes bypass
|
|
411
439
|
// `runAgentLoopImpl` entirely and execute under workspace defaults,
|
|
412
|
-
// silently violating the user's pinned preference.
|
|
413
|
-
//
|
|
440
|
+
// silently violating the user's pinned preference. Resolve the effective
|
|
441
|
+
// context budget here as well because wakes bypass the normal user-turn
|
|
442
|
+
// path that computes it for tool-result truncation. Read before
|
|
443
|
+
// `markProcessing(true)` so a thrown DB/config read can't strand the
|
|
414
444
|
// processing flag.
|
|
415
445
|
const overrideProfile = getConversationOverrideProfile(conversationId);
|
|
446
|
+
const config = getConfig();
|
|
447
|
+
const effectiveContextWindow = resolveEffectiveContextWindow({
|
|
448
|
+
llm: config.llm,
|
|
449
|
+
callSite: "mainAgent",
|
|
450
|
+
overrideProfile,
|
|
451
|
+
});
|
|
416
452
|
|
|
417
453
|
// Mark processing for the duration of the run so a concurrent user
|
|
418
454
|
// send is queued by `enqueueMessage()` rather than spawning a second
|
|
@@ -442,6 +478,7 @@ export async function wakeAgentForOpportunity(
|
|
|
442
478
|
"mainAgent",
|
|
443
479
|
undefined, // turnContext
|
|
444
480
|
overrideProfile,
|
|
481
|
+
effectiveContextWindow.maxInputTokens,
|
|
445
482
|
);
|
|
446
483
|
} catch (err) {
|
|
447
484
|
// Capture the error for post-finally logging, then short-circuit
|