@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
|
@@ -13,8 +13,14 @@ import type { MessageQueuedDeletedEvent } from "../../api/events/message-queued-
|
|
|
13
13
|
import type { MessageRequestCompleteEvent } from "../../api/events/message-request-complete.js";
|
|
14
14
|
import type { QuestionRequestEvent } from "../../api/events/question-request.js";
|
|
15
15
|
import type { SecretRequestEvent } from "../../api/events/secret-request.js";
|
|
16
|
+
import type { ToolOutputChunkEvent } from "../../api/events/tool-output-chunk.js";
|
|
16
17
|
import type { ToolResultEvent } from "../../api/events/tool-result.js";
|
|
18
|
+
import type { ToolUsePreviewStartEvent } from "../../api/events/tool-use-preview-start.js";
|
|
17
19
|
import type { ToolUseStartEvent } from "../../api/events/tool-use-start.js";
|
|
20
|
+
import type {
|
|
21
|
+
TraceEvent,
|
|
22
|
+
TraceEventKind,
|
|
23
|
+
} from "../../api/events/trace-event.js";
|
|
18
24
|
import type { TurnProfileAutoRoutedEvent } from "../../api/events/turn-profile-auto-routed.js";
|
|
19
25
|
import type { UserMessageEchoEvent } from "../../api/events/user-message-echo.js";
|
|
20
26
|
import type { ChannelId, InterfaceId } from "../../channels/types.js";
|
|
@@ -79,31 +85,6 @@ export interface AssistantThinkingDelta {
|
|
|
79
85
|
messageId?: string;
|
|
80
86
|
}
|
|
81
87
|
|
|
82
|
-
export interface ToolOutputChunk {
|
|
83
|
-
type: "tool_output_chunk";
|
|
84
|
-
chunk: string;
|
|
85
|
-
conversationId?: string;
|
|
86
|
-
toolUseId?: string;
|
|
87
|
-
subType?: "tool_start" | "tool_complete" | "status";
|
|
88
|
-
subToolName?: string;
|
|
89
|
-
subToolInput?: string;
|
|
90
|
-
subToolIsError?: boolean;
|
|
91
|
-
subToolId?: string;
|
|
92
|
-
/** Database ID of the assistant message that owns the parent tool_use
|
|
93
|
-
* block. Same semantics as `AssistantTextDeltaEvent.messageId`. */
|
|
94
|
-
messageId?: string;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export interface ToolUsePreviewStart {
|
|
98
|
-
type: "tool_use_preview_start";
|
|
99
|
-
toolUseId: string;
|
|
100
|
-
toolName: string;
|
|
101
|
-
conversationId?: string;
|
|
102
|
-
/** Database ID of the assistant message that owns this tool_use block.
|
|
103
|
-
* Same semantics as `AssistantTextDeltaEvent.messageId`. */
|
|
104
|
-
messageId?: string;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
88
|
export interface ToolInputDelta {
|
|
108
89
|
type: "tool_input_delta";
|
|
109
90
|
toolName: string;
|
|
@@ -165,36 +146,7 @@ export interface ConversationInferenceProfileUpdated {
|
|
|
165
146
|
expiresAt?: number | null;
|
|
166
147
|
}
|
|
167
148
|
|
|
168
|
-
export type TraceEventKind
|
|
169
|
-
| "request_received"
|
|
170
|
-
| "request_queued"
|
|
171
|
-
| "request_dequeued"
|
|
172
|
-
| "llm_call_started"
|
|
173
|
-
| "llm_call_finished"
|
|
174
|
-
| "assistant_message"
|
|
175
|
-
| "tool_started"
|
|
176
|
-
| "tool_permission_requested"
|
|
177
|
-
| "tool_permission_decided"
|
|
178
|
-
| "tool_finished"
|
|
179
|
-
| "tool_failed"
|
|
180
|
-
| "generation_handoff"
|
|
181
|
-
| "message_complete"
|
|
182
|
-
| "generation_cancelled"
|
|
183
|
-
| "request_error"
|
|
184
|
-
| "tool_profiling_summary";
|
|
185
|
-
|
|
186
|
-
export interface TraceEvent {
|
|
187
|
-
type: "trace_event";
|
|
188
|
-
eventId: string;
|
|
189
|
-
conversationId: string;
|
|
190
|
-
requestId?: string;
|
|
191
|
-
timestampMs: number;
|
|
192
|
-
sequence: number;
|
|
193
|
-
kind: TraceEventKind;
|
|
194
|
-
status?: "info" | "success" | "warning" | "error";
|
|
195
|
-
summary: string;
|
|
196
|
-
attributes?: Record<string, string | number | boolean | null>;
|
|
197
|
-
}
|
|
149
|
+
export type { TraceEvent, TraceEventKind };
|
|
198
150
|
|
|
199
151
|
// --- Domain-level union aliases (consumed by the barrel file) ---
|
|
200
152
|
|
|
@@ -210,8 +162,8 @@ export type _MessagesServerMessages =
|
|
|
210
162
|
| AssistantTextDeltaEvent
|
|
211
163
|
| AssistantThinkingDelta
|
|
212
164
|
| ToolUseStartEvent
|
|
213
|
-
|
|
|
214
|
-
|
|
|
165
|
+
| ToolUsePreviewStartEvent
|
|
166
|
+
| ToolOutputChunkEvent
|
|
215
167
|
| ToolInputDelta
|
|
216
168
|
| ToolResultEvent
|
|
217
169
|
| ConfirmationRequestEvent
|
|
@@ -86,6 +86,7 @@ interface SlimSkillBase {
|
|
|
86
86
|
id: string;
|
|
87
87
|
name: string;
|
|
88
88
|
description: string;
|
|
89
|
+
icon?: string;
|
|
89
90
|
emoji?: string;
|
|
90
91
|
kind: "bundled" | "installed" | "catalog";
|
|
91
92
|
status: "enabled" | "disabled" | "available";
|
|
@@ -157,6 +158,7 @@ interface SkillDetailBase {
|
|
|
157
158
|
id: string;
|
|
158
159
|
name: string;
|
|
159
160
|
description: string;
|
|
161
|
+
icon?: string;
|
|
160
162
|
emoji?: string;
|
|
161
163
|
kind: "bundled" | "installed" | "catalog";
|
|
162
164
|
status: "enabled" | "disabled" | "available";
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
export type SurfaceType =
|
|
6
6
|
| "card"
|
|
7
|
+
| "choice"
|
|
8
|
+
| "copy_block"
|
|
9
|
+
| "oauth_connect"
|
|
7
10
|
| "form"
|
|
8
11
|
| "list"
|
|
9
12
|
| "table"
|
|
@@ -11,9 +14,12 @@ export type SurfaceType =
|
|
|
11
14
|
| "dynamic_page"
|
|
12
15
|
| "file_upload"
|
|
13
16
|
| "document_preview"
|
|
14
|
-
| "task_preferences"
|
|
17
|
+
| "task_preferences"
|
|
18
|
+
| "work_result";
|
|
15
19
|
|
|
16
20
|
export const INTERACTIVE_SURFACE_TYPES: SurfaceType[] = [
|
|
21
|
+
"choice",
|
|
22
|
+
"oauth_connect",
|
|
17
23
|
"form",
|
|
18
24
|
"confirmation",
|
|
19
25
|
"dynamic_page",
|
|
@@ -40,6 +46,45 @@ export interface CardSurfaceData {
|
|
|
40
46
|
templateData?: Record<string, unknown>;
|
|
41
47
|
}
|
|
42
48
|
|
|
49
|
+
export interface ChoiceOption {
|
|
50
|
+
id: string;
|
|
51
|
+
title: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
/** Visually highlight this option as the assistant's recommendation. */
|
|
54
|
+
recommended?: boolean;
|
|
55
|
+
/** Optional structured payload returned with this choice. */
|
|
56
|
+
data?: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface ChoiceSurfaceData {
|
|
60
|
+
description?: string;
|
|
61
|
+
options: ChoiceOption[];
|
|
62
|
+
selectionMode?: "single" | "multiple";
|
|
63
|
+
/**
|
|
64
|
+
* When true, clicking an option submits it immediately. Defaults to true for
|
|
65
|
+
* single-select choice surfaces.
|
|
66
|
+
*/
|
|
67
|
+
commitOnSelect?: boolean;
|
|
68
|
+
submitLabel?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface CopyBlockSurfaceData {
|
|
72
|
+
text: string;
|
|
73
|
+
label?: string;
|
|
74
|
+
language?: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface OAuthConnectSurfaceData {
|
|
78
|
+
/** OAuth provider key from the managed provider catalog, e.g. "google". */
|
|
79
|
+
providerKey: string;
|
|
80
|
+
/** Optional display label. The client falls back to the provider catalog. */
|
|
81
|
+
displayName?: string;
|
|
82
|
+
/** Optional helper text. The client falls back to the provider catalog. */
|
|
83
|
+
description?: string;
|
|
84
|
+
/** Optional provider logo URL. The client falls back to the provider catalog. */
|
|
85
|
+
logoUrl?: string | null;
|
|
86
|
+
}
|
|
87
|
+
|
|
43
88
|
export interface FormField {
|
|
44
89
|
id: string;
|
|
45
90
|
type: "text" | "textarea" | "select" | "toggle" | "number" | "password";
|
|
@@ -148,15 +193,79 @@ export interface DocumentPreviewSurfaceData {
|
|
|
148
193
|
subtitle?: string;
|
|
149
194
|
}
|
|
150
195
|
|
|
196
|
+
export type WorkResultStatus =
|
|
197
|
+
| "completed"
|
|
198
|
+
| "partial"
|
|
199
|
+
| "failed"
|
|
200
|
+
| "in_progress";
|
|
201
|
+
|
|
202
|
+
export type WorkResultTone = "neutral" | "positive" | "warning" | "negative";
|
|
203
|
+
|
|
204
|
+
export type WorkResultSectionType =
|
|
205
|
+
| "items"
|
|
206
|
+
| "timeline"
|
|
207
|
+
| "diff"
|
|
208
|
+
| "artifacts"
|
|
209
|
+
| "warnings";
|
|
210
|
+
|
|
211
|
+
export interface WorkResultMetric {
|
|
212
|
+
label: string;
|
|
213
|
+
value: string | number;
|
|
214
|
+
detail?: string;
|
|
215
|
+
tone?: WorkResultTone;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export interface WorkResultMetadata {
|
|
219
|
+
label: string;
|
|
220
|
+
value: string | number;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export interface WorkResultItem {
|
|
224
|
+
id?: string;
|
|
225
|
+
title: string;
|
|
226
|
+
description?: string;
|
|
227
|
+
status?: string;
|
|
228
|
+
tone?: WorkResultTone;
|
|
229
|
+
metadata?: WorkResultMetadata[];
|
|
230
|
+
href?: string;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export interface WorkResultDiff {
|
|
234
|
+
label?: string;
|
|
235
|
+
before?: string;
|
|
236
|
+
after?: string;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export interface WorkResultSection {
|
|
240
|
+
id?: string;
|
|
241
|
+
title: string;
|
|
242
|
+
description?: string;
|
|
243
|
+
type?: WorkResultSectionType;
|
|
244
|
+
items?: WorkResultItem[];
|
|
245
|
+
diffs?: WorkResultDiff[];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export interface WorkResultSurfaceData {
|
|
249
|
+
eyebrow?: string;
|
|
250
|
+
status?: WorkResultStatus;
|
|
251
|
+
summary?: string;
|
|
252
|
+
metrics?: WorkResultMetric[];
|
|
253
|
+
sections?: WorkResultSection[];
|
|
254
|
+
}
|
|
255
|
+
|
|
151
256
|
export type SurfaceData =
|
|
152
257
|
| CardSurfaceData
|
|
258
|
+
| ChoiceSurfaceData
|
|
259
|
+
| CopyBlockSurfaceData
|
|
260
|
+
| OAuthConnectSurfaceData
|
|
153
261
|
| FormSurfaceData
|
|
154
262
|
| ListSurfaceData
|
|
155
263
|
| TableSurfaceData
|
|
156
264
|
| ConfirmationSurfaceData
|
|
157
265
|
| DynamicPageSurfaceData
|
|
158
266
|
| FileUploadSurfaceData
|
|
159
|
-
| DocumentPreviewSurfaceData
|
|
267
|
+
| DocumentPreviewSurfaceData
|
|
268
|
+
| WorkResultSurfaceData;
|
|
160
269
|
|
|
161
270
|
// === Client → Server ===
|
|
162
271
|
|
|
@@ -197,6 +306,21 @@ export interface UiSurfaceShowCard extends UiSurfaceShowBase {
|
|
|
197
306
|
data: CardSurfaceData;
|
|
198
307
|
}
|
|
199
308
|
|
|
309
|
+
export interface UiSurfaceShowChoice extends UiSurfaceShowBase {
|
|
310
|
+
surfaceType: "choice";
|
|
311
|
+
data: ChoiceSurfaceData;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export interface UiSurfaceShowCopyBlock extends UiSurfaceShowBase {
|
|
315
|
+
surfaceType: "copy_block";
|
|
316
|
+
data: CopyBlockSurfaceData;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export interface UiSurfaceShowOAuthConnect extends UiSurfaceShowBase {
|
|
320
|
+
surfaceType: "oauth_connect";
|
|
321
|
+
data: OAuthConnectSurfaceData;
|
|
322
|
+
}
|
|
323
|
+
|
|
200
324
|
export interface UiSurfaceShowForm extends UiSurfaceShowBase {
|
|
201
325
|
surfaceType: "form";
|
|
202
326
|
data: FormSurfaceData;
|
|
@@ -232,15 +356,24 @@ export interface UiSurfaceShowDocumentPreview extends UiSurfaceShowBase {
|
|
|
232
356
|
data: DocumentPreviewSurfaceData;
|
|
233
357
|
}
|
|
234
358
|
|
|
359
|
+
export interface UiSurfaceShowWorkResult extends UiSurfaceShowBase {
|
|
360
|
+
surfaceType: "work_result";
|
|
361
|
+
data: WorkResultSurfaceData;
|
|
362
|
+
}
|
|
363
|
+
|
|
235
364
|
export type UiSurfaceShow =
|
|
236
365
|
| UiSurfaceShowCard
|
|
366
|
+
| UiSurfaceShowChoice
|
|
367
|
+
| UiSurfaceShowCopyBlock
|
|
368
|
+
| UiSurfaceShowOAuthConnect
|
|
237
369
|
| UiSurfaceShowForm
|
|
238
370
|
| UiSurfaceShowList
|
|
239
371
|
| UiSurfaceShowTable
|
|
240
372
|
| UiSurfaceShowConfirmation
|
|
241
373
|
| UiSurfaceShowDynamicPage
|
|
242
374
|
| UiSurfaceShowFileUpload
|
|
243
|
-
| UiSurfaceShowDocumentPreview
|
|
375
|
+
| UiSurfaceShowDocumentPreview
|
|
376
|
+
| UiSurfaceShowWorkResult;
|
|
244
377
|
|
|
245
378
|
export interface UiSurfaceUpdate {
|
|
246
379
|
type: "ui_surface_update";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
import { getWorkspacePromptPath } from "../util/platform.js";
|
|
4
|
+
import { stripCommentLines } from "../util/strip-comment-lines.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Read the NOW.md scratchpad from the workspace prompt directory.
|
|
8
|
+
*
|
|
9
|
+
* Returns the trimmed content with `_`-prefixed comment lines stripped,
|
|
10
|
+
* or `null` if the file is missing, empty, or unreadable.
|
|
11
|
+
*/
|
|
12
|
+
export function readNowScratchpad(): string | null {
|
|
13
|
+
const nowPath = getWorkspacePromptPath("NOW.md");
|
|
14
|
+
if (!existsSync(nowPath)) return null;
|
|
15
|
+
try {
|
|
16
|
+
const stripped = stripCommentLines(readFileSync(nowPath, "utf-8")).trim();
|
|
17
|
+
return stripped.length > 0 ? stripped : null;
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the orphan subprocess reaper.
|
|
3
|
+
*
|
|
4
|
+
* - `parseProcStat` must read state/ppid correctly even when the executable
|
|
5
|
+
* name (`comm`) contains spaces and parentheses.
|
|
6
|
+
* - `selectReapable` must defer a zombie for one full scan interval (so libuv
|
|
7
|
+
* reaps its own tracked children first) and reap it on the next scan.
|
|
8
|
+
* - An integration test makes the test process a child subreaper via
|
|
9
|
+
* `PR_SET_CHILD_SUBREAPER`, orphans a grandchild, and verifies the
|
|
10
|
+
* exported logic defers-then-reaps the real `<defunct>` entry while libuv
|
|
11
|
+
* independently reaps the directly-spawned (tracked) child.
|
|
12
|
+
*/
|
|
13
|
+
import { spawn } from "node:child_process";
|
|
14
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
15
|
+
import { dlopen, FFIType, ptr } from "bun:ffi";
|
|
16
|
+
import { afterAll, describe, expect, mock, test } from "bun:test";
|
|
17
|
+
|
|
18
|
+
mock.module("../util/logger.js", () => ({
|
|
19
|
+
getLogger: () =>
|
|
20
|
+
new Proxy({} as Record<string, unknown>, { get: () => () => {} }),
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
const { parseProcStat, selectReapable } = await import("./orphan-reaper.js");
|
|
24
|
+
const { DaemonConfigSchema } = await import("../config/schemas/platform.js");
|
|
25
|
+
|
|
26
|
+
describe("parseProcStat", () => {
|
|
27
|
+
test("parses a normal stat line", () => {
|
|
28
|
+
// GIVEN a well-formed /proc/<pid>/stat line for a zombie
|
|
29
|
+
const line = "1234 (bash) Z 1 1234 1234 0 -1 ...";
|
|
30
|
+
// WHEN it is parsed
|
|
31
|
+
const parsed = parseProcStat(line);
|
|
32
|
+
// THEN comm, state, and ppid are extracted
|
|
33
|
+
expect(parsed).toEqual({ comm: "bash", state: "Z", ppid: 1 });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("handles comm containing spaces and parentheses", () => {
|
|
37
|
+
// GIVEN a stat line whose comm field itself contains spaces and parens
|
|
38
|
+
const line = "42 (weird (name) x) Z 1 42 42 0 -1 4194560";
|
|
39
|
+
// WHEN it is parsed
|
|
40
|
+
const parsed = parseProcStat(line);
|
|
41
|
+
// THEN fields are read relative to the final ')', not naive splitting
|
|
42
|
+
expect(parsed).toEqual({ comm: "weird (name) x", state: "Z", ppid: 1 });
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("reads a non-zombie running state", () => {
|
|
46
|
+
// GIVEN a running (non-zombie) process line
|
|
47
|
+
const line = "77 (node) R 12 77 77";
|
|
48
|
+
// WHEN it is parsed
|
|
49
|
+
const parsed = parseProcStat(line);
|
|
50
|
+
// THEN the running state and parent pid are reported
|
|
51
|
+
expect(parsed?.state).toBe("R");
|
|
52
|
+
expect(parsed?.ppid).toBe(12);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("returns null for malformed lines", () => {
|
|
56
|
+
// GIVEN malformed or truncated stat content
|
|
57
|
+
// WHEN each is parsed
|
|
58
|
+
// THEN null is returned rather than a bogus record
|
|
59
|
+
expect(parseProcStat("")).toBeNull();
|
|
60
|
+
expect(parseProcStat("no parens here")).toBeNull();
|
|
61
|
+
expect(parseProcStat("123 (proc)")).toBeNull();
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe("selectReapable", () => {
|
|
66
|
+
test("defers a newly-seen zombie for one interval", () => {
|
|
67
|
+
// GIVEN zombies never seen on a previous scan
|
|
68
|
+
// WHEN deciding what to reap with an empty seen set
|
|
69
|
+
const { reap, nextSeen } = selectReapable([100, 101], new Set());
|
|
70
|
+
// THEN nothing is reaped yet, but both are carried into the next scan
|
|
71
|
+
expect(reap).toEqual([]);
|
|
72
|
+
expect([...nextSeen].sort()).toEqual([100, 101]);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("reaps a zombie that survived the previous scan", () => {
|
|
76
|
+
// GIVEN pid 100 was already seen on the prior scan and 101 is new
|
|
77
|
+
// WHEN deciding what to reap
|
|
78
|
+
const { reap } = selectReapable([100, 101], new Set([100]));
|
|
79
|
+
// THEN only the survivor (100) is reaped; the newcomer is deferred
|
|
80
|
+
expect(reap).toEqual([100]);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("drops PIDs that have disappeared from the next seen set", () => {
|
|
84
|
+
// GIVEN pid 100 was seen before but is gone now
|
|
85
|
+
// WHEN computing the next seen set
|
|
86
|
+
const { nextSeen } = selectReapable([101], new Set([100, 101]));
|
|
87
|
+
// THEN only currently-present pids are retained
|
|
88
|
+
expect([...nextSeen]).toEqual([101]);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe("daemon.reapOrphanedSubprocesses gate", () => {
|
|
93
|
+
test("defaults to off so the reaper is opt-in", () => {
|
|
94
|
+
// GIVEN a daemon config with the reaper flag unspecified
|
|
95
|
+
// WHEN it is parsed with schema defaults
|
|
96
|
+
const parsed = DaemonConfigSchema.parse({});
|
|
97
|
+
// THEN the reaper is disabled unless explicitly turned on
|
|
98
|
+
expect(parsed.reapOrphanedSubprocesses).toBe(false);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("honors an explicit opt-in", () => {
|
|
102
|
+
// GIVEN a daemon config that explicitly enables the reaper
|
|
103
|
+
// WHEN it is parsed
|
|
104
|
+
const parsed = DaemonConfigSchema.parse({ reapOrphanedSubprocesses: true });
|
|
105
|
+
// THEN the flag is respected
|
|
106
|
+
expect(parsed.reapOrphanedSubprocesses).toBe(true);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// ── Integration: real reparented orphan on Linux ────────────────────────────
|
|
111
|
+
const itLinux = process.platform === "linux" ? test : test.skip;
|
|
112
|
+
|
|
113
|
+
// Bind libc only on Linux — "libc.so.6" does not exist on macOS, so binding it
|
|
114
|
+
// unconditionally would throw at import and break the pure-function tests too.
|
|
115
|
+
const lib =
|
|
116
|
+
process.platform === "linux"
|
|
117
|
+
? dlopen("libc.so.6", {
|
|
118
|
+
waitpid: {
|
|
119
|
+
args: [FFIType.i32, FFIType.ptr, FFIType.i32],
|
|
120
|
+
returns: FFIType.i32,
|
|
121
|
+
},
|
|
122
|
+
prctl: {
|
|
123
|
+
args: [
|
|
124
|
+
FFIType.i32,
|
|
125
|
+
FFIType.u64,
|
|
126
|
+
FFIType.u64,
|
|
127
|
+
FFIType.u64,
|
|
128
|
+
FFIType.u64,
|
|
129
|
+
],
|
|
130
|
+
returns: FFIType.i32,
|
|
131
|
+
},
|
|
132
|
+
})
|
|
133
|
+
: null;
|
|
134
|
+
const WNOHANG = 1;
|
|
135
|
+
const PR_SET_CHILD_SUBREAPER = 36;
|
|
136
|
+
const statusBuf = new Int32Array(1);
|
|
137
|
+
|
|
138
|
+
function zombieChildPids(): number[] {
|
|
139
|
+
const self = process.pid;
|
|
140
|
+
const out: number[] = [];
|
|
141
|
+
for (const entry of readdirSync("/proc")) {
|
|
142
|
+
const pid = Number(entry);
|
|
143
|
+
if (!Number.isInteger(pid) || pid <= 1) continue;
|
|
144
|
+
let stat: string;
|
|
145
|
+
try {
|
|
146
|
+
stat = readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
147
|
+
} catch {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const parsed = parseProcStat(stat);
|
|
151
|
+
if (parsed && parsed.state === "Z" && parsed.ppid === self) out.push(pid);
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
157
|
+
|
|
158
|
+
afterAll(() => {
|
|
159
|
+
if (!lib) return;
|
|
160
|
+
// Reap anything still lingering so the test process leaves no zombies.
|
|
161
|
+
for (const pid of zombieChildPids())
|
|
162
|
+
lib.symbols.waitpid(pid, ptr(statusBuf), WNOHANG);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
itLinux(
|
|
166
|
+
"defers then reaps a reparented orphan while libuv reaps the tracked child",
|
|
167
|
+
async () => {
|
|
168
|
+
if (!lib) return;
|
|
169
|
+
// GIVEN this process is a child subreaper, so orphaned grandchildren
|
|
170
|
+
// reparent here exactly as they reparent to a PID-1 daemon
|
|
171
|
+
expect(lib.symbols.prctl(PR_SET_CHILD_SUBREAPER, 1n, 0n, 0n, 0n)).toBe(0);
|
|
172
|
+
|
|
173
|
+
// AND a libuv-tracked child (A) that detaches a grandchild (B) into its
|
|
174
|
+
// own session and exits immediately; B reparents to us and, once it
|
|
175
|
+
// exits, becomes a zombie with our pid as its parent
|
|
176
|
+
let trackedChildExited = false;
|
|
177
|
+
const a = spawn("bash", ["-c", "setsid -f sleep 0.4; exit 0"], {
|
|
178
|
+
stdio: "ignore",
|
|
179
|
+
});
|
|
180
|
+
a.on("exit", () => {
|
|
181
|
+
trackedChildExited = true;
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// AND we wait for that orphan to surface as our zombie child
|
|
185
|
+
let zombies: number[] = [];
|
|
186
|
+
for (let i = 0; i < 40 && zombies.length === 0; i++) {
|
|
187
|
+
await sleep(50);
|
|
188
|
+
zombies = zombieChildPids();
|
|
189
|
+
}
|
|
190
|
+
expect(zombies.length).toBeGreaterThan(0);
|
|
191
|
+
expect(trackedChildExited).toBe(true); // libuv reaped A independently
|
|
192
|
+
|
|
193
|
+
// WHEN we run the deferred-reap algorithm across two scans
|
|
194
|
+
// (scan #1 is the grace pass, scan #2 reaps the survivor)
|
|
195
|
+
const scan1 = selectReapable(zombieChildPids(), new Set<number>());
|
|
196
|
+
const scan2 = selectReapable(zombieChildPids(), scan1.nextSeen);
|
|
197
|
+
let reaped = 0;
|
|
198
|
+
for (const pid of scan2.reap) {
|
|
199
|
+
if (lib.symbols.waitpid(pid, ptr(statusBuf), WNOHANG) > 0) reaped++;
|
|
200
|
+
}
|
|
201
|
+
await sleep(50);
|
|
202
|
+
|
|
203
|
+
// THEN nothing is reaped on the grace pass, the survivor is reaped on the
|
|
204
|
+
// second pass, and no defunct child remains
|
|
205
|
+
expect(scan1.reap).toEqual([]);
|
|
206
|
+
expect(scan2.reap.length).toBeGreaterThan(0);
|
|
207
|
+
expect(reaped).toBeGreaterThan(0);
|
|
208
|
+
expect(zombieChildPids()).toEqual([]);
|
|
209
|
+
},
|
|
210
|
+
);
|