@vellumai/assistant 0.8.5 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +33 -1
- package/ARCHITECTURE.md +1 -1
- package/bunfig.toml +6 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +1900 -166
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
- package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/annotate-risk-options.test.ts +1 -0
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +9 -13
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +9 -25
- package/src/__tests__/audit-log-rotation.test.ts +2 -2
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +5 -8
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +3 -2
- package/src/__tests__/call-controller.test.ts +3 -2
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +3 -2
- package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +320 -3
- package/src/__tests__/checker.test.ts +12 -12
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +1 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +7 -5
- package/src/__tests__/computer-use-tools.test.ts +12 -14
- package/src/__tests__/config-loader-backfill.test.ts +13 -28
- package/src/__tests__/config-loader-corrupt.test.ts +5 -5
- package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
- package/src/__tests__/config-schema.test.ts +10 -10
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-token-estimator.test.ts +22 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +34 -0
- package/src/__tests__/conversation-agent-loop.test.ts +488 -2
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +29 -19
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-attention-store.test.ts +101 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-error.test.ts +30 -0
- package/src/__tests__/conversation-fork-crud.test.ts +69 -8
- package/src/__tests__/conversation-fork-route.test.ts +3 -2
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
- package/src/__tests__/conversation-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
- package/src/__tests__/conversation-load-history-stripped.test.ts +1 -0
- package/src/__tests__/conversation-pairing.test.ts +53 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +33 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +38 -142
- package/src/__tests__/conversation-slash-queue.test.ts +84 -32
- package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
- package/src/__tests__/conversation-sync-tags.test.ts +128 -12
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
- package/src/__tests__/conversation-usage.test.ts +1 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -0
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +10 -12
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -5
- package/src/__tests__/credential-vault-unit.test.ts +19 -19
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +56 -2
- package/src/__tests__/db-connection-isolation.test.ts +7 -6
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +58 -41
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +0 -33
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +26 -40
- package/src/__tests__/document-create-dedupe.test.ts +189 -0
- package/src/__tests__/document-find-replace.test.ts +3 -2
- package/src/__tests__/document-tool-security.test.ts +81 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
- package/src/__tests__/encrypted-store.test.ts +11 -9
- package/src/__tests__/feature-flag-test-helpers.ts +53 -0
- package/src/__tests__/filing-service.test.ts +1 -0
- package/src/__tests__/first-greeting.test.ts +62 -12
- package/src/__tests__/gateway-flag-listener.test.ts +0 -1
- package/src/__tests__/gemini-provider.test.ts +26 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-outbound-http.test.ts +3 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/host-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-shell-tool.test.ts +5 -4
- package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +29 -7
- package/src/__tests__/identity-intro-cache.test.ts +133 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/injector-disk-pressure.test.ts +3 -17
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-resolver.test.ts +331 -0
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +14 -0
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/messaging-send-tool.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +3 -3
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/oauth-commands-routes.test.ts +37 -0
- package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
- package/src/__tests__/oauth-store.test.ts +3 -2
- package/src/__tests__/onboarding-template-contract.test.ts +3 -2
- package/src/__tests__/openai-provider.test.ts +8 -9
- package/src/__tests__/openai-responses-provider.test.ts +70 -10
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/plugin-bootstrap.test.ts +9 -11
- package/src/__tests__/plugin-tool-contribution.test.ts +41 -38
- package/src/__tests__/process-message-background-slack.test.ts +21 -16
- package/src/__tests__/process-message-display-content.test.ts +19 -22
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- package/src/__tests__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +82 -76
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/schedule-store.test.ts +16 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +81 -42
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +14 -16
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +44 -30
- package/src/__tests__/skill-projection.benchmark.test.ts +5 -7
- package/src/__tests__/skill-tool-factory.test.ts +96 -95
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +5 -4
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +1 -0
- package/src/__tests__/system-prompt.test.ts +38 -0
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +20 -7
- package/src/__tests__/tool-executor.test.ts +55 -10
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/twilio-routes.test.ts +3 -2
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
- package/src/__tests__/voice-session-bridge.test.ts +37 -28
- package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
- package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
- package/src/acp/session-manager.ts +5 -6
- package/src/agent/loop.ts +80 -0
- package/src/api/README.md +124 -2
- package/src/api/constants/call-sites.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +51 -0
- package/src/api/events/assistant-text-delta.ts +32 -0
- package/src/api/events/assistant-turn-start.ts +33 -0
- package/src/api/events/document-comment-created.ts +48 -0
- package/src/api/events/document-comment-deleted.ts +24 -0
- package/src/api/events/document-comment-reopened.ts +25 -0
- package/src/api/events/document-comment-resolved.ts +27 -0
- package/src/api/events/generation-cancelled.ts +24 -0
- package/src/api/events/generation-handoff.ts +41 -0
- package/src/api/events/message-complete.ts +42 -0
- package/src/api/events/open-url.ts +30 -0
- package/src/{events → api/events}/relationship-state-updated.ts +3 -3
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +128 -3
- package/src/api/responses/llm-context-response.ts +39 -0
- package/src/api/responses/llm-request-log-entry.ts +93 -0
- package/src/api/responses/memory-recall-log.ts +65 -0
- package/src/api/responses/memory-v2-activation-log.ts +78 -0
- package/src/background-wake/background-wake-routes.test.ts +687 -52
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +2 -2
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/voice-session-bridge.ts +4 -4
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/memory-v3-render.ts +147 -0
- package/src/cli/commands/memory-v3.ts +255 -4
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +2 -0
- package/src/config/assistant-feature-flags.ts +23 -42
- package/src/config/bundled-skills/document-editor/SKILL.md +5 -1
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/call-site-defaults.ts +1 -1
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +17 -17
- package/src/config/llm-context-resolution.ts +10 -1
- package/src/config/llm-resolver.ts +121 -15
- package/src/config/loader.ts +4 -5
- package/src/config/schemas/__tests__/memory-v2.test.ts +15 -0
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +90 -1
- package/src/config/schemas/memory-v2.ts +26 -0
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/token-estimator.ts +10 -5
- package/src/credential-execution/executable-discovery.ts +40 -0
- package/src/credential-execution/process-manager.ts +6 -2
- package/src/credential-health/credential-health-service.ts +125 -40
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -2
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +389 -68
- package/src/daemon/conversation-agent-loop.ts +132 -28
- package/src/daemon/conversation-error.ts +33 -5
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +29 -9
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +33 -48
- package/src/daemon/conversation.ts +26 -46
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +27 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/lifecycle.ts +12 -12
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +10 -17
- package/src/daemon/message-types/conversations.ts +20 -22
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -2
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +23 -38
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/process-message.ts +9 -9
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +16 -0
- package/src/daemon/switch-inference-profile-tool.ts +13 -3
- package/src/daemon/tool-setup-types.ts +0 -6
- package/src/daemon/wake-target-adapter.ts +10 -0
- package/src/documents/document-store.ts +38 -0
- package/src/export/__tests__/transcript-formatter.test.ts +1 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +29 -0
- package/src/heartbeat/heartbeat-service.ts +63 -0
- package/src/home/__tests__/feed-writer.test.ts +161 -0
- package/src/home/__tests__/post-connect-feed.test.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +55 -59
- package/src/home/feed-writer.ts +146 -7
- package/src/home/suggested-prompts.ts +27 -145
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
- package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
- package/src/ipc/skill-routes/memory.ts +4 -3
- package/src/ipc/skill-routes/registries.ts +28 -29
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +1 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +352 -112
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +4 -0
- package/src/memory/db-singleton.ts +77 -0
- package/src/memory/delivery-channels.ts +82 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
- package/src/memory/graph/retriever.test.ts +3 -3
- package/src/memory/job-handlers/embedding.test.ts +3 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs-worker.ts +12 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +80 -0
- package/src/memory/llm-request-log-source-local.ts +24 -0
- package/src/memory/llm-request-log-source.ts +31 -0
- package/src/memory/llm-request-log-store.ts +188 -3
- package/src/memory/memory-v2-activation-log-store.ts +95 -1
- package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- package/src/memory/migrations/index.ts +2 -0
- package/src/memory/schema/conversations.ts +9 -1
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/harness-metrics.test.ts +9 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +9 -4
- package/src/memory/v2/__tests__/harness-runner.test.ts +26 -0
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/metrics.ts +5 -1
- package/src/memory/v2/harness/replay-input.ts +19 -3
- package/src/memory/v2/harness/runner.ts +6 -0
- package/src/memory/v2/harness/trace.ts +6 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +2 -4
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edges.test.ts +144 -1
- package/src/memory/v3/__tests__/filter.test.ts +48 -0
- package/src/memory/v3/__tests__/gate.test.ts +96 -33
- package/src/memory/v3/__tests__/index-composition.test.ts +58 -0
- package/src/memory/v3/__tests__/loop.test.ts +250 -5
- package/src/memory/v3/__tests__/scouts.test.ts +49 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +88 -2
- package/src/memory/v3/__tests__/traversal.test.ts +39 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +77 -0
- package/src/memory/v3/__tests__/validate.test.ts +32 -0
- package/src/memory/v3/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edges.ts +58 -21
- package/src/memory/v3/filter.ts +27 -22
- package/src/memory/v3/gate.ts +51 -36
- package/src/memory/v3/index-composition.ts +18 -5
- package/src/memory/v3/loop.ts +65 -17
- package/src/memory/v3/scouts.ts +15 -4
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +44 -2
- package/src/memory/v3/traversal.ts +6 -1
- package/src/memory/v3/tree-walk.ts +6 -1
- package/src/memory/v3/validate.ts +56 -33
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +23 -3
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +11 -1
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +37 -0
- package/src/oauth/byo-connection.test.ts +67 -3
- package/src/oauth/byo-connection.ts +32 -5
- package/src/oauth/connect-orchestrator.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +76 -0
- package/src/oauth/connection-resolver.ts +49 -10
- package/src/oauth/manual-token-connection.ts +51 -3
- package/src/oauth/seed-providers.ts +3 -0
- package/src/permissions/approval-policy.test.ts +19 -5
- package/src/permissions/approval-policy.ts +14 -3
- package/src/permissions/checker.ts +21 -8
- package/src/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- package/src/plugins/defaults/injectors.ts +2 -8
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/types.ts +57 -13
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/system-prompt.ts +38 -40
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +7 -11
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -4
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/call-site-routing.ts +33 -9
- package/src/providers/connection-model-compat.ts +23 -0
- package/src/providers/connection-resolution.ts +39 -20
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +24 -3
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/model-catalog.ts +35 -1
- package/src/providers/model-intents.ts +3 -3
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
- package/src/providers/openai/chat-completions-provider.ts +110 -12
- package/src/providers/openai/codex-models.ts +2 -0
- package/src/providers/openai/responses-provider.ts +53 -53
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +18 -9
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +16 -4
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/types.ts +9 -0
- package/src/runtime/__tests__/agent-wake.test.ts +1 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/auth/route-policy.ts +10 -0
- package/src/runtime/channel-readiness-service.ts +68 -0
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +47 -14
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/migrations/vbundle-builder.ts +3 -2
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +51 -3
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/app-management-routes.ts +111 -4
- package/src/runtime/routes/background-wake-routes.ts +188 -20
- package/src/runtime/routes/btw-routes.ts +4 -4
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +147 -0
- package/src/runtime/routes/conversation-management-routes.ts +39 -14
- package/src/runtime/routes/conversation-query-routes.ts +60 -10
- package/src/runtime/routes/conversation-routes.ts +186 -140
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/documents-routes.ts +10 -1
- package/src/runtime/routes/group-routes.ts +11 -0
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- package/src/runtime/routes/identity-intro-cache.ts +61 -16
- package/src/runtime/routes/identity-routes.ts +30 -9
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
- package/src/runtime/routes/integrations/vercel.ts +15 -0
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-v3-routes.ts +160 -2
- package/src/runtime/routes/migration-routes.ts +20 -13
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- package/src/runtime/routes/surface-action-routes.ts +1 -38
- package/src/runtime/routes/surface-content-routes.ts +12 -5
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- package/src/runtime/sync/resource-sync-events.ts +1 -1
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- package/src/schedule/schedule-store.ts +8 -1
- package/src/schedule/scheduler.ts +111 -15
- package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
- package/src/security/encrypted-store.ts +7 -16
- package/src/security/store-path-override.ts +61 -0
- package/src/signals/user-message.ts +5 -8
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +13 -13
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -2
- package/src/tools/apps/definitions.ts +35 -21
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/computer-use/definitions.ts +268 -266
- package/src/tools/document/document-tool.ts +131 -8
- package/src/tools/execution-target.ts +2 -5
- package/src/tools/executor.ts +18 -55
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/mcp/mcp-tool-factory.ts +0 -2
- package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
- package/src/tools/network/__tests__/web-search.test.ts +211 -3
- package/src/tools/network/managed-search-proxy.ts +183 -0
- package/src/tools/network/web-search.ts +199 -44
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +146 -103
- package/src/tools/schedule/create.ts +1 -1
- package/src/tools/skills/skill-tool-factory.ts +17 -36
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +17 -15
- package/src/tools/ui-surface/definitions.ts +98 -86
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/util/browser.ts +7 -2
- package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
- package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
- package/src/workspace/migrations/registry.ts +4 -0
|
@@ -29,10 +29,18 @@ const log = getLogger("provider-registry");
|
|
|
29
29
|
const providers = new Map<string, Provider>();
|
|
30
30
|
const routingSources = new Map<string, "user-key" | "managed-proxy">();
|
|
31
31
|
const OPENAI_COMPATIBLE_ENDPOINTS_FLAG = "openai-compatible-endpoints";
|
|
32
|
+
const NATIVE_WEB_SEARCH_PROVIDER_IDS = new Set(["anthropic", "openai"]);
|
|
32
33
|
|
|
33
|
-
/** Per-connection provider cache, keyed by connection name. */
|
|
34
|
+
/** Per-connection provider cache, keyed by connection name and model. */
|
|
34
35
|
const connectionProviders = new Map<string, Provider>();
|
|
35
36
|
|
|
37
|
+
function getConnectionProviderCacheKey(
|
|
38
|
+
connection: ProviderConnection,
|
|
39
|
+
model: string,
|
|
40
|
+
): string {
|
|
41
|
+
return `${connection.name}\u0000${model}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
function registerProvider(name: string, provider: Provider): void {
|
|
37
45
|
providers.set(name, new UsageTrackingProvider(provider));
|
|
38
46
|
}
|
|
@@ -98,6 +106,30 @@ function resolveModel(config: ProvidersConfig, providerName: string): string {
|
|
|
98
106
|
return getProviderDefaultModel(providerName);
|
|
99
107
|
}
|
|
100
108
|
|
|
109
|
+
export function isNativeWebSearchCapableProvider(
|
|
110
|
+
providerName: string,
|
|
111
|
+
model: string,
|
|
112
|
+
): boolean {
|
|
113
|
+
if (NATIVE_WEB_SEARCH_PROVIDER_IDS.has(providerName)) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (providerName === "openrouter" && model.startsWith("anthropic/")) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function shouldUseNativeWebSearch(
|
|
123
|
+
config: ProvidersConfig,
|
|
124
|
+
providerName: string,
|
|
125
|
+
model: string,
|
|
126
|
+
): boolean {
|
|
127
|
+
return (
|
|
128
|
+
config.services["web-search"].provider === "inference-provider-native" &&
|
|
129
|
+
isNativeWebSearchCapableProvider(providerName, model)
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
101
133
|
/**
|
|
102
134
|
* Resolve provider credentials. User key takes precedence; managed proxy is
|
|
103
135
|
* used as a fallback when platform prerequisites are available.
|
|
@@ -135,8 +167,6 @@ export async function initializeProviders(
|
|
|
135
167
|
|
|
136
168
|
const streamTimeoutMs =
|
|
137
169
|
(config.timeouts?.providerStreamTimeoutSec ?? 1800) * 1000;
|
|
138
|
-
const useNativeWebSearch =
|
|
139
|
-
config.services["web-search"].provider === "inference-provider-native";
|
|
140
170
|
const mainAgentProvider = resolveCallSiteConfig(
|
|
141
171
|
"mainAgent",
|
|
142
172
|
config.llm,
|
|
@@ -174,6 +204,11 @@ export async function initializeProviders(
|
|
|
174
204
|
}
|
|
175
205
|
|
|
176
206
|
const model = resolveModel(config, entry.id);
|
|
207
|
+
const useNativeWebSearch = shouldUseNativeWebSearch(
|
|
208
|
+
config,
|
|
209
|
+
entry.id,
|
|
210
|
+
model,
|
|
211
|
+
);
|
|
177
212
|
const adapter = buildProviderAdapter(entry.id, {
|
|
178
213
|
apiKey,
|
|
179
214
|
model,
|
|
@@ -221,6 +256,7 @@ export async function initializeProviders(
|
|
|
221
256
|
export async function resolveProviderFromConnection(
|
|
222
257
|
connection: ProviderConnection,
|
|
223
258
|
config: ProvidersConfig,
|
|
259
|
+
opts: { model?: string } = {},
|
|
224
260
|
): Promise<Provider | null> {
|
|
225
261
|
if (
|
|
226
262
|
connection.provider === "openai-compatible" &&
|
|
@@ -229,7 +265,9 @@ export async function resolveProviderFromConnection(
|
|
|
229
265
|
return null;
|
|
230
266
|
}
|
|
231
267
|
|
|
232
|
-
const
|
|
268
|
+
const model = opts.model ?? resolveModel(config, connection.provider);
|
|
269
|
+
const cacheKey = getConnectionProviderCacheKey(connection, model);
|
|
270
|
+
const cached = connectionProviders.get(cacheKey);
|
|
233
271
|
if (cached) return cached;
|
|
234
272
|
|
|
235
273
|
const authResult = await resolveAuth(connection.auth, connection.provider, {
|
|
@@ -259,9 +297,11 @@ export async function resolveProviderFromConnection(
|
|
|
259
297
|
|
|
260
298
|
const streamTimeoutMs =
|
|
261
299
|
(config.timeouts?.providerStreamTimeoutSec ?? 1800) * 1000;
|
|
262
|
-
const useNativeWebSearch =
|
|
263
|
-
config
|
|
264
|
-
|
|
300
|
+
const useNativeWebSearch = shouldUseNativeWebSearch(
|
|
301
|
+
config,
|
|
302
|
+
connection.provider,
|
|
303
|
+
model,
|
|
304
|
+
);
|
|
265
305
|
|
|
266
306
|
const provider = createAdapterFromConnection(
|
|
267
307
|
connection,
|
|
@@ -274,7 +314,7 @@ export async function resolveProviderFromConnection(
|
|
|
274
314
|
);
|
|
275
315
|
|
|
276
316
|
if (provider) {
|
|
277
|
-
connectionProviders.set(
|
|
317
|
+
connectionProviders.set(cacheKey, provider);
|
|
278
318
|
}
|
|
279
319
|
|
|
280
320
|
return provider;
|
package/src/providers/retry.ts
CHANGED
|
@@ -34,6 +34,7 @@ const USAGE_ATTRIBUTION_HEADER_NAMES = {
|
|
|
34
34
|
inferenceProfileSource: "X-Vellum-Inference-Profile-Source",
|
|
35
35
|
resolvedProvider: "X-Vellum-Resolved-Provider",
|
|
36
36
|
resolvedModel: "X-Vellum-Resolved-Model",
|
|
37
|
+
resolvedMixArm: "X-Vellum-Resolved-Mix-Arm",
|
|
37
38
|
} as const;
|
|
38
39
|
|
|
39
40
|
/** Providers that support the `effort` config (extended thinking / reasoning). */
|
|
@@ -195,19 +196,23 @@ function normalizeSendMessageOptions(
|
|
|
195
196
|
delete nextConfig.usageAttributionHeaders;
|
|
196
197
|
delete nextConfig.usageTracking;
|
|
197
198
|
|
|
198
|
-
// `overrideProfile`
|
|
199
|
-
// resolver below and `CallSiteRoutingProvider`'s provider
|
|
200
|
-
//
|
|
201
|
-
// provider request bodies even when callers set
|
|
199
|
+
// `overrideProfile` and `selectionSeed` are routing/resolution-time concerns
|
|
200
|
+
// (consumed by the resolver below and `CallSiteRoutingProvider`'s provider
|
|
201
|
+
// selection); neither is a wire-format field. Strip unconditionally so they
|
|
202
|
+
// never leak into provider request bodies even when callers set them without
|
|
203
|
+
// a `callSite`.
|
|
202
204
|
delete nextConfig.overrideProfile;
|
|
205
|
+
delete nextConfig.selectionSeed;
|
|
203
206
|
|
|
204
207
|
if (config.callSite !== undefined) {
|
|
205
208
|
const resolved = resolveCallSiteConfig(config.callSite, getConfig().llm, {
|
|
206
209
|
overrideProfile: config.overrideProfile,
|
|
210
|
+
selectionSeed: config.selectionSeed,
|
|
207
211
|
});
|
|
208
212
|
const attribution = resolveUsageAttribution({
|
|
209
213
|
callSite: config.callSite,
|
|
210
214
|
overrideProfile: config.overrideProfile,
|
|
215
|
+
selectionSeed: config.selectionSeed,
|
|
211
216
|
});
|
|
212
217
|
|
|
213
218
|
const explicitModel =
|
|
@@ -225,6 +230,7 @@ function normalizeSendMessageOptions(
|
|
|
225
230
|
profileSource: attribution.profileSource,
|
|
226
231
|
resolvedProvider: attribution.resolvedProvider,
|
|
227
232
|
resolvedModel: attribution.resolvedModel,
|
|
233
|
+
resolvedMixArm: attribution.resolvedMixArm,
|
|
228
234
|
});
|
|
229
235
|
if (Object.keys(usageAttributionHeaders).length > 0) {
|
|
230
236
|
nextConfig.usageAttributionHeaders = usageAttributionHeaders;
|
|
@@ -446,6 +452,7 @@ function buildUsageAttributionHeaders(input: {
|
|
|
446
452
|
profileSource: string;
|
|
447
453
|
resolvedProvider: string;
|
|
448
454
|
resolvedModel: string;
|
|
455
|
+
resolvedMixArm: string | null;
|
|
449
456
|
}): Record<string, string> {
|
|
450
457
|
const headers: Record<string, string> = {};
|
|
451
458
|
addSanitizedHeader(
|
|
@@ -475,6 +482,11 @@ function buildUsageAttributionHeaders(input: {
|
|
|
475
482
|
USAGE_ATTRIBUTION_HEADER_NAMES.resolvedModel,
|
|
476
483
|
input.resolvedModel,
|
|
477
484
|
);
|
|
485
|
+
addSanitizedHeader(
|
|
486
|
+
headers,
|
|
487
|
+
USAGE_ATTRIBUTION_HEADER_NAMES.resolvedMixArm,
|
|
488
|
+
input.resolvedMixArm,
|
|
489
|
+
);
|
|
478
490
|
return headers;
|
|
479
491
|
}
|
|
480
492
|
|
|
@@ -42,8 +42,17 @@ export interface SearchProviderCatalogEntry {
|
|
|
42
42
|
* privacy notices). Defaults to {@link displayName} when omitted.
|
|
43
43
|
*/
|
|
44
44
|
readonly displayNameLong?: string;
|
|
45
|
-
/**
|
|
46
|
-
*
|
|
45
|
+
/**
|
|
46
|
+
* Authentication style for the search provider choice.
|
|
47
|
+
*
|
|
48
|
+
* `managed` means the choice does not require a user-supplied search API key.
|
|
49
|
+
* For `inference-provider-native`, the daemon uses the inference API's native
|
|
50
|
+
* hosted web-search tool only when the selected inference provider/model
|
|
51
|
+
* supports it. Managed non-native inference providers keep the app-executed
|
|
52
|
+
* `web_search` tool, which can route through the platform search proxy.
|
|
53
|
+
*
|
|
54
|
+
* `byok` providers require a user-supplied key in Your Own mode.
|
|
55
|
+
*/
|
|
47
56
|
readonly kind: SearchProviderKind;
|
|
48
57
|
/** Placeholder shown in the API-key input. BYOK providers only. */
|
|
49
58
|
readonly apiKeyPrefix?: string;
|
|
@@ -99,19 +108,18 @@ export const SEARCH_PROVIDER_CATALOG: readonly SearchProviderCatalogEntry[] = [
|
|
|
99
108
|
];
|
|
100
109
|
|
|
101
110
|
/** Provider ids accepted by the web-search config schema. */
|
|
102
|
-
export const SEARCH_PROVIDER_IDS: readonly string[] =
|
|
103
|
-
(p) => p.id
|
|
104
|
-
);
|
|
111
|
+
export const SEARCH_PROVIDER_IDS: readonly string[] =
|
|
112
|
+
SEARCH_PROVIDER_CATALOG.map((p) => p.id);
|
|
105
113
|
|
|
106
114
|
/** Catalog entries that store an API key under their bare provider name. */
|
|
107
115
|
export const BYOK_SEARCH_PROVIDERS: readonly SearchProviderCatalogEntry[] =
|
|
108
116
|
SEARCH_PROVIDER_CATALOG.filter((p) => p.kind === "byok");
|
|
109
117
|
|
|
110
118
|
/** BYOK provider ids, ordered by `fallbackOrder` (ascending). */
|
|
111
|
-
export const SEARCH_PROVIDER_FALLBACK_ORDER: readonly string[] =
|
|
112
|
-
.slice()
|
|
113
|
-
|
|
114
|
-
|
|
119
|
+
export const SEARCH_PROVIDER_FALLBACK_ORDER: readonly string[] =
|
|
120
|
+
BYOK_SEARCH_PROVIDERS.slice()
|
|
121
|
+
.sort((a, b) => (a.fallbackOrder ?? 0) - (b.fallbackOrder ?? 0))
|
|
122
|
+
.map((p) => p.id);
|
|
115
123
|
|
|
116
124
|
/** Look up a single catalog entry by id. Returns `undefined` if unknown. */
|
|
117
125
|
export function getSearchProvider(
|
package/src/providers/types.ts
CHANGED
|
@@ -182,6 +182,15 @@ export interface SendMessageConfig {
|
|
|
182
182
|
* silently fall through.
|
|
183
183
|
*/
|
|
184
184
|
overrideProfile?: string;
|
|
185
|
+
/**
|
|
186
|
+
* Per-conversation seed for deterministic `mix`-profile expansion. The agent
|
|
187
|
+
* loop sets this to the conversation id so every resolver call this send
|
|
188
|
+
* triggers — provider/transport selection, wire-param normalization, usage
|
|
189
|
+
* attribution — picks the same mix constituent, stable across the
|
|
190
|
+
* conversation's turns and retries. A resolution/routing-time concern only;
|
|
191
|
+
* stripped before any provider wire request.
|
|
192
|
+
*/
|
|
193
|
+
selectionSeed?: string;
|
|
185
194
|
/**
|
|
186
195
|
* Internal per-request HTTP headers for managed-proxy usage attribution.
|
|
187
196
|
* Provider clients may pass these through SDK request options only when the
|
|
@@ -29,6 +29,7 @@ import type { DiskPressureStatus } from "../../daemon/disk-pressure-guard.js";
|
|
|
29
29
|
mock.module("../../memory/conversation-crud.js", () => ({
|
|
30
30
|
getConversationOverrideProfile: () => undefined,
|
|
31
31
|
getConversation: () => ({ archivedAt: null }),
|
|
32
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
32
33
|
}));
|
|
33
34
|
|
|
34
35
|
const mockGetOrCreateConversationCalls: Array<{
|
|
@@ -40,6 +40,7 @@ mock.module("../../memory/conversation-crud.js", () => ({
|
|
|
40
40
|
addMessageCalls.push({ conversationId, role, content });
|
|
41
41
|
return { id: `msg-${addMessageCalls.length}` };
|
|
42
42
|
},
|
|
43
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
43
44
|
}));
|
|
44
45
|
|
|
45
46
|
let processMessageImpl: (
|
|
@@ -217,6 +217,7 @@ export function notifyGuardianOfAccessRequest(
|
|
|
217
217
|
sourceEventName: "ingress.access_request",
|
|
218
218
|
sourceChannel: sourceChannel as NotificationSourceChannel,
|
|
219
219
|
sourceContextId: `access-req-${sourceChannel}-${actorExternalId}`,
|
|
220
|
+
requiresConversation: true,
|
|
220
221
|
...(sameChannelOnly ? { routingIntent: "single_channel" as const } : {}),
|
|
221
222
|
attentionHints: {
|
|
222
223
|
requiresAction: true,
|
|
@@ -209,6 +209,7 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
209
209
|
{ endpoint: "identity/intro", scopes: ["settings.read"] },
|
|
210
210
|
{ endpoint: "home/state", scopes: ["settings.read"] },
|
|
211
211
|
{ endpoint: "home/feed", scopes: ["settings.read"] },
|
|
212
|
+
{ endpoint: "home/feed/query", scopes: ["settings.read"] },
|
|
212
213
|
{ endpoint: "home/feed:PATCH", scopes: ["settings.write"] },
|
|
213
214
|
{ endpoint: "home/feed/actions", scopes: ["settings.write"] },
|
|
214
215
|
{ endpoint: "brain-graph", scopes: ["settings.read"] },
|
|
@@ -442,6 +443,7 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
442
443
|
{ endpoint: "messages/content", scopes: ["chat.read"] },
|
|
443
444
|
{ endpoint: "messages/llm-context", scopes: ["chat.read"] },
|
|
444
445
|
{ endpoint: "conversations/llm-context", scopes: ["chat.read"] },
|
|
446
|
+
{ endpoint: "conversations/compaction", scopes: ["chat.read"] },
|
|
445
447
|
{ endpoint: "llm-request-logs/payload", scopes: ["chat.read"] },
|
|
446
448
|
{ endpoint: "messages/tts", scopes: ["chat.read"] },
|
|
447
449
|
{ endpoint: "tts/synthesize", scopes: ["chat.read"] },
|
|
@@ -490,6 +492,8 @@ const ACTOR_ENDPOINTS: Array<{ endpoint: string; scopes: Scope[] }> = [
|
|
|
490
492
|
{ endpoint: "memory/v3/validate:POST", scopes: ["settings.read"] },
|
|
491
493
|
{ endpoint: "memory/v3/tree:POST", scopes: ["settings.read"] },
|
|
492
494
|
{ endpoint: "memory/v3/simulate:POST", scopes: ["settings.read"] },
|
|
495
|
+
{ endpoint: "memory/v3/shadow-diff:POST", scopes: ["settings.read"] },
|
|
496
|
+
{ endpoint: "memory/v3/seed-edges:POST", scopes: ["settings.write"] },
|
|
493
497
|
|
|
494
498
|
// Trust rule listing
|
|
495
499
|
{ endpoint: "trust-rules/manage:GET", scopes: ["settings.read"] },
|
|
@@ -868,6 +872,12 @@ registerPolicy("notifications/events", {
|
|
|
868
872
|
allowedPrincipalTypes: ["local"],
|
|
869
873
|
});
|
|
870
874
|
|
|
875
|
+
// Edit an already-sent notification: local-only (CLI / IPC callers)
|
|
876
|
+
registerPolicy("notifications/edit", {
|
|
877
|
+
requiredScopes: ["settings.write"],
|
|
878
|
+
allowedPrincipalTypes: ["local"],
|
|
879
|
+
});
|
|
880
|
+
|
|
871
881
|
// Defer operations: local-only (CLI / IPC callers)
|
|
872
882
|
registerPolicy("defer/create", {
|
|
873
883
|
requiredScopes: ["settings.write"],
|
|
@@ -282,6 +282,74 @@ const slackProbe: ChannelProbe = {
|
|
|
282
282
|
),
|
|
283
283
|
];
|
|
284
284
|
},
|
|
285
|
+
async runRemoteChecks(): Promise<ReadinessCheckResult[]> {
|
|
286
|
+
const botToken = await getSecureKeyAsync(
|
|
287
|
+
credentialKey("slack_channel", "bot_token"),
|
|
288
|
+
);
|
|
289
|
+
if (!botToken) {
|
|
290
|
+
return [
|
|
291
|
+
check(
|
|
292
|
+
"auth_test",
|
|
293
|
+
false,
|
|
294
|
+
"Slack auth.test ok",
|
|
295
|
+
"Skipped: no bot_token stored",
|
|
296
|
+
),
|
|
297
|
+
];
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
const res = await fetch("https://slack.com/api/auth.test", {
|
|
301
|
+
method: "POST",
|
|
302
|
+
headers: { Authorization: `Bearer ${botToken}` },
|
|
303
|
+
});
|
|
304
|
+
const data = (await res.json()) as {
|
|
305
|
+
ok: boolean;
|
|
306
|
+
error?: string;
|
|
307
|
+
team_id?: string;
|
|
308
|
+
team?: string;
|
|
309
|
+
user?: string;
|
|
310
|
+
};
|
|
311
|
+
if (!data.ok) {
|
|
312
|
+
return [
|
|
313
|
+
check(
|
|
314
|
+
"auth_test",
|
|
315
|
+
false,
|
|
316
|
+
"Slack auth.test ok",
|
|
317
|
+
`Slack auth.test rejected bot_token: ${data.error ?? "unknown error"}`,
|
|
318
|
+
),
|
|
319
|
+
];
|
|
320
|
+
}
|
|
321
|
+
const raw = loadRawConfig();
|
|
322
|
+
const storedTeamId = getNestedValue(raw, "slack.teamId");
|
|
323
|
+
const teamMatches =
|
|
324
|
+
typeof storedTeamId !== "string" ||
|
|
325
|
+
storedTeamId.length === 0 ||
|
|
326
|
+
storedTeamId === data.team_id;
|
|
327
|
+
return [
|
|
328
|
+
check(
|
|
329
|
+
"auth_test",
|
|
330
|
+
true,
|
|
331
|
+
`Slack auth.test ok (workspace ${data.team ?? data.team_id ?? "unknown"}, bot ${data.user ?? "unknown"})`,
|
|
332
|
+
"Slack auth.test ok",
|
|
333
|
+
),
|
|
334
|
+
check(
|
|
335
|
+
"workspace_match",
|
|
336
|
+
teamMatches,
|
|
337
|
+
"Stored workspace matches bot token",
|
|
338
|
+
`Stored workspace ${storedTeamId} does not match bot token's workspace ${data.team_id ?? "unknown"} — run 'assistant channels slack reconnect' to refresh metadata`,
|
|
339
|
+
),
|
|
340
|
+
];
|
|
341
|
+
} catch (err) {
|
|
342
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
343
|
+
return [
|
|
344
|
+
check(
|
|
345
|
+
"auth_test",
|
|
346
|
+
false,
|
|
347
|
+
"Slack auth.test ok",
|
|
348
|
+
`Failed to reach Slack auth.test: ${message}`,
|
|
349
|
+
),
|
|
350
|
+
];
|
|
351
|
+
}
|
|
352
|
+
},
|
|
285
353
|
};
|
|
286
354
|
|
|
287
355
|
// ── Service ─────────────────────────────────────────────────────────────────
|
|
@@ -141,6 +141,29 @@ export async function deliverRenderedReplyViaCallback(
|
|
|
141
141
|
return;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
if (startFromSegment >= deliverableSegments.length) {
|
|
145
|
+
if (replyAttachments) {
|
|
146
|
+
const result: ChannelDeliveryResult = await deliverChannelReply(
|
|
147
|
+
callbackUrl,
|
|
148
|
+
{
|
|
149
|
+
chatId,
|
|
150
|
+
attachments: replyAttachments,
|
|
151
|
+
assistantId,
|
|
152
|
+
ephemeral,
|
|
153
|
+
user,
|
|
154
|
+
messageTs,
|
|
155
|
+
},
|
|
156
|
+
);
|
|
157
|
+
const deliveredTs = result.ts ?? messageTs;
|
|
158
|
+
if (deliveredTs) {
|
|
159
|
+
onMessageTs?.(deliveredTs);
|
|
160
|
+
}
|
|
161
|
+
} else if (messageTs) {
|
|
162
|
+
onMessageTs?.(messageTs);
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
144
167
|
const isSlack = isSlackCallbackUrl(callbackUrl);
|
|
145
168
|
|
|
146
169
|
// Only the first segment uses messageTs for in-place update;
|
|
@@ -11,7 +11,11 @@ import { getDiskPressureStatus } from "../daemon/disk-pressure-guard.js";
|
|
|
11
11
|
import { classifyDiskPressureTurnPolicy } from "../daemon/disk-pressure-policy.js";
|
|
12
12
|
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
13
13
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
addSlackDmLiveDeliveredTextResponseIndex,
|
|
16
|
+
getSlackDmLiveDeliveredTextResponseIndexes,
|
|
17
|
+
updateDeliveredSegmentCount,
|
|
18
|
+
} from "../memory/delivery-channels.js";
|
|
15
19
|
import {
|
|
16
20
|
clearPayload,
|
|
17
21
|
linkMessage,
|
|
@@ -33,6 +37,7 @@ import {
|
|
|
33
37
|
} from "./channel-reply-delivery.js";
|
|
34
38
|
import { deliverChannelReply } from "./gateway-client.js";
|
|
35
39
|
import type { MessageProcessor } from "./http-types.js";
|
|
40
|
+
import { createSlackDmTextDeliveryController } from "./slack-dm-text-delivery.js";
|
|
36
41
|
import { resolveRoutingStateFromRuntime } from "./trust-context-resolver.js";
|
|
37
42
|
|
|
38
43
|
const log = getLogger("runtime-http");
|
|
@@ -258,6 +263,27 @@ export async function sweepFailedEvents(
|
|
|
258
263
|
sourceMetadata.chatType.trim().length > 0
|
|
259
264
|
? sourceMetadata.chatType.trim()
|
|
260
265
|
: undefined;
|
|
266
|
+
const replyCallbackUrl =
|
|
267
|
+
typeof payload.replyCallbackUrl === "string"
|
|
268
|
+
? payload.replyCallbackUrl
|
|
269
|
+
: undefined;
|
|
270
|
+
const externalChatId =
|
|
271
|
+
typeof payload.externalChatId === "string"
|
|
272
|
+
? payload.externalChatId
|
|
273
|
+
: undefined;
|
|
274
|
+
const slackDmTextDelivery = externalChatId
|
|
275
|
+
? createSlackDmTextDeliveryController({
|
|
276
|
+
sourceChannel,
|
|
277
|
+
chatType: metadataChatType,
|
|
278
|
+
replyCallbackUrl,
|
|
279
|
+
chatId: externalChatId,
|
|
280
|
+
assistantId,
|
|
281
|
+
deliveredTextResponseIndexes:
|
|
282
|
+
getSlackDmLiveDeliveredTextResponseIndexes(event.id),
|
|
283
|
+
onTextResponseDelivered: (responseIndex) =>
|
|
284
|
+
addSlackDmLiveDeliveredTextResponseIndex(event.id, responseIndex),
|
|
285
|
+
})
|
|
286
|
+
: undefined;
|
|
261
287
|
let replyMessageId: string | undefined;
|
|
262
288
|
const observeAgentEvent = (msg: ServerMessage): void => {
|
|
263
289
|
if (
|
|
@@ -267,6 +293,7 @@ export async function sweepFailedEvents(
|
|
|
267
293
|
) {
|
|
268
294
|
replyMessageId = msg.messageId;
|
|
269
295
|
}
|
|
296
|
+
slackDmTextDelivery?.observeEvent(msg);
|
|
270
297
|
};
|
|
271
298
|
|
|
272
299
|
let userMessageId: string | undefined;
|
|
@@ -304,26 +331,29 @@ export async function sweepFailedEvents(
|
|
|
304
331
|
);
|
|
305
332
|
} catch (err) {
|
|
306
333
|
log.error({ err, eventId: event.id }, "Retry failed for channel event");
|
|
334
|
+
if (slackDmTextDelivery) {
|
|
335
|
+
await slackDmTextDelivery.waitForPendingDeliveries();
|
|
336
|
+
}
|
|
307
337
|
recordProcessingFailure(event.id, err);
|
|
308
338
|
continue;
|
|
309
339
|
}
|
|
310
340
|
|
|
311
|
-
const replyCallbackUrl =
|
|
312
|
-
typeof payload.replyCallbackUrl === "string"
|
|
313
|
-
? payload.replyCallbackUrl
|
|
314
|
-
: undefined;
|
|
315
341
|
if (replyCallbackUrl) {
|
|
316
|
-
const externalChatId =
|
|
317
|
-
typeof payload.externalChatId === "string"
|
|
318
|
-
? payload.externalChatId
|
|
319
|
-
: undefined;
|
|
320
342
|
if (externalChatId) {
|
|
321
343
|
try {
|
|
344
|
+
if (slackDmTextDelivery) {
|
|
345
|
+
await slackDmTextDelivery.waitForPendingDeliveries();
|
|
346
|
+
}
|
|
322
347
|
// processMessage above generated a fresh assistant response, so any
|
|
323
|
-
// previously tracked
|
|
324
|
-
// must not carry over.
|
|
325
|
-
// new
|
|
326
|
-
|
|
348
|
+
// previously tracked final-delivery progress belongs to the old
|
|
349
|
+
// response and must not carry over. Use live Slack DM progress as
|
|
350
|
+
// the new baseline before final delivery so delivery-only retries do
|
|
351
|
+
// not duplicate text if the callback fails before reporting progress.
|
|
352
|
+
const liveDeliveryResumeOptions =
|
|
353
|
+
slackDmTextDelivery?.getFinalDeliveryResumeOptions(replyMessageId);
|
|
354
|
+
const finalDeliveryStartFromSegment =
|
|
355
|
+
liveDeliveryResumeOptions?.startFromSegment ?? 0;
|
|
356
|
+
updateDeliveredSegmentCount(event.id, finalDeliveryStartFromSegment);
|
|
327
357
|
await deliverReplyViaCallback(
|
|
328
358
|
event.conversationId,
|
|
329
359
|
externalChatId,
|
|
@@ -332,7 +362,10 @@ export async function sweepFailedEvents(
|
|
|
332
362
|
{
|
|
333
363
|
messageId: replyMessageId,
|
|
334
364
|
sinceMessageId: userMessageId,
|
|
335
|
-
startFromSegment:
|
|
365
|
+
startFromSegment: finalDeliveryStartFromSegment,
|
|
366
|
+
...(liveDeliveryResumeOptions?.messageTs
|
|
367
|
+
? { messageTs: liveDeliveryResumeOptions.messageTs }
|
|
368
|
+
: {}),
|
|
336
369
|
onSegmentDelivered: (count) =>
|
|
337
370
|
updateDeliveredSegmentCount(event.id, count),
|
|
338
371
|
},
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
* canonical records.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
17
16
|
import {
|
|
18
17
|
type CanonicalGuardianRequest,
|
|
@@ -150,6 +149,7 @@ export function bridgeConfirmationRequestToGuardian(
|
|
|
150
149
|
sourceEventName: "guardian.question",
|
|
151
150
|
sourceChannel: sourceChannel as NotificationSourceChannel,
|
|
152
151
|
sourceContextId: conversationId,
|
|
152
|
+
requiresConversation: true,
|
|
153
153
|
attentionHints: {
|
|
154
154
|
requiresAction: true,
|
|
155
155
|
urgency: "high",
|
|
@@ -679,7 +679,8 @@ export interface BuildExportVBundleOptions {
|
|
|
679
679
|
* Optional callback to checkpoint the WAL before reading the database file.
|
|
680
680
|
* In WAL mode, committed rows may live in the -wal file and not yet be
|
|
681
681
|
* flushed to the main .db file. Callers should pass a function that runs
|
|
682
|
-
* PRAGMA wal_checkpoint(
|
|
682
|
+
* PRAGMA wal_checkpoint(FULL) on the live database connection. (Not
|
|
683
|
+
* TRUNCATE — see assistant/AGENTS.md "SQLite WAL checkpointing".)
|
|
683
684
|
* Called before the workspace walk so the DB file is up to date.
|
|
684
685
|
*
|
|
685
686
|
* May return a Promise — `streamExportVBundle` awaits the result so an
|
|
@@ -1127,7 +1128,7 @@ export async function streamExportVBundle(
|
|
|
1127
1128
|
|
|
1128
1129
|
// Flush WAL to the main database file before reading. Awaiting allows
|
|
1129
1130
|
// the callback to dispatch the checkpoint via `runAsyncSqlite` so the
|
|
1130
|
-
// daemon event loop stays responsive while SQLite
|
|
1131
|
+
// daemon event loop stays responsive while SQLite flushes the WAL.
|
|
1131
1132
|
if (checkpoint) {
|
|
1132
1133
|
await checkpoint();
|
|
1133
1134
|
}
|