@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
|
@@ -14,43 +14,24 @@ import { getVisibleProviderCatalog } from "../providers/provider-catalog-visibil
|
|
|
14
14
|
export type SlashResolution =
|
|
15
15
|
| { kind: "passthrough"; content: string }
|
|
16
16
|
| { kind: "unknown"; message: string }
|
|
17
|
-
| { kind: "compact"
|
|
17
|
+
| { kind: "compact" }
|
|
18
18
|
| { kind: "clean" };
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
"Usage: `/compact [<tokens>]` (e.g. `/compact 30000`, `/compact 30k`, `/compact 1m`).";
|
|
20
|
+
type CompactParse = { kind: "compact" } | { kind: "unknown"; message: string };
|
|
22
21
|
|
|
23
|
-
type CompactParse =
|
|
24
|
-
| { kind: "compact"; targetInputTokensOverride?: number }
|
|
25
|
-
| { kind: "unknown"; message: string };
|
|
26
|
-
|
|
27
|
-
const TOKEN_COUNT_PATTERN = /^(\d+(?:\.\d+)?)([km])?$/i;
|
|
28
22
|
const COMPACT_COMMAND_PATTERN = /^\/compact(?:\s+(.+?))?\s*$/i;
|
|
29
23
|
|
|
30
|
-
function parseTokenCount(input: string): number | null {
|
|
31
|
-
const match = input.match(TOKEN_COUNT_PATTERN);
|
|
32
|
-
if (!match) return null;
|
|
33
|
-
const value = Number.parseFloat(match[1]);
|
|
34
|
-
if (!Number.isFinite(value) || value <= 0) return null;
|
|
35
|
-
const suffix = match[2]?.toLowerCase();
|
|
36
|
-
const multiplier = suffix === "m" ? 1_000_000 : suffix === "k" ? 1_000 : 1;
|
|
37
|
-
const tokens = Math.floor(value * multiplier);
|
|
38
|
-
return tokens > 0 ? tokens : null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
24
|
function parseCompactCommand(trimmed: string): CompactParse | null {
|
|
42
25
|
const match = trimmed.match(COMPACT_COMMAND_PATTERN);
|
|
43
26
|
if (!match) return null;
|
|
44
27
|
const rest = match[1]?.trim();
|
|
45
|
-
if (
|
|
46
|
-
const tokens = parseTokenCount(rest);
|
|
47
|
-
if (tokens == null) {
|
|
28
|
+
if (rest) {
|
|
48
29
|
return {
|
|
49
30
|
kind: "unknown",
|
|
50
|
-
message:
|
|
31
|
+
message: `\`/compact\` does not take arguments. Usage: \`/compact\`.`,
|
|
51
32
|
};
|
|
52
33
|
}
|
|
53
|
-
return { kind: "compact"
|
|
34
|
+
return { kind: "compact" };
|
|
54
35
|
}
|
|
55
36
|
|
|
56
37
|
type CleanParse = { kind: "clean" } | { kind: "unknown"; message: string };
|
|
@@ -448,7 +429,7 @@ export async function resolveSlash(
|
|
|
448
429
|
return await resolveModelList();
|
|
449
430
|
}
|
|
450
431
|
|
|
451
|
-
// Handle /compact command (
|
|
432
|
+
// Handle /compact command (summarize history; takes no arguments).
|
|
452
433
|
const compactParse = parseCompactCommand(trimmed);
|
|
453
434
|
if (compactParse) return compactParse;
|
|
454
435
|
|
|
@@ -27,99 +27,18 @@ import { ProviderNotConfiguredError } from "../util/errors.js";
|
|
|
27
27
|
import { getSandboxWorkingDir } from "../util/platform.js";
|
|
28
28
|
import { Conversation } from "./conversation.js";
|
|
29
29
|
import type { ConversationEvictor } from "./conversation-evictor.js";
|
|
30
|
+
import {
|
|
31
|
+
allConversations,
|
|
32
|
+
clearConversations,
|
|
33
|
+
conversationCount,
|
|
34
|
+
conversationIds,
|
|
35
|
+
deleteConversation,
|
|
36
|
+
findConversation,
|
|
37
|
+
setConversation,
|
|
38
|
+
} from "./conversation-registry.js";
|
|
30
39
|
import type { ConversationCreateOptions } from "./handlers/shared.js";
|
|
31
40
|
import { buildTransportHints } from "./transport-hints.js";
|
|
32
41
|
|
|
33
|
-
// ── Private store ──────────────────────────────────────────────────
|
|
34
|
-
|
|
35
|
-
const conversations = new Map<string, Conversation>();
|
|
36
|
-
|
|
37
|
-
// ── Read helpers ───────────────────────────────────────────────────
|
|
38
|
-
|
|
39
|
-
export function findConversation(
|
|
40
|
-
conversationId: string,
|
|
41
|
-
): Conversation | undefined {
|
|
42
|
-
return conversations.get(conversationId);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function findConversationBySurfaceId(
|
|
46
|
-
surfaceId: string,
|
|
47
|
-
): Conversation | undefined {
|
|
48
|
-
// Fast path: exact surfaceId match in surfaceState
|
|
49
|
-
for (const c of conversations.values()) {
|
|
50
|
-
if (c.surfaceState.has(surfaceId)) return c;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Fallback: standalone app surfaces use "app-open-{appId}" IDs that
|
|
54
|
-
// were never part of any conversation. Extract the appId and find
|
|
55
|
-
// a conversation whose surfaceState has a surface for that app.
|
|
56
|
-
const appOpenPrefix = "app-open-";
|
|
57
|
-
if (surfaceId.startsWith(appOpenPrefix)) {
|
|
58
|
-
const appId = surfaceId.slice(appOpenPrefix.length);
|
|
59
|
-
for (const c of conversations.values()) {
|
|
60
|
-
for (const [, state] of c.surfaceState.entries()) {
|
|
61
|
-
const data = state.data as unknown as Record<string, unknown>;
|
|
62
|
-
if (data?.appId === appId) {
|
|
63
|
-
// Register this surfaceId so subsequent lookups are O(1)
|
|
64
|
-
c.surfaceState.set(surfaceId, state);
|
|
65
|
-
return c;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function conversationCount(): number {
|
|
75
|
-
return conversations.size;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** Iterate over all active conversations. */
|
|
79
|
-
export function allConversations(): IterableIterator<Conversation> {
|
|
80
|
-
return conversations.values();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** Iterate over all [id, conversation] entries. */
|
|
84
|
-
export function conversationEntries(): IterableIterator<
|
|
85
|
-
[string, Conversation]
|
|
86
|
-
> {
|
|
87
|
-
return conversations.entries();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** Iterate over all active conversation IDs. */
|
|
91
|
-
function conversationIds(): IterableIterator<string> {
|
|
92
|
-
return conversations.keys();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// ── Write helpers ──────────────────────────────────────────────────
|
|
96
|
-
|
|
97
|
-
export function setConversation(
|
|
98
|
-
conversationId: string,
|
|
99
|
-
conversation: Conversation,
|
|
100
|
-
): void {
|
|
101
|
-
conversations.set(conversationId, conversation);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export function deleteConversation(conversationId: string): boolean {
|
|
105
|
-
return conversations.delete(conversationId);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export function clearConversations(): void {
|
|
109
|
-
conversations.clear();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// ── Underlying Map (for the evictor, which takes a mutable ref) ───
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Expose the raw Map for the {@link ConversationEvictor}, which needs
|
|
116
|
-
* a mutable reference to delete entries during sweeps. No other code
|
|
117
|
-
* should use this — prefer the named helpers above.
|
|
118
|
-
*/
|
|
119
|
-
export function getConversationMap(): Map<string, Conversation> {
|
|
120
|
-
return conversations;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
42
|
// ── Per-conversation persistent options ────────────────────────────
|
|
124
43
|
|
|
125
44
|
const conversationOptions = new Map<string, ConversationCreateOptions>();
|
|
@@ -38,10 +38,13 @@ import type { HostAppControlProxy } from "./host-app-control-proxy.js";
|
|
|
38
38
|
import type { HostCuProxy } from "./host-cu-proxy.js";
|
|
39
39
|
import type {
|
|
40
40
|
CardSurfaceData,
|
|
41
|
+
ChoiceSurfaceData,
|
|
41
42
|
ConfirmationSurfaceData,
|
|
43
|
+
CopyBlockSurfaceData,
|
|
42
44
|
DynamicPageSurfaceData,
|
|
43
45
|
FormSurfaceData,
|
|
44
46
|
ListSurfaceData,
|
|
47
|
+
OAuthConnectSurfaceData,
|
|
45
48
|
ServerMessage,
|
|
46
49
|
SurfaceData,
|
|
47
50
|
SurfaceType,
|
|
@@ -395,6 +398,107 @@ function normalizeTaskProgressCardPatch(
|
|
|
395
398
|
return normalizedPatch;
|
|
396
399
|
}
|
|
397
400
|
|
|
401
|
+
function normalizeChoiceShowData(
|
|
402
|
+
rawData: Record<string, unknown>,
|
|
403
|
+
): ChoiceSurfaceData {
|
|
404
|
+
const options = Array.isArray(rawData.options)
|
|
405
|
+
? rawData.options
|
|
406
|
+
.filter((option): option is Record<string, unknown> =>
|
|
407
|
+
isPlainObject(option),
|
|
408
|
+
)
|
|
409
|
+
.map((option) => {
|
|
410
|
+
const id = typeof option.id === "string" ? option.id.trim() : "";
|
|
411
|
+
const title =
|
|
412
|
+
typeof option.title === "string"
|
|
413
|
+
? option.title.trim()
|
|
414
|
+
: typeof option.label === "string"
|
|
415
|
+
? option.label.trim()
|
|
416
|
+
: "";
|
|
417
|
+
if (!id || !title) return null;
|
|
418
|
+
return {
|
|
419
|
+
id,
|
|
420
|
+
title,
|
|
421
|
+
...(typeof option.description === "string"
|
|
422
|
+
? { description: option.description }
|
|
423
|
+
: {}),
|
|
424
|
+
...(option.recommended === true ? { recommended: true } : {}),
|
|
425
|
+
...(isPlainObject(option.data)
|
|
426
|
+
? { data: option.data as Record<string, unknown> }
|
|
427
|
+
: {}),
|
|
428
|
+
};
|
|
429
|
+
})
|
|
430
|
+
.filter(
|
|
431
|
+
(option): option is NonNullable<typeof option> => option !== null,
|
|
432
|
+
)
|
|
433
|
+
: [];
|
|
434
|
+
|
|
435
|
+
return {
|
|
436
|
+
...(typeof rawData.description === "string"
|
|
437
|
+
? { description: rawData.description }
|
|
438
|
+
: {}),
|
|
439
|
+
options,
|
|
440
|
+
selectionMode: rawData.selectionMode === "multiple" ? "multiple" : "single",
|
|
441
|
+
...(typeof rawData.submitLabel === "string"
|
|
442
|
+
? { submitLabel: rawData.submitLabel }
|
|
443
|
+
: {}),
|
|
444
|
+
...(typeof rawData.commitOnSelect === "boolean"
|
|
445
|
+
? { commitOnSelect: rawData.commitOnSelect }
|
|
446
|
+
: {}),
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
function normalizeCopyBlockShowData(
|
|
451
|
+
rawData: Record<string, unknown>,
|
|
452
|
+
): CopyBlockSurfaceData {
|
|
453
|
+
return {
|
|
454
|
+
text: typeof rawData.text === "string" ? rawData.text : "",
|
|
455
|
+
...(typeof rawData.label === "string" ? { label: rawData.label } : {}),
|
|
456
|
+
...(typeof rawData.language === "string"
|
|
457
|
+
? { language: rawData.language }
|
|
458
|
+
: {}),
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function normalizeOAuthConnectShowData(
|
|
463
|
+
rawData: Record<string, unknown>,
|
|
464
|
+
): OAuthConnectSurfaceData {
|
|
465
|
+
return {
|
|
466
|
+
providerKey:
|
|
467
|
+
typeof rawData.providerKey === "string" ? rawData.providerKey.trim() : "",
|
|
468
|
+
...(typeof rawData.displayName === "string"
|
|
469
|
+
? { displayName: rawData.displayName }
|
|
470
|
+
: {}),
|
|
471
|
+
...(typeof rawData.description === "string"
|
|
472
|
+
? { description: rawData.description }
|
|
473
|
+
: {}),
|
|
474
|
+
...(typeof rawData.logoUrl === "string" || rawData.logoUrl === null
|
|
475
|
+
? { logoUrl: rawData.logoUrl }
|
|
476
|
+
: {}),
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function buildChoiceActions(data: ChoiceSurfaceData): Array<{
|
|
481
|
+
id: string;
|
|
482
|
+
label: string;
|
|
483
|
+
style?: string;
|
|
484
|
+
data?: Record<string, unknown>;
|
|
485
|
+
}> {
|
|
486
|
+
return data.options.map((option) => ({
|
|
487
|
+
id: option.id,
|
|
488
|
+
label: option.title,
|
|
489
|
+
style: option.recommended ? "primary" : "secondary",
|
|
490
|
+
data: {
|
|
491
|
+
choiceId: option.id,
|
|
492
|
+
choiceTitle: option.title,
|
|
493
|
+
selectedIds: [option.id],
|
|
494
|
+
selectedTitles: [option.title],
|
|
495
|
+
...(option.description ? { choiceDescription: option.description } : {}),
|
|
496
|
+
...(option.recommended ? { recommended: true } : {}),
|
|
497
|
+
...(option.data ?? {}),
|
|
498
|
+
},
|
|
499
|
+
}));
|
|
500
|
+
}
|
|
501
|
+
|
|
398
502
|
function isTaskProgressCardData(data: SurfaceData | Record<string, unknown>) {
|
|
399
503
|
return (data as Record<string, unknown>).template === "task_progress";
|
|
400
504
|
}
|
|
@@ -1699,6 +1803,8 @@ export async function handleSurfaceAction(
|
|
|
1699
1803
|
// been accepted. Deferred until after rejection check so the surface stays
|
|
1700
1804
|
// active and retryable if the queue was full.
|
|
1701
1805
|
const ONE_SHOT_SURFACE_TYPES = [
|
|
1806
|
+
"choice",
|
|
1807
|
+
"oauth_connect",
|
|
1702
1808
|
"form",
|
|
1703
1809
|
"confirmation",
|
|
1704
1810
|
"file_upload",
|
|
@@ -1860,6 +1966,12 @@ export function buildCompletionSummary(
|
|
|
1860
1966
|
data?: Record<string, unknown>,
|
|
1861
1967
|
surfaceData?: Record<string, unknown>,
|
|
1862
1968
|
): string {
|
|
1969
|
+
const selectedTitles = Array.isArray(data?.selectedTitles)
|
|
1970
|
+
? data.selectedTitles.filter(
|
|
1971
|
+
(title): title is string => typeof title === "string",
|
|
1972
|
+
)
|
|
1973
|
+
: [];
|
|
1974
|
+
|
|
1863
1975
|
if (surfaceType === "confirmation") {
|
|
1864
1976
|
if (actionId === "cancel") {
|
|
1865
1977
|
const cancelLabel =
|
|
@@ -1892,6 +2004,43 @@ export function buildCompletionSummary(
|
|
|
1892
2004
|
if (surfaceType === "form") {
|
|
1893
2005
|
return "Submitted";
|
|
1894
2006
|
}
|
|
2007
|
+
if (surfaceType === "choice" && data) {
|
|
2008
|
+
const choiceTitle =
|
|
2009
|
+
typeof data.choiceTitle === "string" ? data.choiceTitle : undefined;
|
|
2010
|
+
if (choiceTitle) return `User chose: "${choiceTitle}"`;
|
|
2011
|
+
if (selectedTitles.length === 1)
|
|
2012
|
+
return `User chose: "${selectedTitles[0]}"`;
|
|
2013
|
+
if (selectedTitles.length > 1) {
|
|
2014
|
+
return `User chose ${selectedTitles.length} options: ${selectedTitles
|
|
2015
|
+
.map((title) => `"${title}"`)
|
|
2016
|
+
.join(", ")}`;
|
|
2017
|
+
}
|
|
2018
|
+
return `User chose: ${actionId}`;
|
|
2019
|
+
}
|
|
2020
|
+
if (surfaceType === "oauth_connect") {
|
|
2021
|
+
const providerLabel =
|
|
2022
|
+
typeof data?.providerLabel === "string"
|
|
2023
|
+
? data.providerLabel
|
|
2024
|
+
: typeof data?.displayName === "string"
|
|
2025
|
+
? data.displayName
|
|
2026
|
+
: typeof data?.providerKey === "string"
|
|
2027
|
+
? data.providerKey
|
|
2028
|
+
: "OAuth";
|
|
2029
|
+
const accountLabel =
|
|
2030
|
+
typeof data?.accountLabel === "string" ? data.accountLabel : undefined;
|
|
2031
|
+
if (actionId === "connect" || data?.status === "connected") {
|
|
2032
|
+
return accountLabel
|
|
2033
|
+
? `Connected ${providerLabel}: ${accountLabel}`
|
|
2034
|
+
: `Connected ${providerLabel}`;
|
|
2035
|
+
}
|
|
2036
|
+
if (actionId === "cancel" || data?.status === "cancelled") {
|
|
2037
|
+
return `Cancelled ${providerLabel} connection`;
|
|
2038
|
+
}
|
|
2039
|
+
if (data?.status === "error") {
|
|
2040
|
+
return `${providerLabel} connection failed`;
|
|
2041
|
+
}
|
|
2042
|
+
return `${providerLabel} connection ${actionId}`;
|
|
2043
|
+
}
|
|
1895
2044
|
if (surfaceType === "list" && data) {
|
|
1896
2045
|
const selectedIds = data.selectedIds as string[] | undefined;
|
|
1897
2046
|
const actionSuffix = actionId ? ` (action: ${actionId})` : "";
|
|
@@ -1922,6 +2071,11 @@ function buildUserFacingLabel(
|
|
|
1922
2071
|
surfaceData?: Record<string, unknown>,
|
|
1923
2072
|
): string {
|
|
1924
2073
|
const count = (data?.selectedIds as string[] | undefined)?.length;
|
|
2074
|
+
const selectedTitles = Array.isArray(data?.selectedTitles)
|
|
2075
|
+
? data.selectedTitles.filter(
|
|
2076
|
+
(title): title is string => typeof title === "string",
|
|
2077
|
+
)
|
|
2078
|
+
: [];
|
|
1925
2079
|
|
|
1926
2080
|
if (surfaceType === "confirmation") {
|
|
1927
2081
|
if (actionId === "cancel") {
|
|
@@ -1948,6 +2102,39 @@ function buildUserFacingLabel(
|
|
|
1948
2102
|
return `Selected: ${actionId}`;
|
|
1949
2103
|
}
|
|
1950
2104
|
if (surfaceType === "form") return "Submitted";
|
|
2105
|
+
if (surfaceType === "choice") {
|
|
2106
|
+
const choiceTitle =
|
|
2107
|
+
typeof data?.choiceTitle === "string" ? data.choiceTitle : undefined;
|
|
2108
|
+
if (choiceTitle) return choiceTitle;
|
|
2109
|
+
if (selectedTitles.length === 1) return selectedTitles[0];
|
|
2110
|
+
if (selectedTitles.length > 1)
|
|
2111
|
+
return `Selected ${selectedTitles.length} options`;
|
|
2112
|
+
return "Selected";
|
|
2113
|
+
}
|
|
2114
|
+
if (surfaceType === "oauth_connect") {
|
|
2115
|
+
const providerLabel =
|
|
2116
|
+
typeof data?.providerLabel === "string"
|
|
2117
|
+
? data.providerLabel
|
|
2118
|
+
: typeof data?.displayName === "string"
|
|
2119
|
+
? data.displayName
|
|
2120
|
+
: typeof data?.providerKey === "string"
|
|
2121
|
+
? data.providerKey
|
|
2122
|
+
: "OAuth";
|
|
2123
|
+
const accountLabel =
|
|
2124
|
+
typeof data?.accountLabel === "string" ? data.accountLabel : undefined;
|
|
2125
|
+
if (actionId === "connect" || data?.status === "connected") {
|
|
2126
|
+
return accountLabel
|
|
2127
|
+
? `Connected ${providerLabel}: ${accountLabel}`
|
|
2128
|
+
: `Connected ${providerLabel}`;
|
|
2129
|
+
}
|
|
2130
|
+
if (actionId === "cancel" || data?.status === "cancelled") {
|
|
2131
|
+
return "Cancelled";
|
|
2132
|
+
}
|
|
2133
|
+
if (data?.status === "error") {
|
|
2134
|
+
return `${providerLabel} connection failed`;
|
|
2135
|
+
}
|
|
2136
|
+
return `Selected: ${actionId}`;
|
|
2137
|
+
}
|
|
1951
2138
|
|
|
1952
2139
|
// Table / list selection actions
|
|
1953
2140
|
if (count) {
|
|
@@ -2213,11 +2400,17 @@ export async function surfaceProxyResolver(
|
|
|
2213
2400
|
const data = (
|
|
2214
2401
|
surfaceType === "card"
|
|
2215
2402
|
? normalizeCardShowData(input, rawData)
|
|
2216
|
-
: surfaceType === "
|
|
2217
|
-
?
|
|
2218
|
-
:
|
|
2403
|
+
: surfaceType === "choice"
|
|
2404
|
+
? normalizeChoiceShowData(rawData)
|
|
2405
|
+
: surfaceType === "copy_block"
|
|
2406
|
+
? normalizeCopyBlockShowData(rawData)
|
|
2407
|
+
: surfaceType === "oauth_connect"
|
|
2408
|
+
? normalizeOAuthConnectShowData(rawData)
|
|
2409
|
+
: surfaceType === "dynamic_page"
|
|
2410
|
+
? normalizeDynamicPageShowData(input, rawData)
|
|
2411
|
+
: rawData
|
|
2219
2412
|
) as SurfaceData;
|
|
2220
|
-
const
|
|
2413
|
+
const inputActions = input.actions as
|
|
2221
2414
|
| Array<{
|
|
2222
2415
|
id: string;
|
|
2223
2416
|
label: string;
|
|
@@ -2225,8 +2418,33 @@ export async function surfaceProxyResolver(
|
|
|
2225
2418
|
data?: Record<string, unknown>;
|
|
2226
2419
|
}>
|
|
2227
2420
|
| undefined;
|
|
2421
|
+
const actions =
|
|
2422
|
+
surfaceType === "choice"
|
|
2423
|
+
? buildChoiceActions(data as ChoiceSurfaceData)
|
|
2424
|
+
: inputActions;
|
|
2228
2425
|
// Interactive surfaces default to awaiting user action.
|
|
2229
2426
|
const hasActions = Array.isArray(actions) && actions.length > 0;
|
|
2427
|
+
if (surfaceType === "choice" && !hasActions) {
|
|
2428
|
+
return {
|
|
2429
|
+
content:
|
|
2430
|
+
"choice surfaces require at least one option with both id and title.",
|
|
2431
|
+
isError: true,
|
|
2432
|
+
};
|
|
2433
|
+
}
|
|
2434
|
+
const oauthProviderKey =
|
|
2435
|
+
surfaceType === "oauth_connect"
|
|
2436
|
+
? (data as unknown as Record<string, unknown>).providerKey
|
|
2437
|
+
: undefined;
|
|
2438
|
+
if (
|
|
2439
|
+
surfaceType === "oauth_connect" &&
|
|
2440
|
+
(typeof oauthProviderKey !== "string" ||
|
|
2441
|
+
oauthProviderKey.trim().length === 0)
|
|
2442
|
+
) {
|
|
2443
|
+
return {
|
|
2444
|
+
content: "oauth_connect surfaces require data.providerKey.",
|
|
2445
|
+
isError: true,
|
|
2446
|
+
};
|
|
2447
|
+
}
|
|
2230
2448
|
const isInteractive =
|
|
2231
2449
|
surfaceType === "card"
|
|
2232
2450
|
? hasActions
|
|
@@ -11,14 +11,12 @@ import {
|
|
|
11
11
|
type InterfaceId,
|
|
12
12
|
supportsHostProxy,
|
|
13
13
|
} from "../channels/types.js";
|
|
14
|
-
import { isHttpAuthDisabled } from "../config/env.js";
|
|
15
14
|
import { getIsPlatform } from "../config/env-registry.js";
|
|
16
15
|
import { getConfig } from "../config/loader.js";
|
|
17
16
|
import { getBindingByConversation } from "../memory/external-conversation-store.js";
|
|
18
17
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
19
18
|
import type { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
20
19
|
import type { Message, ToolDefinition } from "../providers/types.js";
|
|
21
|
-
import type { TrustClass } from "../runtime/actor-trust-resolver.js";
|
|
22
20
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
23
21
|
import { registerConversationSender } from "../tools/browser/browser-screencast.js";
|
|
24
22
|
import type { ToolExecutor } from "../tools/executor.js";
|
|
@@ -48,27 +46,10 @@ import {
|
|
|
48
46
|
} from "./doordash-steps.js";
|
|
49
47
|
import type { ServerMessage, UiSurfaceShow } from "./message-protocol.js";
|
|
50
48
|
import { runPostExecutionSideEffects } from "./tool-side-effects.js";
|
|
51
|
-
import
|
|
49
|
+
import { resolveTrustClass } from "./trust-context.js";
|
|
52
50
|
|
|
53
51
|
const log = getLogger("conversation-tool-setup");
|
|
54
52
|
|
|
55
|
-
/**
|
|
56
|
-
* Resolve the effective trust class for tool execution.
|
|
57
|
-
*
|
|
58
|
-
* When HTTP auth is disabled (dev bypass), always returns `'guardian'`
|
|
59
|
-
* so that control-plane gates don't block local development.
|
|
60
|
-
*
|
|
61
|
-
* When no trust context is available (e.g. desktop-only conversations that
|
|
62
|
-
* don't go through channel trust resolution), defaults to `'unknown'`
|
|
63
|
-
* to fail-closed.
|
|
64
|
-
*/
|
|
65
|
-
export function resolveTrustClass(
|
|
66
|
-
trustContext: TrustContext | undefined,
|
|
67
|
-
): TrustClass {
|
|
68
|
-
if (isHttpAuthDisabled()) return "guardian";
|
|
69
|
-
return trustContext?.trustClass ?? "unknown";
|
|
70
|
-
}
|
|
71
|
-
|
|
72
53
|
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
73
54
|
import { AUTO_PROFILE_KEY } from "../config/seed-inference-profiles.js";
|
|
74
55
|
import {
|
|
@@ -97,7 +78,6 @@ export function createToolExecutor(
|
|
|
97
78
|
input: Record<string, unknown>,
|
|
98
79
|
onOutput?: (chunk: string) => void,
|
|
99
80
|
toolUseId?: string,
|
|
100
|
-
turnContext?: import("../plugins/types.js").TurnContext,
|
|
101
81
|
) => Promise<ToolExecutionResult> {
|
|
102
82
|
// Register the conversation's sendToClient for browser screencast surface messages
|
|
103
83
|
registerConversationSender(ctx.conversationId, (msg) =>
|
|
@@ -109,7 +89,6 @@ export function createToolExecutor(
|
|
|
109
89
|
input: Record<string, unknown>,
|
|
110
90
|
onOutput?: (chunk: string) => void,
|
|
111
91
|
toolUseId?: string,
|
|
112
|
-
turnContext?: import("../plugins/types.js").TurnContext,
|
|
113
92
|
) => {
|
|
114
93
|
const { name: executionName, input: executionInput } =
|
|
115
94
|
resolveToolInvocationAlias(name, input, ctx.allowedToolNames);
|
|
@@ -257,12 +236,7 @@ export function createToolExecutor(
|
|
|
257
236
|
};
|
|
258
237
|
}
|
|
259
238
|
|
|
260
|
-
const result = await executor.execute(
|
|
261
|
-
toolName,
|
|
262
|
-
toolInput,
|
|
263
|
-
toolContext,
|
|
264
|
-
turnContext,
|
|
265
|
-
);
|
|
239
|
+
const result = await executor.execute(toolName, toolInput, toolContext);
|
|
266
240
|
if (toolContext.approvedViaPrompt) {
|
|
267
241
|
ctx.approvedViaPromptThisTurn = true;
|
|
268
242
|
}
|
|
@@ -276,7 +250,6 @@ export function createToolExecutor(
|
|
|
276
250
|
executionName,
|
|
277
251
|
executionInput,
|
|
278
252
|
toolContext,
|
|
279
|
-
turnContext,
|
|
280
253
|
);
|
|
281
254
|
if (toolContext.approvedViaPrompt) {
|
|
282
255
|
ctx.approvedViaPromptThisTurn = true;
|
|
@@ -4,6 +4,7 @@ import { getConversation } from "../memory/conversation-crud.js";
|
|
|
4
4
|
import { resolveConversationDirectoryPaths } from "../memory/conversation-directories.js";
|
|
5
5
|
import { renderWorkspaceTopLevelContext } from "../workspace/top-level-renderer.js";
|
|
6
6
|
import { scanTopLevelDirectories } from "../workspace/top-level-scanner.js";
|
|
7
|
+
import { findConversationOrSubagent } from "./conversation-registry.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Subset of Conversation state that workspace context helpers need.
|
|
@@ -25,6 +26,22 @@ export interface WorkspaceConversationContext {
|
|
|
25
26
|
hostUsername?: string;
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the live workspace top-level block for a conversation, refreshing
|
|
31
|
+
* the dirty-guarded cache first so a workspace-mutating tool's
|
|
32
|
+
* `markWorkspaceTopLevelDirty` from the prior turn is picked up. Returns `null`
|
|
33
|
+
* when no live conversation is found (no active conversation, or a context with
|
|
34
|
+
* no conversation id) or when the rendered context is empty.
|
|
35
|
+
*/
|
|
36
|
+
export function resolveWorkspaceTopLevelContext(
|
|
37
|
+
conversationId: string | undefined,
|
|
38
|
+
): string | null {
|
|
39
|
+
const conversation = findConversationOrSubagent(conversationId);
|
|
40
|
+
if (!conversation) return null;
|
|
41
|
+
refreshWorkspaceTopLevelContextIfNeeded(conversation);
|
|
42
|
+
return conversation.workspaceTopLevelContext;
|
|
43
|
+
}
|
|
44
|
+
|
|
28
45
|
/** Refresh workspace top-level directory context if needed. */
|
|
29
46
|
export function refreshWorkspaceTopLevelContextIfNeeded(
|
|
30
47
|
ctx: WorkspaceConversationContext,
|