@vellumai/assistant 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +13 -19
- package/Dockerfile +75 -1
- package/bun.lock +11 -1
- package/docker-entrypoint.sh +17 -0
- package/docker-init-apt-root.sh +167 -0
- package/docker-kata-apt-env.sh +39 -0
- package/docs/plugins.md +88 -47
- package/docs/skills.md +9 -7
- package/examples/plugins/echo/README.md +27 -27
- package/examples/plugins/echo/package.json +3 -0
- package/examples/plugins/echo/register.ts +31 -31
- package/node_modules/@vellumai/slack-text/src/index.test.ts +114 -14
- package/node_modules/@vellumai/slack-text/src/index.ts +82 -18
- package/openapi.yaml +642 -5
- package/package.json +3 -1
- package/scripts/generate-openapi.ts +83 -10
- package/scripts/sync-llm-catalog.ts +2 -2
- package/scripts/sync-web-search-catalog.ts +47 -25
- package/src/__tests__/agent-image-optimize.test.ts +11 -3
- package/src/__tests__/agent-loop-exit-reason.test.ts +272 -0
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +195 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +131 -0
- package/src/__tests__/anthropic-provider.test.ts +45 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +9 -3
- package/src/__tests__/app-executors.test.ts +220 -4
- package/src/__tests__/auto-analysis-end-to-end.test.ts +35 -0
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/channel-availability-routes.test.ts +206 -0
- package/src/__tests__/channel-delivery-store.test.ts +289 -1
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -1
- package/src/__tests__/clawhub.test.ts +75 -16
- package/src/__tests__/compactor-tail-resolution.test.ts +147 -0
- package/src/__tests__/config-get-vision-flag.test.ts +136 -0
- package/src/__tests__/config-loader-backfill.test.ts +115 -18
- package/src/__tests__/config-schema.test.ts +21 -0
- package/src/__tests__/config-set-route.test.ts +80 -0
- package/src/__tests__/config-sounds-sync.test.ts +97 -0
- package/src/__tests__/config-watcher-skill-reseed.test.ts +453 -0
- package/src/__tests__/context-search-conversations-source.test.ts +117 -2
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
- package/src/__tests__/context-search-workspace-source.test.ts +7 -0
- package/src/__tests__/context-token-estimator.test.ts +31 -65
- package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +92 -92
- package/src/__tests__/conversation-agent-loop.test.ts +59 -1
- package/src/__tests__/conversation-error.test.ts +42 -3
- package/src/__tests__/conversation-fork-crud.test.ts +82 -0
- package/src/__tests__/conversation-inference-profile-route.test.ts +40 -4
- package/src/__tests__/conversation-lifecycle.test.ts +173 -0
- package/src/__tests__/conversation-media-retry.test.ts +19 -8
- package/src/__tests__/conversation-message-sync-tags.test.ts +97 -0
- package/src/__tests__/conversation-pairing.test.ts +54 -0
- package/src/__tests__/conversation-process-callsite.test.ts +4 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -1
- package/src/__tests__/conversation-queue.test.ts +4 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +102 -13
- package/src/__tests__/conversation-slash-queue.test.ts +59 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +4 -1
- package/src/__tests__/conversation-surfaces-table-action.test.ts +360 -0
- package/src/__tests__/conversation-sync-tags.test.ts +235 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-security-invariants.test.ts +3 -2
- package/src/__tests__/date-context.test.ts +45 -0
- package/src/__tests__/db-slack-external-content-normalization.test.ts +301 -0
- package/src/__tests__/delete-managed-skill-tool.test.ts +55 -13
- package/src/__tests__/disk-pressure-tools.test.ts +1 -0
- package/src/__tests__/dm-backfill.test.ts +121 -10
- package/src/__tests__/document-tool-security.test.ts +258 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/edit-propagation.test.ts +33 -0
- package/src/__tests__/empty-response-pipeline.test.ts +0 -4
- package/src/__tests__/external-plugin-loader.test.ts +151 -55
- package/src/__tests__/filing-service.test.ts +140 -0
- package/src/__tests__/get-skill-detail-audit.test.ts +0 -4
- package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +0 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +43 -62
- package/src/__tests__/heartbeat-service.test.ts +24 -164
- package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
- package/src/__tests__/helpers/tar-fixtures.ts +39 -0
- package/src/__tests__/helpers/wait-for.ts +21 -0
- package/src/__tests__/history-repair-pipeline.test.ts +0 -3
- package/src/__tests__/history-repair.test.ts +73 -0
- package/src/__tests__/host-app-control-proxy.test.ts +507 -10
- package/src/__tests__/host-proxy-preactivation.test.ts +200 -13
- package/src/__tests__/image-credentials.test.ts +1 -1
- package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +1 -1
- package/src/__tests__/inference-profile-reaper.test.ts +4 -2
- package/src/__tests__/inference-profile-session-handler.test.ts +18 -6
- package/src/__tests__/inference-profile-session-ipc.test.ts +17 -5
- package/src/__tests__/injector-background-turn.test.ts +153 -0
- package/src/__tests__/injector-chain.test.ts +15 -8
- package/src/__tests__/install-skill-routing.test.ts +155 -37
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +99 -3
- package/src/__tests__/list-messages-page-latest.test.ts +55 -0
- package/src/__tests__/llm-call-pipeline.test.ts +0 -3
- package/src/__tests__/llm-callsite-catalog.test.ts +25 -0
- package/src/__tests__/llm-catalog-parity.test.ts +58 -13
- package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +116 -0
- package/src/__tests__/llm-request-log-error-payload.test.ts +138 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +36 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +29 -53
- package/src/__tests__/llm-resolver.test.ts +255 -2
- package/src/__tests__/llm-usage-store.test.ts +114 -0
- package/src/__tests__/managed-profile-guard.test.ts +41 -29
- package/src/__tests__/managed-skill-lifecycle.test.ts +109 -18
- package/src/__tests__/managed-store.test.ts +84 -192
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -2
- package/src/__tests__/messages-after-tiebreaker.test.ts +122 -0
- package/src/__tests__/notification-decision-fallback.test.ts +0 -91
- package/src/__tests__/notification-decision-strategy.test.ts +14 -31
- package/src/__tests__/notification-deep-link.test.ts +15 -0
- package/src/__tests__/notification-guardian-path.test.ts +1 -2
- package/src/__tests__/notification-platform-adapter.test.ts +5 -4
- package/src/__tests__/notification-telegram-adapter.test.ts +1 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +113 -0
- package/src/__tests__/oauth-commands-routes.test.ts +168 -16
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -0
- package/src/__tests__/openai-provider.test.ts +242 -3
- package/src/__tests__/openai-responses-cutover-guard.test.ts +17 -9
- package/src/__tests__/openrouter-provider-only.test.ts +51 -3
- package/src/__tests__/openrouter-token-estimation.test.ts +34 -25
- package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -2
- package/src/__tests__/persistence-pipeline.test.ts +0 -2
- package/src/__tests__/{managed-proxy-context.test.ts → platform-proxy-context.test.ts} +7 -2
- package/src/__tests__/platform.test.ts +2 -0
- package/src/__tests__/plugin-api-shim.test.ts +125 -0
- package/src/__tests__/plugin-bootstrap.test.ts +10 -36
- package/src/__tests__/plugin-external-api.test.ts +68 -0
- package/src/__tests__/plugin-registry.test.ts +0 -77
- package/src/__tests__/plugin-route-contribution.test.ts +0 -1
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -2
- package/src/__tests__/plugin-tool-contribution.test.ts +16 -15
- package/src/__tests__/plugin-types.test.ts +3 -13
- package/src/__tests__/process-message-background-slack.test.ts +8 -1
- package/src/__tests__/process-message-display-content.test.ts +421 -0
- package/src/__tests__/provider-catalog-visibility.test.ts +158 -0
- package/src/__tests__/provider-error-scenarios.test.ts +111 -0
- package/src/__tests__/{provider-managed-proxy-integration.test.ts → provider-platform-proxy-integration.test.ts} +33 -31
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +65 -13
- package/src/__tests__/schedule-routes.test.ts +50 -3
- package/src/__tests__/schedule-store.test.ts +94 -0
- package/src/__tests__/scheduler-reuse-conversation.test.ts +54 -7
- package/src/__tests__/schema-transforms.test.ts +20 -0
- package/src/__tests__/search-skills-unified.test.ts +0 -5
- package/src/__tests__/{secret-routes-managed-proxy.test.ts → secret-routes-platform-proxy.test.ts} +1 -1
- package/src/__tests__/server-history-render.test.ts +43 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -12
- package/src/__tests__/skill-load-tool.test.ts +27 -89
- package/src/__tests__/skill-memory.test.ts +23 -3
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -38
- package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -3
- package/src/__tests__/skills-install-extract.test.ts +49 -38
- package/src/__tests__/skills-install-staging.test.ts +159 -0
- package/src/__tests__/skills-uninstall.test.ts +9 -41
- package/src/__tests__/skills.test.ts +51 -58
- package/src/__tests__/slack-channel-config.test.ts +9 -0
- package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
- package/src/__tests__/system-prompt.test.ts +670 -63
- package/src/__tests__/terminal-tools.test.ts +28 -1
- package/src/__tests__/thread-backfill.test.ts +557 -27
- package/src/__tests__/title-generate-pipeline.test.ts +0 -13
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -3
- package/src/__tests__/tool-error-pipeline.test.ts +0 -3
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +16 -4
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -12
- package/src/__tests__/turn-events-store.test.ts +256 -0
- package/src/__tests__/twilio-routes.test.ts +4 -0
- package/src/__tests__/user-plugin-loader.test.ts +0 -7
- package/src/__tests__/voice-session-bridge.test.ts +198 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +32 -10
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +115 -3
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +50 -0
- package/src/__tests__/workspace-migration-073-repair-recall-callsite-empty-profile.test.ts +153 -0
- package/src/__tests__/workspace-migration-085-memory-v2-bm25-b-reembed-disabled-v2-pages.test.ts +220 -0
- package/src/__tests__/workspace-migration-086-revert-stale-gemini-mis-rewrites.test.ts +269 -0
- package/src/__tests__/workspace-migration-087-memory-router-balanced-profile.test.ts +228 -0
- package/src/__tests__/workspace-migration-remove-legacy-skills-index.test.ts +309 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +111 -3
- package/src/a2a/__tests__/agent-card.test.ts +98 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +597 -0
- package/src/a2a/__tests__/protocol-helpers.test.ts +113 -0
- package/src/a2a/__tests__/task-store.test.ts +246 -0
- package/src/a2a/agent-card.ts +58 -0
- package/src/a2a/feature-gate.ts +8 -0
- package/src/a2a/protocol-constants.ts +21 -0
- package/src/a2a/protocol-errors.ts +50 -0
- package/src/a2a/protocol-types.ts +162 -0
- package/src/a2a/task-store.ts +168 -0
- package/src/acp/resolve-agent.ts +1 -1
- package/src/agent/image-optimize.ts +13 -5
- package/src/agent/loop.ts +167 -18
- package/src/calls/voice-session-bridge.ts +61 -42
- package/src/channels/config.ts +9 -0
- package/src/channels/types.ts +122 -0
- package/src/cli/__tests__/unknown-command.test.ts +24 -0
- package/src/cli/commands/__tests__/changelog.test.ts +304 -319
- package/src/cli/{__tests__ → commands/__tests__}/notifications.test.ts +201 -28
- package/src/cli/commands/__tests__/schedules.test.ts +960 -0
- package/src/cli/commands/changelog.ts +106 -42
- package/src/cli/commands/conversations.ts +102 -17
- package/src/cli/commands/default-action.ts +10 -53
- package/src/cli/commands/notifications.ts +388 -346
- package/src/cli/commands/plugins.ts +252 -0
- package/src/cli/commands/schedules.ts +683 -0
- package/src/cli/commands/telemetry.ts +40 -0
- package/src/cli/lib/__tests__/cli-colors.test.ts +48 -0
- package/src/cli/lib/__tests__/confirm-prompt.test.ts +159 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +355 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +154 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +261 -0
- package/src/cli/lib/__tests__/uninstall-plugin.test.ts +124 -0
- package/src/cli/lib/__tests__/unknown-command.test.ts +106 -0
- package/src/cli/lib/cli-colors.ts +12 -0
- package/src/cli/lib/confirm-prompt.ts +79 -0
- package/src/cli/lib/install-from-github.ts +303 -0
- package/src/cli/lib/list-installed-plugins.ts +137 -0
- package/src/cli/lib/search-plugins.ts +163 -0
- package/src/cli/lib/uninstall-plugin.ts +82 -0
- package/src/cli/lib/unknown-command.ts +111 -0
- package/src/cli/program.ts +52 -2
- package/src/config/assistant-feature-flags.ts +24 -54
- package/src/config/bundled-skills/app-builder/SKILL.md +140 -22
- package/src/config/bundled-skills/app-builder/TOOLS.json +7 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +15 -52
- package/src/config/bundled-skills/document/SKILL.md +23 -3
- package/src/config/bundled-skills/document/TOOLS.json +53 -0
- package/src/config/bundled-skills/document/tools/document-delete.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-list.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-read.ts +12 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
- package/src/config/bundled-skills/skill-management/SKILL.md +2 -2
- package/src/config/bundled-skills/skill-management/TOOLS.json +7 -7
- package/src/config/bundled-tool-registry.ts +6 -0
- package/src/config/call-site-defaults.ts +105 -0
- package/src/config/feature-flag-registry.json +41 -9
- package/src/config/llm-resolver.ts +52 -1
- package/src/config/loader.ts +64 -38
- package/src/config/schema.ts +9 -10
- package/src/config/schemas/__tests__/llm-request-logs.test.ts +36 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +3 -3
- package/src/config/schemas/channels.ts +17 -0
- package/src/config/schemas/compaction.ts +28 -0
- package/src/config/schemas/conversations.ts +10 -0
- package/src/config/schemas/heartbeat.ts +23 -0
- package/src/config/schemas/llm-request-logs.ts +31 -7
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-retrieval.ts +18 -0
- package/src/config/schemas/memory-retrospective.ts +1 -1
- package/src/config/schemas/memory-v2.ts +4 -4
- package/src/config/schemas/memory.ts +3 -1
- package/src/config/schemas/tools.ts +14 -0
- package/src/config/seed-inference-profiles.ts +99 -29
- package/src/config/skills.ts +3 -96
- package/src/context/compactor.ts +1107 -0
- package/src/context/token-estimator.ts +34 -36
- package/src/context/window-manager.ts +197 -1520
- package/src/credential-execution/managed-catalog.ts +37 -0
- package/src/credential-health/credential-health-service.ts +280 -19
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +33 -18
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +138 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +74 -0
- package/src/daemon/approval-generators.ts +8 -6
- package/src/daemon/config-watcher.ts +94 -31
- package/src/daemon/conversation-agent-loop-handlers.ts +78 -0
- package/src/daemon/conversation-agent-loop.ts +198 -11
- package/src/daemon/conversation-error.ts +171 -37
- package/src/daemon/conversation-lifecycle.ts +53 -40
- package/src/daemon/conversation-messaging.ts +25 -6
- package/src/daemon/conversation-process.ts +49 -12
- package/src/daemon/conversation-runtime-assembly.ts +25 -1
- package/src/daemon/conversation-slash.ts +12 -5
- package/src/daemon/conversation-store.ts +11 -4
- package/src/daemon/conversation-tool-setup.ts +39 -7
- package/src/daemon/conversation.ts +33 -8
- package/src/daemon/date-context.ts +40 -0
- package/src/daemon/external-plugins-bootstrap.ts +217 -181
- package/src/daemon/first-greeting.ts +22 -2
- package/src/daemon/guardian-action-generators.ts +1 -125
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +248 -0
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +154 -0
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +133 -0
- package/src/daemon/handlers/__tests__/config-a2a.test.ts +95 -0
- package/src/daemon/handlers/config-a2a.ts +289 -0
- package/src/daemon/handlers/config-model.ts +6 -5
- package/src/daemon/handlers/config-slack-channel.ts +15 -3
- package/src/daemon/handlers/conversations.ts +1 -0
- package/src/daemon/handlers/shared.ts +14 -5
- package/src/daemon/handlers/skills.ts +111 -108
- package/src/daemon/history-repair.ts +28 -1
- package/src/daemon/host-app-control-proxy.ts +153 -27
- package/src/daemon/host-proxy-preactivation.ts +85 -18
- package/src/daemon/lifecycle.ts +89 -91
- package/src/daemon/meet-host-supervisor.ts +5 -4
- package/src/daemon/memory-v2-startup.ts +85 -0
- package/src/daemon/message-protocol.ts +1 -0
- package/src/daemon/message-types/conversations.ts +25 -0
- package/src/daemon/message-types/messages.ts +61 -0
- package/src/daemon/message-types/notifications.ts +21 -0
- package/src/daemon/message-types/subagents.ts +1 -0
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/pkb-reminder-builder.test.ts +11 -54
- package/src/daemon/pkb-reminder-builder.ts +5 -20
- package/src/daemon/plugin-source-watcher.ts +146 -0
- package/src/daemon/process-message.ts +24 -3
- package/src/daemon/server.ts +11 -2
- package/src/daemon/skill-memory-refresh.ts +33 -0
- package/src/daemon/wake-target-adapter.ts +2 -0
- package/src/documents/document-store.ts +221 -3
- package/src/embedded/plugin-api.ts +40 -0
- package/src/export/__tests__/transcript-formatter.test.ts +121 -0
- package/src/export/transcript-formatter.ts +54 -20
- package/src/filing/filing-service.ts +39 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +135 -6
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +73 -189
- package/src/home/__tests__/feed-types.test.ts +80 -0
- package/src/home/feed-types.ts +36 -2
- package/src/home/post-connect-feed.ts +1 -0
- package/src/index.ts +18 -1
- package/src/ipc/cli-client.ts +147 -45
- package/src/live-voice/__tests__/live-voice-stt.test.ts +57 -0
- package/src/mcp/client.ts +20 -4
- package/src/media/image-credentials.ts +3 -3
- package/src/memory/__tests__/bookmark-crud.test.ts +33 -27
- package/src/memory/__tests__/conversation-queries.test.ts +483 -0
- package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +113 -0
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +2 -50
- package/src/memory/__tests__/memory-retrospective-job.test.ts +87 -4
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +119 -14
- package/src/memory/__tests__/message-content.test.ts +35 -0
- package/src/memory/bookmark-crud.ts +42 -10
- package/src/memory/context-search/sources/conversations.ts +62 -2
- package/src/memory/context-search/sources/workspace.ts +4 -0
- package/src/memory/conversation-crud.ts +63 -19
- package/src/memory/conversation-queries.ts +197 -11
- package/src/memory/conversation-title-service.ts +26 -4
- package/src/memory/db-init.ts +12 -0
- package/src/memory/delivery-crud.ts +152 -5
- package/src/memory/embedding-backend.ts +4 -4
- package/src/memory/external-conversation-store.ts +66 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +150 -12
- package/src/memory/graph/conversation-graph-memory.ts +49 -21
- package/src/memory/graph/tools.ts +9 -40
- package/src/memory/indexer.ts +34 -29
- package/src/memory/invite-store.ts +53 -0
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +73 -0
- package/src/memory/jobs/embed-concept-page.ts +20 -11
- package/src/memory/jobs-worker.ts +6 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +24 -12
- package/src/memory/llm-request-log-source.ts +19 -52
- package/src/memory/llm-request-log-store.ts +92 -1
- package/src/memory/llm-usage-store.ts +125 -5
- package/src/memory/memory-retrospective-enqueue.ts +1 -20
- package/src/memory/memory-retrospective-job.ts +33 -6
- package/src/memory/memory-retrospective-startup-cleanup.ts +72 -5
- package/src/memory/message-content.ts +1 -1
- package/src/memory/migrations/109-external-conversation-bindings.ts +15 -4
- package/src/memory/migrations/229-delete-private-conversations.test.ts +38 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +7 -0
- package/src/memory/migrations/247-external-conversation-binding-thread-id.ts +78 -0
- package/src/memory/migrations/248-create-onboarding-events.ts +21 -0
- package/src/memory/migrations/249-normalize-slack-external-content.ts +240 -0
- package/src/memory/migrations/250-provider-connection-base-url-and-models.ts +28 -0
- package/src/memory/migrations/251-a2a-tasks.ts +49 -0
- package/src/memory/migrations/252-llm-request-log-agent-loop-exit-reason.ts +32 -0
- package/src/memory/migrations/index.ts +9 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/onboarding-events-store.ts +106 -0
- package/src/memory/schema/a2a.ts +15 -0
- package/src/memory/schema/bookmarks.ts +0 -2
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/inference.ts +3 -3
- package/src/memory/schema/infrastructure.ts +13 -0
- package/src/memory/turn-events-store.ts +127 -2
- package/src/memory/v2/__tests__/activation-store.test.ts +25 -23
- package/src/memory/v2/__tests__/activation.test.ts +0 -8
- package/src/memory/v2/__tests__/cli-command-store.test.ts +404 -0
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +25 -4
- package/src/memory/v2/__tests__/injection.test.ts +288 -11
- package/src/memory/v2/__tests__/migration.test.ts +87 -0
- package/src/memory/v2/__tests__/page-index.test.ts +83 -0
- package/src/memory/v2/__tests__/prompts-router.test.ts +58 -6
- package/src/memory/v2/__tests__/qdrant.test.ts +66 -3
- package/src/memory/v2/__tests__/router.test.ts +15 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +387 -8
- package/src/memory/v2/__tests__/static-context.test.ts +12 -1
- package/src/memory/v2/activation-store.ts +14 -16
- package/src/memory/v2/cli-command-content.ts +19 -0
- package/src/memory/v2/cli-command-store.ts +304 -0
- package/src/memory/v2/frontmatter-sweep.ts +7 -1
- package/src/memory/v2/injection.ts +81 -26
- package/src/memory/v2/migration.ts +49 -19
- package/src/memory/v2/page-index.ts +63 -8
- package/src/memory/v2/prompts/router.ts +11 -8
- package/src/memory/v2/prompts/sweep.ts +2 -2
- package/src/memory/v2/qdrant.ts +135 -7
- package/src/memory/v2/router.ts +9 -8
- package/src/memory/v2/skill-store.ts +120 -35
- package/src/memory/v2/static-context.ts +4 -4
- package/src/memory/v2/types.ts +23 -0
- package/src/messaging/providers/a2a/__tests__/deliver.test.ts +274 -0
- package/src/messaging/providers/a2a/deliver.ts +156 -0
- package/src/messaging/providers/gmail/client.ts +9 -2
- package/src/messaging/providers/index.ts +11 -2
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +45 -5
- package/src/messaging/providers/slack/__tests__/download.test.ts +231 -0
- package/src/messaging/providers/slack/adapter.ts +43 -5
- package/src/messaging/providers/slack/client.ts +27 -0
- package/src/messaging/providers/slack/deep-link.ts +65 -0
- package/src/messaging/providers/slack/download.ts +104 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +32 -0
- package/src/messaging/providers/slack/message-metadata.ts +27 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +134 -0
- package/src/messaging/providers/slack/render-transcript.ts +69 -5
- package/src/messaging/providers/slack/types.ts +20 -1
- package/src/notifications/__tests__/broadcaster.test.ts +203 -0
- package/src/notifications/__tests__/decision-engine.test.ts +283 -0
- package/src/notifications/__tests__/deterministic-checks.test.ts +286 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +430 -7
- package/src/notifications/adapters/macos.ts +12 -2
- package/src/notifications/broadcaster.ts +29 -4
- package/src/notifications/conversation-pairing.ts +2 -1
- package/src/notifications/copy-composer.ts +17 -64
- package/src/notifications/decision-engine.ts +113 -45
- package/src/notifications/deterministic-checks.ts +96 -0
- package/src/notifications/emit-signal.ts +21 -1
- package/src/notifications/home-feed-side-effect.ts +138 -5
- package/src/notifications/signal.ts +3 -5
- package/src/notifications/types.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -4
- package/src/oauth/platform-connection.test.ts +43 -3
- package/src/oauth/platform-connection.ts +19 -6
- package/src/oauth/seed-providers.ts +10 -1
- package/src/permissions/checker.ts +2 -0
- package/src/permissions/ipc-risk-types.ts +1 -0
- package/src/permissions/question-prompter.test.ts +416 -0
- package/src/permissions/question-prompter.ts +294 -0
- package/src/platform/client.test.ts +1 -1
- package/src/platform/client.ts +1 -1
- package/src/plugin-api/constants.ts +26 -0
- package/src/plugin-api/index.ts +34 -1
- package/src/plugin-api/types.ts +104 -22
- package/src/plugins/defaults/circuit-breaker.ts +0 -5
- package/src/plugins/defaults/compaction.ts +0 -4
- package/src/plugins/defaults/empty-response.ts +0 -2
- package/src/plugins/defaults/history-repair.ts +0 -2
- package/src/plugins/defaults/injectors.ts +74 -22
- package/src/plugins/defaults/llm-call.ts +0 -2
- package/src/plugins/defaults/memory-retrieval.ts +0 -1
- package/src/plugins/defaults/overflow-reduce.ts +0 -1
- package/src/plugins/defaults/persistence.ts +0 -2
- package/src/plugins/defaults/title-generate.ts +0 -5
- package/src/plugins/defaults/token-estimate.ts +0 -2
- package/src/plugins/defaults/tool-error.ts +0 -7
- package/src/plugins/defaults/tool-execute.ts +0 -2
- package/src/plugins/defaults/tool-result-truncate.ts +0 -4
- package/src/plugins/ensure-plugin-api-shim.ts +96 -0
- package/src/plugins/external-api.ts +104 -0
- package/src/plugins/external-plugin-loader.ts +187 -42
- package/src/plugins/feature-gate.ts +22 -0
- package/src/plugins/pipeline.ts +37 -0
- package/src/plugins/registry.ts +48 -80
- package/src/plugins/types.ts +40 -26
- package/src/plugins/user-loader.ts +21 -2
- package/src/proactive-artifact/aux-message-injector.ts +11 -0
- package/src/proactive-artifact/job.test.ts +37 -5
- package/src/prompts/__tests__/system-prompt.test.ts +10 -43
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +95 -0
- package/src/prompts/normalize-onboarding.ts +27 -0
- package/src/prompts/sections.ts +302 -0
- package/src/prompts/system-prompt.ts +63 -174
- package/src/prompts/templates/BOOTSTRAP.md +17 -1
- package/src/prompts/templates/system-sections.ts +164 -0
- package/src/providers/__tests__/inference.test.ts +24 -7
- package/src/providers/anthropic/client.ts +28 -28
- package/src/providers/call-site-routing.ts +24 -6
- package/src/providers/connection-resolution.ts +68 -11
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +74 -0
- package/src/providers/inference/__tests__/connections-openai-compatible.test.ts +175 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +15 -0
- package/src/providers/inference/adapter-factory.ts +32 -6
- package/src/providers/inference/auth.ts +12 -0
- package/src/providers/inference/backfill.ts +14 -1
- package/src/providers/inference/connections.ts +159 -34
- package/src/providers/inference/resolve-auth.ts +14 -4
- package/src/providers/model-catalog.ts +249 -12
- package/src/providers/model-intents.ts +3 -3
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +235 -0
- package/src/providers/openai/chat-completions-provider.ts +169 -8
- package/src/providers/openrouter/client.ts +49 -4
- package/src/providers/{managed-proxy → platform-proxy}/constants.ts +4 -2
- package/src/providers/{managed-proxy → platform-proxy}/context.ts +3 -3
- package/src/providers/provider-availability.ts +17 -2
- package/src/providers/provider-catalog-visibility.ts +38 -0
- package/src/providers/provider-send-message.ts +27 -12
- package/src/providers/registry.ts +52 -15
- package/src/providers/retry.ts +47 -1
- package/src/runtime/__tests__/agent-wake.test.ts +152 -0
- package/src/runtime/agent-wake.ts +103 -15
- package/src/runtime/auth/route-policy.ts +21 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/http-server.ts +7 -16
- package/src/runtime/http-types.ts +19 -47
- package/src/runtime/migrations/origin-mode.ts +1 -1
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +17 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +258 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +172 -23
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +275 -44
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +12 -0
- package/src/runtime/routes/__tests__/question-routes.test.ts +395 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +64 -1
- package/src/runtime/routes/acp-routes-list.test.ts +143 -0
- package/src/runtime/routes/acp-routes.ts +5 -3
- package/src/runtime/routes/auth-routes.ts +1 -1
- package/src/runtime/routes/bookmark-routes.ts +5 -3
- package/src/runtime/routes/btw-routes.ts +5 -1
- package/src/runtime/routes/channel-availability-routes.ts +126 -0
- package/src/runtime/routes/consolidation-routes.ts +100 -0
- package/src/runtime/routes/conversation-cli-routes.ts +44 -3
- package/src/runtime/routes/conversation-list-routes.ts +3 -20
- package/src/runtime/routes/conversation-management-routes.ts +17 -42
- package/src/runtime/routes/conversation-query-routes.ts +99 -35
- package/src/runtime/routes/conversation-routes.ts +97 -11
- package/src/runtime/routes/documents-routes.ts +25 -86
- package/src/runtime/routes/group-routes.ts +5 -0
- package/src/runtime/routes/inbound-conversation.ts +28 -8
- package/src/runtime/routes/inbound-message-handler.ts +236 -41
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +111 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +32 -1
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +17 -4
- package/src/runtime/routes/index.ts +8 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +17 -44
- package/src/runtime/routes/inference-profile-session-reaper.ts +7 -21
- package/src/runtime/routes/inference-provider-connection-routes.ts +199 -22
- package/src/runtime/routes/integrations/a2a.ts +235 -0
- package/src/runtime/routes/integrations/slack/share.ts +4 -52
- package/src/runtime/routes/integrations/slack/token.ts +43 -0
- package/src/runtime/routes/integrations/twilio.ts +6 -13
- package/src/runtime/routes/llm-call-sites-routes.ts +11 -1
- package/src/runtime/routes/notification-routes.ts +1 -1
- package/src/runtime/routes/oauth-commands-routes.ts +105 -15
- package/src/runtime/routes/oauth-lifecycle-routes.ts +43 -0
- package/src/runtime/routes/question-routes.ts +259 -0
- package/src/runtime/routes/rename-conversation-routes.ts +2 -33
- package/src/runtime/routes/schedule-routes.ts +4 -7
- package/src/runtime/routes/subagents-routes.ts +98 -18
- package/src/runtime/routes/telemetry-routes.ts +27 -0
- package/src/runtime/routes/tts-routes.ts +27 -2
- package/src/runtime/routes/workspace-routes.test.ts +43 -0
- package/src/runtime/routes/workspace-routes.ts +28 -0
- package/src/runtime/services/conversation-serializer.ts +39 -7
- package/src/runtime/sync/resource-sync-events.ts +93 -1
- package/src/schedule/schedule-store.ts +27 -2
- package/src/schedule/scheduler.ts +9 -1
- package/src/security/__tests__/untrusted-content.test.ts +86 -0
- package/src/security/untrusted-content.ts +93 -8
- package/src/skills/catalog-files.ts +1 -1
- package/src/skills/catalog-install.ts +233 -116
- package/src/skills/clawhub.ts +70 -13
- package/src/skills/managed-store.ts +4 -119
- package/src/skills/skillssh-registry.ts +27 -48
- package/src/subagent/manager.ts +17 -7
- package/src/telemetry/types.ts +113 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +312 -5
- package/src/telemetry/usage-telemetry-reporter.ts +113 -7
- package/src/tools/apps/executors.ts +58 -7
- package/src/tools/ask-question/ask-question-tool.test.ts +509 -0
- package/src/tools/ask-question/ask-question-tool.ts +304 -0
- package/src/tools/browser/browser-execution.ts +15 -11
- package/src/tools/computer-use/definitions.ts +3 -3
- package/src/tools/credentials/vault.ts +1 -1
- package/src/tools/document/document-tool.ts +124 -1
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +5 -2
- package/src/tools/host-filesystem/transfer.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +1 -1
- package/src/tools/memory/register.ts +1 -9
- package/src/tools/permission-checker.ts +1 -1
- package/src/tools/registry.ts +17 -7
- package/src/tools/schedule/create.ts +2 -2
- package/src/tools/schema-transforms.ts +7 -2
- package/src/tools/side-effects.ts +1 -0
- package/src/tools/skills/delete-managed.ts +4 -4
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/scaffold-managed.ts +3 -2
- package/src/tools/subagent/notify-parent.ts +1 -1
- package/src/tools/system/request-permission.ts +2 -2
- package/src/tools/terminal/safe-env.ts +60 -1
- package/src/tools/tool-manifest.ts +2 -0
- package/src/tools/types.ts +107 -21
- package/src/tools/ui-surface/definitions.ts +6 -5
- package/src/tts/__tests__/provider-adapters.test.ts +76 -2
- package/src/tts/providers/elevenlabs-provider.ts +75 -1
- package/src/types/onboarding-context.ts +2 -0
- package/src/util/errors.ts +17 -0
- package/src/util/platform.ts +10 -0
- package/src/watcher/__tests__/engine.test.ts +22 -0
- package/src/watcher/engine.ts +6 -2
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +80 -15
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +35 -22
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +3 -1
- package/src/workspace/migrations/083-system-prompt-prefix-to-file.ts +191 -0
- package/src/workspace/migrations/084-remove-legacy-skills-index.ts +276 -0
- package/src/workspace/migrations/085-memory-v2-bm25-b-reembed-disabled-v2-pages.ts +137 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +198 -0
- package/src/workspace/migrations/087-memory-router-balanced-profile.ts +91 -0
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/migrations/runner.ts +39 -9
- package/src/workspace/migrations/types.ts +4 -0
- package/examples/plugins/echo/bun.lock +0 -25
- package/src/__tests__/context-window-manager.test.ts +0 -2481
- package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -441
- package/src/context/__tests__/compact-prompt.test.ts +0 -63
- package/src/context/prompts/compact.md +0 -26
- package/src/memory/graph/__tests__/remember-description.test.ts +0 -55
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +0 -37
- package/src/runtime/guardian-action-conversation-turn.ts +0 -99
|
@@ -116,7 +116,7 @@ describe("OpenRouter provider.only plumbing", () => {
|
|
|
116
116
|
expect(extras.provider).toBe(undefined);
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
test("
|
|
119
|
+
test("enables thinking with default detailed summary alongside provider.only", () => {
|
|
120
120
|
const provider = new ProbeOpenRouterProvider(
|
|
121
121
|
"fake-key",
|
|
122
122
|
"x-ai/grok-4.20-beta",
|
|
@@ -128,12 +128,12 @@ describe("OpenRouter provider.only plumbing", () => {
|
|
|
128
128
|
},
|
|
129
129
|
});
|
|
130
130
|
expect(extras).toEqual({
|
|
131
|
-
reasoning: { enabled: true },
|
|
131
|
+
reasoning: { enabled: true, summary: "detailed" },
|
|
132
132
|
provider: { only: ["xAI"] },
|
|
133
133
|
});
|
|
134
134
|
});
|
|
135
135
|
|
|
136
|
-
test("disabled thinking keeps reasoning disabled
|
|
136
|
+
test("disabled thinking keeps reasoning disabled and omits summary", () => {
|
|
137
137
|
const provider = new ProbeOpenRouterProvider(
|
|
138
138
|
"fake-key",
|
|
139
139
|
"x-ai/grok-4.20-beta",
|
|
@@ -149,5 +149,53 @@ describe("OpenRouter provider.only plumbing", () => {
|
|
|
149
149
|
provider: { only: ["xAI"] },
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
|
+
|
|
153
|
+
test("nests effort under reasoning and maps `max` to xhigh", () => {
|
|
154
|
+
const provider = new ProbeOpenRouterProvider(
|
|
155
|
+
"fake-key",
|
|
156
|
+
"moonshotai/kimi-k2.6",
|
|
157
|
+
);
|
|
158
|
+
const extras = provider.probeExtras({
|
|
159
|
+
config: {
|
|
160
|
+
thinking: { enabled: true },
|
|
161
|
+
effort: "max",
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
expect(extras).toEqual({
|
|
165
|
+
reasoning: { enabled: true, effort: "xhigh", summary: "detailed" },
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("honors a per-call summary override", () => {
|
|
170
|
+
const provider = new ProbeOpenRouterProvider(
|
|
171
|
+
"fake-key",
|
|
172
|
+
"moonshotai/kimi-k2.6",
|
|
173
|
+
);
|
|
174
|
+
const extras = provider.probeExtras({
|
|
175
|
+
config: {
|
|
176
|
+
thinking: { enabled: true },
|
|
177
|
+
openrouter: { reasoning: { summary: "concise" } },
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
expect(extras).toEqual({
|
|
181
|
+
reasoning: { enabled: true, summary: "concise" },
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test("ignores an invalid summary override and falls back to detailed", () => {
|
|
186
|
+
const provider = new ProbeOpenRouterProvider(
|
|
187
|
+
"fake-key",
|
|
188
|
+
"moonshotai/kimi-k2.6",
|
|
189
|
+
);
|
|
190
|
+
const extras = provider.probeExtras({
|
|
191
|
+
config: {
|
|
192
|
+
thinking: { enabled: true },
|
|
193
|
+
openrouter: { reasoning: { summary: "verbose" } },
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
expect(extras).toEqual({
|
|
197
|
+
reasoning: { enabled: true, summary: "detailed" },
|
|
198
|
+
});
|
|
199
|
+
});
|
|
152
200
|
});
|
|
153
201
|
});
|
|
@@ -5,7 +5,11 @@ import { OpenRouterProvider } from "../providers/openrouter/client.js";
|
|
|
5
5
|
import type { Message } from "../providers/types.js";
|
|
6
6
|
|
|
7
7
|
/** Build a minimal valid PNG header encoding the given dimensions. */
|
|
8
|
-
function makePngBase64(
|
|
8
|
+
function makePngBase64(
|
|
9
|
+
width: number,
|
|
10
|
+
height: number,
|
|
11
|
+
paddingBytes = 0,
|
|
12
|
+
): string {
|
|
9
13
|
const header = Buffer.alloc(24);
|
|
10
14
|
header[0] = 0x89;
|
|
11
15
|
header[1] = 0x50;
|
|
@@ -41,13 +45,13 @@ describe("OpenRouterProvider token estimation routing", () => {
|
|
|
41
45
|
expect(provider.tokenEstimationProvider).toBe("openrouter");
|
|
42
46
|
});
|
|
43
47
|
|
|
44
|
-
test("estimatePromptTokens applies
|
|
48
|
+
test("estimatePromptTokens applies dimension-based image scaling when routed via OpenRouter to Anthropic", () => {
|
|
45
49
|
const provider = new OpenRouterProvider(
|
|
46
50
|
"fake-key",
|
|
47
51
|
"anthropic/claude-opus-4-6",
|
|
48
52
|
);
|
|
49
53
|
// 1920x1080 screenshot with ~200 KB of pixel data → base64/4 would be ~65k
|
|
50
|
-
// tokens; dimension-based
|
|
54
|
+
// tokens; dimension-based rules land around 1.6k tokens.
|
|
51
55
|
const messages: Message[] = [
|
|
52
56
|
{
|
|
53
57
|
role: "user",
|
|
@@ -68,33 +72,38 @@ describe("OpenRouterProvider token estimation routing", () => {
|
|
|
68
72
|
providerName: provider.tokenEstimationProvider,
|
|
69
73
|
});
|
|
70
74
|
|
|
71
|
-
// Dimension-based estimate should be well under 5k; base64/4 would exceed 50k.
|
|
72
75
|
expect(estimated).toBeLessThan(5_000);
|
|
73
76
|
});
|
|
74
77
|
|
|
75
|
-
test("estimatePromptTokens
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
78
|
+
test("estimatePromptTokens applies dimension-based image scaling for non-Anthropic OpenRouter models", () => {
|
|
79
|
+
// A naive base64/4 estimate on a 1920x1080 screenshot (~200 KB) lands near
|
|
80
|
+
// 65k tokens and trips spurious compaction long before the real context
|
|
81
|
+
// window fills. Vision models on OpenRouter — both anthropic/* and
|
|
82
|
+
// non-Anthropic (Kimi K2.6, Grok, etc.) — must use the dimension-based
|
|
83
|
+
// formula.
|
|
84
|
+
for (const model of ["moonshotai/kimi-k2.6", "x-ai/grok-4.20-beta"]) {
|
|
85
|
+
const provider = new OpenRouterProvider("fake-key", model);
|
|
86
|
+
const messages: Message[] = [
|
|
87
|
+
{
|
|
88
|
+
role: "user",
|
|
89
|
+
content: [
|
|
90
|
+
{
|
|
91
|
+
type: "image",
|
|
92
|
+
source: {
|
|
93
|
+
type: "base64",
|
|
94
|
+
media_type: "image/png",
|
|
95
|
+
data: makePngBase64(1920, 1080, 200_000),
|
|
96
|
+
},
|
|
87
97
|
},
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
];
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
];
|
|
92
101
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
const estimated = estimatePromptTokens(messages, "system", {
|
|
103
|
+
providerName: provider.tokenEstimationProvider,
|
|
104
|
+
});
|
|
96
105
|
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
expect(estimated).toBeLessThan(5_000);
|
|
107
|
+
}
|
|
99
108
|
});
|
|
100
109
|
});
|
|
@@ -453,7 +453,6 @@ describe("overflow-reduce pipeline", () => {
|
|
|
453
453
|
manifest: {
|
|
454
454
|
name: "spy-overflow",
|
|
455
455
|
version: "0.0.1",
|
|
456
|
-
requires: { pluginRuntime: "v1", overflowReduceApi: "v1" },
|
|
457
456
|
},
|
|
458
457
|
middleware: { overflowReduce: spy },
|
|
459
458
|
};
|
|
@@ -512,7 +511,6 @@ describe("overflow-reduce pipeline", () => {
|
|
|
512
511
|
manifest: {
|
|
513
512
|
name: "short-circuit-overflow",
|
|
514
513
|
version: "0.0.1",
|
|
515
|
-
requires: { pluginRuntime: "v1", overflowReduceApi: "v1" },
|
|
516
514
|
},
|
|
517
515
|
middleware: { overflowReduce: shortCircuit },
|
|
518
516
|
});
|
|
@@ -267,7 +267,6 @@ describe("persistence pipeline", () => {
|
|
|
267
267
|
manifest: {
|
|
268
268
|
name: "mock-persistence",
|
|
269
269
|
version: "0.0.1",
|
|
270
|
-
requires: { pluginRuntime: "v1" },
|
|
271
270
|
},
|
|
272
271
|
middleware: { persistence: redirect },
|
|
273
272
|
};
|
|
@@ -352,7 +351,6 @@ describe("persistence pipeline", () => {
|
|
|
352
351
|
manifest: {
|
|
353
352
|
name: "late-user-plugin",
|
|
354
353
|
version: "0.0.1",
|
|
355
|
-
requires: { pluginRuntime: "v1" },
|
|
356
354
|
},
|
|
357
355
|
middleware: { persistence: userMiddleware },
|
|
358
356
|
});
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
hasManagedProxyPrereqs,
|
|
33
33
|
managedFallbackEnabledFor,
|
|
34
34
|
resolveManagedProxyContext,
|
|
35
|
-
} from "../providers/
|
|
35
|
+
} from "../providers/platform-proxy/context.js";
|
|
36
36
|
|
|
37
37
|
describe("resolveManagedProxyContext", () => {
|
|
38
38
|
beforeEach(() => {
|
|
@@ -117,8 +117,13 @@ describe("buildManagedBaseUrl", () => {
|
|
|
117
117
|
);
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
+
test("returns managed URL for fireworks", async () => {
|
|
121
|
+
expect(await buildManagedBaseUrl("fireworks")).toBe(
|
|
122
|
+
"https://platform.example.com/v1/runtime-proxy/fireworks",
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
|
|
120
126
|
test("returns undefined for non-managed providers", async () => {
|
|
121
|
-
expect(await buildManagedBaseUrl("fireworks")).toBeUndefined();
|
|
122
127
|
expect(await buildManagedBaseUrl("openrouter")).toBeUndefined();
|
|
123
128
|
expect(await buildManagedBaseUrl("ollama")).toBeUndefined();
|
|
124
129
|
});
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
getWorkspaceConfigPath,
|
|
17
17
|
getWorkspaceDir,
|
|
18
18
|
getWorkspaceHooksDir,
|
|
19
|
+
getWorkspacePluginsDir,
|
|
19
20
|
getWorkspacePromptPath,
|
|
20
21
|
getWorkspaceSkillsDir,
|
|
21
22
|
getXdgVellumConfigDirName,
|
|
@@ -161,6 +162,7 @@ describe("workspace path primitives", () => {
|
|
|
161
162
|
expect(getWorkspaceConfigPath()).toBe(join(ws, "config.json"));
|
|
162
163
|
expect(getWorkspaceSkillsDir()).toBe(join(ws, "skills"));
|
|
163
164
|
expect(getWorkspaceHooksDir()).toBe(join(ws, "hooks"));
|
|
165
|
+
expect(getWorkspacePluginsDir()).toBe(join(ws, "plugins"));
|
|
164
166
|
expect(getWorkspacePromptPath("IDENTITY.md")).toBe(join(ws, "IDENTITY.md"));
|
|
165
167
|
expect(getWorkspacePromptPath("SOUL.md")).toBe(join(ws, "SOUL.md"));
|
|
166
168
|
});
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smoke tests for the workspace-level `@vellumai/plugin-api` shim.
|
|
3
|
+
*
|
|
4
|
+
* - shim files are materialized at `<workspaceDir>/node_modules/@vellumai/plugin-api/`
|
|
5
|
+
* - the shim's index.js re-binds each runtime export from globalThis
|
|
6
|
+
* - the shim is idempotent across re-runs
|
|
7
|
+
* - a fake plugin in `<workspaceDir>/plugins/<name>/` can resolve the
|
|
8
|
+
* bare `@vellumai/plugin-api` specifier via Node-style walk-up,
|
|
9
|
+
* proving the end-to-end import path works for real user plugins
|
|
10
|
+
*
|
|
11
|
+
* As plugin-api's runtime surface grows in follow-up PRs, the shim's
|
|
12
|
+
* generated export list expands automatically — the test below covers
|
|
13
|
+
* the generator (`buildShimSource`) directly so we don't need to
|
|
14
|
+
* update assertions every time an export is added.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { mkdir, mkdtemp, readFile, writeFile } from "node:fs/promises";
|
|
18
|
+
import { tmpdir } from "node:os";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
import { describe, expect, test } from "bun:test";
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
PLUGIN_API_EXPORTS,
|
|
24
|
+
PLUGIN_API_REGISTRY_KEY,
|
|
25
|
+
} from "../embedded/plugin-api.js";
|
|
26
|
+
import {
|
|
27
|
+
buildShimSource,
|
|
28
|
+
ensurePluginApiShim,
|
|
29
|
+
} from "../plugins/ensure-plugin-api-shim.js";
|
|
30
|
+
|
|
31
|
+
const SHIM_REL_PATH = "node_modules/@vellumai/plugin-api";
|
|
32
|
+
|
|
33
|
+
describe("buildShimSource", () => {
|
|
34
|
+
test("emits a globalThis trampoline + one binding per export", () => {
|
|
35
|
+
const source = buildShimSource(
|
|
36
|
+
["foo", "bar"],
|
|
37
|
+
Symbol.for("vellum.plugin-api.v1"),
|
|
38
|
+
);
|
|
39
|
+
expect(source).toBe(
|
|
40
|
+
`const api = globalThis[Symbol.for("vellum.plugin-api.v1")];\n` +
|
|
41
|
+
`export const foo = api.foo;\n` +
|
|
42
|
+
`export const bar = api.bar;\n`,
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("handles an empty export list (today's types-only surface)", () => {
|
|
47
|
+
const source = buildShimSource(
|
|
48
|
+
[],
|
|
49
|
+
Symbol.for("vellum.plugin-api.v1"),
|
|
50
|
+
);
|
|
51
|
+
expect(source).toBe(
|
|
52
|
+
`const api = globalThis[Symbol.for("vellum.plugin-api.v1")];\n`,
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("ensurePluginApiShim", () => {
|
|
58
|
+
test("creates a resolvable @vellumai/plugin-api package under workspaceDir", async () => {
|
|
59
|
+
const workspaceDir = await mkdtemp(join(tmpdir(), "plugin-api-shim-"));
|
|
60
|
+
await ensurePluginApiShim({ workspaceDir });
|
|
61
|
+
|
|
62
|
+
const shimDir = join(workspaceDir, SHIM_REL_PATH);
|
|
63
|
+
const indexJs = await readFile(join(shimDir, "index.js"), "utf8");
|
|
64
|
+
expect(indexJs).toBe(buildShimSource());
|
|
65
|
+
|
|
66
|
+
const pkg = JSON.parse(
|
|
67
|
+
await readFile(join(shimDir, "package.json"), "utf8"),
|
|
68
|
+
);
|
|
69
|
+
expect(pkg.name).toBe("@vellumai/plugin-api");
|
|
70
|
+
expect(pkg.type).toBe("module");
|
|
71
|
+
expect(pkg.main).toBe("./index.js");
|
|
72
|
+
expect(typeof pkg.version).toBe("string");
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("is idempotent — re-running yields the same shim contents", async () => {
|
|
76
|
+
const workspaceDir = await mkdtemp(join(tmpdir(), "plugin-api-shim-"));
|
|
77
|
+
await ensurePluginApiShim({ workspaceDir });
|
|
78
|
+
const first = await readFile(
|
|
79
|
+
join(workspaceDir, SHIM_REL_PATH, "index.js"),
|
|
80
|
+
"utf8",
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
await ensurePluginApiShim({ workspaceDir });
|
|
84
|
+
const second = await readFile(
|
|
85
|
+
join(workspaceDir, SHIM_REL_PATH, "index.js"),
|
|
86
|
+
"utf8",
|
|
87
|
+
);
|
|
88
|
+
expect(second).toBe(first);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("globalThis is populated with the plugin-api namespace", () => {
|
|
92
|
+
// Importing the embed wrapper has the side effect of installing the
|
|
93
|
+
// namespace on globalThis. By the time this test runs (any earlier
|
|
94
|
+
// test in the file has already imported it), the registry must be
|
|
95
|
+
// populated.
|
|
96
|
+
const namespace = (globalThis as Record<symbol, unknown>)[
|
|
97
|
+
PLUGIN_API_REGISTRY_KEY
|
|
98
|
+
];
|
|
99
|
+
expect(namespace).toBeDefined();
|
|
100
|
+
// Exports list is non-null but may be empty until runtime exports
|
|
101
|
+
// migrate in later PRs.
|
|
102
|
+
expect(Array.isArray(PLUGIN_API_EXPORTS)).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("a fake user plugin can resolve @vellumai/plugin-api via Node-style walk-up", async () => {
|
|
106
|
+
const workspaceDir = await mkdtemp(join(tmpdir(), "plugin-api-shim-"));
|
|
107
|
+
await ensurePluginApiShim({ workspaceDir });
|
|
108
|
+
|
|
109
|
+
const pluginDir = join(workspaceDir, "plugins", "fake-plugin");
|
|
110
|
+
await mkdir(pluginDir, { recursive: true });
|
|
111
|
+
await writeFile(
|
|
112
|
+
join(pluginDir, "register.js"),
|
|
113
|
+
`import * as api from "@vellumai/plugin-api";\nexport { api };\n`,
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
// Resolution walks up: plugins/fake-plugin → plugins → workspaceDir
|
|
117
|
+
// → workspaceDir/node_modules/@vellumai/plugin-api → shim → globalThis
|
|
118
|
+
// → plugin-api namespace. If any link in that chain is broken, this
|
|
119
|
+
// import throws.
|
|
120
|
+
const mod: { api: Record<string, unknown> } = await import(
|
|
121
|
+
join(pluginDir, "register.js")
|
|
122
|
+
);
|
|
123
|
+
expect(mod.api).toBeDefined();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -43,7 +43,6 @@ import {
|
|
|
43
43
|
import { runShutdownHooks } from "../daemon/shutdown-registry.js";
|
|
44
44
|
import { RiskLevel } from "../permissions/types.js";
|
|
45
45
|
import {
|
|
46
|
-
ASSISTANT_API_VERSIONS,
|
|
47
46
|
getInjectors,
|
|
48
47
|
getMiddlewaresFor,
|
|
49
48
|
registerPlugin,
|
|
@@ -84,7 +83,6 @@ function buildPlugin(
|
|
|
84
83
|
onShutdown?: () => Promise<void>;
|
|
85
84
|
} = {},
|
|
86
85
|
options: {
|
|
87
|
-
requires?: Record<string, string>;
|
|
88
86
|
requiresCredential?: string[];
|
|
89
87
|
requiresFlag?: string[];
|
|
90
88
|
} = {},
|
|
@@ -111,7 +109,6 @@ function buildPlugin(
|
|
|
111
109
|
manifest: {
|
|
112
110
|
name,
|
|
113
111
|
version: "0.0.1",
|
|
114
|
-
requires: options.requires ?? { pluginRuntime: "v1" },
|
|
115
112
|
...(options.requiresCredential
|
|
116
113
|
? { requiresCredential: options.requiresCredential }
|
|
117
114
|
: {}),
|
|
@@ -161,10 +158,6 @@ describe("plugin bootstrap", () => {
|
|
|
161
158
|
);
|
|
162
159
|
expect(existsSync(ctx.pluginStorageDir)).toBe(true);
|
|
163
160
|
expect(ctx.assistantVersion).toBe("9.9.9-test");
|
|
164
|
-
// apiVersions must surface the canonical capability table from the
|
|
165
|
-
// registry so plugins can negotiate at runtime.
|
|
166
|
-
expect(ctx.apiVersions).toBe(ASSISTANT_API_VERSIONS);
|
|
167
|
-
expect(ctx.apiVersions.pluginRuntime).toEqual(["v1"]);
|
|
168
161
|
});
|
|
169
162
|
|
|
170
163
|
test("credential resolution: init receives the resolved value under credentials[key]", async () => {
|
|
@@ -215,29 +208,15 @@ describe("plugin bootstrap", () => {
|
|
|
215
208
|
expect(msg).toContain("absent-key");
|
|
216
209
|
});
|
|
217
210
|
|
|
218
|
-
test("version mismatch:
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
// single authoritative point of
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
let caught: unknown;
|
|
230
|
-
try {
|
|
231
|
-
registerPlugin(plugin);
|
|
232
|
-
} catch (err) {
|
|
233
|
-
caught = err;
|
|
234
|
-
}
|
|
235
|
-
expect(caught).toBeInstanceOf(PluginExecutionError);
|
|
236
|
-
const msg = (caught as PluginExecutionError).message;
|
|
237
|
-
expect(msg).toContain("from-the-future");
|
|
238
|
-
expect(msg).toContain("pluginRuntime");
|
|
239
|
-
expect(msg).toContain("v99");
|
|
240
|
-
expect((caught as PluginExecutionError).pluginName).toBe("from-the-future");
|
|
211
|
+
test("version mismatch: external plugin loader rejects when peerDependency unsatisfied", async () => {
|
|
212
|
+
// Host-compat negotiation lives in the external-plugin loader against
|
|
213
|
+
// `peerDependencies["@vellumai/plugin-api"]`. The registry no longer
|
|
214
|
+
// re-validates a manifest-level `requires` block — the loader is the
|
|
215
|
+
// single authoritative point. End-to-end coverage of the loader path
|
|
216
|
+
// lives in `external-plugin-loader.test.ts`; this test asserts the
|
|
217
|
+
// bootstrap doesn't gain its own validation surface.
|
|
218
|
+
const plugin = buildPlugin("compat-claim-checked-upstream");
|
|
219
|
+
expect(() => registerPlugin(plugin)).not.toThrow();
|
|
241
220
|
});
|
|
242
221
|
|
|
243
222
|
test("plugin init throw: bootstrap throws a PluginExecutionError naming the plugin", async () => {
|
|
@@ -395,13 +374,8 @@ describe("plugin bootstrap", () => {
|
|
|
395
374
|
{
|
|
396
375
|
name: "gated-off-tool",
|
|
397
376
|
description: "should not be registered",
|
|
398
|
-
category: "plugin-test",
|
|
399
377
|
defaultRiskLevel: RiskLevel.Low,
|
|
400
|
-
|
|
401
|
-
name: "gated-off-tool",
|
|
402
|
-
description: "should not be registered",
|
|
403
|
-
input_schema: { type: "object", properties: {}, required: [] },
|
|
404
|
-
}),
|
|
378
|
+
input_schema: { type: "object", properties: {}, required: [] },
|
|
405
379
|
execute: async () => ({ content: "nope", isError: false }),
|
|
406
380
|
},
|
|
407
381
|
],
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the `globalThis.__vellumPluginRuntime` bridge.
|
|
3
|
+
*
|
|
4
|
+
* The bridge exists so workspace-local plugins (`<workspaceDir>/plugins/*`)
|
|
5
|
+
* can register with the daemon's bundled module instances even when the
|
|
6
|
+
* daemon is a `bun --compile` binary. Absolute-path imports against a
|
|
7
|
+
* compiled binary load fresh disk copies into a disjoint module graph; the
|
|
8
|
+
* bridge sidesteps that by attaching a stable handle to globalThis.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
getPluginRuntime,
|
|
15
|
+
installPluginRuntime,
|
|
16
|
+
uninstallPluginRuntimeForTests,
|
|
17
|
+
} from "../plugins/external-api.js";
|
|
18
|
+
import { registerPlugin } from "../plugins/registry.js";
|
|
19
|
+
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
20
|
+
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
21
|
+
|
|
22
|
+
describe("plugin external-api bridge", () => {
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
uninstallPluginRuntimeForTests();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
uninstallPluginRuntimeForTests();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("installs a runtime handle on globalThis", () => {
|
|
32
|
+
expect(getPluginRuntime()).toBeUndefined();
|
|
33
|
+
installPluginRuntime();
|
|
34
|
+
const runtime = getPluginRuntime();
|
|
35
|
+
expect(runtime).toBeDefined();
|
|
36
|
+
expect(runtime?.version).toBe(1);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("exposes the canonical registerPlugin / hub / secrets references", () => {
|
|
40
|
+
installPluginRuntime();
|
|
41
|
+
const runtime = getPluginRuntime();
|
|
42
|
+
expect(runtime?.registerPlugin).toBe(registerPlugin);
|
|
43
|
+
expect(runtime?.assistantEventHub).toBe(assistantEventHub);
|
|
44
|
+
expect(runtime?.getSecureKeyAsync).toBe(getSecureKeyAsync);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("plugins can read the runtime via the documented globalThis key", () => {
|
|
48
|
+
installPluginRuntime();
|
|
49
|
+
// Mirror the access pattern documented for plugin authors.
|
|
50
|
+
const runtime = (
|
|
51
|
+
globalThis as { __vellumPluginRuntime?: { version: number } }
|
|
52
|
+
).__vellumPluginRuntime;
|
|
53
|
+
expect(runtime).toBeDefined();
|
|
54
|
+
expect(runtime?.version).toBe(1);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("install is idempotent — repeat calls preserve the same handle", () => {
|
|
58
|
+
installPluginRuntime();
|
|
59
|
+
const first = getPluginRuntime();
|
|
60
|
+
installPluginRuntime();
|
|
61
|
+
installPluginRuntime();
|
|
62
|
+
expect(getPluginRuntime()).toBe(first);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("getPluginRuntime returns undefined when the bridge is not installed", () => {
|
|
66
|
+
expect(getPluginRuntime()).toBeUndefined();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
import { beforeEach, describe, expect, test } from "bun:test";
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
|
-
ASSISTANT_API_VERSIONS,
|
|
13
12
|
closeRegistration,
|
|
14
13
|
getInjectors,
|
|
15
14
|
getMiddlewaresFor,
|
|
@@ -30,13 +29,11 @@ import {
|
|
|
30
29
|
function buildPlugin(
|
|
31
30
|
name: string,
|
|
32
31
|
extras: Partial<Omit<Plugin, "manifest">> = {},
|
|
33
|
-
requiresOverride?: Record<string, string>,
|
|
34
32
|
): Plugin {
|
|
35
33
|
return {
|
|
36
34
|
manifest: {
|
|
37
35
|
name,
|
|
38
36
|
version: "0.0.1",
|
|
39
|
-
requires: requiresOverride ?? { pluginRuntime: "v1" },
|
|
40
37
|
},
|
|
41
38
|
...extras,
|
|
42
39
|
};
|
|
@@ -106,7 +103,6 @@ describe("plugin registry", () => {
|
|
|
106
103
|
const bad = {
|
|
107
104
|
manifest: {
|
|
108
105
|
version: "0.0.1",
|
|
109
|
-
requires: { pluginRuntime: "v1" },
|
|
110
106
|
},
|
|
111
107
|
} as unknown as Plugin;
|
|
112
108
|
expect(() => registerPlugin(bad)).toThrow(/manifest\.name is required/);
|
|
@@ -148,84 +144,11 @@ describe("plugin registry", () => {
|
|
|
148
144
|
const bad = {
|
|
149
145
|
manifest: {
|
|
150
146
|
name: "missing-version",
|
|
151
|
-
requires: { pluginRuntime: "v1" },
|
|
152
147
|
},
|
|
153
148
|
} as unknown as Plugin;
|
|
154
149
|
expect(() => registerPlugin(bad)).toThrow(/manifest\.version is required/);
|
|
155
150
|
});
|
|
156
151
|
|
|
157
|
-
test("throws when manifest.requires is missing", () => {
|
|
158
|
-
const bad = {
|
|
159
|
-
manifest: { name: "missing-requires", version: "0.0.1" },
|
|
160
|
-
} as unknown as Plugin;
|
|
161
|
-
expect(() => registerPlugin(bad)).toThrow(/manifest\.requires is required/);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
test("throws when requires.pluginRuntime is missing", () => {
|
|
165
|
-
const plugin = buildPlugin(
|
|
166
|
-
"no-runtime",
|
|
167
|
-
{},
|
|
168
|
-
// Valid shape but no pluginRuntime entry.
|
|
169
|
-
{ memoryApi: "v1" },
|
|
170
|
-
);
|
|
171
|
-
expect(() => registerPlugin(plugin)).toThrow(PluginExecutionError);
|
|
172
|
-
expect(() => registerPlugin(plugin)).toThrow(/pluginRuntime/);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
test("throws with version-mismatch message when a required version is not exposed", () => {
|
|
176
|
-
// The assistant seeds memoryApi with ["v1"]. Requesting v2 must fail.
|
|
177
|
-
const plugin = buildPlugin(
|
|
178
|
-
"too-new",
|
|
179
|
-
{},
|
|
180
|
-
{
|
|
181
|
-
pluginRuntime: "v1",
|
|
182
|
-
memoryApi: "v2",
|
|
183
|
-
},
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
expect(() => registerPlugin(plugin)).toThrow(PluginExecutionError);
|
|
187
|
-
|
|
188
|
-
// Sanity-check the assistant actually exposes only v1 for memoryApi so
|
|
189
|
-
// this test fails loudly if the capability table ever adds v2.
|
|
190
|
-
expect(ASSISTANT_API_VERSIONS.memoryApi).toEqual(["v1"]);
|
|
191
|
-
|
|
192
|
-
try {
|
|
193
|
-
registerPlugin(plugin);
|
|
194
|
-
throw new Error("expected registerPlugin to throw");
|
|
195
|
-
} catch (err) {
|
|
196
|
-
expect(err).toBeInstanceOf(PluginExecutionError);
|
|
197
|
-
const msg = (err as PluginExecutionError).message;
|
|
198
|
-
// Error message must reference plugin name, API, required version,
|
|
199
|
-
// and the versions the assistant exposes.
|
|
200
|
-
expect(msg).toContain("too-new");
|
|
201
|
-
expect(msg).toContain("memoryApi");
|
|
202
|
-
expect(msg).toContain("v2");
|
|
203
|
-
expect(msg).toContain("v1");
|
|
204
|
-
expect((err as PluginExecutionError).pluginName).toBe("too-new");
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
test("throws with clear message when a required capability is unknown", () => {
|
|
209
|
-
const plugin = buildPlugin(
|
|
210
|
-
"asks-for-mystery",
|
|
211
|
-
{},
|
|
212
|
-
{
|
|
213
|
-
pluginRuntime: "v1",
|
|
214
|
-
thisDoesNotExist: "v1",
|
|
215
|
-
},
|
|
216
|
-
);
|
|
217
|
-
expect(() => registerPlugin(plugin)).toThrow(PluginExecutionError);
|
|
218
|
-
try {
|
|
219
|
-
registerPlugin(plugin);
|
|
220
|
-
throw new Error("expected registerPlugin to throw");
|
|
221
|
-
} catch (err) {
|
|
222
|
-
const msg = (err as PluginExecutionError).message;
|
|
223
|
-
expect(msg).toContain("asks-for-mystery");
|
|
224
|
-
expect(msg).toContain("thisDoesNotExist");
|
|
225
|
-
expect(msg).toContain("(none)");
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
|
|
229
152
|
test("getInjectors returns injectors sorted by order ascending", () => {
|
|
230
153
|
const high: Injector = {
|
|
231
154
|
name: "high-order",
|
|
@@ -80,7 +80,6 @@ function buildSkillPlugin(
|
|
|
80
80
|
manifest: {
|
|
81
81
|
name,
|
|
82
82
|
version: "0.0.1",
|
|
83
|
-
requires: { pluginRuntime: "v1" },
|
|
84
83
|
},
|
|
85
84
|
skills,
|
|
86
85
|
...extras,
|
|
@@ -204,7 +203,6 @@ describe("plugin skill contributions", () => {
|
|
|
204
203
|
manifest: {
|
|
205
204
|
name: "no-skills-plugin",
|
|
206
205
|
version: "0.0.1",
|
|
207
|
-
requires: { pluginRuntime: "v1" },
|
|
208
206
|
},
|
|
209
207
|
});
|
|
210
208
|
|