@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
|
@@ -55,12 +55,21 @@ interface TtsProviderCatalogCapabilities {
|
|
|
55
55
|
readonly supportedFormats: readonly string[];
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Link to a provider's API-key management page, shown in settings UI.
|
|
60
|
+
*/
|
|
61
|
+
interface TtsCredentialsGuide {
|
|
62
|
+
readonly description: string;
|
|
63
|
+
readonly url: string;
|
|
64
|
+
readonly linkLabel: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
58
67
|
/**
|
|
59
68
|
* A single entry in the TTS provider catalog.
|
|
60
69
|
*
|
|
61
70
|
* Captures everything the system needs to know about a provider at a
|
|
62
71
|
* metadata level — identity, display name, telephony call mode,
|
|
63
|
-
* capabilities, and
|
|
72
|
+
* capabilities, secret requirements, and client-facing display metadata.
|
|
64
73
|
*/
|
|
65
74
|
interface TtsProviderCatalogEntry {
|
|
66
75
|
/** Unique provider identifier matching {@link TtsProviderId}. */
|
|
@@ -69,6 +78,18 @@ interface TtsProviderCatalogEntry {
|
|
|
69
78
|
/** Human-readable name for display in settings UI and logs. */
|
|
70
79
|
readonly displayName: string;
|
|
71
80
|
|
|
81
|
+
/** Short description shown beneath the provider name in settings UI. */
|
|
82
|
+
readonly subtitle: string;
|
|
83
|
+
|
|
84
|
+
/** Whether the provider supports user-chosen voice IDs. */
|
|
85
|
+
readonly supportsVoiceSelection: boolean;
|
|
86
|
+
|
|
87
|
+
/** Placeholder text for the API-key input in settings UI. */
|
|
88
|
+
readonly apiKeyPlaceholder: string;
|
|
89
|
+
|
|
90
|
+
/** Link to the provider's API-key management page. */
|
|
91
|
+
readonly credentialsGuide: TtsCredentialsGuide;
|
|
92
|
+
|
|
72
93
|
/** How this provider integrates with the telephony call path. */
|
|
73
94
|
readonly callMode: TtsCallMode;
|
|
74
95
|
|
|
@@ -106,6 +127,16 @@ const CATALOG: readonly TtsProviderCatalogEntry[] = [
|
|
|
106
127
|
{
|
|
107
128
|
id: "elevenlabs",
|
|
108
129
|
displayName: "ElevenLabs",
|
|
130
|
+
subtitle:
|
|
131
|
+
"High-quality voice synthesis for conversations and read-aloud. Requires an ElevenLabs API key.",
|
|
132
|
+
supportsVoiceSelection: true,
|
|
133
|
+
apiKeyPlaceholder: "sk_…",
|
|
134
|
+
credentialsGuide: {
|
|
135
|
+
description:
|
|
136
|
+
"Sign in to ElevenLabs, go to your Profile, and copy your API key.",
|
|
137
|
+
url: "https://elevenlabs.io/app/settings/api-keys",
|
|
138
|
+
linkLabel: "Open ElevenLabs API Keys",
|
|
139
|
+
},
|
|
109
140
|
callMode: "native-twilio",
|
|
110
141
|
allowNativeFallback: true,
|
|
111
142
|
capabilities: {
|
|
@@ -124,6 +155,16 @@ const CATALOG: readonly TtsProviderCatalogEntry[] = [
|
|
|
124
155
|
{
|
|
125
156
|
id: "fish-audio",
|
|
126
157
|
displayName: "Fish Audio",
|
|
158
|
+
subtitle:
|
|
159
|
+
"Natural-sounding voice synthesis with custom voice cloning. Requires a Fish Audio API key and voice reference ID.",
|
|
160
|
+
supportsVoiceSelection: true,
|
|
161
|
+
apiKeyPlaceholder: "Enter your Fish Audio API key",
|
|
162
|
+
credentialsGuide: {
|
|
163
|
+
description:
|
|
164
|
+
"Sign in to Fish Audio, navigate to API Keys in your dashboard, and create a new key.",
|
|
165
|
+
url: "https://fish.audio/app/api-keys/",
|
|
166
|
+
linkLabel: "Open Fish Audio API Keys",
|
|
167
|
+
},
|
|
127
168
|
callMode: "synthesized-play",
|
|
128
169
|
allowNativeFallback: true,
|
|
129
170
|
capabilities: {
|
|
@@ -142,6 +183,16 @@ const CATALOG: readonly TtsProviderCatalogEntry[] = [
|
|
|
142
183
|
{
|
|
143
184
|
id: "deepgram",
|
|
144
185
|
displayName: "Deepgram",
|
|
186
|
+
subtitle:
|
|
187
|
+
"Fast, accurate text-to-speech synthesis. Uses the same API key as Deepgram speech-to-text.",
|
|
188
|
+
supportsVoiceSelection: false,
|
|
189
|
+
apiKeyPlaceholder: "Enter your Deepgram API key",
|
|
190
|
+
credentialsGuide: {
|
|
191
|
+
description:
|
|
192
|
+
"Sign in to Deepgram, navigate to your API Keys page, and create or copy an existing key. This is the same key used for speech-to-text.",
|
|
193
|
+
url: "https://console.deepgram.com/",
|
|
194
|
+
linkLabel: "Open Deepgram Console",
|
|
195
|
+
},
|
|
145
196
|
callMode: "synthesized-play",
|
|
146
197
|
allowNativeFallback: false,
|
|
147
198
|
capabilities: {
|
|
@@ -159,6 +210,16 @@ const CATALOG: readonly TtsProviderCatalogEntry[] = [
|
|
|
159
210
|
{
|
|
160
211
|
id: "xai",
|
|
161
212
|
displayName: "xAI",
|
|
213
|
+
subtitle:
|
|
214
|
+
"Text-to-speech from xAI with expressive voices (eve, ara, rex, sal, leo). Requires an xAI API key.",
|
|
215
|
+
supportsVoiceSelection: false,
|
|
216
|
+
apiKeyPlaceholder: "Enter your xAI API key",
|
|
217
|
+
credentialsGuide: {
|
|
218
|
+
description:
|
|
219
|
+
"Sign in to the xAI console, navigate to API Keys, and create a new key.",
|
|
220
|
+
url: "https://console.x.ai/",
|
|
221
|
+
linkLabel: "Open xAI Console",
|
|
222
|
+
},
|
|
162
223
|
callMode: "synthesized-play",
|
|
163
224
|
allowNativeFallback: false,
|
|
164
225
|
capabilities: {
|
|
@@ -199,6 +260,20 @@ export function listCatalogProviderIds(): TtsProviderId[] {
|
|
|
199
260
|
return CATALOG.map((entry) => entry.id);
|
|
200
261
|
}
|
|
201
262
|
|
|
263
|
+
/**
|
|
264
|
+
* List all catalog providers projected to client-facing display fields only.
|
|
265
|
+
*/
|
|
266
|
+
export function listCatalogProvidersForDisplay() {
|
|
267
|
+
return CATALOG.map((e) => ({
|
|
268
|
+
id: e.id,
|
|
269
|
+
displayName: e.displayName,
|
|
270
|
+
subtitle: e.subtitle,
|
|
271
|
+
supportsVoiceSelection: e.supportsVoiceSelection,
|
|
272
|
+
apiKeyPlaceholder: e.apiKeyPlaceholder,
|
|
273
|
+
credentialsGuide: e.credentialsGuide,
|
|
274
|
+
}));
|
|
275
|
+
}
|
|
276
|
+
|
|
202
277
|
/**
|
|
203
278
|
* Look up a catalog entry by provider ID.
|
|
204
279
|
*
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Async mutex for serializing access to a shared resource.
|
|
3
|
+
*
|
|
4
|
+
* Callers wait in FIFO order. `withLock(fn)` is the primary API —
|
|
5
|
+
* it acquires the lock, runs `fn`, and releases the lock when `fn`
|
|
6
|
+
* settles (even on throw).
|
|
7
|
+
*
|
|
8
|
+
* Used by git-service (per-workspace repo operations) and
|
|
9
|
+
* conversation-title-service (serial LLM calls) to prevent
|
|
10
|
+
* concurrent access to resources that cannot safely overlap.
|
|
11
|
+
*/
|
|
12
|
+
export class Mutex {
|
|
13
|
+
private locked = false;
|
|
14
|
+
private waitQueue: Array<() => void> = [];
|
|
15
|
+
|
|
16
|
+
async acquire(): Promise<void> {
|
|
17
|
+
if (!this.locked) {
|
|
18
|
+
this.locked = true;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
await new Promise<void>((resolve) => {
|
|
22
|
+
this.waitQueue.push(resolve);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
release(): void {
|
|
27
|
+
const next = this.waitQueue.shift();
|
|
28
|
+
if (next) {
|
|
29
|
+
next();
|
|
30
|
+
} else {
|
|
31
|
+
this.locked = false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Execute `fn` while holding the lock.
|
|
37
|
+
* Automatically releases the lock when done, even if `fn` throws.
|
|
38
|
+
*/
|
|
39
|
+
async withLock<T>(fn: () => Promise<T>): Promise<T> {
|
|
40
|
+
await this.acquire();
|
|
41
|
+
try {
|
|
42
|
+
return await fn();
|
|
43
|
+
} finally {
|
|
44
|
+
this.release();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -12,6 +12,7 @@ import { promisify } from "node:util";
|
|
|
12
12
|
|
|
13
13
|
import { getConfig } from "../config/loader.js";
|
|
14
14
|
import { getLogger } from "../util/logger.js";
|
|
15
|
+
import { Mutex } from "../util/mutex.js";
|
|
15
16
|
import { PromiseGuard } from "../util/promise-guard.js";
|
|
16
17
|
|
|
17
18
|
const execFileAsync = promisify(execFile);
|
|
@@ -119,48 +120,6 @@ interface ExecError extends Error {
|
|
|
119
120
|
code?: string | number;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
/**
|
|
123
|
-
* Simple mutex implementation for per-workspace git operation serialization.
|
|
124
|
-
* Prevents concurrent git operations from corrupting the repository state.
|
|
125
|
-
*/
|
|
126
|
-
class Mutex {
|
|
127
|
-
private locked = false;
|
|
128
|
-
private waitQueue: Array<() => void> = [];
|
|
129
|
-
|
|
130
|
-
async acquire(): Promise<void> {
|
|
131
|
-
if (!this.locked) {
|
|
132
|
-
this.locked = true;
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
// Wait for the lock to be released
|
|
136
|
-
await new Promise<void>((resolve) => {
|
|
137
|
-
this.waitQueue.push(resolve);
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
release(): void {
|
|
142
|
-
const next = this.waitQueue.shift();
|
|
143
|
-
if (next) {
|
|
144
|
-
next();
|
|
145
|
-
} else {
|
|
146
|
-
this.locked = false;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Execute a function while holding the lock.
|
|
152
|
-
* Automatically releases the lock when done, even if the function throws.
|
|
153
|
-
*/
|
|
154
|
-
async withLock<T>(fn: () => Promise<T>): Promise<T> {
|
|
155
|
-
await this.acquire();
|
|
156
|
-
try {
|
|
157
|
-
return await fn();
|
|
158
|
-
} finally {
|
|
159
|
-
this.release();
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
123
|
interface GitCommitMetadata {
|
|
165
124
|
/** Optional metadata to include in the commit message or as git notes */
|
|
166
125
|
[key: string]: unknown;
|
|
@@ -9,10 +9,9 @@ import type { WorkspaceMigration } from "./types.js";
|
|
|
9
9
|
* `conversationSummarization` is invoked from `ContextWindowManager.
|
|
10
10
|
* updateSummary()` during mid-loop compaction. Without a call-site entry it
|
|
11
11
|
* falls through to `llm.default` (opus + `effort: "max"` + `thinking:
|
|
12
|
-
* { enabled: true }` + `maxTokens: 64000`), which is far too expensive
|
|
13
|
-
* summarizing a ~150k-token transcript inside the agent
|
|
14
|
-
*
|
|
15
|
-
* failing the turn.
|
|
12
|
+
* { enabled: true }` + `maxTokens: 64000`), which is far too expensive and
|
|
13
|
+
* slow for summarizing a ~150k-token transcript inside the agent loop —
|
|
14
|
+
* the summary call would stall the turn.
|
|
16
15
|
*
|
|
17
16
|
* This migration seeds `effort: "low"` and `thinking: { enabled: false }`
|
|
18
17
|
* (and opus-4.7 as the model when absent) so the summary call runs cheaply
|
|
@@ -99,7 +98,7 @@ export const seedConversationSummarizationCallsiteMigration: WorkspaceMigration
|
|
|
99
98
|
},
|
|
100
99
|
down(_workspaceDir: string): void {
|
|
101
100
|
// Forward-only: removing the seeded defaults would reintroduce the
|
|
102
|
-
//
|
|
101
|
+
// expensive, slow summary call this migration fixes.
|
|
103
102
|
},
|
|
104
103
|
};
|
|
105
104
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
const THIRTY_MINUTES_MS = 30 * 60 * 1000;
|
|
7
|
+
const SIXTY_MINUTES_MS = 60 * 60 * 1000;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Bump persisted heartbeat default from 30 minutes to 60 minutes.
|
|
11
|
+
*
|
|
12
|
+
* Migration 065 moved legacy 3h/6h defaults to 30 minutes. The schema default
|
|
13
|
+
* has since been raised to 60 minutes, but existing users whose config.json
|
|
14
|
+
* already has 1800000 persisted won't pick up the new default. This migration
|
|
15
|
+
* idempotently updates those configs.
|
|
16
|
+
*/
|
|
17
|
+
export const bumpHeartbeatInterval30mTo60mMigration: WorkspaceMigration = {
|
|
18
|
+
id: "095-bump-heartbeat-interval-30m-to-60m",
|
|
19
|
+
description:
|
|
20
|
+
"Bump persisted heartbeat.intervalMs from 30 minutes to 60 minutes",
|
|
21
|
+
run(workspaceDir: string): void {
|
|
22
|
+
const configPath = join(workspaceDir, "config.json");
|
|
23
|
+
if (!existsSync(configPath)) return;
|
|
24
|
+
|
|
25
|
+
let config: Record<string, unknown>;
|
|
26
|
+
try {
|
|
27
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
28
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
29
|
+
config = raw as Record<string, unknown>;
|
|
30
|
+
} catch {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const heartbeat = config.heartbeat;
|
|
35
|
+
if (!heartbeat || typeof heartbeat !== "object" || Array.isArray(heartbeat))
|
|
36
|
+
return;
|
|
37
|
+
|
|
38
|
+
const heartbeatConfig = heartbeat as Record<string, unknown>;
|
|
39
|
+
const intervalMs = heartbeatConfig.intervalMs;
|
|
40
|
+
if (typeof intervalMs !== "number" || intervalMs !== THIRTY_MINUTES_MS) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
heartbeatConfig.intervalMs = SIXTY_MINUTES_MS;
|
|
45
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
46
|
+
},
|
|
47
|
+
down(_workspaceDir: string): void {
|
|
48
|
+
// Forward-only: cannot distinguish users who explicitly chose 60 minutes
|
|
49
|
+
// from those migrated by this migration.
|
|
50
|
+
},
|
|
51
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// Reduce effort from "max" to "high" on the quality-optimized profile.
|
|
7
|
+
//
|
|
8
|
+
// With adaptive thinking enabled, the effort parameter acts as a nudge for
|
|
9
|
+
// how much thinking the model does. "max" means "always think with no
|
|
10
|
+
// constraints on thinking depth", which defeats adaptive thinking's ability
|
|
11
|
+
// to skip or minimize thinking for simple queries. "high" (the API default)
|
|
12
|
+
// means "almost always thinks, deep reasoning on complex tasks" — letting
|
|
13
|
+
// adaptive thinking decide when full-depth reasoning is actually needed.
|
|
14
|
+
//
|
|
15
|
+
// This migration patches both managed and user quality-optimized profiles
|
|
16
|
+
// that still have effort: "max". It only downgrades "max" → "high"; any
|
|
17
|
+
// other effort value is preserved.
|
|
18
|
+
|
|
19
|
+
const TARGET_PROFILES = ["quality-optimized", "custom-quality-optimized"];
|
|
20
|
+
|
|
21
|
+
export const reduceQualityProfileEffortMigration: WorkspaceMigration = {
|
|
22
|
+
id: "096-reduce-quality-profile-effort",
|
|
23
|
+
description:
|
|
24
|
+
'Reduce effort from "max" to "high" on quality-optimized profiles to let adaptive thinking work',
|
|
25
|
+
run(workspaceDir: string): void {
|
|
26
|
+
const configPath = join(workspaceDir, "config.json");
|
|
27
|
+
if (!existsSync(configPath)) return;
|
|
28
|
+
|
|
29
|
+
let config: Record<string, unknown>;
|
|
30
|
+
try {
|
|
31
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
32
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
33
|
+
config = raw as Record<string, unknown>;
|
|
34
|
+
} catch {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const llm = readObject(config.llm);
|
|
39
|
+
if (llm === null) return;
|
|
40
|
+
|
|
41
|
+
const profiles = readObject(llm.profiles);
|
|
42
|
+
if (profiles === null) return;
|
|
43
|
+
|
|
44
|
+
let changed = false;
|
|
45
|
+
|
|
46
|
+
for (const name of TARGET_PROFILES) {
|
|
47
|
+
const profile = readObject(profiles[name]);
|
|
48
|
+
if (profile === null) continue;
|
|
49
|
+
if (profile.effort !== "max") continue;
|
|
50
|
+
|
|
51
|
+
profile.effort = "high";
|
|
52
|
+
profiles[name] = profile;
|
|
53
|
+
changed = true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (changed) {
|
|
57
|
+
llm.profiles = profiles;
|
|
58
|
+
config.llm = llm;
|
|
59
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
down(_workspaceDir: string): void {
|
|
63
|
+
// Forward-only.
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
68
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return value as Record<string, unknown>;
|
|
72
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// Enable adaptive thinking on the managed "balanced" and "quality-optimized"
|
|
7
|
+
// profiles for existing platform instances.
|
|
8
|
+
//
|
|
9
|
+
// The assistant-side seed defaults (MANAGED_PROFILE_TEMPLATES in
|
|
10
|
+
// seed-inference-profiles.ts) already ship thinking: { enabled: true,
|
|
11
|
+
// streamThinking: true } for both profiles, which normalizes to
|
|
12
|
+
// { type: "adaptive" } on the wire. Off-platform (BYOK) instances pick this
|
|
13
|
+
// up on every boot because the seeder overwrites managed profiles. On-platform
|
|
14
|
+
// instances preserve existing profiles (the platform overlay is authoritative),
|
|
15
|
+
// so instances that were hatched before thinking was enabled in the templates
|
|
16
|
+
// are stuck with thinking disabled or absent.
|
|
17
|
+
//
|
|
18
|
+
// This migration patches the on-disk config for both profiles, adding
|
|
19
|
+
// thinking: { enabled: true, streamThinking: true } where it's missing or
|
|
20
|
+
// explicitly disabled. It skips profiles that:
|
|
21
|
+
// - Don't exist (no profile to patch)
|
|
22
|
+
// - Already have thinking enabled (idempotent)
|
|
23
|
+
// - Are source: "user" (user-created profiles are untouched)
|
|
24
|
+
// - Have a non-managed, non-absent source (unknown origin)
|
|
25
|
+
// - Use a non-Anthropic provider (adaptive thinking is Anthropic-specific)
|
|
26
|
+
|
|
27
|
+
const ADAPTIVE_THINKING = { enabled: true, streamThinking: true } as const;
|
|
28
|
+
const TARGET_PROFILES = ["balanced", "quality-optimized"] as const;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Patch managed Anthropic profiles that are missing adaptive thinking.
|
|
32
|
+
*
|
|
33
|
+
* Exported so lifecycle.ts can re-run the repair after mergeDefaultWorkspaceConfig()
|
|
34
|
+
* and seedInferenceProfiles(). On-platform instances with a config overlay have their
|
|
35
|
+
* profiles overwritten by the overlay merge (which runs after workspace migrations),
|
|
36
|
+
* so the migration alone is insufficient — the post-overlay call ensures the repair
|
|
37
|
+
* sticks even when the overlay supplies profiles without thinking enabled.
|
|
38
|
+
*
|
|
39
|
+
* The function is idempotent: profiles that already have thinking enabled are skipped.
|
|
40
|
+
*/
|
|
41
|
+
export function repairAdaptiveThinkingOnManagedProfiles(
|
|
42
|
+
workspaceDir: string,
|
|
43
|
+
): void {
|
|
44
|
+
const configPath = join(workspaceDir, "config.json");
|
|
45
|
+
if (!existsSync(configPath)) return;
|
|
46
|
+
|
|
47
|
+
let config: Record<string, unknown>;
|
|
48
|
+
try {
|
|
49
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
50
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
51
|
+
config = raw as Record<string, unknown>;
|
|
52
|
+
} catch {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const llm = readObject(config.llm);
|
|
57
|
+
if (llm === null) return;
|
|
58
|
+
|
|
59
|
+
const profiles = readObject(llm.profiles);
|
|
60
|
+
if (profiles === null) return;
|
|
61
|
+
|
|
62
|
+
let changed = false;
|
|
63
|
+
|
|
64
|
+
for (const name of TARGET_PROFILES) {
|
|
65
|
+
const profile = readObject(profiles[name]);
|
|
66
|
+
if (profile === null) continue;
|
|
67
|
+
|
|
68
|
+
// Only patch managed Anthropic profiles.
|
|
69
|
+
// Legacy profiles created before the `source` metadata field was introduced
|
|
70
|
+
// have source=undefined. Treat these as managed when the profile name is one
|
|
71
|
+
// of the canonical managed names (which TARGET_PROFILES already guarantees)
|
|
72
|
+
// and the provider is Anthropic (or absent). Explicit `source: "user"`
|
|
73
|
+
// profiles are always skipped.
|
|
74
|
+
if (profile.source === "user") continue;
|
|
75
|
+
if (profile.source !== undefined && profile.source !== "managed") continue;
|
|
76
|
+
if (
|
|
77
|
+
typeof profile.provider === "string" &&
|
|
78
|
+
profile.provider !== "anthropic"
|
|
79
|
+
) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Skip if thinking is already enabled.
|
|
84
|
+
const thinking = readObject(profile.thinking);
|
|
85
|
+
if (thinking !== null && thinking.enabled === true) continue;
|
|
86
|
+
|
|
87
|
+
profile.thinking = { ...ADAPTIVE_THINKING };
|
|
88
|
+
profiles[name] = profile;
|
|
89
|
+
changed = true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (changed) {
|
|
93
|
+
llm.profiles = profiles;
|
|
94
|
+
config.llm = llm;
|
|
95
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const enableAdaptiveThinkingManagedProfilesMigration: WorkspaceMigration =
|
|
100
|
+
{
|
|
101
|
+
id: "097-enable-adaptive-thinking-managed-profiles",
|
|
102
|
+
description:
|
|
103
|
+
"Enable adaptive thinking on managed balanced and quality-optimized profiles",
|
|
104
|
+
run(workspaceDir: string): void {
|
|
105
|
+
repairAdaptiveThinkingOnManagedProfiles(workspaceDir);
|
|
106
|
+
},
|
|
107
|
+
down(_workspaceDir: string): void {
|
|
108
|
+
// Forward-only.
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
113
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return value as Record<string, unknown>;
|
|
117
|
+
}
|
|
@@ -92,6 +92,9 @@ import { retightenMigrationOnboardingThreadMigration } from "./091-retighten-mig
|
|
|
92
92
|
import { backfillV3LeavesMigration } from "./092-backfill-v3-leaves.js";
|
|
93
93
|
import { backfillLeafIdsMigration } from "./093-backfill-leaf-ids.js";
|
|
94
94
|
import { seedAvatarManifestMigration } from "./094-seed-avatar-manifest.js";
|
|
95
|
+
import { bumpHeartbeatInterval30mTo60mMigration } from "./095-bump-heartbeat-interval-30m-to-60m.js";
|
|
96
|
+
import { reduceQualityProfileEffortMigration } from "./096-reduce-quality-profile-effort.js";
|
|
97
|
+
import { enableAdaptiveThinkingManagedProfilesMigration } from "./097-enable-adaptive-thinking-managed-profiles.js";
|
|
95
98
|
import { migrateToWorkspaceVolumeMigration } from "./migrate-to-workspace-volume.js";
|
|
96
99
|
import type { WorkspaceMigration } from "./types.js";
|
|
97
100
|
|
|
@@ -195,4 +198,7 @@ export const WORKSPACE_MIGRATIONS: WorkspaceMigration[] = [
|
|
|
195
198
|
backfillV3LeavesMigration,
|
|
196
199
|
backfillLeafIdsMigration,
|
|
197
200
|
seedAvatarManifestMigration,
|
|
201
|
+
bumpHeartbeatInterval30mTo60mMigration,
|
|
202
|
+
reduceQualityProfileEffortMigration,
|
|
203
|
+
enableAdaptiveThinkingManagedProfilesMigration,
|
|
198
204
|
];
|