@vellumai/assistant 0.8.10 → 0.8.11-staging.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bun.lock +62 -1
- package/docs/workspace-tools.md +196 -0
- package/examples/plugins/echo/README.md +3 -3
- package/knip.json +1 -0
- package/openapi.yaml +460 -128
- package/package.json +2 -1
- package/scripts/build-plugin-api.ts +299 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +7 -0
- package/src/__tests__/agent-loop-compaction-events.test.ts +197 -0
- package/src/__tests__/agent-loop-exit-reason.test.ts +93 -96
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +2 -0
- package/src/__tests__/agent-loop-output-hooks.test.ts +274 -1
- package/src/__tests__/agent-loop-override-profile.test.ts +3 -0
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +4 -0
- package/src/__tests__/agent-loop-thinking.test.ts +4 -0
- package/src/__tests__/agent-loop.test.ts +578 -5
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -1
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -1
- package/src/__tests__/build-persisted-content.test.ts +75 -1
- package/src/__tests__/catalog-install-normalize.test.ts +141 -0
- package/src/__tests__/ces-startup-timeout.test.ts +60 -0
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
- package/src/__tests__/context-overflow-reducer.test.ts +264 -124
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +351 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -5
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +284 -455
- package/src/__tests__/conversation-agent-loop.test.ts +131 -551
- package/src/__tests__/conversation-app-control-instantiation.test.ts +13 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-fork-crud.test.ts +259 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-lifecycle.test.ts +257 -1
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +38 -377
- package/src/__tests__/conversation-queue.test.ts +1 -39
- package/src/__tests__/conversation-runtime-assembly.test.ts +119 -8
- package/src/__tests__/conversation-skill-tools.test.ts +491 -5
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +74 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +4 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +323 -0
- package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +34 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -5
- package/src/__tests__/credential-execution-tools.test.ts +23 -11
- package/src/__tests__/credential-security-invariants.test.ts +6 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +80 -0
- package/src/__tests__/device-id.test.ts +70 -1
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
- package/src/__tests__/empty-response-hook.test.ts +242 -66
- package/src/__tests__/external-plugin-loader.test.ts +0 -31
- package/src/__tests__/get-skill-detail-audit.test.ts +43 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +91 -0
- package/src/__tests__/history-repair-hook.test.ts +228 -3
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- package/src/__tests__/host-browser-proxy.test.ts +254 -9
- package/src/__tests__/identity-routes.test.ts +1 -0
- package/src/__tests__/image-recovery-hook.test.ts +387 -0
- package/src/__tests__/injector-chain.test.ts +5 -4
- package/src/__tests__/injector-v3-suppression.test.ts +373 -47
- package/src/__tests__/intent-routing.test.ts +7 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +117 -15
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/oauth-store.test.ts +0 -85
- package/src/__tests__/{context-overflow-policy.test.ts → overflow-policy.test.ts} +1 -1
- package/src/__tests__/parallel-tool.benchmark.test.ts +4 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +29 -9
- package/src/__tests__/persist-unsendable-image.test.ts +4 -4
- package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
- package/src/__tests__/plugin-bootstrap.test.ts +82 -73
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -8
- package/src/__tests__/provider-catalog-visibility.test.ts +1 -9
- package/src/__tests__/prune-old-conversations-job.test.ts +99 -0
- package/src/__tests__/registry.test.ts +240 -1
- package/src/__tests__/require-fresh-approval.test.ts +3 -0
- package/src/__tests__/schedule-routes.test.ts +116 -1
- package/src/__tests__/schedule-store.test.ts +28 -0
- package/src/__tests__/schedule-tools.test.ts +94 -1
- package/src/__tests__/server-history-render.test.ts +39 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +13 -0
- package/src/__tests__/skill-projection.benchmark.test.ts +25 -7
- package/src/__tests__/skills.test.ts +202 -0
- package/src/__tests__/slim-skill-category.test.ts +195 -0
- package/src/__tests__/strip-memory-injections.test.ts +33 -39
- package/src/__tests__/test-support/tool-invocation-seed.ts +79 -0
- package/src/__tests__/title-generate-hook.test.ts +9 -7
- package/src/__tests__/tool-audit-listener.test.ts +264 -1
- package/src/__tests__/tool-error-hook.test.ts +4 -3
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +273 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +218 -0
- package/src/__tests__/tools-get-route.test.ts +202 -0
- package/src/__tests__/workspace-tool-loader.test.ts +319 -0
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +569 -319
- package/src/api/events/tool-result.ts +9 -0
- package/src/api/events/tool-use-start.ts +7 -0
- package/src/api/index.ts +10 -0
- package/src/api/responses/conversation-message.ts +135 -27
- package/src/api/responses/memory-v3-selection-log.ts +4 -4
- package/src/approvals/guardian-request-resolvers.ts +26 -0
- package/src/browser-session/backends/host-bridge.ts +29 -0
- package/src/browser-session/index.ts +1 -0
- package/src/browser-session/types.ts +5 -1
- package/src/cli/commands/__tests__/schedules.test.ts +62 -4
- package/src/cli/commands/__tests__/skills.test.ts +53 -0
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/inference-providers.ts +0 -8
- package/src/cli/commands/plugins.ts +2 -2
- package/src/cli/commands/schedules.ts +27 -4
- package/src/cli/commands/skills.ts +187 -146
- package/src/cli/commands/tools.ts +106 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +256 -328
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +6 -2
- package/src/cli/lib/__tests__/plugin-details.test.ts +10 -16
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +2 -2
- package/src/cli/lib/__tests__/search-plugins.test.ts +145 -240
- package/src/cli/lib/install-from-github.ts +187 -117
- package/src/cli/lib/plugin-catalog-cache.ts +9 -9
- package/src/cli/lib/plugin-details.ts +38 -68
- package/src/cli/lib/plugin-marketplace.ts +42 -14
- package/src/cli/lib/search-plugins.ts +29 -129
- package/src/cli/program.ts +2 -0
- package/src/config/bundled-skills/acp/SKILL.md +1 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -0
- package/src/config/bundled-skills/app-control/SKILL.md +1 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -0
- package/src/config/bundled-skills/contacts/SKILL.md +1 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +1 -0
- package/src/config/bundled-skills/followups/SKILL.md +1 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +1 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +1 -0
- package/src/config/bundled-skills/messaging/SKILL.md +1 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -0
- package/src/config/bundled-skills/playbooks/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/TOOLS.json +11 -3
- package/src/config/bundled-skills/sequences/SKILL.md +1 -0
- package/src/config/bundled-skills/settings/SKILL.md +1 -0
- package/src/config/bundled-skills/skill-management/SKILL.md +101 -1
- package/src/config/bundled-skills/subagent/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -0
- package/src/config/env-registry.ts +23 -0
- package/src/config/feature-flag-registry.json +17 -81
- package/src/config/loader.ts +5 -22
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/compaction-logs.test.ts +56 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +0 -1
- package/src/config/schemas/__tests__/memory-v3.test.ts +61 -1
- package/src/config/schemas/compaction-logs.ts +79 -0
- package/src/config/schemas/memory-v2.ts +0 -8
- package/src/config/schemas/memory-v3.ts +104 -33
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/config/skills.ts +117 -47
- package/src/context/compactor.ts +11 -0
- package/src/context/strip-injections.ts +38 -4
- package/src/credential-execution/feature-gates.ts +0 -21
- package/src/credential-execution/startup-timeout.ts +32 -4
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +18 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +140 -91
- package/src/daemon/conversation-agent-loop.ts +123 -658
- package/src/daemon/conversation-error.ts +6 -33
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-runtime-assembly.ts +183 -22
- package/src/daemon/conversation-skill-tools.ts +137 -8
- package/src/daemon/conversation-slash.ts +0 -14
- package/src/daemon/conversation-store.ts +2 -19
- package/src/daemon/conversation-tool-setup.ts +87 -1
- package/src/daemon/conversation.ts +119 -50
- package/src/daemon/external-plugins-bootstrap.ts +36 -95
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/shared.ts +9 -1
- package/src/daemon/handlers/skills.ts +10 -4
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-browser-proxy.ts +117 -22
- package/src/daemon/lifecycle.ts +34 -5
- package/src/daemon/message-protocol.ts +0 -7
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/skills.ts +17 -0
- package/src/daemon/providers-setup.ts +3 -0
- package/src/daemon/server.ts +3 -3
- package/src/daemon/tool-setup-types.ts +9 -3
- package/src/daemon/trust-context.ts +23 -0
- package/src/daemon/workspace-tools-watcher.ts +324 -0
- package/src/events/tool-audit-listener.ts +78 -16
- package/src/events/tool-metrics-listener.ts +2 -5
- package/src/memory/__tests__/compaction-log-writer-clickhouse.test.ts +227 -0
- package/src/memory/__tests__/conversation-queries.test.ts +176 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +20 -32
- package/src/memory/compaction-log-writer-clickhouse.ts +418 -0
- package/src/memory/conversation-crud.ts +134 -3
- package/src/memory/conversation-queries.ts +64 -7
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.test.ts +130 -1
- package/src/memory/embedding-backend.ts +79 -106
- package/src/memory/embedding-gemini.ts +5 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +12 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +19 -0
- package/src/memory/graph/conversation-graph-memory.ts +36 -25
- package/src/memory/graph/tool-handlers.ts +3 -0
- package/src/memory/job-handlers/cleanup.ts +3 -1
- package/src/memory/jobs-store.ts +0 -28
- package/src/memory/jobs-worker.ts +10 -22
- package/src/memory/memory-marker.ts +29 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +1 -1
- package/src/memory/migrations/268-add-memory-v3-selections.ts +6 -0
- package/src/memory/migrations/270-schedule-description.ts +36 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.test.ts +81 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.ts +20 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.test.ts +68 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.ts +20 -0
- package/src/memory/migrations/277-add-memory-v3-ever-injected.ts +29 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.test.ts +96 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.ts +39 -0
- package/src/memory/migrations/279-create-skill-loaded-events.test.ts +84 -0
- package/src/memory/migrations/279-create-skill-loaded-events.ts +26 -0
- package/src/memory/migrations/280-conversations-surfaced-at.test.ts +88 -0
- package/src/memory/migrations/280-conversations-surfaced-at.ts +24 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +16 -0
- package/src/memory/schema/infrastructure.ts +26 -0
- package/src/memory/skill-loaded-events-store.test.ts +160 -0
- package/src/memory/skill-loaded-events-store.ts +95 -0
- package/src/memory/tool-executed-events-store.test.ts +219 -0
- package/src/memory/tool-executed-events-store.ts +102 -0
- package/src/memory/tool-usage-store.ts +15 -3
- package/src/memory/v2/__tests__/consolidation-job.test.ts +117 -12
- package/src/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +189 -0
- package/src/memory/v2/__tests__/injected-block-slugs.test.ts +90 -0
- package/src/memory/v2/__tests__/page-store.test.ts +33 -0
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +88 -15
- package/src/memory/v2/activation-store.ts +50 -1
- package/src/memory/v2/consolidation-job.ts +113 -29
- package/src/memory/v2/injected-block-slugs.ts +79 -0
- package/src/memory/v2/injection.ts +6 -1
- package/src/memory/v2/prompts/consolidation.ts +414 -13
- package/src/memory/v2/router.ts +2 -28
- package/src/memory/v2/static-context.ts +1 -1
- package/src/memory/v2/types.ts +16 -0
- package/src/notifications/__tests__/copy-composer.test.ts +244 -0
- package/src/notifications/access-request-copy.ts +298 -0
- package/src/notifications/adapters/slack.ts +3 -3
- package/src/notifications/adapters/telegram.ts +2 -1
- package/src/notifications/copy-composer.ts +49 -267
- package/src/notifications/decision-engine.ts +16 -35
- package/src/notifications/home-feed-side-effect.ts +1 -6
- package/src/oauth/oauth-store.ts +0 -9
- package/src/permissions/checker.test.ts +83 -1
- package/src/permissions/checker.ts +25 -2
- package/src/permissions/gateway-threshold-reader.test.ts +182 -0
- package/src/permissions/gateway-threshold-reader.ts +80 -0
- package/src/platform/client.ts +1 -3
- package/src/platform/feature-gate.ts +3 -12
- package/src/plugin-api/constants.ts +4 -2
- package/src/plugin-api/index.ts +63 -11
- package/src/plugin-api/types.ts +236 -71
- package/src/plugins/defaults/compaction/compact.ts +66 -2
- package/src/plugins/defaults/compaction/context-overflow-reducer.ts +240 -32
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/{daemon/context-overflow-policy.ts → plugins/defaults/compaction/overflow-policy.ts} +1 -1
- package/src/plugins/defaults/compaction/window-manager.ts +303 -1
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +173 -0
- package/src/plugins/defaults/empty-response/hooks/stop.ts +11 -115
- package/src/plugins/defaults/empty-response/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +50 -0
- package/src/plugins/defaults/history-repair/hooks/stop.ts +22 -0
- package/src/plugins/defaults/history-repair/repair-state-store.ts +51 -0
- package/src/plugins/defaults/history-repair/terminal.ts +39 -2
- package/src/plugins/defaults/image-recovery/detect.ts +25 -0
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +73 -0
- package/src/plugins/defaults/image-recovery/hooks/stop.ts +22 -0
- package/src/plugins/defaults/image-recovery/image-recovery-state-store.ts +48 -0
- package/src/plugins/defaults/image-recovery/package.json +14 -0
- package/src/{daemon/persist-unsendable-image.ts → plugins/defaults/image-recovery/recover.ts} +67 -14
- package/src/plugins/defaults/index.ts +71 -5
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +76 -112
- package/src/plugins/defaults/memory-retrieval/hooks/{user-prompt-submit-temp.ts → user-prompt-submit.ts} +83 -74
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +14 -8
- package/src/plugins/defaults/memory-retrieval/injectors.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1157 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +683 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +161 -140
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +160 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +335 -316
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +145 -53
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +38 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +18 -8
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +112 -71
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +192 -51
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +4 -16
- package/src/plugins/defaults/memory-v3-shadow/card.test.ts +173 -0
- package/src/plugins/defaults/memory-v3-shadow/card.ts +116 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.test.ts +104 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.test.ts +305 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.ts +278 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.test.ts +138 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.ts +85 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +331 -24
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +119 -13
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +169 -114
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +47 -16
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +144 -66
- package/src/plugins/defaults/memory-v3-shadow/prune.test.ts +758 -0
- package/src/plugins/defaults/memory-v3-shadow/prune.ts +471 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +68 -16
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +19 -12
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +96 -43
- package/src/plugins/defaults/memory-v3-shadow/types.ts +34 -17
- package/src/plugins/defaults/title-generate/hooks/stop.ts +9 -11
- package/src/plugins/pipeline.ts +8 -5
- package/src/plugins/types.ts +5 -51
- package/src/providers/cache-control.ts +26 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -2
- package/src/providers/model-catalog.ts +13 -1
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +147 -0
- package/src/providers/openai/chat-completions-provider.ts +46 -0
- package/src/providers/openai/responses-provider.ts +45 -0
- package/src/providers/registry.ts +0 -8
- package/src/runtime/__tests__/agent-wake.test.ts +0 -1
- package/src/runtime/agent-wake.ts +13 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +151 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +12 -50
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +322 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +0 -62
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +31 -11
- package/src/runtime/routes/acp-routes.test.ts +106 -0
- package/src/runtime/routes/acp-routes.ts +248 -2
- package/src/runtime/routes/browser-tabs-routes.ts +1 -1
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +0 -14
- package/src/runtime/routes/consolidation-routes.ts +6 -82
- package/src/runtime/routes/conversation-list-routes.ts +6 -0
- package/src/runtime/routes/conversation-management-routes.ts +71 -0
- package/src/runtime/routes/identity-routes.ts +8 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -45
- package/src/runtime/routes/plugins-routes.ts +34 -45
- package/src/runtime/routes/schedule-routes.ts +43 -5
- package/src/runtime/routes/settings-routes.ts +140 -15
- package/src/runtime/routes/skills-routes.ts +18 -6
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +140 -0
- package/src/runtime/services/conversation-serializer.ts +38 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/schedule/schedule-store.ts +19 -0
- package/src/skills/catalog-install.ts +77 -13
- package/src/tasks/task-scheduler.ts +1 -0
- package/src/telemetry/types.ts +66 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +542 -13
- package/src/telemetry/usage-telemetry-reporter.ts +213 -20
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +49 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +29 -5
- package/src/tools/browser/browser-execution.ts +27 -9
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +380 -4
- package/src/tools/browser/cdp-client/__tests__/host-bridge-cdp-client.test.ts +107 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +6 -1
- package/src/tools/browser/cdp-client/factory.ts +217 -17
- package/src/tools/browser/cdp-client/host-bridge-cdp-client.ts +67 -0
- package/src/tools/browser/cdp-client/types.ts +22 -2
- package/src/tools/credential-execution/make-authenticated-request.ts +2 -1
- package/src/tools/credential-execution/manage-secure-command-tool.ts +169 -164
- package/src/tools/credential-execution/run-authenticated-command.ts +2 -1
- package/src/tools/executor.ts +39 -7
- package/src/tools/registry.ts +387 -5
- package/src/tools/schedule/create.ts +16 -0
- package/src/tools/schedule/list.ts +12 -4
- package/src/tools/schedule/update.ts +12 -0
- package/src/tools/skills/load.ts +11 -6
- package/src/tools/terminal/safe-env.ts +2 -0
- package/src/tools/types.ts +65 -9
- package/src/tools/workspace-tools/loader.ts +673 -0
- package/src/usage/attribution.ts +28 -0
- package/src/util/device-id.ts +17 -3
- package/src/util/platform.ts +16 -0
- package/tsconfig.plugin-api.json +13 -0
- package/src/__tests__/plugin-external-api.test.ts +0 -68
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -355
- package/src/daemon/message-types/browser.ts +0 -10
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +0 -36
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +0 -37
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +0 -106
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +0 -44
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +0 -91
- package/src/plugins/external-api.ts +0 -114
- package/src/plugins/plugin-skill-contributions.ts +0 -292
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
+
import type { CesClient } from "../credential-execution/client.js";
|
|
3
4
|
import { RiskLevel } from "../permissions/types.js";
|
|
5
|
+
import { setCesClient } from "../security/secure-keys.js";
|
|
4
6
|
import { makeAuthenticatedRequestTool } from "../tools/credential-execution/make-authenticated-request.js";
|
|
5
7
|
import { manageSecureCommandTool } from "../tools/credential-execution/manage-secure-command-tool.js";
|
|
6
8
|
import { runAuthenticatedCommandTool } from "../tools/credential-execution/run-authenticated-command.js";
|
|
@@ -168,6 +170,11 @@ describe("CES tool execution without client", () => {
|
|
|
168
170
|
trustClass: "guardian" as const,
|
|
169
171
|
};
|
|
170
172
|
|
|
173
|
+
// The CES tools resolve the client via the module-level getCesClient()
|
|
174
|
+
// resolver, so ensure none is injected for the "absent client" cases.
|
|
175
|
+
beforeEach(() => setCesClient(undefined));
|
|
176
|
+
afterEach(() => setCesClient(undefined));
|
|
177
|
+
|
|
171
178
|
test("make_authenticated_request fails gracefully when CES client is absent", async () => {
|
|
172
179
|
const result = await makeAuthenticatedRequestTool.execute(
|
|
173
180
|
{
|
|
@@ -218,19 +225,24 @@ describe("CES tool execution without client", () => {
|
|
|
218
225
|
// ---------------------------------------------------------------------------
|
|
219
226
|
|
|
220
227
|
describe("manage_secure_command_tool input validation", () => {
|
|
221
|
-
const
|
|
228
|
+
const minimalContext = {
|
|
222
229
|
workingDir: "/tmp",
|
|
223
230
|
conversationId: "test-conversation",
|
|
224
231
|
trustClass: "guardian" as const,
|
|
225
|
-
cesClient: {
|
|
226
|
-
isReady: () => true,
|
|
227
|
-
handshake: async () => ({ accepted: true }),
|
|
228
|
-
call: async () => ({ success: true }),
|
|
229
|
-
updateAssistantApiKey: async () => ({ updated: true }),
|
|
230
|
-
close: () => {},
|
|
231
|
-
},
|
|
232
232
|
};
|
|
233
233
|
|
|
234
|
+
// Input validation runs only after the client readiness check passes, so
|
|
235
|
+
// inject a ready mock client via the resolver for these cases.
|
|
236
|
+
const mockCesClient = {
|
|
237
|
+
isReady: () => true,
|
|
238
|
+
handshake: async () => ({ accepted: true }),
|
|
239
|
+
call: async () => ({ success: true }),
|
|
240
|
+
updateAssistantApiKey: async () => ({ updated: true }),
|
|
241
|
+
close: () => {},
|
|
242
|
+
} as unknown as CesClient;
|
|
243
|
+
beforeEach(() => setCesClient(mockCesClient));
|
|
244
|
+
afterEach(() => setCesClient(undefined));
|
|
245
|
+
|
|
234
246
|
test("rejects register without required bundle metadata", async () => {
|
|
235
247
|
const result = await manageSecureCommandTool.execute(
|
|
236
248
|
{
|
|
@@ -238,7 +250,7 @@ describe("manage_secure_command_tool input validation", () => {
|
|
|
238
250
|
toolName: "test-tool",
|
|
239
251
|
// Missing bundleId, version, sourceUrl, sha256, credentialHandle
|
|
240
252
|
},
|
|
241
|
-
|
|
253
|
+
minimalContext,
|
|
242
254
|
);
|
|
243
255
|
expect(result.isError).toBe(true);
|
|
244
256
|
expect(result.content).toContain("bundleId");
|
|
@@ -270,7 +282,7 @@ describe("manage_secure_command_tool input validation", () => {
|
|
|
270
282
|
egressMode: "no_network",
|
|
271
283
|
},
|
|
272
284
|
},
|
|
273
|
-
|
|
285
|
+
minimalContext,
|
|
274
286
|
);
|
|
275
287
|
expect(result.isError).toBe(true);
|
|
276
288
|
expect(result.content).toContain("HTTPS");
|
|
@@ -216,6 +216,7 @@ describe("Invariant 2: no generic plaintext secret read API", () => {
|
|
|
216
216
|
"media/image-credentials.ts", // shared image-gen credential resolver (provider API key lookup)
|
|
217
217
|
"memory/embedding-backend.ts", // embedding backend API key lookup
|
|
218
218
|
"memory/llm-request-log-source-clickhouse.ts", // ClickHouse read source — lazy lookup of clickhouse:url + clickhouse:password + vellum:platform_assistant_id for self-scoped mirror reads
|
|
219
|
+
"memory/compaction-log-writer-clickhouse.ts", // ClickHouse compaction log writer — lazy lookup of clickhouse:url + clickhouse:password + vellum:platform_assistant_id for self-scoped event writes
|
|
219
220
|
"daemon/providers-setup.ts", // provider initialization API key lookup
|
|
220
221
|
"workspace/migrations/006-services-config.ts", // services config migration reads provider API keys
|
|
221
222
|
"workspace/migrations/018-rekey-compound-credential-keys.ts", // re-key compound credential storage keys
|
|
@@ -230,7 +231,7 @@ describe("Invariant 2: no generic plaintext secret read API", () => {
|
|
|
230
231
|
"runtime/routes/platform-routes.ts", // CLI platform connect/disconnect/status routes (CLI-migrated to IPC)
|
|
231
232
|
"ipc/skill-routes/providers.ts", // host.providers.secureKeys.getProviderKey IPC route (out-of-process SkillHost companion)
|
|
232
233
|
"daemon/external-plugins-bootstrap.ts", // reads credentials at plugin init (manifest.requiresCredential) via the CES-mediated getSecureKeyAsync path
|
|
233
|
-
"
|
|
234
|
+
"plugin-api/index.ts", // public @vellumai/plugin-api surface re-exports getSecureKeyAsync to dynamically-imported workspace plugins via the boot-time shim (compiled-binary plugin loading)
|
|
234
235
|
"inbound/platform-callback-registration.ts", // managed credential lookup for platform base URL, assistant ID, and API key
|
|
235
236
|
"tts/providers/elevenlabs-provider.ts", // ElevenLabs TTS API key lookup
|
|
236
237
|
"tts/providers/deepgram-provider.ts", // Deepgram TTS API key lookup
|
|
@@ -242,6 +243,10 @@ describe("Invariant 2: no generic plaintext secret read API", () => {
|
|
|
242
243
|
"cli/commands/oauth/connect.ts", // CLI OAuth connect stored-secret verification
|
|
243
244
|
"runtime/routes/chatgpt-subscription-auth-routes.ts", // ChatGPT subscription OAuth token storage
|
|
244
245
|
"runtime/routes/identity-routes.ts", // health/readyz endpoint checks CES connectivity via getCesClient
|
|
246
|
+
"tools/credential-execution/run-authenticated-command.ts", // resolves the CES RPC client via getCesClient
|
|
247
|
+
"tools/credential-execution/make-authenticated-request.ts", // resolves the CES RPC client via getCesClient
|
|
248
|
+
"tools/credential-execution/manage-secure-command-tool.ts", // resolves the CES RPC client via getCesClient
|
|
249
|
+
"tools/executor.ts", // CES approval bridge resolves the CES RPC client via getCesClient
|
|
245
250
|
]);
|
|
246
251
|
|
|
247
252
|
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -4,6 +4,7 @@ import { describe, expect, test } from "bun:test";
|
|
|
4
4
|
import { eq } from "drizzle-orm";
|
|
5
5
|
import { drizzle } from "drizzle-orm/bun-sqlite";
|
|
6
6
|
|
|
7
|
+
import { migrateScheduleDescription } from "../memory/migrations/270-schedule-description.js";
|
|
7
8
|
import { migrateScheduleSourceConversation } from "../memory/migrations/270-schedule-source-conversation.js";
|
|
8
9
|
import * as schema from "../memory/schema.js";
|
|
9
10
|
import { scheduleJobs } from "../memory/schema.js";
|
|
@@ -50,6 +51,7 @@ describe("schedule_syntax column migration", () => {
|
|
|
50
51
|
script TEXT,
|
|
51
52
|
wake_conversation_id TEXT,
|
|
52
53
|
timeout_ms INTEGER,
|
|
54
|
+
description TEXT NOT NULL DEFAULT '',
|
|
53
55
|
created_at INTEGER NOT NULL,
|
|
54
56
|
updated_at INTEGER NOT NULL
|
|
55
57
|
)
|
|
@@ -137,6 +139,7 @@ describe("schedule_syntax column migration", () => {
|
|
|
137
139
|
/* already exists */
|
|
138
140
|
}
|
|
139
141
|
migrateScheduleSourceConversation(db);
|
|
142
|
+
migrateScheduleDescription(db);
|
|
140
143
|
|
|
141
144
|
const row = db
|
|
142
145
|
.select()
|
|
@@ -202,6 +205,8 @@ describe("schedule_syntax column migration", () => {
|
|
|
202
205
|
}
|
|
203
206
|
migrateScheduleSourceConversation(db);
|
|
204
207
|
migrateScheduleSourceConversation(db);
|
|
208
|
+
migrateScheduleDescription(db);
|
|
209
|
+
migrateScheduleDescription(db);
|
|
205
210
|
|
|
206
211
|
const now = Date.now();
|
|
207
212
|
raw.exec(
|
|
@@ -214,4 +219,79 @@ describe("schedule_syntax column migration", () => {
|
|
|
214
219
|
.get();
|
|
215
220
|
expect(row!.scheduleSyntax).toBe("cron");
|
|
216
221
|
});
|
|
222
|
+
|
|
223
|
+
test("schedule description migration backfills non-defer rows once", () => {
|
|
224
|
+
const db = createTestDb();
|
|
225
|
+
const raw = getRawSqlite(db);
|
|
226
|
+
|
|
227
|
+
raw.exec(/*sql*/ `
|
|
228
|
+
CREATE TABLE IF NOT EXISTS cron_jobs (
|
|
229
|
+
id TEXT PRIMARY KEY,
|
|
230
|
+
name TEXT NOT NULL,
|
|
231
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
232
|
+
cron_expression TEXT,
|
|
233
|
+
schedule_syntax TEXT NOT NULL DEFAULT 'cron',
|
|
234
|
+
timezone TEXT,
|
|
235
|
+
message TEXT NOT NULL,
|
|
236
|
+
next_run_at INTEGER NOT NULL,
|
|
237
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
238
|
+
created_by TEXT NOT NULL,
|
|
239
|
+
created_at INTEGER NOT NULL,
|
|
240
|
+
updated_at INTEGER NOT NULL
|
|
241
|
+
)
|
|
242
|
+
`);
|
|
243
|
+
|
|
244
|
+
const now = Date.now();
|
|
245
|
+
raw
|
|
246
|
+
.query(
|
|
247
|
+
`INSERT INTO cron_jobs (id, name, cron_expression, message, next_run_at, created_by, created_at, updated_at)
|
|
248
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
249
|
+
)
|
|
250
|
+
.run(
|
|
251
|
+
"legacy-schedule",
|
|
252
|
+
"Legacy report",
|
|
253
|
+
"0 9 * * *",
|
|
254
|
+
"compile report",
|
|
255
|
+
now + 60_000,
|
|
256
|
+
"agent",
|
|
257
|
+
now,
|
|
258
|
+
now,
|
|
259
|
+
);
|
|
260
|
+
raw
|
|
261
|
+
.query(
|
|
262
|
+
`INSERT INTO cron_jobs (id, name, cron_expression, message, next_run_at, created_by, created_at, updated_at)
|
|
263
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
264
|
+
)
|
|
265
|
+
.run(
|
|
266
|
+
"legacy-defer",
|
|
267
|
+
"Deferred wake",
|
|
268
|
+
null,
|
|
269
|
+
"resume later",
|
|
270
|
+
now + 60_000,
|
|
271
|
+
"defer",
|
|
272
|
+
now,
|
|
273
|
+
now,
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
migrateScheduleDescription(db);
|
|
277
|
+
|
|
278
|
+
const rows = raw
|
|
279
|
+
.query("SELECT id, description FROM cron_jobs ORDER BY id")
|
|
280
|
+
.all() as Array<{ id: string; description: string }>;
|
|
281
|
+
expect(rows).toEqual([
|
|
282
|
+
{ id: "legacy-defer", description: "" },
|
|
283
|
+
{ id: "legacy-schedule", description: "Legacy report" },
|
|
284
|
+
]);
|
|
285
|
+
|
|
286
|
+
raw
|
|
287
|
+
.query("UPDATE cron_jobs SET description = ? WHERE id = ?")
|
|
288
|
+
.run("", "legacy-schedule");
|
|
289
|
+
|
|
290
|
+
migrateScheduleDescription(db);
|
|
291
|
+
|
|
292
|
+
const description = raw
|
|
293
|
+
.query("SELECT description FROM cron_jobs WHERE id = ?")
|
|
294
|
+
.get("legacy-schedule") as { description: string };
|
|
295
|
+
expect(description.description).toBe("");
|
|
296
|
+
});
|
|
217
297
|
});
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
mkdirSync,
|
|
4
|
+
mkdtempSync,
|
|
5
|
+
readdirSync,
|
|
6
|
+
readFileSync,
|
|
7
|
+
rmSync,
|
|
8
|
+
writeFileSync,
|
|
9
|
+
} from "node:fs";
|
|
2
10
|
import { tmpdir } from "node:os";
|
|
3
11
|
import { join } from "node:path";
|
|
4
12
|
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
@@ -16,11 +24,13 @@ import { getDeviceId, resetDeviceIdCache } from "../util/device-id.js";
|
|
|
16
24
|
const originalVellumEnvironment = process.env.VELLUM_ENVIRONMENT;
|
|
17
25
|
const originalXdgConfigHome = process.env.XDG_CONFIG_HOME;
|
|
18
26
|
const originalIsContainerized = process.env.IS_CONTAINERIZED;
|
|
27
|
+
const originalVellumDeviceId = process.env.VELLUM_DEVICE_ID;
|
|
19
28
|
|
|
20
29
|
let tempDir: string;
|
|
21
30
|
|
|
22
31
|
beforeEach(() => {
|
|
23
32
|
tempDir = mkdtempSync(join(tmpdir(), "vellum-device-id-test-"));
|
|
33
|
+
delete process.env.VELLUM_DEVICE_ID;
|
|
24
34
|
resetDeviceIdCache();
|
|
25
35
|
});
|
|
26
36
|
|
|
@@ -42,6 +52,11 @@ afterEach(() => {
|
|
|
42
52
|
} else {
|
|
43
53
|
process.env.IS_CONTAINERIZED = originalIsContainerized;
|
|
44
54
|
}
|
|
55
|
+
if (originalVellumDeviceId == null) {
|
|
56
|
+
delete process.env.VELLUM_DEVICE_ID;
|
|
57
|
+
} else {
|
|
58
|
+
process.env.VELLUM_DEVICE_ID = originalVellumDeviceId;
|
|
59
|
+
}
|
|
45
60
|
|
|
46
61
|
try {
|
|
47
62
|
rmSync(tempDir, { recursive: true, force: true });
|
|
@@ -110,3 +125,57 @@ describe("getDeviceId env-awareness", () => {
|
|
|
110
125
|
expect(existsSync(xdgPath)).toBe(false);
|
|
111
126
|
});
|
|
112
127
|
});
|
|
128
|
+
|
|
129
|
+
describe("getDeviceId VELLUM_DEVICE_ID precedence", () => {
|
|
130
|
+
beforeEach(() => {
|
|
131
|
+
delete process.env.IS_CONTAINERIZED;
|
|
132
|
+
process.env.VELLUM_ENVIRONMENT = "dev";
|
|
133
|
+
process.env.XDG_CONFIG_HOME = tempDir;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("env var set returns that value without writing device.json", () => {
|
|
137
|
+
process.env.VELLUM_DEVICE_ID = "abc-123";
|
|
138
|
+
|
|
139
|
+
expect(getDeviceId()).toBe("abc-123");
|
|
140
|
+
// Nothing written anywhere under the XDG tempdir.
|
|
141
|
+
expect(readdirSync(tempDir)).toEqual([]);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("env var with surrounding whitespace returns the trimmed value", () => {
|
|
145
|
+
process.env.VELLUM_DEVICE_ID = " abc-123 ";
|
|
146
|
+
|
|
147
|
+
expect(getDeviceId()).toBe("abc-123");
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test("empty/whitespace-only env var falls through to file resolution", () => {
|
|
151
|
+
process.env.VELLUM_DEVICE_ID = " ";
|
|
152
|
+
|
|
153
|
+
const id = getDeviceId();
|
|
154
|
+
expect(id.length).toBeGreaterThan(0);
|
|
155
|
+
expect(existsSync(join(tempDir, "vellum-dev", "device.json"))).toBe(true);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test("env var wins over an existing device.json without overwriting it", () => {
|
|
159
|
+
const dir = join(tempDir, "vellum-dev");
|
|
160
|
+
mkdirSync(dir, { recursive: true });
|
|
161
|
+
const filePath = join(dir, "device.json");
|
|
162
|
+
writeFileSync(filePath, JSON.stringify({ deviceId: "file-id" }));
|
|
163
|
+
process.env.VELLUM_DEVICE_ID = "env-id";
|
|
164
|
+
|
|
165
|
+
expect(getDeviceId()).toBe("env-id");
|
|
166
|
+
expect(JSON.parse(readFileSync(filePath, "utf-8")).deviceId).toBe(
|
|
167
|
+
"file-id",
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test("env-resolved value stays cached until resetDeviceIdCache", () => {
|
|
172
|
+
process.env.VELLUM_DEVICE_ID = "env-id";
|
|
173
|
+
expect(getDeviceId()).toBe("env-id");
|
|
174
|
+
|
|
175
|
+
delete process.env.VELLUM_DEVICE_ID;
|
|
176
|
+
expect(getDeviceId()).toBe("env-id");
|
|
177
|
+
|
|
178
|
+
resetDeviceIdCache();
|
|
179
|
+
expect(getDeviceId()).not.toBe("env-id");
|
|
180
|
+
});
|
|
181
|
+
});
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* Tests for managed proxy Gemini embedding backend selection.
|
|
3
3
|
*
|
|
4
4
|
* Verifies that selectEmbeddingBackend correctly routes through the
|
|
5
|
-
* managed proxy when
|
|
6
|
-
* prerequisites are satisfied.
|
|
5
|
+
* managed proxy when managed proxy prerequisites are satisfied.
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
@@ -42,13 +41,9 @@ mock.module("../security/secure-keys.js", () => ({
|
|
|
42
41
|
},
|
|
43
42
|
}));
|
|
44
43
|
|
|
45
|
-
// Feature flag mock
|
|
46
|
-
const mockFeatureFlags: Record<string, boolean> = {};
|
|
47
|
-
|
|
44
|
+
// Feature flag mock — always returns true (flag is GA'ed)
|
|
48
45
|
mock.module("../config/assistant-feature-flags.js", () => ({
|
|
49
|
-
isAssistantFeatureFlagEnabled: (
|
|
50
|
-
return mockFeatureFlags[key] ?? false;
|
|
51
|
-
},
|
|
46
|
+
isAssistantFeatureFlagEnabled: () => true,
|
|
52
47
|
}));
|
|
53
48
|
|
|
54
49
|
import type { AssistantConfig } from "../config/types.js";
|
|
@@ -75,14 +70,6 @@ function disableManagedProxy() {
|
|
|
75
70
|
mockAssistantApiKey = null;
|
|
76
71
|
}
|
|
77
72
|
|
|
78
|
-
function enableFlag() {
|
|
79
|
-
mockFeatureFlags["managed-gemini-embeddings-enabled"] = true;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function disableFlag() {
|
|
83
|
-
mockFeatureFlags["managed-gemini-embeddings-enabled"] = false;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
73
|
function makeConfig(
|
|
87
74
|
overrides: {
|
|
88
75
|
provider?: string;
|
|
@@ -116,7 +103,6 @@ function makeConfig(
|
|
|
116
103
|
|
|
117
104
|
beforeEach(() => {
|
|
118
105
|
disableManagedProxy();
|
|
119
|
-
disableFlag();
|
|
120
106
|
mockProviderKeys = {};
|
|
121
107
|
clearEmbeddingBackendCache();
|
|
122
108
|
});
|
|
@@ -126,9 +112,8 @@ afterEach(() => {
|
|
|
126
112
|
});
|
|
127
113
|
|
|
128
114
|
describe("managed proxy Gemini embedding selection", () => {
|
|
129
|
-
test("selects managed proxy Gemini when
|
|
115
|
+
test("selects managed proxy Gemini when proxy context available", async () => {
|
|
130
116
|
enableManagedProxy();
|
|
131
|
-
enableFlag();
|
|
132
117
|
const config = makeConfig();
|
|
133
118
|
|
|
134
119
|
const { backend, reason } = await selectEmbeddingBackend(config);
|
|
@@ -141,7 +126,6 @@ describe("managed proxy Gemini embedding selection", () => {
|
|
|
141
126
|
|
|
142
127
|
test("managed proxy backend uses default 3072 dimensions when geminiDimensions not set", async () => {
|
|
143
128
|
enableManagedProxy();
|
|
144
|
-
enableFlag();
|
|
145
129
|
const config = makeConfig();
|
|
146
130
|
|
|
147
131
|
const { backend } = await selectEmbeddingBackend(config);
|
|
@@ -155,7 +139,6 @@ describe("managed proxy Gemini embedding selection", () => {
|
|
|
155
139
|
|
|
156
140
|
test("managed proxy backend uses explicit geminiDimensions when set", async () => {
|
|
157
141
|
enableManagedProxy();
|
|
158
|
-
enableFlag();
|
|
159
142
|
const config = makeConfig({ geminiDimensions: 768 });
|
|
160
143
|
|
|
161
144
|
const { backend } = await selectEmbeddingBackend(config);
|
|
@@ -168,7 +151,6 @@ describe("managed proxy Gemini embedding selection", () => {
|
|
|
168
151
|
|
|
169
152
|
test("managed proxy backend uses managedBaseUrl (not direct Google API)", async () => {
|
|
170
153
|
enableManagedProxy();
|
|
171
|
-
enableFlag();
|
|
172
154
|
const config = makeConfig();
|
|
173
155
|
|
|
174
156
|
const { backend } = await selectEmbeddingBackend(config);
|
|
@@ -179,32 +161,19 @@ describe("managed proxy Gemini embedding selection", () => {
|
|
|
179
161
|
expect(managedBaseUrl).toBe(`${PLATFORM_BASE}/v1/runtime-proxy/gemini`);
|
|
180
162
|
});
|
|
181
163
|
|
|
182
|
-
test("falls back to local when flag is disabled (no managed proxy)", async () => {
|
|
183
|
-
enableManagedProxy();
|
|
184
|
-
disableFlag();
|
|
185
|
-
const config = makeConfig();
|
|
186
|
-
|
|
187
|
-
const { backend } = await selectEmbeddingBackend(config);
|
|
188
|
-
|
|
189
|
-
// With auto and no provider keys, falls through to local
|
|
190
|
-
expect(backend).not.toBeNull();
|
|
191
|
-
expect(backend!.provider).toBe("local");
|
|
192
|
-
});
|
|
193
|
-
|
|
194
164
|
test("falls back to local when managed proxy context unavailable", async () => {
|
|
195
165
|
disableManagedProxy();
|
|
196
|
-
enableFlag();
|
|
197
166
|
const config = makeConfig();
|
|
198
167
|
|
|
199
168
|
const { backend } = await selectEmbeddingBackend(config);
|
|
200
169
|
|
|
170
|
+
// With auto and no provider keys or proxy, falls through to local
|
|
201
171
|
expect(backend).not.toBeNull();
|
|
202
172
|
expect(backend!.provider).toBe("local");
|
|
203
173
|
});
|
|
204
174
|
|
|
205
175
|
test("selects managed proxy when provider is explicitly gemini", async () => {
|
|
206
176
|
enableManagedProxy();
|
|
207
|
-
enableFlag();
|
|
208
177
|
const config = makeConfig({ provider: "gemini" });
|
|
209
178
|
|
|
210
179
|
const { backend } = await selectEmbeddingBackend(config);
|
|
@@ -217,7 +186,6 @@ describe("managed proxy Gemini embedding selection", () => {
|
|
|
217
186
|
|
|
218
187
|
test("does not use managed proxy when provider is explicitly local", async () => {
|
|
219
188
|
enableManagedProxy();
|
|
220
|
-
enableFlag();
|
|
221
189
|
const config = makeConfig({ provider: "local" });
|
|
222
190
|
|
|
223
191
|
const { backend } = await selectEmbeddingBackend(config);
|
|
@@ -228,7 +196,6 @@ describe("managed proxy Gemini embedding selection", () => {
|
|
|
228
196
|
|
|
229
197
|
test("does not use managed proxy when provider is explicitly openai", async () => {
|
|
230
198
|
enableManagedProxy();
|
|
231
|
-
enableFlag();
|
|
232
199
|
mockProviderKeys[credentialKey("openai", "api_key")] = "user-openai-key";
|
|
233
200
|
const config = makeConfig({ provider: "openai" });
|
|
234
201
|
|
|
@@ -238,9 +205,8 @@ describe("managed proxy Gemini embedding selection", () => {
|
|
|
238
205
|
expect(backend!.provider).toBe("openai");
|
|
239
206
|
});
|
|
240
207
|
|
|
241
|
-
test("direct Gemini key still works
|
|
208
|
+
test("direct Gemini key still works without managed proxy", async () => {
|
|
242
209
|
disableManagedProxy();
|
|
243
|
-
disableFlag();
|
|
244
210
|
mockProviderKeys[credentialKey("gemini", "api_key")] = "user-gemini-key";
|
|
245
211
|
const config = makeConfig({ provider: "gemini" });
|
|
246
212
|
|