@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091853.fbaa2ae
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +6 -6
- package/bun.lock +2 -2
- package/docs/activation-funnel-telemetry.md +310 -0
- package/examples/plugins/echo/README.md +61 -60
- package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
- package/examples/plugins/echo/hooks/stop.ts +16 -0
- package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
- package/examples/plugins/echo/package.json +1 -2
- package/examples/plugins/echo/src/emit.ts +19 -0
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
- package/openapi.yaml +263 -121
- package/package.json +2 -2
- package/src/__tests__/activation-early-marking.test.ts +120 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
- package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
- package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
- package/src/__tests__/agent-loop-thinking.test.ts +36 -20
- package/src/__tests__/agent-loop.test.ts +441 -96
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
- package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
- package/src/__tests__/anthropic-provider.test.ts +23 -8
- package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +132 -0
- package/src/__tests__/approval-cascade.test.ts +6 -5
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +146 -0
- package/src/__tests__/compaction-events.test.ts +7 -7
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
- package/src/__tests__/context-overflow-reducer.test.ts +265 -125
- package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
- package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
- package/src/__tests__/conversation-agent-loop.test.ts +342 -623
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
- package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
- package/src/__tests__/conversation-error.test.ts +15 -1
- package/src/__tests__/conversation-history-web-search.test.ts +6 -1
- package/src/__tests__/conversation-media-retry.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
- package/src/__tests__/conversation-process-callsite.test.ts +15 -15
- package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
- package/src/__tests__/conversation-queue.test.ts +10 -10
- package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
- package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
- package/src/__tests__/conversation-slash-queue.test.ts +7 -5
- package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
- package/src/__tests__/conversation-speed-override.test.ts +11 -10
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
- package/src/__tests__/conversation-undo.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
- package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +36 -0
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/empty-response-hook.test.ts +1 -1
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/gateway-only-guard.test.ts +17 -2
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +93 -4
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/history-repair-hook.test.ts +5 -1
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/inference-profile-reaper.test.ts +62 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
- package/src/__tests__/injector-background-turn.test.ts +13 -23
- package/src/__tests__/injector-chain.test.ts +268 -44
- package/src/__tests__/injector-disk-pressure.test.ts +210 -52
- package/src/__tests__/injector-document-comments.test.ts +97 -114
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-v3-suppression.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
- package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
- package/src/__tests__/llm-resolver.test.ts +73 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
- package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
- package/src/__tests__/persist-unsendable-image.test.ts +97 -1
- package/src/__tests__/plugin-api-shim.test.ts +6 -9
- package/src/__tests__/plugin-bootstrap.test.ts +91 -81
- package/src/__tests__/plugin-registry.test.ts +3 -49
- package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -70
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
- package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
- package/src/__tests__/published-app-updater.test.ts +138 -0
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
- package/src/__tests__/steer-tool-repair.test.ts +1 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-detail.test.ts +25 -7
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +1 -3
- package/src/__tests__/subagent-notify-parent.test.ts +1 -3
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +5 -1
- package/src/__tests__/tool-error-hook.test.ts +1 -1
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- package/src/__tests__/web-fetch.test.ts +45 -0
- package/src/acp/__tests__/agent-process.test.ts +161 -0
- package/src/acp/__tests__/client-handler.test.ts +40 -0
- package/src/acp/__tests__/helpers/acp-config-stub.ts +0 -2
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +280 -0
- package/src/acp/auto-install.ts +232 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/prepare-agent-env.ts +80 -27
- package/src/acp/resolve-agent.test.ts +188 -28
- package/src/acp/resolve-agent.ts +119 -42
- package/src/acp/resume-hint.ts +23 -0
- package/src/acp/session-manager.ts +507 -73
- package/src/agent/compaction-circuit.ts +60 -102
- package/src/agent/loop.ts +403 -251
- package/src/api/responses/conversation-message.ts +22 -2
- package/src/api/responses/memory-v3-selection-log.ts +19 -10
- package/src/approvals/guardian-request-resolvers.ts +27 -1
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
- package/src/cli/commands/memory-v3.ts +57 -199
- package/src/cli/commands/plugins.ts +43 -37
- package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
- package/src/cli/lib/install-from-github.ts +797 -60
- package/src/cli/lib/plugin-catalog-cache.ts +84 -0
- package/src/cli/lib/plugin-details.ts +416 -0
- package/src/cli/lib/plugin-marketplace.ts +215 -0
- package/src/cli/lib/search-plugins.ts +201 -29
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/acp-defaults.test.ts +10 -0
- package/src/config/acp-defaults.ts +9 -3
- package/src/config/acp-schema.ts +1 -7
- package/src/config/bundled-skills/acp/SKILL.md +80 -41
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
- package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-tool-registry.ts +4 -0
- package/src/config/call-site-defaults.ts +0 -3
- package/src/config/feature-flag-registry.json +10 -16
- package/src/config/llm-resolver.ts +39 -7
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
- package/src/config/schemas/call-site-catalog.ts +0 -21
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +17 -3
- package/src/config/schemas/memory-v3.ts +58 -8
- package/src/config/seed-inference-profiles.ts +18 -0
- package/src/context/compactor.ts +22 -4
- package/src/context/post-turn-tool-result-truncation.ts +39 -1
- package/src/context/strip-injections.ts +8 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +18 -36
- package/src/daemon/conversation-agent-loop.ts +308 -1297
- package/src/daemon/conversation-error.ts +31 -4
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +11 -255
- package/src/daemon/conversation-media-retry.ts +19 -6
- package/src/daemon/conversation-messaging.ts +17 -0
- package/src/daemon/conversation-process.ts +22 -141
- package/src/daemon/conversation-queue-manager.ts +8 -0
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +361 -393
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +165 -11
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +444 -62
- package/src/daemon/disk-pressure-policy.ts +0 -1
- package/src/daemon/external-plugins-bootstrap.ts +36 -46
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-proxy-preactivation.ts +1 -3
- package/src/daemon/lifecycle.ts +21 -7
- package/src/daemon/persist-unsendable-image.ts +62 -25
- package/src/daemon/process-message.ts +1 -1
- package/src/daemon/server.ts +2 -0
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/daemon/wake-conversation-ops.ts +269 -0
- package/src/embedded/plugin-api.ts +2 -2
- package/src/export/__tests__/transcript-formatter.test.ts +5 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
- package/src/heartbeat/heartbeat-run-store.ts +23 -1
- package/src/heartbeat/heartbeat-service.ts +26 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
- package/src/ipc/skill-routes/memory.ts +4 -2
- package/src/memory/__tests__/activation-session-store.test.ts +41 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
- package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
- package/src/memory/activation-session-store.ts +43 -0
- package/src/memory/conversation-crud.ts +29 -19
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/db-init.ts +6 -0
- package/src/memory/job-handlers/conversation-starters.ts +13 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
- package/src/memory/jobs-worker.ts +25 -1
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
- package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
- package/src/memory/migrations/index.ts +3 -0
- package/src/memory/onboarding-events-store.ts +66 -18
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +13 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
- package/src/memory/v2/__tests__/page-store.test.ts +22 -0
- package/src/memory/v2/consolidation-job.ts +2 -63
- package/src/memory/v2/types.ts +5 -0
- package/src/messaging/providers/telegram-bot/api.ts +14 -5
- package/src/notifications/__tests__/copy-composer.test.ts +244 -0
- package/src/notifications/access-request-copy.ts +298 -0
- package/src/notifications/adapters/slack.ts +3 -3
- package/src/notifications/adapters/telegram.ts +9 -2
- package/src/notifications/copy-composer.ts +49 -267
- package/src/notifications/decision-engine.ts +16 -35
- package/src/notifications/home-feed-side-effect.ts +1 -6
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +40 -11
- package/src/plugin-api/types.ts +108 -0
- package/src/plugins/defaults/compaction/compact.ts +106 -0
- package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/plugins/defaults/compaction/manager-store.ts +57 -0
- package/src/plugins/defaults/compaction/package.json +1 -2
- package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
- package/src/plugins/defaults/empty-response/package.json +0 -1
- package/src/plugins/defaults/history-repair/package.json +0 -1
- package/src/plugins/defaults/index.ts +156 -26
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
- package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
- package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
- package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
- package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +76 -0
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
- package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
- package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
- package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
- package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
- package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
- package/src/plugins/defaults/title-generate/package.json +0 -1
- package/src/plugins/defaults/tool-error/package.json +0 -1
- package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
- package/src/plugins/external-api.ts +12 -2
- package/src/plugins/pipeline.ts +6 -293
- package/src/plugins/registry.ts +9 -37
- package/src/plugins/types.ts +76 -381
- package/src/plugins/user-loader.ts +30 -127
- package/src/prompts/__tests__/system-prompt.test.ts +6 -0
- package/src/prompts/system-prompt.ts +61 -10
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
- package/src/providers/anthropic/client.ts +9 -10
- package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
- package/src/providers/inference/logit-bias.ts +55 -0
- package/src/providers/model-catalog.ts +34 -0
- package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -1
- package/src/providers/retry.ts +22 -0
- package/src/providers/types.ts +6 -0
- package/src/runtime/__tests__/agent-wake.test.ts +555 -691
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +108 -209
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
- package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
- package/src/runtime/routes/acp-routes.test.ts +185 -32
- package/src/runtime/routes/acp-routes.ts +328 -30
- package/src/runtime/routes/app-management-routes.ts +3 -0
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +6 -10
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +1 -1
- package/src/runtime/routes/conversation-routes.ts +30 -2
- package/src/runtime/routes/conversation-starter-routes.ts +13 -7
- package/src/runtime/routes/conversations-import-routes.ts +24 -7
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-cu-routes.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +18 -3
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
- package/src/runtime/routes/memory-v3-routes.ts +65 -305
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/plugins-routes.ts +337 -35
- package/src/runtime/routes/stt-routes.ts +45 -12
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/routes/workspace-routes.ts +50 -15
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/services/published-app-updater.ts +30 -8
- package/src/signals/cancel.ts +2 -4
- package/src/subagent/manager.ts +21 -5
- package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
- package/src/telemetry/activation-funnel.ts +167 -0
- package/src/telemetry/types.ts +13 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
- package/src/telemetry/usage-telemetry-reporter.ts +26 -1
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +9 -19
- package/src/tools/acp/list-agents.ts +3 -15
- package/src/tools/acp/spawn.test.ts +173 -202
- package/src/tools/acp/spawn.ts +37 -172
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/executors.ts +166 -50
- package/src/tools/browser/browser-execution.ts +12 -2
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/network/web-fetch.ts +65 -24
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/ui-surface/definitions.ts +32 -5
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
- package/docs/plugins.md +0 -832
- package/examples/plugins/echo/register.ts +0 -143
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
- package/src/__tests__/compaction-pipeline.test.ts +0 -210
- package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
- package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
- package/src/__tests__/pipeline-runner.test.ts +0 -554
- package/src/daemon/wake-target-adapter.ts +0 -253
- package/src/memory/v3/__tests__/assign.test.ts +0 -242
- package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
- package/src/memory/v3/__tests__/core.test.ts +0 -39
- package/src/memory/v3/__tests__/health.test.ts +0 -219
- package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
- package/src/memory/v3/__tests__/needle.test.ts +0 -107
- package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
- package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
- package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
- package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
- package/src/memory/v3/__tests__/router.test.ts +0 -332
- package/src/memory/v3/__tests__/selector.test.ts +0 -470
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
- package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
- package/src/memory/v3/__tests__/tree.test.ts +0 -192
- package/src/memory/v3/assign.ts +0 -268
- package/src/memory/v3/capabilities.ts +0 -124
- package/src/memory/v3/core.ts +0 -26
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +0 -314
- package/src/memory/v3/needle.ts +0 -115
- package/src/memory/v3/orchestrate.ts +0 -126
- package/src/memory/v3/page-content.ts +0 -34
- package/src/memory/v3/provider-blocks.ts +0 -26
- package/src/memory/v3/reconcile.ts +0 -523
- package/src/memory/v3/router.ts +0 -190
- package/src/memory/v3/selection-log-store.ts +0 -84
- package/src/memory/v3/selector.ts +0 -226
- package/src/memory/v3/shadow-plugin.ts +0 -411
- package/src/memory/v3/snapshot.ts +0 -209
- package/src/memory/v3/tree.ts +0 -174
- package/src/memory/v3/types.ts +0 -59
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
- package/src/plugins/defaults/circuit-breaker/package.json +0 -15
- package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
- package/src/plugins/defaults/compaction/register.ts +0 -35
- package/src/plugins/defaults/compaction/terminal.ts +0 -73
- package/src/plugins/defaults/empty-response/register.ts +0 -23
- package/src/plugins/defaults/history-repair/register.ts +0 -24
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
- package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
- package/src/plugins/defaults/overflow-reduce/package.json +0 -15
- package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
- package/src/plugins/defaults/title-generate/register.ts +0 -35
- package/src/plugins/defaults/tool-error/register.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
- package/src/proactive-artifact/aux-message-injector.ts +0 -97
- package/src/proactive-artifact/decision.test.ts +0 -226
- package/src/proactive-artifact/decision.ts +0 -165
- package/src/proactive-artifact/index.ts +0 -7
- package/src/proactive-artifact/job.test.ts +0 -962
- package/src/proactive-artifact/job.ts +0 -372
- package/src/proactive-artifact/message-copy.ts +0 -58
- package/src/proactive-artifact/trigger-state.test.ts +0 -286
- package/src/proactive-artifact/trigger-state.ts +0 -123
- package/src/util/map-limit.ts +0 -27
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External plugin runtime — `globalThis.__vellumPluginRuntime` bridge.
|
|
3
3
|
*
|
|
4
|
+
* ⚠️ DO NOT DELETE THIS AS "UNUSED". There is intentionally NO in-repo consumer:
|
|
5
|
+
* the consumers are out-of-repo, user-authored workspace plugins under
|
|
6
|
+
* `<workspaceDir>/plugins/*`, which a repo-wide reference search cannot see. On
|
|
7
|
+
* a `bun --compile` daemon (the shipped macOS app) this bridge is the ONLY way
|
|
8
|
+
* such a plugin can reach the daemon's real `assistantEventHub` /
|
|
9
|
+
* `getSecureKeyAsync` singletons — an absolute-path `import` re-loads a disjoint
|
|
10
|
+
* copy (see the module-identity note below). Removing it silently breaks every
|
|
11
|
+
* event-subscribing workspace plugin on the next app rebuild. This was already
|
|
12
|
+
* removed once on the false "unused" assumption (PR #33825) and restored here.
|
|
13
|
+
*
|
|
4
14
|
* Workspace-local plugins (`<workspaceDir>/plugins/*`) get dynamic-imported by
|
|
5
15
|
* {@link loadUserPlugins}. They need to call `registerPlugin()` from their
|
|
6
16
|
* module body and they typically also want to read secrets, subscribe to
|
|
@@ -31,8 +41,8 @@
|
|
|
31
41
|
* absolute paths or workspace-local copies — the TypeScript compiler erases
|
|
32
42
|
* them and they have no module-identity effect at runtime.
|
|
33
43
|
*
|
|
34
|
-
* See `
|
|
35
|
-
* `assistant/examples/plugins/echo
|
|
44
|
+
* See `experimental/plugins/README.md` for the full authoring contract and
|
|
45
|
+
* `assistant/examples/plugins/echo/` for a worked example.
|
|
36
46
|
*/
|
|
37
47
|
|
|
38
48
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
package/src/plugins/pipeline.ts
CHANGED
|
@@ -1,297 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Plugin
|
|
2
|
+
* Plugin hook runner.
|
|
3
3
|
*
|
|
4
|
-
* A "
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* covering success, error, and timeout uniformly.
|
|
4
|
+
* A "hook" is a named lifecycle event (`user-prompt-submit`, `post-tool-use`,
|
|
5
|
+
* …) that every registered plugin may handle. The runner walks each plugin's
|
|
6
|
+
* hook for a given event in registration order, threading a context value
|
|
7
|
+
* through the chain so hooks can observe and transform it.
|
|
9
8
|
*
|
|
10
|
-
* Design doc: `.private/plans/agent-plugin-system.md
|
|
11
|
-
*
|
|
12
|
-
* Semantics:
|
|
13
|
-
* - Onion composition — the first element of `middlewares` is the outermost
|
|
14
|
-
* wrapper; it sees the request first and the response last. Terminal runs
|
|
15
|
-
* in the middle.
|
|
16
|
-
* - Strict-fail — there is NO `try/catch` around user middleware. Errors,
|
|
17
|
-
* including `PluginTimeoutError` from a breached budget, propagate to the
|
|
18
|
-
* caller. The `finally` block only handles logging, never error recovery.
|
|
19
|
-
* - Timeout — when `timeoutMs` is a finite number, the invocation races a
|
|
20
|
-
* timer. A timeout rejection is a `PluginTimeoutError` carrying the
|
|
21
|
-
* pipeline name, the best-known offending plugin (from `ctx.pluginName`),
|
|
22
|
-
* and elapsed ms. When `timeoutMs` is `null`/`undefined`, no timer is
|
|
23
|
-
* armed — pipelines like `compaction` rely on downstream timeouts instead.
|
|
9
|
+
* Design doc: `.private/plans/agent-plugin-system.md`.
|
|
24
10
|
*/
|
|
25
11
|
|
|
26
|
-
import type { Logger } from "pino";
|
|
27
|
-
|
|
28
12
|
import type { HookName } from "../plugin-api/constants.js";
|
|
29
|
-
import { getLogger } from "../util/logger.js";
|
|
30
13
|
import { getHooksFor } from "./registry.js";
|
|
31
|
-
import {
|
|
32
|
-
type Middleware,
|
|
33
|
-
type PipelineName,
|
|
34
|
-
PluginTimeoutError,
|
|
35
|
-
type TurnContext,
|
|
36
|
-
} from "./types.js";
|
|
37
|
-
|
|
38
|
-
const moduleLogger = getLogger("plugin-pipeline");
|
|
39
|
-
|
|
40
|
-
// ─── Default timeouts ───────────────────────────────────────────────────────
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Default per-pipeline timeout budgets in milliseconds. A value of `null`
|
|
44
|
-
* means the runner does NOT arm a timer — the pipeline relies on its
|
|
45
|
-
* downstream for budgeting (e.g. `compaction` defers to the provider-level
|
|
46
|
-
* HTTP timeouts of the summary call it wraps).
|
|
47
|
-
*
|
|
48
|
-
* Callers pass the appropriate entry as `runPipeline`'s `timeoutMs` argument.
|
|
49
|
-
* The design doc locks these numbers in; do not tweak without coordinating
|
|
50
|
-
* a design update.
|
|
51
|
-
*/
|
|
52
|
-
export const DEFAULT_TIMEOUTS: Record<PipelineName, number | null> = {
|
|
53
|
-
compaction: null,
|
|
54
|
-
overflowReduce: null,
|
|
55
|
-
circuitBreaker: null,
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// ─── Composition ────────────────────────────────────────────────────────────
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Compose an ordered list of {@link Middleware}s around a terminal handler
|
|
62
|
-
* using onion semantics. The first element of `middlewares` is the outermost
|
|
63
|
-
* layer.
|
|
64
|
-
*
|
|
65
|
-
* The returned function accepts `(args, ctx)` and runs the entire chain:
|
|
66
|
-
* ```
|
|
67
|
-
* middlewares[0] → middlewares[1] → ... → terminal → ... → middlewares[1] → middlewares[0]
|
|
68
|
-
* ```
|
|
69
|
-
*
|
|
70
|
-
* Middlewares that never call `next` short-circuit the chain — the terminal
|
|
71
|
-
* and any deeper middleware are never invoked. Middlewares that throw abort
|
|
72
|
-
* the chain; the error flows back out through any outer middleware unchanged
|
|
73
|
-
* (no internal try/catch).
|
|
74
|
-
*/
|
|
75
|
-
export function composeMiddleware<A, R>(
|
|
76
|
-
middlewares: ReadonlyArray<Middleware<A, R>>,
|
|
77
|
-
terminal: (args: A) => Promise<R>,
|
|
78
|
-
): (args: A, ctx: TurnContext) => Promise<R> {
|
|
79
|
-
return (args, ctx) => {
|
|
80
|
-
// Walk back-to-front, wrapping each middleware around `next`. The last
|
|
81
|
-
// middleware in the array wraps `terminal`; earlier entries wrap the
|
|
82
|
-
// accumulated chain so they execute first.
|
|
83
|
-
let next: (args: A) => Promise<R> = terminal;
|
|
84
|
-
for (let i = middlewares.length - 1; i >= 0; i--) {
|
|
85
|
-
const mw = middlewares[i]!;
|
|
86
|
-
const downstream = next;
|
|
87
|
-
next = (innerArgs: A) => mw(innerArgs, downstream, ctx);
|
|
88
|
-
}
|
|
89
|
-
return next(args);
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// ─── Abort-signal linking ───────────────────────────────────────────────────
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Return a shallow-cloned `args` object where every `AbortSignal`-typed
|
|
97
|
-
* top-level property is swapped for a signal linked to `internalController`.
|
|
98
|
-
*
|
|
99
|
-
* "Linked" here means: the returned signal aborts when either the caller's
|
|
100
|
-
* original signal aborts OR `internalController` aborts (e.g. the pipeline
|
|
101
|
-
* timer fires). The caller's args are never mutated.
|
|
102
|
-
*
|
|
103
|
-
* When `args` carries no `AbortSignal` property, the original object is
|
|
104
|
-
* returned unchanged — pipelines whose terminals don't consume a signal
|
|
105
|
-
* (e.g. `circuitBreaker`) see identical behavior to before.
|
|
106
|
-
* The return value's `cleanup()` tears down any `addEventListener("abort",
|
|
107
|
-
* ...)` handlers attached to the caller's signal so a pipeline that
|
|
108
|
-
* completes successfully doesn't leak listeners on the caller's controller.
|
|
109
|
-
*/
|
|
110
|
-
function linkAbortSignal<A>(
|
|
111
|
-
args: A,
|
|
112
|
-
internalController: AbortController,
|
|
113
|
-
): { args: A; cleanup: () => void } {
|
|
114
|
-
if (args === null || typeof args !== "object") {
|
|
115
|
-
return { args, cleanup: () => {} };
|
|
116
|
-
}
|
|
117
|
-
const abortListeners: Array<{
|
|
118
|
-
signal: AbortSignal;
|
|
119
|
-
listener: () => void;
|
|
120
|
-
}> = [];
|
|
121
|
-
const record = args as Record<string, unknown>;
|
|
122
|
-
const patched: Record<string, unknown> = { ...record };
|
|
123
|
-
let swappedAny = false;
|
|
124
|
-
for (const key of Object.keys(record)) {
|
|
125
|
-
const value = record[key];
|
|
126
|
-
if (value instanceof AbortSignal) {
|
|
127
|
-
swappedAny = true;
|
|
128
|
-
if (value.aborted) {
|
|
129
|
-
// Caller already aborted — propagate immediately so the inner call
|
|
130
|
-
// sees the abort without waiting for the listener to fire.
|
|
131
|
-
internalController.abort();
|
|
132
|
-
} else {
|
|
133
|
-
const listener = () => internalController.abort();
|
|
134
|
-
value.addEventListener("abort", listener, { once: true });
|
|
135
|
-
abortListeners.push({ signal: value, listener });
|
|
136
|
-
}
|
|
137
|
-
patched[key] = internalController.signal;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
const cleanup = () => {
|
|
141
|
-
for (const { signal, listener } of abortListeners) {
|
|
142
|
-
signal.removeEventListener("abort", listener);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
return { args: (swappedAny ? patched : args) as A, cleanup };
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// ─── Runner ─────────────────────────────────────────────────────────────────
|
|
149
|
-
|
|
150
|
-
type PipelineLogRecord = {
|
|
151
|
-
event: "plugin.pipeline";
|
|
152
|
-
pipeline: PipelineName;
|
|
153
|
-
chain: ReadonlyArray<string>;
|
|
154
|
-
durationMs: number;
|
|
155
|
-
outcome: "success" | "error" | "timeout";
|
|
156
|
-
pluginName?: string;
|
|
157
|
-
errorName?: string;
|
|
158
|
-
errorMessage?: string;
|
|
159
|
-
errorStack?: string;
|
|
160
|
-
timeoutMs?: number;
|
|
161
|
-
requestId: string;
|
|
162
|
-
conversationId: string;
|
|
163
|
-
turnIndex?: number;
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Best-effort detection of a pino-compatible logger on the `TurnContext`.
|
|
168
|
-
*
|
|
169
|
-
* `TurnContext` intentionally doesn't require a logger slot — most code paths
|
|
170
|
-
* use the module-level logger. Some callers (notably plugin-scoped pipelines
|
|
171
|
-
* in later PRs) may attach a child logger via `(ctx as any).logger`. We type
|
|
172
|
-
* the field loosely to avoid coupling `TurnContext` to pino.
|
|
173
|
-
*/
|
|
174
|
-
function selectLogger(ctx: TurnContext): Logger {
|
|
175
|
-
const maybe = (ctx as { logger?: unknown }).logger;
|
|
176
|
-
if (maybe && typeof maybe === "object" && "info" in maybe) {
|
|
177
|
-
return maybe as Logger;
|
|
178
|
-
}
|
|
179
|
-
return moduleLogger;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Execute a named pipeline: compose middleware, run it under an optional
|
|
184
|
-
* timeout, and emit one structured log record covering success, error, or
|
|
185
|
-
* timeout uniformly.
|
|
186
|
-
*
|
|
187
|
-
* @param name The pipeline identifier. Used for telemetry and error
|
|
188
|
-
* attribution.
|
|
189
|
-
* @param middlewares Ordered list of middlewares to wrap around `terminal`.
|
|
190
|
-
* Names for the log `chain` are pulled from `Function.name`
|
|
191
|
-
* (empty strings are kept so length always matches).
|
|
192
|
-
* @param terminal The original behavior. Runs when all middlewares call
|
|
193
|
-
* `next`.
|
|
194
|
-
* @param args Pipeline-specific input payload.
|
|
195
|
-
* @param ctx Per-turn context. May carry an optional `logger` slot;
|
|
196
|
-
* otherwise the module logger is used.
|
|
197
|
-
* @param timeoutMs Deadline in milliseconds. `null`/`undefined` disables
|
|
198
|
-
* the timer entirely (inherits downstream timeouts).
|
|
199
|
-
*
|
|
200
|
-
* @throws {PluginTimeoutError} When `timeoutMs` is non-null and the chain
|
|
201
|
-
* exceeds the budget. `ctx.pluginName` (if set) is attached as the
|
|
202
|
-
* offending plugin.
|
|
203
|
-
* @throws Any error produced by user middleware or the terminal — flows
|
|
204
|
-
* through unchanged.
|
|
205
|
-
*/
|
|
206
|
-
export async function runPipeline<A, R>(
|
|
207
|
-
name: PipelineName,
|
|
208
|
-
middlewares: ReadonlyArray<Middleware<A, R>>,
|
|
209
|
-
terminal: (args: A) => Promise<R>,
|
|
210
|
-
args: A,
|
|
211
|
-
ctx: TurnContext,
|
|
212
|
-
timeoutMs?: number | null,
|
|
213
|
-
): Promise<R> {
|
|
214
|
-
const logger = selectLogger(ctx);
|
|
215
|
-
const chain = middlewares.map((m) => m.name || "anonymous");
|
|
216
|
-
const composed = composeMiddleware(middlewares, terminal);
|
|
217
|
-
const start = performance.now();
|
|
218
|
-
|
|
219
|
-
let outcome: "success" | "error" | "timeout" = "success";
|
|
220
|
-
let thrown: unknown = undefined;
|
|
221
|
-
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
222
|
-
|
|
223
|
-
try {
|
|
224
|
-
if (typeof timeoutMs === "number" && Number.isFinite(timeoutMs)) {
|
|
225
|
-
const budget = timeoutMs;
|
|
226
|
-
// Internal controller: fires on either (a) the timer, so the inner call
|
|
227
|
-
// actually observes the budget breach instead of running forever after
|
|
228
|
-
// `Promise.race` rejects; or (b) the caller's own signal, so external
|
|
229
|
-
// cancellation still reaches the inner call transparently. Any
|
|
230
|
-
// `AbortSignal`-typed property on `args` (e.g. `signal` on
|
|
231
|
-
// `CompactionArgs`, `abortSignal` on `OverflowReduceArgs`) is swapped
|
|
232
|
-
// for this linked signal on a shallow-cloned args object — we never
|
|
233
|
-
// mutate the caller's args.
|
|
234
|
-
const internalController = new AbortController();
|
|
235
|
-
const { args: effectiveArgs, cleanup } = linkAbortSignal(
|
|
236
|
-
args,
|
|
237
|
-
internalController,
|
|
238
|
-
);
|
|
239
|
-
const timeoutPromise = new Promise<never>((_resolve, reject) => {
|
|
240
|
-
timer = setTimeout(() => {
|
|
241
|
-
internalController.abort();
|
|
242
|
-
reject(
|
|
243
|
-
new PluginTimeoutError(
|
|
244
|
-
name,
|
|
245
|
-
ctx.pluginName,
|
|
246
|
-
Math.round(performance.now() - start),
|
|
247
|
-
),
|
|
248
|
-
);
|
|
249
|
-
}, budget);
|
|
250
|
-
});
|
|
251
|
-
try {
|
|
252
|
-
return await Promise.race([
|
|
253
|
-
composed(effectiveArgs, ctx),
|
|
254
|
-
timeoutPromise,
|
|
255
|
-
]);
|
|
256
|
-
} finally {
|
|
257
|
-
cleanup();
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return await composed(args, ctx);
|
|
261
|
-
} catch (err) {
|
|
262
|
-
thrown = err;
|
|
263
|
-
outcome = err instanceof PluginTimeoutError ? "timeout" : "error";
|
|
264
|
-
throw err;
|
|
265
|
-
} finally {
|
|
266
|
-
if (timer !== undefined) clearTimeout(timer);
|
|
267
|
-
const durationMs = Math.round(performance.now() - start);
|
|
268
|
-
const record: PipelineLogRecord = {
|
|
269
|
-
event: "plugin.pipeline",
|
|
270
|
-
pipeline: name,
|
|
271
|
-
chain,
|
|
272
|
-
durationMs,
|
|
273
|
-
outcome,
|
|
274
|
-
requestId: ctx.requestId,
|
|
275
|
-
conversationId: ctx.conversationId,
|
|
276
|
-
};
|
|
277
|
-
if (ctx.turnIndex !== undefined) record.turnIndex = ctx.turnIndex;
|
|
278
|
-
if (ctx.pluginName !== undefined) record.pluginName = ctx.pluginName;
|
|
279
|
-
if (typeof timeoutMs === "number" && Number.isFinite(timeoutMs)) {
|
|
280
|
-
record.timeoutMs = timeoutMs;
|
|
281
|
-
}
|
|
282
|
-
if (thrown !== undefined) {
|
|
283
|
-
if (thrown instanceof Error) {
|
|
284
|
-
record.errorName = thrown.name;
|
|
285
|
-
record.errorMessage = thrown.message;
|
|
286
|
-
if (thrown.stack) record.errorStack = thrown.stack;
|
|
287
|
-
} else {
|
|
288
|
-
record.errorName = "NonError";
|
|
289
|
-
record.errorMessage = String(thrown);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
logger.info(record, "plugin.pipeline");
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
14
|
|
|
296
15
|
// ─── Hook runner ────────────────────────────────────────────────────────────
|
|
297
16
|
|
|
@@ -302,12 +21,6 @@ export async function runPipeline<A, R>(
|
|
|
302
21
|
* that replaces the threaded value for subsequent hooks. The final context
|
|
303
22
|
* after the chain settles is returned.
|
|
304
23
|
*
|
|
305
|
-
* `runHook` is the hook-side counterpart to {@link runPipeline}:
|
|
306
|
-
* `runPipeline` composes middleware around a terminal handler for stateful
|
|
307
|
-
* request/response pipelines (compaction, overflow reduction, etc.);
|
|
308
|
-
* `runHook` walks ordered hook functions for declarative chain-style
|
|
309
|
-
* context transformations (`user-prompt-submit`, `post-tool-use`).
|
|
310
|
-
*
|
|
311
24
|
* @param name The hook identifier — pick one from {@link HOOKS}.
|
|
312
25
|
* @param initialCtx Context the first hook receives.
|
|
313
26
|
* @returns The final context after the chain settles. Same reference as
|
package/src/plugins/registry.ts
CHANGED
|
@@ -10,20 +10,16 @@
|
|
|
10
10
|
* late-arriving registrations.
|
|
11
11
|
*
|
|
12
12
|
* Registration is order-preserving: {@link getRegisteredPlugins} and
|
|
13
|
-
* {@link
|
|
14
|
-
*
|
|
15
|
-
* in the pipeline runner.
|
|
13
|
+
* {@link getHooksFor} reflect the order in which {@link registerPlugin} was
|
|
14
|
+
* called, which in turn determines the order plugin hooks run.
|
|
16
15
|
*
|
|
17
16
|
* This module does not call `Plugin.init()` — that is the job of the
|
|
18
|
-
* bootstrap
|
|
19
|
-
* later PRs introduce consumers.
|
|
17
|
+
* bootstrap. It also does not wire the registry into the daemon.
|
|
20
18
|
*
|
|
21
|
-
* Design doc: `.private/plans/agent-plugin-system.md
|
|
19
|
+
* Design doc: `.private/plans/agent-plugin-system.md`.
|
|
22
20
|
*/
|
|
23
21
|
|
|
24
22
|
import {
|
|
25
|
-
type PipelineMiddlewareMap,
|
|
26
|
-
type PipelineName,
|
|
27
23
|
type Plugin,
|
|
28
24
|
PluginExecutionError,
|
|
29
25
|
type PluginHookFn,
|
|
@@ -33,7 +29,7 @@ import {
|
|
|
33
29
|
|
|
34
30
|
/**
|
|
35
31
|
* Registered plugins keyed by `manifest.name`. A `Map` preserves insertion
|
|
36
|
-
* order, which the registry relies on for
|
|
32
|
+
* order, which the registry relies on for hook ordering and
|
|
37
33
|
* `getRegisteredPlugins()` output.
|
|
38
34
|
*/
|
|
39
35
|
const registeredPlugins = new Map<string, Plugin>();
|
|
@@ -46,8 +42,7 @@ const registeredPlugins = new Map<string, Plugin>();
|
|
|
46
42
|
* top-level `await` later resolves and still tries to call
|
|
47
43
|
* {@link registerPlugin}. Without the latch such a late arrival would land in
|
|
48
44
|
* the registry after `bootstrapPlugins()` has already walked it, leaving the
|
|
49
|
-
* plugin visible
|
|
50
|
-
* `init()` hook never invoked.
|
|
45
|
+
* plugin visible in the registry with its `init()` hook never invoked.
|
|
51
46
|
*/
|
|
52
47
|
let registrationClosed = false;
|
|
53
48
|
|
|
@@ -66,7 +61,7 @@ let registrationClosed = false;
|
|
|
66
61
|
*
|
|
67
62
|
* On success the plugin is appended to the registry in the order this
|
|
68
63
|
* function is called. This function does NOT invoke `plugin.init()` — that
|
|
69
|
-
* runs in the bootstrap sequence
|
|
64
|
+
* runs in the bootstrap sequence.
|
|
70
65
|
*/
|
|
71
66
|
export function registerPlugin(plugin: Plugin): void {
|
|
72
67
|
// Basic shape / required-field validation. The type system already enforces
|
|
@@ -143,27 +138,6 @@ export function getRegisteredPlugins(): Plugin[] {
|
|
|
143
138
|
return Array.from(registeredPlugins.values());
|
|
144
139
|
}
|
|
145
140
|
|
|
146
|
-
/**
|
|
147
|
-
* Collect the middleware each registered plugin contributes for the given
|
|
148
|
-
* pipeline, in registration order. Consumers feed the returned array into the
|
|
149
|
-
* pipeline runner's `composeMiddleware` helper (PR 12), which applies the
|
|
150
|
-
* outermost-first convention.
|
|
151
|
-
*
|
|
152
|
-
* Plugins that don't declare a middleware for `pipeline` are skipped.
|
|
153
|
-
*/
|
|
154
|
-
export function getMiddlewaresFor<P extends PipelineName>(
|
|
155
|
-
pipeline: P,
|
|
156
|
-
): PipelineMiddlewareMap[P][] {
|
|
157
|
-
const out: PipelineMiddlewareMap[P][] = [];
|
|
158
|
-
for (const plugin of registeredPlugins.values()) {
|
|
159
|
-
const middleware = plugin.middleware?.[pipeline];
|
|
160
|
-
if (middleware) {
|
|
161
|
-
out.push(middleware);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return out;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
141
|
/**
|
|
168
142
|
* Collect every registered plugin's hook for the given name, in
|
|
169
143
|
* registration order. Plugins that don't declare a hook for `name` are
|
|
@@ -208,10 +182,8 @@ export function closeRegistration(): void {
|
|
|
208
182
|
|
|
209
183
|
/**
|
|
210
184
|
* Remove a plugin from the registry. Invoked from the bootstrap's failure path
|
|
211
|
-
* after {@link Plugin.onShutdown} and contribution teardown have run, so
|
|
212
|
-
*
|
|
213
|
-
* mid-bootstrap. Without this, every subsequent pipeline invocation would
|
|
214
|
-
* re-enter the uninitialized plugin's middleware.
|
|
185
|
+
* after {@link Plugin.onShutdown} and contribution teardown have run, so the
|
|
186
|
+
* registry no longer exposes a plugin whose `init()` aborted mid-bootstrap.
|
|
215
187
|
* Safe to call on an already-absent name (no-op).
|
|
216
188
|
*/
|
|
217
189
|
export function unregisterPlugin(name: string): void {
|