@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
|
@@ -23,17 +23,22 @@ import {
|
|
|
23
23
|
import type { Provider } from "../providers/types.js";
|
|
24
24
|
import { getLogger } from "../util/logger.js";
|
|
25
25
|
import { truncate } from "../util/truncate.js";
|
|
26
|
+
import {
|
|
27
|
+
buildAccessRequestContractText,
|
|
28
|
+
buildAccessRequestInviteDirective,
|
|
29
|
+
hasAccessRequestInstructions,
|
|
30
|
+
hasInviteFlowDirective,
|
|
31
|
+
} from "./access-request-copy.js";
|
|
26
32
|
import {
|
|
27
33
|
buildConversationCandidates,
|
|
28
34
|
type ConversationCandidateSet,
|
|
29
35
|
serializeCandidatesForPrompt,
|
|
30
36
|
} from "./conversation-candidates.js";
|
|
31
37
|
import {
|
|
32
|
-
buildAccessRequestContractText,
|
|
33
|
-
buildAccessRequestInviteDirective,
|
|
34
38
|
composeFallbackCopy,
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
deriveTitle,
|
|
40
|
+
nonEmpty,
|
|
41
|
+
readPayloadString,
|
|
37
42
|
} from "./copy-composer.js";
|
|
38
43
|
import { createDecision } from "./decisions-store.js";
|
|
39
44
|
import {
|
|
@@ -56,21 +61,6 @@ const log = getLogger("notification-decision-engine");
|
|
|
56
61
|
const DECISION_TIMEOUT_MS = 15_000;
|
|
57
62
|
const PROMPT_VERSION = "v4";
|
|
58
63
|
|
|
59
|
-
/**
|
|
60
|
-
* Derive a short notification title from a message body. Used when an
|
|
61
|
-
* assistant_tool-sourced signal supplies `requestedMessage` without an
|
|
62
|
-
* explicit `requestedTitle`: trims to the first sentence terminator when
|
|
63
|
-
* present, then caps the result at 60 characters with an ellipsis.
|
|
64
|
-
*/
|
|
65
|
-
function deriveTitle(body: string): string {
|
|
66
|
-
const firstSentenceEnd = body.search(/[.!?](\s|$)/);
|
|
67
|
-
const candidate =
|
|
68
|
-
firstSentenceEnd > 0 ? body.slice(0, firstSentenceEnd + 1) : body;
|
|
69
|
-
return candidate.length > 60
|
|
70
|
-
? candidate.slice(0, 60).trim() + "…"
|
|
71
|
-
: candidate.trim();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
64
|
/**
|
|
75
65
|
* Maximum character budget for identity context injected into the notification
|
|
76
66
|
* decision prompt. We truncate to prevent oversized prompts when SOUL.md /
|
|
@@ -768,24 +758,15 @@ export async function evaluateSignal(
|
|
|
768
758
|
// classifier entirely. The producer has already done the routing and
|
|
769
759
|
// copy decisions — we just enforce the standard post-decision guards
|
|
770
760
|
// and persist the result.
|
|
771
|
-
|
|
772
|
-
signal.
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
typeof (signal.contextPayload as Record<string, unknown>)
|
|
776
|
-
.requestedMessage === "string" &&
|
|
777
|
-
(
|
|
778
|
-
(signal.contextPayload as Record<string, unknown>)
|
|
779
|
-
.requestedMessage as string
|
|
780
|
-
).trim().length > 0
|
|
781
|
-
) {
|
|
761
|
+
const requestedBody = nonEmpty(
|
|
762
|
+
readPayloadString(signal.contextPayload, "requestedMessage"),
|
|
763
|
+
);
|
|
764
|
+
if (signal.sourceChannel === "assistant_tool" && requestedBody) {
|
|
782
765
|
const payload = signal.contextPayload as Record<string, unknown>;
|
|
783
|
-
const body =
|
|
766
|
+
const body = requestedBody;
|
|
784
767
|
const title =
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
? (payload.requestedTitle as string).trim()
|
|
788
|
-
: deriveTitle(body);
|
|
768
|
+
nonEmpty(readPayloadString(signal.contextPayload, "requestedTitle")) ??
|
|
769
|
+
deriveTitle(body);
|
|
789
770
|
const isUrgent =
|
|
790
771
|
signal.attentionHints.urgency === "critical" ||
|
|
791
772
|
signal.attentionHints.urgency === "high";
|
|
@@ -22,6 +22,7 @@ import { getConversation } from "../memory/conversation-crud.js";
|
|
|
22
22
|
import { isBackgroundConversationType } from "../memory/conversation-types.js";
|
|
23
23
|
import { getLogger } from "../util/logger.js";
|
|
24
24
|
import { isConversationSeedSane } from "./conversation-seed-composer.js";
|
|
25
|
+
import { readPayloadString } from "./copy-composer.js";
|
|
25
26
|
import type { NotificationSignal } from "./signal.js";
|
|
26
27
|
import type { NotificationDecision, RenderedChannelCopy } from "./types.js";
|
|
27
28
|
|
|
@@ -231,12 +232,6 @@ function resolveHomeFeedMirror(
|
|
|
231
232
|
return { mirror: false };
|
|
232
233
|
}
|
|
233
234
|
|
|
234
|
-
function readPayloadString(payload: unknown, key: string): string | undefined {
|
|
235
|
-
if (!payload || typeof payload !== "object") return undefined;
|
|
236
|
-
const value = (payload as Record<string, unknown>)[key];
|
|
237
|
-
return typeof value === "string" ? value : undefined;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
235
|
/**
|
|
241
236
|
* Routing-intent enforcement can prune `selectedChannels` without also
|
|
242
237
|
* pruning `renderedCopy`, so iterating `renderedCopy` directly risks
|
|
@@ -20,10 +20,14 @@ export const HOOKS = {
|
|
|
20
20
|
SHUTDOWN: "shutdown",
|
|
21
21
|
/** Fires once per user turn, immediately before the agent loop receives `runMessages`. */
|
|
22
22
|
USER_PROMPT_SUBMIT: "user-prompt-submit",
|
|
23
|
+
/** Fires immediately before each provider call. A hook may edit the outbound request (e.g. the system prompt) and opt the turn into deferred output streaming. */
|
|
24
|
+
PRE_MODEL_CALL: "pre-model-call",
|
|
23
25
|
/** Fires once per tool result, after the tool returns and before the result is sent to the provider. */
|
|
24
26
|
POST_TOOL_USE: "post-tool-use",
|
|
25
27
|
/** Fires when the model yields a response with no tool calls — the run's stop boundary. Decides whether to stop or continue with a follow-up turn. */
|
|
26
28
|
STOP: "stop",
|
|
29
|
+
/** Fires for each finalized assistant message, once per model call, before it is persisted/streamed-final. A hook may transform the message content. */
|
|
30
|
+
POST_MODEL_CALL: "post-model-call",
|
|
27
31
|
} as const;
|
|
28
32
|
|
|
29
33
|
/** Union of every hook name declared in {@link HOOKS}. */
|
package/src/plugin-api/index.ts
CHANGED
|
@@ -11,34 +11,46 @@
|
|
|
11
11
|
*
|
|
12
12
|
* ## Surface today
|
|
13
13
|
*
|
|
14
|
-
* The
|
|
15
|
-
*
|
|
16
|
-
* `
|
|
17
|
-
*
|
|
18
|
-
* runtime — plugin authors never call a runtime registration function.
|
|
14
|
+
* The primary authoring model is **declarative**: a plugin is a directory
|
|
15
|
+
* whose `package.json` is the manifest and whose `hooks/` / `tools/` /
|
|
16
|
+
* `skills/` / `routes/` subdirectories are the contributions. The host
|
|
17
|
+
* introspects the directory at load time and wires it into the runtime.
|
|
19
18
|
*
|
|
20
|
-
*
|
|
19
|
+
* Most of what this module exposes is therefore types: the context shapes
|
|
21
20
|
* the host hands to plugin hooks, and the logger shape they include.
|
|
22
21
|
*
|
|
22
|
+
* Alongside those types, the module exposes a small set of **runtime
|
|
23
|
+
* handles** for plugins that need to reach the assistant's live singletons
|
|
24
|
+
* (subscribe to runtime events, read secrets). These resolve to the
|
|
25
|
+
* assistant's own instances: the host parks the loaded plugin-api namespace
|
|
26
|
+
* on `globalThis` at boot, and the workspace-level shim re-binds each
|
|
27
|
+
* runtime export from there — so a plugin's
|
|
28
|
+
* `import { assistantEventHub } from "@vellumai/plugin-api"` lands on the
|
|
29
|
+
* same singleton the assistant uses, even when the daemon is a
|
|
30
|
+
* `bun --compile` binary where an absolute-path import would load a
|
|
31
|
+
* disjoint module copy.
|
|
32
|
+
*
|
|
33
|
+
* - {@link assistantEventHub} — the assistant's pub/sub hub for runtime events
|
|
34
|
+
* - {@link getSecureKeyAsync} — read a secret from secure storage
|
|
35
|
+
*
|
|
23
36
|
* - {@link PluginInitContext} — passed to `init` hook at bootstrap
|
|
24
37
|
* - {@link PluginShutdownContext} — passed to `shutdown` hook at teardown
|
|
25
38
|
* - {@link UserPromptSubmitContext} — passed to `user-prompt-submit` hook,
|
|
26
39
|
* fired immediately before the agent loop receives a user's prompt
|
|
40
|
+
* - {@link PreModelCallContext} — passed to `pre-model-call` hook, fired
|
|
41
|
+
* before each provider call to edit the request / defer output streaming
|
|
27
42
|
* - {@link PostToolUseContext} — passed to `post-tool-use` hook, fired once
|
|
28
43
|
* per tool result before it joins the provider-bound history
|
|
29
44
|
* - {@link StopContext} — passed to `stop` hook, fired when the model yields
|
|
30
45
|
* a response with no tool calls
|
|
46
|
+
* - {@link PostModelCallContext} — passed to `post-model-call` hook,
|
|
47
|
+
* fired for each finalized assistant message to transform its content
|
|
31
48
|
* - {@link PluginHookFn} — signature every lifecycle hook implements
|
|
32
49
|
* - {@link PluginLogger} — pino-compatible logger shape on the contexts
|
|
33
50
|
* - {@link ToolDefinition} — author-facing tool spec (default-export shape
|
|
34
51
|
* for both plugin tool files and workspace tool files)
|
|
35
52
|
* - {@link ToolContext} — passed to a plugin tool's `execute` method
|
|
36
53
|
* - {@link ToolExecutionResult} — return shape of a plugin tool's `execute`
|
|
37
|
-
*
|
|
38
|
-
* Pipeline-argument types (`MemoryArgs`, `CompactionArgs`, etc.) currently
|
|
39
|
-
* live in `assistant/src/plugins/types.ts` and have not yet migrated into
|
|
40
|
-
* this package. A follow-up PR will move them into this surface as the
|
|
41
|
-
* per-pipeline schemas stabilize.
|
|
42
54
|
*/
|
|
43
55
|
|
|
44
56
|
export type { HookName } from "./constants.js";
|
|
@@ -48,7 +60,9 @@ export type {
|
|
|
48
60
|
PluginInitContext,
|
|
49
61
|
PluginLogger,
|
|
50
62
|
PluginShutdownContext,
|
|
63
|
+
PostModelCallContext,
|
|
51
64
|
PostToolUseContext,
|
|
65
|
+
PreModelCallContext,
|
|
52
66
|
StopContext,
|
|
53
67
|
StopDecision,
|
|
54
68
|
ToolContext,
|
|
@@ -57,3 +71,18 @@ export type {
|
|
|
57
71
|
UserPromptSubmitContext,
|
|
58
72
|
} from "./types.js";
|
|
59
73
|
export { RiskLevel } from "./types.js";
|
|
74
|
+
|
|
75
|
+
// ─── Runtime handles ─────────────────────────────────────────────────────────
|
|
76
|
+
// Values (not just types) that plugins consume at module-load / init time.
|
|
77
|
+
// Workspace-local plugins resolve these via the boot-time shim, which
|
|
78
|
+
// re-binds each from the assistant's globalThis-parked namespace so they
|
|
79
|
+
// share module identity with the assistant's own singletons.
|
|
80
|
+
export type { AssistantEvent } from "../runtime/assistant-event.js";
|
|
81
|
+
export type {
|
|
82
|
+
AssistantEventCallback,
|
|
83
|
+
AssistantEventFilter,
|
|
84
|
+
AssistantEventHub,
|
|
85
|
+
AssistantEventSubscription,
|
|
86
|
+
} from "../runtime/assistant-event-hub.js";
|
|
87
|
+
export { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
88
|
+
export { getSecureKeyAsync } from "../security/secure-keys.js";
|
package/src/plugin-api/types.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* removing is breaking and gated on a major bump.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
7
8
|
import type {
|
|
8
9
|
ContentBlock,
|
|
9
10
|
Message,
|
|
@@ -51,8 +52,10 @@ export interface PluginLogger {
|
|
|
51
52
|
* - `init` — {@link PluginInitContext}
|
|
52
53
|
* - `shutdown` — {@link PluginShutdownContext}
|
|
53
54
|
* - `user-prompt-submit` — {@link UserPromptSubmitContext}
|
|
55
|
+
* - `pre-model-call` — {@link PreModelCallContext}
|
|
54
56
|
* - `post-tool-use` — {@link PostToolUseContext}
|
|
55
57
|
* - `stop` — {@link StopContext}
|
|
58
|
+
* - `post-model-call` — {@link PostModelCallContext}
|
|
56
59
|
*/
|
|
57
60
|
export type PluginHookFn<TCtx = unknown> = (ctx: TCtx) => Promise<TCtx | void>;
|
|
58
61
|
|
|
@@ -127,6 +130,39 @@ export interface PluginShutdownContext {
|
|
|
127
130
|
export interface UserPromptSubmitContext {
|
|
128
131
|
/** Conversation ID the user prompt was submitted on. */
|
|
129
132
|
readonly conversationId: string;
|
|
133
|
+
/**
|
|
134
|
+
* Persisted ID of the user message that triggered this turn. Hooks that
|
|
135
|
+
* attach turn-scoped metadata to the originating message (e.g. recording an
|
|
136
|
+
* injected memory block so it survives a conversation reload) key off this
|
|
137
|
+
* row id rather than the in-memory message arrays, whose entries carry no id.
|
|
138
|
+
*/
|
|
139
|
+
readonly userMessageId: string;
|
|
140
|
+
/**
|
|
141
|
+
* Stable ID for the request that drives this turn. Hooks that perform
|
|
142
|
+
* runtime injection forward it onto the injector turn context so the
|
|
143
|
+
* assembled blocks are attributed to the originating request; it is fixed
|
|
144
|
+
* for the turn and cannot be recovered from the message arrays.
|
|
145
|
+
*/
|
|
146
|
+
readonly requestId: string;
|
|
147
|
+
/**
|
|
148
|
+
* Active inference profile key to surface in this turn's context, or `null`
|
|
149
|
+
* when the profile is unchanged since the one last announced to the model.
|
|
150
|
+
* Hooks that emit the `model_profile` grounding line resolve the
|
|
151
|
+
* human-readable label (and model id) from this key via the workspace LLM
|
|
152
|
+
* config rather than receiving the rendered string — the key is the minimal
|
|
153
|
+
* turn input the message arrays cannot carry.
|
|
154
|
+
*/
|
|
155
|
+
readonly modelProfileKey: string | null;
|
|
156
|
+
/**
|
|
157
|
+
* Whether the turn has no human present to answer clarification questions
|
|
158
|
+
* (e.g. a scheduled, background, or headless run). Resolved once at turn
|
|
159
|
+
* start from the run's interactivity option, falling back to live client
|
|
160
|
+
* presence — a single value the hook reads rather than re-deriving from
|
|
161
|
+
* mutable conversation state that can flip mid-turn. Hooks that assemble the
|
|
162
|
+
* turn's runtime injections forward it so the assembled context reflects the
|
|
163
|
+
* turn's interactivity.
|
|
164
|
+
*/
|
|
165
|
+
readonly isNonInteractive: boolean;
|
|
130
166
|
/**
|
|
131
167
|
* The text of the user prompt that triggered this turn — the resolved
|
|
132
168
|
* user message (after slash-command expansion), independent of any
|
|
@@ -288,3 +324,75 @@ export interface StopContext {
|
|
|
288
324
|
*/
|
|
289
325
|
readonly logger: PluginLogger;
|
|
290
326
|
}
|
|
327
|
+
|
|
328
|
+
// ─── Pre-model-call hook context ─────────────────────────────────────────────
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Context passed to the `pre-model-call` hook. Fires immediately before each
|
|
332
|
+
* provider call — once per model call within a turn, including tool-result
|
|
333
|
+
* follow-up calls. Because it runs for every provider call (background, subagent,
|
|
334
|
+
* and compaction work can share a conversation), hooks MUST self-gate on
|
|
335
|
+
* {@link callSite} / {@link conversationId} before acting.
|
|
336
|
+
*
|
|
337
|
+
* A hook may edit the outbound request by replacing {@link systemPrompt}, and may
|
|
338
|
+
* opt this turn into deferred output streaming via {@link deferAssistantOutput}.
|
|
339
|
+
* Mutate the context in place or return a new one; throwing is contained by the
|
|
340
|
+
* loop (the call proceeds with the original request).
|
|
341
|
+
*/
|
|
342
|
+
export interface PreModelCallContext {
|
|
343
|
+
/** Conversation ID the call belongs to. */
|
|
344
|
+
readonly conversationId: string;
|
|
345
|
+
/**
|
|
346
|
+
* The call site this provider call serves — `"mainAgent"` for the user-facing
|
|
347
|
+
* reply, or a background/utility site. Omitted by call sites that don't tag one.
|
|
348
|
+
*/
|
|
349
|
+
readonly callSite?: LLMCallSite;
|
|
350
|
+
/**
|
|
351
|
+
* The system prompt about to be sent. A hook may replace it (e.g. strip or
|
|
352
|
+
* append a section); the loop sends the resulting value.
|
|
353
|
+
*/
|
|
354
|
+
systemPrompt: string | undefined;
|
|
355
|
+
/**
|
|
356
|
+
* Seeded `false`. When a hook sets it `true`, the loop suppresses this turn's
|
|
357
|
+
* live assistant `text_delta` stream; a `post-model-call` hook is then
|
|
358
|
+
* expected to produce the text the client sees (emitted once, after the reply
|
|
359
|
+
* is finalized). Lets a plugin replace streamed output wholesale — e.g.
|
|
360
|
+
* redaction that needs the full message — instead of leaking the raw stream.
|
|
361
|
+
*/
|
|
362
|
+
deferAssistantOutput: boolean;
|
|
363
|
+
/** Logger scoped to the current turn (tag structured fields with `{ plugin }`). */
|
|
364
|
+
readonly logger: PluginLogger;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// ─── Post-model-call hook context ────────────────────────────────────────────
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Context passed to the `post-model-call` hook. Fires for each finalized
|
|
371
|
+
* assistant message — once per model call, at the message-complete boundary —
|
|
372
|
+
* before the message is persisted and (if deferred) streamed-final. Unlike
|
|
373
|
+
* {@link StopContext}'s read-only `responseContent` (which exists for the stop
|
|
374
|
+
* decision), {@link content} is mutable: the loop adopts the hook's result as the
|
|
375
|
+
* persisted and streamed message.
|
|
376
|
+
*
|
|
377
|
+
* Fires on tool-bearing turns too (a reply can carry both text and `tool_use`),
|
|
378
|
+
* so a hook should transform only the blocks it owns and leave others — notably
|
|
379
|
+
* `tool_use` — intact. Runs for every finalized message regardless of call site;
|
|
380
|
+
* hooks MUST self-gate on {@link callSite} / {@link conversationId}. Mutate in
|
|
381
|
+
* place or return a new context; throwing is contained by the loop (the original
|
|
382
|
+
* content is kept).
|
|
383
|
+
*/
|
|
384
|
+
export interface PostModelCallContext {
|
|
385
|
+
/** Conversation ID the message belongs to. */
|
|
386
|
+
readonly conversationId: string;
|
|
387
|
+
/** The call site this message serves — `"mainAgent"` for the user-facing reply. */
|
|
388
|
+
readonly callSite?: LLMCallSite;
|
|
389
|
+
/**
|
|
390
|
+
* The finalized message content. Mutable — transform the text blocks and leave
|
|
391
|
+
* `tool_use` (and other non-text blocks) intact.
|
|
392
|
+
*/
|
|
393
|
+
content: ContentBlock[];
|
|
394
|
+
/** Provider-reported stop reason for the turn, when reported. */
|
|
395
|
+
readonly stopReason: string | null | undefined;
|
|
396
|
+
/** Logger scoped to the current turn (tag structured fields with `{ plugin }`). */
|
|
397
|
+
readonly logger: PluginLogger;
|
|
398
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default compaction implementation.
|
|
3
|
+
*
|
|
4
|
+
* Summarizes conversation history when the context window fills up by
|
|
5
|
+
* delegating to the conversation's {@link ContextWindowManager}. The agent loop
|
|
6
|
+
* calls {@link defaultCompact} directly with a {@link CompactionContext}; the
|
|
7
|
+
* request carries the conversational inputs while the compaction module resolves
|
|
8
|
+
* (and, if needed, builds) the manager from its per-conversation store.
|
|
9
|
+
*
|
|
10
|
+
* This module is side-effect free: importing it does not register any plugin.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { Message } from "../../../providers/types.js";
|
|
14
|
+
import type { TrustClass } from "../../../runtime/actor-trust-resolver.js";
|
|
15
|
+
import { PluginExecutionError } from "../../types.js";
|
|
16
|
+
import { getContextWindowManager } from "./manager-store.js";
|
|
17
|
+
import type {
|
|
18
|
+
ContextWindowResult,
|
|
19
|
+
EmergencyCompactOptions,
|
|
20
|
+
} from "./window-manager.js";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Name under which the default compaction plugin registers. Exposed so call
|
|
24
|
+
* sites can attribute compaction failures to the default plugin.
|
|
25
|
+
*/
|
|
26
|
+
export const DEFAULT_COMPACTION_PLUGIN_NAME = "default-compaction";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Self-describing compaction request handed to {@link defaultCompact}. Carries
|
|
30
|
+
* the conversational inputs plus the `conversationId` the compaction module
|
|
31
|
+
* resolves its manager from, so callers never hold or pass a manager handle and
|
|
32
|
+
* the request can grow toward a model-facing compaction-method shape without
|
|
33
|
+
* coupling callers to the manager's option bag.
|
|
34
|
+
*/
|
|
35
|
+
export interface CompactionContext {
|
|
36
|
+
/** Conversation whose manager performs the compaction. */
|
|
37
|
+
conversationId: string;
|
|
38
|
+
/** Message history to consider for compaction. */
|
|
39
|
+
messages: Message[];
|
|
40
|
+
/** Abort signal forwarded to the compaction summary call. */
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
/** Skip the auto-threshold check (forced/overflow/emergency compaction). */
|
|
43
|
+
force?: boolean;
|
|
44
|
+
/** Per-conversation inference-profile override for the summary call. */
|
|
45
|
+
overrideProfile?: string | null;
|
|
46
|
+
/** Pre-computed token estimate from a prior `shouldCompact()` call. */
|
|
47
|
+
precomputedEstimate?: number;
|
|
48
|
+
/** Legacy keep-boundary hint forwarded to the compactor. */
|
|
49
|
+
minKeepRecentUserTurns?: number;
|
|
50
|
+
/** Trust class of the actor whose turn triggered compaction. */
|
|
51
|
+
actorTrustClass?: TrustClass;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Run compaction for the turn: resolves the conversation's context window
|
|
56
|
+
* manager from the compaction store (building it on first access) and returns
|
|
57
|
+
* the (possibly summarized) message history.
|
|
58
|
+
*/
|
|
59
|
+
export async function defaultCompact(
|
|
60
|
+
context: CompactionContext,
|
|
61
|
+
): Promise<ContextWindowResult> {
|
|
62
|
+
const { conversationId, messages, signal, ...options } = context;
|
|
63
|
+
const manager = getContextWindowManager(conversationId);
|
|
64
|
+
if (manager == null) {
|
|
65
|
+
throw new PluginExecutionError(
|
|
66
|
+
`default-compaction: no ContextWindowManager registered for conversation ${conversationId} — the conversation must register one before compaction runs`,
|
|
67
|
+
DEFAULT_COMPACTION_PLUGIN_NAME,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return manager.maybeCompact(messages, signal, options);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Self-describing emergency-compaction request handed to
|
|
75
|
+
* {@link defaultEmergencyCompact}. Mirrors {@link CompactionContext} but
|
|
76
|
+
* carries the provider-reported token estimate at the overflow that triggered
|
|
77
|
+
* recovery, which sizes the summarize-around-last-tool-pair cut.
|
|
78
|
+
*/
|
|
79
|
+
export interface EmergencyCompactionContext extends EmergencyCompactOptions {
|
|
80
|
+
/** Conversation whose manager performs the emergency compaction. */
|
|
81
|
+
conversationId: string;
|
|
82
|
+
/** Message history to summarize around the last tool_use/tool_result pair. */
|
|
83
|
+
messages: Message[];
|
|
84
|
+
/** Abort signal forwarded to the compaction summary call. */
|
|
85
|
+
signal?: AbortSignal;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Run emergency mid-turn compaction for the turn: resolves the conversation's
|
|
90
|
+
* context window manager from the compaction store and summarizes everything
|
|
91
|
+
* before the last tool_use/tool_result pair, preserving the agent's most recent
|
|
92
|
+
* action context while aggressively compressing earlier history.
|
|
93
|
+
*/
|
|
94
|
+
export async function defaultEmergencyCompact(
|
|
95
|
+
context: EmergencyCompactionContext,
|
|
96
|
+
): Promise<ContextWindowResult> {
|
|
97
|
+
const { conversationId, messages, signal, ...options } = context;
|
|
98
|
+
const manager = getContextWindowManager(conversationId);
|
|
99
|
+
if (manager == null) {
|
|
100
|
+
throw new PluginExecutionError(
|
|
101
|
+
`default-compaction: no ContextWindowManager registered for conversation ${conversationId} — the conversation must register one before emergency compaction runs`,
|
|
102
|
+
DEFAULT_COMPACTION_PLUGIN_NAME,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return manager.emergencyCompact(messages, options, signal);
|
|
106
|
+
}
|