@vellumai/assistant 0.11.2 → 0.11.3-staging.1
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/ARCHITECTURE.md +58 -3
- package/docs/trusted-contact-access.md +9 -5
- package/docs/vellum-doctor.md +195 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/ces-client/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +19 -2
- package/node_modules/@vellumai/environments/package.json +2 -1
- package/node_modules/@vellumai/environments/src/__tests__/cloud-assistant-hub-url.test.ts +38 -0
- package/node_modules/@vellumai/environments/src/__tests__/install-layout.test.ts +98 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +5 -5
- package/node_modules/@vellumai/environments/src/index.ts +17 -6
- package/node_modules/@vellumai/environments/src/install-layout.ts +49 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +29 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +4 -0
- package/node_modules/@vellumai/gateway-client/src/verification-session-contract.ts +91 -6
- package/node_modules/@vellumai/ipc-server-utils/src/endpoint.test.ts +36 -0
- package/node_modules/@vellumai/ipc-server-utils/src/endpoint.ts +142 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +2 -0
- package/node_modules/@vellumai/ipc-server-utils/src/listen-options.ts +3 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +15 -1
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +17 -2
- package/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +16 -2
- package/openapi.yaml +589 -30
- package/package.json +1 -1
- package/src/__tests__/agent-image-optimize.test.ts +4 -4
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +113 -66
- package/src/__tests__/agent-loop-override-profile.test.ts +38 -48
- package/src/__tests__/agent-loop-subagent-billing-headers.test.ts +166 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/answered-question-persistence.test.ts +240 -0
- package/src/__tests__/anthropic-provider.test.ts +165 -30
- package/src/__tests__/app-control-flow.test.ts +9 -8
- package/src/__tests__/assistant-event-hub.test.ts +48 -0
- package/src/__tests__/attachments-store-heic-normalize.test.ts +16 -12
- package/src/__tests__/attachments-store.test.ts +130 -68
- package/src/__tests__/attachments.test.ts +36 -36
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/call-start-guardian-guard.test.ts +18 -4
- package/src/__tests__/canned-reply-release.test.ts +86 -0
- package/src/__tests__/channel-guardian.test.ts +59 -29
- package/src/__tests__/channel-readiness-telegram-remote.test.ts +154 -0
- package/src/__tests__/channel-setup-panel-ack.test.ts +6 -5
- package/src/__tests__/client-os-metadata-persistence.test.ts +103 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
- package/src/__tests__/consult-deadline.test.ts +65 -0
- package/src/__tests__/conversation-agent-loop.test.ts +438 -2
- package/src/__tests__/conversation-disk-view-integration.test.ts +5 -1
- package/src/__tests__/conversation-disk-view.test.ts +4 -4
- package/src/__tests__/conversation-error.test.ts +22 -3
- package/src/__tests__/conversation-fork-crud.test.ts +5 -1
- package/src/__tests__/conversation-fork-referential.test.ts +352 -0
- package/src/__tests__/conversation-fork-retrospective.test.ts +5 -1
- package/src/__tests__/conversation-group-tools.test.ts +32 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +27 -1
- package/src/__tests__/conversation-initial-prompt.test.ts +51 -22
- package/src/__tests__/conversation-key-store-bootstrap-cleanup.test.ts +119 -0
- package/src/__tests__/conversation-key-store-origin.test.ts +105 -0
- package/src/__tests__/conversation-list-recency-ordering.test.ts +104 -0
- package/src/__tests__/conversation-origin-at-creation.test.ts +153 -0
- package/src/__tests__/conversation-origin-channel-filter.test.ts +95 -0
- package/src/__tests__/conversation-placement-promotion.test.ts +172 -0
- package/src/__tests__/conversation-queue.test.ts +265 -1
- package/src/__tests__/conversation-retry-route.test.ts +3 -1
- package/src/__tests__/conversation-store-ephemeral.test.ts +4 -0
- package/src/__tests__/conversation-store.test.ts +26 -10
- package/src/__tests__/conversation-summarize-route.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +15 -6
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -5
- package/src/__tests__/conversation-surfaces-app-control.test.ts +12 -11
- package/src/__tests__/conversation-surfaces-app-open.test.ts +11 -5
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +5 -4
- package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +967 -0
- package/src/__tests__/conversation-surfaces-persisted-info.test.ts +312 -0
- package/src/__tests__/conversation-surfaces-queued-emit.test.ts +6 -5
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -8
- package/src/__tests__/conversation-surfaces-standalone.test.ts +21 -11
- package/src/__tests__/conversation-surfaces-state-update.test.ts +7 -11
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -6
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +11 -6
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +9 -6
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +70 -7
- package/src/__tests__/conversation-wait-for-idle.test.ts +6 -11
- package/src/__tests__/credential-prompt-route.test.ts +57 -7
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +89 -28
- package/src/__tests__/custom-group-listing-visibility.test.ts +1 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +4 -1
- package/src/__tests__/discord-access-request-privacy.test.ts +366 -0
- package/src/__tests__/discord-requester-notice-privacy.test.ts +87 -0
- package/src/__tests__/disk-pressure-guard.test.ts +55 -55
- package/src/__tests__/disk-pressure-routes.test.ts +10 -10
- package/src/__tests__/disk-pressure-tools.test.ts +2 -2
- package/src/__tests__/disk-usage.test.ts +35 -20
- package/src/__tests__/document-sync-tags.test.ts +379 -0
- package/src/__tests__/document-update-default-surface.test.ts +28 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +2 -2
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -4
- package/src/__tests__/ensure-conversation-exists.test.ts +8 -5
- package/src/__tests__/events-dev-bypass-actor.test.ts +183 -1
- package/src/__tests__/evict-conversations-for-reload.test.ts +90 -0
- package/src/__tests__/file-list-tool.test.ts +12 -10
- package/src/__tests__/file-ops-service.test.ts +151 -44
- package/src/__tests__/file-read-container-boundary.test.ts +137 -0
- package/src/__tests__/file-read-tool.test.ts +21 -9
- package/src/__tests__/file-url-path-guard.test.ts +83 -0
- package/src/__tests__/filesystem-tools.test.ts +82 -66
- package/src/__tests__/guardian-outbound-http.test.ts +8 -8
- package/src/__tests__/helpers/gateway-verification-sessions-stub.ts +14 -1
- package/src/__tests__/helpers/hub-clients.ts +42 -0
- package/src/__tests__/helpers/mock-conversation.ts +46 -0
- package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +61 -57
- package/src/__tests__/history-repair.test.ts +112 -12
- package/src/__tests__/host-bash-proxy.test.ts +10 -5
- package/src/__tests__/host-bash-routes.test.ts +67 -0
- package/src/__tests__/host-browser-proxy.test.ts +2 -2
- package/src/__tests__/host-cu-proxy.test.ts +3 -7
- package/src/__tests__/host-file-proxy.test.ts +3 -7
- package/src/__tests__/host-file-read-tool.test.ts +5 -1
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +6 -4
- package/src/__tests__/http-conversation-lineage.test.ts +2 -5
- package/src/__tests__/http-user-message-parity.test.ts +44 -0
- package/src/__tests__/identity-routes.test.ts +13 -13
- package/src/__tests__/image-conversion.test.ts +29 -26
- package/src/__tests__/image-source-path-reinject.test.ts +2 -2
- package/src/__tests__/inference-profile-session-handler.test.ts +95 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +25 -0
- package/src/__tests__/introduction-card-resolver.test.ts +6 -1
- package/src/__tests__/list-messages-attachments.test.ts +56 -32
- package/src/__tests__/list-messages-background-tool-completion.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +2 -2
- package/src/__tests__/list-messages-hidden-metadata.test.ts +16 -16
- package/src/__tests__/list-messages-page-latest.test.ts +61 -61
- package/src/__tests__/list-messages-provider-error.test.ts +6 -6
- package/src/__tests__/list-messages-queued.test.ts +49 -6
- package/src/__tests__/list-messages-system-card.test.ts +4 -4
- package/src/__tests__/list-messages-tool-merge.test.ts +9 -9
- package/src/__tests__/llm-resolver-override-or-default.test.ts +141 -0
- package/src/__tests__/llm-usage-store.test.ts +55 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +45 -0
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +133 -0
- package/src/__tests__/media-stream-server-integration.test.ts +36 -0
- package/src/__tests__/migration-export-http.test.ts +1 -1
- package/src/__tests__/migration-import-commit-http.test.ts +1 -1
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -1
- package/src/__tests__/migration-validate-http.test.ts +1 -1
- package/src/__tests__/mtime-cache.test.ts +65 -3
- package/src/__tests__/notification-platform-adapter.test.ts +104 -0
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
- package/src/__tests__/oauth-provider-profiles.test.ts +4 -2
- package/src/__tests__/oauth-provider-serializer.test.ts +17 -0
- package/src/__tests__/oauth-providers-routes.test.ts +1 -0
- package/src/__tests__/openai-responses-prompt-cache.test.ts +5 -2
- package/src/__tests__/path-policy.test.ts +164 -1
- package/src/__tests__/persist-media-references.test.ts +2 -2
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +5 -5
- package/src/__tests__/persist-unsendable-image.test.ts +23 -23
- package/src/__tests__/persona-resolver.test.ts +154 -0
- package/src/__tests__/plugin-api-webhook-url.test.ts +170 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +6 -0
- package/src/__tests__/processing-flag-persist-failure.test.ts +15 -10
- package/src/__tests__/profile-availability-incomplete.test.ts +113 -0
- package/src/__tests__/profiler-routes.test.ts +13 -13
- package/src/__tests__/prompt-cache-cross-turn-stability.test.ts +593 -0
- package/src/__tests__/proxy-approval-callback.test.ts +3 -3
- package/src/__tests__/queued-message-cancel-and-steer.test.ts +189 -0
- package/src/__tests__/queued-message-steer-actor-scoping.test.ts +164 -0
- package/src/__tests__/resolve-trust-class.test.ts +20 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +1 -1
- package/src/__tests__/run-due-schedules.test.ts +174 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +15 -7
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +166 -0
- package/src/__tests__/schedule-routes.test.ts +730 -8
- package/src/__tests__/schedule-store.test.ts +540 -0
- package/src/__tests__/schedule-tools.test.ts +103 -0
- package/src/__tests__/scheduler-wake.test.ts +5 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +29 -1
- package/src/__tests__/secure-keys.test.ts +91 -0
- package/src/__tests__/server-history-render.test.ts +97 -7
- package/src/__tests__/size-guard.test.ts +8 -8
- package/src/__tests__/skill-docs-sync-guard.test.ts +3 -2
- package/src/__tests__/skill-tool-factory.test.ts +247 -0
- package/src/__tests__/skills-install-staging.test.ts +15 -6
- package/src/__tests__/slack-edit-ordering-characterization.test.ts +103 -0
- package/src/__tests__/slack-inbound-verification.test.ts +4 -1
- package/src/__tests__/slack-mention-binding-invariance.test.ts +103 -0
- package/src/__tests__/slack-mention-provider-leak-audit.test.ts +135 -0
- package/src/__tests__/starter-task-flow.test.ts +5 -4
- package/src/__tests__/steer-on-enqueue-question.test.ts +3 -2
- package/src/__tests__/stt-language-catalog-parity.test.ts +38 -0
- package/src/__tests__/subagent-allowlist-validation.test.ts +26 -4
- package/src/__tests__/subagent-cron-run-attribution.test.ts +301 -0
- package/src/__tests__/subagent-disposal.test.ts +10 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +10 -0
- package/src/__tests__/subagent-fork-prompt-role.test.ts +85 -11
- package/src/__tests__/subagent-fork-spawn.test.ts +15 -7
- package/src/__tests__/subagent-manager-notify.test.ts +148 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/subagent-persistence.test.ts +141 -0
- package/src/__tests__/subagent-role-registry.test.ts +172 -63
- package/src/__tests__/subagent-role-resolution.test.ts +88 -0
- package/src/__tests__/subagent-spawn-and-await.test.ts +48 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +111 -10
- package/src/__tests__/subagent-terminal-message.test.ts +88 -1
- package/src/__tests__/subagent-tool-gate-mode.test.ts +225 -10
- package/src/__tests__/subagent-tools.test.ts +1901 -108
- package/src/__tests__/surface-completion-compaction-boundary.test.ts +124 -0
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +298 -0
- package/src/__tests__/system-prompt.test.ts +82 -7
- package/src/__tests__/tool-result-spool.test.ts +74 -18
- package/src/__tests__/tool-side-effects-documents.test.ts +174 -0
- package/src/__tests__/tool-side-effects-hook-failures.test.ts +129 -0
- package/src/__tests__/tools-audio-read.test.ts +10 -10
- package/src/__tests__/tools-get-route.test.ts +85 -12
- package/src/__tests__/tools-list-cli.test.ts +171 -0
- package/src/__tests__/top-level-renderer.test.ts +54 -1
- package/src/__tests__/trusted-contact-multichannel.test.ts +4 -1
- package/src/__tests__/turn-tail-chain.test.ts +135 -0
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +6 -4
- package/src/__tests__/ui-visual-surface.test.ts +5 -4
- package/src/__tests__/ui-work-result-surface.test.ts +5 -4
- package/src/__tests__/unified-turn-context-visible-app.test.ts +7 -8
- package/src/__tests__/usage-routes.test.ts +62 -0
- package/src/__tests__/verification-outbound-delivery.test.ts +176 -0
- package/src/__tests__/visible-app-context.test.ts +20 -4
- package/src/__tests__/web-search-history.test.ts +96 -0
- package/src/__tests__/workspace-migration-139-clear-renamed-cost-profile-label.test.ts +6 -6
- package/src/__tests__/workspace-migration-140-repair-seed-pinned-memory-v3-live.test.ts +330 -0
- package/src/acp/failure-error.ts +3 -5
- package/src/agent/attachments.ts +26 -24
- package/src/agent/history-repair/history-repair.ts +27 -26
- package/src/agent/image-optimize.ts +6 -6
- package/src/agent/loop.ts +40 -22
- package/src/agent/message-types.ts +3 -3
- package/src/api/constants/document-tools.ts +55 -0
- package/src/api/events/question-answered.ts +53 -0
- package/src/api/events/tool-result.ts +7 -0
- package/src/api/index.ts +13 -0
- package/src/api/responses/conversation-message.ts +11 -0
- package/src/api/surfaces-oauth-connect.test.ts +96 -0
- package/src/api/surfaces.ts +36 -8
- package/src/approvals/guardian-channel-delivery.ts +83 -0
- package/src/approvals/guardian-expiry-notifier.ts +13 -11
- package/src/approvals/guardian-request-resolvers.ts +216 -132
- package/src/calls/__tests__/voice-session-bridge.test.ts +50 -0
- package/src/calls/media-stream-server.ts +9 -1
- package/src/calls/voice-session-bridge.ts +38 -0
- package/src/channels/__tests__/gateway-verification-sessions.test.ts +3 -3
- package/src/channels/config.ts +7 -2
- package/src/channels/gateway-verification-sessions.ts +7 -2
- package/src/channels/types.ts +7 -1
- package/src/cli/commands/__tests__/cache.test.ts +7 -4
- package/src/cli/commands/__tests__/cli-test-harness.ts +82 -0
- package/src/cli/commands/__tests__/conversations-wake.test.ts +51 -6
- package/src/cli/commands/__tests__/inference-models.test.ts +14 -0
- package/src/cli/commands/__tests__/inference-profiles.test.ts +44 -1
- package/src/cli/commands/__tests__/inference-providers.test.ts +7 -0
- package/src/cli/commands/__tests__/plugins.test.ts +692 -0
- package/src/cli/commands/__tests__/schedules.test.ts +136 -37
- package/src/cli/commands/conversations.ts +7 -3
- package/src/cli/commands/credentials.help.ts +7 -0
- package/src/cli/commands/inference-profiles.ts +9 -3
- package/src/cli/commands/inference.help.ts +16 -2
- package/src/cli/commands/mcp.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +18 -0
- package/src/cli/commands/notifications.ts +3 -6
- package/src/cli/commands/oauth/connect-surface-guidance.test.ts +16 -0
- package/src/cli/commands/oauth/connect-surface-guidance.ts +25 -7
- package/src/cli/commands/oauth/connect.test.ts +26 -1
- package/src/cli/commands/oauth/connect.ts +4 -1
- package/src/cli/commands/oauth/index.help.ts +3 -1
- package/src/cli/commands/oauth/providers.ts +3 -0
- package/src/cli/commands/plugins.help.ts +25 -2
- package/src/cli/commands/plugins.ts +289 -10
- package/src/cli/commands/schedules.help.ts +14 -12
- package/src/cli/commands/schedules.ts +19 -5
- package/src/cli/commands/tools.help.ts +4 -2
- package/src/cli/commands/tools.ts +38 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +1 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +79 -0
- package/src/cli/lib/__tests__/install-from-platform.test.ts +47 -1
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +86 -7
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +122 -0
- package/src/cli/lib/install-from-github.ts +61 -0
- package/src/cli/lib/install-from-platform.ts +13 -2
- package/src/cli/lib/plugin-surfaces.ts +124 -4
- package/src/cli/lib/upgrade-plugin.ts +18 -0
- package/src/cli.ts +1 -1
- package/src/config/__tests__/deployment-context-defaults.test.ts +73 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +40 -0
- package/src/config/__tests__/plugin-updates-schema.test.ts +43 -0
- package/src/config/__tests__/profile-tool-support.test.ts +131 -0
- package/src/config/bundled-skills/AGENTS.md +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +3 -3
- package/src/config/bundled-skills/schedule/SKILL.md +5 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +1 -0
- package/src/config/bundled-skills/subagent/SKILL.md +53 -22
- package/src/config/bundled-skills/subagent/TOOLS.json +14 -13
- package/src/config/bundled-skills/visualize/SKILL.md +1 -1
- package/src/config/default-profile-catalog.ts +6 -2
- package/src/config/feature-flag-registry.json +25 -17
- package/src/config/llm-resolver.ts +45 -15
- package/src/config/loader.ts +70 -1
- package/src/config/profile-tool-support.ts +110 -0
- package/src/config/sanitize-for-transfer.ts +11 -0
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/stt.test.ts +20 -5
- package/src/config/schemas/channels.ts +13 -0
- package/src/config/schemas/memory-retrospective.ts +25 -0
- package/src/config/schemas/plugin-updates.ts +55 -0
- package/src/config/schemas/services.ts +8 -4
- package/src/config/schemas/stt.ts +17 -5
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +16 -0
- package/src/contacts/guardian-delivery-reader.ts +29 -2
- package/src/context/compactor.ts +4 -4
- package/src/context/post-turn-tool-result-truncation.ts +32 -16
- package/src/context/strip-injections.ts +42 -0
- package/src/context/tool-result-spool.ts +32 -18
- package/src/credential-execution/ces-runtime.ts +3 -0
- package/src/credential-execution/client.ts +22 -1
- package/src/credential-execution/process-manager.test.ts +99 -0
- package/src/credential-execution/process-manager.ts +62 -16
- package/src/daemon/__tests__/abort-null-controller.test.ts +141 -5
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +8 -12
- package/src/daemon/__tests__/install-assistant-command.test.ts +234 -0
- package/src/daemon/__tests__/turn-tail-assistant-reply-notify.test.ts +2 -4
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +20 -29
- package/src/daemon/channel-ui-capability.ts +4 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +117 -61
- package/src/daemon/conversation-agent-loop.ts +296 -145
- package/src/daemon/conversation-attachments.ts +1 -1
- package/src/daemon/conversation-error.ts +8 -1
- package/src/daemon/conversation-initial-prompt.ts +16 -38
- package/src/daemon/conversation-lifecycle.ts +154 -32
- package/src/daemon/conversation-messaging.ts +85 -42
- package/src/daemon/conversation-process.ts +76 -28
- package/src/daemon/conversation-runtime-assembly.ts +9 -4
- package/src/daemon/conversation-store.ts +52 -3
- package/src/daemon/conversation-surface-state.ts +9 -0
- package/src/daemon/conversation-surfaces.ts +403 -210
- package/src/daemon/conversation-tool-setup.ts +56 -7
- package/src/daemon/conversation-turn-finalize.ts +134 -89
- package/src/daemon/conversation.ts +105 -27
- package/src/daemon/disk-pressure-guard-lifecycle.ts +2 -2
- package/src/daemon/disk-pressure-guard.ts +3 -3
- package/src/daemon/doordash-steps.ts +5 -5
- package/src/daemon/external-plugins-bootstrap.ts +7 -1
- package/src/daemon/handlers/config-channels.ts +48 -5
- package/src/daemon/handlers/conversation-history.ts +1 -1
- package/src/daemon/handlers/conversations.ts +62 -17
- package/src/daemon/handlers/shared.ts +12 -0
- package/src/daemon/handlers/skills.ts +11 -1
- package/src/daemon/identity-helpers.ts +38 -10
- package/src/daemon/install-assistant-command.ts +322 -0
- package/src/daemon/lifecycle.ts +14 -3
- package/src/daemon/message-types/conversations.ts +6 -7
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/persist-media-references.ts +23 -14
- package/src/daemon/process-message.ts +6 -6
- package/src/daemon/tool-setup-types.ts +19 -122
- package/src/daemon/tool-side-effects.ts +17 -94
- package/src/daemon/trust-context.ts +14 -6
- package/src/daemon/turn-tail-chain.ts +73 -0
- package/src/daemon/web-search-history.ts +47 -33
- package/src/heartbeat/heartbeat-service.ts +6 -6
- package/src/ipc/__tests__/socket-path.test.ts +21 -0
- package/src/ipc/assistant-server.ts +17 -10
- package/src/ipc/cli-client.ts +10 -1
- package/src/ipc/routes/__tests__/documents-sync-ipc-routes.test.ts +56 -0
- package/src/ipc/routes/documents-sync-ipc-routes.ts +42 -0
- package/src/ipc/socket-cleanup.ts +9 -7
- package/src/ipc/socket-path.ts +4 -96
- package/src/live-voice/__tests__/live-voice-archive.test.ts +16 -16
- package/src/live-voice/__tests__/live-voice-attach-image.test.ts +209 -0
- package/src/live-voice/__tests__/live-voice-connection.test.ts +20 -0
- package/src/live-voice/__tests__/live-voice-integration.test.ts +7 -5
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +265 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +6 -1
- package/src/live-voice/__tests__/live-voice-vad.test.ts +35 -15
- package/src/live-voice/__tests__/protocol.test.ts +52 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +3 -0
- package/src/live-voice/live-voice-archive.ts +13 -13
- package/src/live-voice/live-voice-connection.ts +7 -1
- package/src/live-voice/live-voice-photo.ts +169 -0
- package/src/live-voice/live-voice-session.ts +108 -4
- package/src/live-voice/protocol.ts +89 -1
- package/src/mcp/client.ts +10 -0
- package/src/messaging/providers/__tests__/callback-routing.test.ts +5 -1
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +66 -4
- package/src/messaging/providers/callback-routing.ts +1 -0
- package/src/messaging/providers/discord/api.ts +312 -0
- package/src/messaging/providers/discord/dm-delivery.test.ts +204 -0
- package/src/messaging/providers/discord/render.test.ts +204 -0
- package/src/messaging/providers/discord/render.ts +195 -0
- package/src/messaging/providers/discord/send.test.ts +179 -0
- package/src/messaging/providers/discord/send.ts +212 -0
- package/src/messaging/providers/discord/transport.ts +81 -0
- package/src/messaging/providers/index.ts +3 -1
- package/src/messaging/providers/retry-policy.test.ts +247 -0
- package/src/messaging/providers/retry-policy.ts +206 -0
- package/src/messaging/providers/slack/mention-source.test.ts +285 -0
- package/src/messaging/providers/slack/mention-source.ts +287 -0
- package/src/messaging/providers/telegram-bot/api.ts +47 -130
- package/src/messaging/providers/whatsapp/api.ts +47 -136
- package/src/monitoring/__tests__/db-integrity-sample.test.ts +4 -1
- package/src/monitoring/__tests__/plugin-auto-update.test.ts +332 -0
- package/src/monitoring/db-integrity-sample.ts +6 -1
- package/src/monitoring/plugin-auto-update.ts +359 -0
- package/src/monitoring/resource-sampler.ts +21 -5
- package/src/monitoring/worker.ts +13 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +375 -2
- package/src/notifications/__tests__/broadcaster.test.ts +37 -1
- package/src/notifications/__tests__/copy-composer.test.ts +165 -0
- package/src/notifications/__tests__/emit-signal-pipeline-failure.test.ts +205 -0
- package/src/notifications/__tests__/notification-utils.test.ts +249 -0
- package/src/notifications/adapters/platform.ts +31 -2
- package/src/notifications/assistant-reply-producer.ts +79 -32
- package/src/notifications/broadcaster.ts +30 -10
- package/src/notifications/copy-composer.ts +69 -0
- package/src/notifications/emit-signal.ts +82 -15
- package/src/notifications/events-store.ts +10 -2
- package/src/notifications/home-feed-side-effect.ts +6 -3
- package/src/notifications/notification-utils.ts +173 -5
- package/src/notifications/signal.ts +12 -0
- package/src/oauth/byo-connection.ts +6 -1
- package/src/oauth/credential-token-resolver.ts +3 -10
- package/src/oauth/manual-token-connection.ts +29 -64
- package/src/oauth/manual-token-providers.ts +62 -0
- package/src/oauth/provider-serializer.ts +13 -0
- package/src/oauth/seed-providers.ts +56 -8
- package/src/onboarding/onboarding-events-store.ts +91 -1
- package/src/permissions/question-prompter.test.ts +4 -0
- package/src/permissions/question-prompter.ts +21 -4
- package/src/persistence/__tests__/conversation-lineage.test.ts +248 -0
- package/src/persistence/attachments-store.ts +15 -15
- package/src/persistence/conversation-attention-store.ts +30 -10
- package/src/persistence/conversation-bootstrap.ts +17 -0
- package/src/persistence/conversation-crud.ts +363 -97
- package/src/persistence/conversation-group-migration.ts +1 -1
- package/src/persistence/conversation-key-store.ts +38 -10
- package/src/persistence/conversation-lineage.ts +226 -0
- package/src/persistence/conversation-plugin-facade.ts +28 -3
- package/src/persistence/conversation-queries.ts +207 -33
- package/src/persistence/conversation-types.ts +107 -1
- package/src/persistence/jobs-store.ts +32 -8
- package/src/persistence/llm-usage-store.ts +22 -0
- package/src/persistence/migrations/361-normalize-managed-connection-rows.test.ts +168 -0
- package/src/persistence/migrations/361-normalize-managed-connection-rows.ts +76 -0
- package/src/persistence/migrations/362-add-conversation-subagent-kind.test.ts +187 -0
- package/src/persistence/migrations/362-add-conversation-subagent-kind.ts +93 -0
- package/src/persistence/migrations/363-backfill-schedule-inference-profile.test.ts +229 -0
- package/src/persistence/migrations/363-backfill-schedule-inference-profile.ts +127 -0
- package/src/persistence/migrations/364-add-schedule-source-key.test.ts +120 -0
- package/src/persistence/migrations/364-add-schedule-source-key.ts +43 -0
- package/src/persistence/migrations/365-add-conversation-fork-strategy.ts +27 -0
- package/src/persistence/schema/conversations.ts +32 -0
- package/src/persistence/schema/infrastructure.ts +3 -0
- package/src/persistence/steps.ts +30 -0
- package/src/persistence/subagent-store.ts +148 -6
- package/src/platform/managed-speech.test.ts +20 -0
- package/src/platform/managed-speech.ts +9 -0
- package/src/plugin-api/index.ts +8 -0
- package/src/plugin-api/webhook-url.ts +151 -0
- package/src/plugins/__tests__/installed-plugin-dirs.test.ts +82 -0
- package/src/plugins/__tests__/source-fingerprint.test.ts +5 -1
- package/src/plugins/collect-source-versions.ts +4 -27
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +5 -5
- package/src/plugins/defaults/exploration-drift/package.json +1 -1
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +4 -2
- package/src/plugins/defaults/image-recovery/recover.ts +67 -57
- package/src/plugins/defaults/index.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +64 -18
- package/src/plugins/defaults/memory/__tests__/jobs-worker-outcome-contract.test.ts +242 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-retrospective-sweep.test.ts +24 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +48 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +511 -19
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +39 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +493 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +5 -4
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +5 -1
- package/src/plugins/defaults/memory/job-handlers.ts +87 -5
- package/src/plugins/defaults/memory/jobs-worker.ts +60 -6
- package/src/plugins/defaults/memory/memory-retrospective-constants.ts +11 -0
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +29 -0
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +342 -60
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +23 -3
- package/src/plugins/defaults/memory/substrate/consolidation-lock.ts +9 -4
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +7 -0
- package/src/plugins/defaults/memory/v1/graph/injection.ts +1 -1
- package/src/plugins/defaults/memory/v2/router.ts +8 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +1 -2
- package/src/plugins/external-plugin-loader.ts +17 -8
- package/src/plugins/installed-plugin-dirs.ts +101 -0
- package/src/plugins/mtime-cache.ts +34 -22
- package/src/plugins/types.ts +69 -8
- package/src/prompts/persona-resolver.ts +6 -2
- package/src/prompts/system-prompt.ts +72 -17
- package/src/providers/__tests__/inference.test.ts +40 -0
- package/src/providers/__tests__/preflight-resolved-config.test.ts +58 -1
- package/src/providers/__tests__/retry-callsite.test.ts +67 -0
- package/src/providers/__tests__/vellum-connection-routing.test.ts +42 -11
- package/src/providers/anthropic/client.ts +112 -95
- package/src/providers/connection-resolution.ts +35 -1
- package/src/providers/gemini/client.ts +5 -5
- package/src/providers/inference/adapter-factory.ts +16 -10
- package/src/providers/inference/auth.ts +16 -0
- package/src/providers/inference/connection-availability.ts +164 -12
- package/src/providers/inference/connections.ts +25 -1
- package/src/providers/media-resolve.ts +21 -11
- package/src/providers/model-catalog.ts +15 -0
- package/src/providers/openai/chat-completions-provider.ts +4 -4
- package/src/providers/openai/responses-provider.ts +12 -25
- package/src/providers/registry.ts +9 -4
- package/src/providers/retry.ts +25 -0
- package/src/providers/server-tool-pairing.ts +134 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +187 -6
- package/src/providers/speech-to-text/deepgram.ts +1 -0
- package/src/providers/speech-to-text/resolve.ts +80 -10
- package/src/providers/speech-to-text/vellum-managed.ts +7 -1
- package/src/providers/speech-to-text/vellum-speech-relay-connection.ts +3 -1
- package/src/providers/types.ts +26 -6
- package/src/providers/vellum-model-routing.ts +6 -7
- package/src/runtime/AGENTS.md +2 -0
- package/src/runtime/__tests__/agent-wake.test.ts +16 -16
- package/src/runtime/__tests__/background-job-runner.test.ts +0 -144
- package/src/runtime/__tests__/desktop-presence.test.ts +162 -0
- package/src/runtime/agent-wake.ts +63 -24
- package/src/runtime/assistant-event-hub.ts +87 -12
- package/src/runtime/auth/__tests__/guard-tests.test.ts +2 -0
- package/src/runtime/auth/__tests__/scopes.test.ts +20 -0
- package/src/runtime/auth/same-actor.ts +56 -8
- package/src/runtime/auth/scopes.ts +12 -0
- package/src/runtime/auth/types.ts +2 -0
- package/src/runtime/background-job-runner.ts +5 -27
- package/src/runtime/channel-readiness-service.ts +59 -3
- package/src/runtime/channel-readiness-types.ts +18 -0
- package/src/runtime/desktop-presence.ts +69 -0
- package/src/runtime/http-server.ts +12 -0
- package/src/runtime/local-actor-identity.ts +11 -9
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/client-routes.test.ts +186 -14
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +547 -1
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +162 -7
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +14 -10
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +340 -3
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +28 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +173 -1
- package/src/runtime/routes/__tests__/question-routes.test.ts +64 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +20 -0
- package/src/runtime/routes/__tests__/skill-history-route.test.ts +116 -0
- package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +60 -2
- package/src/runtime/routes/archive-utils.ts +16 -12
- package/src/runtime/routes/attachment-routes.ts +13 -6
- package/src/runtime/routes/canned-reply-release.ts +54 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -27
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +5 -0
- package/src/runtime/routes/client-routes.ts +114 -2
- package/src/runtime/routes/conversation-cli-routes.ts +10 -12
- package/src/runtime/routes/conversation-list-routes.ts +59 -10
- package/src/runtime/routes/conversation-management-routes.ts +47 -18
- package/src/runtime/routes/conversation-query-routes.ts +32 -53
- package/src/runtime/routes/conversation-routes.ts +350 -293
- package/src/runtime/routes/credential-prompt-routes.ts +23 -2
- package/src/runtime/routes/debug-routes.ts +4 -1
- package/src/runtime/routes/default-provider-routes.ts +7 -11
- package/src/runtime/routes/documents-routes.ts +44 -1
- package/src/runtime/routes/events-routes.ts +28 -1
- package/src/runtime/routes/host-app-control-routes.ts +2 -0
- package/src/runtime/routes/host-bash-routes.ts +2 -0
- package/src/runtime/routes/host-browser-routes.ts +2 -0
- package/src/runtime/routes/host-cu-routes.ts +2 -0
- package/src/runtime/routes/host-file-routes.ts +2 -0
- package/src/runtime/routes/host-transfer-routes.ts +4 -0
- package/src/runtime/routes/identity-routes.ts +6 -6
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +7 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +14 -0
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +14 -11
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -17
- package/src/runtime/routes/inference-profile-availability-guard.ts +171 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +26 -2
- package/src/runtime/routes/inference-profile-session-routes.ts +2 -1
- package/src/runtime/routes/inference-profiles-routes.ts +152 -73
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -16
- package/src/runtime/routes/llm-call-sites-routes.ts +13 -0
- package/src/runtime/routes/log-export-routes.ts +1 -1
- package/src/runtime/routes/notification-routes.ts +0 -14
- package/src/runtime/routes/oauth-providers.ts +1 -0
- package/src/runtime/routes/plugins-routes.ts +106 -1
- package/src/runtime/routes/profiler-routes.ts +4 -2
- package/src/runtime/routes/question-routes.ts +28 -10
- package/src/runtime/routes/retrospective-routes.ts +9 -3
- package/src/runtime/routes/schedule-routes.ts +210 -12
- package/src/runtime/routes/secret-routes.ts +40 -23
- package/src/runtime/routes/settings-routes.ts +41 -13
- package/src/runtime/routes/skills-routes.ts +79 -0
- package/src/runtime/routes/ui-snapshot-routes.ts +1 -0
- package/src/runtime/routes/wake-conversation-routes.ts +23 -0
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +1 -0
- package/src/runtime/services/conversation-serializer.ts +24 -9
- package/src/runtime/sync/documents-sidecar-publish.test.ts +101 -0
- package/src/runtime/sync/resource-sync-events.ts +79 -1
- package/src/runtime/sync/worker-daemon-notify.test.ts +34 -0
- package/src/runtime/sync/worker-daemon-notify.ts +44 -6
- package/src/runtime/verification-outbound-actions.ts +250 -222
- package/src/runtime/verification-templates.ts +41 -30
- package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +614 -0
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1066 -0
- package/src/schedule/inference-profile.ts +64 -3
- package/src/schedule/plugin-schedule-declarations.ts +518 -0
- package/src/schedule/plugin-schedule-reconciler.ts +605 -0
- package/src/schedule/plugin-schedules-gate.ts +23 -0
- package/src/schedule/schedule-store.ts +520 -26
- package/src/schedule/scheduler.ts +38 -0
- package/src/security/credential-backend.ts +51 -4
- package/src/security/encrypted-store.ts +64 -42
- package/src/security/secure-keys.ts +55 -7
- package/src/skills/catalog-install.ts +20 -7
- package/src/skills/inline-command-runner.ts +2 -7
- package/src/skills/skill-history.test.ts +269 -0
- package/src/skills/skill-history.ts +250 -0
- package/src/skills/skillssh-registry.ts +1 -1
- package/src/stt/daemon-batch-transcriber.ts +8 -6
- package/src/subagent/__tests__/consult-prompt.test.ts +25 -0
- package/src/subagent/consult-prompt.ts +3 -1
- package/src/subagent/consult-transcript.ts +1 -1
- package/src/subagent/manager.ts +295 -42
- package/src/subagent/progress-events.ts +35 -0
- package/src/subagent/role-resolution.ts +88 -0
- package/src/subagent/types.ts +302 -67
- package/src/subagent/validate-allowlists.ts +3 -4
- package/src/telegram/__tests__/webhook-health.test.ts +73 -1
- package/src/telegram/webhook-health.ts +101 -3
- package/src/telemetry/__tests__/telemetry-event-fixtures.ts +2 -0
- package/src/telemetry/activation-funnel.ts +6 -1
- package/src/telemetry/live-voice-funnel.ts +75 -0
- package/src/telemetry/telemetry-event-sources.ts +6 -0
- package/src/telemetry/telemetry-wire-source.json +1 -1
- package/src/telemetry/telemetry-wire.generated.ts +2 -0
- package/src/telemetry/types.ts +23 -4
- package/src/telemetry/usage-telemetry-reporter.test.ts +4 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +1 -1
- package/src/tools/ask-question/ask-question-tool.test.ts +118 -3
- package/src/tools/ask-question/ask-question-tool.ts +56 -2
- package/src/tools/browser/browser-execution.ts +1 -1
- package/src/tools/calls/call-start.ts +8 -5
- package/src/tools/conversation-groups/move_to_group.ts +10 -12
- package/src/tools/document/document-tool.ts +11 -4
- package/src/tools/executor.ts +7 -6
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +7 -13
- package/src/tools/filesystem/search.ts +23 -21
- package/src/tools/filesystem/write.ts +4 -1
- package/src/tools/host-filesystem/edit.ts +7 -2
- package/src/tools/host-filesystem/read.ts +21 -8
- package/src/tools/host-filesystem/write.ts +10 -2
- package/src/tools/host-terminal/host-shell.ts +2 -2
- package/src/tools/mcp/mcp-tool-factory.ts +25 -1
- package/src/tools/permission-checker.ts +8 -3
- package/src/tools/schedule/delete.ts +13 -1
- package/src/tools/schedule/list.ts +14 -3
- package/src/tools/schedule/update.ts +56 -33
- package/src/tools/shared/filesystem/audio-read.ts +6 -4
- package/src/tools/shared/filesystem/file-ops-service.ts +176 -116
- package/src/tools/shared/filesystem/image-read.ts +12 -12
- package/src/tools/shared/filesystem/path-policy.ts +70 -5
- package/src/tools/shared/filesystem/size-guard.ts +6 -6
- package/src/tools/shared/input-misuse.ts +72 -0
- package/src/tools/skills/scaffold-managed.ts +82 -0
- package/src/tools/skills/skill-tool-factory.ts +14 -1
- package/src/tools/subagent/consult-deadline.ts +12 -7
- package/src/tools/subagent/message.ts +3 -1
- package/src/tools/subagent/read.ts +66 -4
- package/src/tools/subagent/spawn.ts +500 -78
- package/src/tools/types.ts +22 -3
- package/src/tools/ui-surface/surface-shape-docs.ts +1 -1
- package/src/tools/ui-surface/visual-validation.ts +2 -0
- package/src/usage/__tests__/subagent-attribution.test.ts +109 -0
- package/src/usage/subagent-attribution.ts +108 -0
- package/src/util/__tests__/sqlite-retry.test.ts +112 -0
- package/src/util/abort-reasons.ts +16 -0
- package/src/util/ansi.ts +44 -0
- package/src/util/disk-usage.ts +17 -13
- package/src/util/image-conversion.ts +20 -13
- package/src/util/schedule-source-key.ts +23 -0
- package/src/util/worker-process.ts +7 -1
- package/src/workspace/git-service.ts +33 -9
- package/src/workspace/migrations/140-repair-seed-pinned-memory-v3-live.ts +260 -0
- package/src/workspace/migrations/141-stt-english-default-to-multilingual.ts +111 -0
- package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +126 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/workspace/top-level-renderer.ts +15 -2
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +0 -357
- package/src/daemon/install-symlink.ts +0 -207
- package/src/notifications/deferred-emit.ts +0 -147
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
addMessage,
|
|
27
27
|
isEchoSuppressedUserMessage,
|
|
28
28
|
isHiddenMessageMetadata,
|
|
29
|
+
isSuppressedQueuedMessage,
|
|
29
30
|
provenanceFromTrustContext,
|
|
30
31
|
recordConversationPersistedSeq,
|
|
31
32
|
setConversationOriginChannelIfUnset,
|
|
@@ -285,9 +286,9 @@ async function buildPassthroughBatch(
|
|
|
285
286
|
break;
|
|
286
287
|
}
|
|
287
288
|
// The batched turn applies only the head's `clientOs`, so messages from a
|
|
288
|
-
// different OS surface must not coalesce.
|
|
289
|
+
// different OS surface must not coalesce. Browser, mobile, and desktop apps
|
|
289
290
|
// report `interfaceId: "web"`, so the interface check above no longer
|
|
290
|
-
// separates them
|
|
291
|
+
// separates them, so split on the reported OS explicitly.
|
|
291
292
|
if (candidate.transport?.clientOs !== head.transport?.clientOs) {
|
|
292
293
|
break;
|
|
293
294
|
}
|
|
@@ -324,10 +325,11 @@ async function buildPassthroughBatch(
|
|
|
324
325
|
return conversation.queue.shiftN(matched);
|
|
325
326
|
}
|
|
326
327
|
|
|
327
|
-
// ── Steer repair
|
|
328
|
+
// ── Steer / interrupt repair ────────────────────────────────────────
|
|
328
329
|
|
|
329
330
|
/**
|
|
330
|
-
* When a steer-to-message abort
|
|
331
|
+
* When a steer-to-message abort (or a user interrupt with messages still
|
|
332
|
+
* queued behind the stopped turn) cuts off an in-flight tool call, the
|
|
331
333
|
* conversation history may end with an assistant message containing one
|
|
332
334
|
* or more `tool_use` blocks that have no corresponding `tool_result`.
|
|
333
335
|
* LLM providers reject this sequence. This helper scans the tail of the
|
|
@@ -335,10 +337,12 @@ async function buildPassthroughBatch(
|
|
|
335
337
|
* unmatched `tool_use` blocks.
|
|
336
338
|
*/
|
|
337
339
|
function repairPendingToolUseBlocks(conversation: Conversation): void {
|
|
338
|
-
|
|
340
|
+
const steered = conversation.pendingSteerRepair;
|
|
341
|
+
if (!steered && !conversation.pendingInterruptRepair) {
|
|
339
342
|
return;
|
|
340
343
|
}
|
|
341
344
|
conversation.pendingSteerRepair = false;
|
|
345
|
+
conversation.pendingInterruptRepair = false;
|
|
342
346
|
|
|
343
347
|
const messages = conversation.messages;
|
|
344
348
|
if (messages.length === 0) {
|
|
@@ -381,15 +385,18 @@ function repairPendingToolUseBlocks(conversation: Conversation): void {
|
|
|
381
385
|
{
|
|
382
386
|
conversationId: conversation.conversationId,
|
|
383
387
|
pendingToolUseCount: pendingToolUseIds.length,
|
|
388
|
+
trigger: steered ? "steer" : "interrupt",
|
|
384
389
|
},
|
|
385
|
-
"Injecting synthetic tool_result for pending tool_use blocks
|
|
390
|
+
"Injecting synthetic tool_result for pending tool_use blocks",
|
|
386
391
|
);
|
|
387
392
|
|
|
388
393
|
// Build a single user message with tool_result blocks for all pending IDs.
|
|
389
394
|
const syntheticContent = pendingToolUseIds.map((toolUseId) => ({
|
|
390
395
|
type: "tool_result" as const,
|
|
391
396
|
tool_use_id: toolUseId,
|
|
392
|
-
content:
|
|
397
|
+
content: steered
|
|
398
|
+
? "Tool execution was interrupted by user steering."
|
|
399
|
+
: "Tool execution was interrupted by the user.",
|
|
393
400
|
is_error: true,
|
|
394
401
|
}));
|
|
395
402
|
conversation.messages.push({
|
|
@@ -405,11 +412,23 @@ function repairPendingToolUseBlocks(conversation: Conversation): void {
|
|
|
405
412
|
* we did. The flag is what makes the requeue paths able to distinguish a
|
|
406
413
|
* message clients still believe is running from one they never stopped
|
|
407
414
|
* showing as queued. See {@link requeueDrainedMessages}.
|
|
415
|
+
*
|
|
416
|
+
* Queue events come in pairs. A row with no client-visible queued counterpart
|
|
417
|
+
* ({@link isSuppressedQueuedMessage} — hidden sends and the daemon-injected
|
|
418
|
+
* subagent/ACP/wake notifications) never produced a `message_queued` ack, so
|
|
419
|
+
* releasing one produces no dequeue either: an unpaired dequeue would retire a
|
|
420
|
+
* client's counter entry for a message that is still waiting. Nothing was
|
|
421
|
+
* announced, so the flag stays false and the requeue paths correctly send
|
|
422
|
+
* nothing for it. The activity-state transition callers emit alongside this is
|
|
423
|
+
* unrelated to the queue and always fires: the turn really is starting.
|
|
408
424
|
*/
|
|
409
425
|
function announceDequeue(
|
|
410
426
|
conversation: Conversation,
|
|
411
427
|
message: QueuedMessage,
|
|
412
428
|
): void {
|
|
429
|
+
if (isSuppressedQueuedMessage(message.metadata)) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
413
432
|
message.onEvent({
|
|
414
433
|
type: "message_dequeued",
|
|
415
434
|
conversationId: conversation.conversationId,
|
|
@@ -434,7 +453,7 @@ function visibleQueuePosition(
|
|
|
434
453
|
): number | undefined {
|
|
435
454
|
let position = 0;
|
|
436
455
|
for (const item of conversation.queue.snapshot()) {
|
|
437
|
-
if (
|
|
456
|
+
if (isSuppressedQueuedMessage(item.metadata)) {
|
|
438
457
|
continue;
|
|
439
458
|
}
|
|
440
459
|
position += 1;
|
|
@@ -460,8 +479,10 @@ function visibleQueuePosition(
|
|
|
460
479
|
* `message_dequeued` and would otherwise see the row vanish until a later
|
|
461
480
|
* drain. Messages requeued before the announcement (the pre-flight
|
|
462
481
|
* processing-lock checks) get nothing, because clients never stopped showing
|
|
463
|
-
* them as queued and an event there would be noise.
|
|
464
|
-
*
|
|
482
|
+
* them as queued and an event there would be noise. Rows with no client-visible
|
|
483
|
+
* queued counterpart ({@link isSuppressedQueuedMessage} — hidden sends and
|
|
484
|
+
* daemon-injected subagent/ACP/wake notifications) are suppressed for the same
|
|
485
|
+
* reason they get no queued ack: they have no client row.
|
|
465
486
|
*/
|
|
466
487
|
function requeueDrainedMessages(
|
|
467
488
|
conversation: Conversation,
|
|
@@ -488,7 +509,7 @@ function requeueDrainedMessages(
|
|
|
488
509
|
continue;
|
|
489
510
|
}
|
|
490
511
|
message.dequeueAnnounced = false;
|
|
491
|
-
if (
|
|
512
|
+
if (isSuppressedQueuedMessage(message.metadata)) {
|
|
492
513
|
continue;
|
|
493
514
|
}
|
|
494
515
|
const position = visibleQueuePosition(conversation, message.requestId);
|
|
@@ -653,7 +674,15 @@ export async function kickQueueDrain(
|
|
|
653
674
|
},
|
|
654
675
|
"drainQueue retry rejected; queued messages remain stranded until the next drain trigger",
|
|
655
676
|
);
|
|
656
|
-
|
|
677
|
+
// Only the sends a user is waiting on get the failure notice. A stranded
|
|
678
|
+
// row with no client-visible queued counterpart (hidden machine signal,
|
|
679
|
+
// daemon-injected subagent/ACP/wake notification) has no queued bubble to
|
|
680
|
+
// explain, so a "your queued message" error would describe something the
|
|
681
|
+
// user never sent.
|
|
682
|
+
const strandedVisible = conversation.queue
|
|
683
|
+
.snapshot()
|
|
684
|
+
.filter((queued) => !isSuppressedQueuedMessage(queued.metadata));
|
|
685
|
+
for (const queued of strandedVisible) {
|
|
657
686
|
queued.onEvent({
|
|
658
687
|
type: "error",
|
|
659
688
|
conversationId: conversation.conversationId,
|
|
@@ -813,7 +842,10 @@ async function drainSingleMessage(
|
|
|
813
842
|
: {}),
|
|
814
843
|
sentAt: next.sentAt,
|
|
815
844
|
};
|
|
816
|
-
const cleanUserMsg = createUserMessage(
|
|
845
|
+
const cleanUserMsg = await createUserMessage(
|
|
846
|
+
next.content,
|
|
847
|
+
next.attachments,
|
|
848
|
+
);
|
|
817
849
|
const llmUserMsg = enrichMessageWithSourcePaths(
|
|
818
850
|
cleanUserMsg,
|
|
819
851
|
next.attachments,
|
|
@@ -821,7 +853,7 @@ async function drainSingleMessage(
|
|
|
821
853
|
// When displayContent is provided (e.g. original text before recording
|
|
822
854
|
// intent stripping), persist that to DB so users see the full message.
|
|
823
855
|
// The in-memory userMessage (sent to the LLM) still uses the stripped content.
|
|
824
|
-
const contentToPersist = serializePersistedUserMessageContent(
|
|
856
|
+
const contentToPersist = await serializePersistedUserMessageContent(
|
|
825
857
|
next.content,
|
|
826
858
|
next.displayContent,
|
|
827
859
|
next.attachments,
|
|
@@ -913,11 +945,14 @@ async function drainSingleMessage(
|
|
|
913
945
|
: {}),
|
|
914
946
|
sentAt: next.sentAt,
|
|
915
947
|
};
|
|
916
|
-
const cleanUserMsg = createUserMessage(
|
|
948
|
+
const cleanUserMsg = await createUserMessage(
|
|
949
|
+
next.content,
|
|
950
|
+
next.attachments,
|
|
951
|
+
);
|
|
917
952
|
await addMessage(
|
|
918
953
|
conversation.conversationId,
|
|
919
954
|
"user",
|
|
920
|
-
serializePersistedUserMessageContent(
|
|
955
|
+
await serializePersistedUserMessageContent(
|
|
921
956
|
next.content,
|
|
922
957
|
next.displayContent,
|
|
923
958
|
next.attachments,
|
|
@@ -1003,11 +1038,14 @@ async function drainSingleMessage(
|
|
|
1003
1038
|
: {}),
|
|
1004
1039
|
sentAt: next.sentAt,
|
|
1005
1040
|
};
|
|
1006
|
-
const cleanUserMsg = createUserMessage(
|
|
1041
|
+
const cleanUserMsg = await createUserMessage(
|
|
1042
|
+
next.content,
|
|
1043
|
+
next.attachments,
|
|
1044
|
+
);
|
|
1007
1045
|
await addMessage(
|
|
1008
1046
|
conversation.conversationId,
|
|
1009
1047
|
"user",
|
|
1010
|
-
serializePersistedUserMessageContent(
|
|
1048
|
+
await serializePersistedUserMessageContent(
|
|
1011
1049
|
next.content,
|
|
1012
1050
|
next.displayContent,
|
|
1013
1051
|
next.attachments,
|
|
@@ -1097,6 +1135,9 @@ async function drainSingleMessage(
|
|
|
1097
1135
|
metadata: { ...next.metadata, sentAt: next.sentAt },
|
|
1098
1136
|
displayContent: next.displayContent,
|
|
1099
1137
|
clientMessageId: next.clientMessageId,
|
|
1138
|
+
...(next.transport?.clientOs
|
|
1139
|
+
? { requestClientOs: next.transport.clientOs }
|
|
1140
|
+
: {}),
|
|
1100
1141
|
});
|
|
1101
1142
|
} catch (err) {
|
|
1102
1143
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -1447,6 +1488,9 @@ async function drainBatch(
|
|
|
1447
1488
|
metadata: { ...qm.metadata, sentAt: qm.sentAt },
|
|
1448
1489
|
displayContent: qm.displayContent,
|
|
1449
1490
|
clientMessageId: qm.clientMessageId,
|
|
1491
|
+
...(qm.transport?.clientOs
|
|
1492
|
+
? { requestClientOs: qm.transport.clientOs }
|
|
1493
|
+
: {}),
|
|
1450
1494
|
};
|
|
1451
1495
|
if (i === 0) {
|
|
1452
1496
|
batchPersistResult =
|
|
@@ -1873,7 +1917,7 @@ export async function processMessage(
|
|
|
1873
1917
|
: {}),
|
|
1874
1918
|
};
|
|
1875
1919
|
|
|
1876
|
-
const cleanUserMsg = createUserMessage(content, attachments);
|
|
1920
|
+
const cleanUserMsg = await createUserMessage(content, attachments);
|
|
1877
1921
|
const llmUserMsg = enrichMessageWithSourcePaths(
|
|
1878
1922
|
cleanUserMsg,
|
|
1879
1923
|
attachments,
|
|
@@ -1881,7 +1925,7 @@ export async function processMessage(
|
|
|
1881
1925
|
const persisted = await addMessage(
|
|
1882
1926
|
conversation.conversationId,
|
|
1883
1927
|
"user",
|
|
1884
|
-
serializePersistedUserMessageContent(
|
|
1928
|
+
await serializePersistedUserMessageContent(
|
|
1885
1929
|
content,
|
|
1886
1930
|
displayContent,
|
|
1887
1931
|
attachments,
|
|
@@ -1965,12 +2009,12 @@ export async function processMessage(
|
|
|
1965
2009
|
? { imageSourcePaths: pmImageSourcePaths }
|
|
1966
2010
|
: {}),
|
|
1967
2011
|
};
|
|
1968
|
-
const cleanUserMsg = createUserMessage(content, attachments);
|
|
2012
|
+
const cleanUserMsg = await createUserMessage(content, attachments);
|
|
1969
2013
|
const llmUserMsg = enrichMessageWithSourcePaths(cleanUserMsg, attachments);
|
|
1970
2014
|
// When displayContent is provided (e.g. original text before recording
|
|
1971
2015
|
// intent stripping), persist that to DB so users see the full message.
|
|
1972
2016
|
// The in-memory userMessage (sent to the LLM) still uses the stripped content.
|
|
1973
|
-
const contentToPersist = serializePersistedUserMessageContent(
|
|
2017
|
+
const contentToPersist = await serializePersistedUserMessageContent(
|
|
1974
2018
|
content,
|
|
1975
2019
|
displayContent,
|
|
1976
2020
|
attachments,
|
|
@@ -2049,11 +2093,11 @@ export async function processMessage(
|
|
|
2049
2093
|
}
|
|
2050
2094
|
: {}),
|
|
2051
2095
|
};
|
|
2052
|
-
const cleanUserMsg = createUserMessage(content, attachments);
|
|
2096
|
+
const cleanUserMsg = await createUserMessage(content, attachments);
|
|
2053
2097
|
const persisted = await addMessage(
|
|
2054
2098
|
conversation.conversationId,
|
|
2055
2099
|
"user",
|
|
2056
|
-
serializePersistedUserMessageContent(
|
|
2100
|
+
await serializePersistedUserMessageContent(
|
|
2057
2101
|
content,
|
|
2058
2102
|
displayContent,
|
|
2059
2103
|
attachments,
|
|
@@ -2097,7 +2141,10 @@ export async function processMessage(
|
|
|
2097
2141
|
throw err;
|
|
2098
2142
|
} finally {
|
|
2099
2143
|
conversation.setProcessing(false);
|
|
2100
|
-
|
|
2144
|
+
// `kickQueueDrain` never rejects, so a failed drain in this `finally`
|
|
2145
|
+
// cannot mask the error the try block is unwinding, and its retry plus
|
|
2146
|
+
// sender notification replace a silently stranded queue.
|
|
2147
|
+
await kickQueueDrain(conversation, "loop_complete", "compact_command");
|
|
2101
2148
|
}
|
|
2102
2149
|
}
|
|
2103
2150
|
|
|
@@ -2127,11 +2174,11 @@ export async function processMessage(
|
|
|
2127
2174
|
}
|
|
2128
2175
|
: {}),
|
|
2129
2176
|
};
|
|
2130
|
-
const cleanUserMsg = createUserMessage(content, attachments);
|
|
2177
|
+
const cleanUserMsg = await createUserMessage(content, attachments);
|
|
2131
2178
|
const persisted = await addMessage(
|
|
2132
2179
|
conversation.conversationId,
|
|
2133
2180
|
"user",
|
|
2134
|
-
serializePersistedUserMessageContent(
|
|
2181
|
+
await serializePersistedUserMessageContent(
|
|
2135
2182
|
content,
|
|
2136
2183
|
displayContent,
|
|
2137
2184
|
attachments,
|
|
@@ -2171,7 +2218,8 @@ export async function processMessage(
|
|
|
2171
2218
|
throw err;
|
|
2172
2219
|
} finally {
|
|
2173
2220
|
conversation.setProcessing(false);
|
|
2174
|
-
|
|
2221
|
+
// Same never-rejecting drain as the `/compact` branch above.
|
|
2222
|
+
await kickQueueDrain(conversation, "loop_complete", "clean_command");
|
|
2175
2223
|
}
|
|
2176
2224
|
}
|
|
2177
2225
|
|
|
@@ -451,12 +451,18 @@ export function buildActiveDocuments(conversationId: string): Array<{
|
|
|
451
451
|
* the readable handle is its `slug` (the directory stem, frozen at creation).
|
|
452
452
|
* The app tools key off the id, so the line carries it for tool calls and the
|
|
453
453
|
* slug for everything a human or the model would recognize.
|
|
454
|
+
*
|
|
455
|
+
* The resolved directory is not part of the returned shape. A workspace app's
|
|
456
|
+
* files are reachable by joining the workspace `Root:` from the `<workspace>`
|
|
457
|
+
* block with the app-builder skill's `data/apps/<slug>/` layout and the slug
|
|
458
|
+
* above. A plugin-bundled app's files sit outside that layout and belong to
|
|
459
|
+
* the plugin, which the provenance clause marks as not the assistant's to
|
|
460
|
+
* rewrite, so no path is offered for them either.
|
|
454
461
|
*/
|
|
455
462
|
export function buildVisibleAppContext(appId: string | undefined): {
|
|
456
463
|
appId: string;
|
|
457
464
|
name: string;
|
|
458
465
|
slug: string;
|
|
459
|
-
sourceDir: string;
|
|
460
466
|
pluginName?: string;
|
|
461
467
|
} | null {
|
|
462
468
|
if (!appId) {
|
|
@@ -471,7 +477,6 @@ export function buildVisibleAppContext(appId: string | undefined): {
|
|
|
471
477
|
appId: source.id,
|
|
472
478
|
name: source.name,
|
|
473
479
|
slug: source.dirName,
|
|
474
|
-
sourceDir: source.sourceDir,
|
|
475
480
|
...(source.origin.kind === "plugin"
|
|
476
481
|
? { pluginName: source.origin.pluginName }
|
|
477
482
|
: {}),
|
|
@@ -2239,10 +2244,10 @@ export async function applyRuntimeInjections(
|
|
|
2239
2244
|
: undefined;
|
|
2240
2245
|
// OS surface reported by the client, independent of the transport interface
|
|
2241
2246
|
// above. Drives the per-turn `client_os:` line so the model knows whether it
|
|
2242
|
-
// is talking to
|
|
2247
|
+
// is talking to a browser, mobile, or desktop app (all sharing the `"web"`
|
|
2243
2248
|
// transport interface). Read the frozen per-turn snapshot (not the live
|
|
2244
2249
|
// `clientOs`) so a queued message from another surface can't perturb the
|
|
2245
|
-
// in-flight turn
|
|
2250
|
+
// in-flight turn, using the same anti-race pattern as `clientTimezone`.
|
|
2246
2251
|
const clientOs = liveConversation?.currentTurnClientOs ?? undefined;
|
|
2247
2252
|
// The app the client has on screen (app viewer or the app-editing split),
|
|
2248
2253
|
// resolved to its name and source directory so the assistant can act on it
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
ensureConversationExists,
|
|
20
20
|
getConversation,
|
|
21
21
|
} from "../persistence/conversation-crud.js";
|
|
22
|
+
import type { ConversationOrigin } from "../persistence/conversation-types.js";
|
|
22
23
|
import { wrapWithCallSiteRouting } from "../providers/call-site-routing.js";
|
|
23
24
|
import {
|
|
24
25
|
mainAgentResolutionError,
|
|
@@ -51,6 +52,37 @@ import { buildTransportHints } from "./transport-hints.js";
|
|
|
51
52
|
|
|
52
53
|
const conversationOptions = new Map<string, ConversationCreateOptions>();
|
|
53
54
|
|
|
55
|
+
/**
|
|
56
|
+
* The channel a conversation created here belongs to.
|
|
57
|
+
*
|
|
58
|
+
* A trust context is stamped per inbound message from the gateway verdict,
|
|
59
|
+
* so `sourceChannel` names the channel the message creating this
|
|
60
|
+
* conversation actually arrived on. This is the moment that fact is known,
|
|
61
|
+
* and the caller is the only party that holds it.
|
|
62
|
+
*
|
|
63
|
+
* Returns `undefined` when there is no trust context, which does NOT mean
|
|
64
|
+
* native. `handleSendMessage` materializes a conversation before the route
|
|
65
|
+
* resolves trust, so a Slack or phone send reaches here with no
|
|
66
|
+
* `sourceChannel` yet. Assuming native there would stamp a remote
|
|
67
|
+
* conversation as the guardian's own, and nothing could repair it:
|
|
68
|
+
* `setConversationOriginChannelIfUnset` only writes over NULL, and
|
|
69
|
+
* `recoverRestingTrustContext` grants INTERNAL_GUARDIAN_TRUST_CONTEXT to the
|
|
70
|
+
* native channel on every later wake and boot-resume.
|
|
71
|
+
*
|
|
72
|
+
* `transport.channelId` is not a substitute. It is the external Slack
|
|
73
|
+
* conversation id, not a {@link ChannelId}.
|
|
74
|
+
*
|
|
75
|
+
* So this states the origin only where it is genuinely known, and leaves the
|
|
76
|
+
* rest to attribution exactly as before. The remaining callers get their
|
|
77
|
+
* origin when they are migrated with real knowledge of it, not by guessing
|
|
78
|
+
* here.
|
|
79
|
+
*/
|
|
80
|
+
function originFromStoredOptions(
|
|
81
|
+
storedOptions: ConversationCreateOptions | undefined,
|
|
82
|
+
): ConversationOrigin | undefined {
|
|
83
|
+
return storedOptions?.trustContext?.sourceChannel;
|
|
84
|
+
}
|
|
85
|
+
|
|
54
86
|
/**
|
|
55
87
|
* Drops the transport fields that describe what the client had on screen for a
|
|
56
88
|
* single message rather than for the conversation as a whole.
|
|
@@ -141,9 +173,17 @@ export async function getOrCreateConversation(
|
|
|
141
173
|
);
|
|
142
174
|
}
|
|
143
175
|
|
|
176
|
+
// A stale conversation is rebuilt only once it is genuinely idle. Queued
|
|
177
|
+
// messages live in memory on the instance being disposed, and the queue
|
|
178
|
+
// drains via an async dispatch after the current turn releases, so
|
|
179
|
+
// `isProcessing()` can read false while a queued turn is still pending:
|
|
180
|
+
// rebuilding in that gap would silently drop those messages. The conversation
|
|
181
|
+
// stays stale and is rebuilt on a later call.
|
|
144
182
|
if (
|
|
145
183
|
!conversation ||
|
|
146
|
-
(conversation.isStale() &&
|
|
184
|
+
(conversation.isStale() &&
|
|
185
|
+
!conversation.isProcessing() &&
|
|
186
|
+
!conversation.hasQueuedMessages())
|
|
147
187
|
) {
|
|
148
188
|
if (conversation) {
|
|
149
189
|
// Stale rebuild: the conversation id lives on, so abort in-flight
|
|
@@ -229,9 +269,13 @@ export async function getOrCreateConversation(
|
|
|
229
269
|
createConversation({
|
|
230
270
|
id: conversationId,
|
|
231
271
|
conversationType: storedOptions.conversationType,
|
|
272
|
+
origin: originFromStoredOptions(storedOptions),
|
|
232
273
|
});
|
|
233
274
|
} else {
|
|
234
|
-
ensureConversationExists(
|
|
275
|
+
ensureConversationExists(
|
|
276
|
+
conversationId,
|
|
277
|
+
originFromStoredOptions(storedOptions),
|
|
278
|
+
);
|
|
235
279
|
}
|
|
236
280
|
}
|
|
237
281
|
|
|
@@ -353,7 +397,12 @@ export function clearAllActiveConversations(): number {
|
|
|
353
397
|
export function evictConversationsForReload(): void {
|
|
354
398
|
const subagentManager = getSubagentManager();
|
|
355
399
|
for (const [id, conversation] of conversationEntries()) {
|
|
356
|
-
|
|
400
|
+
// A conversation with queued messages is not idle: the queue drains via an
|
|
401
|
+
// async dispatch after the current turn releases, so `isProcessing()` can
|
|
402
|
+
// read false while a queued turn is still pending. Disposing in that gap
|
|
403
|
+
// would silently drop the queued messages, so mark it stale instead and
|
|
404
|
+
// let it rebuild once the queue has run.
|
|
405
|
+
if (!conversation.isProcessing() && !conversation.hasQueuedMessages()) {
|
|
357
406
|
subagentManager.abortAllForParent(id);
|
|
358
407
|
conversation.dispose();
|
|
359
408
|
deleteConversation(id);
|
|
@@ -76,6 +76,15 @@ export type CurrentTurnSurface = {
|
|
|
76
76
|
* to the client.
|
|
77
77
|
*/
|
|
78
78
|
activationMoment?: ActivationMomentParam;
|
|
79
|
+
/**
|
|
80
|
+
* Completion stamped when the user answers the surface before this turn's
|
|
81
|
+
* message lands. The snapshot is the only record of the surface at that
|
|
82
|
+
* point, so both persisted-content appenders carry these onto the
|
|
83
|
+
* `ui_surface` block they build; without them a reseed reactivates an
|
|
84
|
+
* already-answered card.
|
|
85
|
+
*/
|
|
86
|
+
completed?: boolean;
|
|
87
|
+
completionSummary?: string;
|
|
79
88
|
};
|
|
80
89
|
}[SurfaceType];
|
|
81
90
|
|