@vellumai/assistant 0.6.4 → 0.6.6
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/.prettierignore +5 -0
- package/AGENTS.md +9 -1
- package/ARCHITECTURE.md +43 -49
- package/Dockerfile +17 -3
- package/README.md +3 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
- package/bun.lock +8 -3
- package/docs/architecture/integrations.md +33 -59
- package/docs/architecture/memory.md +25 -30
- package/docs/architecture/security.md +19 -18
- package/docs/browser-use-architecture-phase2.md +63 -20
- package/docs/error-handling.md +111 -0
- package/docs/plugins.md +761 -0
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +2 -1
- package/examples/plugins/echo/README.md +132 -0
- package/examples/plugins/echo/package.json +17 -0
- package/examples/plugins/echo/register.ts +187 -0
- package/knip.json +9 -2
- package/node_modules/@vellumai/ces-contracts/package.json +2 -1
- package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
- package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
- package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
- package/node_modules/@vellumai/credential-storage/package.json +2 -2
- package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
- package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
- package/node_modules/@vellumai/egress-proxy/package.json +2 -2
- package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
- package/openapi.yaml +334 -78
- package/package.json +6 -3
- package/scripts/generate-openapi.ts +50 -11
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
- package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
- package/src/__tests__/agent-loop.test.ts +112 -1
- package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
- package/src/__tests__/anthropic-provider.test.ts +171 -2
- package/src/__tests__/app-compiler.test.ts +57 -0
- package/src/__tests__/approval-cascade.test.ts +36 -10
- package/src/__tests__/approval-routes-http.test.ts +134 -10
- package/src/__tests__/assistant-attachments.test.ts +44 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +1 -0
- package/src/__tests__/avatar-generator.test.ts +4 -2
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
- package/src/__tests__/browser-skill-endstate.test.ts +51 -182
- package/src/__tests__/btw-routes.test.ts +47 -1
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/call-controller.test.ts +1 -2
- package/src/__tests__/call-site-routing-provider.test.ts +214 -0
- package/src/__tests__/catalog-cache.test.ts +96 -4
- package/src/__tests__/channel-approval-routes.test.ts +4 -4
- package/src/__tests__/channel-reply-delivery.test.ts +300 -2
- package/src/__tests__/checker.test.ts +870 -655
- package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
- package/src/__tests__/compaction-events.test.ts +501 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/config-analysis.test.ts +11 -28
- package/src/__tests__/config-loader-backfill.test.ts +174 -0
- package/src/__tests__/config-loader-corrupt.test.ts +183 -0
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
- package/src/__tests__/config-model-image-provider.test.ts +110 -0
- package/src/__tests__/config-schema-cmd.test.ts +11 -5
- package/src/__tests__/config-schema.test.ts +440 -114
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
- package/src/__tests__/config-watcher.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +72 -73
- package/src/__tests__/contacts-tools.test.ts +26 -0
- package/src/__tests__/contacts-write.test.ts +4 -4
- package/src/__tests__/context-overflow-policy.test.ts +7 -7
- package/src/__tests__/context-token-estimator.test.ts +191 -1
- package/src/__tests__/context-window-manager.test.ts +883 -4
- package/src/__tests__/conversation-abort-tool-results.test.ts +32 -15
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +86 -46
- package/src/__tests__/conversation-agent-loop.test.ts +435 -216
- package/src/__tests__/conversation-attachments.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +36 -10
- package/src/__tests__/conversation-error.test.ts +37 -6
- package/src/__tests__/conversation-history-web-search.test.ts +7 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +34 -12
- package/src/__tests__/conversation-lifecycle.test.ts +336 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
- package/src/__tests__/conversation-pairing.test.ts +174 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +32 -15
- package/src/__tests__/conversation-process-callsite.test.ts +309 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +44 -21
- package/src/__tests__/conversation-queue.test.ts +68 -38
- package/src/__tests__/conversation-routes-disk-view.test.ts +36 -7
- package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
- package/src/__tests__/conversation-runtime-assembly.test.ts +2877 -152
- package/src/__tests__/conversation-runtime-workspace.test.ts +35 -50
- package/src/__tests__/conversation-seed-composer.test.ts +2 -2
- package/src/__tests__/conversation-skill-tools.test.ts +12 -146
- package/src/__tests__/conversation-slash-queue.test.ts +39 -19
- package/src/__tests__/conversation-slash-unknown.test.ts +53 -16
- package/src/__tests__/conversation-speed-override.test.ts +36 -12
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
- package/src/__tests__/conversation-title-service.test.ts +118 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +1 -1
- package/src/__tests__/conversation-unread-route.test.ts +2 -2
- package/src/__tests__/conversation-usage.test.ts +4 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +33 -9
- package/src/__tests__/conversation-workspace-injection.test.ts +46 -15
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +46 -15
- package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
- package/src/__tests__/credential-health-service.test.ts +78 -9
- package/src/__tests__/credential-security-invariants.test.ts +5 -2
- package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
- package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
- package/src/__tests__/credential-vault-unit.test.ts +135 -19
- package/src/__tests__/credentials-cli.test.ts +1 -9
- package/src/__tests__/cross-provider-web-search.test.ts +84 -0
- package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
- package/src/__tests__/delete-propagation.test.ts +437 -0
- package/src/__tests__/dm-backfill.test.ts +417 -0
- package/src/__tests__/dm-persistence.test.ts +227 -0
- package/src/__tests__/edit-propagation.test.ts +280 -0
- package/src/__tests__/empty-response-pipeline.test.ts +305 -0
- package/src/__tests__/ephemeral-permissions.test.ts +93 -3
- package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
- package/src/__tests__/estimator-calibration.test.ts +213 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +29 -10
- package/src/__tests__/file-write-tool.test.ts +151 -1
- package/src/__tests__/filing-service.test.ts +255 -0
- package/src/__tests__/first-greeting.test.ts +247 -5
- package/src/__tests__/gemini-provider.test.ts +0 -3
- package/src/__tests__/guardian-grant-minting.test.ts +8 -0
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/headless-browser-mode.test.ts +57 -0
- package/src/__tests__/heartbeat-service.test.ts +96 -15
- package/src/__tests__/history-repair-pipeline.test.ts +399 -0
- package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
- package/src/__tests__/host-proxy-interface.test.ts +36 -2
- package/src/__tests__/host-shell-tool.test.ts +124 -18
- package/src/__tests__/http-user-message-parity.test.ts +29 -1
- package/src/__tests__/image-credentials.test.ts +137 -0
- package/src/__tests__/image-service-dispatcher.test.ts +186 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
- package/src/__tests__/injector-chain.test.ts +526 -0
- package/src/__tests__/intent-routing.test.ts +1 -66
- package/src/__tests__/llm-call-pipeline.test.ts +285 -0
- package/src/__tests__/llm-catalog-parity.test.ts +174 -0
- package/src/__tests__/llm-context-normalization.test.ts +121 -0
- package/src/__tests__/llm-resolver.test.ts +214 -0
- package/src/__tests__/llm-schema.test.ts +223 -0
- package/src/__tests__/managed-proxy-context.test.ts +6 -2
- package/src/__tests__/media-generate-image.test.ts +119 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
- package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
- package/src/__tests__/messaging-skill-split.test.ts +3 -34
- package/src/__tests__/migration-import-from-url.test.ts +621 -0
- package/src/__tests__/model-intents.test.ts +11 -83
- package/src/__tests__/notification-broadcaster.test.ts +3 -3
- package/src/__tests__/notification-decision-fallback.test.ts +0 -10
- package/src/__tests__/notification-decision-identity.test.ts +0 -9
- package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
- package/src/__tests__/notification-decision-strategy.test.ts +0 -11
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
- package/src/__tests__/oauth-apps-routes.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +14 -12
- package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
- package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
- package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
- package/src/__tests__/oauth-providers-routes.test.ts +3 -2
- package/src/__tests__/oauth-store.test.ts +46 -78
- package/src/__tests__/oauth2-gateway-transport.test.ts +8 -3
- package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
- package/src/__tests__/onboarding-template-contract.test.ts +16 -64
- package/src/__tests__/openai-image-service.test.ts +368 -0
- package/src/__tests__/openai-provider.test.ts +7 -0
- package/src/__tests__/openai-responses-provider.test.ts +396 -0
- package/src/__tests__/openrouter-provider-only.test.ts +135 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
- package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +1 -25
- package/src/__tests__/permission-mode.test.ts +16 -0
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
- package/src/__tests__/persistence-pipeline.test.ts +377 -0
- package/src/__tests__/persona-resolver.test.ts +13 -13
- package/src/__tests__/pipeline-runner.test.ts +565 -0
- package/src/__tests__/pkb-autoinject.test.ts +37 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
- package/src/__tests__/platform.test.ts +5 -2
- package/src/__tests__/plugin-bootstrap.test.ts +483 -0
- package/src/__tests__/plugin-registry.test.ts +273 -0
- package/src/__tests__/plugin-route-contribution.test.ts +288 -0
- package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
- package/src/__tests__/plugin-types.test.ts +320 -0
- package/src/__tests__/pricing.test.ts +93 -14
- package/src/__tests__/profiler-routes.test.ts +1 -1
- package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
- package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
- package/src/__tests__/provider-error-scenarios.test.ts +135 -6
- package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
- package/src/__tests__/provider-registry-ollama.test.ts +1 -2
- package/src/__tests__/proxy-approval-callback.test.ts +69 -9
- package/src/__tests__/reaction-persistence.test.ts +561 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +0 -2
- package/src/__tests__/relay-server.test.ts +1 -1
- package/src/__tests__/require-fresh-approval.test.ts +1 -1
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
- package/src/__tests__/risk-classifier-parity.test.ts +230 -0
- package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
- package/src/__tests__/schedule-routes.test.ts +131 -1
- package/src/__tests__/scheduler-recurrence.test.ts +14 -70
- package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
- package/src/__tests__/secret-detection-handler.test.ts +0 -10
- package/src/__tests__/secret-ingress-http.test.ts +28 -0
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
- package/src/__tests__/secret-scanner-executor.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +29 -1
- package/src/__tests__/server-history-render.test.ts +31 -0
- package/src/__tests__/shell-identity.test.ts +0 -134
- package/src/__tests__/shell-parser-property.test.ts +13 -13
- package/src/__tests__/skill-cache-store.test.ts +182 -0
- package/src/__tests__/skills.test.ts +19 -33
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-skill.test.ts +3 -8
- package/src/__tests__/starter-bundle.test.ts +35 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
- package/src/__tests__/suggestion-routes.test.ts +259 -3
- package/src/__tests__/system-prompt.test.ts +22 -35
- package/src/__tests__/task-memory-cleanup.test.ts +1 -0
- package/src/__tests__/task-runner.test.ts +3 -1
- package/src/__tests__/task-scheduler.test.ts +3 -15
- package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/test-preload.ts +11 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +2 -52
- package/src/__tests__/thread-backfill.test.ts +941 -0
- package/src/__tests__/title-generate-pipeline.test.ts +224 -0
- package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
- package/src/__tests__/tool-error-pipeline.test.ts +244 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -8
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
- package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
- package/src/__tests__/tool-executor.test.ts +201 -94
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -110
- package/src/__tests__/trust-store.test.ts +442 -109
- package/src/__tests__/update-bulletin-job.test.ts +389 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
- package/src/__tests__/user-plugin-loader.test.ts +191 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -22
- package/src/__tests__/voice-session-bridge.test.ts +39 -0
- package/src/__tests__/volume-security-guard.test.ts +3 -2
- package/src/__tests__/web-search-history.test.ts +337 -0
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
- package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
- package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
- package/src/__tests__/workspace-migration-046-seed-conversation-starters-callsite.test.ts +185 -0
- package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
- package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
- package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +11 -11
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
- package/src/__tests__/workspace-policy.test.ts +22 -16
- package/src/acp/client-handler.ts +1 -2
- package/src/agent/loop.ts +545 -115
- package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
- package/src/approvals/guardian-request-resolvers.ts +80 -0
- package/src/avatar/resvg-lazy.test.ts +136 -0
- package/src/avatar/resvg-lazy.ts +82 -9
- package/src/avatar/traits-png-sync.ts +21 -1
- package/src/backup/__tests__/backup-worker.test.ts +2 -13
- package/src/backup/backup-worker.ts +3 -15
- package/src/browser/__tests__/operations.test.ts +163 -0
- package/src/browser/identifiers.ts +51 -0
- package/src/browser/operations.ts +660 -0
- package/src/browser/types.ts +81 -0
- package/src/bundler/app-compiler.ts +84 -1
- package/src/calls/call-state.ts +2 -2
- package/src/calls/guardian-question-copy.ts +2 -2
- package/src/calls/telephony-stt-routing.ts +1 -1
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/channels/__tests__/types.test.ts +3 -3
- package/src/channels/types.ts +6 -4
- package/src/cli/AGENTS.md +1 -1
- package/src/cli/__tests__/notifications.test.ts +87 -211
- package/src/cli/commands/__tests__/attachment.test.ts +438 -0
- package/src/cli/commands/__tests__/backup.test.ts +1 -1
- package/src/cli/commands/__tests__/browser.test.ts +554 -0
- package/src/cli/commands/__tests__/cache.test.ts +623 -0
- package/src/cli/commands/__tests__/email-list.test.ts +6 -0
- package/src/cli/commands/__tests__/email-send.test.ts +93 -1
- package/src/cli/commands/__tests__/image-generation.test.ts +886 -0
- package/src/cli/commands/__tests__/inference-send.test.ts +463 -0
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
- package/src/cli/commands/__tests__/task.test.ts +913 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +606 -0
- package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
- package/src/cli/commands/__tests__/ui.test.ts +1215 -0
- package/src/cli/commands/__tests__/watchers.test.ts +716 -0
- package/src/cli/commands/attachment.ts +182 -0
- package/src/cli/commands/backup.ts +2 -2
- package/src/cli/commands/browser.ts +350 -0
- package/src/cli/commands/cache.ts +341 -0
- package/src/cli/commands/clients.ts +138 -0
- package/src/cli/commands/completions.ts +2 -12
- package/src/cli/commands/config.ts +6 -6
- package/src/cli/commands/conversations-import.ts +347 -0
- package/src/cli/commands/conversations.ts +69 -8
- package/src/cli/commands/email.ts +234 -194
- package/src/cli/commands/image-generation.ts +299 -0
- package/src/cli/commands/inference.ts +200 -0
- package/src/cli/commands/memory.ts +127 -17
- package/src/cli/commands/notifications.ts +68 -103
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +2 -2
- package/src/cli/commands/oauth/providers.ts +176 -8
- package/src/cli/commands/oauth/status.ts +46 -36
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +0 -1
- package/src/cli/commands/skills.ts +3 -4
- package/src/cli/commands/stt.ts +339 -0
- package/src/cli/commands/task.ts +795 -0
- package/src/cli/commands/trust.ts +50 -19
- package/src/cli/commands/tts.ts +273 -0
- package/src/cli/commands/ui.ts +670 -0
- package/src/cli/commands/watchers.ts +509 -0
- package/src/cli/lib/daemon-credential-client.ts +0 -19
- package/src/cli/program.ts +39 -24
- package/src/cli.ts +0 -37
- package/src/config/__tests__/backup-schema.test.ts +7 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
- package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +20 -1
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +69 -12
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -8
- package/src/config/bundled-skills/schedule/SKILL.md +8 -3
- package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
- package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-tool-registry.ts +0 -190
- package/src/config/env.ts +7 -2
- package/src/config/feature-flag-registry.json +42 -10
- package/src/config/llm-resolver.ts +128 -0
- package/src/config/loader.ts +194 -10
- package/src/config/raw-config-utils.ts +30 -2
- package/src/config/sanitize-for-transfer.ts +35 -0
- package/src/config/schema.ts +49 -41
- package/src/config/schemas/analysis.ts +3 -22
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/calls.ts +0 -4
- package/src/config/schemas/conversations.ts +16 -0
- package/src/config/schemas/filing.ts +2 -7
- package/src/config/schemas/heartbeat.ts +0 -5
- package/src/config/schemas/inference.ts +3 -23
- package/src/config/schemas/llm.ts +317 -0
- package/src/config/schemas/memory-processing.ts +1 -9
- package/src/config/schemas/notifications.ts +4 -11
- package/src/config/schemas/platform.ts +3 -9
- package/src/config/schemas/security.ts +33 -0
- package/src/config/schemas/services.ts +9 -4
- package/src/config/schemas/stt.ts +1 -0
- package/src/config/schemas/tts.ts +64 -0
- package/src/config/schemas/updates.ts +1 -1
- package/src/config/schemas/workspace-git.ts +3 -40
- package/src/config/skill-state.ts +6 -2
- package/src/config/skills.ts +96 -7
- package/src/context/__tests__/compact-prompt.test.ts +63 -0
- package/src/context/__tests__/microcompact.test.ts +805 -0
- package/src/context/estimator-calibration.ts +136 -0
- package/src/context/microcompact.ts +443 -0
- package/src/context/prompts/compact.md +26 -0
- package/src/context/token-estimator.ts +61 -3
- package/src/context/tool-result-truncation.ts +3 -63
- package/src/context/window-manager.ts +417 -39
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/executable-discovery.ts +19 -8
- package/src/credential-execution/process-manager.test.ts +109 -0
- package/src/credential-execution/process-manager.ts +65 -2
- package/src/credential-health/credential-health-service.ts +19 -6
- package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
- package/src/daemon/approval-generators.ts +29 -4
- package/src/daemon/assistant-attachments.ts +24 -13
- package/src/daemon/classifier.ts +2 -2
- package/src/daemon/config-watcher.ts +0 -3
- package/src/daemon/context-overflow-policy.ts +4 -13
- package/src/daemon/context-overflow-reducer.ts +4 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +162 -34
- package/src/daemon/conversation-agent-loop.ts +1282 -599
- package/src/daemon/conversation-attachments.ts +2 -6
- package/src/daemon/conversation-error.ts +36 -1
- package/src/daemon/conversation-history.ts +10 -19
- package/src/daemon/conversation-lifecycle.ts +59 -17
- package/src/daemon/conversation-messaging.ts +73 -4
- package/src/daemon/conversation-notifiers.ts +2 -110
- package/src/daemon/conversation-process.ts +24 -11
- package/src/daemon/conversation-queue-manager.ts +3 -0
- package/src/daemon/conversation-runtime-assembly.ts +1063 -211
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +389 -1
- package/src/daemon/conversation-tool-setup.ts +51 -9
- package/src/daemon/conversation-usage.ts +1 -1
- package/src/daemon/conversation.ts +197 -64
- package/src/daemon/external-plugins-bootstrap.ts +478 -0
- package/src/daemon/external-skills-bootstrap.ts +41 -0
- package/src/daemon/first-greeting.ts +191 -14
- package/src/daemon/guardian-action-generators.ts +34 -14
- package/src/daemon/handlers/config-model.test.ts +86 -0
- package/src/daemon/handlers/config-model.ts +65 -12
- package/src/daemon/handlers/conversations.ts +9 -2
- package/src/daemon/handlers/shared.ts +39 -11
- package/src/daemon/handlers/skills.ts +7 -3
- package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
- package/src/daemon/lifecycle.ts +109 -82
- package/src/daemon/message-types/computer-use.ts +2 -34
- package/src/daemon/message-types/conversations.ts +63 -0
- package/src/daemon/message-types/messages.ts +21 -1
- package/src/daemon/message-types/trust.ts +0 -2
- package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
- package/src/daemon/pkb-context-tracker.test.ts +169 -0
- package/src/daemon/pkb-context-tracker.ts +125 -0
- package/src/daemon/pkb-reminder-builder.test.ts +70 -0
- package/src/daemon/pkb-reminder-builder.ts +31 -0
- package/src/daemon/providers-setup.ts +6 -0
- package/src/daemon/server.ts +122 -12
- package/src/daemon/shutdown-handlers.ts +2 -12
- package/src/daemon/tool-side-effects.ts +14 -65
- package/src/daemon/web-search-history.ts +126 -0
- package/src/events/domain-events.ts +0 -1
- package/src/filing/filing-service.ts +9 -10
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
- package/src/heartbeat/heartbeat-service.ts +99 -28
- package/src/home/__tests__/feed-population-integration.test.ts +312 -0
- package/src/home/__tests__/feed-scheduler.test.ts +39 -11
- package/src/home/__tests__/rollup-producer.test.ts +44 -0
- package/src/home/assistant-feed-authoring.ts +4 -0
- package/src/home/emit-feed-event.ts +11 -0
- package/src/home/feed-scheduler.ts +20 -4
- package/src/home/feed-types.ts +97 -4
- package/src/home/relationship-state-writer.ts +2 -2
- package/src/home/rewrite-command-preview.ts +66 -0
- package/src/home/rollup-producer.ts +34 -5
- package/src/home/suggested-prompts.ts +101 -0
- package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
- package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
- package/src/ipc/__tests__/socket-path.test.ts +34 -0
- package/src/ipc/__tests__/task-ipc.test.ts +577 -0
- package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
- package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
- package/src/ipc/cli-client.ts +2 -1
- package/src/ipc/cli-server.ts +26 -8
- package/src/ipc/gateway-client.ts +6 -3
- package/src/ipc/routes/attachment.ts +114 -0
- package/src/ipc/routes/browser-context.ts +63 -0
- package/src/ipc/routes/browser.ts +97 -0
- package/src/ipc/routes/cache.ts +96 -0
- package/src/ipc/routes/get-contact.ts +16 -0
- package/src/ipc/routes/index.ts +31 -1
- package/src/ipc/routes/list-clients.ts +31 -0
- package/src/ipc/routes/merge-contacts.ts +17 -0
- package/src/ipc/routes/notification.ts +133 -0
- package/src/ipc/routes/rename-conversation.ts +59 -0
- package/src/ipc/routes/search-contacts.ts +19 -0
- package/src/ipc/routes/task-queue.ts +226 -0
- package/src/ipc/routes/task.ts +173 -0
- package/src/ipc/routes/ui-request.ts +50 -0
- package/src/ipc/routes/upsert-contact.ts +25 -0
- package/src/ipc/routes/watcher.ts +203 -0
- package/src/ipc/socket-path.ts +76 -0
- package/src/media/app-icon-generator.ts +23 -46
- package/src/media/avatar-router.ts +26 -41
- package/src/media/gemini-image-service.ts +8 -41
- package/src/media/image-credentials.ts +73 -0
- package/src/media/image-service.ts +85 -0
- package/src/media/openai-image-service.ts +131 -0
- package/src/media/types.ts +46 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +9 -8
- package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
- package/src/memory/admin.ts +18 -0
- package/src/memory/conversation-analyze-job.ts +14 -13
- package/src/memory/conversation-attention-store.ts +13 -6
- package/src/memory/conversation-crud.ts +133 -3
- package/src/memory/conversation-group-migration.ts +38 -6
- package/src/memory/conversation-queries.ts +57 -4
- package/src/memory/conversation-title-service.ts +32 -4
- package/src/memory/db-init.ts +10 -0
- package/src/memory/embedding-backend.ts +1 -1
- package/src/memory/embedding-gemini.test.ts +41 -2
- package/src/memory/embedding-gemini.ts +6 -1
- package/src/memory/graph/bootstrap.test.ts +282 -0
- package/src/memory/graph/bootstrap.ts +8 -5
- package/src/memory/graph/compaction.ts +299 -0
- package/src/memory/graph/consolidation.ts +4 -4
- package/src/memory/graph/conversation-graph-memory.ts +89 -29
- package/src/memory/graph/extraction.test.ts +272 -2
- package/src/memory/graph/extraction.ts +183 -53
- package/src/memory/graph/graph-search.test.ts +93 -0
- package/src/memory/graph/graph-search.ts +4 -1
- package/src/memory/graph/inspect.ts +2 -2
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.test.ts +459 -0
- package/src/memory/graph/retriever.ts +237 -48
- package/src/memory/graph/store.ts +41 -0
- package/src/memory/graph/tool-handlers.ts +27 -0
- package/src/memory/graph/tools.ts +6 -1
- package/src/memory/indexer.ts +5 -5
- package/src/memory/job-handlers/conversation-starters.ts +23 -20
- package/src/memory/job-handlers/summarization.ts +2 -2
- package/src/memory/job-utils.ts +7 -1
- package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
- package/src/memory/jobs/embed-pkb-file.ts +54 -0
- package/src/memory/jobs-store.ts +44 -3
- package/src/memory/jobs-worker.ts +4 -0
- package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
- package/src/memory/migrations/149-oauth-tables.ts +1 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +2 -2
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
- package/src/memory/migrations/223-schedule-script-column.ts +11 -0
- package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
- package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/pkb/pkb-index.test.ts +369 -0
- package/src/memory/pkb/pkb-index.ts +255 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +252 -0
- package/src/memory/pkb/pkb-reconcile.ts +148 -0
- package/src/memory/pkb/pkb-search.test.ts +499 -0
- package/src/memory/pkb/pkb-search.ts +159 -0
- package/src/memory/pkb/types.ts +53 -0
- package/src/memory/qdrant-client.test.ts +60 -0
- package/src/memory/qdrant-client.ts +147 -1
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/schema/oauth.ts +4 -1
- package/src/memory/slack-thread-store.ts +37 -0
- package/src/messaging/providers/gmail/adapter.ts +6 -16
- package/src/messaging/providers/gmail/client.ts +22 -0
- package/src/messaging/providers/gmail/types.ts +7 -0
- package/src/messaging/providers/slack/adapter.ts +14 -2
- package/src/messaging/providers/slack/backfill.test.ts +257 -0
- package/src/messaging/providers/slack/backfill.ts +101 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
- package/src/messaging/providers/slack/message-metadata.ts +123 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1421 -0
- package/src/messaging/providers/slack/render-transcript.ts +501 -0
- package/src/messaging/style-analyzer.ts +5 -2
- package/src/notifications/README.md +9 -5
- package/src/notifications/conversation-pairing.ts +78 -19
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/decision-engine.ts +3 -9
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/preference-extractor.ts +2 -6
- package/src/notifications/signal.ts +1 -2
- package/src/oauth/AGENTS.md +1 -1
- package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
- package/src/oauth/connect-orchestrator.ts +8 -34
- package/src/oauth/connect-types.ts +6 -10
- package/src/oauth/manual-token-connection.ts +23 -0
- package/src/oauth/oauth-store.ts +31 -14
- package/src/oauth/platform-connection.test.ts +47 -0
- package/src/oauth/platform-connection.ts +15 -5
- package/src/oauth/provider-serializer.ts +6 -1
- package/src/oauth/seed-providers.ts +56 -106
- package/src/outbound-proxy/http-forwarder.ts +9 -0
- package/src/permissions/approval-policy.test.ts +1223 -0
- package/src/permissions/approval-policy.ts +309 -0
- package/src/permissions/arg-parser.test.ts +161 -0
- package/src/permissions/arg-parser.ts +141 -0
- package/src/permissions/bash-risk-classifier.test.ts +1620 -0
- package/src/permissions/bash-risk-classifier.ts +950 -0
- package/src/permissions/checker.ts +348 -711
- package/src/permissions/command-registry.test.ts +774 -0
- package/src/permissions/command-registry.ts +1005 -0
- package/src/permissions/defaults.ts +28 -79
- package/src/permissions/file-risk-classifier.test.ts +535 -0
- package/src/permissions/file-risk-classifier.ts +274 -0
- package/src/permissions/gateway-threshold-reader.ts +196 -0
- package/src/permissions/prompter.ts +4 -0
- package/src/permissions/risk-types.ts +262 -0
- package/src/permissions/schedule-risk-classifier.test.ts +129 -0
- package/src/permissions/schedule-risk-classifier.ts +85 -0
- package/src/permissions/secret-prompter.ts +53 -2
- package/src/permissions/shell-identity.ts +2 -42
- package/src/permissions/skill-risk-classifier.test.ts +311 -0
- package/src/permissions/skill-risk-classifier.ts +214 -0
- package/src/permissions/trust-client.ts +52 -25
- package/src/permissions/trust-store-interface.ts +1 -6
- package/src/permissions/trust-store.ts +161 -62
- package/src/permissions/types.ts +25 -14
- package/src/permissions/web-risk-classifier.test.ts +170 -0
- package/src/permissions/web-risk-classifier.ts +89 -0
- package/src/permissions/workspace-policy.ts +9 -19
- package/src/platform/client.ts +19 -1
- package/src/plugins/defaults/circuit-breaker.ts +146 -0
- package/src/plugins/defaults/compaction.ts +145 -0
- package/src/plugins/defaults/empty-response.ts +126 -0
- package/src/plugins/defaults/history-repair.ts +85 -0
- package/src/plugins/defaults/index.ts +116 -0
- package/src/plugins/defaults/injectors.ts +491 -0
- package/src/plugins/defaults/llm-call.ts +82 -0
- package/src/plugins/defaults/memory-retrieval.ts +226 -0
- package/src/plugins/defaults/overflow-reduce.ts +181 -0
- package/src/plugins/defaults/persistence.ts +129 -0
- package/src/plugins/defaults/title-generate.ts +95 -0
- package/src/plugins/defaults/token-estimate.ts +104 -0
- package/src/plugins/defaults/tool-error.ts +126 -0
- package/src/plugins/defaults/tool-execute.ts +89 -0
- package/src/plugins/defaults/tool-result-truncate.ts +88 -0
- package/src/plugins/pipeline.ts +316 -0
- package/src/plugins/plugin-skill-contributions.ts +292 -0
- package/src/plugins/registry.ts +241 -0
- package/src/plugins/types.ts +1134 -0
- package/src/plugins/user-loader.ts +177 -0
- package/src/prompts/persona-resolver.ts +3 -3
- package/src/prompts/system-prompt.ts +19 -20
- package/src/prompts/templates/BOOTSTRAP.md +27 -77
- package/src/prompts/templates/SOUL.md +2 -2
- package/src/prompts/update-bulletin-job.ts +190 -0
- package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
- package/src/providers/__tests__/retry-callsite.test.ts +424 -0
- package/src/providers/anthropic/client.ts +183 -14
- package/src/providers/call-site-routing.ts +71 -0
- package/src/providers/gemini/client.ts +65 -2
- package/src/providers/managed-proxy/constants.ts +2 -1
- package/src/providers/model-catalog.ts +524 -33
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/chat-completions-provider.ts +57 -1
- package/src/providers/openai/responses-provider.ts +86 -9
- package/src/providers/openrouter/client.ts +80 -9
- package/src/providers/provider-env-vars.ts +56 -0
- package/src/providers/provider-send-message.ts +22 -5
- package/src/providers/ratelimit.ts +4 -0
- package/src/providers/registry.ts +19 -8
- package/src/providers/retry.ts +174 -39
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +55 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +4 -4
- package/src/providers/speech-to-text/provider-catalog.ts +17 -0
- package/src/providers/speech-to-text/resolve.ts +7 -0
- package/src/providers/speech-to-text/xai-realtime.test.ts +646 -0
- package/src/providers/speech-to-text/xai-realtime.ts +821 -0
- package/src/providers/speech-to-text/xai.test.ts +155 -0
- package/src/providers/speech-to-text/xai.ts +97 -0
- package/src/providers/types.ts +93 -3
- package/src/runtime/AGENTS.md +27 -18
- package/src/runtime/__tests__/agent-wake.test.ts +43 -2
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
- package/src/runtime/__tests__/client-registry.test.ts +293 -0
- package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
- package/src/runtime/agent-wake.ts +63 -22
- package/src/runtime/auth/route-policy.ts +4 -0
- package/src/runtime/btw-sidechain.ts +13 -3
- package/src/runtime/channel-reply-delivery.ts +106 -2
- package/src/runtime/client-registry.ts +261 -0
- package/src/runtime/decision-token.ts +116 -0
- package/src/runtime/gateway-client.ts +2 -2
- package/src/runtime/http-router.ts +32 -0
- package/src/runtime/http-server.ts +129 -9
- package/src/runtime/http-types.ts +23 -3
- package/src/runtime/interactive-ui.ts +362 -0
- package/src/runtime/invite-instruction-generator.ts +2 -2
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
- package/src/runtime/migrations/gcs-signed-url.ts +162 -0
- package/src/runtime/migrations/vbundle-builder.ts +1 -22
- package/src/runtime/migrations/vbundle-importer.ts +154 -9
- package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
- package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
- package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
- package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
- package/src/runtime/migrations/vbundle-validator.ts +15 -6
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +111 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +114 -75
- package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +78 -0
- package/src/runtime/routes/approval-routes.ts +29 -17
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
- package/src/runtime/routes/avatar-routes.ts +20 -4
- package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
- package/src/runtime/routes/btw-routes.ts +1 -4
- package/src/runtime/routes/conversation-management-routes.ts +20 -2
- package/src/runtime/routes/conversation-routes.ts +351 -138
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/diagnostics-routes.ts +6 -4
- package/src/runtime/routes/events-routes.ts +16 -0
- package/src/runtime/routes/guardian-approval-interception.ts +33 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
- package/src/runtime/routes/home-feed-routes.ts +120 -2
- package/src/runtime/routes/inbound-message-handler.ts +987 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
- package/src/runtime/routes/integrations/slack/channel.ts +25 -3
- package/src/runtime/routes/llm-context-normalization.ts +23 -1
- package/src/runtime/routes/memory-item-routes.test.ts +1 -0
- package/src/runtime/routes/migration-routes.ts +720 -127
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
- package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
- package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
- package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
- package/src/runtime/routes/playground/deps.ts +56 -0
- package/src/runtime/routes/playground/force-compact.ts +73 -0
- package/src/runtime/routes/playground/guard.ts +37 -0
- package/src/runtime/routes/playground/index.ts +28 -0
- package/src/runtime/routes/playground/inject-failures.ts +159 -0
- package/src/runtime/routes/playground/reset-circuit.ts +115 -0
- package/src/runtime/routes/playground/seed-conversation.ts +139 -0
- package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
- package/src/runtime/routes/playground/state.ts +78 -0
- package/src/runtime/routes/schedule-routes.ts +89 -8
- package/src/runtime/routes/settings-routes.ts +4 -2
- package/src/runtime/routes/trust-rules-routes.ts +30 -14
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +3 -2
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +25 -43
- package/src/runtime/services/analyze-conversation.ts +12 -16
- package/src/runtime/skill-route-registry.ts +97 -15
- package/src/schedule/run-script.ts +68 -0
- package/src/schedule/schedule-store.ts +7 -1
- package/src/schedule/scheduler.ts +56 -8
- package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
- package/src/security/__tests__/untrusted-content.test.ts +109 -0
- package/src/security/oauth2.ts +98 -35
- package/src/security/secure-keys.ts +7 -8
- package/src/security/token-manager.ts +27 -13
- package/src/security/untrusted-content.ts +102 -0
- package/src/skills/catalog-cache.ts +35 -9
- package/src/skills/catalog-install.ts +31 -3
- package/src/skills/skill-cache-store.ts +97 -0
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +76 -0
- package/src/stt/daemon-batch-transcriber.ts +33 -0
- package/src/stt/stt-stream-session.ts +8 -1
- package/src/stt/types.ts +5 -1
- package/src/subagent/manager.ts +41 -13
- package/src/tasks/ephemeral-permissions.ts +9 -4
- package/src/telemetry/usage-telemetry-reporter.ts +27 -5
- package/src/tools/browser/__tests__/browser-status.test.ts +234 -2
- package/src/tools/browser/browser-execution.ts +150 -54
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
- package/src/tools/browser/cdp-client/factory.ts +15 -4
- package/src/tools/credentials/tool-policy.ts +39 -5
- package/src/tools/credentials/vault.ts +9 -4
- package/src/tools/executor.ts +129 -73
- package/src/tools/filesystem/write.ts +52 -0
- package/src/tools/host-terminal/host-shell.ts +45 -5
- package/src/tools/memory/register.test.ts +185 -0
- package/src/tools/memory/register.ts +3 -1
- package/src/tools/network/script-proxy/session-manager.ts +37 -1
- package/src/tools/network/web-fetch.ts +20 -10
- package/src/tools/network/web-search.ts +19 -4
- package/src/tools/permission-checker.ts +116 -46
- package/src/tools/policy-context.ts +29 -8
- package/src/tools/registry.ts +195 -6
- package/src/tools/schedule/create.ts +23 -8
- package/src/tools/schedule/update.ts +3 -1
- package/src/tools/secret-detection-handler.ts +0 -51
- package/src/tools/side-effects.ts +0 -11
- package/src/tools/skills/execute.ts +2 -2
- package/src/tools/skills/sandbox-runner.ts +5 -2
- package/src/tools/system/avatar-generator.ts +6 -2
- package/src/tools/terminal/backends/native.ts +51 -2
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +1 -0
- package/src/tools/tool-manifest.ts +6 -21
- package/src/tools/types.ts +40 -5
- package/src/tools/verification-control-plane-policy.ts +1 -1
- package/src/tts/__tests__/provider-adapters.test.ts +240 -13
- package/src/tts/provider-catalog.ts +18 -0
- package/src/tts/providers/index.ts +2 -0
- package/src/tts/providers/xai-provider.ts +224 -0
- package/src/tts/types.ts +46 -0
- package/src/types/tar-stream.d.ts +66 -0
- package/src/util/json.ts +17 -0
- package/src/util/platform.ts +9 -4
- package/src/util/pricing.ts +41 -8
- package/src/watcher/engine.ts +1 -1
- package/src/watcher/providers/google-calendar.ts +134 -8
- package/src/watcher/providers/outlook-calendar.ts +42 -2
- package/src/workspace/git-service.ts +23 -4
- package/src/workspace/migrations/006-services-config.ts +2 -4
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
- package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
- package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +56 -0
- package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
- package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
- package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
- package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
- package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
- package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/registry.ts +28 -0
- package/src/workspace/provider-commit-message-generator.ts +19 -38
- package/tsconfig.json +1 -1
- package/hook-templates/debug-prompt-logger/hook.json +0 -7
- package/hook-templates/debug-prompt-logger/run.sh +0 -66
- package/src/__tests__/context-overflow-approval.test.ts +0 -156
- package/src/__tests__/gmail-archive-fallback.test.ts +0 -193
- package/src/__tests__/gmail-archive-gate.test.ts +0 -246
- package/src/__tests__/gmail-preferences.test.ts +0 -117
- package/src/__tests__/hooks-blocking.test.ts +0 -178
- package/src/__tests__/hooks-cli.test.ts +0 -182
- package/src/__tests__/hooks-config.test.ts +0 -108
- package/src/__tests__/hooks-discovery.test.ts +0 -211
- package/src/__tests__/hooks-integration.test.ts +0 -196
- package/src/__tests__/hooks-manager.test.ts +0 -226
- package/src/__tests__/hooks-runner.test.ts +0 -175
- package/src/__tests__/hooks-settings.test.ts +0 -160
- package/src/__tests__/hooks-templates.test.ts +0 -169
- package/src/__tests__/hooks-ts-runner.test.ts +0 -170
- package/src/__tests__/hooks-watch.test.ts +0 -112
- package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
- package/src/__tests__/oauth-scope-policy.test.ts +0 -180
- package/src/__tests__/outlook-attachments.test.ts +0 -301
- package/src/__tests__/outlook-automation-tools.test.ts +0 -425
- package/src/__tests__/outlook-categories.test.ts +0 -212
- package/src/__tests__/outlook-compose-tools.test.ts +0 -325
- package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
- package/src/__tests__/outlook-follow-up.test.ts +0 -196
- package/src/__tests__/outlook-trash.test.ts +0 -77
- package/src/__tests__/outlook-unsubscribe.test.ts +0 -279
- package/src/__tests__/send-notification-tool.test.ts +0 -83
- package/src/__tests__/update-bulletin-format.test.ts +0 -181
- package/src/__tests__/update-bulletin-state.test.ts +0 -135
- package/src/__tests__/update-bulletin.test.ts +0 -478
- package/src/__tests__/update-template-contract.test.ts +0 -29
- package/src/cli/commands/doctor.ts +0 -341
- package/src/cli/commands/shotgun.ts +0 -266
- package/src/config/bundled-skills/browser/SKILL.md +0 -88
- package/src/config/bundled-skills/browser/TOOLS.json +0 -516
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-status.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -49
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
- package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
- package/src/config/bundled-skills/conversations/SKILL.md +0 -20
- package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -66
- package/src/config/bundled-skills/gmail/SKILL.md +0 -221
- package/src/config/bundled-skills/gmail/TOOLS.json +0 -588
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -256
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +0 -59
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +0 -82
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
- package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
- package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
- package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/google-calendar/types.ts +0 -97
- package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
- package/src/config/bundled-skills/notifications/SKILL.md +0 -40
- package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
- package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
- package/src/config/bundled-skills/outlook/SKILL.md +0 -196
- package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
- package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
- package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
- package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
- package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
- package/src/config/bundled-skills/slack/SKILL.md +0 -108
- package/src/config/bundled-skills/tasks/SKILL.md +0 -37
- package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
- package/src/config/bundled-skills/tasks/icon.svg +0 -34
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
- package/src/config/bundled-skills/watcher/SKILL.md +0 -31
- package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
- package/src/daemon/context-overflow-approval.ts +0 -52
- package/src/daemon/watch-handler.ts +0 -399
- package/src/hooks/cli.ts +0 -253
- package/src/hooks/config.ts +0 -100
- package/src/hooks/discovery.ts +0 -135
- package/src/hooks/manager.ts +0 -179
- package/src/hooks/runner.ts +0 -117
- package/src/hooks/templates.ts +0 -77
- package/src/hooks/types.ts +0 -75
- package/src/oauth/scope-policy.ts +0 -89
- package/src/prompts/templates/UPDATES.md +0 -50
- package/src/prompts/update-bulletin-format.ts +0 -85
- package/src/prompts/update-bulletin-state.ts +0 -58
- package/src/prompts/update-bulletin-template-path.ts +0 -13
- package/src/prompts/update-bulletin.ts +0 -139
- package/src/runtime/gateway-internal-client.ts +0 -94
- package/src/runtime/routes/watch-routes.ts +0 -156
- package/src/shared/provider-env-vars.ts +0 -19
- package/src/signals/shotgun.ts +0 -203
- package/src/tools/watch/screen-watch.ts +0 -144
- package/src/tools/watch/watch-state.ts +0 -142
- package/src/tools/watcher/create.ts +0 -86
- package/src/tools/watcher/delete.ts +0 -36
- package/src/tools/watcher/digest.ts +0 -54
- package/src/tools/watcher/list.ts +0 -83
- package/src/tools/watcher/update.ts +0 -71
package/docs/plugins.md
ADDED
|
@@ -0,0 +1,761 @@
|
|
|
1
|
+
# Plugin authoring guide
|
|
2
|
+
|
|
3
|
+
Plugins let you extend the assistant by hooking middleware into named
|
|
4
|
+
runtime pipelines, contributing tools/routes/skills, and injecting
|
|
5
|
+
system-prompt content. This guide is the authoritative reference for how
|
|
6
|
+
plugins are structured, registered, and executed — everything the code
|
|
7
|
+
actually enforces.
|
|
8
|
+
|
|
9
|
+
For a worked minimal example, see
|
|
10
|
+
[`assistant/examples/plugins/echo/`](../examples/plugins/echo/README.md).
|
|
11
|
+
That plugin observes every pipeline and logs to stderr, and is the fastest
|
|
12
|
+
way to see the system in action.
|
|
13
|
+
|
|
14
|
+
## Table of contents
|
|
15
|
+
|
|
16
|
+
- [Anatomy of a plugin](#anatomy-of-a-plugin)
|
|
17
|
+
- [Where plugins live](#where-plugins-live)
|
|
18
|
+
- [Manifest](#manifest)
|
|
19
|
+
- [Registration](#registration)
|
|
20
|
+
- [Middleware patterns](#middleware-patterns)
|
|
21
|
+
- [Pipeline reference](#pipeline-reference)
|
|
22
|
+
- [Timeouts](#timeouts)
|
|
23
|
+
- [Strict-fail semantics](#strict-fail-semantics)
|
|
24
|
+
- [Credentials and config](#credentials-and-config)
|
|
25
|
+
- [Tool, route, and skill contributions](#tool-route-and-skill-contributions)
|
|
26
|
+
- [Cross-plugin communication](#cross-plugin-communication)
|
|
27
|
+
- [Hot reload](#hot-reload)
|
|
28
|
+
- [Troubleshooting](#troubleshooting)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Anatomy of a plugin
|
|
33
|
+
|
|
34
|
+
A plugin is a directory that exports a single `register.ts` (or compiled
|
|
35
|
+
`register.js`) entry point. That file builds a `Plugin` object and passes
|
|
36
|
+
it to `registerPlugin()` as an import-time side effect. Everything else —
|
|
37
|
+
pipeline middleware, lifecycle hooks, model-visible capabilities — hangs
|
|
38
|
+
off that one `Plugin` object.
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
my-plugin/
|
|
42
|
+
├── package.json # Node/Bun package metadata
|
|
43
|
+
├── README.md # optional — human docs
|
|
44
|
+
└── register.ts # the entry point the assistant imports
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The `Plugin` shape is declared in
|
|
48
|
+
[`assistant/src/plugins/types.ts`](../src/plugins/types.ts):
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
export interface Plugin {
|
|
52
|
+
manifest: PluginManifest;
|
|
53
|
+
init?(ctx: PluginInitContext): Promise<void>;
|
|
54
|
+
onShutdown?(): Promise<void>;
|
|
55
|
+
tools?: PluginToolRegistration[];
|
|
56
|
+
routes?: PluginRouteRegistration[];
|
|
57
|
+
skills?: PluginSkillRegistration[];
|
|
58
|
+
injectors?: Injector[];
|
|
59
|
+
middleware?: Partial<PipelineMiddlewareMap>;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Every field except `manifest` is optional. A plugin that only contributes
|
|
64
|
+
middleware doesn't need tools or routes; a plugin that only contributes a
|
|
65
|
+
skill can omit middleware entirely.
|
|
66
|
+
|
|
67
|
+
## Where plugins live
|
|
68
|
+
|
|
69
|
+
The assistant scans `~/.vellum/plugins/*` at startup. Any subdirectory
|
|
70
|
+
containing `register.js` or `register.ts` is dynamic-imported once. The
|
|
71
|
+
loader lives in
|
|
72
|
+
[`assistant/src/plugins/user-loader.ts`](../src/plugins/user-loader.ts) and
|
|
73
|
+
has three key properties:
|
|
74
|
+
|
|
75
|
+
- **Compiled wins.** If both `register.js` and `register.ts` are present,
|
|
76
|
+
the compiled `.js` file is loaded. This matches how the compiled
|
|
77
|
+
assistant binary resolves modules in production.
|
|
78
|
+
- **Per-plugin isolation.** If one plugin throws at import time, the error
|
|
79
|
+
is logged with the plugin directory and the loader moves on. Other
|
|
80
|
+
plugins still load. One broken plugin cannot brick the assistant.
|
|
81
|
+
- **Per-instance.** The scan runs under `vellumRoot()`, which honors the
|
|
82
|
+
multi-instance `BASE_DATA_DIR` override. Each assistant instance loads
|
|
83
|
+
its own plugin set.
|
|
84
|
+
|
|
85
|
+
The loader runs after first-party plugin registrations and before
|
|
86
|
+
`bootstrapPlugins()` invokes every plugin's `init()`.
|
|
87
|
+
|
|
88
|
+
## Manifest
|
|
89
|
+
|
|
90
|
+
The manifest is static metadata validated by the registry at registration
|
|
91
|
+
time. Its shape (see
|
|
92
|
+
[`types.ts`](../src/plugins/types.ts)):
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
export interface PluginManifest {
|
|
96
|
+
name: string; // kebab-case, unique
|
|
97
|
+
version: string; // semver, informational
|
|
98
|
+
provides?: Record<string, string>; // reserved; not consumed at runtime today
|
|
99
|
+
requires: Record<string, string>; // capability → version required from the assistant
|
|
100
|
+
requiresCredential?: string[]; // credential keys resolved before init()
|
|
101
|
+
requiresFlag?: string[]; // feature flag keys that must all be enabled
|
|
102
|
+
config?: unknown; // Zod-like parser for plugins.<name>
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
| Field | Required | Purpose |
|
|
107
|
+
| -------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
108
|
+
| `name` | yes | Unique plugin identifier. Duplicate names fail registration. Used as the directory under `~/.vellum/plugins-data/<name>/` and the attribution tag in logs. |
|
|
109
|
+
| `version` | yes | Plugin's own semver. Informational — the registry does not compare it. |
|
|
110
|
+
| `provides` | no | Reserved for future cross-plugin composition and not currently consumed by the assistant. Plugin authors may set this field, but no runtime code reads it yet — it is declared here so future cross-plugin work can land without a manifest version bump. Do not rely on it for any runtime behavior today. |
|
|
111
|
+
| `requires` | yes | Must include `pluginRuntime: "v1"` at minimum. The registry checks every entry against `ASSISTANT_API_VERSIONS` and refuses to register plugins that ask for a capability or version the assistant does not expose. |
|
|
112
|
+
| `requiresCredential` | no | Credential keys the plugin needs. The bootstrap resolves them via the credential store before `init()` runs and hands the values to the plugin in `ctx.credentials`. A missing credential fails startup with a clear error. |
|
|
113
|
+
| `requiresFlag` | no | Assistant feature-flag keys that must all be ON for the plugin to activate. If any listed flag is disabled at bootstrap, the plugin is skipped entirely: `init()` is not invoked and no tools, routes, skills, or shutdown hooks are registered for it. See [Feature-flag gating](#feature-flag-gating) below. |
|
|
114
|
+
| `config` | no | A parser-like validator (Zod schema, or any object with a `.parse(input)` method). If supplied, the bootstrap validates `config.plugins.<name>` through it before passing the result into `init()`. |
|
|
115
|
+
|
|
116
|
+
The exposed capability table (`ASSISTANT_API_VERSIONS`) lives in
|
|
117
|
+
[`registry.ts`](../src/plugins/registry.ts). It lists:
|
|
118
|
+
|
|
119
|
+
- `pluginRuntime` — the base runtime every plugin must negotiate for.
|
|
120
|
+
- `memoryApi`, `compactionApi`, `persistenceApi` — top-level subsystem APIs.
|
|
121
|
+
- One `*Api` entry per pipeline slot (e.g. `llmCallApi`, `toolExecuteApi`,
|
|
122
|
+
`titleGenerateApi`, …).
|
|
123
|
+
|
|
124
|
+
Every entry is currently on `v1`. Removing or changing a version tag is a
|
|
125
|
+
breaking change — plugins relying on it will fail to register until they
|
|
126
|
+
update their `requires` map.
|
|
127
|
+
|
|
128
|
+
### Example manifest
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const manifest: PluginManifest = {
|
|
132
|
+
name: "my-logger",
|
|
133
|
+
version: "1.2.3",
|
|
134
|
+
provides: {},
|
|
135
|
+
requires: {
|
|
136
|
+
pluginRuntime: "v1",
|
|
137
|
+
llmCallApi: "v1",
|
|
138
|
+
},
|
|
139
|
+
requiresCredential: ["LOGGER_API_KEY"],
|
|
140
|
+
requiresFlag: ["my-logger-enabled"],
|
|
141
|
+
config: z.object({
|
|
142
|
+
endpoint: z.string().url(),
|
|
143
|
+
sampleRate: z.number().min(0).max(1).default(0.1),
|
|
144
|
+
}),
|
|
145
|
+
};
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Feature-flag gating
|
|
149
|
+
|
|
150
|
+
`manifest.requiresFlag` lists one or more **assistant-scope** feature-flag
|
|
151
|
+
keys (the same keys declared in
|
|
152
|
+
`meta/feature-flags/feature-flag-registry.json`). The bootstrap checks each
|
|
153
|
+
key against `isAssistantFeatureFlagEnabled` before touching the plugin. If
|
|
154
|
+
**any** listed flag is disabled, the plugin is skipped entirely for the
|
|
155
|
+
duration of this assistant boot:
|
|
156
|
+
|
|
157
|
+
- `init()` is **not** invoked.
|
|
158
|
+
- `tools`, `routes`, and `skills` are **not** registered.
|
|
159
|
+
- No shutdown hook entry is installed, so a plugin skipped at boot has
|
|
160
|
+
nothing to tear down on shutdown.
|
|
161
|
+
|
|
162
|
+
Flag state is resolved once at bootstrap time. Flipping a `requiresFlag`
|
|
163
|
+
key at runtime does not hot-reload the plugin — restart the assistant
|
|
164
|
+
after changing the flag to pick up the new state. An empty `requiresFlag` (or
|
|
165
|
+
the field being absent) means the plugin activates unconditionally.
|
|
166
|
+
|
|
167
|
+
The skip path emits a single `info`-level log line naming both the plugin
|
|
168
|
+
and the disabled flag, so operators can diagnose "why isn't my plugin
|
|
169
|
+
loading?" at a glance:
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
plugins-bootstrap skipping plugin my-logger: feature flag my-logger-enabled is disabled
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Cross-repo note:** new flag keys used here must be declared in the
|
|
176
|
+
assistant-scope section of
|
|
177
|
+
`meta/feature-flags/feature-flag-registry.json` (and provisioned in the
|
|
178
|
+
platform's Terraform configuration). See the root `CLAUDE.md`'s "Assistant
|
|
179
|
+
Feature Flags" section for the full procedure.
|
|
180
|
+
|
|
181
|
+
## Registration
|
|
182
|
+
|
|
183
|
+
A plugin's `register.ts` calls `registerPlugin()` at module load time:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
import { registerPlugin } from "<path-to-assistant>/src/plugins/registry.js";
|
|
187
|
+
import type { Plugin } from "<path-to-assistant>/src/plugins/types.js";
|
|
188
|
+
|
|
189
|
+
const myPlugin: Plugin = {
|
|
190
|
+
manifest: {
|
|
191
|
+
name: "my-plugin",
|
|
192
|
+
version: "0.1.0",
|
|
193
|
+
requires: { pluginRuntime: "v1" },
|
|
194
|
+
},
|
|
195
|
+
middleware: {
|
|
196
|
+
/* ... */
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
registerPlugin(myPlugin);
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Rules:**
|
|
204
|
+
|
|
205
|
+
- Exactly one `registerPlugin()` call per plugin. The registry rejects
|
|
206
|
+
duplicate names.
|
|
207
|
+
- `register.ts` must not export named symbols consumed from outside. The
|
|
208
|
+
loader treats the import as side-effect-only.
|
|
209
|
+
- Throwing inside `register.ts` is caught by the loader and logged, then
|
|
210
|
+
the loader moves on. Do not rely on throws to signal "please don't load
|
|
211
|
+
this plugin" — use `requiresFlag` or a guard inside `init()` instead.
|
|
212
|
+
- The file runs before any lifecycle hooks. Keep it fast — heavy work
|
|
213
|
+
belongs in `init()`.
|
|
214
|
+
|
|
215
|
+
## Middleware patterns
|
|
216
|
+
|
|
217
|
+
Middleware is the heart of the plugin system. Every pipeline slot uses the
|
|
218
|
+
same onion-style signature:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
export type Middleware<A, R> = (
|
|
222
|
+
args: A,
|
|
223
|
+
next: (args: A) => Promise<R>,
|
|
224
|
+
ctx: TurnContext,
|
|
225
|
+
) => Promise<R>;
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The runner composes an array of middleware around a terminal handler. The
|
|
229
|
+
first middleware sees the request first and the response last; the
|
|
230
|
+
terminal runs at the innermost layer. See
|
|
231
|
+
[`assistant/src/plugins/pipeline.ts`](../src/plugins/pipeline.ts) for the
|
|
232
|
+
composition algorithm.
|
|
233
|
+
|
|
234
|
+
Four common patterns emerge from that signature:
|
|
235
|
+
|
|
236
|
+
### Observe-only
|
|
237
|
+
|
|
238
|
+
Record something without changing the call. Call `next(args)` unchanged,
|
|
239
|
+
return the result unchanged. Wrap the call in `try`/`finally` so your
|
|
240
|
+
observer runs on both success and failure paths.
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
const observer: Middleware<ToolExecuteArgs, ToolExecuteResult> =
|
|
244
|
+
async function observeToolExecute(args, next, ctx) {
|
|
245
|
+
const start = performance.now();
|
|
246
|
+
let outcome: "success" | "error" = "success";
|
|
247
|
+
try {
|
|
248
|
+
return await next(args);
|
|
249
|
+
} catch (err) {
|
|
250
|
+
outcome = "error";
|
|
251
|
+
throw err;
|
|
252
|
+
} finally {
|
|
253
|
+
const ms = Math.round(performance.now() - start);
|
|
254
|
+
console.error(JSON.stringify({ tool: args.name, ms, outcome }));
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Transform input
|
|
260
|
+
|
|
261
|
+
Rewrite `args` before calling downstream. Useful for request shimming
|
|
262
|
+
(adding headers, redacting inputs, picking a different provider).
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
const addHeader: Middleware<LLMCallArgs, LLMCallResult> =
|
|
266
|
+
async function addHeader(args, next, ctx) {
|
|
267
|
+
const tagged = {
|
|
268
|
+
...args,
|
|
269
|
+
options: {
|
|
270
|
+
...args.options,
|
|
271
|
+
config: { ...args.options?.config, requestId: ctx.requestId },
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
return next(tagged);
|
|
275
|
+
};
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Transform output
|
|
279
|
+
|
|
280
|
+
Call `next(args)` first, then modify the result before returning.
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
const redactPII: Middleware<LLMCallArgs, LLMCallResult> =
|
|
284
|
+
async function redactPII(args, next, ctx) {
|
|
285
|
+
const response = await next(args);
|
|
286
|
+
return {
|
|
287
|
+
...response,
|
|
288
|
+
content: response.content.map(redactBlock),
|
|
289
|
+
};
|
|
290
|
+
};
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Short-circuit
|
|
294
|
+
|
|
295
|
+
Do not call `next(args)` — return a synthetic result directly. The
|
|
296
|
+
terminal and any inner middleware are skipped. Use this to stub, cache,
|
|
297
|
+
or mock a pipeline.
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
const cacheHit: Middleware<LLMCallArgs, LLMCallResult> =
|
|
301
|
+
async function cacheHit(args, next, ctx) {
|
|
302
|
+
const cached = await lookupCache(args);
|
|
303
|
+
if (cached) return cached;
|
|
304
|
+
return next(args);
|
|
305
|
+
};
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Veto (throw)
|
|
309
|
+
|
|
310
|
+
Throwing from middleware aborts the pipeline. The error propagates out
|
|
311
|
+
through any outer middleware unchanged — there is no internal
|
|
312
|
+
`try`/`catch` around user middleware.
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
const denyIfUnauthorized: Middleware<ToolExecuteArgs, ToolExecuteResult> =
|
|
316
|
+
async function denyIfUnauthorized(args, next, ctx) {
|
|
317
|
+
if (!isAuthorizedFor(args.name, ctx.trust)) {
|
|
318
|
+
throw new Error(`tool ${args.name} denied by policy`);
|
|
319
|
+
}
|
|
320
|
+
return next(args);
|
|
321
|
+
};
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Naming middleware
|
|
325
|
+
|
|
326
|
+
Give middleware a stable `name` (via `async function <name>(…)`). The
|
|
327
|
+
pipeline runner pulls `Function.name` into its `chain` log field so
|
|
328
|
+
operators can see the registered chain at a glance:
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
plugin.pipeline pipeline=llmCall chain=["observeLlm","addHeader","defaultLlmCall"] durationMs=1840 outcome=success
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Pipeline reference
|
|
335
|
+
|
|
336
|
+
Every pipeline slot and its purpose. Type details live in
|
|
337
|
+
[`types.ts`](../src/plugins/types.ts).
|
|
338
|
+
|
|
339
|
+
| Pipeline | Purpose |
|
|
340
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
341
|
+
| `turn` | The outermost wrapper around a single assistant turn. Middleware here sees everything a turn does end-to-end. |
|
|
342
|
+
| `llmCall` | Every call to `Provider.sendMessage`. Input carries `messages`, `tools`, `systemPrompt`, `options`. |
|
|
343
|
+
| `toolExecute` | Every `ToolExecutor.execute` call. Input carries `name`, `input`, and the full `ToolContext`. |
|
|
344
|
+
| `memoryRetrieval` | PKB, NOW.md, and memory-graph retrieval for a turn. Output is a merged `MemoryResult`. |
|
|
345
|
+
| `historyRepair` | The pre-run repair pass on the message history. Wraps `repairHistory`. |
|
|
346
|
+
| `tokenEstimate` | The token-count estimate used for budgeting. Wraps `estimatePromptTokensRaw`. |
|
|
347
|
+
| `compaction` | The conversation-compaction step. Wraps `ContextWindowManager.maybeCompact`. |
|
|
348
|
+
| `overflowReduce` | The reducer tier loop invoked when a turn blows the context budget. |
|
|
349
|
+
| `persistence` | Every message CRUD op (`add` / `update` / `delete`). Discriminated by `args.op`. |
|
|
350
|
+
| `titleGenerate` | Conversation title generation. Fire-and-forget by default. |
|
|
351
|
+
| `toolResultTruncate` | The per-tool-result truncation step that fits a tool's output into the context window. |
|
|
352
|
+
| `emptyResponse` | The decision about what to do when the model returns an empty turn (nudge / accept / error). |
|
|
353
|
+
| `toolError` | The decision about what to do when one or more tool calls errored on a turn. |
|
|
354
|
+
| `circuitBreaker` | The compaction circuit breaker. Tracks consecutive-failure state, decides whether to open the circuit. |
|
|
355
|
+
|
|
356
|
+
## Timeouts
|
|
357
|
+
|
|
358
|
+
Each pipeline has a default timeout budget in milliseconds. When the
|
|
359
|
+
budget is exceeded the runner throws `PluginTimeoutError` carrying the
|
|
360
|
+
pipeline name, the offending plugin's name (if known), and the elapsed
|
|
361
|
+
duration. See
|
|
362
|
+
[`assistant/src/plugins/pipeline.ts`](../src/plugins/pipeline.ts) for the
|
|
363
|
+
current values.
|
|
364
|
+
|
|
365
|
+
| Pipeline | Timeout | Rationale |
|
|
366
|
+
| -------------------- | -------- | -------------------------------------------------------------------------------------------------------------- |
|
|
367
|
+
| `turn` | none | Turn duration is bounded by the downstream `llmCall` / `toolExecute` timeouts, not a pipeline-level timer. |
|
|
368
|
+
| `llmCall` | none | Deferred to the provider's HTTP timeout so network hiccups surface as provider errors, not pipeline timeouts. |
|
|
369
|
+
| `toolExecute` | none | Deferred to the per-tool timeout already enforced by `ToolExecutor`. |
|
|
370
|
+
| `memoryRetrieval` | 5000 ms | Memory reads may hit Qdrant and disk; 5 s leaves slack for cold caches without blocking the turn indefinitely. |
|
|
371
|
+
| `historyRepair` | 1000 ms | CPU-bound list walk — should finish in a few ms. |
|
|
372
|
+
| `tokenEstimate` | 1000 ms | Same — CPU-bound, should return instantly. |
|
|
373
|
+
| `compaction` | 30000 ms | Summarization involves a provider call; mirrors the pipeline-level budget for LLM-backed operations. |
|
|
374
|
+
| `overflowReduce` | 30000 ms | Iterative compaction; matches the `compaction` budget since each tier step may invoke it. |
|
|
375
|
+
| `persistence` | 10000 ms | SQLite writes, Qdrant deletes, and disk syncs. 10 s is generous for the slowest op (batched segment inserts). |
|
|
376
|
+
| `titleGenerate` | 30000 ms | Provider-backed. Fire-and-forget, but the budget exists so a stuck call doesn't leak forever. |
|
|
377
|
+
| `toolResultTruncate` | 1000 ms | Pure string op. |
|
|
378
|
+
| `emptyResponse` | 500 ms | Decision logic only — must be near-instant. |
|
|
379
|
+
| `toolError` | 500 ms | Decision logic only — must be near-instant. |
|
|
380
|
+
| `circuitBreaker` | 500 ms | Numeric state update — must be near-instant. |
|
|
381
|
+
|
|
382
|
+
`null` timeouts skip the timer entirely. Finite timeouts arm a
|
|
383
|
+
`setTimeout` that races the pipeline via `Promise.race`.
|
|
384
|
+
|
|
385
|
+
## Strict-fail semantics
|
|
386
|
+
|
|
387
|
+
**Plugin errors and timeouts fail the turn loudly. There is no silent
|
|
388
|
+
fallback to the default behavior.**
|
|
389
|
+
|
|
390
|
+
This is a deliberate design decision. The old inline behavior silently
|
|
391
|
+
absorbed many edge cases (a memory retrieval failure became an empty
|
|
392
|
+
memory block, a compaction error became no compaction, etc.). That made
|
|
393
|
+
debugging production issues miserable because failures disappeared into
|
|
394
|
+
logs nobody checked.
|
|
395
|
+
|
|
396
|
+
With strict-fail:
|
|
397
|
+
|
|
398
|
+
- Any error thrown from middleware propagates up to the caller. The
|
|
399
|
+
pipeline runner does not catch it.
|
|
400
|
+
- Any `PluginTimeoutError` from a budget breach propagates identically.
|
|
401
|
+
- The caller (agent loop, memory subsystem, whoever) decides how to
|
|
402
|
+
degrade. The pipeline itself does not paper over the failure.
|
|
403
|
+
- Exactly one structured log line is emitted per pipeline invocation, in
|
|
404
|
+
a `finally` block, regardless of outcome. It carries `outcome`
|
|
405
|
+
(`"success" | "error" | "timeout"`), `durationMs`, `chain`, plugin
|
|
406
|
+
attribution, and error details when applicable.
|
|
407
|
+
|
|
408
|
+
If you're writing middleware that wants to "try, fall back to default on
|
|
409
|
+
failure," express that at the call site instead — wrap the pipeline
|
|
410
|
+
invocation in your own try/catch. Do not swallow the error inside your
|
|
411
|
+
middleware's `try`/`catch` and silently return a degraded result.
|
|
412
|
+
|
|
413
|
+
## Credentials and config
|
|
414
|
+
|
|
415
|
+
### Credentials
|
|
416
|
+
|
|
417
|
+
Declare required credential keys in `manifest.requiresCredential`:
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
const manifest: PluginManifest = {
|
|
421
|
+
name: "my-plugin",
|
|
422
|
+
version: "1.0.0",
|
|
423
|
+
requires: { pluginRuntime: "v1" },
|
|
424
|
+
requiresCredential: ["MY_PLUGIN_API_KEY"],
|
|
425
|
+
};
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
During bootstrap, the assistant resolves each key through the credential
|
|
429
|
+
store (via `getSecureKeyAsync`). In Docker mode that call goes through
|
|
430
|
+
the CES HTTP API; in local mode it hits the encrypted file store / CES
|
|
431
|
+
RPC backend. The resolved values are handed to your `init()`:
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
async init(ctx: PluginInitContext) {
|
|
435
|
+
const apiKey = ctx.credentials["MY_PLUGIN_API_KEY"];
|
|
436
|
+
// use it
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
**Rules:**
|
|
441
|
+
|
|
442
|
+
- Never import the credential store directly. Always go through the
|
|
443
|
+
manifest.
|
|
444
|
+
- Missing credentials fail startup with a clear error naming the plugin
|
|
445
|
+
and the key. There is no silent fallback.
|
|
446
|
+
- Credentials are resolved once at bootstrap. Long-running plugins that
|
|
447
|
+
need rotation must re-resolve through their own mechanism.
|
|
448
|
+
|
|
449
|
+
### Config
|
|
450
|
+
|
|
451
|
+
Declare a parser-like validator in `manifest.config`:
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
const configSchema = z.object({
|
|
455
|
+
endpoint: z.string().url(),
|
|
456
|
+
sampleRate: z.number().min(0).max(1).default(0.1),
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
const manifest: PluginManifest = {
|
|
460
|
+
name: "my-plugin",
|
|
461
|
+
version: "1.0.0",
|
|
462
|
+
requires: { pluginRuntime: "v1" },
|
|
463
|
+
config: configSchema,
|
|
464
|
+
};
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
The bootstrap reads `config.plugins.<name>` from the assistant's config
|
|
468
|
+
and calls `manifest.config.parse(raw)`. The parsed result is handed to
|
|
469
|
+
your `init()`:
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
async init(ctx: PluginInitContext) {
|
|
473
|
+
const cfg = ctx.config as z.infer<typeof configSchema>;
|
|
474
|
+
// use cfg
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
If you don't supply a validator, the raw config is passed through
|
|
479
|
+
untouched as `unknown` and your plugin must narrow it itself.
|
|
480
|
+
|
|
481
|
+
### Other init context fields
|
|
482
|
+
|
|
483
|
+
The full `PluginInitContext`:
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
export interface PluginInitContext {
|
|
487
|
+
config: unknown; // parsed config (or raw if no validator)
|
|
488
|
+
credentials: Record<string, string>; // resolved credentials from requiresCredential
|
|
489
|
+
logger: unknown; // pino child logger, tagged { plugin: <name> }
|
|
490
|
+
pluginStorageDir: string; // ~/.vellum/plugins-data/<name>/ (created by bootstrap)
|
|
491
|
+
assistantVersion: string; // assistant semver
|
|
492
|
+
apiVersions: Record<string, string[]>; // ASSISTANT_API_VERSIONS, for runtime checks
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
`pluginStorageDir` is a per-plugin writable directory. Use it for
|
|
497
|
+
persistent state — cache files, counters, anything that must survive an
|
|
498
|
+
assistant restart. The bootstrap creates it on demand.
|
|
499
|
+
|
|
500
|
+
## Tool, route, and skill contributions
|
|
501
|
+
|
|
502
|
+
Plugins can contribute model-visible capabilities alongside their
|
|
503
|
+
middleware. Each is optional.
|
|
504
|
+
|
|
505
|
+
### Tools (`plugin.tools`)
|
|
506
|
+
|
|
507
|
+
An array of `Tool` objects. The bootstrap registers them with the global
|
|
508
|
+
tool registry after `init()` succeeds, stamping `origin: "plugin"` and
|
|
509
|
+
`ownerPluginId: <plugin.name>` so they live in a ref-count namespace
|
|
510
|
+
disjoint from real skills (a plugin whose `manifest.name` happens to
|
|
511
|
+
match a skill id cannot collide with that skill's registrations).
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
const myPlugin: Plugin = {
|
|
515
|
+
manifest: {
|
|
516
|
+
/* ... */
|
|
517
|
+
},
|
|
518
|
+
tools: [
|
|
519
|
+
{
|
|
520
|
+
name: "my_tool",
|
|
521
|
+
description: "Does the thing.",
|
|
522
|
+
category: "plugin",
|
|
523
|
+
defaultRiskLevel: "low",
|
|
524
|
+
getDefinition: () => ({
|
|
525
|
+
name: "my_tool",
|
|
526
|
+
description: "Does the thing.",
|
|
527
|
+
input_schema: { type: "object", properties: {}, required: [] },
|
|
528
|
+
}),
|
|
529
|
+
execute: async (input, ctx) => ({ content: "result", isError: false }),
|
|
530
|
+
},
|
|
531
|
+
],
|
|
532
|
+
};
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
Tools are unregistered automatically on shutdown. See
|
|
536
|
+
[`assistant/src/tools/types.ts`](../src/tools/types.ts) for the full
|
|
537
|
+
`Tool` interface including optional fields like `executionMode` and
|
|
538
|
+
`executionTarget`.
|
|
539
|
+
|
|
540
|
+
### Routes (`plugin.routes`)
|
|
541
|
+
|
|
542
|
+
An array of `SkillRoute` objects — the same shape the skill-route
|
|
543
|
+
registry consumes. Registered via `registerSkillRoute` after `init()`
|
|
544
|
+
succeeds; the runtime retains the opaque handle returned by each call
|
|
545
|
+
and uses those handles to unregister the plugin's routes on shutdown.
|
|
546
|
+
Handle-keyed unregistration is deliberate: two owners (plugin vs.
|
|
547
|
+
skill, or plugin vs. plugin) can legitimately declare the same regex,
|
|
548
|
+
and identity matching ensures one owner's teardown cannot evict
|
|
549
|
+
another owner's live routes.
|
|
550
|
+
|
|
551
|
+
```typescript
|
|
552
|
+
const myPlugin: Plugin = {
|
|
553
|
+
manifest: {
|
|
554
|
+
/* ... */
|
|
555
|
+
},
|
|
556
|
+
routes: [
|
|
557
|
+
{
|
|
558
|
+
pattern: /^\/_plugin\/my-plugin\/status$/,
|
|
559
|
+
methods: ["GET"],
|
|
560
|
+
handler: async (req, match) => new Response("ok"),
|
|
561
|
+
},
|
|
562
|
+
],
|
|
563
|
+
};
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### Skills (`plugin.skills`)
|
|
567
|
+
|
|
568
|
+
An array of `PluginSkillRegistration` objects. Each becomes a discoverable
|
|
569
|
+
skill under `source: "plugin"` in the model's `skill_load` /
|
|
570
|
+
`skill_execute` flow.
|
|
571
|
+
|
|
572
|
+
```typescript
|
|
573
|
+
const myPlugin: Plugin = {
|
|
574
|
+
manifest: {
|
|
575
|
+
/* ... */
|
|
576
|
+
},
|
|
577
|
+
skills: [
|
|
578
|
+
{
|
|
579
|
+
id: "my-plugin/do-thing",
|
|
580
|
+
name: "do-thing",
|
|
581
|
+
description: "Does the thing via plugin-contributed skill.",
|
|
582
|
+
body: "# SKILL.md body returned when loaded\n...",
|
|
583
|
+
},
|
|
584
|
+
],
|
|
585
|
+
};
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
See
|
|
589
|
+
[`plugin-skill-contributions.ts`](../src/plugins/plugin-skill-contributions.ts)
|
|
590
|
+
for the in-memory registry details and ref-counted lifecycle.
|
|
591
|
+
|
|
592
|
+
### Injectors (`plugin.injectors`)
|
|
593
|
+
|
|
594
|
+
An array of `Injector` objects that emit system-prompt-time content.
|
|
595
|
+
Each has a stable `name`, an ascending `order` used to position it in the
|
|
596
|
+
injection chain, and a `produce(ctx)` method that returns an
|
|
597
|
+
`InjectionBlock` or `null`.
|
|
598
|
+
|
|
599
|
+
The default injectors use `order` 10 through 70 with gaps of 10, so
|
|
600
|
+
plugin-contributed injectors can slot at `25`, `35`, etc. without
|
|
601
|
+
renumbering.
|
|
602
|
+
|
|
603
|
+
```typescript
|
|
604
|
+
const myPlugin: Plugin = {
|
|
605
|
+
manifest: {
|
|
606
|
+
/* ... */
|
|
607
|
+
},
|
|
608
|
+
injectors: [
|
|
609
|
+
{
|
|
610
|
+
name: "my-plugin/status",
|
|
611
|
+
order: 25,
|
|
612
|
+
async produce(ctx) {
|
|
613
|
+
return {
|
|
614
|
+
id: "my-plugin/status",
|
|
615
|
+
text: `<my_plugin_status>ok</my_plugin_status>`,
|
|
616
|
+
};
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
],
|
|
620
|
+
};
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
## Cross-plugin communication
|
|
624
|
+
|
|
625
|
+
Plugins should not call each other directly. There is no cross-plugin
|
|
626
|
+
import API — a plugin's export surface is intentionally limited to the
|
|
627
|
+
`Plugin` object it registers.
|
|
628
|
+
|
|
629
|
+
For cross-cutting concerns (broadcasting events, reacting to
|
|
630
|
+
system-level changes), use the `assistantEventHub` pub/sub in
|
|
631
|
+
[`runtime/assistant-event-hub.ts`](../src/runtime/assistant-event-hub.ts).
|
|
632
|
+
The hub is the canonical place to publish events from inside the
|
|
633
|
+
assistant process and to subscribe from anywhere that has access to the
|
|
634
|
+
assistant's module graph.
|
|
635
|
+
|
|
636
|
+
Do not add new HTTP endpoints to implement plugin-to-plugin messaging
|
|
637
|
+
inside a single assistant process.
|
|
638
|
+
|
|
639
|
+
`manifest.provides` is reserved as the hook for a future cross-plugin
|
|
640
|
+
capability-negotiation protocol but is **not currently consumed by any
|
|
641
|
+
runtime code**. Declaring `provides` today has no behavioral effect —
|
|
642
|
+
plugins must not depend on it for capability discovery or any other
|
|
643
|
+
runtime purpose. The field is intentionally retained on the manifest so
|
|
644
|
+
that adding real consumers later does not require bumping
|
|
645
|
+
`pluginRuntime` or any other capability version.
|
|
646
|
+
|
|
647
|
+
## Hot reload
|
|
648
|
+
|
|
649
|
+
**Not supported in v1.** Registering a plugin takes effect at assistant
|
|
650
|
+
startup only. To pick up a new or modified plugin:
|
|
651
|
+
|
|
652
|
+
```bash
|
|
653
|
+
vellum restart
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
The registry's internal state is not mutable at runtime. `init()` and
|
|
657
|
+
`onShutdown()` hooks are fired exactly once per assistant boot.
|
|
658
|
+
|
|
659
|
+
If you need hot reload for development, symlink your plugin directory
|
|
660
|
+
into `~/.vellum/plugins/` so edits propagate, and automate the restart
|
|
661
|
+
loop externally.
|
|
662
|
+
|
|
663
|
+
## Troubleshooting
|
|
664
|
+
|
|
665
|
+
### "plugin X must declare requires.pluginRuntime"
|
|
666
|
+
|
|
667
|
+
The manifest's `requires` map is missing the `pluginRuntime` entry. Every
|
|
668
|
+
plugin must negotiate against the base runtime:
|
|
669
|
+
|
|
670
|
+
```typescript
|
|
671
|
+
requires: { pluginRuntime: "v1" },
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### "plugin X requires Y@vN, assistant exposes (none|v...)"
|
|
675
|
+
|
|
676
|
+
The `requires` map names a capability the assistant does not expose, or
|
|
677
|
+
asks for a version not listed under that capability. See
|
|
678
|
+
`ASSISTANT_API_VERSIONS` in
|
|
679
|
+
[`registry.ts`](../src/plugins/registry.ts) for the currently-exposed
|
|
680
|
+
list. Either downgrade the required version or update your plugin to
|
|
681
|
+
match.
|
|
682
|
+
|
|
683
|
+
### "plugin X is already registered"
|
|
684
|
+
|
|
685
|
+
Two plugins tried to register under the same `manifest.name`. Names must
|
|
686
|
+
be globally unique. Rename one, or if this is a dev-reload issue,
|
|
687
|
+
restart the assistant.
|
|
688
|
+
|
|
689
|
+
### "plugin X requires credential Y but the credential store returned no value"
|
|
690
|
+
|
|
691
|
+
The credential named in `requiresCredential` is not set. Run:
|
|
692
|
+
|
|
693
|
+
```bash
|
|
694
|
+
vellum credentials set Y
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
…and restart the assistant.
|
|
698
|
+
|
|
699
|
+
### "plugin X config validation failed: …"
|
|
700
|
+
|
|
701
|
+
The config block under `config.plugins.<name>` failed the manifest's
|
|
702
|
+
parser. Check your config against the plugin's schema — the error
|
|
703
|
+
message carries the validator's diagnostic.
|
|
704
|
+
|
|
705
|
+
### `PluginTimeoutError: Plugin pipeline '<name>' timed out after N ms`
|
|
706
|
+
|
|
707
|
+
A plugin's middleware exceeded the pipeline's budget. The offending
|
|
708
|
+
plugin is named in `ctx.pluginName` when available. Tighten the
|
|
709
|
+
middleware (it's probably blocking on I/O it shouldn't) or, if the
|
|
710
|
+
work is genuinely heavy, move it out of the critical path into a
|
|
711
|
+
background job that publishes results through `assistantEventHub`.
|
|
712
|
+
|
|
713
|
+
### Reading pipeline log records
|
|
714
|
+
|
|
715
|
+
Every pipeline invocation emits one structured line tagged
|
|
716
|
+
`event=plugin.pipeline`. The fields:
|
|
717
|
+
|
|
718
|
+
| Field | Meaning |
|
|
719
|
+
| ------------------------------------------ | ----------------------------------------------------------------------- |
|
|
720
|
+
| `pipeline` | Pipeline name (`llmCall`, `toolExecute`, …). |
|
|
721
|
+
| `chain` | Ordered list of middleware function names, outermost first. |
|
|
722
|
+
| `durationMs` | Total time spent in the composed chain. |
|
|
723
|
+
| `outcome` | `"success"`, `"error"`, or `"timeout"`. |
|
|
724
|
+
| `pluginName` | The specific plugin's name when the runner could attribute the frame. |
|
|
725
|
+
| `timeoutMs` | The configured budget (only when one was set). |
|
|
726
|
+
| `errorName`, `errorMessage`, `errorStack` | Present on failure outcomes. |
|
|
727
|
+
| `requestId`, `conversationId`, `turnIndex` | Per-turn context for correlating with the rest of the assistant's logs. |
|
|
728
|
+
|
|
729
|
+
Pipe the assistant's stderr through `jq` to filter and inspect:
|
|
730
|
+
|
|
731
|
+
```bash
|
|
732
|
+
tail -f ~/.vellum/daemon.log | jq 'select(.event == "plugin.pipeline")'
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
To isolate slow pipelines:
|
|
736
|
+
|
|
737
|
+
```bash
|
|
738
|
+
tail -f ~/.vellum/daemon.log \
|
|
739
|
+
| jq 'select(.event == "plugin.pipeline" and .durationMs > 1000)'
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
To isolate errors and timeouts:
|
|
743
|
+
|
|
744
|
+
```bash
|
|
745
|
+
tail -f ~/.vellum/daemon.log \
|
|
746
|
+
| jq 'select(.event == "plugin.pipeline" and .outcome != "success")'
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
### Plugin not loading at all
|
|
750
|
+
|
|
751
|
+
- Confirm the directory is under `~/.vellum/plugins/` (or the per-instance
|
|
752
|
+
equivalent under `$BASE_DATA_DIR/.vellum/plugins/`).
|
|
753
|
+
- Confirm it has a `register.ts` or `register.js` at the top level.
|
|
754
|
+
- Check the assistant's stderr for a line like
|
|
755
|
+
`loaded user plugin (side-effect import completed)` or
|
|
756
|
+
`Failed to load user plugin <dir>: <err>`. Import-time throws are
|
|
757
|
+
logged but do not crash the assistant — the plugin is silently skipped
|
|
758
|
+
otherwise.
|
|
759
|
+
- Verify `register.ts` calls `registerPlugin()` exactly once at module
|
|
760
|
+
level. If the call is inside an unrelated conditional or wrapped in
|
|
761
|
+
an async function that is never awaited, the registry won't see it.
|