@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
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
export interface ScheduleAttributionFilter {
|
|
2
|
+
scheduleId?: string;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export type ScheduleAttributionSqlParam = string | number;
|
|
6
|
+
|
|
7
|
+
export interface ScheduleAttributionSqlFragment {
|
|
8
|
+
sql: string;
|
|
9
|
+
params: ScheduleAttributionSqlParam[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function normalizeScheduleAttributionFilter(
|
|
13
|
+
filter?: ScheduleAttributionFilter,
|
|
14
|
+
): ScheduleAttributionFilter {
|
|
15
|
+
const scheduleId = filter?.scheduleId?.trim();
|
|
16
|
+
return scheduleId ? { scheduleId } : {};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function usageColumn(column: string, eventAlias: string): string {
|
|
20
|
+
return `${eventAlias}.${column}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function buildScheduleRunWindowPredicate({
|
|
24
|
+
eventAlias,
|
|
25
|
+
runAlias,
|
|
26
|
+
filter,
|
|
27
|
+
}: {
|
|
28
|
+
eventAlias: string;
|
|
29
|
+
runAlias: string;
|
|
30
|
+
filter?: ScheduleAttributionFilter;
|
|
31
|
+
}): string {
|
|
32
|
+
const normalized = normalizeScheduleAttributionFilter(filter);
|
|
33
|
+
const scheduleClause = normalized.scheduleId
|
|
34
|
+
? `${runAlias}.job_id = ? AND `
|
|
35
|
+
: "";
|
|
36
|
+
return `${scheduleClause}${runAlias}.conversation_id = ${usageColumn(
|
|
37
|
+
"conversation_id",
|
|
38
|
+
eventAlias,
|
|
39
|
+
)}
|
|
40
|
+
AND ${usageColumn("created_at", eventAlias)} >= ${runAlias}.started_at
|
|
41
|
+
AND ${usageColumn("created_at", eventAlias)} <= COALESCE(${runAlias}.finished_at, ?)`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function buildScheduleRunWindowParams(
|
|
45
|
+
filter: ScheduleAttributionFilter | undefined,
|
|
46
|
+
now: number,
|
|
47
|
+
): ScheduleAttributionSqlParam[] {
|
|
48
|
+
const normalized = normalizeScheduleAttributionFilter(filter);
|
|
49
|
+
return normalized.scheduleId ? [normalized.scheduleId, now] : [now];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function buildScheduleRunWindowExists({
|
|
53
|
+
eventAlias,
|
|
54
|
+
filter,
|
|
55
|
+
now,
|
|
56
|
+
runAlias = "schedule_filter_runs",
|
|
57
|
+
}: {
|
|
58
|
+
eventAlias: string;
|
|
59
|
+
filter?: ScheduleAttributionFilter;
|
|
60
|
+
now: number;
|
|
61
|
+
runAlias?: string;
|
|
62
|
+
}): ScheduleAttributionSqlFragment {
|
|
63
|
+
return {
|
|
64
|
+
sql: `EXISTS (
|
|
65
|
+
SELECT 1
|
|
66
|
+
FROM cron_runs ${runAlias}
|
|
67
|
+
WHERE ${buildScheduleRunWindowPredicate({
|
|
68
|
+
eventAlias,
|
|
69
|
+
runAlias,
|
|
70
|
+
filter,
|
|
71
|
+
})}
|
|
72
|
+
)`,
|
|
73
|
+
params: buildScheduleRunWindowParams(filter, now),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function buildScheduleAttributionSubquery({
|
|
78
|
+
eventAlias,
|
|
79
|
+
filter,
|
|
80
|
+
now,
|
|
81
|
+
selectExpression,
|
|
82
|
+
runAlias = "schedule_attr_runs",
|
|
83
|
+
}: {
|
|
84
|
+
eventAlias: string;
|
|
85
|
+
filter?: ScheduleAttributionFilter;
|
|
86
|
+
now: number;
|
|
87
|
+
selectExpression: string;
|
|
88
|
+
runAlias?: string;
|
|
89
|
+
}): ScheduleAttributionSqlFragment {
|
|
90
|
+
return {
|
|
91
|
+
sql: `(
|
|
92
|
+
SELECT ${selectExpression}
|
|
93
|
+
FROM cron_runs ${runAlias}
|
|
94
|
+
WHERE ${buildScheduleRunWindowPredicate({
|
|
95
|
+
eventAlias,
|
|
96
|
+
runAlias,
|
|
97
|
+
filter,
|
|
98
|
+
})}
|
|
99
|
+
ORDER BY ${runAlias}.started_at DESC, ${runAlias}.id DESC
|
|
100
|
+
LIMIT 1
|
|
101
|
+
)`,
|
|
102
|
+
params: buildScheduleRunWindowParams(filter, now),
|
|
103
|
+
};
|
|
104
|
+
}
|
package/src/memory/schema/acp.ts
CHANGED
|
@@ -20,6 +20,10 @@ export const acpSessionHistory = sqliteTable(
|
|
|
20
20
|
stopReason: text("stop_reason"),
|
|
21
21
|
error: text("error"),
|
|
22
22
|
eventLogJson: text("event_log_json").notNull().default("[]"),
|
|
23
|
+
// Working directory the agent process was spawned with. Required to
|
|
24
|
+
// resume a persisted session; null for rows written before migration
|
|
25
|
+
// 272 (those sessions are not resumable).
|
|
26
|
+
cwd: text("cwd"),
|
|
23
27
|
},
|
|
24
28
|
(table) => [
|
|
25
29
|
index("idx_acp_session_history_started_at").on(table.startedAt),
|
|
@@ -22,6 +22,7 @@ export const cronJobs = sqliteTable("cron_jobs", {
|
|
|
22
22
|
maxRetries: integer("max_retries").notNull().default(3),
|
|
23
23
|
retryBackoffMs: integer("retry_backoff_ms").notNull().default(60000),
|
|
24
24
|
timeoutMs: integer("timeout_ms"), // script-mode execution timeout override (ms); null = use default
|
|
25
|
+
createdFromConversationId: text("created_from_conversation_id"),
|
|
25
26
|
createdBy: text("created_by").notNull(), // 'agent' | 'user'
|
|
26
27
|
mode: text("mode").notNull().default("execute"), // 'notify' | 'execute'
|
|
27
28
|
routingIntent: text("routing_intent").notNull().default("all_channels"), // 'single_channel' | 'multi_channel' | 'all_channels'
|
|
@@ -278,6 +279,21 @@ export const onboardingEvents = sqliteTable("onboarding_events", {
|
|
|
278
279
|
abVariant: text("ab_variant"),
|
|
279
280
|
});
|
|
280
281
|
|
|
282
|
+
// Aggregated legacy-loopback auth-fallback counts forwarded by the gateway.
|
|
283
|
+
// One row per (guard, path, failure_kind) per flush window; `count` is how many
|
|
284
|
+
// requests fell back to the loopback exemption in that window. Flushed to the
|
|
285
|
+
// platform telemetry endpoint by the usage telemetry reporter.
|
|
286
|
+
export const authFallbackEvents = sqliteTable("auth_fallback_events", {
|
|
287
|
+
id: text("id").primaryKey(),
|
|
288
|
+
createdAt: integer("created_at").notNull(),
|
|
289
|
+
guard: text("guard").notNull(), // 'edge' | 'edge-scoped' | 'edge-guardian'
|
|
290
|
+
path: text("path").notNull(),
|
|
291
|
+
failureKind: text("failure_kind").notNull(),
|
|
292
|
+
count: integer("count").notNull(),
|
|
293
|
+
windowStart: integer("window_start").notNull(),
|
|
294
|
+
windowEnd: integer("window_end").notNull(),
|
|
295
|
+
});
|
|
296
|
+
|
|
281
297
|
export const traceEvents = sqliteTable(
|
|
282
298
|
"trace_events",
|
|
283
299
|
{
|
|
@@ -27,6 +27,7 @@ export interface UsageGroupedSeriesBucket extends UsageDayBucket {
|
|
|
27
27
|
|
|
28
28
|
export interface UsageGroupedBucketRow extends UsageEventBucketRow {
|
|
29
29
|
group_key: string | null;
|
|
30
|
+
group_label?: string | null;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
const VALUE_GROUP_PREFIX = "value:";
|
|
@@ -42,6 +43,9 @@ export function displayUsageGroup(
|
|
|
42
43
|
if (groupBy === "inference_profile") {
|
|
43
44
|
return groupKey === null ? "Default / Unset" : groupKey;
|
|
44
45
|
}
|
|
46
|
+
if (groupBy === "schedule") {
|
|
47
|
+
return groupKey ?? "Other";
|
|
48
|
+
}
|
|
45
49
|
return groupKey ?? "Other";
|
|
46
50
|
}
|
|
47
51
|
|
|
@@ -102,7 +106,8 @@ export function bucketGroupedUsageEvents(
|
|
|
102
106
|
let group = groupedBucket.groups[seriesKey];
|
|
103
107
|
if (!group) {
|
|
104
108
|
group = {
|
|
105
|
-
group:
|
|
109
|
+
group:
|
|
110
|
+
row.group_label ?? displayUsageGroup(options.groupBy, row.group_key),
|
|
106
111
|
groupKey: row.group_key,
|
|
107
112
|
totalInputTokens: 0,
|
|
108
113
|
totalOutputTokens: 0,
|
|
@@ -121,7 +121,7 @@ mock.module("../../../config/assistant-feature-flags.js", () => ({
|
|
|
121
121
|
|
|
122
122
|
let renderedHealth = "";
|
|
123
123
|
let computeThrows = false;
|
|
124
|
-
mock.module("
|
|
124
|
+
mock.module("../../../plugins/defaults/memory-v3-shadow/health.js", () => ({
|
|
125
125
|
computeV3Health: () => {
|
|
126
126
|
if (computeThrows) throw new Error("simulated health compute failure");
|
|
127
127
|
return {};
|
|
@@ -129,12 +129,12 @@ mock.module("../../v3/health.js", () => ({
|
|
|
129
129
|
renderV3Health: () => renderedHealth,
|
|
130
130
|
}));
|
|
131
131
|
|
|
132
|
-
mock.module("
|
|
132
|
+
mock.module("../../../plugins/defaults/memory-v3-shadow/tree.js", () => ({
|
|
133
133
|
loadLeafTree: async () => ({ leaves: new Map(), byPage: new Map() }),
|
|
134
134
|
resolveDataDir: () => "/tmp/v3-data-stub",
|
|
135
135
|
}));
|
|
136
136
|
|
|
137
|
-
mock.module("
|
|
137
|
+
mock.module("../../../plugins/defaults/memory-v3-shadow/core.js", () => ({
|
|
138
138
|
loadCore: async () => new Set<string>(),
|
|
139
139
|
}));
|
|
140
140
|
|
|
@@ -279,7 +279,7 @@ describe("memoryV2ConsolidateJob — non-empty buffer", () => {
|
|
|
279
279
|
expect(runnerLastArgs).not.toBeNull();
|
|
280
280
|
expect(runnerLastArgs?.jobName).toBe("memory.consolidate");
|
|
281
281
|
expect(runnerLastArgs?.source).toBe("memory_v2_consolidation");
|
|
282
|
-
expect(runnerLastArgs?.callSite).toBe("
|
|
282
|
+
expect(runnerLastArgs?.callSite).toBe("memoryV2Consolidation");
|
|
283
283
|
expect(runnerLastArgs?.origin).toBe("memory_consolidation");
|
|
284
284
|
// The whole point of this PR: opt out of activity.failed notifications
|
|
285
285
|
// because consolidation runs on tight intervals and transient failures
|
|
@@ -63,6 +63,19 @@ import { dirname, join } from "node:path";
|
|
|
63
63
|
|
|
64
64
|
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
65
65
|
import type { AssistantConfig } from "../../config/types.js";
|
|
66
|
+
import { loadCore } from "../../plugins/defaults/memory-v3-shadow/core.js";
|
|
67
|
+
import {
|
|
68
|
+
computeV3Health,
|
|
69
|
+
renderV3Health,
|
|
70
|
+
} from "../../plugins/defaults/memory-v3-shadow/health.js";
|
|
71
|
+
import {
|
|
72
|
+
loadLeafTree,
|
|
73
|
+
resolveDataDir,
|
|
74
|
+
} from "../../plugins/defaults/memory-v3-shadow/tree.js";
|
|
75
|
+
import type {
|
|
76
|
+
LeafPath,
|
|
77
|
+
Slug,
|
|
78
|
+
} from "../../plugins/defaults/memory-v3-shadow/types.js";
|
|
66
79
|
import { runBackgroundJob } from "../../runtime/background-job-runner.js";
|
|
67
80
|
import { getLogger } from "../../util/logger.js";
|
|
68
81
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
@@ -74,10 +87,6 @@ import {
|
|
|
74
87
|
type MemoryJobType,
|
|
75
88
|
} from "../jobs-store.js";
|
|
76
89
|
import { getPageIndex } from "../v2/page-index.js";
|
|
77
|
-
import { loadCore } from "../v3/core.js";
|
|
78
|
-
import { computeV3Health, renderV3Health } from "../v3/health.js";
|
|
79
|
-
import { loadLeafTree, resolveDataDir } from "../v3/tree.js";
|
|
80
|
-
import type { LeafPath, Slug } from "../v3/types.js";
|
|
81
90
|
import { MEMORY_V2_CONSOLIDATION_SOURCE } from "./constants.js";
|
|
82
91
|
import { resolveConsolidationPrompt } from "./prompts/consolidation.js";
|
|
83
92
|
|
|
@@ -197,7 +206,7 @@ export async function memoryV2ConsolidateJob(
|
|
|
197
206
|
source: MEMORY_V2_CONSOLIDATION_SOURCE,
|
|
198
207
|
prompt,
|
|
199
208
|
trustContext: { sourceChannel: "vellum", trustClass: "guardian" },
|
|
200
|
-
callSite: "
|
|
209
|
+
callSite: "memoryV2Consolidation",
|
|
201
210
|
timeoutMs: CONSOLIDATION_TIMEOUT_MS,
|
|
202
211
|
origin: "memory_consolidation",
|
|
203
212
|
suppressFailureNotifications: true,
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
import type { ConversationStrategy } from "../channels/config.js";
|
|
22
22
|
import { getConversationStrategy } from "../channels/config.js";
|
|
23
23
|
import type { ChannelId } from "../channels/types.js";
|
|
24
|
-
import { isHomePageEnabled } from "../home/feature-gate.js";
|
|
25
24
|
import {
|
|
26
25
|
addMessage,
|
|
27
26
|
createConversation,
|
|
@@ -120,20 +119,14 @@ export async function pairDeliveryWithConversation(
|
|
|
120
119
|
// Passive vellum notifications surface via the home feed alone and link
|
|
121
120
|
// back to the originating conversation via `signal.sourceContextId`.
|
|
122
121
|
// Materializing a fresh per-notification conversation just to host the
|
|
123
|
-
// seed message leaves a graveyard entry in the sidebar; skip it
|
|
124
|
-
// the producer
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
if (
|
|
132
|
-
strategy === "start_new_conversation" &&
|
|
133
|
-
!signal.requiresConversation &&
|
|
134
|
-
conversationAction?.action !== "reuse_existing" &&
|
|
135
|
-
isHomePageEnabled()
|
|
136
|
-
) {
|
|
122
|
+
// seed message leaves a graveyard entry in the sidebar; skip it
|
|
123
|
+
// unconditionally when the producer did not opt in via
|
|
124
|
+
// `requiresConversation`. The decision engine's `reuse_existing` hint is
|
|
125
|
+
// also ignored here: even a successful reuse would append a seed message
|
|
126
|
+
// to a conversation that the user didn't ask for, and a failed reuse
|
|
127
|
+
// (stale target / source mismatch) falls through to `createConversation`
|
|
128
|
+
// — producing exactly the graveyard entry we want to avoid.
|
|
129
|
+
if (strategy === "start_new_conversation" && !signal.requiresConversation) {
|
|
137
130
|
return {
|
|
138
131
|
conversationId: null,
|
|
139
132
|
messageId: null,
|
|
@@ -149,8 +149,8 @@ function buildSystemPrompt(
|
|
|
149
149
|
` - Avoid meta-send phrasing (e.g. "I'd like to send a notification", "May I go ahead with that?"). Write the recipient-facing message directly.`,
|
|
150
150
|
` - Avoid intermediary-instruction phrasing like "consider telling the guardian", "ask the recipient to", or "the assistant should remind them". Rewrite it as final copy the recipient can act on directly.`,
|
|
151
151
|
` - For telegram: 1-2 concise sentences.`,
|
|
152
|
-
`- \`conversationSeedMessage\` is the opening message in the internal notification conversation
|
|
153
|
-
` - For vellum (desktop):
|
|
152
|
+
`- \`conversationSeedMessage\` is the opening message in the internal notification conversation and also the expanded detail shown in the home feed. It should be richer and more contextual than the popup body.`,
|
|
153
|
+
` - For vellum (desktop): use structured markdown for readability. Break content into bullet points, numbered lists, or short sections with **bold** labels. Avoid long unbroken paragraphs — scan-friendly formatting is preferred.`,
|
|
154
154
|
` - Never dump raw JSON. Include only human-readable context.`,
|
|
155
155
|
``,
|
|
156
156
|
`Conversation reuse guidelines:`,
|
|
@@ -838,7 +838,10 @@ export async function evaluateSignal(
|
|
|
838
838
|
selectedChannels,
|
|
839
839
|
reasoningSummary: "assistant_tool pass-through",
|
|
840
840
|
renderedCopy: Object.fromEntries(
|
|
841
|
-
availableChannels.map((ch) => [
|
|
841
|
+
availableChannels.map((ch) => [
|
|
842
|
+
ch,
|
|
843
|
+
{ title, body, conversationSeedMessage: body },
|
|
844
|
+
]),
|
|
842
845
|
) as NotificationDecision["renderedCopy"],
|
|
843
846
|
conversationActions: Object.fromEntries(
|
|
844
847
|
availableChannels.map((ch) => [ch, { action: "start_new" as const }]),
|
|
@@ -21,6 +21,7 @@ import { appendFeedItem } from "../home/feed-writer.js";
|
|
|
21
21
|
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
|
+
import { isConversationSeedSane } from "./conversation-seed-composer.js";
|
|
24
25
|
import type { NotificationSignal } from "./signal.js";
|
|
25
26
|
import type { NotificationDecision, RenderedChannelCopy } from "./types.js";
|
|
26
27
|
|
|
@@ -77,8 +78,18 @@ export async function writeHomeFeedItemForSignal(
|
|
|
77
78
|
// against `summary` in the row. Leave undefined when absent; renderers
|
|
78
79
|
// fall back to `summary`.
|
|
79
80
|
const resolvedTitle = payloadTitle?.trim() || undefined;
|
|
81
|
+
// Prefer conversationSeedMessage over body for the home feed: the seed
|
|
82
|
+
// message is richer and may contain structured markdown (lists, headers,
|
|
83
|
+
// bold) that the detail panel renders. The popup-oriented `body` is
|
|
84
|
+
// intentionally short (≤ 2 sentences) and loses formatting.
|
|
85
|
+
const seedCandidate = renderedCopy?.conversationSeedMessage;
|
|
80
86
|
const resolvedSummary =
|
|
81
|
-
|
|
87
|
+
(isConversationSeedSane(seedCandidate)
|
|
88
|
+
? seedCandidate.trim()
|
|
89
|
+
: undefined) ||
|
|
90
|
+
renderedCopy?.body?.trim() ||
|
|
91
|
+
payloadBody?.trim() ||
|
|
92
|
+
"";
|
|
82
93
|
if (!resolvedSummary) {
|
|
83
94
|
log.warn(
|
|
84
95
|
{ signalId: signal.signalId, sourceEventName: signal.sourceEventName },
|
|
@@ -118,6 +118,10 @@ export class PermissionPrompter {
|
|
|
118
118
|
label: o.label,
|
|
119
119
|
scope: o.scope,
|
|
120
120
|
})),
|
|
121
|
+
directoryScopeOptions: directoryScopeOptions?.map((o) => ({
|
|
122
|
+
label: o.label,
|
|
123
|
+
scope: o.scope,
|
|
124
|
+
})),
|
|
121
125
|
persistentDecisionsAllowed: persistentDecisionsAllowed ?? true,
|
|
122
126
|
},
|
|
123
127
|
rpcResolve: resolve as (value: unknown) => void,
|
|
@@ -20,6 +20,10 @@ 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 once per tool result, after the tool returns and before the result is sent to the provider. */
|
|
24
|
+
POST_TOOL_USE: "post-tool-use",
|
|
25
|
+
/** 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
|
+
STOP: "stop",
|
|
23
27
|
} as const;
|
|
24
28
|
|
|
25
29
|
/** Union of every hook name declared in {@link HOOKS}. */
|
package/src/plugin-api/index.ts
CHANGED
|
@@ -24,17 +24,16 @@
|
|
|
24
24
|
* - {@link PluginShutdownContext} — passed to `shutdown` hook at teardown
|
|
25
25
|
* - {@link UserPromptSubmitContext} — passed to `user-prompt-submit` hook,
|
|
26
26
|
* fired immediately before the agent loop receives a user's prompt
|
|
27
|
+
* - {@link PostToolUseContext} — passed to `post-tool-use` hook, fired once
|
|
28
|
+
* per tool result before it joins the provider-bound history
|
|
29
|
+
* - {@link StopContext} — passed to `stop` hook, fired when the model yields
|
|
30
|
+
* a response with no tool calls
|
|
27
31
|
* - {@link PluginHookFn} — signature every lifecycle hook implements
|
|
28
32
|
* - {@link PluginLogger} — pino-compatible logger shape on the contexts
|
|
29
33
|
* - {@link ToolDefinition} — author-facing tool spec (default-export shape
|
|
30
34
|
* for both plugin tool files and workspace tool files)
|
|
31
35
|
* - {@link ToolContext} — passed to a plugin tool's `execute` method
|
|
32
36
|
* - {@link ToolExecutionResult} — return shape of a plugin tool's `execute`
|
|
33
|
-
*
|
|
34
|
-
* Pipeline-argument types (`LLMCallArgs`, `MemoryArgs`, etc.) currently
|
|
35
|
-
* live in `assistant/src/plugins/types.ts` and have not yet migrated into
|
|
36
|
-
* this package. A follow-up PR will move them into this surface as the
|
|
37
|
-
* per-pipeline schemas stabilize.
|
|
38
37
|
*/
|
|
39
38
|
|
|
40
39
|
export type { HookName } from "./constants.js";
|
|
@@ -44,6 +43,9 @@ export type {
|
|
|
44
43
|
PluginInitContext,
|
|
45
44
|
PluginLogger,
|
|
46
45
|
PluginShutdownContext,
|
|
46
|
+
PostToolUseContext,
|
|
47
|
+
StopContext,
|
|
48
|
+
StopDecision,
|
|
47
49
|
ToolContext,
|
|
48
50
|
ToolDefinition,
|
|
49
51
|
ToolExecutionResult,
|
package/src/plugin-api/types.ts
CHANGED
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
* removing is breaking and gated on a major bump.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
ContentBlock,
|
|
9
|
+
Message,
|
|
10
|
+
ToolResultContent,
|
|
11
|
+
} from "../providers/types.js";
|
|
8
12
|
|
|
9
13
|
export type {
|
|
10
14
|
ToolContext,
|
|
@@ -47,6 +51,8 @@ export interface PluginLogger {
|
|
|
47
51
|
* - `init` — {@link PluginInitContext}
|
|
48
52
|
* - `shutdown` — {@link PluginShutdownContext}
|
|
49
53
|
* - `user-prompt-submit` — {@link UserPromptSubmitContext}
|
|
54
|
+
* - `post-tool-use` — {@link PostToolUseContext}
|
|
55
|
+
* - `stop` — {@link StopContext}
|
|
50
56
|
*/
|
|
51
57
|
export type PluginHookFn<TCtx = unknown> = (ctx: TCtx) => Promise<TCtx | void>;
|
|
52
58
|
|
|
@@ -121,6 +127,16 @@ export interface PluginShutdownContext {
|
|
|
121
127
|
export interface UserPromptSubmitContext {
|
|
122
128
|
/** Conversation ID the user prompt was submitted on. */
|
|
123
129
|
readonly conversationId: string;
|
|
130
|
+
/**
|
|
131
|
+
* The text of the user prompt that triggered this turn — the resolved
|
|
132
|
+
* user message (after slash-command expansion), independent of any
|
|
133
|
+
* internal rewriting applied to the message that flows into the model.
|
|
134
|
+
* Mirrors the `prompt` field Claude Code / Codex pass to their
|
|
135
|
+
* `UserPromptSubmit` hooks, so hooks that key off the submitted text
|
|
136
|
+
* (e.g. title generation) read it directly rather than reconstructing
|
|
137
|
+
* it from the message arrays.
|
|
138
|
+
*/
|
|
139
|
+
readonly prompt: string;
|
|
124
140
|
/**
|
|
125
141
|
* The user's original message list, immutable for the hook. Plugins
|
|
126
142
|
* may snapshot or compare against this but MUST NOT mutate it.
|
|
@@ -138,3 +154,137 @@ export interface UserPromptSubmitContext {
|
|
|
138
154
|
*/
|
|
139
155
|
readonly logger: PluginLogger;
|
|
140
156
|
}
|
|
157
|
+
|
|
158
|
+
// ─── Post-tool-use hook context ──────────────────────────────────────────────
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Context passed to the `post-tool-use` hook. Fires once per tool result —
|
|
162
|
+
* after the tool returns and before the result is appended to the message
|
|
163
|
+
* history sent to the provider. With several tools dispatched in a single
|
|
164
|
+
* turn, the hook fires once per result, in tool-use order.
|
|
165
|
+
*
|
|
166
|
+
* The hook may transform the result either by mutating `toolResponse` in
|
|
167
|
+
* place (e.g. reassigning `toolResponse.content`) or by returning a new
|
|
168
|
+
* context with a fresh `toolResponse` — see {@link PluginHookFn}'s
|
|
169
|
+
* polymorphic return shape. The daemon threads the final `toolResponse`
|
|
170
|
+
* into the provider-bound history.
|
|
171
|
+
*
|
|
172
|
+
* Multiple plugins' hooks chain in registration order — each plugin's hook
|
|
173
|
+
* sees the previous plugin's mutations. The default tool-result-truncate
|
|
174
|
+
* plugin contributes a hook here that tail-drops oversized output to fit the
|
|
175
|
+
* model's context window; the default tool-error plugin sets
|
|
176
|
+
* {@link additionalContext} with retry coaching for failed results. User hooks
|
|
177
|
+
* can swap in a smarter strategy (e.g. a summarizer) or observe results for
|
|
178
|
+
* side effects.
|
|
179
|
+
*/
|
|
180
|
+
export interface PostToolUseContext {
|
|
181
|
+
/** Conversation ID the tool ran on. */
|
|
182
|
+
readonly conversationId: string;
|
|
183
|
+
/**
|
|
184
|
+
* The tool result block. Plugins may mutate its `content` in place or
|
|
185
|
+
* replace the block by returning a new context.
|
|
186
|
+
*/
|
|
187
|
+
toolResponse: ToolResultContent;
|
|
188
|
+
/**
|
|
189
|
+
* Conversation history up to and including the assistant turn that issued
|
|
190
|
+
* this tool call. The current result is not in it yet — it lives in
|
|
191
|
+
* {@link toolResponse}. A hook reasoning about prior tool outcomes (e.g.
|
|
192
|
+
* how many times a tool has failed in a row) derives that from the history
|
|
193
|
+
* content rather than a precomputed counter, so the signal survives mid-run
|
|
194
|
+
* compaction rewriting the array. Read-only: hooks transform the result via
|
|
195
|
+
* {@link toolResponse}, not by mutating history.
|
|
196
|
+
*/
|
|
197
|
+
readonly messages: ReadonlyArray<Message>;
|
|
198
|
+
/**
|
|
199
|
+
* Extra guidance for the model that is not part of the tool's output. A hook
|
|
200
|
+
* sets this to surface provider-only context — e.g. retry coaching for a
|
|
201
|
+
* failed result — and the daemon appends it to the provider-bound history as
|
|
202
|
+
* a separate block *after* emitting the tool_result, so it reaches the model
|
|
203
|
+
* without polluting the client-facing or persisted tool output. Mirrors
|
|
204
|
+
* Claude Code's PostToolUse `hookSpecificOutput.additionalContext` and the
|
|
205
|
+
* singular of Codex's `additional_contexts`. Unset means no extra context.
|
|
206
|
+
*/
|
|
207
|
+
additionalContext?: string;
|
|
208
|
+
/**
|
|
209
|
+
* The model's context-window size in tokens. Plugins derive their own
|
|
210
|
+
* character budget from this (e.g. a share of the window) rather than
|
|
211
|
+
* receiving a precomputed limit.
|
|
212
|
+
*/
|
|
213
|
+
readonly maxInputTokens: number;
|
|
214
|
+
/**
|
|
215
|
+
* Logger scoped to the current turn. The same instance is shared by
|
|
216
|
+
* every hook in the chain, so plugins should tag their structured log
|
|
217
|
+
* fields (e.g. `{ plugin: "<name>" }`) for attribution.
|
|
218
|
+
*/
|
|
219
|
+
readonly logger: PluginLogger;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ─── Stop hook context ───────────────────────────────────────────────────────
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Binary outcome of the `stop` hook. The agent loop seeds it to `"stop"`
|
|
226
|
+
* and acts on the value the chain settles on:
|
|
227
|
+
*
|
|
228
|
+
* - `"stop"` — let the turn end; the loop yields the assistant response
|
|
229
|
+
* to the user. This is the default.
|
|
230
|
+
* - `"continue"` — re-query the model. The hook is responsible for appending
|
|
231
|
+
* the follow-up turn it wants the model to see to
|
|
232
|
+
* {@link StopContext.messages} before returning.
|
|
233
|
+
*
|
|
234
|
+
* To abort with an error a hook should throw — the loop's error handler
|
|
235
|
+
* surfaces it. There is intentionally no error decision value.
|
|
236
|
+
*/
|
|
237
|
+
export type StopDecision = "continue" | "stop";
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Context passed to the `stop` hook. Fires when the model yields a response
|
|
241
|
+
* with no tool calls — the run's stop boundary, where the loop is about to
|
|
242
|
+
* hand the turn back to the user. The default empty-response plugin uses it
|
|
243
|
+
* to re-query the model when a turn came back empty or as a provider refusal.
|
|
244
|
+
*
|
|
245
|
+
* The hook decides the outcome by setting {@link decision}. When it sets
|
|
246
|
+
* `"continue"` it must also append the follow-up turn (e.g. a nudge `user`
|
|
247
|
+
* message) to {@link messages}; the loop threads those messages into the next
|
|
248
|
+
* iteration. {@link messages} is the full conversation history, carried back
|
|
249
|
+
* verbatim. A hook that needs to reason about just the current response cycle
|
|
250
|
+
* (e.g. whether an earlier turn already delivered visible text) derives that
|
|
251
|
+
* boundary from the history itself — the messages after the last genuine user
|
|
252
|
+
* prompt — rather than an index, since mid-run compaction can rewrite the
|
|
253
|
+
* array.
|
|
254
|
+
*
|
|
255
|
+
* Multiple plugins' hooks chain in registration order — each sees the
|
|
256
|
+
* previous hook's `decision` and `messages` mutations.
|
|
257
|
+
*/
|
|
258
|
+
export interface StopContext {
|
|
259
|
+
/** Conversation ID the run belongs to. */
|
|
260
|
+
readonly conversationId: string;
|
|
261
|
+
/**
|
|
262
|
+
* Full conversation history: the inbound conversation followed by every
|
|
263
|
+
* message produced this run. A hook that sets `decision` to `"continue"`
|
|
264
|
+
* appends its follow-up turn here; the loop carries the result into the
|
|
265
|
+
* next iteration.
|
|
266
|
+
*/
|
|
267
|
+
messages: Message[];
|
|
268
|
+
/**
|
|
269
|
+
* Content blocks of the assistant turn that triggered the stop. Guaranteed
|
|
270
|
+
* to contain no `tool_use` blocks — the hook only fires at the boundary
|
|
271
|
+
* where the model stopped requesting tools.
|
|
272
|
+
*/
|
|
273
|
+
readonly responseContent: ReadonlyArray<ContentBlock>;
|
|
274
|
+
/**
|
|
275
|
+
* Provider-reported stop reason for the assistant turn (e.g. `"refusal"`,
|
|
276
|
+
* `"end_turn"`). `null`/`undefined` when the provider didn't report one.
|
|
277
|
+
*/
|
|
278
|
+
readonly stopReason: string | null | undefined;
|
|
279
|
+
/**
|
|
280
|
+
* Seeded to `"stop"`. A hook sets it to `"continue"` to force another loop
|
|
281
|
+
* iteration; later hooks in the chain may override it.
|
|
282
|
+
*/
|
|
283
|
+
decision: StopDecision;
|
|
284
|
+
/**
|
|
285
|
+
* Logger scoped to the current turn. The same instance is shared by
|
|
286
|
+
* every hook in the chain, so plugins should tag their structured log
|
|
287
|
+
* fields (e.g. `{ plugin: "<name>" }`) for attribution.
|
|
288
|
+
*/
|
|
289
|
+
readonly logger: PluginLogger;
|
|
290
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default compaction implementation.
|
|
3
|
+
*
|
|
4
|
+
* Summarizes conversation history when the context window fills up by
|
|
5
|
+
* delegating to a {@link ContextWindowManager}. The agent loop calls
|
|
6
|
+
* {@link defaultCompact} directly with a {@link CompactionContext}; the request
|
|
7
|
+
* carries the conversational inputs while the manager performs the work.
|
|
8
|
+
*
|
|
9
|
+
* This module is side-effect free: importing it does not register any plugin.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {
|
|
13
|
+
ContextWindowManager,
|
|
14
|
+
ContextWindowResult,
|
|
15
|
+
} from "../../../context/window-manager.js";
|
|
16
|
+
import type { Message } from "../../../providers/types.js";
|
|
17
|
+
import type { TrustClass } from "../../../runtime/actor-trust-resolver.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Name under which the default compaction plugin registers. Exposed so call
|
|
21
|
+
* sites can attribute compaction failures to the default plugin.
|
|
22
|
+
*/
|
|
23
|
+
export const DEFAULT_COMPACTION_PLUGIN_NAME = "default-compaction";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Self-describing compaction request handed to {@link defaultCompact}. Carries
|
|
27
|
+
* the conversational inputs plus the {@link ContextWindowManager} that runs the
|
|
28
|
+
* summary, so the request is the part that can grow toward a model-facing
|
|
29
|
+
* compaction-method shape without coupling callers to the manager's option bag.
|
|
30
|
+
*/
|
|
31
|
+
export interface CompactionContext {
|
|
32
|
+
/** Context window manager that performs the compaction. */
|
|
33
|
+
manager: ContextWindowManager;
|
|
34
|
+
/** Message history to consider for compaction. */
|
|
35
|
+
messages: Message[];
|
|
36
|
+
/** Abort signal forwarded to the compaction summary call. */
|
|
37
|
+
signal?: AbortSignal;
|
|
38
|
+
/** Skip the auto-threshold check (forced/overflow/emergency compaction). */
|
|
39
|
+
force?: boolean;
|
|
40
|
+
/** Per-conversation inference-profile override for the summary call. */
|
|
41
|
+
overrideProfile?: string | null;
|
|
42
|
+
/** Pre-computed token estimate from a prior `shouldCompact()` call. */
|
|
43
|
+
precomputedEstimate?: number;
|
|
44
|
+
/** Legacy keep-boundary hint forwarded to the compactor. */
|
|
45
|
+
minKeepRecentUserTurns?: number;
|
|
46
|
+
/** Trust class of the actor whose turn triggered compaction. */
|
|
47
|
+
actorTrustClass?: TrustClass;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Run compaction for the turn: delegates to the request's context window
|
|
52
|
+
* manager and returns the (possibly summarized) message history.
|
|
53
|
+
*/
|
|
54
|
+
export async function defaultCompact(
|
|
55
|
+
context: CompactionContext,
|
|
56
|
+
): Promise<ContextWindowResult> {
|
|
57
|
+
const { manager, messages, signal, ...options } = context;
|
|
58
|
+
return manager.maybeCompact(messages, signal, options);
|
|
59
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "default-compaction",
|
|
3
3
|
"version": "1.0.0",
|
|
4
|
-
"description": "First-party default plugin
|
|
4
|
+
"description": "First-party default plugin providing the assistant's built-in conversation-history compaction.",
|
|
5
5
|
"private": true,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|