@vellumai/assistant 0.8.7 → 0.8.8-dev.202606052332.17fc8ea
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/Dockerfile +20 -4
- package/bun.lock +2 -2
- package/docker-entrypoint.sh +4 -2
- package/docker-init-apt-root.sh +3 -1
- package/docker-kata-apt-env.sh +3 -1
- package/docker-kata-runtime-family.sh +12 -0
- package/docs/architecture/memory.md +1 -1
- package/examples/plugins/echo/README.md +61 -66
- 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/server-message.ts +3 -3
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
- package/openapi.yaml +3378 -335
- package/package.json +2 -2
- package/scripts/generate-openapi.ts +68 -41
- package/src/__tests__/agent-loop-exit-reason.test.ts +35 -93
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +37 -87
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -3
- package/src/__tests__/anthropic-provider.test.ts +95 -2
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/assistant-event-hub.test.ts +25 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
- package/src/__tests__/{conversation-stream-state.test.ts → assistant-stream-state.test.ts} +252 -91
- package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +6 -0
- package/src/__tests__/btw-routes.test.ts +62 -3
- package/src/__tests__/build-persisted-content.test.ts +184 -0
- package/src/__tests__/catalog-files.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__/clawhub-files.test.ts +1 -1
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +132 -0
- package/src/__tests__/compaction.benchmark.test.ts +0 -30
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +57 -19
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +6 -5
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -7
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +316 -1143
- package/src/__tests__/conversation-agent-loop.test.ts +638 -1655
- package/src/__tests__/conversation-analysis-routes.test.ts +6 -0
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-history-web-search.test.ts +11 -1
- package/src/__tests__/conversation-pairing.test.ts +4 -31
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +6 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +30 -10
- package/src/__tests__/conversation-queue.test.ts +2 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +6 -5
- package/src/__tests__/conversation-runtime-assembly.test.ts +310 -300
- package/src/__tests__/conversation-runtime-workspace.test.ts +105 -45
- package/src/__tests__/conversation-slash-commands.test.ts +8 -42
- package/src/__tests__/conversation-slash-queue.test.ts +6 -1
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +84 -0
- package/src/__tests__/conversation-sync-tags.test.ts +27 -15
- package/src/__tests__/conversation-title-service.test.ts +135 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +17 -16
- package/src/__tests__/conversation-workspace-injection.test.ts +67 -2
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +7 -6
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/cross-provider-web-search.test.ts +214 -1
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +5 -0
- package/src/__tests__/dm-persistence.test.ts +5 -1
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/empty-response-hook.test.ts +304 -0
- package/src/__tests__/feature-flag-test-helpers.ts +2 -2
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/gateway-only-guard.test.ts +12 -2
- package/src/__tests__/gemini-image-service.test.ts +13 -0
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -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__/helpers/mock-provider.ts +110 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
- package/src/__tests__/history-repair-hook.test.ts +1 -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__/identity-intro-cache.test.ts +12 -100
- package/src/__tests__/identity-routes.test.ts +248 -7
- package/src/__tests__/inbound-slack-persistence.test.ts +5 -1
- package/src/__tests__/injector-background-turn.test.ts +3 -9
- package/src/__tests__/injector-chain.test.ts +139 -275
- package/src/__tests__/injector-disk-pressure.test.ts +75 -41
- package/src/__tests__/injector-document-comments.test.ts +3 -3
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
- package/src/__tests__/injector-v3-suppression.test.ts +31 -37
- package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
- package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
- package/src/__tests__/list-messages-page-latest.test.ts +60 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +20 -0
- package/src/__tests__/llm-usage-store.test.ts +223 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
- package/src/__tests__/native-web-search.test.ts +191 -0
- package/src/__tests__/onboarding-template-contract.test.ts +2 -0
- package/src/__tests__/openai-image-service.test.ts +17 -0
- package/src/__tests__/openai-provider.test.ts +31 -1
- package/src/__tests__/{overflow-reduce-pipeline.test.ts → overflow-reduction-loop.test.ts} +64 -284
- package/src/__tests__/persist-unsendable-image.test.ts +215 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +1 -0
- package/src/__tests__/pkb-autoinject.test.ts +2 -5
- package/src/__tests__/plugin-api-shim.test.ts +3 -6
- package/src/__tests__/plugin-bootstrap.test.ts +14 -40
- package/src/__tests__/plugin-registry.test.ts +3 -76
- package/src/__tests__/plugin-types.test.ts +0 -193
- package/src/__tests__/process-message-display-content.test.ts +6 -2
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +5 -1
- package/src/__tests__/resolve-trust-class.test.ts +4 -4
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +60 -23
- package/src/__tests__/schedule-routes.test.ts +603 -2
- package/src/__tests__/schedule-store.test.ts +41 -0
- package/src/__tests__/schedule-tools.test.ts +35 -0
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/server-history-render.test.ts +314 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
- package/src/__tests__/skillssh-files.test.ts +1 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- 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__/system-prompt.test.ts +20 -0
- package/src/__tests__/task-scheduler.test.ts +162 -1
- package/src/__tests__/terminal-tools.test.ts +6 -1
- package/src/__tests__/title-generate-hook.test.ts +319 -0
- package/src/__tests__/tool-error-hook.test.ts +278 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +468 -5
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -2
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
- package/src/__tests__/ui-work-result-surface.test.ts +159 -0
- package/src/__tests__/usage-routes.test.ts +285 -1
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- package/src/__tests__/voice-session-bridge.test.ts +6 -3
- package/src/__tests__/web-search-backend-failure.test.ts +166 -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-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +137 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +736 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +196 -0
- package/src/acp/auto-install.ts +177 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/feature-gate.test.ts +48 -0
- package/src/acp/feature-gate.ts +34 -0
- package/src/acp/prepare-agent-env.ts +83 -29
- package/src/acp/resolve-agent.test.ts +320 -7
- package/src/acp/resolve-agent.ts +182 -18
- package/src/acp/resume-hint.ts +25 -0
- package/src/acp/session-manager.ts +495 -73
- package/src/acp/types.ts +8 -0
- package/src/agent/compaction-circuit.ts +60 -102
- package/src/agent/loop.ts +362 -485
- package/src/api/events/assistant-thinking-delta.ts +33 -0
- package/src/api/events/tool-output-chunk.ts +45 -0
- package/src/api/events/tool-use-preview-start.ts +32 -0
- package/src/api/events/trace-event.ts +69 -0
- package/src/api/index.ts +48 -13
- package/src/api/responses/conversation-message.ts +374 -0
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/avatar/__tests__/avatar-store.test.ts +34 -29
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/__tests__/notifications.test.ts +58 -14
- package/src/cli/commands/notifications.ts +112 -60
- 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 +6 -0
- package/src/config/assistant-feature-flags.ts +22 -11
- package/src/config/bundled-skills/acp/SKILL.md +83 -31
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -398
- package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
- 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/references/examples/README.md +17 -0
- package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
- package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
- package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -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-skills/messaging/SKILL.md +0 -7
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/feature-flag-cache.ts +3 -3
- package/src/config/feature-flag-registry.json +48 -7
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-v2.ts +8 -0
- package/src/config/schemas/memory-v3.ts +8 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills.ts +13 -0
- package/src/context/compactor.ts +1 -1
- package/src/context/strip-injections.ts +128 -0
- package/src/context/token-estimator.ts +23 -0
- package/src/context/tool-result-truncation.ts +0 -23
- package/src/context/window-manager.ts +5 -7
- package/src/credential-execution/executable-discovery.ts +16 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +6 -0
- package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +10 -8
- package/src/daemon/assistant-attachments.ts +1 -1
- package/src/daemon/config-watcher.ts +2 -2
- package/src/daemon/context-overflow-reducer.ts +0 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +594 -153
- package/src/daemon/conversation-agent-loop.ts +301 -997
- package/src/daemon/conversation-history.ts +5 -4
- package/src/daemon/conversation-lifecycle.ts +3 -4
- package/src/daemon/conversation-messaging.ts +7 -6
- package/src/daemon/conversation-process.ts +11 -16
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +218 -398
- package/src/daemon/conversation-slash.ts +6 -25
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +222 -4
- package/src/daemon/conversation-tool-setup.ts +2 -29
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +32 -20
- package/src/daemon/external-plugins-bootstrap.ts +17 -18
- package/src/daemon/handlers/config-a2a.ts +51 -36
- package/src/daemon/handlers/config-slack-channel.ts +20 -14
- package/src/daemon/handlers/config-telegram.ts +16 -2
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/shared.ts +156 -84
- package/src/daemon/handlers/skills.ts +42 -10
- package/src/daemon/lifecycle.ts +25 -0
- package/src/daemon/message-types/apps.ts +1 -29
- package/src/daemon/message-types/messages.ts +9 -57
- package/src/daemon/message-types/skills.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +136 -3
- package/src/daemon/now-scratchpad.ts +21 -0
- package/src/daemon/orphan-reaper.test.ts +210 -0
- package/src/daemon/orphan-reaper.ts +240 -0
- package/src/daemon/overflow-reduction-loop.ts +230 -0
- package/src/daemon/persist-unsendable-image.ts +117 -0
- package/src/daemon/process-message.ts +1 -3
- package/src/daemon/server.ts +2 -0
- package/src/daemon/trace-emitter.ts +6 -4
- package/src/daemon/trust-context.ts +19 -0
- package/src/daemon/wake-target-adapter.ts +3 -1
- 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/home/home-greeting-cache.ts +24 -1
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/gateway-client.test.ts +2 -2
- package/src/ipc/gateway-client.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/media/gemini-image-service.ts +15 -0
- package/src/media/openai-image-service.ts +14 -0
- package/src/media/types.ts +34 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +56 -0
- package/src/memory/auth-fallback-events-store.ts +94 -0
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/conversation-title-service.ts +65 -41
- package/src/memory/db-init.ts +6 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
- package/src/memory/graph/conversation-graph-memory.ts +65 -0
- package/src/memory/job-handlers/conversation-starters.ts +13 -2
- package/src/memory/jobs-store.ts +33 -0
- package/src/memory/jobs-worker.ts +32 -5
- package/src/memory/llm-usage-store.ts +224 -50
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
- package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
- package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/index.ts +3 -0
- package/src/memory/pkb/autoinject.ts +61 -0
- package/src/memory/pkb/context.ts +50 -0
- package/src/memory/pkb/types.ts +14 -0
- package/src/memory/schedule-attribution-sql.ts +104 -0
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +16 -0
- package/src/memory/usage-grouped-buckets.ts +6 -1
- package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -4
- package/src/memory/v2/consolidation-job.ts +14 -5
- package/src/notifications/conversation-pairing.ts +8 -15
- package/src/notifications/decision-engine.ts +6 -3
- package/src/notifications/home-feed-side-effect.ts +12 -1
- package/src/permissions/prompter.ts +4 -0
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +7 -5
- package/src/plugin-api/types.ts +151 -1
- package/src/plugins/defaults/compaction/compact.ts +59 -0
- package/src/plugins/defaults/compaction/package.json +1 -1
- package/src/plugins/defaults/compaction/register.ts +8 -19
- package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
- package/src/plugins/defaults/empty-response/register.ts +8 -13
- package/src/plugins/defaults/index.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +95 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
- package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +288 -81
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +16 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +48 -12
- package/src/plugins/defaults/memory-v3-shadow/__tests__/provider-blocks.test.ts +13 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +104 -32
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +96 -30
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +34 -16
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -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 +75 -0
- package/src/plugins/defaults/memory-v3-shadow/llm-retry.ts +32 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +8 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +26 -14
- package/src/plugins/defaults/{llm-call → memory-v3-shadow}/package.json +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/provider-blocks.ts +26 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +3 -3
- package/src/plugins/defaults/memory-v3-shadow/register.ts +26 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +51 -45
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +61 -46
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +69 -99
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +8 -0
- package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/title-generate/package.json +1 -1
- package/src/plugins/defaults/title-generate/register.ts +18 -18
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
- package/src/plugins/defaults/tool-error/package.json +1 -1
- package/src/plugins/defaults/tool-error/register.ts +9 -21
- package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +10 -21
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +37 -18
- package/src/plugins/external-api.ts +2 -2
- package/src/plugins/pipeline.ts +6 -305
- package/src/plugins/registry.ts +10 -55
- package/src/plugins/types.ts +62 -797
- package/src/plugins/user-loader.ts +30 -127
- package/src/proactive-artifact/aux-message-injector.ts +4 -4
- package/src/proactive-artifact/job.test.ts +8 -13
- package/src/prompts/__tests__/system-prompt.test.ts +42 -0
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +64 -0
- package/src/prompts/templates/BOOTSTRAP.md +2 -2
- package/src/prompts/templates/system-sections.ts +15 -0
- package/src/providers/anthropic/client.ts +37 -29
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -0
- package/src/providers/openrouter/client.ts +1 -0
- package/src/providers/placeholder-sentinels.ts +35 -0
- package/src/runtime/__tests__/agent-wake.test.ts +10 -6
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +2 -5
- package/src/runtime/assistant-event-hub.ts +37 -7
- package/src/runtime/{conversation-stream-state.ts → assistant-stream-state.ts} +132 -58
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/http-router.ts +16 -21
- package/src/runtime/http-types.ts +16 -70
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +283 -55
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +31 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
- 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/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.test.ts +89 -25
- package/src/runtime/routes/acp-routes.ts +81 -29
- package/src/runtime/routes/app-management-routes.ts +6 -117
- package/src/runtime/routes/app-routes.ts +13 -15
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/attachment-routes.ts +26 -15
- package/src/runtime/routes/avatar-routes.ts +26 -0
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +6 -10
- package/src/runtime/routes/btw-routes.ts +29 -23
- package/src/runtime/routes/consolidation-routes.ts +120 -20
- 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 +3 -1
- package/src/runtime/routes/conversation-routes.ts +372 -185
- package/src/runtime/routes/conversation-starter-routes.ts +13 -7
- package/src/runtime/routes/conversations-import-routes.ts +24 -7
- package/src/runtime/routes/documents-routes.ts +4 -0
- package/src/runtime/routes/domain-routes.ts +51 -37
- package/src/runtime/routes/epoch-millis-range.ts +34 -0
- package/src/runtime/routes/events-routes.ts +28 -34
- package/src/runtime/routes/gateway-log-routes.ts +26 -4
- package/src/runtime/routes/heartbeat-routes.ts +32 -12
- 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-intro-cache.ts +11 -34
- package/src/runtime/routes/identity-routes.ts +224 -18
- package/src/runtime/routes/image-generation-routes.ts +40 -2
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/a2a.ts +12 -10
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
- package/src/runtime/routes/integrations/slack/channel.ts +4 -0
- package/src/runtime/routes/integrations/slack/share.ts +27 -6
- package/src/runtime/routes/integrations/telegram.ts +6 -0
- package/src/runtime/routes/integrations/twilio.ts +42 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
- package/src/runtime/routes/log-export-routes.ts +8 -0
- package/src/runtime/routes/memory-v2-routes.ts +15 -8
- package/src/runtime/routes/memory-v3-routes.ts +66 -34
- package/src/runtime/routes/oauth-apps.ts +66 -12
- package/src/runtime/routes/oauth-providers.ts +44 -5
- package/src/runtime/routes/platform-routes.ts +81 -5
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +6 -4
- package/src/runtime/routes/playground/force-compact.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/rename-conversation-routes.ts +5 -0
- package/src/runtime/routes/schedule-routes.ts +152 -42
- package/src/runtime/routes/secret-routes.ts +14 -2
- package/src/runtime/routes/skills-routes.ts +43 -14
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
- package/src/runtime/routes/trust-rules-routes.ts +26 -2
- package/src/runtime/routes/tts-routes.ts +35 -0
- package/src/runtime/routes/types.ts +66 -8
- package/src/runtime/routes/usage-routes.ts +47 -39
- package/src/runtime/routes/webhook-routes.ts +41 -2
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/routes/workspace-routes.ts +4 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +6 -0
- package/src/runtime/services/analyze-conversation.ts +2 -2
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/schedule/schedule-store.ts +20 -1
- package/src/schedule/schedule-usage-store.ts +83 -0
- package/src/schedule/scheduler.ts +12 -5
- package/src/signals/cancel.ts +2 -4
- package/src/skills/catalog-files.ts +2 -2
- package/src/skills/catalog-install.ts +3 -0
- package/src/skills/categories-cache.ts +118 -0
- package/src/skills/clawhub-files.ts +1 -2
- package/src/skills/skillssh-files.ts +1 -2
- package/src/subagent/manager.ts +17 -5
- package/src/telemetry/types.ts +29 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +112 -3
- package/src/telemetry/usage-telemetry-reporter.ts +57 -2
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +7 -1
- package/src/tools/acp/spawn.test.ts +158 -55
- package/src/tools/acp/spawn.ts +47 -72
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/executors.ts +13 -8
- package/src/tools/executor.ts +1 -53
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
- package/src/tools/network/__tests__/web-search.test.ts +11 -3
- package/src/tools/network/web-search-error.test.ts +248 -0
- package/src/tools/network/web-search-error.ts +267 -0
- package/src/tools/network/web-search.ts +207 -48
- package/src/tools/schedule/create.ts +2 -0
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/terminal/safe-env.ts +10 -1
- package/src/tools/ui-surface/definitions.ts +34 -5
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
- package/src/tts/provider-catalog.ts +76 -1
- package/src/util/mutex.ts +47 -0
- package/src/workspace/git-service.ts +1 -42
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
- package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
- package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +117 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/docs/plugins.md +0 -836
- package/examples/plugins/echo/register.ts +0 -184
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
- 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__/empty-response-pipeline.test.ts +0 -423
- package/src/__tests__/llm-call-pipeline.test.ts +0 -287
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
- package/src/__tests__/persistence-pipeline.test.ts +0 -503
- package/src/__tests__/pipeline-runner.test.ts +0 -564
- package/src/__tests__/title-generate-pipeline.test.ts +0 -211
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -479
- package/src/__tests__/tool-error-pipeline.test.ts +0 -241
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -341
- package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
- package/src/gallery/default-gallery.ts +0 -1359
- package/src/gallery/gallery-manifest.ts +0 -28
- package/src/home/feature-gate.ts +0 -22
- package/src/memory/v3/provider-blocks.ts +0 -16
- 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/terminal.ts +0 -73
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +0 -22
- package/src/plugins/defaults/empty-response/terminal.ts +0 -106
- package/src/plugins/defaults/injectors/package.json +0 -15
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +0 -17
- package/src/plugins/defaults/llm-call/register.ts +0 -45
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +0 -17
- package/src/plugins/defaults/memory-retrieval/package.json +0 -15
- package/src/plugins/defaults/memory-retrieval/register.ts +0 -181
- 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/persistence/middlewares/persistence.ts +0 -19
- package/src/plugins/defaults/persistence/package.json +0 -15
- package/src/plugins/defaults/persistence/register.ts +0 -38
- package/src/plugins/defaults/persistence/terminal.ts +0 -83
- package/src/plugins/defaults/title-generate/terminal.ts +0 -31
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +0 -23
- package/src/plugins/defaults/token-estimate/package.json +0 -15
- package/src/plugins/defaults/token-estimate/register.ts +0 -34
- package/src/plugins/defaults/token-estimate/terminal.ts +0 -40
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +0 -21
- package/src/plugins/defaults/tool-error/terminal.ts +0 -47
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +0 -23
- package/src/plugins/defaults/tool-execute/package.json +0 -15
- package/src/plugins/defaults/tool-execute/register.ts +0 -49
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/types.ts +0 -22
- package/src/skills/category-inference.ts +0 -111
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
- /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__/needle.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +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}/core.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}/needle.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
|
@@ -46,6 +46,14 @@ export interface TurnContext {
|
|
|
46
46
|
turnNumber: number;
|
|
47
47
|
currentMessage: string;
|
|
48
48
|
recentContext: string;
|
|
49
|
+
/**
|
|
50
|
+
* Optional situational signal — the current date plus the live NOW.md
|
|
51
|
+
* scratchpad — so a leaf or page can be routed/selected on a date or
|
|
52
|
+
* live-state cue the message itself never names (e.g. a person whose
|
|
53
|
+
* anniversary is today). Omitted when unavailable; the router and selector
|
|
54
|
+
* render nothing for an undefined value.
|
|
55
|
+
*/
|
|
56
|
+
situationalContext?: string;
|
|
49
57
|
}
|
|
50
58
|
|
|
51
59
|
export type SelectionSource = "l1+l2" | "core+l2" | "needle" | "carry-forward";
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `stop` hook: triggers the second-pass conversation-title
|
|
3
|
+
* regeneration once a conversation has accumulated enough context.
|
|
4
|
+
*
|
|
5
|
+
* The first title is generated from the opening prompt alone (see
|
|
6
|
+
* `./user-prompt-submit.ts`). After a few exchanges the conversation's real
|
|
7
|
+
* topic is usually clearer, so a single second pass re-titles using the most
|
|
8
|
+
* recent messages. This hook is the trigger — it fires the regeneration when
|
|
9
|
+
* the conversation reaches its third user turn — and delegates the title
|
|
10
|
+
* itself to the service (`memory/conversation-title-service.ts`), which
|
|
11
|
+
* re-checks that the title is still auto-generated, resolves the title
|
|
12
|
+
* provider, persists, and broadcasts the `conversation_title_updated` /
|
|
13
|
+
* `sync_changed` events.
|
|
14
|
+
*
|
|
15
|
+
* Turn count is read from history rather than an external counter: the number
|
|
16
|
+
* of genuine user prompts — user-role messages that aren't purely tool results
|
|
17
|
+
* — is the conversation's turn number. Deriving it from history keeps the hook
|
|
18
|
+
* stateless and means a mid-run array rewrite (compaction) can't invalidate it.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { PluginHookFn, StopContext } from "@vellumai/plugin-api";
|
|
22
|
+
|
|
23
|
+
import { getConfig } from "../../../../config/loader.js";
|
|
24
|
+
import { queueRegenerateConversationTitle } from "../../../../memory/conversation-title-service.js";
|
|
25
|
+
import type { Message } from "../../../../providers/types.js";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* User turn at which the second title pass fires. Matches the
|
|
29
|
+
* `conversations.skipAutoRetitling` opt-out, documented as skipping the
|
|
30
|
+
* regeneration "that fires after the third user turn".
|
|
31
|
+
*/
|
|
32
|
+
const SECOND_PASS_USER_TURN = 3;
|
|
33
|
+
|
|
34
|
+
/** A user-role message carrying only tool results, not a fresh prompt. */
|
|
35
|
+
function isToolResultMessage(message: Message): boolean {
|
|
36
|
+
return (
|
|
37
|
+
message.role === "user" &&
|
|
38
|
+
message.content.length > 0 &&
|
|
39
|
+
message.content.every((block) => block.type === "tool_result")
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Count of genuine user prompts in history — the conversation's turn number. */
|
|
44
|
+
function countUserTurns(messages: ReadonlyArray<Message>): number {
|
|
45
|
+
let turns = 0;
|
|
46
|
+
for (const message of messages) {
|
|
47
|
+
if (message.role === "user" && !isToolResultMessage(message)) turns++;
|
|
48
|
+
}
|
|
49
|
+
return turns;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const stop: PluginHookFn<StopContext> = async (ctx) => {
|
|
53
|
+
// Only re-title at a genuine turn end. A `"continue"` decision means an
|
|
54
|
+
// earlier hook is re-querying the model (e.g. an empty-response nudge), so
|
|
55
|
+
// defer to the eventual terminal stop.
|
|
56
|
+
if (ctx.decision !== "stop") return;
|
|
57
|
+
|
|
58
|
+
if (getConfig().conversations.skipAutoRetitling) return;
|
|
59
|
+
|
|
60
|
+
if (countUserTurns(ctx.messages) !== SECOND_PASS_USER_TURN) return;
|
|
61
|
+
|
|
62
|
+
const { conversationId } = ctx;
|
|
63
|
+
// Deferred to a later macrotask so the just-completed turn lands first. The
|
|
64
|
+
// hook fires at the stop boundary, before the loop appends the turn's
|
|
65
|
+
// assistant reply to history and emits `message_complete` (which persists
|
|
66
|
+
// it). The service regenerates from the most recent stored messages, so it
|
|
67
|
+
// must run after the reply is persisted to reflect it. The service is itself
|
|
68
|
+
// fire-and-forget and re-checks replaceability, owning provider resolution,
|
|
69
|
+
// persistence, and the resulting broadcast.
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
queueRegenerateConversationTitle({ conversationId });
|
|
72
|
+
}, 0);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export default stop;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `user-prompt-submit` hook: kicks off conversation-title generation
|
|
3
|
+
* from the submitted prompt.
|
|
4
|
+
*
|
|
5
|
+
* Title generation is a self-contained side effect that only needs the user's
|
|
6
|
+
* prompt as context, so it belongs at the prompt-submit boundary rather than
|
|
7
|
+
* threaded through the agent loop. The hook is a pure trigger — it schedules
|
|
8
|
+
* the work and returns; persistence and the resulting
|
|
9
|
+
* `conversation_title_updated` / `sync_changed` broadcast are owned by the
|
|
10
|
+
* title service (see `memory/conversation-title-service.ts`).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type {
|
|
14
|
+
PluginHookFn,
|
|
15
|
+
UserPromptSubmitContext,
|
|
16
|
+
} from "@vellumai/plugin-api";
|
|
17
|
+
|
|
18
|
+
import { queueGenerateConversationTitle } from "../../../../memory/conversation-title-service.js";
|
|
19
|
+
|
|
20
|
+
const userPromptSubmit: PluginHookFn<UserPromptSubmitContext> = async (ctx) => {
|
|
21
|
+
// Deferred to a later macrotask so the main agent-loop LLM request is
|
|
22
|
+
// issued first; on strict single-slot provider configs this keeps the
|
|
23
|
+
// background title call from claiming the rate-limit slot ahead of the
|
|
24
|
+
// user-visible response. The title service is itself fire-and-forget and
|
|
25
|
+
// re-checks title replaceability before making any LLM call, so an
|
|
26
|
+
// already-titled conversation incurs no generation.
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
queueGenerateConversationTitle({
|
|
29
|
+
conversationId: ctx.conversationId,
|
|
30
|
+
userMessage: ctx.prompt,
|
|
31
|
+
});
|
|
32
|
+
}, 0);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default userPromptSubmit;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "default-title-generate",
|
|
3
3
|
"version": "1.0.0",
|
|
4
|
-
"description": "First-party default plugin
|
|
4
|
+
"description": "First-party default plugin that triggers conversation-title generation from the user-prompt-submit hook.",
|
|
5
5
|
"private": true,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default `
|
|
2
|
+
* Default `title-generate` plugin.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* Contributes two hooks, both pure triggers that delegate the title work to
|
|
5
|
+
* the service (`memory/conversation-title-service.ts`):
|
|
6
|
+
*
|
|
7
|
+
* - `user-prompt-submit` (`./hooks/user-prompt-submit.ts`) — first-pass title
|
|
8
|
+
* generation from the submitted prompt.
|
|
9
|
+
* - `stop` (`./hooks/stop.ts`) — second-pass regeneration once the
|
|
10
|
+
* conversation reaches its third user turn, for a title that reflects the
|
|
11
|
+
* established topic.
|
|
12
|
+
*
|
|
13
|
+
* Persistence and the resulting `conversation_title_updated` / `sync_changed`
|
|
14
|
+
* broadcast are owned by the title service.
|
|
9
15
|
*
|
|
10
16
|
* Registered via a side-effect import from
|
|
11
17
|
* `daemon/external-plugins-bootstrap.ts` so it is present in the registry
|
|
@@ -13,23 +19,17 @@
|
|
|
13
19
|
*/
|
|
14
20
|
|
|
15
21
|
import { type Plugin } from "../../types.js";
|
|
22
|
+
import stop from "./hooks/stop.js";
|
|
23
|
+
import userPromptSubmit from "./hooks/user-prompt-submit.js";
|
|
16
24
|
import pkg from "./package.json" with { type: "json" };
|
|
17
25
|
|
|
18
|
-
/**
|
|
19
|
-
* Default titleGenerate plugin. Declares no middleware — it exists purely
|
|
20
|
-
* to negotiate the `titleGenerateApi` capability so bootstrap has a record
|
|
21
|
-
* that the assistant runtime exposes this pipeline.
|
|
22
|
-
*
|
|
23
|
-
* The terminal handler (`./terminal.ts`) is supplied at the call site in
|
|
24
|
-
* `conversation-agent-loop.ts` rather than through `middleware.titleGenerate`,
|
|
25
|
-
* because a default middleware would short-circuit user-registered middleware
|
|
26
|
-
* by always running first in onion order. Keeping the terminal outside the
|
|
27
|
-
* middleware chain lets user plugins observe/transform/short-circuit the
|
|
28
|
-
* call without competing with an assistant-owned default middleware.
|
|
29
|
-
*/
|
|
30
26
|
export const defaultTitleGeneratePlugin: Plugin = {
|
|
31
27
|
manifest: {
|
|
32
28
|
name: pkg.name,
|
|
33
29
|
version: pkg.version,
|
|
34
30
|
},
|
|
31
|
+
hooks: {
|
|
32
|
+
"user-prompt-submit": userPromptSubmit,
|
|
33
|
+
stop,
|
|
34
|
+
},
|
|
35
35
|
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `post-tool-use` hook: when a tool result carries `is_error`, set
|
|
3
|
+
* `additionalContext` with a system-notice that coaches the model to either
|
|
4
|
+
* retry with corrected parameters (for recoverable errors) or report the
|
|
5
|
+
* failure to the user (for unrecoverable ones).
|
|
6
|
+
*
|
|
7
|
+
* The coaching is delivered via `additionalContext`, not by mutating the tool
|
|
8
|
+
* result's `content`. The loop appends it to the provider-bound history as a
|
|
9
|
+
* separate block after the tool_result event is emitted, so the model sees the
|
|
10
|
+
* guidance while the client-facing and persisted tool output stay the tool's
|
|
11
|
+
* actual result. This mirrors how Claude Code (`additionalContext`) and Codex
|
|
12
|
+
* (`additional_contexts`) surface PostToolUse feedback as separate context
|
|
13
|
+
* rather than rewriting the tool response.
|
|
14
|
+
*
|
|
15
|
+
* The coaching is bounded per tool: once a single tool has failed
|
|
16
|
+
* `MAX_CONSECUTIVE_ERROR_NUDGES` times in a row the notice is dropped — the
|
|
17
|
+
* error is likely not something the model can fix on its own, and continuing
|
|
18
|
+
* to coach a retry only burns tokens. The consecutive-failure count is derived
|
|
19
|
+
* from the conversation history (the trailing run of error results for this
|
|
20
|
+
* tool name, plus the current one) rather than a loop-held counter, so the
|
|
21
|
+
* guard survives mid-run compaction rewriting the history array. A successful
|
|
22
|
+
* result for the tool resets its streak.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import type { PluginHookFn, PostToolUseContext } from "@vellumai/plugin-api";
|
|
26
|
+
|
|
27
|
+
import type { Message } from "../../../../providers/types.js";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Canonical tool-error coaching text. Kept as a module-level constant so tests
|
|
31
|
+
* and plugins that wrap the default can match it without duplicating the
|
|
32
|
+
* string.
|
|
33
|
+
*
|
|
34
|
+
* This is shown to the model as provider-only context, not the user. Edits
|
|
35
|
+
* here affect retry behavior but not end-user UX directly.
|
|
36
|
+
*/
|
|
37
|
+
export const TOOL_ERROR_NUDGE_TEXT =
|
|
38
|
+
"<system_notice>This tool call returned an error. If the error looks recoverable (e.g. missing or invalid parameters), fix the parameters and retry. If the error is clearly unrecoverable (e.g. a service is down, a resource does not exist, or a permission is permanently denied), report it to the user.</system_notice>";
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Number of back-to-back failures of a single tool to coach before giving up.
|
|
42
|
+
* Coaching fires on the 1st through Nth consecutive failure and is dropped from
|
|
43
|
+
* the (N+1)th onward.
|
|
44
|
+
*/
|
|
45
|
+
const MAX_CONSECUTIVE_ERROR_NUDGES = 3;
|
|
46
|
+
|
|
47
|
+
/** Map every `tool_use` block id in history to the tool name it invoked. */
|
|
48
|
+
function toolNamesById(messages: ReadonlyArray<Message>): Map<string, string> {
|
|
49
|
+
const names = new Map<string, string>();
|
|
50
|
+
for (const message of messages) {
|
|
51
|
+
if (message.role !== "assistant") continue;
|
|
52
|
+
for (const block of message.content) {
|
|
53
|
+
if (block.type === "tool_use") names.set(block.id, block.name);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return names;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Trailing run of consecutive error results for `toolName` already in history.
|
|
61
|
+
* Walks the tool's results in chronological order and counts back from the most
|
|
62
|
+
* recent until a successful result breaks the streak. The current result is not
|
|
63
|
+
* yet in history, so callers add it themselves.
|
|
64
|
+
*/
|
|
65
|
+
function priorConsecutiveErrors(
|
|
66
|
+
messages: ReadonlyArray<Message>,
|
|
67
|
+
toolName: string,
|
|
68
|
+
namesById: ReadonlyMap<string, string>,
|
|
69
|
+
): number {
|
|
70
|
+
const isErrorByOrder: boolean[] = [];
|
|
71
|
+
for (const message of messages) {
|
|
72
|
+
if (message.role !== "user") continue;
|
|
73
|
+
for (const block of message.content) {
|
|
74
|
+
if (block.type !== "tool_result") continue;
|
|
75
|
+
if (namesById.get(block.tool_use_id) !== toolName) continue;
|
|
76
|
+
isErrorByOrder.push(block.is_error === true);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let streak = 0;
|
|
81
|
+
for (let i = isErrorByOrder.length - 1; i >= 0; i--) {
|
|
82
|
+
if (!isErrorByOrder[i]) break;
|
|
83
|
+
streak++;
|
|
84
|
+
}
|
|
85
|
+
return streak;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const postToolUse: PluginHookFn<PostToolUseContext> = async (ctx) => {
|
|
89
|
+
if (ctx.toolResponse.is_error !== true) return;
|
|
90
|
+
|
|
91
|
+
const namesById = toolNamesById(ctx.messages);
|
|
92
|
+
const toolName = namesById.get(ctx.toolResponse.tool_use_id);
|
|
93
|
+
|
|
94
|
+
// Prior failures of this tool plus the current one. An unresolved name (the
|
|
95
|
+
// current turn's tool_use is always in history, so this is defensive) falls
|
|
96
|
+
// back to coaching this lone failure.
|
|
97
|
+
const consecutiveErrors =
|
|
98
|
+
(toolName === undefined
|
|
99
|
+
? 0
|
|
100
|
+
: priorConsecutiveErrors(ctx.messages, toolName, namesById)) + 1;
|
|
101
|
+
|
|
102
|
+
if (consecutiveErrors > MAX_CONSECUTIVE_ERROR_NUDGES) {
|
|
103
|
+
ctx.logger.info(
|
|
104
|
+
{
|
|
105
|
+
plugin: "tool-error",
|
|
106
|
+
toolName,
|
|
107
|
+
toolUseId: ctx.toolResponse.tool_use_id,
|
|
108
|
+
consecutiveErrors,
|
|
109
|
+
},
|
|
110
|
+
"Skipping tool-error coaching after repeated consecutive failures",
|
|
111
|
+
);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
ctx.additionalContext = TOOL_ERROR_NUDGE_TEXT;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export default postToolUse;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "default-tool-error",
|
|
3
3
|
"version": "1.0.0",
|
|
4
|
-
"description": "First-party default plugin
|
|
4
|
+
"description": "First-party default plugin contributing a post-tool-use hook that coaches the model to retry or report a failed tool call.",
|
|
5
5
|
"private": true,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
@@ -1,35 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default `
|
|
2
|
+
* Default `tool-error` plugin.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* load first via module-side-effect imports / `registerDefaultPlugins`), which
|
|
10
|
-
* puts it at the OUTERMOST position of the onion chain. If the default
|
|
11
|
-
* middleware invoked the decision logic directly without calling `next`, it
|
|
12
|
-
* would shadow every later-registered plugin. Routing through `next(args)`
|
|
13
|
-
* lets user middleware participate normally.
|
|
14
|
-
*
|
|
15
|
-
* Design doc: `.private/plans/agent-plugin-system.md` (PR 19).
|
|
4
|
+
* Contributes a `post-tool-use` hook that coaches the model to retry or report
|
|
5
|
+
* a failed tool call, bounded per tool so an unrecoverable error doesn't churn.
|
|
6
|
+
* The coaching is surfaced via `additionalContext` (a separate provider-only
|
|
7
|
+
* block), leaving the tool result's own content untouched. The decision logic
|
|
8
|
+
* lives in `./hooks/post-tool-use.ts`.
|
|
16
9
|
*/
|
|
17
10
|
|
|
18
11
|
import { type Plugin } from "../../types.js";
|
|
19
|
-
import
|
|
12
|
+
import postToolUse from "./hooks/post-tool-use.js";
|
|
20
13
|
import pkg from "./package.json" with { type: "json" };
|
|
21
14
|
|
|
22
|
-
/**
|
|
23
|
-
* Plugin registration for the default `toolError` behavior. Registered by
|
|
24
|
-
* `daemon/external-plugins-bootstrap.ts` via a side-effect import so the
|
|
25
|
-
* middleware is available to the pipeline runner from daemon startup.
|
|
26
|
-
*/
|
|
27
15
|
export const defaultToolErrorPlugin: Plugin = {
|
|
28
16
|
manifest: {
|
|
29
17
|
name: pkg.name,
|
|
30
18
|
version: pkg.version,
|
|
31
19
|
},
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
hooks: {
|
|
21
|
+
"post-tool-use": postToolUse,
|
|
34
22
|
},
|
|
35
23
|
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `post-tool-use` hook: tail-drops an oversized tool result down to a
|
|
3
|
+
* character budget derived from the model's context window, keeping a single
|
|
4
|
+
* result from blowing the provider's context.
|
|
5
|
+
*
|
|
6
|
+
* Defaults register before any user plugin, so this hook runs at the front of
|
|
7
|
+
* the `post-tool-use` chain — every later hook sees an already-bounded result.
|
|
8
|
+
* The hook mutates `toolResponse.content` in place.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { PluginHookFn, PostToolUseContext } from "@vellumai/plugin-api";
|
|
12
|
+
|
|
13
|
+
import { truncateToolResult } from "../terminal.js";
|
|
14
|
+
|
|
15
|
+
const postToolUse: PluginHookFn<PostToolUseContext> = async (ctx) => {
|
|
16
|
+
const { content, truncated } = truncateToolResult(
|
|
17
|
+
ctx.toolResponse.content,
|
|
18
|
+
ctx.maxInputTokens,
|
|
19
|
+
);
|
|
20
|
+
if (truncated) {
|
|
21
|
+
ctx.toolResponse.content = content;
|
|
22
|
+
ctx.logger.warn(
|
|
23
|
+
{
|
|
24
|
+
plugin: "tool-result-truncate",
|
|
25
|
+
toolUseId: ctx.toolResponse.tool_use_id,
|
|
26
|
+
},
|
|
27
|
+
"Truncated oversized tool result to prevent context overflow",
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default postToolUse;
|
|
@@ -1,35 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default `
|
|
2
|
+
* Default `tool-result-truncate` plugin.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* the
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* chain. If the default
|
|
11
|
-
* middleware were to invoke the terminal directly without calling `next`, it
|
|
12
|
-
* would shadow every later-registered plugin (including hot-reloaded ones).
|
|
13
|
-
* Routing through `next(args)` lets user middleware participate normally.
|
|
14
|
-
*
|
|
15
|
-
* Design doc: `.private/plans/agent-plugin-system.md` (PR 17).
|
|
4
|
+
* Contributes a `post-tool-use` hook that tail-drops an oversized tool result
|
|
5
|
+
* down to a character budget derived from the model's context window before
|
|
6
|
+
* the result is sent to the provider. The truncation implementation lives in
|
|
7
|
+
* `./terminal.ts`; the hook in `./hooks/post-tool-use.ts` wires it into the
|
|
8
|
+
* lifecycle. Defaults register before user plugins, so this runs at the front
|
|
9
|
+
* of the hook chain.
|
|
16
10
|
*/
|
|
17
11
|
|
|
18
12
|
import { type Plugin } from "../../types.js";
|
|
19
|
-
import
|
|
13
|
+
import postToolUse from "./hooks/post-tool-use.js";
|
|
20
14
|
import pkg from "./package.json" with { type: "json" };
|
|
21
15
|
|
|
22
|
-
/**
|
|
23
|
-
* Plugin descriptor for the default tool-result truncation middleware.
|
|
24
|
-
* Registered by `plugins/defaults/index.ts` so the registry always has at
|
|
25
|
-
* least one middleware for the `toolResultTruncate` pipeline.
|
|
26
|
-
*/
|
|
27
16
|
export const defaultToolResultTruncatePlugin: Plugin = {
|
|
28
17
|
manifest: {
|
|
29
18
|
name: pkg.name,
|
|
30
19
|
version: pkg.version,
|
|
31
20
|
},
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
hooks: {
|
|
22
|
+
"post-tool-use": postToolUse,
|
|
34
23
|
},
|
|
35
24
|
};
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Tool-result truncation: tail-drops oversized tool-result text down to a
|
|
3
|
+
* character budget derived from the model's context window, plus the
|
|
4
|
+
* primitives it wraps.
|
|
4
5
|
*
|
|
5
6
|
* This module is side-effect free: importing it does not register any plugin.
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
|
-
import type {
|
|
9
|
-
ToolResultTruncateArgs,
|
|
10
|
-
ToolResultTruncateResult,
|
|
11
|
-
} from "./types.js";
|
|
12
|
-
|
|
13
9
|
const HIGH_SURROGATE_START = 0xd800;
|
|
14
10
|
const HIGH_SURROGATE_END = 0xdbff;
|
|
15
11
|
const LOW_SURROGATE_START = 0xdc00;
|
|
@@ -98,16 +94,39 @@ export function truncateToolResultText(text: string, maxChars: number): string {
|
|
|
98
94
|
}
|
|
99
95
|
|
|
100
96
|
/**
|
|
101
|
-
*
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
* Maximum share of the context window that a single tool result may occupy.
|
|
98
|
+
*/
|
|
99
|
+
const MAX_TOOL_RESULT_CONTEXT_SHARE = 0.3;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Absolute cap on tool-result characters (~100K tokens).
|
|
103
|
+
*/
|
|
104
|
+
export const HARD_MAX_TOOL_RESULT_CHARS = 400_000;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Calculate the maximum allowed characters for a tool result based on the
|
|
108
|
+
* context window size. Uses ~4 chars per token as a rough heuristic.
|
|
109
|
+
*/
|
|
110
|
+
export function calculateMaxToolResultChars(
|
|
111
|
+
contextWindowTokens: number,
|
|
112
|
+
): number {
|
|
113
|
+
return Math.min(
|
|
114
|
+
HARD_MAX_TOOL_RESULT_CHARS,
|
|
115
|
+
Math.floor(contextWindowTokens * MAX_TOOL_RESULT_CONTEXT_SHARE * 4),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Truncate a tool result's content to fit the model's context window. Derives
|
|
121
|
+
* the character budget from `maxInputTokens` and tail-drops anything beyond it.
|
|
122
|
+
* Returns the (possibly truncated) content alongside a `truncated` flag the
|
|
123
|
+
* caller can use for telemetry.
|
|
104
124
|
*/
|
|
105
|
-
export function
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
};
|
|
125
|
+
export function truncateToolResult(
|
|
126
|
+
content: string,
|
|
127
|
+
maxInputTokens: number,
|
|
128
|
+
): { content: string; truncated: boolean } {
|
|
129
|
+
const maxChars = calculateMaxToolResultChars(maxInputTokens);
|
|
130
|
+
const next = truncateToolResultText(content, maxChars);
|
|
131
|
+
return { content: next, truncated: next !== content };
|
|
113
132
|
}
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
* absolute paths or workspace-local copies — the TypeScript compiler erases
|
|
32
32
|
* them and they have no module-identity effect at runtime.
|
|
33
33
|
*
|
|
34
|
-
* See `
|
|
35
|
-
* `assistant/examples/plugins/echo
|
|
34
|
+
* See `experimental/plugins/README.md` for the full authoring contract and
|
|
35
|
+
* `assistant/examples/plugins/echo/` for a worked example.
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
38
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|