@vellumai/assistant 0.8.3 → 0.8.5
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 +2 -2
- package/docker-entrypoint.sh +0 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/knip.json +2 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
- package/openapi.yaml +1492 -100
- package/package.json +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +88 -3
- package/src/__tests__/anthropic-provider.test.ts +302 -33
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
- package/src/__tests__/audit-log-rotation.test.ts +70 -16
- package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
- package/src/__tests__/btw-routes.test.ts +2 -3
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-delivery-store.test.ts +193 -0
- package/src/__tests__/channel-guardian.test.ts +3 -3
- package/src/__tests__/channel-reply-delivery.test.ts +284 -5
- package/src/__tests__/channel-retry-sweep.test.ts +274 -1
- package/src/__tests__/checker.test.ts +6 -15
- package/src/__tests__/compaction-events.test.ts +2 -1
- package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
- package/src/__tests__/computer-use-tools.test.ts +2 -4
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-token-estimator.test.ts +91 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
- package/src/__tests__/conversation-agent-loop.test.ts +188 -129
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +137 -0
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +31 -0
- package/src/__tests__/conversation-fork-crud.test.ts +324 -0
- package/src/__tests__/conversation-lifecycle.test.ts +53 -12
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
- package/src/__tests__/conversation-seed-composer.test.ts +66 -4
- package/src/__tests__/conversation-skill-tools.test.ts +2 -5
- package/src/__tests__/conversation-slash-commands.test.ts +36 -8
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
- package/src/__tests__/conversation-sync-tags.test.ts +99 -32
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
- 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-execution-feature-gates.test.ts +9 -7
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-security-invariants.test.ts +7 -0
- package/src/__tests__/credential-vault-unit.test.ts +2 -2
- package/src/__tests__/cu-unified-flow.test.ts +10 -1
- package/src/__tests__/dm-backfill.test.ts +64 -0
- package/src/__tests__/dm-persistence.test.ts +33 -0
- package/src/__tests__/document-find-replace.test.ts +501 -0
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/first-greeting.test.ts +23 -2
- package/src/__tests__/gateway-flag-listener.test.ts +237 -0
- package/src/__tests__/gemini-provider.test.ts +78 -0
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +7 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +172 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +4 -0
- package/src/__tests__/host-bash-proxy.test.ts +6 -0
- package/src/__tests__/host-browser-proxy.test.ts +10 -0
- package/src/__tests__/host-cu-proxy.test.ts +8 -1
- package/src/__tests__/host-file-proxy.test.ts +8 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/host-transfer-proxy.test.ts +8 -1
- package/src/__tests__/identity-routes.test.ts +57 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-chain.test.ts +2 -0
- package/src/__tests__/injector-document-comments.test.ts +378 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
- package/src/__tests__/list-messages-attachments.test.ts +21 -17
- package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
- package/src/__tests__/list-messages-page-latest.test.ts +130 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
- package/src/__tests__/llm-context-normalization.test.ts +0 -2
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +161 -9
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/log-export-routes.test.ts +99 -2
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/mcp-abort-signal.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/message-queue-steer.test.ts +114 -0
- package/src/__tests__/model-intents.test.ts +2 -4
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/onboarding-template-contract.test.ts +1 -1
- package/src/__tests__/openai-provider.test.ts +151 -0
- package/src/__tests__/openai-responses-provider.test.ts +118 -16
- package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
- package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -5
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +2 -2
- package/src/__tests__/plugin-source-watcher.test.ts +302 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +1 -51
- package/src/__tests__/process-message-display-content.test.ts +21 -16
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/registry.test.ts +2 -8
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/server-history-render.test.ts +83 -4
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
- package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
- package/src/__tests__/skill-tool-factory.test.ts +1 -1
- package/src/__tests__/steer-tool-repair.test.ts +249 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/suggestion-routes.test.ts +1 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +161 -124
- package/src/__tests__/terminal-tools.test.ts +12 -2
- package/src/__tests__/thinking-block-replay.test.ts +113 -0
- package/src/__tests__/thread-backfill.test.ts +370 -22
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
- package/src/__tests__/tool-executor.test.ts +89 -53
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
- package/src/__tests__/web-fetch.test.ts +2 -2
- package/src/__tests__/workspace-git-service.test.ts +94 -10
- package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +1 -1
- package/src/agent/attachments.ts +1 -0
- package/src/agent/loop.ts +65 -20
- package/src/api/README.md +5 -0
- package/src/api/index.ts +4 -0
- package/src/api/package.json +10 -0
- package/src/background-wake/background-wake-routes.test.ts +233 -0
- package/src/background-wake/next-wake.test.ts +289 -0
- package/src/background-wake/next-wake.ts +172 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/browser/operations.ts +15 -0
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/conversations.ts +128 -1
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference-providers.ts +147 -1
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +483 -0
- package/src/cli/commands/memory-v3-render.ts +344 -0
- package/src/cli/commands/memory-v3.ts +316 -0
- package/src/cli/commands/notifications.ts +24 -2
- package/src/cli/program.ts +2 -0
- package/src/cli/utils/conversation-id.ts +17 -5
- package/src/config/assistant-feature-flags.ts +21 -9
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
- package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
- package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +8 -0
- package/src/config/bundled-tool-registry.ts +24 -12
- package/src/config/call-site-defaults.ts +20 -0
- package/src/config/feature-flag-registry.json +115 -3
- package/src/config/llm-resolver.ts +16 -2
- package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
- package/src/config/schemas/call-site-catalog.ts +35 -0
- package/src/config/schemas/llm.ts +14 -0
- package/src/config/schemas/memory-v2.ts +294 -1
- package/src/config/schemas/memory.ts +2 -1
- package/src/context/compactor.ts +60 -1
- package/src/context/token-estimator.ts +47 -4
- package/src/context/window-manager.ts +25 -0
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-health/credential-health-service.ts +34 -19
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
- package/src/daemon/conversation-agent-loop.ts +307 -88
- package/src/daemon/conversation-error.ts +31 -1
- package/src/daemon/conversation-lifecycle.ts +149 -118
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +273 -0
- package/src/daemon/conversation-queue-manager.ts +14 -0
- package/src/daemon/conversation-runtime-assembly.ts +145 -84
- package/src/daemon/conversation-slash.ts +37 -5
- package/src/daemon/conversation-surfaces.ts +45 -2
- package/src/daemon/conversation-tool-setup.ts +70 -3
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +54 -32
- package/src/daemon/disk-pressure-guard.ts +14 -2
- package/src/daemon/first-greeting.ts +10 -0
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
- package/src/daemon/handlers/config-a2a.ts +160 -0
- package/src/daemon/handlers/config-model.test.ts +2 -0
- package/src/daemon/handlers/conversations.ts +90 -3
- package/src/daemon/handlers/shared.ts +92 -29
- package/src/daemon/host-bash-proxy.ts +1 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +5 -5
- package/src/daemon/host-file-proxy.ts +5 -5
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +11 -11
- package/src/daemon/lifecycle.ts +40 -23
- package/src/daemon/meet-manifest-loader.ts +1 -7
- package/src/daemon/message-protocol.ts +4 -0
- package/src/daemon/message-types/conversations.ts +14 -9
- package/src/daemon/message-types/document-comments.ts +50 -0
- package/src/daemon/message-types/home.ts +1 -13
- package/src/daemon/message-types/messages.ts +66 -7
- package/src/daemon/message-types/surfaces.ts +3 -1
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/message-types/web-activity.ts +57 -0
- package/src/daemon/plugin-source-watcher.ts +135 -3
- package/src/daemon/process-message.ts +69 -12
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +52 -0
- package/src/daemon/tool-setup-types.ts +13 -0
- package/src/daemon/trust-context.ts +6 -0
- package/src/documents/document-comments-store.test.ts +338 -0
- package/src/documents/document-comments-store.ts +237 -0
- package/src/documents/document-store.ts +202 -0
- package/src/events/relationship-state-updated.ts +25 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +33 -2
- package/src/home/feed-types.ts +6 -1
- package/src/home/home-content-refresh.ts +52 -0
- package/src/home/home-greeting-cache.ts +69 -0
- package/src/home/home-greeting.ts +85 -0
- package/src/home/suggested-prompts.ts +168 -9
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/registries.ts +8 -12
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-crud.ts +191 -100
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-init.ts +26 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/delivery-crud.ts +41 -0
- package/src/memory/delivery-status.ts +141 -15
- package/src/memory/external-conversation-store.ts +32 -1
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +68 -15
- package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
- package/src/memory/llm-request-log-source-local.ts +7 -0
- package/src/memory/llm-request-log-source.ts +9 -2
- package/src/memory/llm-request-log-store.ts +43 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-constants.ts +28 -0
- package/src/memory/memory-retrospective-enqueue.ts +11 -3
- package/src/memory/memory-retrospective-job.ts +413 -18
- package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
- package/src/memory/memory-v2-activation-log-store.ts +41 -14
- package/src/memory/migrations/100-core-tables.ts +1 -0
- package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
- package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
- package/src/memory/migrations/253-document-comments.ts +47 -0
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
- package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
- package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
- package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
- package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/index.ts +34 -0
- package/src/memory/migrations/registry.ts +58 -0
- package/src/memory/onboarding-events-store.ts +7 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/infrastructure.ts +22 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
- package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
- package/src/memory/v2/__tests__/injection.test.ts +158 -112
- package/src/memory/v2/__tests__/page-index.test.ts +365 -1
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +660 -4
- package/src/memory/v2/consolidation-job.ts +14 -0
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +124 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +224 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +106 -0
- package/src/memory/v2/harness/trace.ts +58 -0
- package/src/memory/v2/injection-events.ts +101 -0
- package/src/memory/v2/injection.ts +42 -25
- package/src/memory/v2/page-index.ts +209 -7
- package/src/memory/v2/page-store.ts +18 -0
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +369 -62
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +563 -0
- package/src/memory/v3/__tests__/filter.test.ts +512 -0
- package/src/memory/v3/__tests__/gate.test.ts +574 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
- package/src/memory/v3/__tests__/loop.test.ts +530 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +440 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +469 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
- package/src/memory/v3/__tests__/validate.test.ts +245 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +249 -0
- package/src/memory/v3/filter.ts +281 -0
- package/src/memory/v3/gate.ts +334 -0
- package/src/memory/v3/index-composition.ts +113 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +382 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +420 -0
- package/src/memory/v3/shadow-middleware.ts +305 -0
- package/src/memory/v3/traversal.ts +206 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +351 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +300 -0
- package/src/messaging/providers/index.ts +7 -1
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
- package/src/messaging/providers/slack/adapter.ts +178 -25
- package/src/messaging/providers/slack/api.test.ts +54 -0
- package/src/messaging/providers/slack/api.ts +119 -3
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/deep-link.ts +20 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
- package/src/messaging/providers/slack/message-metadata.ts +156 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
- package/src/messaging/providers/slack/render-transcript.ts +176 -49
- package/src/messaging/providers/slack/send.test.ts +77 -0
- package/src/messaging/providers/slack/send.ts +8 -2
- package/src/messaging/providers/slack/types.ts +14 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/conversation-seed-composer.ts +14 -2
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/deferred-emit.ts +135 -0
- package/src/notifications/emit-signal.ts +38 -50
- package/src/notifications/home-feed-side-effect.ts +60 -30
- package/src/oauth/connect-orchestrator.ts +3 -0
- package/src/oauth/credential-token-resolver.ts +2 -0
- package/src/oauth/manual-token-connection.ts +19 -0
- package/src/oauth/oauth-store.ts +12 -0
- package/src/oauth/seed-providers.ts +22 -0
- package/src/permissions/prompter.ts +8 -5
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +6 -3
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +100 -20
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +11 -16
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/prompts/__tests__/system-prompt.test.ts +46 -2
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/normalize-onboarding.ts +40 -0
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +69 -19
- package/src/prompts/system-prompt.ts +118 -216
- package/src/prompts/template-detection.ts +37 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
- package/src/prompts/templates/BOOTSTRAP.md +10 -2
- package/src/prompts/templates/VOICE.md +3 -0
- package/src/prompts/templates/system-sections.ts +281 -9
- package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +159 -66
- package/src/providers/call-site-routing.ts +14 -2
- package/src/providers/connection-model-compat.ts +38 -0
- package/src/providers/connection-resolution.ts +16 -2
- package/src/providers/fireworks/client.ts +20 -2
- package/src/providers/gemini/client.ts +49 -6
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
- package/src/providers/inference/adapter-factory.ts +18 -1
- package/src/providers/inference/auth.ts +3 -3
- package/src/providers/inference/codex-token-refresh.ts +128 -0
- package/src/providers/inference/resolve-auth.ts +49 -6
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +91 -1
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openai/chat-completions-provider.ts +63 -23
- package/src/providers/openai/codex-models.ts +18 -0
- package/src/providers/openai/responses-provider.ts +86 -23
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/provider-send-message.ts +7 -1
- package/src/providers/retry.ts +34 -3
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +25 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +214 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
- package/src/runtime/agent-wake.ts +152 -56
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +43 -3
- package/src/runtime/background-job-runner.ts +26 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-reply-delivery.ts +182 -47
- package/src/runtime/channel-retry-sweep.ts +141 -16
- package/src/runtime/http-types.ts +7 -6
- package/src/runtime/migrations/vbundle-builder.ts +10 -3
- package/src/runtime/pending-interactions.ts +50 -8
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/approval-routes.ts +4 -1
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +188 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +0 -6
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
- package/src/runtime/routes/content-source-routes.ts +78 -0
- package/src/runtime/routes/conversation-cli-routes.ts +147 -2
- package/src/runtime/routes/conversation-list-routes.ts +12 -4
- package/src/runtime/routes/conversation-management-routes.ts +77 -20
- package/src/runtime/routes/conversation-query-routes.ts +196 -31
- package/src/runtime/routes/conversation-routes.ts +472 -425
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/document-comments-routes.ts +287 -0
- package/src/runtime/routes/documents-routes.ts +33 -0
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +24 -8
- package/src/runtime/routes/home-feed-routes.ts +6 -3
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-browser-routes.ts +17 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-routes.ts +21 -0
- package/src/runtime/routes/inbound-message-handler.ts +288 -58
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
- package/src/runtime/routes/index.ts +20 -4
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
- package/src/runtime/routes/integrations/a2a.ts +60 -1
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/log-export-routes.ts +39 -0
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +427 -0
- package/src/runtime/routes/memory-v3-routes.ts +316 -0
- package/src/runtime/routes/migration-routes.ts +21 -24
- package/src/runtime/routes/notification-routes.ts +19 -2
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/question-routes.ts +4 -1
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/sanity-routes.ts +159 -0
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +188 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/conversation-serializer.ts +30 -4
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/integration-status.ts +3 -1
- package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
- package/src/security/oauth2-device-code.ts +307 -0
- package/src/security/oauth2.ts +26 -9
- package/src/security/secure-keys.ts +5 -0
- package/src/skills/catalog-install.ts +6 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +2 -8
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
- package/src/tools/browser/browser-execution.ts +106 -0
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
- package/src/tools/browser/cdp-client/factory.ts +171 -4
- package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
- package/src/tools/browser/cdp-client/types.ts +101 -0
- package/src/tools/browser/pinned-tabs.ts +146 -0
- package/src/tools/computer-use/definitions.ts +22 -78
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-comment-tool.test.ts +379 -0
- package/src/tools/document/document-comment-tool.ts +156 -0
- package/src/tools/document/document-tool.ts +187 -2
- package/src/tools/execution-target.ts +21 -23
- package/src/tools/executor.ts +6 -1
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -8
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
- package/src/tools/network/domain-normalize.ts +17 -0
- package/src/tools/network/web-fetch.ts +216 -73
- package/src/tools/network/web-search.ts +216 -98
- package/src/tools/registry.ts +7 -23
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +1 -8
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +19 -12
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/types.ts +31 -98
- package/src/tools/ui-surface/definitions.ts +9 -23
- package/src/types/onboarding-context.ts +4 -0
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/__tests__/favicon.test.ts +84 -0
- package/src/util/favicon.ts +40 -0
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -7
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/git-service.ts +75 -4
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/config/bundled-skills/document/SKILL.md +0 -54
- package/src/config/bundled-skills/document/TOOLS.json +0 -106
- package/src/daemon/seed-files.ts +0 -18
- package/src/prompts/cache-boundary.ts +0 -8
- package/src/runtime/routes/interface-routes.ts +0 -43
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route handlers for the assistant plugins surface.
|
|
3
|
+
*
|
|
4
|
+
* GET /v1/plugins — list installed plugins under `<workspaceDir>/plugins/`.
|
|
5
|
+
* GET /v1/plugins/search — search the canonical GitHub catalog of installable plugins.
|
|
6
|
+
* DELETE /v1/plugins/:name — uninstall a plugin from `<workspaceDir>/plugins/<name>/`.
|
|
7
|
+
*
|
|
8
|
+
* The read-only routes are projections over the same library functions
|
|
9
|
+
* the CLI uses (`assistant plugins list`, `assistant plugins search`).
|
|
10
|
+
* The DELETE route is symmetric to `assistant plugins uninstall` and
|
|
11
|
+
* delegates to the same `uninstallPlugin` lib function. CLI / daemon /
|
|
12
|
+
* web stay aligned on what an installed or available plugin looks like.
|
|
13
|
+
*
|
|
14
|
+
* Install is intentionally not exposed here. The CLI remains the
|
|
15
|
+
* install surface because installation fetches from GitHub, applies
|
|
16
|
+
* sanitization, and writes to disk — a heavier flow than a single
|
|
17
|
+
* JSON request justifies right now.
|
|
18
|
+
*
|
|
19
|
+
* # Policy gating
|
|
20
|
+
*
|
|
21
|
+
* Every route declares `policyKey: "plugins"` + `requirePolicyEnforcement:
|
|
22
|
+
* true`. The HTTP router enforces via `enforcePolicy()` against the
|
|
23
|
+
* `plugins:GET` / `plugins/search:GET` / `plugins:DELETE` registry
|
|
24
|
+
* entries in `runtime/auth/route-policy.ts`. The IPC adapter exposes
|
|
25
|
+
* the same policies to the gateway IPC proxy, whose own policy table
|
|
26
|
+
* (`gateway/src/auth/ipc-route-policy.ts`) holds the matching entries
|
|
27
|
+
* for `plugins_list` / `plugins_search` / `plugins_uninstall`. Reads
|
|
28
|
+
* require `settings.read`; uninstall requires `settings.write`.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import { z } from "zod";
|
|
32
|
+
|
|
33
|
+
import { InvalidPluginNameError } from "../../cli/lib/install-from-github.js";
|
|
34
|
+
import {
|
|
35
|
+
type InstalledPluginInfo,
|
|
36
|
+
listInstalledPlugins,
|
|
37
|
+
} from "../../cli/lib/list-installed-plugins.js";
|
|
38
|
+
import {
|
|
39
|
+
InvalidSearchPatternError,
|
|
40
|
+
type PluginSearchMatch,
|
|
41
|
+
searchPlugins,
|
|
42
|
+
} from "../../cli/lib/search-plugins.js";
|
|
43
|
+
import {
|
|
44
|
+
PluginNotInstalledError,
|
|
45
|
+
uninstallPlugin,
|
|
46
|
+
} from "../../cli/lib/uninstall-plugin.js";
|
|
47
|
+
import {
|
|
48
|
+
BadRequestError,
|
|
49
|
+
InternalError,
|
|
50
|
+
NotFoundError,
|
|
51
|
+
} from "./errors.js";
|
|
52
|
+
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
53
|
+
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Schema
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
const pluginInfoSchema = z.object({
|
|
59
|
+
id: z
|
|
60
|
+
.string()
|
|
61
|
+
.describe(
|
|
62
|
+
"Plugin's directory name (kebab-case). Matches `assistant plugins install <id>`.",
|
|
63
|
+
),
|
|
64
|
+
name: z.string().describe("Display name. Equal to `id` today."),
|
|
65
|
+
description: z
|
|
66
|
+
.string()
|
|
67
|
+
.nullable()
|
|
68
|
+
.describe("From `package.json#description`; `null` when unknown."),
|
|
69
|
+
version: z
|
|
70
|
+
.string()
|
|
71
|
+
.nullable()
|
|
72
|
+
.describe("From `package.json#version`; `null` when unknown."),
|
|
73
|
+
path: z
|
|
74
|
+
.string()
|
|
75
|
+
.optional()
|
|
76
|
+
.describe("Absolute path to the plugin directory on the assistant host."),
|
|
77
|
+
issues: z
|
|
78
|
+
.array(z.string())
|
|
79
|
+
.optional()
|
|
80
|
+
.describe(
|
|
81
|
+
"Non-fatal issues with this entry (missing `package.json`, malformed JSON, ...). Omitted when clean.",
|
|
82
|
+
),
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const pluginsListResponseSchema = z.object({
|
|
86
|
+
plugins: z.array(pluginInfoSchema),
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const pluginSearchMatchSchema = z.object({
|
|
90
|
+
name: z
|
|
91
|
+
.string()
|
|
92
|
+
.describe(
|
|
93
|
+
"Directory name under `experimental/plugins/`. Matches `assistant plugins install <name>`.",
|
|
94
|
+
),
|
|
95
|
+
path: z
|
|
96
|
+
.string()
|
|
97
|
+
.describe(
|
|
98
|
+
"Repo-relative path of the match (e.g. `experimental/plugins/<name>`).",
|
|
99
|
+
),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const pluginsSearchResponseSchema = z.object({
|
|
103
|
+
query: z
|
|
104
|
+
.string()
|
|
105
|
+
.describe("Echo of the requested query (ECMAScript regex source)."),
|
|
106
|
+
ref: z.string().describe("Git ref the catalog was listed at."),
|
|
107
|
+
matches: z
|
|
108
|
+
.array(pluginSearchMatchSchema)
|
|
109
|
+
.describe("Directory matches, sorted alphabetically by name."),
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const pluginUninstallResponseSchema = z.object({
|
|
113
|
+
name: z
|
|
114
|
+
.string()
|
|
115
|
+
.describe(
|
|
116
|
+
"Directory name that was removed. Echoes the request's `:name` path parameter after sanitization.",
|
|
117
|
+
),
|
|
118
|
+
target: z
|
|
119
|
+
.string()
|
|
120
|
+
.describe(
|
|
121
|
+
"Absolute path that was removed on the assistant host. Useful for audit logs and confirmation toasts.",
|
|
122
|
+
),
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// Helpers
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
interface PluginView {
|
|
130
|
+
id: string;
|
|
131
|
+
name: string;
|
|
132
|
+
description: string | null;
|
|
133
|
+
version: string | null;
|
|
134
|
+
path: string;
|
|
135
|
+
issues?: string[];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function projectPlugin(entry: InstalledPluginInfo): PluginView {
|
|
139
|
+
// `id` and `name` both track the directory name. `package.json#name` can
|
|
140
|
+
// be scoped (e.g. `@vendor/plugin-name`) which is fine for npm but not
|
|
141
|
+
// what the CLI uses to install — so we don't surface it as `name`.
|
|
142
|
+
const view: PluginView = {
|
|
143
|
+
id: entry.name,
|
|
144
|
+
name: entry.name,
|
|
145
|
+
description: entry.packageJson?.description ?? null,
|
|
146
|
+
version: entry.packageJson?.version ?? null,
|
|
147
|
+
path: entry.target,
|
|
148
|
+
};
|
|
149
|
+
if (entry.issues.length > 0) {
|
|
150
|
+
view.issues = [...entry.issues];
|
|
151
|
+
}
|
|
152
|
+
return view;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function matchesQuery(plugin: PluginView, needle: string): boolean {
|
|
156
|
+
const q = needle.toLowerCase();
|
|
157
|
+
if (plugin.id.toLowerCase().includes(q)) return true;
|
|
158
|
+
if (plugin.name.toLowerCase().includes(q)) return true;
|
|
159
|
+
if (plugin.description && plugin.description.toLowerCase().includes(q)) {
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// Handler — list installed
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
|
|
169
|
+
function handleListPlugins({
|
|
170
|
+
queryParams = {},
|
|
171
|
+
}: RouteHandlerArgs): { plugins: PluginView[] } {
|
|
172
|
+
const q = queryParams.q?.trim();
|
|
173
|
+
const installed = listInstalledPlugins();
|
|
174
|
+
const projected = installed.map(projectPlugin);
|
|
175
|
+
const filtered = q ? projected.filter((p) => matchesQuery(p, q)) : projected;
|
|
176
|
+
return { plugins: filtered };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// Handler — search catalog
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
|
|
183
|
+
interface PluginsSearchResponse {
|
|
184
|
+
query: string;
|
|
185
|
+
ref: string;
|
|
186
|
+
matches: PluginSearchMatch[];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function handleSearchPlugins({
|
|
190
|
+
queryParams = {},
|
|
191
|
+
}: RouteHandlerArgs): Promise<PluginsSearchResponse> {
|
|
192
|
+
// Empty string is a legitimate "match everything" query per the lib's
|
|
193
|
+
// contract — accept it without forcing the caller to pick a sentinel.
|
|
194
|
+
const query = queryParams.q ?? "";
|
|
195
|
+
const ref = queryParams.ref?.trim() || undefined;
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
const result = await searchPlugins(
|
|
199
|
+
{ query, ref },
|
|
200
|
+
{ fetch: globalThis.fetch.bind(globalThis) },
|
|
201
|
+
);
|
|
202
|
+
// Re-pack `readonly` lib types into mutable copies so the route
|
|
203
|
+
// serializer's `Record<string, unknown>` contract holds. The wire
|
|
204
|
+
// shape is identical.
|
|
205
|
+
return {
|
|
206
|
+
query: result.query,
|
|
207
|
+
ref: result.ref,
|
|
208
|
+
matches: result.matches.map((m) => ({ name: m.name, path: m.path })),
|
|
209
|
+
};
|
|
210
|
+
} catch (err) {
|
|
211
|
+
if (err instanceof InvalidSearchPatternError) {
|
|
212
|
+
throw new BadRequestError(err.message);
|
|
213
|
+
}
|
|
214
|
+
throw new InternalError(
|
|
215
|
+
err instanceof Error ? err.message : "plugin catalog search failed",
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
// Handler — uninstall
|
|
222
|
+
// ---------------------------------------------------------------------------
|
|
223
|
+
|
|
224
|
+
interface PluginUninstallResponse {
|
|
225
|
+
name: string;
|
|
226
|
+
target: string;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function handleUninstallPlugin({
|
|
230
|
+
pathParams = {},
|
|
231
|
+
}: RouteHandlerArgs): PluginUninstallResponse {
|
|
232
|
+
// The HTTP router has already URL-decoded `:name` for us; pass it
|
|
233
|
+
// through verbatim — `uninstallPlugin` runs the same
|
|
234
|
+
// `sanitizePluginName` check the CLI uses, so attacker-supplied
|
|
235
|
+
// `../escape` style names get rejected before `rmSync` is reached.
|
|
236
|
+
const rawName = pathParams.name ?? "";
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
const result = uninstallPlugin({ name: rawName });
|
|
240
|
+
return { name: result.name, target: result.target };
|
|
241
|
+
} catch (err) {
|
|
242
|
+
if (err instanceof InvalidPluginNameError) {
|
|
243
|
+
throw new BadRequestError(err.message);
|
|
244
|
+
}
|
|
245
|
+
if (err instanceof PluginNotInstalledError) {
|
|
246
|
+
throw new NotFoundError(err.message);
|
|
247
|
+
}
|
|
248
|
+
throw new InternalError(
|
|
249
|
+
err instanceof Error ? err.message : "plugin uninstall failed",
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// Route definitions
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
|
|
258
|
+
export const ROUTES: RouteDefinition[] = [
|
|
259
|
+
{
|
|
260
|
+
operationId: "plugins_list",
|
|
261
|
+
endpoint: "plugins",
|
|
262
|
+
method: "GET",
|
|
263
|
+
policyKey: "plugins",
|
|
264
|
+
requirePolicyEnforcement: true,
|
|
265
|
+
summary: "List installed plugins",
|
|
266
|
+
description:
|
|
267
|
+
"Return one entry per directory under `<workspaceDir>/plugins/`, sorted alphabetically. Matches the CLI's `assistant plugins list`. Supports `?q=<text>` for case-insensitive substring matching across plugin id, name, and description.",
|
|
268
|
+
tags: ["plugins"],
|
|
269
|
+
queryParams: [
|
|
270
|
+
{
|
|
271
|
+
name: "q",
|
|
272
|
+
schema: { type: "string" },
|
|
273
|
+
description:
|
|
274
|
+
"Optional substring filter applied to plugin id, name, and description.",
|
|
275
|
+
},
|
|
276
|
+
],
|
|
277
|
+
responseBody: pluginsListResponseSchema,
|
|
278
|
+
handler: handleListPlugins,
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
operationId: "plugins_search",
|
|
282
|
+
endpoint: "plugins/search",
|
|
283
|
+
method: "GET",
|
|
284
|
+
policyKey: "plugins",
|
|
285
|
+
requirePolicyEnforcement: true,
|
|
286
|
+
summary: "Search the plugin catalog",
|
|
287
|
+
description:
|
|
288
|
+
"List installable plugins from the canonical `vellum-ai/vellum-assistant` catalog at `experimental/plugins/`. The query is an ECMAScript regex matched case-insensitively against the directory name (e.g. `memory`, `^simple`). Empty query returns every entry. Mirrors the CLI's `assistant plugins search`.",
|
|
289
|
+
tags: ["plugins"],
|
|
290
|
+
queryParams: [
|
|
291
|
+
{
|
|
292
|
+
name: "q",
|
|
293
|
+
schema: { type: "string" },
|
|
294
|
+
description:
|
|
295
|
+
"ECMAScript regex pattern matched case-insensitively against catalog directory names. Empty/missing matches everything.",
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: "ref",
|
|
299
|
+
schema: { type: "string" },
|
|
300
|
+
description:
|
|
301
|
+
"Optional git ref to list the catalog at. Defaults to the CLI's `DEFAULT_PLUGIN_REF` (typically `main`).",
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
responseBody: pluginsSearchResponseSchema,
|
|
305
|
+
handler: handleSearchPlugins,
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
operationId: "plugins_uninstall",
|
|
309
|
+
endpoint: "plugins/:name",
|
|
310
|
+
method: "DELETE",
|
|
311
|
+
policyKey: "plugins",
|
|
312
|
+
requirePolicyEnforcement: true,
|
|
313
|
+
summary: "Uninstall a plugin",
|
|
314
|
+
description:
|
|
315
|
+
"Remove the directory at `<workspaceDir>/plugins/<name>/`. Mirrors the CLI's `assistant plugins uninstall <name>` (without the interactive confirmation — the API caller is responsible for any prompt). The plugin name is sanitized by the same regex the CLI uses; `../escape`-style values, hidden names, and absolute paths return 400. Missing plugins return 404. The assistant must be restarted to drop the plugin from the running runtime.",
|
|
316
|
+
tags: ["plugins"],
|
|
317
|
+
pathParams: [
|
|
318
|
+
{
|
|
319
|
+
name: "name",
|
|
320
|
+
type: "string",
|
|
321
|
+
description:
|
|
322
|
+
"Directory name under `<workspaceDir>/plugins/`. Must match the kebab-case name accepted by `assistant plugins install`.",
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
responseBody: pluginUninstallResponseSchema,
|
|
326
|
+
additionalResponses: {
|
|
327
|
+
"400": {
|
|
328
|
+
description:
|
|
329
|
+
"The plugin name failed sanitization (e.g. contained slashes, dots, or uppercase letters).",
|
|
330
|
+
},
|
|
331
|
+
"404": {
|
|
332
|
+
description: "No plugin directory exists with the given name.",
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
handler: handleUninstallPlugin,
|
|
336
|
+
},
|
|
337
|
+
];
|
|
@@ -148,7 +148,10 @@ function handleQuestionResponse({ body }: RouteHandlerArgs) {
|
|
|
148
148
|
|
|
149
149
|
// Validation passed — deregister now to clear the prompter timer, then
|
|
150
150
|
// hand the result to the prompter's caller via rpcResolve.
|
|
151
|
-
pendingInteractions.resolve(
|
|
151
|
+
pendingInteractions.resolve(
|
|
152
|
+
requestId,
|
|
153
|
+
response.kind === "close" ? "cancelled" : "answered",
|
|
154
|
+
);
|
|
152
155
|
|
|
153
156
|
log.info(
|
|
154
157
|
{
|
|
@@ -31,7 +31,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
31
31
|
description: "Update the display title of a conversation.",
|
|
32
32
|
tags: ["conversations"],
|
|
33
33
|
requestBody: RenameConversationBody,
|
|
34
|
-
handler: ({ body }) => {
|
|
34
|
+
handler: ({ body, headers }) => {
|
|
35
35
|
const parsed = RenameConversationBody.safeParse(body);
|
|
36
36
|
if (!parsed.success) {
|
|
37
37
|
throw new BadRequestError("conversationId and title are required");
|
|
@@ -46,7 +46,11 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
46
46
|
|
|
47
47
|
updateConversationTitle(conversationId, title, 0);
|
|
48
48
|
|
|
49
|
-
publishConversationTitleChanged(
|
|
49
|
+
publishConversationTitleChanged(
|
|
50
|
+
conversationId,
|
|
51
|
+
title,
|
|
52
|
+
headers?.["x-vellum-client-id"]?.trim() || undefined,
|
|
53
|
+
);
|
|
50
54
|
|
|
51
55
|
return { ok: true };
|
|
52
56
|
},
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route definitions for Sanity CMS connection management.
|
|
3
|
+
*
|
|
4
|
+
* POST /v1/sanity/discover — project/dataset discovery using the stored API token
|
|
5
|
+
* POST /v1/sanity/connect — finalise connection by writing the sidecar file
|
|
6
|
+
*
|
|
7
|
+
* Both routes use policyKey: "secrets" — they read credentials and write
|
|
8
|
+
* workspace data, the same policy tier as the existing secrets routes.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { dirname, join } from "node:path";
|
|
13
|
+
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
|
|
16
|
+
import { credentialKey } from "../../security/credential-key.js";
|
|
17
|
+
import { getSecureKeyAsync } from "../../security/secure-keys.js";
|
|
18
|
+
import { getWorkspaceDir } from "../../util/platform.js";
|
|
19
|
+
import { BadRequestError } from "./errors.js";
|
|
20
|
+
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
21
|
+
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Helpers
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
async function getStoredToken(): Promise<string | undefined> {
|
|
27
|
+
return getSecureKeyAsync(credentialKey("sanity", "api_token"));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function writeSidecar(relPath: string, data: Record<string, unknown>): void {
|
|
31
|
+
const workspaceDir = getWorkspaceDir();
|
|
32
|
+
const absPath = join(workspaceDir, relPath);
|
|
33
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
34
|
+
writeFileSync(absPath, JSON.stringify(data, null, 2), "utf-8");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// POST /v1/sanity/discover
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
async function handleDiscover(
|
|
42
|
+
args: RouteHandlerArgs,
|
|
43
|
+
): Promise<Record<string, unknown>> {
|
|
44
|
+
const token = await getStoredToken();
|
|
45
|
+
if (!token) {
|
|
46
|
+
return { error: "no_token" };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const projectId =
|
|
50
|
+
typeof args.body?.projectId === "string" ? args.body.projectId : undefined;
|
|
51
|
+
|
|
52
|
+
if (!projectId) {
|
|
53
|
+
// List all projects this token has access to
|
|
54
|
+
const response = await fetch("https://api.sanity.io/v2021-06-07/projects", {
|
|
55
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (response.status === 401 || response.status === 403) {
|
|
59
|
+
return { error: "token_scope_limited" };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
return { error: "discovery_failed" };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const raw = (await response.json()) as Array<{
|
|
67
|
+
id: string;
|
|
68
|
+
displayName?: string;
|
|
69
|
+
}>;
|
|
70
|
+
const projects = raw.map((p) => ({
|
|
71
|
+
id: p.id,
|
|
72
|
+
displayName: p.displayName ?? p.id,
|
|
73
|
+
}));
|
|
74
|
+
return { projects };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// List datasets for a specific project
|
|
78
|
+
const response = await fetch(
|
|
79
|
+
`https://api.sanity.io/v2021-06-07/projects/${projectId}/datasets`,
|
|
80
|
+
{
|
|
81
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
82
|
+
},
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
if (response.status === 401 || response.status === 403) {
|
|
86
|
+
return { error: "token_scope_limited" };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!response.ok) {
|
|
90
|
+
return { error: "discovery_failed" };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const raw = (await response.json()) as Array<{ name: string }>;
|
|
94
|
+
const datasets = raw.map((d) => d.name);
|
|
95
|
+
return { projectId, datasets };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// POST /v1/sanity/connect
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
async function handleConnect(
|
|
103
|
+
args: RouteHandlerArgs,
|
|
104
|
+
): Promise<Record<string, unknown>> {
|
|
105
|
+
const token = await getStoredToken();
|
|
106
|
+
if (!token) {
|
|
107
|
+
throw new BadRequestError(
|
|
108
|
+
"Sanity API token not found. Store it first via POST /v1/secrets.",
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const projectId =
|
|
113
|
+
typeof args.body?.projectId === "string" ? args.body.projectId.trim() : "";
|
|
114
|
+
const dataset =
|
|
115
|
+
typeof args.body?.dataset === "string" ? args.body.dataset.trim() : "";
|
|
116
|
+
|
|
117
|
+
if (!projectId) {
|
|
118
|
+
throw new BadRequestError(
|
|
119
|
+
"projectId is required and must be a non-empty string",
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
if (!dataset) {
|
|
123
|
+
throw new BadRequestError(
|
|
124
|
+
"dataset is required and must be a non-empty string",
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
writeSidecar("data/sanity-connection.json", { projectId, dataset });
|
|
129
|
+
|
|
130
|
+
return { ok: true };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Route definitions
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
|
|
137
|
+
export const ROUTES: RouteDefinition[] = [
|
|
138
|
+
{
|
|
139
|
+
operationId: "sanity_discover",
|
|
140
|
+
endpoint: "sanity/discover",
|
|
141
|
+
method: "POST",
|
|
142
|
+
policyKey: "secrets",
|
|
143
|
+
summary: "Discover Sanity projects and datasets using the stored API token",
|
|
144
|
+
requestBody: z.object({ projectId: z.string().optional() }).optional(),
|
|
145
|
+
handler: handleDiscover,
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
operationId: "sanity_connect",
|
|
149
|
+
endpoint: "sanity/connect",
|
|
150
|
+
method: "POST",
|
|
151
|
+
policyKey: "secrets",
|
|
152
|
+
summary: "Finalise Sanity connection and write sidecar file",
|
|
153
|
+
requestBody: z.object({
|
|
154
|
+
projectId: z.string(),
|
|
155
|
+
dataset: z.string(),
|
|
156
|
+
}),
|
|
157
|
+
handler: handleConnect,
|
|
158
|
+
},
|
|
159
|
+
];
|
|
@@ -27,6 +27,7 @@ import { clearEmbeddingBackendCache } from "../../memory/embedding-backend.js";
|
|
|
27
27
|
import { syncManualTokenConnection } from "../../oauth/manual-token-connection.js";
|
|
28
28
|
import { validateAnthropicApiKey } from "../../providers/anthropic/client.js";
|
|
29
29
|
import { validateGeminiApiKey } from "../../providers/gemini/client.js";
|
|
30
|
+
import { validateMinimaxApiKey } from "../../providers/minimax/client.js";
|
|
30
31
|
import { validateOpenAIApiKey } from "../../providers/openai/client.js";
|
|
31
32
|
import { initializeProviders } from "../../providers/registry.js";
|
|
32
33
|
import { credentialKey } from "../../security/credential-key.js";
|
|
@@ -195,9 +196,21 @@ async function handleAddSecret({ body }: RouteHandlerArgs) {
|
|
|
195
196
|
);
|
|
196
197
|
return { success: false, error: validation.reason };
|
|
197
198
|
}
|
|
199
|
+
} else if (name === "minimax") {
|
|
200
|
+
const validation = await validateMinimaxApiKey(value);
|
|
201
|
+
if (!validation.valid) {
|
|
202
|
+
log.warn(
|
|
203
|
+
{ provider: name, reason: validation.reason },
|
|
204
|
+
"API key validation failed",
|
|
205
|
+
);
|
|
206
|
+
return { success: false, error: validation.reason };
|
|
207
|
+
}
|
|
198
208
|
}
|
|
199
209
|
|
|
200
|
-
const stored = await setSecureKeyAsync(
|
|
210
|
+
const stored = await setSecureKeyAsync(
|
|
211
|
+
credentialKey(name, "api_key"),
|
|
212
|
+
value,
|
|
213
|
+
);
|
|
201
214
|
if (!stored) {
|
|
202
215
|
throw new InternalError(
|
|
203
216
|
`Failed to store API key in secure storage (backend: ${getActiveBackendName()})`,
|
|
@@ -339,7 +352,9 @@ async function handleReadSecret({ body }: RouteHandlerArgs) {
|
|
|
339
352
|
|
|
340
353
|
try {
|
|
341
354
|
let accountKey: string;
|
|
342
|
-
let prefetchedResult:
|
|
355
|
+
let prefetchedResult:
|
|
356
|
+
| Awaited<ReturnType<typeof getSecureKeyResultAsync>>
|
|
357
|
+
| undefined;
|
|
343
358
|
|
|
344
359
|
if (type === "api_key") {
|
|
345
360
|
if (
|
|
@@ -350,7 +365,9 @@ async function handleReadSecret({ body }: RouteHandlerArgs) {
|
|
|
350
365
|
);
|
|
351
366
|
}
|
|
352
367
|
// Check credential namespace first; fall back to bare key only if not found and store is reachable.
|
|
353
|
-
const credResult = await getSecureKeyResultAsync(
|
|
368
|
+
const credResult = await getSecureKeyResultAsync(
|
|
369
|
+
credentialKey(name, "api_key"),
|
|
370
|
+
);
|
|
354
371
|
if (credResult.value === undefined && !credResult.unreachable) {
|
|
355
372
|
accountKey = name;
|
|
356
373
|
} else {
|
|
@@ -373,7 +390,8 @@ async function handleReadSecret({ body }: RouteHandlerArgs) {
|
|
|
373
390
|
);
|
|
374
391
|
}
|
|
375
392
|
|
|
376
|
-
const { value, unreachable } =
|
|
393
|
+
const { value, unreachable } =
|
|
394
|
+
prefetchedResult ?? (await getSecureKeyResultAsync(accountKey));
|
|
377
395
|
if (value === undefined) {
|
|
378
396
|
return { found: false, unreachable };
|
|
379
397
|
}
|
|
@@ -543,7 +561,9 @@ async function handleListSecrets() {
|
|
|
543
561
|
const field = rest.slice(slashIdx + 1);
|
|
544
562
|
if (
|
|
545
563
|
field === "api_key" &&
|
|
546
|
-
API_KEY_PROVIDERS.includes(
|
|
564
|
+
API_KEY_PROVIDERS.includes(
|
|
565
|
+
service as (typeof API_KEY_PROVIDERS)[number],
|
|
566
|
+
)
|
|
547
567
|
) {
|
|
548
568
|
return [service];
|
|
549
569
|
}
|
|
@@ -78,7 +78,10 @@ function handleVoiceConfigUpdate({ body = {} }: RouteHandlerArgs) {
|
|
|
78
78
|
// Avatar generation
|
|
79
79
|
// ---------------------------------------------------------------------------
|
|
80
80
|
|
|
81
|
-
async function handleGenerateAvatar({
|
|
81
|
+
async function handleGenerateAvatar({
|
|
82
|
+
body = {},
|
|
83
|
+
headers,
|
|
84
|
+
}: RouteHandlerArgs) {
|
|
82
85
|
const { description } = body as { description?: string };
|
|
83
86
|
if (!description?.trim()) {
|
|
84
87
|
throw new BadRequestError("Description is required.");
|
|
@@ -95,7 +98,7 @@ async function handleGenerateAvatar({ body = {} }: RouteHandlerArgs) {
|
|
|
95
98
|
|
|
96
99
|
const avatarPath = getAvatarImagePath();
|
|
97
100
|
|
|
98
|
-
publishAvatarChanged();
|
|
101
|
+
publishAvatarChanged(headers?.["x-vellum-client-id"]?.trim() || undefined);
|
|
99
102
|
|
|
100
103
|
return { ok: true, avatarPath };
|
|
101
104
|
} catch (err) {
|
|
@@ -381,14 +384,7 @@ function handleToolNamesList() {
|
|
|
381
384
|
};
|
|
382
385
|
const schemas: Record<string, SchemaShape> = {};
|
|
383
386
|
|
|
384
|
-
const rawDefs: ToolDefinition[] =
|
|
385
|
-
for (const tool of tools) {
|
|
386
|
-
try {
|
|
387
|
-
rawDefs.push(tool.getDefinition());
|
|
388
|
-
} catch {
|
|
389
|
-
// Skip tools whose definitions can't be resolved
|
|
390
|
-
}
|
|
391
|
-
}
|
|
387
|
+
const rawDefs: ToolDefinition[] = tools;
|
|
392
388
|
|
|
393
389
|
const transformedDefs = injectActivityField(rawDefs, ACTIVITY_SKIP_SET);
|
|
394
390
|
for (const def of transformedDefs) {
|
|
@@ -444,7 +440,12 @@ async function handleToolPermissionSimulate({ body = {} }: RouteHandlerArgs) {
|
|
|
444
440
|
|
|
445
441
|
try {
|
|
446
442
|
const manifestOverride = resolveManifestOverride(toolName);
|
|
447
|
-
|
|
443
|
+
// Permission Simulator path: registered tool wins, then explicit
|
|
444
|
+
// manifest override, then the standard inference rules.
|
|
445
|
+
const executionTarget =
|
|
446
|
+
getTool(toolName)?.executionTarget ??
|
|
447
|
+
manifestOverride?.execution_target ??
|
|
448
|
+
resolveExecutionTarget({ name: toolName });
|
|
448
449
|
const executionContext =
|
|
449
450
|
isInteractive === false ? "headless" : "conversation";
|
|
450
451
|
const policyContext = { executionTarget, executionContext } as const;
|