@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
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* ring buffer for `Last-Event-ID` replay
|
|
2
|
+
* Assistant Stream State -- a single per-assistant (per-daemon-process)
|
|
3
|
+
* SSE sequence counter and ring buffer for `Last-Event-ID` replay.
|
|
4
4
|
*
|
|
5
5
|
* Every conversation-scoped outbound event picks up a monotonic `seq`
|
|
6
|
-
*
|
|
7
|
-
* ring buffer
|
|
8
|
-
* daemon
|
|
6
|
+
* from one global counter shared across all conversations, and is pushed
|
|
7
|
+
* onto one shared ring buffer. A reconnecting client presents the highest
|
|
8
|
+
* `seq` it has applied; the daemon replays everything newer from the ring
|
|
9
|
+
* -- re-applying the subscriber's targeting/scope filter -- then goes
|
|
10
|
+
* live.
|
|
11
|
+
*
|
|
12
|
+
* A single global seq space means the reconnect cursor is one number, not
|
|
13
|
+
* a per-conversation map: on one ordered SSE connection the client has
|
|
14
|
+
* received a contiguous prefix of the global stream, so "highest seq
|
|
15
|
+
* applied" is a valid resume point no matter how many conversations are
|
|
16
|
+
* multiplexed on the connection.
|
|
9
17
|
*
|
|
10
18
|
* Bounds (oldest evicted first; first bound hit wins):
|
|
11
19
|
* - Count: 200 events
|
|
@@ -13,9 +21,23 @@
|
|
|
13
21
|
* - Age: 30 seconds
|
|
14
22
|
*
|
|
15
23
|
* The ring is in-memory and per-daemon-process. After a daemon restart
|
|
16
|
-
*
|
|
17
|
-
* path
|
|
18
|
-
*
|
|
24
|
+
* the seq resets and reconnecting clients fall through to the snapshot
|
|
25
|
+
* path. The ring is sized generously enough that a typical refresh
|
|
26
|
+
* round-trip (~1-3s) is well within window.
|
|
27
|
+
*
|
|
28
|
+
* Persisted-seq map: alongside the live counter and ring, this module
|
|
29
|
+
* tracks, per conversation, the `seq` of the last event whose content is
|
|
30
|
+
* durably committed to the message rows (`persistedSeqByConversation`).
|
|
31
|
+
* The `/messages` snapshot returns this value so a client can align the
|
|
32
|
+
* snapshot with the stream: "these rows reflect all of this
|
|
33
|
+
* conversation's events through `seq = S`." It is recorded at each
|
|
34
|
+
* persistence flush (assistant rows persist incrementally, debounced, so
|
|
35
|
+
* the snapshot can lag the live counter) -- never the live counter
|
|
36
|
+
* itself, which would over-claim events that have streamed but not yet
|
|
37
|
+
* been written. It shares the live counter's lifetime by design: both
|
|
38
|
+
* are in-memory and reset together on restart, so a stored value can
|
|
39
|
+
* never dangle against a fresh counter. The map is LRU-bounded; an
|
|
40
|
+
* evicted conversation reports no seq and the client cold-starts.
|
|
19
41
|
*/
|
|
20
42
|
|
|
21
43
|
import type { AssistantEvent } from "./assistant-event.js";
|
|
@@ -26,6 +48,16 @@ const RING_COUNT_LIMIT = 200;
|
|
|
26
48
|
const RING_SIZE_LIMIT_BYTES = 256 * 1024;
|
|
27
49
|
const RING_AGE_LIMIT_MS = 30_000;
|
|
28
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Cap on how many conversations retain a persisted-seq entry. Unlike the
|
|
53
|
+
* ring (which the live stream needs only briefly), the persisted-seq map
|
|
54
|
+
* grows with the number of conversations that have ever streamed in this
|
|
55
|
+
* process. Bound it LRU so it can't grow without limit; an evicted
|
|
56
|
+
* conversation simply reports no seq on its next `/messages` and the
|
|
57
|
+
* client cold-starts, which is harmless.
|
|
58
|
+
*/
|
|
59
|
+
const PERSISTED_SEQ_CONVERSATION_LIMIT = 1024;
|
|
60
|
+
|
|
29
61
|
// ── Types ────────────────────────────────────────────────────────────
|
|
30
62
|
|
|
31
63
|
/**
|
|
@@ -63,30 +95,33 @@ interface RingEntry {
|
|
|
63
95
|
targeting?: EventTargeting;
|
|
64
96
|
}
|
|
65
97
|
|
|
66
|
-
interface
|
|
98
|
+
interface AssistantStreamState {
|
|
67
99
|
nextSeq: number;
|
|
68
100
|
ring: RingEntry[];
|
|
69
101
|
totalSizeBytes: number;
|
|
102
|
+
/**
|
|
103
|
+
* Per-conversation `seq` of the last event durably committed to the
|
|
104
|
+
* message rows. Insertion order is maintained as an LRU recency list:
|
|
105
|
+
* the oldest key is evicted first once the map exceeds
|
|
106
|
+
* {@link PERSISTED_SEQ_CONVERSATION_LIMIT}.
|
|
107
|
+
*/
|
|
108
|
+
persistedSeqByConversation: Map<string, number>;
|
|
70
109
|
}
|
|
71
110
|
|
|
72
111
|
// ── State ────────────────────────────────────────────────────────────
|
|
73
112
|
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
streams.set(conversationId, state);
|
|
81
|
-
}
|
|
82
|
-
return state;
|
|
83
|
-
}
|
|
113
|
+
const state: AssistantStreamState = {
|
|
114
|
+
nextSeq: 1,
|
|
115
|
+
ring: [],
|
|
116
|
+
totalSizeBytes: 0,
|
|
117
|
+
persistedSeqByConversation: new Map(),
|
|
118
|
+
};
|
|
84
119
|
|
|
85
120
|
// ── Public API ───────────────────────────────────────────────────────
|
|
86
121
|
|
|
87
122
|
/**
|
|
88
|
-
* Assign a monotonic `seq` to a conversation-scoped event and push
|
|
89
|
-
* onto the ring buffer. No-op when `event.conversationId` is absent
|
|
123
|
+
* Assign a monotonic global `seq` to a conversation-scoped event and push
|
|
124
|
+
* it onto the ring buffer. No-op when `event.conversationId` is absent
|
|
90
125
|
* (unscoped broadcasts are never replayable).
|
|
91
126
|
*
|
|
92
127
|
* When `options.targeting` is provided, the metadata is stored on the
|
|
@@ -101,10 +136,8 @@ export function stampAndBuffer(
|
|
|
101
136
|
event: AssistantEvent,
|
|
102
137
|
options?: { targeting?: EventTargeting },
|
|
103
138
|
): void {
|
|
104
|
-
|
|
105
|
-
if (cid == null) return;
|
|
139
|
+
if (event.conversationId == null) return;
|
|
106
140
|
|
|
107
|
-
const state = getOrCreate(cid);
|
|
108
141
|
event.seq = state.nextSeq++;
|
|
109
142
|
|
|
110
143
|
// Approximate size by serialized JSON length. This is the same
|
|
@@ -123,43 +156,36 @@ export function stampAndBuffer(
|
|
|
123
156
|
state.ring.push(entry);
|
|
124
157
|
state.totalSizeBytes += sizeBytes;
|
|
125
158
|
|
|
126
|
-
evict(
|
|
159
|
+
evict();
|
|
127
160
|
}
|
|
128
161
|
|
|
129
162
|
/**
|
|
130
|
-
* Replay events with `seq > lastSeenSeq`
|
|
163
|
+
* Replay events with `seq > lastSeenSeq` from the single global ring.
|
|
131
164
|
* Returns `null` when the requested cursor is older than the oldest
|
|
132
165
|
* buffered entry -- callers should fall back to a snapshot resync.
|
|
133
166
|
*
|
|
134
167
|
* When `subscriber` is provided, entries carrying targeting metadata
|
|
135
168
|
* are filtered using the same rules as the live `publish()` path in
|
|
136
|
-
* `AssistantEventHub
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
169
|
+
* `AssistantEventHub`, so targeted events do not leak to subscribers
|
|
170
|
+
* outside their intended delivery set on reconnect.
|
|
171
|
+
*
|
|
172
|
+
* When `conversationId` is provided, only that conversation's events are
|
|
173
|
+
* returned -- a conversation-scoped subscription only delivers its own
|
|
174
|
+
* conversation live, so replaying any other conversation's gap would
|
|
175
|
+
* push events the client will never receive again live.
|
|
140
176
|
*
|
|
141
|
-
* Sweeps age-expired entries at read time so an idle
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* would retain its tail until the next write). When the sweep
|
|
145
|
-
* drains the ring entirely, the conversation's state entry is
|
|
146
|
-
* dropped to keep the global map from growing unboundedly with
|
|
147
|
-
* inactive conversations.
|
|
177
|
+
* Sweeps age-expired entries at read time so an idle stream cannot serve
|
|
178
|
+
* stale deltas past the 30-second window (eviction otherwise only runs on
|
|
179
|
+
* `stampAndBuffer`).
|
|
148
180
|
*/
|
|
149
181
|
export function getReplayWindow(
|
|
150
|
-
conversationId: string,
|
|
151
182
|
lastSeenSeq: number,
|
|
152
183
|
subscriber?: ReplaySubscriber,
|
|
184
|
+
conversationId?: string,
|
|
153
185
|
): readonly AssistantEvent[] | null {
|
|
154
|
-
|
|
155
|
-
if (!state) return [];
|
|
186
|
+
evict();
|
|
156
187
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (state.ring.length === 0) {
|
|
160
|
-
streams.delete(conversationId);
|
|
161
|
-
return [];
|
|
162
|
-
}
|
|
188
|
+
if (state.ring.length === 0) return [];
|
|
163
189
|
|
|
164
190
|
const oldest = state.ring[0]?.seq ?? Infinity;
|
|
165
191
|
if (lastSeenSeq < oldest - 1) return null;
|
|
@@ -168,39 +194,87 @@ export function getReplayWindow(
|
|
|
168
194
|
.filter(
|
|
169
195
|
(entry) =>
|
|
170
196
|
entry.seq > lastSeenSeq &&
|
|
197
|
+
(conversationId == null ||
|
|
198
|
+
entry.event.conversationId === conversationId) &&
|
|
171
199
|
(subscriber == null || matchesSubscriber(entry, subscriber)),
|
|
172
200
|
)
|
|
173
201
|
.map((entry) => entry.event);
|
|
174
202
|
}
|
|
175
203
|
|
|
176
204
|
/**
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
205
|
+
* Current high-water `seq` -- the value last assigned by
|
|
206
|
+
* {@link stampAndBuffer}, or `0` when nothing has been stamped yet in
|
|
207
|
+
* this process.
|
|
208
|
+
*
|
|
209
|
+
* Read synchronously right after emitting an event to learn that event's
|
|
210
|
+
* `seq`: `stampAndBuffer` runs inline on the publish path (before the
|
|
211
|
+
* async fanout), so no other event can interleave between the emit
|
|
212
|
+
* returning and this read on the single-threaded event loop.
|
|
213
|
+
*/
|
|
214
|
+
export function getCurrentSeq(): number {
|
|
215
|
+
return state.nextSeq - 1;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Record that conversation `conversationId` has durably persisted all of
|
|
220
|
+
* its events through `seq`. Called at each persistence flush with the
|
|
221
|
+
* `seq` of the last event whose content the write committed.
|
|
222
|
+
*
|
|
223
|
+
* Monotonic: a lower `seq` never regresses a higher one (out-of-order
|
|
224
|
+
* async commits are clamped). LRU-bounded by
|
|
225
|
+
* {@link PERSISTED_SEQ_CONVERSATION_LIMIT}: re-recording refreshes
|
|
226
|
+
* recency, and the oldest conversation is evicted once the cap is
|
|
227
|
+
* exceeded. Non-positive or non-finite `seq` values are ignored.
|
|
228
|
+
*/
|
|
229
|
+
export function recordPersistedSeq(conversationId: string, seq: number): void {
|
|
230
|
+
if (!Number.isFinite(seq) || seq <= 0) return;
|
|
231
|
+
|
|
232
|
+
const map = state.persistedSeqByConversation;
|
|
233
|
+
const prev = map.get(conversationId);
|
|
234
|
+
if (prev !== undefined) {
|
|
235
|
+
// Re-insert to move this key to the most-recently-used end.
|
|
236
|
+
map.delete(conversationId);
|
|
237
|
+
map.set(conversationId, Math.max(prev, seq));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
map.set(conversationId, seq);
|
|
242
|
+
if (map.size > PERSISTED_SEQ_CONVERSATION_LIMIT) {
|
|
243
|
+
const oldestKey = map.keys().next().value;
|
|
244
|
+
if (oldestKey !== undefined) map.delete(oldestKey);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Highest `seq` durably persisted for `conversationId`, or `null` when
|
|
250
|
+
* none has been recorded in this process (cold conversation, or evicted
|
|
251
|
+
* from the LRU map). Returned by `/messages` so a client can align the
|
|
252
|
+
* snapshot with the live stream.
|
|
180
253
|
*/
|
|
181
|
-
export function
|
|
182
|
-
|
|
254
|
+
export function getPersistedSeq(conversationId: string): number | null {
|
|
255
|
+
return state.persistedSeqByConversation.get(conversationId) ?? null;
|
|
183
256
|
}
|
|
184
257
|
|
|
185
258
|
/**
|
|
186
259
|
* Reset all stream state. Test-only.
|
|
187
260
|
*/
|
|
188
|
-
export function
|
|
189
|
-
|
|
261
|
+
export function _resetStreamStateForTesting(): void {
|
|
262
|
+
state.nextSeq = 1;
|
|
263
|
+
state.ring = [];
|
|
264
|
+
state.totalSizeBytes = 0;
|
|
265
|
+
state.persistedSeqByConversation.clear();
|
|
190
266
|
}
|
|
191
267
|
|
|
192
268
|
/**
|
|
193
269
|
* Read-only inspector for tests.
|
|
194
270
|
*/
|
|
195
|
-
export function _peekStreamForTesting(
|
|
271
|
+
export function _peekStreamForTesting(): {
|
|
196
272
|
nextSeq: number;
|
|
197
273
|
ringLength: number;
|
|
198
274
|
totalSizeBytes: number;
|
|
199
275
|
oldestSeq: number | null;
|
|
200
276
|
newestSeq: number | null;
|
|
201
|
-
}
|
|
202
|
-
const state = streams.get(conversationId);
|
|
203
|
-
if (!state) return null;
|
|
277
|
+
} {
|
|
204
278
|
return {
|
|
205
279
|
nextSeq: state.nextSeq,
|
|
206
280
|
ringLength: state.ring.length,
|
|
@@ -276,7 +350,7 @@ function matchesSubscriber(
|
|
|
276
350
|
return true;
|
|
277
351
|
}
|
|
278
352
|
|
|
279
|
-
function evict(
|
|
353
|
+
function evict(): void {
|
|
280
354
|
const now = Date.now();
|
|
281
355
|
while (state.ring.length > 0) {
|
|
282
356
|
const head = state.ring[0];
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* 3. Consume user decisions and apply them to the underlying session
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { findConversation } from "../daemon/conversation-
|
|
12
|
+
import { findConversation } from "../daemon/conversation-registry.js";
|
|
13
13
|
import type { UserDecision } from "../permissions/types.js";
|
|
14
14
|
import { composeApprovalMessage } from "./approval-message-composer.js";
|
|
15
15
|
import type {
|
|
@@ -19,7 +19,12 @@ import { httpError } from "./http-errors.js";
|
|
|
19
19
|
import { withErrorHandling } from "./middleware/error-handler.js";
|
|
20
20
|
import { routeDefinitionsToHTTPRoutes } from "./routes/http-adapter.js";
|
|
21
21
|
import { ROUTES } from "./routes/index.js";
|
|
22
|
-
import type {
|
|
22
|
+
import type {
|
|
23
|
+
RouteLoggingConfig,
|
|
24
|
+
RoutePathParam,
|
|
25
|
+
RouteRequestBody,
|
|
26
|
+
RouteResponseBody,
|
|
27
|
+
} from "./routes/types.js";
|
|
23
28
|
|
|
24
29
|
// ---------------------------------------------------------------------------
|
|
25
30
|
// Route definition types
|
|
@@ -64,17 +69,6 @@ export interface RouteAdditionalResponse {
|
|
|
64
69
|
schema?: RouteBodySchema | Record<string, unknown>;
|
|
65
70
|
}
|
|
66
71
|
|
|
67
|
-
/**
|
|
68
|
-
* Request-body variant keyed by Content-Type. Use this when an endpoint
|
|
69
|
-
* accepts multiple body shapes (e.g. `application/octet-stream` OR
|
|
70
|
-
* `application/json`). For the common single-JSON case, use `requestBody`.
|
|
71
|
-
*/
|
|
72
|
-
export interface RouteRequestBodyVariant {
|
|
73
|
-
contentType: string;
|
|
74
|
-
/** Zod schema or plain JSON Schema fragment. Plain objects are embedded verbatim. */
|
|
75
|
-
schema: RouteBodySchema | Record<string, unknown>;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
72
|
/**
|
|
79
73
|
* A single route entry in the declarative table.
|
|
80
74
|
*
|
|
@@ -110,17 +104,18 @@ export interface HTTPRouteDefinition {
|
|
|
110
104
|
tags?: string[];
|
|
111
105
|
/** Query parameter definitions for the operation. */
|
|
112
106
|
queryParams?: RouteQueryParam[];
|
|
113
|
-
/** Zod schema for the request body (POST/PUT/PATCH/DELETE). */
|
|
114
|
-
requestBody?: RouteBodySchema;
|
|
115
107
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
|
|
108
|
+
* Request body for POST/PUT/PATCH/DELETE. A bare Zod schema is advertised
|
|
109
|
+
* as `application/json`; use the `{ contentType, schema }` form for non-JSON
|
|
110
|
+
* bodies (e.g. a raw `application/octet-stream` upload).
|
|
111
|
+
*/
|
|
112
|
+
requestBody?: RouteRequestBody;
|
|
113
|
+
/**
|
|
114
|
+
* Success response body. A bare Zod schema is advertised as
|
|
115
|
+
* `application/json`; use the `{ contentType, schema }` form for non-JSON
|
|
116
|
+
* responses (e.g. a binary `application/octet-stream` download).
|
|
120
117
|
*/
|
|
121
|
-
|
|
122
|
-
/** Zod schema for the success response body. */
|
|
123
|
-
responseBody?: RouteBodySchema;
|
|
118
|
+
responseBody?: RouteResponseBody;
|
|
124
119
|
/**
|
|
125
120
|
* HTTP status code for the documented success response. Defaults to 200.
|
|
126
121
|
* Set to "202" for async endpoints that enqueue a job and return
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared types for the runtime HTTP server and its route handlers.
|
|
3
3
|
*/
|
|
4
|
+
import type {
|
|
5
|
+
ConversationMessage,
|
|
6
|
+
ConversationMessageAttachment,
|
|
7
|
+
} from "../api/responses/conversation-message.js";
|
|
4
8
|
import type { ChannelId, InterfaceId } from "../channels/types.js";
|
|
5
9
|
import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
6
10
|
import type { Conversation } from "../daemon/conversation.js";
|
|
@@ -137,74 +141,16 @@ export interface RuntimeHttpServerOptions {
|
|
|
137
141
|
hostname?: string;
|
|
138
142
|
}
|
|
139
143
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
data?: string;
|
|
147
|
-
thumbnailData?: string;
|
|
148
|
-
fileBacked?: boolean;
|
|
149
|
-
}
|
|
144
|
+
/**
|
|
145
|
+
* Structured attachment metadata returned on a history row. Canonical wire
|
|
146
|
+
* shape lives in `@vellumai/assistant-api`; aliased here so route modules can
|
|
147
|
+
* keep importing the runtime-local name.
|
|
148
|
+
*/
|
|
149
|
+
export type RuntimeAttachmentMetadata = ConversationMessageAttachment;
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
mergedMessageIds?: string[];
|
|
158
|
-
role: string;
|
|
159
|
-
timestamp: string;
|
|
160
|
-
attachments: RuntimeAttachmentMetadata[];
|
|
161
|
-
toolCalls?: Array<{
|
|
162
|
-
name: string;
|
|
163
|
-
input: Record<string, unknown>;
|
|
164
|
-
result?: string;
|
|
165
|
-
isError?: boolean;
|
|
166
|
-
riskLevel?: string;
|
|
167
|
-
riskReason?: string;
|
|
168
|
-
autoApproved?: boolean;
|
|
169
|
-
approvalMode?: string;
|
|
170
|
-
approvalReason?: string;
|
|
171
|
-
riskThreshold?: string;
|
|
172
|
-
}>;
|
|
173
|
-
surfaces?: Array<{
|
|
174
|
-
surfaceId: string;
|
|
175
|
-
surfaceType: string;
|
|
176
|
-
title?: string;
|
|
177
|
-
data: Record<string, unknown>;
|
|
178
|
-
actions?: unknown[];
|
|
179
|
-
display?: string;
|
|
180
|
-
}>;
|
|
181
|
-
textSegments?: string[];
|
|
182
|
-
thinkingSegments?: string[];
|
|
183
|
-
contentOrder?: string[];
|
|
184
|
-
subagentNotification?: {
|
|
185
|
-
subagentId: string;
|
|
186
|
-
label: string;
|
|
187
|
-
status: string;
|
|
188
|
-
error?: string;
|
|
189
|
-
conversationId?: string;
|
|
190
|
-
objective?: string;
|
|
191
|
-
};
|
|
192
|
-
slackMessage?: {
|
|
193
|
-
channelId: string;
|
|
194
|
-
channelName?: string;
|
|
195
|
-
channelTs: string;
|
|
196
|
-
threadTs?: string;
|
|
197
|
-
sender?: {
|
|
198
|
-
displayName?: string;
|
|
199
|
-
externalUserId?: string;
|
|
200
|
-
};
|
|
201
|
-
messageLink?: {
|
|
202
|
-
appUrl?: string;
|
|
203
|
-
webUrl?: string;
|
|
204
|
-
};
|
|
205
|
-
threadLink?: {
|
|
206
|
-
appUrl?: string;
|
|
207
|
-
webUrl?: string;
|
|
208
|
-
};
|
|
209
|
-
};
|
|
210
|
-
}
|
|
151
|
+
/**
|
|
152
|
+
* The daemon's history-row payload. Canonical wire contract lives in
|
|
153
|
+
* `@vellumai/assistant-api` (`responses/conversation-message.ts`) so the
|
|
154
|
+
* producer and every consumer (web, CLI, evals) derive from one source.
|
|
155
|
+
*/
|
|
156
|
+
export type RuntimeMessagePayload = ConversationMessage;
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* `"timed_out"`.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
import { findConversation } from "../daemon/conversation-
|
|
33
|
+
import { findConversation } from "../daemon/conversation-registry.js";
|
|
34
34
|
import { showStandaloneSurface } from "../daemon/conversation-surfaces.js";
|
|
35
35
|
import { getLogger } from "../util/logger.js";
|
|
36
36
|
import { mintDecisionToken } from "./decision-token.js";
|
|
@@ -38,6 +38,7 @@ export interface ConfirmationDetails {
|
|
|
38
38
|
pattern: string;
|
|
39
39
|
}>;
|
|
40
40
|
scopeOptions: Array<{ label: string; scope: string }>;
|
|
41
|
+
directoryScopeOptions?: Array<{ label: string; scope: string }>;
|
|
41
42
|
persistentDecisionsAllowed?: boolean;
|
|
42
43
|
/** ACP tool kind from the agent (e.g. "read", "edit", "execute"). */
|
|
43
44
|
acpToolKind?: string;
|