@vellumai/assistant 0.8.1 → 0.8.3
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 +13 -19
- package/Dockerfile +75 -1
- package/bun.lock +11 -1
- package/docker-entrypoint.sh +17 -0
- package/docker-init-apt-root.sh +167 -0
- package/docker-kata-apt-env.sh +39 -0
- package/docs/plugins.md +88 -47
- package/docs/skills.md +9 -7
- package/examples/plugins/echo/README.md +27 -27
- package/examples/plugins/echo/package.json +3 -0
- package/examples/plugins/echo/register.ts +31 -31
- package/node_modules/@vellumai/slack-text/src/index.test.ts +114 -14
- package/node_modules/@vellumai/slack-text/src/index.ts +82 -18
- package/openapi.yaml +642 -5
- package/package.json +3 -1
- package/scripts/generate-openapi.ts +83 -10
- package/scripts/sync-llm-catalog.ts +2 -2
- package/scripts/sync-web-search-catalog.ts +47 -25
- package/src/__tests__/agent-image-optimize.test.ts +11 -3
- package/src/__tests__/agent-loop-exit-reason.test.ts +272 -0
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +195 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +131 -0
- package/src/__tests__/anthropic-provider.test.ts +45 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +9 -3
- package/src/__tests__/app-executors.test.ts +220 -4
- package/src/__tests__/auto-analysis-end-to-end.test.ts +35 -0
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/channel-availability-routes.test.ts +206 -0
- package/src/__tests__/channel-delivery-store.test.ts +289 -1
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -1
- package/src/__tests__/clawhub.test.ts +75 -16
- package/src/__tests__/compactor-tail-resolution.test.ts +147 -0
- package/src/__tests__/config-get-vision-flag.test.ts +136 -0
- package/src/__tests__/config-loader-backfill.test.ts +115 -18
- package/src/__tests__/config-schema.test.ts +21 -0
- package/src/__tests__/config-set-route.test.ts +80 -0
- package/src/__tests__/config-sounds-sync.test.ts +97 -0
- package/src/__tests__/config-watcher-skill-reseed.test.ts +453 -0
- package/src/__tests__/context-search-conversations-source.test.ts +117 -2
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
- package/src/__tests__/context-search-workspace-source.test.ts +7 -0
- package/src/__tests__/context-token-estimator.test.ts +31 -65
- package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +92 -92
- package/src/__tests__/conversation-agent-loop.test.ts +59 -1
- package/src/__tests__/conversation-error.test.ts +42 -3
- package/src/__tests__/conversation-fork-crud.test.ts +82 -0
- package/src/__tests__/conversation-inference-profile-route.test.ts +40 -4
- package/src/__tests__/conversation-lifecycle.test.ts +173 -0
- package/src/__tests__/conversation-media-retry.test.ts +19 -8
- package/src/__tests__/conversation-message-sync-tags.test.ts +97 -0
- package/src/__tests__/conversation-pairing.test.ts +54 -0
- package/src/__tests__/conversation-process-callsite.test.ts +4 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -1
- package/src/__tests__/conversation-queue.test.ts +4 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +102 -13
- package/src/__tests__/conversation-slash-queue.test.ts +59 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +4 -1
- package/src/__tests__/conversation-surfaces-table-action.test.ts +360 -0
- package/src/__tests__/conversation-sync-tags.test.ts +235 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-security-invariants.test.ts +3 -2
- package/src/__tests__/date-context.test.ts +45 -0
- package/src/__tests__/db-slack-external-content-normalization.test.ts +301 -0
- package/src/__tests__/delete-managed-skill-tool.test.ts +55 -13
- package/src/__tests__/disk-pressure-tools.test.ts +1 -0
- package/src/__tests__/dm-backfill.test.ts +121 -10
- package/src/__tests__/document-tool-security.test.ts +258 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/edit-propagation.test.ts +33 -0
- package/src/__tests__/empty-response-pipeline.test.ts +0 -4
- package/src/__tests__/external-plugin-loader.test.ts +151 -55
- package/src/__tests__/filing-service.test.ts +140 -0
- package/src/__tests__/get-skill-detail-audit.test.ts +0 -4
- package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +0 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +43 -62
- package/src/__tests__/heartbeat-service.test.ts +24 -164
- package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
- package/src/__tests__/helpers/tar-fixtures.ts +39 -0
- package/src/__tests__/helpers/wait-for.ts +21 -0
- package/src/__tests__/history-repair-pipeline.test.ts +0 -3
- package/src/__tests__/history-repair.test.ts +73 -0
- package/src/__tests__/host-app-control-proxy.test.ts +507 -10
- package/src/__tests__/host-proxy-preactivation.test.ts +200 -13
- package/src/__tests__/image-credentials.test.ts +1 -1
- package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +1 -1
- package/src/__tests__/inference-profile-reaper.test.ts +4 -2
- package/src/__tests__/inference-profile-session-handler.test.ts +18 -6
- package/src/__tests__/inference-profile-session-ipc.test.ts +17 -5
- package/src/__tests__/injector-background-turn.test.ts +153 -0
- package/src/__tests__/injector-chain.test.ts +15 -8
- package/src/__tests__/install-skill-routing.test.ts +155 -37
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +99 -3
- package/src/__tests__/list-messages-page-latest.test.ts +55 -0
- package/src/__tests__/llm-call-pipeline.test.ts +0 -3
- package/src/__tests__/llm-callsite-catalog.test.ts +25 -0
- package/src/__tests__/llm-catalog-parity.test.ts +58 -13
- package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +116 -0
- package/src/__tests__/llm-request-log-error-payload.test.ts +138 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +36 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +29 -53
- package/src/__tests__/llm-resolver.test.ts +255 -2
- package/src/__tests__/llm-usage-store.test.ts +114 -0
- package/src/__tests__/managed-profile-guard.test.ts +41 -29
- package/src/__tests__/managed-skill-lifecycle.test.ts +109 -18
- package/src/__tests__/managed-store.test.ts +84 -192
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -2
- package/src/__tests__/messages-after-tiebreaker.test.ts +122 -0
- package/src/__tests__/notification-decision-fallback.test.ts +0 -91
- package/src/__tests__/notification-decision-strategy.test.ts +14 -31
- package/src/__tests__/notification-deep-link.test.ts +15 -0
- package/src/__tests__/notification-guardian-path.test.ts +1 -2
- package/src/__tests__/notification-platform-adapter.test.ts +5 -4
- package/src/__tests__/notification-telegram-adapter.test.ts +1 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +113 -0
- package/src/__tests__/oauth-commands-routes.test.ts +168 -16
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -0
- package/src/__tests__/openai-provider.test.ts +242 -3
- package/src/__tests__/openai-responses-cutover-guard.test.ts +17 -9
- package/src/__tests__/openrouter-provider-only.test.ts +51 -3
- package/src/__tests__/openrouter-token-estimation.test.ts +34 -25
- package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -2
- package/src/__tests__/persistence-pipeline.test.ts +0 -2
- package/src/__tests__/{managed-proxy-context.test.ts → platform-proxy-context.test.ts} +7 -2
- package/src/__tests__/platform.test.ts +2 -0
- package/src/__tests__/plugin-api-shim.test.ts +125 -0
- package/src/__tests__/plugin-bootstrap.test.ts +10 -36
- package/src/__tests__/plugin-external-api.test.ts +68 -0
- package/src/__tests__/plugin-registry.test.ts +0 -77
- package/src/__tests__/plugin-route-contribution.test.ts +0 -1
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -2
- package/src/__tests__/plugin-tool-contribution.test.ts +16 -15
- package/src/__tests__/plugin-types.test.ts +3 -13
- package/src/__tests__/process-message-background-slack.test.ts +8 -1
- package/src/__tests__/process-message-display-content.test.ts +421 -0
- package/src/__tests__/provider-catalog-visibility.test.ts +158 -0
- package/src/__tests__/provider-error-scenarios.test.ts +111 -0
- package/src/__tests__/{provider-managed-proxy-integration.test.ts → provider-platform-proxy-integration.test.ts} +33 -31
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +65 -13
- package/src/__tests__/schedule-routes.test.ts +50 -3
- package/src/__tests__/schedule-store.test.ts +94 -0
- package/src/__tests__/scheduler-reuse-conversation.test.ts +54 -7
- package/src/__tests__/schema-transforms.test.ts +20 -0
- package/src/__tests__/search-skills-unified.test.ts +0 -5
- package/src/__tests__/{secret-routes-managed-proxy.test.ts → secret-routes-platform-proxy.test.ts} +1 -1
- package/src/__tests__/server-history-render.test.ts +43 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -12
- package/src/__tests__/skill-load-tool.test.ts +27 -89
- package/src/__tests__/skill-memory.test.ts +23 -3
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -38
- package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -3
- package/src/__tests__/skills-install-extract.test.ts +49 -38
- package/src/__tests__/skills-install-staging.test.ts +159 -0
- package/src/__tests__/skills-uninstall.test.ts +9 -41
- package/src/__tests__/skills.test.ts +51 -58
- package/src/__tests__/slack-channel-config.test.ts +9 -0
- package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
- package/src/__tests__/system-prompt.test.ts +670 -63
- package/src/__tests__/terminal-tools.test.ts +28 -1
- package/src/__tests__/thread-backfill.test.ts +557 -27
- package/src/__tests__/title-generate-pipeline.test.ts +0 -13
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -3
- package/src/__tests__/tool-error-pipeline.test.ts +0 -3
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +16 -4
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -12
- package/src/__tests__/turn-events-store.test.ts +256 -0
- package/src/__tests__/twilio-routes.test.ts +4 -0
- package/src/__tests__/user-plugin-loader.test.ts +0 -7
- package/src/__tests__/voice-session-bridge.test.ts +198 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +32 -10
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +115 -3
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +50 -0
- package/src/__tests__/workspace-migration-073-repair-recall-callsite-empty-profile.test.ts +153 -0
- package/src/__tests__/workspace-migration-085-memory-v2-bm25-b-reembed-disabled-v2-pages.test.ts +220 -0
- package/src/__tests__/workspace-migration-086-revert-stale-gemini-mis-rewrites.test.ts +269 -0
- package/src/__tests__/workspace-migration-087-memory-router-balanced-profile.test.ts +228 -0
- package/src/__tests__/workspace-migration-remove-legacy-skills-index.test.ts +309 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +111 -3
- package/src/a2a/__tests__/agent-card.test.ts +98 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +597 -0
- package/src/a2a/__tests__/protocol-helpers.test.ts +113 -0
- package/src/a2a/__tests__/task-store.test.ts +246 -0
- package/src/a2a/agent-card.ts +58 -0
- package/src/a2a/feature-gate.ts +8 -0
- package/src/a2a/protocol-constants.ts +21 -0
- package/src/a2a/protocol-errors.ts +50 -0
- package/src/a2a/protocol-types.ts +162 -0
- package/src/a2a/task-store.ts +168 -0
- package/src/acp/resolve-agent.ts +1 -1
- package/src/agent/image-optimize.ts +13 -5
- package/src/agent/loop.ts +167 -18
- package/src/calls/voice-session-bridge.ts +61 -42
- package/src/channels/config.ts +9 -0
- package/src/channels/types.ts +122 -0
- package/src/cli/__tests__/unknown-command.test.ts +24 -0
- package/src/cli/commands/__tests__/changelog.test.ts +304 -319
- package/src/cli/{__tests__ → commands/__tests__}/notifications.test.ts +201 -28
- package/src/cli/commands/__tests__/schedules.test.ts +960 -0
- package/src/cli/commands/changelog.ts +106 -42
- package/src/cli/commands/conversations.ts +102 -17
- package/src/cli/commands/default-action.ts +10 -53
- package/src/cli/commands/notifications.ts +388 -346
- package/src/cli/commands/plugins.ts +252 -0
- package/src/cli/commands/schedules.ts +683 -0
- package/src/cli/commands/telemetry.ts +40 -0
- package/src/cli/lib/__tests__/cli-colors.test.ts +48 -0
- package/src/cli/lib/__tests__/confirm-prompt.test.ts +159 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +355 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +154 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +261 -0
- package/src/cli/lib/__tests__/uninstall-plugin.test.ts +124 -0
- package/src/cli/lib/__tests__/unknown-command.test.ts +106 -0
- package/src/cli/lib/cli-colors.ts +12 -0
- package/src/cli/lib/confirm-prompt.ts +79 -0
- package/src/cli/lib/install-from-github.ts +303 -0
- package/src/cli/lib/list-installed-plugins.ts +137 -0
- package/src/cli/lib/search-plugins.ts +163 -0
- package/src/cli/lib/uninstall-plugin.ts +82 -0
- package/src/cli/lib/unknown-command.ts +111 -0
- package/src/cli/program.ts +52 -2
- package/src/config/assistant-feature-flags.ts +24 -54
- package/src/config/bundled-skills/app-builder/SKILL.md +140 -22
- package/src/config/bundled-skills/app-builder/TOOLS.json +7 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +15 -52
- package/src/config/bundled-skills/document/SKILL.md +23 -3
- package/src/config/bundled-skills/document/TOOLS.json +53 -0
- package/src/config/bundled-skills/document/tools/document-delete.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-list.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-read.ts +12 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
- package/src/config/bundled-skills/skill-management/SKILL.md +2 -2
- package/src/config/bundled-skills/skill-management/TOOLS.json +7 -7
- package/src/config/bundled-tool-registry.ts +6 -0
- package/src/config/call-site-defaults.ts +105 -0
- package/src/config/feature-flag-registry.json +41 -9
- package/src/config/llm-resolver.ts +52 -1
- package/src/config/loader.ts +64 -38
- package/src/config/schema.ts +9 -10
- package/src/config/schemas/__tests__/llm-request-logs.test.ts +36 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +3 -3
- package/src/config/schemas/channels.ts +17 -0
- package/src/config/schemas/compaction.ts +28 -0
- package/src/config/schemas/conversations.ts +10 -0
- package/src/config/schemas/heartbeat.ts +23 -0
- package/src/config/schemas/llm-request-logs.ts +31 -7
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-retrieval.ts +18 -0
- package/src/config/schemas/memory-retrospective.ts +1 -1
- package/src/config/schemas/memory-v2.ts +4 -4
- package/src/config/schemas/memory.ts +3 -1
- package/src/config/schemas/tools.ts +14 -0
- package/src/config/seed-inference-profiles.ts +99 -29
- package/src/config/skills.ts +3 -96
- package/src/context/compactor.ts +1107 -0
- package/src/context/token-estimator.ts +34 -36
- package/src/context/window-manager.ts +197 -1520
- package/src/credential-execution/managed-catalog.ts +37 -0
- package/src/credential-health/credential-health-service.ts +280 -19
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +33 -18
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +138 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +74 -0
- package/src/daemon/approval-generators.ts +8 -6
- package/src/daemon/config-watcher.ts +94 -31
- package/src/daemon/conversation-agent-loop-handlers.ts +78 -0
- package/src/daemon/conversation-agent-loop.ts +198 -11
- package/src/daemon/conversation-error.ts +171 -37
- package/src/daemon/conversation-lifecycle.ts +53 -40
- package/src/daemon/conversation-messaging.ts +25 -6
- package/src/daemon/conversation-process.ts +49 -12
- package/src/daemon/conversation-runtime-assembly.ts +25 -1
- package/src/daemon/conversation-slash.ts +12 -5
- package/src/daemon/conversation-store.ts +11 -4
- package/src/daemon/conversation-tool-setup.ts +39 -7
- package/src/daemon/conversation.ts +33 -8
- package/src/daemon/date-context.ts +40 -0
- package/src/daemon/external-plugins-bootstrap.ts +217 -181
- package/src/daemon/first-greeting.ts +22 -2
- package/src/daemon/guardian-action-generators.ts +1 -125
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +248 -0
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +154 -0
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +133 -0
- package/src/daemon/handlers/__tests__/config-a2a.test.ts +95 -0
- package/src/daemon/handlers/config-a2a.ts +289 -0
- package/src/daemon/handlers/config-model.ts +6 -5
- package/src/daemon/handlers/config-slack-channel.ts +15 -3
- package/src/daemon/handlers/conversations.ts +1 -0
- package/src/daemon/handlers/shared.ts +14 -5
- package/src/daemon/handlers/skills.ts +111 -108
- package/src/daemon/history-repair.ts +28 -1
- package/src/daemon/host-app-control-proxy.ts +153 -27
- package/src/daemon/host-proxy-preactivation.ts +85 -18
- package/src/daemon/lifecycle.ts +89 -91
- package/src/daemon/meet-host-supervisor.ts +5 -4
- package/src/daemon/memory-v2-startup.ts +85 -0
- package/src/daemon/message-protocol.ts +1 -0
- package/src/daemon/message-types/conversations.ts +25 -0
- package/src/daemon/message-types/messages.ts +61 -0
- package/src/daemon/message-types/notifications.ts +21 -0
- package/src/daemon/message-types/subagents.ts +1 -0
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/pkb-reminder-builder.test.ts +11 -54
- package/src/daemon/pkb-reminder-builder.ts +5 -20
- package/src/daemon/plugin-source-watcher.ts +146 -0
- package/src/daemon/process-message.ts +24 -3
- package/src/daemon/server.ts +11 -2
- package/src/daemon/skill-memory-refresh.ts +33 -0
- package/src/daemon/wake-target-adapter.ts +2 -0
- package/src/documents/document-store.ts +221 -3
- package/src/embedded/plugin-api.ts +40 -0
- package/src/export/__tests__/transcript-formatter.test.ts +121 -0
- package/src/export/transcript-formatter.ts +54 -20
- package/src/filing/filing-service.ts +39 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +135 -6
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +73 -189
- package/src/home/__tests__/feed-types.test.ts +80 -0
- package/src/home/feed-types.ts +36 -2
- package/src/home/post-connect-feed.ts +1 -0
- package/src/index.ts +18 -1
- package/src/ipc/cli-client.ts +147 -45
- package/src/live-voice/__tests__/live-voice-stt.test.ts +57 -0
- package/src/mcp/client.ts +20 -4
- package/src/media/image-credentials.ts +3 -3
- package/src/memory/__tests__/bookmark-crud.test.ts +33 -27
- package/src/memory/__tests__/conversation-queries.test.ts +483 -0
- package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +113 -0
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +2 -50
- package/src/memory/__tests__/memory-retrospective-job.test.ts +87 -4
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +119 -14
- package/src/memory/__tests__/message-content.test.ts +35 -0
- package/src/memory/bookmark-crud.ts +42 -10
- package/src/memory/context-search/sources/conversations.ts +62 -2
- package/src/memory/context-search/sources/workspace.ts +4 -0
- package/src/memory/conversation-crud.ts +63 -19
- package/src/memory/conversation-queries.ts +197 -11
- package/src/memory/conversation-title-service.ts +26 -4
- package/src/memory/db-init.ts +12 -0
- package/src/memory/delivery-crud.ts +152 -5
- package/src/memory/embedding-backend.ts +4 -4
- package/src/memory/external-conversation-store.ts +66 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +150 -12
- package/src/memory/graph/conversation-graph-memory.ts +49 -21
- package/src/memory/graph/tools.ts +9 -40
- package/src/memory/indexer.ts +34 -29
- package/src/memory/invite-store.ts +53 -0
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +73 -0
- package/src/memory/jobs/embed-concept-page.ts +20 -11
- package/src/memory/jobs-worker.ts +6 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +24 -12
- package/src/memory/llm-request-log-source.ts +19 -52
- package/src/memory/llm-request-log-store.ts +92 -1
- package/src/memory/llm-usage-store.ts +125 -5
- package/src/memory/memory-retrospective-enqueue.ts +1 -20
- package/src/memory/memory-retrospective-job.ts +33 -6
- package/src/memory/memory-retrospective-startup-cleanup.ts +72 -5
- package/src/memory/message-content.ts +1 -1
- package/src/memory/migrations/109-external-conversation-bindings.ts +15 -4
- package/src/memory/migrations/229-delete-private-conversations.test.ts +38 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +7 -0
- package/src/memory/migrations/247-external-conversation-binding-thread-id.ts +78 -0
- package/src/memory/migrations/248-create-onboarding-events.ts +21 -0
- package/src/memory/migrations/249-normalize-slack-external-content.ts +240 -0
- package/src/memory/migrations/250-provider-connection-base-url-and-models.ts +28 -0
- package/src/memory/migrations/251-a2a-tasks.ts +49 -0
- package/src/memory/migrations/252-llm-request-log-agent-loop-exit-reason.ts +32 -0
- package/src/memory/migrations/index.ts +9 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/onboarding-events-store.ts +106 -0
- package/src/memory/schema/a2a.ts +15 -0
- package/src/memory/schema/bookmarks.ts +0 -2
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/inference.ts +3 -3
- package/src/memory/schema/infrastructure.ts +13 -0
- package/src/memory/turn-events-store.ts +127 -2
- package/src/memory/v2/__tests__/activation-store.test.ts +25 -23
- package/src/memory/v2/__tests__/activation.test.ts +0 -8
- package/src/memory/v2/__tests__/cli-command-store.test.ts +404 -0
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +25 -4
- package/src/memory/v2/__tests__/injection.test.ts +288 -11
- package/src/memory/v2/__tests__/migration.test.ts +87 -0
- package/src/memory/v2/__tests__/page-index.test.ts +83 -0
- package/src/memory/v2/__tests__/prompts-router.test.ts +58 -6
- package/src/memory/v2/__tests__/qdrant.test.ts +66 -3
- package/src/memory/v2/__tests__/router.test.ts +15 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +387 -8
- package/src/memory/v2/__tests__/static-context.test.ts +12 -1
- package/src/memory/v2/activation-store.ts +14 -16
- package/src/memory/v2/cli-command-content.ts +19 -0
- package/src/memory/v2/cli-command-store.ts +304 -0
- package/src/memory/v2/frontmatter-sweep.ts +7 -1
- package/src/memory/v2/injection.ts +81 -26
- package/src/memory/v2/migration.ts +49 -19
- package/src/memory/v2/page-index.ts +63 -8
- package/src/memory/v2/prompts/router.ts +11 -8
- package/src/memory/v2/prompts/sweep.ts +2 -2
- package/src/memory/v2/qdrant.ts +135 -7
- package/src/memory/v2/router.ts +9 -8
- package/src/memory/v2/skill-store.ts +120 -35
- package/src/memory/v2/static-context.ts +4 -4
- package/src/memory/v2/types.ts +23 -0
- package/src/messaging/providers/a2a/__tests__/deliver.test.ts +274 -0
- package/src/messaging/providers/a2a/deliver.ts +156 -0
- package/src/messaging/providers/gmail/client.ts +9 -2
- package/src/messaging/providers/index.ts +11 -2
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +45 -5
- package/src/messaging/providers/slack/__tests__/download.test.ts +231 -0
- package/src/messaging/providers/slack/adapter.ts +43 -5
- package/src/messaging/providers/slack/client.ts +27 -0
- package/src/messaging/providers/slack/deep-link.ts +65 -0
- package/src/messaging/providers/slack/download.ts +104 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +32 -0
- package/src/messaging/providers/slack/message-metadata.ts +27 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +134 -0
- package/src/messaging/providers/slack/render-transcript.ts +69 -5
- package/src/messaging/providers/slack/types.ts +20 -1
- package/src/notifications/__tests__/broadcaster.test.ts +203 -0
- package/src/notifications/__tests__/decision-engine.test.ts +283 -0
- package/src/notifications/__tests__/deterministic-checks.test.ts +286 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +430 -7
- package/src/notifications/adapters/macos.ts +12 -2
- package/src/notifications/broadcaster.ts +29 -4
- package/src/notifications/conversation-pairing.ts +2 -1
- package/src/notifications/copy-composer.ts +17 -64
- package/src/notifications/decision-engine.ts +113 -45
- package/src/notifications/deterministic-checks.ts +96 -0
- package/src/notifications/emit-signal.ts +21 -1
- package/src/notifications/home-feed-side-effect.ts +138 -5
- package/src/notifications/signal.ts +3 -5
- package/src/notifications/types.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -4
- package/src/oauth/platform-connection.test.ts +43 -3
- package/src/oauth/platform-connection.ts +19 -6
- package/src/oauth/seed-providers.ts +10 -1
- package/src/permissions/checker.ts +2 -0
- package/src/permissions/ipc-risk-types.ts +1 -0
- package/src/permissions/question-prompter.test.ts +416 -0
- package/src/permissions/question-prompter.ts +294 -0
- package/src/platform/client.test.ts +1 -1
- package/src/platform/client.ts +1 -1
- package/src/plugin-api/constants.ts +26 -0
- package/src/plugin-api/index.ts +34 -1
- package/src/plugin-api/types.ts +104 -22
- package/src/plugins/defaults/circuit-breaker.ts +0 -5
- package/src/plugins/defaults/compaction.ts +0 -4
- package/src/plugins/defaults/empty-response.ts +0 -2
- package/src/plugins/defaults/history-repair.ts +0 -2
- package/src/plugins/defaults/injectors.ts +74 -22
- package/src/plugins/defaults/llm-call.ts +0 -2
- package/src/plugins/defaults/memory-retrieval.ts +0 -1
- package/src/plugins/defaults/overflow-reduce.ts +0 -1
- package/src/plugins/defaults/persistence.ts +0 -2
- package/src/plugins/defaults/title-generate.ts +0 -5
- package/src/plugins/defaults/token-estimate.ts +0 -2
- package/src/plugins/defaults/tool-error.ts +0 -7
- package/src/plugins/defaults/tool-execute.ts +0 -2
- package/src/plugins/defaults/tool-result-truncate.ts +0 -4
- package/src/plugins/ensure-plugin-api-shim.ts +96 -0
- package/src/plugins/external-api.ts +104 -0
- package/src/plugins/external-plugin-loader.ts +187 -42
- package/src/plugins/feature-gate.ts +22 -0
- package/src/plugins/pipeline.ts +37 -0
- package/src/plugins/registry.ts +48 -80
- package/src/plugins/types.ts +40 -26
- package/src/plugins/user-loader.ts +21 -2
- package/src/proactive-artifact/aux-message-injector.ts +11 -0
- package/src/proactive-artifact/job.test.ts +37 -5
- package/src/prompts/__tests__/system-prompt.test.ts +10 -43
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +95 -0
- package/src/prompts/normalize-onboarding.ts +27 -0
- package/src/prompts/sections.ts +302 -0
- package/src/prompts/system-prompt.ts +63 -174
- package/src/prompts/templates/BOOTSTRAP.md +17 -1
- package/src/prompts/templates/system-sections.ts +164 -0
- package/src/providers/__tests__/inference.test.ts +24 -7
- package/src/providers/anthropic/client.ts +28 -28
- package/src/providers/call-site-routing.ts +24 -6
- package/src/providers/connection-resolution.ts +68 -11
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +74 -0
- package/src/providers/inference/__tests__/connections-openai-compatible.test.ts +175 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +15 -0
- package/src/providers/inference/adapter-factory.ts +32 -6
- package/src/providers/inference/auth.ts +12 -0
- package/src/providers/inference/backfill.ts +14 -1
- package/src/providers/inference/connections.ts +159 -34
- package/src/providers/inference/resolve-auth.ts +14 -4
- package/src/providers/model-catalog.ts +249 -12
- package/src/providers/model-intents.ts +3 -3
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +235 -0
- package/src/providers/openai/chat-completions-provider.ts +169 -8
- package/src/providers/openrouter/client.ts +49 -4
- package/src/providers/{managed-proxy → platform-proxy}/constants.ts +4 -2
- package/src/providers/{managed-proxy → platform-proxy}/context.ts +3 -3
- package/src/providers/provider-availability.ts +17 -2
- package/src/providers/provider-catalog-visibility.ts +38 -0
- package/src/providers/provider-send-message.ts +27 -12
- package/src/providers/registry.ts +52 -15
- package/src/providers/retry.ts +47 -1
- package/src/runtime/__tests__/agent-wake.test.ts +152 -0
- package/src/runtime/agent-wake.ts +103 -15
- package/src/runtime/auth/route-policy.ts +21 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/http-server.ts +7 -16
- package/src/runtime/http-types.ts +19 -47
- package/src/runtime/migrations/origin-mode.ts +1 -1
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +17 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +258 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +172 -23
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +275 -44
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +12 -0
- package/src/runtime/routes/__tests__/question-routes.test.ts +395 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +64 -1
- package/src/runtime/routes/acp-routes-list.test.ts +143 -0
- package/src/runtime/routes/acp-routes.ts +5 -3
- package/src/runtime/routes/auth-routes.ts +1 -1
- package/src/runtime/routes/bookmark-routes.ts +5 -3
- package/src/runtime/routes/btw-routes.ts +5 -1
- package/src/runtime/routes/channel-availability-routes.ts +126 -0
- package/src/runtime/routes/consolidation-routes.ts +100 -0
- package/src/runtime/routes/conversation-cli-routes.ts +44 -3
- package/src/runtime/routes/conversation-list-routes.ts +3 -20
- package/src/runtime/routes/conversation-management-routes.ts +17 -42
- package/src/runtime/routes/conversation-query-routes.ts +99 -35
- package/src/runtime/routes/conversation-routes.ts +97 -11
- package/src/runtime/routes/documents-routes.ts +25 -86
- package/src/runtime/routes/group-routes.ts +5 -0
- package/src/runtime/routes/inbound-conversation.ts +28 -8
- package/src/runtime/routes/inbound-message-handler.ts +236 -41
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +111 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +32 -1
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +17 -4
- package/src/runtime/routes/index.ts +8 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +17 -44
- package/src/runtime/routes/inference-profile-session-reaper.ts +7 -21
- package/src/runtime/routes/inference-provider-connection-routes.ts +199 -22
- package/src/runtime/routes/integrations/a2a.ts +235 -0
- package/src/runtime/routes/integrations/slack/share.ts +4 -52
- package/src/runtime/routes/integrations/slack/token.ts +43 -0
- package/src/runtime/routes/integrations/twilio.ts +6 -13
- package/src/runtime/routes/llm-call-sites-routes.ts +11 -1
- package/src/runtime/routes/notification-routes.ts +1 -1
- package/src/runtime/routes/oauth-commands-routes.ts +105 -15
- package/src/runtime/routes/oauth-lifecycle-routes.ts +43 -0
- package/src/runtime/routes/question-routes.ts +259 -0
- package/src/runtime/routes/rename-conversation-routes.ts +2 -33
- package/src/runtime/routes/schedule-routes.ts +4 -7
- package/src/runtime/routes/subagents-routes.ts +98 -18
- package/src/runtime/routes/telemetry-routes.ts +27 -0
- package/src/runtime/routes/tts-routes.ts +27 -2
- package/src/runtime/routes/workspace-routes.test.ts +43 -0
- package/src/runtime/routes/workspace-routes.ts +28 -0
- package/src/runtime/services/conversation-serializer.ts +39 -7
- package/src/runtime/sync/resource-sync-events.ts +93 -1
- package/src/schedule/schedule-store.ts +27 -2
- package/src/schedule/scheduler.ts +9 -1
- package/src/security/__tests__/untrusted-content.test.ts +86 -0
- package/src/security/untrusted-content.ts +93 -8
- package/src/skills/catalog-files.ts +1 -1
- package/src/skills/catalog-install.ts +233 -116
- package/src/skills/clawhub.ts +70 -13
- package/src/skills/managed-store.ts +4 -119
- package/src/skills/skillssh-registry.ts +27 -48
- package/src/subagent/manager.ts +17 -7
- package/src/telemetry/types.ts +113 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +312 -5
- package/src/telemetry/usage-telemetry-reporter.ts +113 -7
- package/src/tools/apps/executors.ts +58 -7
- package/src/tools/ask-question/ask-question-tool.test.ts +509 -0
- package/src/tools/ask-question/ask-question-tool.ts +304 -0
- package/src/tools/browser/browser-execution.ts +15 -11
- package/src/tools/computer-use/definitions.ts +3 -3
- package/src/tools/credentials/vault.ts +1 -1
- package/src/tools/document/document-tool.ts +124 -1
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +5 -2
- package/src/tools/host-filesystem/transfer.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +1 -1
- package/src/tools/memory/register.ts +1 -9
- package/src/tools/permission-checker.ts +1 -1
- package/src/tools/registry.ts +17 -7
- package/src/tools/schedule/create.ts +2 -2
- package/src/tools/schema-transforms.ts +7 -2
- package/src/tools/side-effects.ts +1 -0
- package/src/tools/skills/delete-managed.ts +4 -4
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/scaffold-managed.ts +3 -2
- package/src/tools/subagent/notify-parent.ts +1 -1
- package/src/tools/system/request-permission.ts +2 -2
- package/src/tools/terminal/safe-env.ts +60 -1
- package/src/tools/tool-manifest.ts +2 -0
- package/src/tools/types.ts +107 -21
- package/src/tools/ui-surface/definitions.ts +6 -5
- package/src/tts/__tests__/provider-adapters.test.ts +76 -2
- package/src/tts/providers/elevenlabs-provider.ts +75 -1
- package/src/types/onboarding-context.ts +2 -0
- package/src/util/errors.ts +17 -0
- package/src/util/platform.ts +10 -0
- package/src/watcher/__tests__/engine.test.ts +22 -0
- package/src/watcher/engine.ts +6 -2
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +80 -15
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +35 -22
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +3 -1
- package/src/workspace/migrations/083-system-prompt-prefix-to-file.ts +191 -0
- package/src/workspace/migrations/084-remove-legacy-skills-index.ts +276 -0
- package/src/workspace/migrations/085-memory-v2-bm25-b-reembed-disabled-v2-pages.ts +137 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +198 -0
- package/src/workspace/migrations/087-memory-router-balanced-profile.ts +91 -0
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/migrations/runner.ts +39 -9
- package/src/workspace/migrations/types.ts +4 -0
- package/examples/plugins/echo/bun.lock +0 -25
- package/src/__tests__/context-window-manager.test.ts +0 -2481
- package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -441
- package/src/context/__tests__/compact-prompt.test.ts +0 -63
- package/src/context/prompts/compact.md +0 -26
- package/src/memory/graph/__tests__/remember-description.test.ts +0 -55
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +0 -37
- package/src/runtime/guardian-action-conversation-turn.ts +0 -99
|
@@ -29,6 +29,7 @@ mock.module("../../../util/logger.js", () => ({
|
|
|
29
29
|
|
|
30
30
|
// ── Real imports (after mocks) ────────────────────────────────────────────────
|
|
31
31
|
|
|
32
|
+
import { _setOverridesForTesting } from "../../../config/assistant-feature-flags.js";
|
|
32
33
|
import { getDb } from "../../../memory/db-connection.js";
|
|
33
34
|
import { initializeDb } from "../../../memory/db-init.js";
|
|
34
35
|
import { providerConnections } from "../../../memory/schema/inference.js";
|
|
@@ -89,6 +90,7 @@ function seedConnection(opts: {
|
|
|
89
90
|
beforeEach(() => {
|
|
90
91
|
clearConnections();
|
|
91
92
|
fakeConfig = {};
|
|
93
|
+
_setOverridesForTesting({ "openai-compatible-endpoints": true });
|
|
92
94
|
});
|
|
93
95
|
|
|
94
96
|
// ── GET list ─────────────────────────────────────────────────────────────────
|
|
@@ -103,8 +105,16 @@ describe("GET inference/provider-connections (list)", () => {
|
|
|
103
105
|
});
|
|
104
106
|
|
|
105
107
|
test("returns all connections when no filter", async () => {
|
|
106
|
-
seedConnection({
|
|
107
|
-
|
|
108
|
+
seedConnection({
|
|
109
|
+
name: "conn-a",
|
|
110
|
+
provider: "anthropic",
|
|
111
|
+
auth: { type: "platform" },
|
|
112
|
+
});
|
|
113
|
+
seedConnection({
|
|
114
|
+
name: "conn-b",
|
|
115
|
+
provider: "openai",
|
|
116
|
+
auth: { type: "none" },
|
|
117
|
+
});
|
|
108
118
|
|
|
109
119
|
const result = (await call(
|
|
110
120
|
findHandler("inference_provider_connections_list"),
|
|
@@ -115,8 +125,16 @@ describe("GET inference/provider-connections (list)", () => {
|
|
|
115
125
|
});
|
|
116
126
|
|
|
117
127
|
test("filters by ?provider= query param", async () => {
|
|
118
|
-
seedConnection({
|
|
119
|
-
|
|
128
|
+
seedConnection({
|
|
129
|
+
name: "ant-1",
|
|
130
|
+
provider: "anthropic",
|
|
131
|
+
auth: { type: "platform" },
|
|
132
|
+
});
|
|
133
|
+
seedConnection({
|
|
134
|
+
name: "oai-1",
|
|
135
|
+
provider: "openai",
|
|
136
|
+
auth: { type: "platform" },
|
|
137
|
+
});
|
|
120
138
|
|
|
121
139
|
const result = (await call(
|
|
122
140
|
findHandler("inference_provider_connections_list"),
|
|
@@ -128,7 +146,11 @@ describe("GET inference/provider-connections (list)", () => {
|
|
|
128
146
|
});
|
|
129
147
|
|
|
130
148
|
test("returns empty list when provider filter matches nothing", async () => {
|
|
131
|
-
seedConnection({
|
|
149
|
+
seedConnection({
|
|
150
|
+
name: "ant-1",
|
|
151
|
+
provider: "anthropic",
|
|
152
|
+
auth: { type: "platform" },
|
|
153
|
+
});
|
|
132
154
|
|
|
133
155
|
const result = (await call(
|
|
134
156
|
findHandler("inference_provider_connections_list"),
|
|
@@ -136,13 +158,48 @@ describe("GET inference/provider-connections (list)", () => {
|
|
|
136
158
|
)) as { connections: unknown[] };
|
|
137
159
|
expect(result.connections).toEqual([]);
|
|
138
160
|
});
|
|
161
|
+
|
|
162
|
+
test("hides openai-compatible rows when the feature flag is disabled", async () => {
|
|
163
|
+
_setOverridesForTesting({ "openai-compatible-endpoints": false });
|
|
164
|
+
seedConnection({
|
|
165
|
+
name: "my-openai",
|
|
166
|
+
provider: "openai",
|
|
167
|
+
auth: { type: "platform" },
|
|
168
|
+
});
|
|
169
|
+
seedConnection({
|
|
170
|
+
name: "my-compatible",
|
|
171
|
+
provider: "openai-compatible",
|
|
172
|
+
auth: { type: "api_key", credential: "ref/k" },
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const result = (await call(
|
|
176
|
+
findHandler("inference_provider_connections_list"),
|
|
177
|
+
{},
|
|
178
|
+
)) as { connections: Array<{ name: string }> };
|
|
179
|
+
|
|
180
|
+
expect(result.connections.map((c) => c.name)).toEqual(["my-openai"]);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test("rejects openai-compatible provider filter when the feature flag is disabled", async () => {
|
|
184
|
+
_setOverridesForTesting({ "openai-compatible-endpoints": false });
|
|
185
|
+
|
|
186
|
+
await expect(
|
|
187
|
+
call(findHandler("inference_provider_connections_list"), {
|
|
188
|
+
queryParams: { provider: "openai-compatible" },
|
|
189
|
+
}),
|
|
190
|
+
).rejects.toBeInstanceOf(BadRequestError);
|
|
191
|
+
});
|
|
139
192
|
});
|
|
140
193
|
|
|
141
194
|
// ── GET single ────────────────────────────────────────────────────────────────
|
|
142
195
|
|
|
143
196
|
describe("GET inference/provider-connections/:name (single)", () => {
|
|
144
197
|
test("returns connection when it exists", async () => {
|
|
145
|
-
seedConnection({
|
|
198
|
+
seedConnection({
|
|
199
|
+
name: "my-conn",
|
|
200
|
+
provider: "anthropic",
|
|
201
|
+
auth: { type: "platform" },
|
|
202
|
+
});
|
|
146
203
|
|
|
147
204
|
const result = (await call(
|
|
148
205
|
findHandler("inference_provider_connections_get"),
|
|
@@ -160,6 +217,21 @@ describe("GET inference/provider-connections/:name (single)", () => {
|
|
|
160
217
|
}),
|
|
161
218
|
).rejects.toBeInstanceOf(NotFoundError);
|
|
162
219
|
});
|
|
220
|
+
|
|
221
|
+
test("throws 404 for openai-compatible row when the feature flag is disabled", async () => {
|
|
222
|
+
_setOverridesForTesting({ "openai-compatible-endpoints": false });
|
|
223
|
+
seedConnection({
|
|
224
|
+
name: "my-compatible",
|
|
225
|
+
provider: "openai-compatible",
|
|
226
|
+
auth: { type: "api_key", credential: "ref/k" },
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
await expect(
|
|
230
|
+
call(findHandler("inference_provider_connections_get"), {
|
|
231
|
+
pathParams: { name: "my-compatible" },
|
|
232
|
+
}),
|
|
233
|
+
).rejects.toBeInstanceOf(NotFoundError);
|
|
234
|
+
});
|
|
163
235
|
});
|
|
164
236
|
|
|
165
237
|
// ── POST create ───────────────────────────────────────────────────────────────
|
|
@@ -179,7 +251,10 @@ describe("POST inference/provider-connections (create)", () => {
|
|
|
179
251
|
|
|
180
252
|
expect(result.name).toBe("my-anthropic");
|
|
181
253
|
expect(result.provider).toBe("anthropic");
|
|
182
|
-
expect(result.auth).toEqual({
|
|
254
|
+
expect(result.auth).toEqual({
|
|
255
|
+
type: "api_key",
|
|
256
|
+
credential: "vault/anthropic/key",
|
|
257
|
+
});
|
|
183
258
|
expect(typeof result.createdAt).toBe("number");
|
|
184
259
|
});
|
|
185
260
|
|
|
@@ -187,7 +262,11 @@ describe("POST inference/provider-connections (create)", () => {
|
|
|
187
262
|
const result = (await call(
|
|
188
263
|
findHandler("inference_provider_connections_create"),
|
|
189
264
|
{
|
|
190
|
-
body: {
|
|
265
|
+
body: {
|
|
266
|
+
name: "managed-openai",
|
|
267
|
+
provider: "openai",
|
|
268
|
+
auth: { type: "platform" },
|
|
269
|
+
},
|
|
191
270
|
},
|
|
192
271
|
)) as { auth: object };
|
|
193
272
|
expect(result.auth).toEqual({ type: "platform" });
|
|
@@ -197,18 +276,30 @@ describe("POST inference/provider-connections (create)", () => {
|
|
|
197
276
|
const result = (await call(
|
|
198
277
|
findHandler("inference_provider_connections_create"),
|
|
199
278
|
{
|
|
200
|
-
body: {
|
|
279
|
+
body: {
|
|
280
|
+
name: "ollama-local",
|
|
281
|
+
provider: "ollama",
|
|
282
|
+
auth: { type: "none" },
|
|
283
|
+
},
|
|
201
284
|
},
|
|
202
285
|
)) as { auth: object };
|
|
203
286
|
expect(result.auth).toEqual({ type: "none" });
|
|
204
287
|
});
|
|
205
288
|
|
|
206
289
|
test("throws 409 when connection name already exists", async () => {
|
|
207
|
-
seedConnection({
|
|
290
|
+
seedConnection({
|
|
291
|
+
name: "dup-name",
|
|
292
|
+
provider: "anthropic",
|
|
293
|
+
auth: { type: "platform" },
|
|
294
|
+
});
|
|
208
295
|
|
|
209
296
|
await expect(
|
|
210
297
|
call(findHandler("inference_provider_connections_create"), {
|
|
211
|
-
body: {
|
|
298
|
+
body: {
|
|
299
|
+
name: "dup-name",
|
|
300
|
+
provider: "openai",
|
|
301
|
+
auth: { type: "platform" },
|
|
302
|
+
},
|
|
212
303
|
}),
|
|
213
304
|
).rejects.toBeInstanceOf(ConflictError);
|
|
214
305
|
});
|
|
@@ -216,7 +307,27 @@ describe("POST inference/provider-connections (create)", () => {
|
|
|
216
307
|
test("throws 400 when provider is invalid", async () => {
|
|
217
308
|
await expect(
|
|
218
309
|
call(findHandler("inference_provider_connections_create"), {
|
|
219
|
-
body: {
|
|
310
|
+
body: {
|
|
311
|
+
name: "test",
|
|
312
|
+
provider: "bogus-provider",
|
|
313
|
+
auth: { type: "platform" },
|
|
314
|
+
},
|
|
315
|
+
}),
|
|
316
|
+
).rejects.toBeInstanceOf(BadRequestError);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test("rejects openai-compatible creation when the feature flag is disabled", async () => {
|
|
320
|
+
_setOverridesForTesting({ "openai-compatible-endpoints": false });
|
|
321
|
+
|
|
322
|
+
await expect(
|
|
323
|
+
call(findHandler("inference_provider_connections_create"), {
|
|
324
|
+
body: {
|
|
325
|
+
name: "my-compatible",
|
|
326
|
+
provider: "openai-compatible",
|
|
327
|
+
auth: { type: "api_key", credential: "ref/k" },
|
|
328
|
+
base_url: "http://localhost:8080/v1",
|
|
329
|
+
models: [{ id: "local-model" }],
|
|
330
|
+
},
|
|
220
331
|
}),
|
|
221
332
|
).rejects.toBeInstanceOf(BadRequestError);
|
|
222
333
|
});
|
|
@@ -224,7 +335,11 @@ describe("POST inference/provider-connections (create)", () => {
|
|
|
224
335
|
test("throws 400 when auth schema is invalid (api_key without credential)", async () => {
|
|
225
336
|
await expect(
|
|
226
337
|
call(findHandler("inference_provider_connections_create"), {
|
|
227
|
-
body: {
|
|
338
|
+
body: {
|
|
339
|
+
name: "test",
|
|
340
|
+
provider: "anthropic",
|
|
341
|
+
auth: { type: "api_key" },
|
|
342
|
+
},
|
|
228
343
|
}),
|
|
229
344
|
).rejects.toBeInstanceOf(BadRequestError);
|
|
230
345
|
});
|
|
@@ -232,7 +347,11 @@ describe("POST inference/provider-connections (create)", () => {
|
|
|
232
347
|
test("throws 400 when auth type is unknown", async () => {
|
|
233
348
|
await expect(
|
|
234
349
|
call(findHandler("inference_provider_connections_create"), {
|
|
235
|
-
body: {
|
|
350
|
+
body: {
|
|
351
|
+
name: "test",
|
|
352
|
+
provider: "anthropic",
|
|
353
|
+
auth: { type: "magic_beans" },
|
|
354
|
+
},
|
|
236
355
|
}),
|
|
237
356
|
).rejects.toBeInstanceOf(BadRequestError);
|
|
238
357
|
});
|
|
@@ -250,7 +369,11 @@ describe("POST inference/provider-connections (create)", () => {
|
|
|
250
369
|
|
|
251
370
|
describe("PATCH inference/provider-connections/:name (update)", () => {
|
|
252
371
|
test("updates auth on existing connection", async () => {
|
|
253
|
-
seedConnection({
|
|
372
|
+
seedConnection({
|
|
373
|
+
name: "upd-conn",
|
|
374
|
+
provider: "anthropic",
|
|
375
|
+
auth: { type: "platform" },
|
|
376
|
+
});
|
|
254
377
|
|
|
255
378
|
const result = (await call(
|
|
256
379
|
findHandler("inference_provider_connections_update"),
|
|
@@ -273,7 +396,11 @@ describe("PATCH inference/provider-connections/:name (update)", () => {
|
|
|
273
396
|
});
|
|
274
397
|
|
|
275
398
|
test("throws 400 when auth schema is invalid", async () => {
|
|
276
|
-
seedConnection({
|
|
399
|
+
seedConnection({
|
|
400
|
+
name: "bad-auth",
|
|
401
|
+
provider: "openai",
|
|
402
|
+
auth: { type: "platform" },
|
|
403
|
+
});
|
|
277
404
|
|
|
278
405
|
await expect(
|
|
279
406
|
call(findHandler("inference_provider_connections_update"), {
|
|
@@ -288,7 +415,11 @@ describe("PATCH inference/provider-connections/:name (update)", () => {
|
|
|
288
415
|
|
|
289
416
|
describe("DELETE inference/provider-connections/:name (delete)", () => {
|
|
290
417
|
test("deletes an unreferenced connection", async () => {
|
|
291
|
-
seedConnection({
|
|
418
|
+
seedConnection({
|
|
419
|
+
name: "del-me",
|
|
420
|
+
provider: "gemini",
|
|
421
|
+
auth: { type: "platform" },
|
|
422
|
+
});
|
|
292
423
|
|
|
293
424
|
const result = (await call(
|
|
294
425
|
findHandler("inference_provider_connections_delete"),
|
|
@@ -313,11 +444,18 @@ describe("DELETE inference/provider-connections/:name (delete)", () => {
|
|
|
313
444
|
});
|
|
314
445
|
|
|
315
446
|
test("throws 409 when a profile references the connection", async () => {
|
|
316
|
-
seedConnection({
|
|
447
|
+
seedConnection({
|
|
448
|
+
name: "ref-conn",
|
|
449
|
+
provider: "anthropic",
|
|
450
|
+
auth: { type: "platform" },
|
|
451
|
+
});
|
|
317
452
|
fakeConfig = {
|
|
318
453
|
llm: {
|
|
319
454
|
profiles: {
|
|
320
|
-
"my-profile": {
|
|
455
|
+
"my-profile": {
|
|
456
|
+
provider_connection: "ref-conn",
|
|
457
|
+
model: "claude-opus-4-7",
|
|
458
|
+
},
|
|
321
459
|
},
|
|
322
460
|
},
|
|
323
461
|
};
|
|
@@ -332,7 +470,11 @@ describe("DELETE inference/provider-connections/:name (delete)", () => {
|
|
|
332
470
|
});
|
|
333
471
|
|
|
334
472
|
test("throws 409 when llm.default references the connection", async () => {
|
|
335
|
-
seedConnection({
|
|
473
|
+
seedConnection({
|
|
474
|
+
name: "default-conn",
|
|
475
|
+
provider: "anthropic",
|
|
476
|
+
auth: { type: "platform" },
|
|
477
|
+
});
|
|
336
478
|
fakeConfig = {
|
|
337
479
|
llm: {
|
|
338
480
|
default: { provider_connection: "default-conn" },
|
|
@@ -366,7 +508,11 @@ describe("DELETE inference/provider-connections/:name (delete)", () => {
|
|
|
366
508
|
});
|
|
367
509
|
|
|
368
510
|
test("throws 409 when both llm.default and a profile reference the connection", async () => {
|
|
369
|
-
seedConnection({
|
|
511
|
+
seedConnection({
|
|
512
|
+
name: "shared-conn",
|
|
513
|
+
provider: "anthropic",
|
|
514
|
+
auth: { type: "none" },
|
|
515
|
+
});
|
|
370
516
|
fakeConfig = {
|
|
371
517
|
llm: {
|
|
372
518
|
default: { provider_connection: "shared-conn" },
|
|
@@ -409,7 +555,11 @@ describe("POST with label and status", () => {
|
|
|
409
555
|
const result = (await call(
|
|
410
556
|
findHandler("inference_provider_connections_create"),
|
|
411
557
|
{
|
|
412
|
-
body: {
|
|
558
|
+
body: {
|
|
559
|
+
name: "no-label-conn",
|
|
560
|
+
provider: "openai",
|
|
561
|
+
auth: { type: "platform" },
|
|
562
|
+
},
|
|
413
563
|
},
|
|
414
564
|
)) as { label: string | null; status: string };
|
|
415
565
|
expect(result.label).toBeNull();
|
|
@@ -419,7 +569,11 @@ describe("POST with label and status", () => {
|
|
|
419
569
|
|
|
420
570
|
describe("PATCH with status and label", () => {
|
|
421
571
|
test("updates status to disabled", async () => {
|
|
422
|
-
seedConnection({
|
|
572
|
+
seedConnection({
|
|
573
|
+
name: "toggleable",
|
|
574
|
+
provider: "anthropic",
|
|
575
|
+
auth: { type: "platform" },
|
|
576
|
+
});
|
|
423
577
|
|
|
424
578
|
const result = (await call(
|
|
425
579
|
findHandler("inference_provider_connections_update"),
|
|
@@ -432,7 +586,11 @@ describe("PATCH with status and label", () => {
|
|
|
432
586
|
});
|
|
433
587
|
|
|
434
588
|
test("updates label to a string", async () => {
|
|
435
|
-
seedConnection({
|
|
589
|
+
seedConnection({
|
|
590
|
+
name: "set-label",
|
|
591
|
+
provider: "openai",
|
|
592
|
+
auth: { type: "platform" },
|
|
593
|
+
});
|
|
436
594
|
|
|
437
595
|
const result = (await call(
|
|
438
596
|
findHandler("inference_provider_connections_update"),
|
|
@@ -445,7 +603,11 @@ describe("PATCH with status and label", () => {
|
|
|
445
603
|
});
|
|
446
604
|
|
|
447
605
|
test("clears label by setting it to null", async () => {
|
|
448
|
-
seedConnection({
|
|
606
|
+
seedConnection({
|
|
607
|
+
name: "clear-label",
|
|
608
|
+
provider: "gemini",
|
|
609
|
+
auth: { type: "platform" },
|
|
610
|
+
});
|
|
449
611
|
// First set a label.
|
|
450
612
|
await call(findHandler("inference_provider_connections_update"), {
|
|
451
613
|
pathParams: { name: "clear-label" },
|
|
@@ -463,7 +625,11 @@ describe("PATCH with status and label", () => {
|
|
|
463
625
|
});
|
|
464
626
|
|
|
465
627
|
test("rejects label: empty string with 400", async () => {
|
|
466
|
-
seedConnection({
|
|
628
|
+
seedConnection({
|
|
629
|
+
name: "reject-empty",
|
|
630
|
+
provider: "anthropic",
|
|
631
|
+
auth: { type: "platform" },
|
|
632
|
+
});
|
|
467
633
|
|
|
468
634
|
await expect(
|
|
469
635
|
call(findHandler("inference_provider_connections_update"), {
|
|
@@ -477,12 +643,20 @@ describe("PATCH with status and label", () => {
|
|
|
477
643
|
// ── Managed-connection write protection ──────────────────────────────────────
|
|
478
644
|
|
|
479
645
|
describe("Managed connection write protection", () => {
|
|
480
|
-
const MANAGED_NAMES = [
|
|
646
|
+
const MANAGED_NAMES = [
|
|
647
|
+
"anthropic-managed",
|
|
648
|
+
"openai-managed",
|
|
649
|
+
"gemini-managed",
|
|
650
|
+
] as const;
|
|
481
651
|
|
|
482
652
|
describe("DELETE", () => {
|
|
483
653
|
for (const name of MANAGED_NAMES) {
|
|
484
654
|
test(`rejects DELETE on ${name} with 400`, async () => {
|
|
485
|
-
seedConnection({
|
|
655
|
+
seedConnection({
|
|
656
|
+
name,
|
|
657
|
+
provider: name.replace("-managed", ""),
|
|
658
|
+
auth: { type: "platform" },
|
|
659
|
+
});
|
|
486
660
|
|
|
487
661
|
const err = await call(
|
|
488
662
|
findHandler("inference_provider_connections_delete"),
|
|
@@ -498,11 +672,15 @@ describe("Managed connection write protection", () => {
|
|
|
498
672
|
test("managed protection short-circuits before reference checks", async () => {
|
|
499
673
|
// Even though a profile references the managed connection, the error
|
|
500
674
|
// should be the managed-protection 400, not the references-409.
|
|
501
|
-
seedConnection({
|
|
675
|
+
seedConnection({
|
|
676
|
+
name: "anthropic-managed",
|
|
677
|
+
provider: "anthropic",
|
|
678
|
+
auth: { type: "platform" },
|
|
679
|
+
});
|
|
502
680
|
fakeConfig = {
|
|
503
681
|
llm: {
|
|
504
682
|
profiles: {
|
|
505
|
-
|
|
683
|
+
balanced: { provider_connection: "anthropic-managed" },
|
|
506
684
|
},
|
|
507
685
|
},
|
|
508
686
|
};
|
|
@@ -520,7 +698,11 @@ describe("Managed connection write protection", () => {
|
|
|
520
698
|
describe("PATCH auth", () => {
|
|
521
699
|
for (const name of MANAGED_NAMES) {
|
|
522
700
|
test(`rejects auth change on ${name} from platform to api_key with 400`, async () => {
|
|
523
|
-
seedConnection({
|
|
701
|
+
seedConnection({
|
|
702
|
+
name,
|
|
703
|
+
provider: name.replace("-managed", ""),
|
|
704
|
+
auth: { type: "platform" },
|
|
705
|
+
});
|
|
524
706
|
|
|
525
707
|
const err = await call(
|
|
526
708
|
findHandler("inference_provider_connections_update"),
|
|
@@ -536,7 +718,11 @@ describe("Managed connection write protection", () => {
|
|
|
536
718
|
});
|
|
537
719
|
|
|
538
720
|
test(`rejects auth change on ${name} from platform to none with 400`, async () => {
|
|
539
|
-
seedConnection({
|
|
721
|
+
seedConnection({
|
|
722
|
+
name,
|
|
723
|
+
provider: name.replace("-managed", ""),
|
|
724
|
+
auth: { type: "platform" },
|
|
725
|
+
});
|
|
540
726
|
|
|
541
727
|
const err = await call(
|
|
542
728
|
findHandler("inference_provider_connections_update"),
|
|
@@ -552,13 +738,20 @@ describe("Managed connection write protection", () => {
|
|
|
552
738
|
}
|
|
553
739
|
|
|
554
740
|
test("allows PATCH with auth still set to platform (no-op auth change)", async () => {
|
|
555
|
-
seedConnection({
|
|
741
|
+
seedConnection({
|
|
742
|
+
name: "anthropic-managed",
|
|
743
|
+
provider: "anthropic",
|
|
744
|
+
auth: { type: "platform" },
|
|
745
|
+
});
|
|
556
746
|
|
|
557
747
|
const result = (await call(
|
|
558
748
|
findHandler("inference_provider_connections_update"),
|
|
559
749
|
{
|
|
560
750
|
pathParams: { name: "anthropic-managed" },
|
|
561
|
-
body: {
|
|
751
|
+
body: {
|
|
752
|
+
auth: { type: "platform" },
|
|
753
|
+
label: "Vellum-managed Anthropic",
|
|
754
|
+
},
|
|
562
755
|
},
|
|
563
756
|
)) as { label: string | null };
|
|
564
757
|
expect(result.label).toBe("Vellum-managed Anthropic");
|
|
@@ -567,7 +760,11 @@ describe("Managed connection write protection", () => {
|
|
|
567
760
|
|
|
568
761
|
describe("PATCH status + label (allowed)", () => {
|
|
569
762
|
test("allows disabling a managed connection", async () => {
|
|
570
|
-
seedConnection({
|
|
763
|
+
seedConnection({
|
|
764
|
+
name: "anthropic-managed",
|
|
765
|
+
provider: "anthropic",
|
|
766
|
+
auth: { type: "platform" },
|
|
767
|
+
});
|
|
571
768
|
|
|
572
769
|
const result = (await call(
|
|
573
770
|
findHandler("inference_provider_connections_update"),
|
|
@@ -580,7 +777,11 @@ describe("Managed connection write protection", () => {
|
|
|
580
777
|
});
|
|
581
778
|
|
|
582
779
|
test("allows relabeling a managed connection", async () => {
|
|
583
|
-
seedConnection({
|
|
780
|
+
seedConnection({
|
|
781
|
+
name: "openai-managed",
|
|
782
|
+
provider: "openai",
|
|
783
|
+
auth: { type: "platform" },
|
|
784
|
+
});
|
|
584
785
|
|
|
585
786
|
const result = (await call(
|
|
586
787
|
findHandler("inference_provider_connections_update"),
|
|
@@ -597,21 +798,35 @@ describe("Managed connection write protection", () => {
|
|
|
597
798
|
// ── isManaged response flag ───────────────────────────────────────────────────
|
|
598
799
|
|
|
599
800
|
describe("isManaged flag on connection responses", () => {
|
|
600
|
-
const MANAGED_NAMES = [
|
|
801
|
+
const MANAGED_NAMES = [
|
|
802
|
+
"anthropic-managed",
|
|
803
|
+
"openai-managed",
|
|
804
|
+
"gemini-managed",
|
|
805
|
+
] as const;
|
|
601
806
|
|
|
602
807
|
describe("GET list", () => {
|
|
603
808
|
test("returns isManaged: true for canonical names and false for user-created rows", async () => {
|
|
604
809
|
for (const name of MANAGED_NAMES) {
|
|
605
|
-
seedConnection({
|
|
810
|
+
seedConnection({
|
|
811
|
+
name,
|
|
812
|
+
provider: name.replace("-managed", ""),
|
|
813
|
+
auth: { type: "platform" },
|
|
814
|
+
});
|
|
606
815
|
}
|
|
607
|
-
seedConnection({
|
|
816
|
+
seedConnection({
|
|
817
|
+
name: "my-custom-anthropic",
|
|
818
|
+
provider: "anthropic",
|
|
819
|
+
auth: { type: "api_key", credential: "ref/k" },
|
|
820
|
+
});
|
|
608
821
|
|
|
609
822
|
const result = (await call(
|
|
610
823
|
findHandler("inference_provider_connections_list"),
|
|
611
824
|
{},
|
|
612
825
|
)) as { connections: Array<{ name: string; isManaged: boolean }> };
|
|
613
826
|
|
|
614
|
-
const byName = Object.fromEntries(
|
|
827
|
+
const byName = Object.fromEntries(
|
|
828
|
+
result.connections.map((c) => [c.name, c.isManaged]),
|
|
829
|
+
);
|
|
615
830
|
expect(byName["anthropic-managed"]).toBe(true);
|
|
616
831
|
expect(byName["openai-managed"]).toBe(true);
|
|
617
832
|
expect(byName["gemini-managed"]).toBe(true);
|
|
@@ -621,7 +836,11 @@ describe("isManaged flag on connection responses", () => {
|
|
|
621
836
|
|
|
622
837
|
describe("GET single", () => {
|
|
623
838
|
test("returns isManaged: true for a managed name", async () => {
|
|
624
|
-
seedConnection({
|
|
839
|
+
seedConnection({
|
|
840
|
+
name: "anthropic-managed",
|
|
841
|
+
provider: "anthropic",
|
|
842
|
+
auth: { type: "platform" },
|
|
843
|
+
});
|
|
625
844
|
|
|
626
845
|
const result = (await call(
|
|
627
846
|
findHandler("inference_provider_connections_get"),
|
|
@@ -632,7 +851,11 @@ describe("isManaged flag on connection responses", () => {
|
|
|
632
851
|
});
|
|
633
852
|
|
|
634
853
|
test("returns isManaged: false for a user-created name", async () => {
|
|
635
|
-
seedConnection({
|
|
854
|
+
seedConnection({
|
|
855
|
+
name: "my-openai",
|
|
856
|
+
provider: "openai",
|
|
857
|
+
auth: { type: "api_key", credential: "ref/k" },
|
|
858
|
+
});
|
|
636
859
|
|
|
637
860
|
const result = (await call(
|
|
638
861
|
findHandler("inference_provider_connections_get"),
|
|
@@ -662,7 +885,11 @@ describe("isManaged flag on connection responses", () => {
|
|
|
662
885
|
|
|
663
886
|
describe("PATCH update", () => {
|
|
664
887
|
test("returns isManaged: true after relabeling a managed connection", async () => {
|
|
665
|
-
seedConnection({
|
|
888
|
+
seedConnection({
|
|
889
|
+
name: "anthropic-managed",
|
|
890
|
+
provider: "anthropic",
|
|
891
|
+
auth: { type: "platform" },
|
|
892
|
+
});
|
|
666
893
|
|
|
667
894
|
const result = (await call(
|
|
668
895
|
findHandler("inference_provider_connections_update"),
|
|
@@ -676,7 +903,11 @@ describe("isManaged flag on connection responses", () => {
|
|
|
676
903
|
});
|
|
677
904
|
|
|
678
905
|
test("returns isManaged: false after updating a user connection", async () => {
|
|
679
|
-
seedConnection({
|
|
906
|
+
seedConnection({
|
|
907
|
+
name: "my-openai",
|
|
908
|
+
provider: "openai",
|
|
909
|
+
auth: { type: "api_key", credential: "ref/k" },
|
|
910
|
+
});
|
|
680
911
|
|
|
681
912
|
const result = (await call(
|
|
682
913
|
findHandler("inference_provider_connections_update"),
|
|
@@ -45,6 +45,18 @@ describe("llm-call-sites-routes", () => {
|
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
+
test("defaultProfile is a non-empty string or undefined per call site", async () => {
|
|
49
|
+
const result = (await route.handler({})) as {
|
|
50
|
+
callSites: Array<{ id: string; defaultProfile?: string }>;
|
|
51
|
+
};
|
|
52
|
+
for (const site of result.callSites) {
|
|
53
|
+
if (site.defaultProfile != null) {
|
|
54
|
+
expect(typeof site.defaultProfile).toBe("string");
|
|
55
|
+
expect(site.defaultProfile.length).toBeGreaterThan(0);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
48
60
|
test("domains have non-empty id and displayName", async () => {
|
|
49
61
|
const result = (await route.handler({})) as {
|
|
50
62
|
domains: Array<{ id: string; displayName: string }>;
|