@vellumai/assistant 0.8.1 → 0.8.2
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 -7
- package/Dockerfile +75 -1
- package/bun.lock +11 -1
- package/docker-entrypoint.sh +5 -0
- package/docker-init-apt-root.sh +94 -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 +325 -3
- 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-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 +41 -0
- 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 +1 -0
- 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 +2 -0
- 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-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 +76 -9
- 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__/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 +60 -36
- package/src/__tests__/filing-service.test.ts +140 -0
- package/src/__tests__/get-skill-detail-audit.test.ts +0 -4
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +43 -62
- 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 +266 -10
- 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-chain.test.ts +10 -8
- package/src/__tests__/install-skill-routing.test.ts +155 -37
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +92 -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-catalog-parity.test.ts +55 -13
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +34 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +29 -53
- package/src/__tests__/llm-usage-store.test.ts +114 -0
- package/src/__tests__/managed-profile-guard.test.ts +31 -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__/oauth-commands-routes.test.ts +168 -16
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -0
- package/src/__tests__/openai-provider.test.ts +24 -0
- package/src/__tests__/openai-responses-cutover-guard.test.ts +17 -9
- 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} +1 -1
- 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 +142 -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} +8 -8
- 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__/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 +737 -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-remove-legacy-skills-index.test.ts +309 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +111 -3
- package/src/acp/resolve-agent.ts +1 -1
- package/src/agent/image-optimize.ts +13 -5
- package/src/calls/voice-session-bridge.ts +61 -42
- package/src/channels/types.ts +108 -0
- package/src/cli/__tests__/unknown-command.test.ts +24 -0
- package/src/cli/commands/__tests__/changelog.test.ts +304 -319
- package/src/cli/commands/__tests__/schedules.test.ts +491 -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 +329 -317
- package/src/cli/commands/plugins.ts +185 -0
- package/src/cli/commands/schedules.ts +391 -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__/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 +304 -0
- package/src/cli/lib/list-installed-plugins.ts +137 -0
- package/src/cli/lib/uninstall-plugin.ts +82 -0
- package/src/cli/lib/unknown-command.ts +111 -0
- package/src/cli/program.ts +38 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +23 -21
- 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/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/feature-flag-registry.json +41 -1
- package/src/config/loader.ts +64 -38
- package/src/config/schema.ts +7 -10
- package/src/config/schemas/__tests__/llm-request-logs.test.ts +36 -0
- package/src/config/schemas/channels.ts +8 -0
- package/src/config/schemas/compaction.ts +28 -0
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm-request-logs.ts +31 -7
- package/src/config/schemas/llm.ts +3 -0
- package/src/config/schemas/memory-retrieval.ts +18 -0
- package/src/config/schemas/tools.ts +14 -0
- package/src/config/skills.ts +3 -96
- package/src/context/compactor.ts +1047 -0
- package/src/context/token-estimator.ts +2 -2
- 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 +34 -0
- 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.ts +169 -9
- 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 +16 -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 -1
- package/src/daemon/external-plugins-bootstrap.ts +217 -181
- package/src/daemon/first-greeting.ts +22 -2
- package/src/daemon/handlers/config-model.ts +6 -5
- package/src/daemon/handlers/config-slack-channel.ts +15 -3
- 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 +98 -23
- package/src/daemon/lifecycle.ts +45 -35
- package/src/daemon/meet-host-supervisor.ts +5 -4
- package/src/daemon/memory-v2-startup.ts +49 -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/subagents.ts +1 -0
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/pkb-reminder-builder.test.ts +1 -1
- package/src/daemon/pkb-reminder-builder.ts +1 -1
- package/src/daemon/plugin-source-watcher.ts +146 -0
- package/src/daemon/process-message.ts +21 -3
- package/src/daemon/server.ts +11 -2
- package/src/daemon/skill-memory-refresh.ts +29 -0
- package/src/documents/document-store.ts +221 -3
- package/src/embedded/plugin-api.ts +40 -0
- package/src/filing/filing-service.ts +39 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +91 -6
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +41 -0
- package/src/home/__tests__/feed-types.test.ts +40 -0
- package/src/home/feed-types.ts +22 -0
- package/src/home/post-connect-feed.ts +1 -0
- package/src/index.ts +18 -1
- 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 +263 -0
- package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +113 -0
- 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 +110 -10
- package/src/memory/db-init.ts +6 -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 +66 -9
- package/src/memory/graph/conversation-graph-memory.ts +31 -15
- package/src/memory/graph/tools.ts +3 -3
- package/src/memory/indexer.ts +34 -29
- 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 +17 -10
- package/src/memory/llm-request-log-source.ts +19 -52
- package/src/memory/llm-usage-store.ts +125 -5
- 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/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/onboarding-events-store.ts +106 -0
- package/src/memory/schema/bookmarks.ts +0 -2
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/inference.ts +1 -3
- package/src/memory/schema/infrastructure.ts +12 -0
- package/src/memory/turn-events-store.ts +127 -2
- package/src/memory/v2/__tests__/activation.test.ts +0 -8
- package/src/memory/v2/__tests__/injection.test.ts +98 -8
- 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/injection.ts +32 -6
- package/src/memory/v2/migration.ts +49 -19
- package/src/memory/v2/page-index.ts +35 -5
- 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/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/conversation-pairing.ts +2 -1
- package/src/notifications/decision-engine.ts +2 -1
- package/src/notifications/emit-signal.ts +20 -1
- package/src/notifications/home-feed-side-effect.ts +54 -0
- package/src/notifications/signal.ts +3 -1
- package/src/oauth/connection-resolver.ts +8 -4
- package/src/oauth/platform-connection.ts +6 -2
- 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 +36 -3
- 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 +105 -32
- 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 +31 -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 +12 -0
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +99 -0
- package/src/prompts/normalize-onboarding.ts +27 -0
- package/src/prompts/sections.ts +302 -0
- package/src/prompts/system-prompt.ts +63 -166
- package/src/prompts/templates/BOOTSTRAP.md +17 -1
- package/src/prompts/templates/system-sections.ts +173 -0
- package/src/providers/__tests__/inference.test.ts +22 -7
- package/src/providers/anthropic/client.ts +28 -28
- package/src/providers/connection-resolution.ts +7 -0
- package/src/providers/inference/adapter-factory.ts +41 -4
- package/src/providers/inference/connections.ts +74 -29
- package/src/providers/inference/resolve-auth.ts +12 -4
- package/src/providers/model-catalog.ts +294 -12
- package/src/providers/openai/chat-completions-provider.ts +10 -2
- package/src/providers/openrouter/client.ts +7 -0
- package/src/providers/{managed-proxy → platform-proxy}/constants.ts +4 -1
- 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 +36 -0
- package/src/providers/registry.ts +22 -14
- package/src/providers/retry.ts +47 -1
- package/src/runtime/__tests__/agent-wake.test.ts +152 -0
- package/src/runtime/agent-wake.ts +42 -14
- package/src/runtime/auth/route-policy.ts +8 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/http-types.ts +19 -0
- 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__/conversation-management-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +107 -20
- 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 +121 -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 +40 -35
- package/src/runtime/routes/conversation-routes.ts +90 -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 +6 -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 +65 -21
- 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/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 +57 -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 +15 -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/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 +72 -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/registry.ts +8 -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/context/__tests__/compact-prompt.test.ts +0 -63
- package/src/context/prompts/compact.md +0 -26
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +0 -37
- /package/src/__tests__/{secret-routes-managed-proxy.test.ts → secret-routes-platform-proxy.test.ts} +0 -0
|
@@ -15,7 +15,7 @@ let mockAssistantId = "";
|
|
|
15
15
|
// Module mocks
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
17
|
|
|
18
|
-
mock.module("../providers/
|
|
18
|
+
mock.module("../providers/platform-proxy/context.js", () => ({
|
|
19
19
|
resolveManagedProxyContext: async () => mockManagedProxyCtx,
|
|
20
20
|
}));
|
|
21
21
|
|
package/src/platform/client.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { getPlatformAssistantId } from "../config/env.js";
|
|
9
|
-
import { resolveManagedProxyContext } from "../providers/
|
|
9
|
+
import { resolveManagedProxyContext } from "../providers/platform-proxy/context.js";
|
|
10
10
|
import { credentialKey } from "../security/credential-key.js";
|
|
11
11
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
12
12
|
import { getLogger } from "../util/logger.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public hook-name constants.
|
|
3
|
+
*
|
|
4
|
+
* Plugin authors reference hooks by name in two places: the keys on
|
|
5
|
+
* `Plugin.hooks` and the daemon's `runHook(name, ctx)` call sites.
|
|
6
|
+
* Centralizing the string literals here keeps the typo surface minimal
|
|
7
|
+
* and lets call sites import a typed constant instead of repeating a
|
|
8
|
+
* free-form string.
|
|
9
|
+
*
|
|
10
|
+
* New hooks land here as additional `HOOKS.*` entries. The runtime
|
|
11
|
+
* `runHook(name, ctx)` accepts any string (so test fixtures and
|
|
12
|
+
* forward-compat hooks can still chain through), but call sites in
|
|
13
|
+
* first-party code should always reach for a `HOOKS.*` constant.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const HOOKS = {
|
|
17
|
+
/** Plugin bootstrap. Fires once when the daemon loads the plugin. */
|
|
18
|
+
INIT: "init",
|
|
19
|
+
/** Plugin teardown. Fires once when the daemon unloads the plugin. */
|
|
20
|
+
SHUTDOWN: "shutdown",
|
|
21
|
+
/** Fires once per user turn, immediately before the agent loop receives `runMessages`. */
|
|
22
|
+
USER_PROMPT_SUBMIT: "user-prompt-submit",
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
/** Union of every hook name declared in {@link HOOKS}. */
|
|
26
|
+
export type HookName = (typeof HOOKS)[keyof typeof HOOKS];
|
package/src/plugin-api/index.ts
CHANGED
|
@@ -8,6 +8,39 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Keep this file's surface stable across minor/patch releases. Anything
|
|
10
10
|
* exported here is part of the public contract.
|
|
11
|
+
*
|
|
12
|
+
* ## Surface today
|
|
13
|
+
*
|
|
14
|
+
* The public package is intentionally **declarative**: a plugin is a
|
|
15
|
+
* directory whose `package.json` is the manifest and whose `hooks/` /
|
|
16
|
+
* `tools/` / `skills/` / `routes/` subdirectories are the contributions.
|
|
17
|
+
* The host introspects the directory at load time and wires it into the
|
|
18
|
+
* runtime — plugin authors never call a runtime registration function.
|
|
19
|
+
*
|
|
20
|
+
* What this module exposes is therefore types-only: the context shapes
|
|
21
|
+
* the host hands to plugin hooks, and the logger shape they include.
|
|
22
|
+
*
|
|
23
|
+
* - {@link PluginInitContext} — passed to `init` hook at bootstrap
|
|
24
|
+
* - {@link PluginShutdownContext} — passed to `shutdown` hook at teardown
|
|
25
|
+
* - {@link UserPromptSubmitContext} — passed to `user-prompt-submit` hook,
|
|
26
|
+
* fired immediately before the agent loop receives a user's prompt
|
|
27
|
+
* - {@link PluginLogger} — pino-compatible logger shape on the contexts
|
|
28
|
+
* - {@link ToolContext} — passed to a plugin tool's `execute` method
|
|
29
|
+
* - {@link ToolExecutionResult} — return shape of a plugin tool's `execute`
|
|
30
|
+
*
|
|
31
|
+
* Pipeline-argument types (`LLMCallArgs`, `MemoryArgs`, etc.) currently
|
|
32
|
+
* live in `assistant/src/plugins/types.ts` and have not yet migrated into
|
|
33
|
+
* this package. A follow-up PR will move them into this surface as the
|
|
34
|
+
* per-pipeline schemas stabilize.
|
|
11
35
|
*/
|
|
12
36
|
|
|
13
|
-
export type {
|
|
37
|
+
export type { HookName } from "./constants.js";
|
|
38
|
+
export { HOOKS } from "./constants.js";
|
|
39
|
+
export type {
|
|
40
|
+
PluginInitContext,
|
|
41
|
+
PluginLogger,
|
|
42
|
+
PluginShutdownContext,
|
|
43
|
+
ToolContext,
|
|
44
|
+
ToolExecutionResult,
|
|
45
|
+
UserPromptSubmitContext,
|
|
46
|
+
} from "./types.js";
|
package/src/plugin-api/types.ts
CHANGED
|
@@ -1,21 +1,64 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Public plugin-API types.
|
|
3
3
|
*
|
|
4
|
-
* This module is the
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
4
|
+
* This module is the entry point plugin authors land on when they import
|
|
5
|
+
* from `@vellumai/plugin-api`. The shapes here are the canonical public
|
|
6
|
+
* contract — anything exported is part of the surface that semver gates.
|
|
7
|
+
*
|
|
8
|
+
* ## Tool-execution types
|
|
9
|
+
*
|
|
10
|
+
* `ToolContext` and `ToolExecutionResult` are re-exports of the narrow,
|
|
11
|
+
* stable bases defined alongside their daemon-internal counterparts in
|
|
12
|
+
* `assistant/src/tools/types.ts`. The daemon-internal `ToolContext` /
|
|
13
|
+
* `ToolExecutionResult` (with CES, trust classification, lifecycle
|
|
14
|
+
* events, sensitive-output bindings, risk metadata, etc.) `extends`
|
|
15
|
+
* the public bases, so the runtime can hand plugins the full value
|
|
16
|
+
* without a manual cast and tsc enforces the structural relationship.
|
|
17
|
+
* Plugin tools see the narrow surface only — they MUST NOT set fields
|
|
18
|
+
* that belong to the daemon-internal extension.
|
|
19
|
+
*
|
|
20
|
+
* ## Hook contexts
|
|
21
|
+
*
|
|
22
|
+
* The init / shutdown hook contexts are owned by this module directly.
|
|
23
|
+
* They have no daemon-internal extension today (the daemon constructs
|
|
24
|
+
* and hands them straight through), so there's nothing to inherit from.
|
|
25
|
+
*
|
|
26
|
+
* ## Compatibility
|
|
27
|
+
*
|
|
28
|
+
* Adding fields to any public shape is non-breaking. Renaming or
|
|
29
|
+
* removing fields is breaking and gated on a major bump of
|
|
30
|
+
* `@vellumai/plugin-api`.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type { Message } from "../providers/types.js";
|
|
34
|
+
|
|
35
|
+
// ─── Tool-execution types (re-exported from daemon source-of-truth) ──────────
|
|
36
|
+
|
|
37
|
+
export type {
|
|
38
|
+
PluginToolContext as ToolContext,
|
|
39
|
+
PluginToolExecutionResult as ToolExecutionResult,
|
|
40
|
+
} from "../tools/types.js";
|
|
41
|
+
|
|
42
|
+
// ─── Logger ──────────────────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Minimal pino-compatible logger surface handed to plugin hooks. The host
|
|
46
|
+
* supplies a pino child logger bound to `{ plugin: <name> }`; this
|
|
47
|
+
* interface intentionally captures only the two call shapes plugin code
|
|
48
|
+
* needs (structured object + optional message), so the public surface
|
|
49
|
+
* doesn't take a dependency on pino's full type machinery.
|
|
50
|
+
*
|
|
51
|
+
* Each method accepts a structured-fields object followed by an optional
|
|
52
|
+
* message string. Plugin authors that need pino's wider API (`child()`,
|
|
53
|
+
* `level`, etc.) can cast to their own narrower interface in plugin code
|
|
54
|
+
* — but the canonical contract here covers the 99% case.
|
|
18
55
|
*/
|
|
56
|
+
export interface PluginLogger {
|
|
57
|
+
info(obj: Record<string, unknown>, msg?: string): void;
|
|
58
|
+
warn(obj: Record<string, unknown>, msg?: string): void;
|
|
59
|
+
error(obj: Record<string, unknown>, msg?: string): void;
|
|
60
|
+
debug(obj: Record<string, unknown>, msg?: string): void;
|
|
61
|
+
}
|
|
19
62
|
|
|
20
63
|
// ─── Init context ────────────────────────────────────────────────────────────
|
|
21
64
|
|
|
@@ -29,17 +72,17 @@ export interface PluginInitContext {
|
|
|
29
72
|
config: unknown;
|
|
30
73
|
/** Resolved credential values keyed by the entries of `manifest.requiresCredential`. */
|
|
31
74
|
credentials: Record<string, string>;
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
* to avoid pulling pino into the types module.
|
|
35
|
-
*/
|
|
36
|
-
logger: unknown;
|
|
75
|
+
/** Pino-compatible child logger bound to `{ plugin: <name> }`. */
|
|
76
|
+
logger: PluginLogger;
|
|
37
77
|
/** Absolute path to `<workspaceDir>/plugins-data/<plugin>/` (created by bootstrap). */
|
|
38
78
|
pluginStorageDir: string;
|
|
39
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* Assistant semver. Plugins can compare against this for defensive
|
|
81
|
+
* runtime checks — but the canonical compat contract is the host
|
|
82
|
+
* version against the plugin's `peerDependencies["@vellumai/plugin-api"]`
|
|
83
|
+
* semver range, enforced at load time by the external-plugin loader.
|
|
84
|
+
*/
|
|
40
85
|
assistantVersion: string;
|
|
41
|
-
/** Capability → version-list map (`ASSISTANT_API_VERSIONS`) for defensive runtime checks. */
|
|
42
|
-
apiVersions: Record<string, string[]>;
|
|
43
86
|
}
|
|
44
87
|
|
|
45
88
|
// ─── Shutdown context ────────────────────────────────────────────────────────
|
|
@@ -60,3 +103,42 @@ export interface PluginShutdownContext {
|
|
|
60
103
|
/** Assistant semver for compatibility checks inside the plugin. */
|
|
61
104
|
assistantVersion: string;
|
|
62
105
|
}
|
|
106
|
+
|
|
107
|
+
// ─── User-prompt-submit hook context ─────────────────────────────────────────
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Context passed to the `user-prompt-submit` hook. Fires once per user
|
|
111
|
+
* turn, after the agent loop has prepared the message list (PKB / NOW /
|
|
112
|
+
* memory-graph injections, history repair, overflow reduction all already
|
|
113
|
+
* applied) and immediately before the messages are handed to the agent
|
|
114
|
+
* loop's tool/LLM iteration.
|
|
115
|
+
*
|
|
116
|
+
* The hook may transform `latestMessages` either by mutating it in place
|
|
117
|
+
* (`push` / `splice` / `length = 0`) or by returning a new context with
|
|
118
|
+
* a fresh `latestMessages` array — see {@link PluginHookFn}'s polymorphic
|
|
119
|
+
* return shape. The daemon threads the final `latestMessages` value into
|
|
120
|
+
* `agentLoop.run()` as the run-messages argument.
|
|
121
|
+
*
|
|
122
|
+
* `originalMessages` is the user's original message list, frozen for the
|
|
123
|
+
* hook. Plugins should treat it as a stable reference point if they need
|
|
124
|
+
* to recover from earlier transformations or compare against the pristine
|
|
125
|
+
* state.
|
|
126
|
+
*
|
|
127
|
+
* Multiple plugins' hooks chain in registration order — each plugin's
|
|
128
|
+
* hook sees the previous plugin's mutations (whether by reassignment or
|
|
129
|
+
* in-place mutation).
|
|
130
|
+
*/
|
|
131
|
+
export interface UserPromptSubmitContext {
|
|
132
|
+
/** Conversation ID the user prompt was submitted on. */
|
|
133
|
+
readonly conversationId: string;
|
|
134
|
+
/**
|
|
135
|
+
* The user's original message list, immutable for the hook. Plugins
|
|
136
|
+
* may snapshot or compare against this but MUST NOT mutate it.
|
|
137
|
+
*/
|
|
138
|
+
readonly originalMessages: ReadonlyArray<Message>;
|
|
139
|
+
/**
|
|
140
|
+
* The working message list that flows into `agentLoop.run`. Plugins
|
|
141
|
+
* may mutate this in place or replace it by returning a new context.
|
|
142
|
+
*/
|
|
143
|
+
latestMessages: Message[];
|
|
144
|
+
}
|
|
@@ -55,11 +55,6 @@ export const defaultCircuitBreakerPlugin: Plugin = {
|
|
|
55
55
|
manifest: {
|
|
56
56
|
name: "default-circuit-breaker",
|
|
57
57
|
version: "1.0.0",
|
|
58
|
-
provides: { circuitBreakerApi: "v1" },
|
|
59
|
-
requires: {
|
|
60
|
-
pluginRuntime: "v1",
|
|
61
|
-
circuitBreakerApi: "v1",
|
|
62
|
-
},
|
|
63
58
|
},
|
|
64
59
|
|
|
65
60
|
middleware: {
|
|
@@ -112,10 +112,6 @@ export const defaultCompactionPlugin: Plugin = {
|
|
|
112
112
|
manifest: {
|
|
113
113
|
name: DEFAULT_COMPACTION_PLUGIN_NAME,
|
|
114
114
|
version: "1.0.0",
|
|
115
|
-
requires: {
|
|
116
|
-
pluginRuntime: "v1",
|
|
117
|
-
compactionApi: "v1",
|
|
118
|
-
},
|
|
119
115
|
},
|
|
120
116
|
middleware: {
|
|
121
117
|
compaction: defaultCompactionMiddleware,
|
|
@@ -95,8 +95,6 @@ export const defaultEmptyResponsePlugin: Plugin = {
|
|
|
95
95
|
manifest: {
|
|
96
96
|
name: "default-empty-response",
|
|
97
97
|
version: "1.0.0",
|
|
98
|
-
provides: { emptyResponseApi: "v1" },
|
|
99
|
-
requires: { pluginRuntime: "v1", emptyResponseApi: "v1" },
|
|
100
98
|
},
|
|
101
99
|
middleware: {
|
|
102
100
|
emptyResponse: passthrough,
|
|
@@ -54,8 +54,6 @@ export const defaultHistoryRepairPlugin: Plugin = {
|
|
|
54
54
|
manifest: {
|
|
55
55
|
name: "default-history-repair",
|
|
56
56
|
version: "1.0.0",
|
|
57
|
-
provides: { historyRepair: "v1" },
|
|
58
|
-
requires: { pluginRuntime: "v1", historyRepairApi: "v1" },
|
|
59
57
|
},
|
|
60
58
|
middleware: {
|
|
61
59
|
historyRepair: passthrough,
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* | `pkb-reminder` | 35 | after-memory-prefix |
|
|
20
20
|
* | `memory-v2-static` | 38 | after-memory-prefix |
|
|
21
21
|
* | `now-md` | 40 | after-memory-prefix |
|
|
22
|
+
* | `active-documents` | 45 | prepend-user-tail |
|
|
22
23
|
* | `subagent-status` | 50 | append-user-tail |
|
|
23
24
|
* | `slack-messages` | 60 | replace-run-messages |
|
|
24
25
|
* | `thread-focus` | 70 | append-user-tail |
|
|
@@ -91,6 +92,7 @@ export const DEFAULT_INJECTOR_ORDER = {
|
|
|
91
92
|
pkbReminder: 35,
|
|
92
93
|
memoryV2Static: 38,
|
|
93
94
|
nowMd: 40,
|
|
95
|
+
activeDocuments: 45,
|
|
94
96
|
subagentStatus: 50,
|
|
95
97
|
slackMessages: 60,
|
|
96
98
|
threadFocus: 70,
|
|
@@ -438,6 +440,39 @@ const nowMdInjector: Injector = {
|
|
|
438
440
|
},
|
|
439
441
|
};
|
|
440
442
|
|
|
443
|
+
/**
|
|
444
|
+
* `active-documents` injector — order 45, prepend-user-tail.
|
|
445
|
+
*
|
|
446
|
+
* Injects an `<active_documents>` block listing open documents in the
|
|
447
|
+
* conversation so the assistant can target them with `document_update`
|
|
448
|
+
* instead of creating duplicates via `document_create`.
|
|
449
|
+
*
|
|
450
|
+
* Gating:
|
|
451
|
+
* - `mode === "full"`.
|
|
452
|
+
* - `activeDocuments` has at least one entry.
|
|
453
|
+
*/
|
|
454
|
+
const activeDocumentsInjector: Injector = {
|
|
455
|
+
name: "active-documents",
|
|
456
|
+
order: DEFAULT_INJECTOR_ORDER.activeDocuments,
|
|
457
|
+
async produce(ctx: TurnContext): Promise<InjectionBlock | null> {
|
|
458
|
+
const inputs = readInjectionInputs(ctx);
|
|
459
|
+
const mode = inputs.mode ?? "full";
|
|
460
|
+
if (mode !== "full") return null;
|
|
461
|
+
const docs = inputs.activeDocuments;
|
|
462
|
+
if (!docs || docs.length === 0) return null;
|
|
463
|
+
const lines = docs.map(
|
|
464
|
+
(d) =>
|
|
465
|
+
`- surface_id: "${d.surfaceId}", title: "${d.title}", words: ${d.wordCount}`,
|
|
466
|
+
);
|
|
467
|
+
const text = `<active_documents>\nThe following documents are open in this conversation. Use document_update with the surface_id to edit them — do NOT call document_create for documents that already exist.\n${lines.join("\n")}\n</active_documents>`;
|
|
468
|
+
return {
|
|
469
|
+
id: "active-documents",
|
|
470
|
+
text,
|
|
471
|
+
placement: "prepend-user-tail",
|
|
472
|
+
};
|
|
473
|
+
},
|
|
474
|
+
};
|
|
475
|
+
|
|
441
476
|
/**
|
|
442
477
|
* `subagent-status` injector — order 50, append-user-tail.
|
|
443
478
|
*
|
|
@@ -562,9 +597,6 @@ export const defaultInjectorsPlugin: Plugin = {
|
|
|
562
597
|
manifest: {
|
|
563
598
|
name: "default-injectors",
|
|
564
599
|
version: "1.0.0",
|
|
565
|
-
requires: {
|
|
566
|
-
pluginRuntime: "v1",
|
|
567
|
-
},
|
|
568
600
|
},
|
|
569
601
|
injectors: [
|
|
570
602
|
diskPressureWarningInjector,
|
|
@@ -574,6 +606,7 @@ export const defaultInjectorsPlugin: Plugin = {
|
|
|
574
606
|
pkbReminderInjector,
|
|
575
607
|
memoryV2StaticInjector,
|
|
576
608
|
nowMdInjector,
|
|
609
|
+
activeDocumentsInjector,
|
|
577
610
|
subagentStatusInjector,
|
|
578
611
|
slackMessagesInjector,
|
|
579
612
|
threadFocusInjector,
|
|
@@ -190,7 +190,6 @@ export const defaultMemoryRetrievalPlugin: Plugin = {
|
|
|
190
190
|
manifest: {
|
|
191
191
|
name: "default-memory-retrieval",
|
|
192
192
|
version: "0.0.1",
|
|
193
|
-
requires: { pluginRuntime: "v1", memoryApi: "v1" },
|
|
194
193
|
},
|
|
195
194
|
middleware: {
|
|
196
195
|
memoryRetrieval: defaultMemoryRetrievalMiddleware,
|
|
@@ -156,7 +156,6 @@ export const defaultOverflowReducePlugin: Plugin = {
|
|
|
156
156
|
manifest: {
|
|
157
157
|
name: "default-overflow-reduce",
|
|
158
158
|
version: "1.0.0",
|
|
159
|
-
requires: { pluginRuntime: "v1", overflowReduceApi: "v1" },
|
|
160
159
|
},
|
|
161
160
|
middleware: {
|
|
162
161
|
overflowReduce: defaultOverflowReduceMiddleware,
|
|
@@ -72,8 +72,6 @@ export const defaultTokenEstimatePlugin: Plugin = {
|
|
|
72
72
|
manifest: {
|
|
73
73
|
name: "default-token-estimate",
|
|
74
74
|
version: "1.0.0",
|
|
75
|
-
provides: { tokenEstimate: "v1" },
|
|
76
|
-
requires: { pluginRuntime: "v1", tokenEstimateApi: "v1" },
|
|
77
75
|
},
|
|
78
76
|
middleware: {
|
|
79
77
|
tokenEstimate: passthrough,
|
|
@@ -90,13 +90,6 @@ export const defaultToolErrorPlugin: Plugin = {
|
|
|
90
90
|
manifest: {
|
|
91
91
|
name: "default-tool-error",
|
|
92
92
|
version: "1.0.0",
|
|
93
|
-
requires: {
|
|
94
|
-
pluginRuntime: "v1",
|
|
95
|
-
toolErrorApi: "v1",
|
|
96
|
-
},
|
|
97
|
-
provides: {
|
|
98
|
-
toolError: "v1",
|
|
99
|
-
},
|
|
100
93
|
},
|
|
101
94
|
middleware: {
|
|
102
95
|
toolError: defaultToolErrorMiddleware,
|
|
@@ -58,8 +58,6 @@ export const defaultToolExecutePlugin: Plugin = {
|
|
|
58
58
|
manifest: {
|
|
59
59
|
name: "default-tool-execute",
|
|
60
60
|
version: "1.0.0",
|
|
61
|
-
provides: { toolExecuteApi: "v1" },
|
|
62
|
-
requires: { pluginRuntime: "v1", toolExecuteApi: "v1" },
|
|
63
61
|
},
|
|
64
62
|
middleware: {
|
|
65
63
|
toolExecute: defaultToolExecute,
|
|
@@ -55,10 +55,6 @@ export const defaultToolResultTruncatePlugin: Plugin = {
|
|
|
55
55
|
manifest: {
|
|
56
56
|
name: "default-tool-result-truncate",
|
|
57
57
|
version: "1.0.0",
|
|
58
|
-
requires: {
|
|
59
|
-
pluginRuntime: "v1",
|
|
60
|
-
toolResultTruncateApi: "v1",
|
|
61
|
-
},
|
|
62
58
|
},
|
|
63
59
|
middleware: {
|
|
64
60
|
toolResultTruncate: passthrough,
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Materializes the workspace-level `@vellumai/plugin-api` shim so that
|
|
3
|
+
* user plugins under `<workspaceDir>/plugins/<name>/` can resolve a
|
|
4
|
+
* standard bare import:
|
|
5
|
+
*
|
|
6
|
+
* import { ... } from "@vellumai/plugin-api";
|
|
7
|
+
*
|
|
8
|
+
* Bun's Node-style resolution walks up from the plugin directory and
|
|
9
|
+
* finds `<workspaceDir>/node_modules/@vellumai/plugin-api/` — a tiny
|
|
10
|
+
* shim package whose `index.js` re-binds the plugin-api namespace that
|
|
11
|
+
* the assistant already loaded into its module graph (and parked on
|
|
12
|
+
* `globalThis` under {@link PLUGIN_API_REGISTRY_KEY}).
|
|
13
|
+
*
|
|
14
|
+
* This avoids duplicating the plugin-api package per plugin while still
|
|
15
|
+
* letting the assistant's compiled binary be the single source of truth
|
|
16
|
+
* for the public API. The runtime mechanism is uniform across:
|
|
17
|
+
* - JIT / Docker: plugin-api loads from source, shim re-binds via globalThis
|
|
18
|
+
* - `bun --compile` (macOS bare-metal): plugin-api ships inside the
|
|
19
|
+
* binary's regular code graph (Bun's bundler resolves
|
|
20
|
+
* `import * as pluginApi from "../plugin-api/index.js"` at compile
|
|
21
|
+
* time, inlining relative imports), shim re-binds via globalThis
|
|
22
|
+
*
|
|
23
|
+
* Idempotent: safe to call repeatedly. The shim's contents are
|
|
24
|
+
* deterministic given the runtime export list — fresh exports (added in
|
|
25
|
+
* later PRs) automatically expand the generated `index.js`.
|
|
26
|
+
*
|
|
27
|
+
* Called from {@link loadUserPlugins} at the top of its body so the
|
|
28
|
+
* ordering constraint (shim exists before any plugin's
|
|
29
|
+
* `import "@vellumai/plugin-api"` is parsed) is enforced by code, not
|
|
30
|
+
* by a docstring in `lifecycle.ts`.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
34
|
+
import { join } from "node:path";
|
|
35
|
+
|
|
36
|
+
import assistantPkg from "../../package.json" with { type: "json" };
|
|
37
|
+
import {
|
|
38
|
+
PLUGIN_API_EXPORTS,
|
|
39
|
+
PLUGIN_API_REGISTRY_KEY,
|
|
40
|
+
} from "../embedded/plugin-api.js";
|
|
41
|
+
import { getLogger } from "../util/logger.js";
|
|
42
|
+
import { getWorkspaceDir } from "../util/platform.js";
|
|
43
|
+
|
|
44
|
+
const log = getLogger("plugin-api-shim");
|
|
45
|
+
|
|
46
|
+
const PACKAGE_NAME = "@vellumai/plugin-api";
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Build the body of the workspace shim's `index.js`. Exported so the
|
|
50
|
+
* smoke test can assert against the same generator the daemon uses.
|
|
51
|
+
*/
|
|
52
|
+
export function buildShimSource(
|
|
53
|
+
exports: readonly string[] = PLUGIN_API_EXPORTS,
|
|
54
|
+
registryKey: symbol = PLUGIN_API_REGISTRY_KEY,
|
|
55
|
+
): string {
|
|
56
|
+
const description = registryKey.description ?? "";
|
|
57
|
+
const lines = [
|
|
58
|
+
`const api = globalThis[Symbol.for(${JSON.stringify(description)})];`,
|
|
59
|
+
...exports.map((name) => `export const ${name} = api.${name};`),
|
|
60
|
+
];
|
|
61
|
+
return `${lines.join("\n")}\n`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function ensurePluginApiShim(opts?: {
|
|
65
|
+
/** Override the workspace root. Defaults to `getWorkspaceDir()`. */
|
|
66
|
+
workspaceDir?: string;
|
|
67
|
+
}): Promise<void> {
|
|
68
|
+
const workspaceDir = opts?.workspaceDir ?? getWorkspaceDir();
|
|
69
|
+
const shimDir = join(workspaceDir, "node_modules", PACKAGE_NAME);
|
|
70
|
+
|
|
71
|
+
await mkdir(shimDir, { recursive: true });
|
|
72
|
+
|
|
73
|
+
const indexJs = buildShimSource();
|
|
74
|
+
const packageJson = `${JSON.stringify(
|
|
75
|
+
{
|
|
76
|
+
name: PACKAGE_NAME,
|
|
77
|
+
version: assistantPkg.version,
|
|
78
|
+
type: "module",
|
|
79
|
+
main: "./index.js",
|
|
80
|
+
},
|
|
81
|
+
null,
|
|
82
|
+
2,
|
|
83
|
+
)}\n`;
|
|
84
|
+
|
|
85
|
+
await writeFile(join(shimDir, "index.js"), indexJs);
|
|
86
|
+
await writeFile(join(shimDir, "package.json"), packageJson);
|
|
87
|
+
|
|
88
|
+
log.info(
|
|
89
|
+
{
|
|
90
|
+
shimDir,
|
|
91
|
+
exports: PLUGIN_API_EXPORTS,
|
|
92
|
+
version: assistantPkg.version,
|
|
93
|
+
},
|
|
94
|
+
"plugin-api shim materialized",
|
|
95
|
+
);
|
|
96
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External plugin runtime — `globalThis.__vellumPluginRuntime` bridge.
|
|
3
|
+
*
|
|
4
|
+
* Workspace-local plugins (`<workspaceDir>/plugins/*`) get dynamic-imported by
|
|
5
|
+
* {@link loadUserPlugins}. They need to call `registerPlugin()` from their
|
|
6
|
+
* module body and they typically also want to read secrets, subscribe to
|
|
7
|
+
* runtime events, etc.
|
|
8
|
+
*
|
|
9
|
+
* Importing those symbols by absolute path
|
|
10
|
+
* (`/abs/path/to/assistant/src/plugins/registry.js`) works when the daemon is
|
|
11
|
+
* running from source — both the daemon and the dynamic-imported plugin
|
|
12
|
+
* resolve the same on-disk file and share module identity. It DOES NOT work
|
|
13
|
+
* when the daemon is a `bun --compile` binary: the daemon's modules are baked
|
|
14
|
+
* into the executable, and any absolute-path import re-loads a fresh disk
|
|
15
|
+
* copy. `registerPlugin()` then writes into a disjoint registry instance and
|
|
16
|
+
* the daemon never sees the plugin.
|
|
17
|
+
*
|
|
18
|
+
* The fix is to expose a single, stable handle on `globalThis` that plugins
|
|
19
|
+
* read at module-load time. The daemon's bundled modules attach themselves
|
|
20
|
+
* here once at startup; plugins consume the same instance regardless of how
|
|
21
|
+
* the daemon was built.
|
|
22
|
+
*
|
|
23
|
+
* Plugins use the bridge like this:
|
|
24
|
+
*
|
|
25
|
+
* const runtime = (globalThis as { __vellumPluginRuntime?: ... })
|
|
26
|
+
* .__vellumPluginRuntime;
|
|
27
|
+
* if (!runtime || runtime.version !== 1) throw new Error("...");
|
|
28
|
+
* const { registerPlugin, assistantEventHub, getSecureKeyAsync } = runtime;
|
|
29
|
+
*
|
|
30
|
+
* Type-only imports (`import type { Plugin } from "..."`) remain free to use
|
|
31
|
+
* absolute paths or workspace-local copies — the TypeScript compiler erases
|
|
32
|
+
* them and they have no module-identity effect at runtime.
|
|
33
|
+
*
|
|
34
|
+
* See `assistant/docs/plugins.md` for the full authoring contract and
|
|
35
|
+
* `assistant/examples/plugins/echo/register.ts` for a worked example.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
39
|
+
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
40
|
+
import { registerPlugin } from "./registry.js";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The handle plugins read from `globalThis.__vellumPluginRuntime`.
|
|
44
|
+
*
|
|
45
|
+
* `version` is the contract version. Plugins should assert against the
|
|
46
|
+
* version they were authored against and refuse to register if they see a
|
|
47
|
+
* different one — bumping it is a breaking change to the plugin surface.
|
|
48
|
+
*
|
|
49
|
+
* The field set is intentionally small: the most-commonly-needed symbols
|
|
50
|
+
* across both static (module-load-time) and dynamic (init-time) plugin
|
|
51
|
+
* lifecycle. Plugins that need richer runtime state can still receive it
|
|
52
|
+
* through {@link PluginInitContext} during `init()`.
|
|
53
|
+
*/
|
|
54
|
+
export interface VellumPluginRuntime {
|
|
55
|
+
readonly version: 1;
|
|
56
|
+
readonly registerPlugin: typeof registerPlugin;
|
|
57
|
+
readonly assistantEventHub: typeof assistantEventHub;
|
|
58
|
+
readonly getSecureKeyAsync: typeof getSecureKeyAsync;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Stable globalThis key. Don't rename — plugins reference it by string. */
|
|
62
|
+
const RUNTIME_GLOBAL_KEY = "__vellumPluginRuntime" as const;
|
|
63
|
+
|
|
64
|
+
interface GlobalWithRuntime {
|
|
65
|
+
[RUNTIME_GLOBAL_KEY]?: VellumPluginRuntime;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Install the plugin runtime bridge on `globalThis`. Idempotent — repeat
|
|
70
|
+
* calls are no-ops, so it's safe to invoke from tests that also touch the
|
|
71
|
+
* lifecycle path.
|
|
72
|
+
*
|
|
73
|
+
* Must be called BEFORE {@link loadUserPlugins} runs, otherwise plugins that
|
|
74
|
+
* touch `globalThis.__vellumPluginRuntime` in their module body will throw.
|
|
75
|
+
*/
|
|
76
|
+
export function installPluginRuntime(): void {
|
|
77
|
+
const g = globalThis as GlobalWithRuntime;
|
|
78
|
+
if (g[RUNTIME_GLOBAL_KEY]) return;
|
|
79
|
+
g[RUNTIME_GLOBAL_KEY] = {
|
|
80
|
+
version: 1,
|
|
81
|
+
registerPlugin,
|
|
82
|
+
assistantEventHub,
|
|
83
|
+
getSecureKeyAsync,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Read the installed runtime. Returns `undefined` if {@link installPluginRuntime}
|
|
89
|
+
* hasn't been called yet — plugins should treat this as a fatal error.
|
|
90
|
+
*
|
|
91
|
+
* Exposed mainly for tests and for the rare in-process consumer that wants
|
|
92
|
+
* to read the bridge from the same module graph that installed it.
|
|
93
|
+
*/
|
|
94
|
+
export function getPluginRuntime(): VellumPluginRuntime | undefined {
|
|
95
|
+
return (globalThis as GlobalWithRuntime)[RUNTIME_GLOBAL_KEY];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Tear down the runtime handle. Test-only — production code never uninstalls
|
|
100
|
+
* because the runtime lifetime is the daemon lifetime.
|
|
101
|
+
*/
|
|
102
|
+
export function uninstallPluginRuntimeForTests(): void {
|
|
103
|
+
delete (globalThis as GlobalWithRuntime)[RUNTIME_GLOBAL_KEY];
|
|
104
|
+
}
|