@vellumai/assistant 0.11.2 → 0.11.3-staging.2
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-process-app-control-preactivation.test.ts +123 -0
- package/src/__tests__/conversation-queue.test.ts +433 -1
- package/src/__tests__/conversation-retry-route.test.ts +3 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +64 -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-seed-logos.test.ts +65 -0
- 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-grant-request-escalation.test.ts +40 -1
- 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-inline-approval-integration.test.ts +68 -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 +222 -135
- 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/config/schemas/timeouts.ts +1 -1
- 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 +318 -148
- 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 +106 -43
- package/src/daemon/conversation-process.ts +131 -33
- package/src/daemon/conversation-queue-manager.ts +10 -0
- 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 +111 -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-types.ts +39 -0
- 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/AGENTS.md +4 -2
- 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 +62 -11
- 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 +360 -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 +304 -44
- 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/execution-timeout.ts +9 -2
- 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/tool-approval-handler.ts +45 -4
- 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
|
@@ -125,3 +125,102 @@ describe("CesProcessManager.onTransportClose", () => {
|
|
|
125
125
|
await pm.stop();
|
|
126
126
|
});
|
|
127
127
|
});
|
|
128
|
+
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Transport-death logging: WARN only for genuinely-unexpected death
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
|
|
133
|
+
type LogCall = { level: string; msg: string };
|
|
134
|
+
|
|
135
|
+
function makeRecordingLogger(): {
|
|
136
|
+
calls: LogCall[];
|
|
137
|
+
logger: NonNullable<Parameters<typeof createCesProcessManager>[0]["logger"]>;
|
|
138
|
+
} {
|
|
139
|
+
const calls: LogCall[] = [];
|
|
140
|
+
const rec =
|
|
141
|
+
(level: string) =>
|
|
142
|
+
(...args: unknown[]) => {
|
|
143
|
+
const msg = typeof args[0] === "string" ? args[0] : args[1];
|
|
144
|
+
calls.push({ level, msg: typeof msg === "string" ? msg : "" });
|
|
145
|
+
};
|
|
146
|
+
const logger = {
|
|
147
|
+
info: rec("info"),
|
|
148
|
+
warn: rec("warn"),
|
|
149
|
+
debug: rec("debug"),
|
|
150
|
+
error: rec("error"),
|
|
151
|
+
} as unknown as NonNullable<
|
|
152
|
+
Parameters<typeof createCesProcessManager>[0]["logger"]
|
|
153
|
+
>;
|
|
154
|
+
return { calls, logger };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
describe("CesProcessManager transport-death logging", () => {
|
|
158
|
+
let tempDir: string;
|
|
159
|
+
let server: Server;
|
|
160
|
+
let connections: Array<import("node:net").Socket>;
|
|
161
|
+
|
|
162
|
+
beforeEach(async () => {
|
|
163
|
+
tempDir = mkdtempSync(join(tmpdir(), "ces-pm-log-test-"));
|
|
164
|
+
mockSocketPath = join(tempDir, "ces.sock");
|
|
165
|
+
connections = [];
|
|
166
|
+
server = createServer((socket) => {
|
|
167
|
+
connections.push(socket);
|
|
168
|
+
socket.on("error", () => {});
|
|
169
|
+
});
|
|
170
|
+
await new Promise<void>((resolve) =>
|
|
171
|
+
server.listen(mockSocketPath, resolve),
|
|
172
|
+
);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
afterEach(async () => {
|
|
176
|
+
for (const sock of connections) {
|
|
177
|
+
sock.destroy();
|
|
178
|
+
}
|
|
179
|
+
connections = [];
|
|
180
|
+
await new Promise<void>((resolve) => server.close(() => resolve()));
|
|
181
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("logs WARN when the transport dies unexpectedly (remote close)", async () => {
|
|
185
|
+
const { calls, logger } = makeRecordingLogger();
|
|
186
|
+
const pm = createCesProcessManager({ logger });
|
|
187
|
+
const transport = await pm.start();
|
|
188
|
+
|
|
189
|
+
// The remote (server) closes the connection: genuinely-unexpected death.
|
|
190
|
+
for (const sock of connections) {
|
|
191
|
+
sock.destroy();
|
|
192
|
+
}
|
|
193
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
194
|
+
expect(transport.isAlive()).toBe(false);
|
|
195
|
+
|
|
196
|
+
expect(
|
|
197
|
+
calls.some(
|
|
198
|
+
(c) => c.level === "warn" && c.msg.includes("died unexpectedly"),
|
|
199
|
+
),
|
|
200
|
+
).toBe(true);
|
|
201
|
+
|
|
202
|
+
await pm.stop();
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test("does not log WARN on an intentional stop()", async () => {
|
|
206
|
+
const { calls, logger } = makeRecordingLogger();
|
|
207
|
+
const pm = createCesProcessManager({ logger });
|
|
208
|
+
await pm.start();
|
|
209
|
+
|
|
210
|
+
await pm.stop();
|
|
211
|
+
// Let the socket close event propagate after destroy().
|
|
212
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
213
|
+
|
|
214
|
+
expect(
|
|
215
|
+
calls.some(
|
|
216
|
+
(c) => c.level === "warn" && c.msg.includes("died unexpectedly"),
|
|
217
|
+
),
|
|
218
|
+
).toBe(false);
|
|
219
|
+
expect(
|
|
220
|
+
calls.some(
|
|
221
|
+
(c) =>
|
|
222
|
+
c.level === "debug" && c.msg.includes("CES socket transport closed"),
|
|
223
|
+
),
|
|
224
|
+
).toBe(true);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
@@ -29,6 +29,8 @@ import {
|
|
|
29
29
|
|
|
30
30
|
const log = getLogger("ces-process-manager");
|
|
31
31
|
|
|
32
|
+
type PmLogger = ReturnType<typeof getLogger>;
|
|
33
|
+
|
|
32
34
|
const SOCKET_CONNECT_TIMEOUT_MS = 5_000;
|
|
33
35
|
|
|
34
36
|
// ---------------------------------------------------------------------------
|
|
@@ -57,6 +59,9 @@ export interface CesProcessManagerConfig {
|
|
|
57
59
|
* Reserved for future feature-flag checks or config-driven behavior.
|
|
58
60
|
*/
|
|
59
61
|
assistantConfig?: AssistantConfig;
|
|
62
|
+
|
|
63
|
+
/** Logger override. Defaults to the module logger; injected in tests. */
|
|
64
|
+
logger?: PmLogger;
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
// ---------------------------------------------------------------------------
|
|
@@ -99,12 +104,13 @@ export interface CesProcessManager {
|
|
|
99
104
|
// ---------------------------------------------------------------------------
|
|
100
105
|
|
|
101
106
|
export function createCesProcessManager(
|
|
102
|
-
|
|
107
|
+
config: CesProcessManagerConfig,
|
|
103
108
|
): CesProcessManager {
|
|
109
|
+
const pmLog = config.logger ?? log;
|
|
104
110
|
let managedSocket: Socket | null = null;
|
|
105
111
|
let discoveryResult: DiscoveryResult | null = null;
|
|
106
112
|
let running = false;
|
|
107
|
-
let currentTransport:
|
|
113
|
+
let currentTransport: SocketTransport | null = null;
|
|
108
114
|
const transportCloseHandlers: Array<() => void> = [];
|
|
109
115
|
|
|
110
116
|
return {
|
|
@@ -136,24 +142,28 @@ export function createCesProcessManager(
|
|
|
136
142
|
}
|
|
137
143
|
|
|
138
144
|
if (managedSocket) {
|
|
145
|
+
// Mark the close as intentional so the transport-death log is debug,
|
|
146
|
+
// not a misleading WARN, on routine shutdown/reconnect.
|
|
147
|
+
currentTransport?.markClosing();
|
|
139
148
|
managedSocket.destroy();
|
|
140
149
|
managedSocket = null;
|
|
141
150
|
}
|
|
142
151
|
|
|
143
152
|
currentTransport = null;
|
|
144
153
|
running = false;
|
|
145
|
-
|
|
154
|
+
pmLog.info("CES process manager stopped");
|
|
146
155
|
},
|
|
147
156
|
|
|
148
157
|
async forceStop(): Promise<void> {
|
|
149
158
|
if (managedSocket) {
|
|
159
|
+
currentTransport?.markClosing();
|
|
150
160
|
managedSocket.destroy();
|
|
151
161
|
managedSocket = null;
|
|
152
162
|
}
|
|
153
163
|
|
|
154
164
|
currentTransport = null;
|
|
155
165
|
running = false;
|
|
156
|
-
|
|
166
|
+
pmLog.info("CES process manager force-stopped");
|
|
157
167
|
},
|
|
158
168
|
|
|
159
169
|
getDiscoveryResult(): DiscoveryResult | null {
|
|
@@ -195,8 +205,8 @@ export function createCesProcessManager(
|
|
|
195
205
|
|
|
196
206
|
async function connectManagedSocket(
|
|
197
207
|
discovery: ManagedDiscoverySuccess | SiblingDiscoverySuccess,
|
|
198
|
-
): Promise<
|
|
199
|
-
|
|
208
|
+
): Promise<SocketTransport> {
|
|
209
|
+
pmLog.info(
|
|
200
210
|
{ socketPath: discovery.socketPath, mode: discovery.mode },
|
|
201
211
|
"Connecting to CES over socket",
|
|
202
212
|
);
|
|
@@ -207,9 +217,14 @@ export function createCesProcessManager(
|
|
|
207
217
|
);
|
|
208
218
|
managedSocket = socket;
|
|
209
219
|
|
|
210
|
-
|
|
220
|
+
pmLog.info("Connected to CES over socket");
|
|
211
221
|
|
|
212
|
-
|
|
222
|
+
// Assign currentTransport synchronously here (no await between socket
|
|
223
|
+
// assignment and this line) so stop()/forceStop() can always mark an
|
|
224
|
+
// intentional close, even if they race the connect.
|
|
225
|
+
const transport = createSocketTransport(socket, pmLog);
|
|
226
|
+
currentTransport = transport;
|
|
227
|
+
return transport;
|
|
213
228
|
}
|
|
214
229
|
}
|
|
215
230
|
|
|
@@ -221,23 +236,43 @@ export function createCesProcessManager(
|
|
|
221
236
|
* Tracks the transport `alive` state and notifies registered handlers exactly
|
|
222
237
|
* once when the transport dies, so the RPC client can fail-fast any in-flight
|
|
223
238
|
* calls instead of waiting out their timeouts.
|
|
239
|
+
*
|
|
240
|
+
* `markClosing()` records that an imminent close was initiated by us (shutdown,
|
|
241
|
+
* reconnect, handshake rejection). A close so marked logs at debug; an
|
|
242
|
+
* unmarked death (remote socket close, socket error) logs at WARN.
|
|
224
243
|
*/
|
|
225
|
-
function createCloseNotifier(): {
|
|
244
|
+
function createCloseNotifier(log: PmLogger): {
|
|
226
245
|
isAlive: () => boolean;
|
|
227
|
-
|
|
246
|
+
markClosing: () => void;
|
|
247
|
+
markDead: (reason?: string) => void;
|
|
228
248
|
onClose: (handler: () => void) => void;
|
|
229
249
|
} {
|
|
230
250
|
let alive = true;
|
|
231
251
|
let notified = false;
|
|
252
|
+
let intentional = false;
|
|
232
253
|
const handlers: Array<() => void> = [];
|
|
233
254
|
return {
|
|
234
255
|
isAlive: () => alive,
|
|
235
|
-
|
|
256
|
+
markClosing() {
|
|
257
|
+
intentional = true;
|
|
258
|
+
},
|
|
259
|
+
markDead(reason?: string) {
|
|
236
260
|
alive = false;
|
|
237
261
|
if (notified) {
|
|
238
262
|
return;
|
|
239
263
|
}
|
|
240
264
|
notified = true;
|
|
265
|
+
if (intentional) {
|
|
266
|
+
log.debug(
|
|
267
|
+
{ reason: reason ?? "intentional" },
|
|
268
|
+
"CES socket transport closed",
|
|
269
|
+
);
|
|
270
|
+
} else {
|
|
271
|
+
log.warn(
|
|
272
|
+
{ reason: reason ?? "unknown" },
|
|
273
|
+
"CES socket transport died unexpectedly; credential ops will fail over or reconnect",
|
|
274
|
+
);
|
|
275
|
+
}
|
|
241
276
|
for (const handler of handlers) {
|
|
242
277
|
try {
|
|
243
278
|
handler();
|
|
@@ -256,10 +291,18 @@ function createCloseNotifier(): {
|
|
|
256
291
|
// Socket transport (managed mode)
|
|
257
292
|
// ---------------------------------------------------------------------------
|
|
258
293
|
|
|
259
|
-
|
|
294
|
+
/**
|
|
295
|
+
* A CesTransport plus `markClosing()`, which the process manager calls before
|
|
296
|
+
* an intentional socket destroy so the ensuing close logs at debug, not WARN.
|
|
297
|
+
*/
|
|
298
|
+
interface SocketTransport extends CesTransport {
|
|
299
|
+
markClosing(): void;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function createSocketTransport(socket: Socket, log: PmLogger): SocketTransport {
|
|
260
303
|
const messageHandlers: Array<(message: string) => void> = [];
|
|
261
304
|
let buffer = "";
|
|
262
|
-
const death = createCloseNotifier();
|
|
305
|
+
const death = createCloseNotifier(log);
|
|
263
306
|
|
|
264
307
|
const decoder = new StringDecoder("utf8");
|
|
265
308
|
|
|
@@ -278,12 +321,12 @@ function createSocketTransport(socket: Socket): CesTransport {
|
|
|
278
321
|
});
|
|
279
322
|
|
|
280
323
|
socket.on("close", () => {
|
|
281
|
-
death.markDead();
|
|
324
|
+
death.markDead("socket closed");
|
|
282
325
|
});
|
|
283
326
|
|
|
284
327
|
socket.on("error", (err) => {
|
|
285
328
|
log.warn({ err }, "CES socket transport error");
|
|
286
|
-
death.markDead();
|
|
329
|
+
death.markDead("socket error");
|
|
287
330
|
});
|
|
288
331
|
|
|
289
332
|
return {
|
|
@@ -304,8 +347,11 @@ function createSocketTransport(socket: Socket): CesTransport {
|
|
|
304
347
|
|
|
305
348
|
onClose: death.onClose,
|
|
306
349
|
|
|
350
|
+
markClosing: death.markClosing,
|
|
351
|
+
|
|
307
352
|
close(): void {
|
|
308
|
-
death.
|
|
353
|
+
death.markClosing();
|
|
354
|
+
death.markDead("transport.close() called");
|
|
309
355
|
socket.destroy();
|
|
310
356
|
},
|
|
311
357
|
};
|
|
@@ -37,25 +37,41 @@ mock.module("../../messaging/providers/telegram-bot/render.js", () => ({
|
|
|
37
37
|
}));
|
|
38
38
|
|
|
39
39
|
const { abortConversation } = await import("../conversation-lifecycle.js");
|
|
40
|
+
import { createAbortReason } from "../../util/abort-reasons.js";
|
|
40
41
|
import type { AbortContext } from "../conversation-lifecycle.js";
|
|
41
42
|
|
|
43
|
+
interface QueuedEvent {
|
|
44
|
+
type: string;
|
|
45
|
+
requestId?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
42
48
|
interface Harness {
|
|
43
49
|
ctx: AbortContext;
|
|
44
50
|
setProcessingCalls: boolean[];
|
|
45
51
|
prompterDisposed: () => boolean;
|
|
46
52
|
secretPrompterDisposed: () => boolean;
|
|
47
53
|
queueClearedCount: () => number;
|
|
54
|
+
queuedEvents: QueuedEvent[];
|
|
55
|
+
drainKicks: string[];
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
function makeContext(opts: {
|
|
51
59
|
processing: boolean;
|
|
52
60
|
controller: AbortController | null;
|
|
61
|
+
/** requestIds of messages sitting in the queue behind the aborted turn. */
|
|
62
|
+
queued?: string[];
|
|
53
63
|
}): Harness {
|
|
54
64
|
let processing = opts.processing;
|
|
55
65
|
const setProcessingCalls: boolean[] = [];
|
|
56
66
|
let prompterDisposed = false;
|
|
57
67
|
let secretPrompterDisposed = false;
|
|
58
68
|
let queueCleared = 0;
|
|
69
|
+
const queuedEvents: QueuedEvent[] = [];
|
|
70
|
+
const drainKicks: string[] = [];
|
|
71
|
+
let queuedItems = (opts.queued ?? []).map((requestId) => ({
|
|
72
|
+
requestId,
|
|
73
|
+
onEvent: (event: QueuedEvent) => queuedEvents.push(event),
|
|
74
|
+
}));
|
|
59
75
|
|
|
60
76
|
const ctx = {
|
|
61
77
|
conversationId: "abort-null-controller-test",
|
|
@@ -82,10 +98,19 @@ function makeContext(opts: {
|
|
|
82
98
|
queue: {
|
|
83
99
|
clear: () => {
|
|
84
100
|
queueCleared += 1;
|
|
101
|
+
queuedItems = [];
|
|
102
|
+
},
|
|
103
|
+
get isEmpty() {
|
|
104
|
+
return queuedItems.length === 0;
|
|
85
105
|
},
|
|
86
|
-
|
|
87
|
-
|
|
106
|
+
get length() {
|
|
107
|
+
return queuedItems.length;
|
|
88
108
|
},
|
|
109
|
+
[Symbol.iterator]: () => queuedItems[Symbol.iterator](),
|
|
110
|
+
},
|
|
111
|
+
pendingInterruptRepair: false,
|
|
112
|
+
kickDrainQueue: async (_reason?: string, origin?: string) => {
|
|
113
|
+
drainKicks.push(origin ?? "");
|
|
89
114
|
},
|
|
90
115
|
} as unknown as AbortContext;
|
|
91
116
|
|
|
@@ -95,6 +120,8 @@ function makeContext(opts: {
|
|
|
95
120
|
prompterDisposed: () => prompterDisposed,
|
|
96
121
|
secretPrompterDisposed: () => secretPrompterDisposed,
|
|
97
122
|
queueClearedCount: () => queueCleared,
|
|
123
|
+
queuedEvents,
|
|
124
|
+
drainKicks,
|
|
98
125
|
};
|
|
99
126
|
}
|
|
100
127
|
|
|
@@ -152,6 +179,114 @@ describe("abortConversation", () => {
|
|
|
152
179
|
);
|
|
153
180
|
});
|
|
154
181
|
|
|
182
|
+
test("a user interrupt leaves queued messages for the stopped turn's drain", () => {
|
|
183
|
+
// GIVEN a live turn with two messages queued behind it
|
|
184
|
+
const controller = new AbortController();
|
|
185
|
+
const h = makeContext({
|
|
186
|
+
processing: true,
|
|
187
|
+
controller,
|
|
188
|
+
queued: ["req-a", "req-b"],
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// WHEN the user stops the turn
|
|
192
|
+
abortConversation(
|
|
193
|
+
h.ctx,
|
|
194
|
+
createAbortReason("user_cancel", "test", "abort-null-controller-test"),
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// THEN the queue is untouched, so the agent loop's `finally` drains it and
|
|
198
|
+
// the queued messages are sent rather than silently dropped
|
|
199
|
+
expect(h.queueClearedCount()).toBe(0);
|
|
200
|
+
expect(h.ctx.queue.length).toBe(2);
|
|
201
|
+
expect(h.queuedEvents).toEqual([]);
|
|
202
|
+
// AND the drain is left to that `finally`, not kicked from here
|
|
203
|
+
expect(h.drainKicks).toEqual([]);
|
|
204
|
+
// AND the drain is told to repair tool_use blocks the killed turn abandoned
|
|
205
|
+
expect(h.ctx.pendingInterruptRepair).toBe(true);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test("a user interrupt with no live turn kicks the drain itself", () => {
|
|
209
|
+
// GIVEN a conversation flagged processing with no controller left to
|
|
210
|
+
// signal, so no agent-loop `finally` is coming to drain the preserved queue
|
|
211
|
+
const h = makeContext({
|
|
212
|
+
processing: true,
|
|
213
|
+
controller: null,
|
|
214
|
+
queued: ["req-a"],
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// WHEN the user stops it
|
|
218
|
+
abortConversation(
|
|
219
|
+
h.ctx,
|
|
220
|
+
createAbortReason("user_cancel", "test", "abort-null-controller-test"),
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
// THEN the queued message is still sent, because the abort kicks the drain
|
|
224
|
+
expect(h.ctx.queue.length).toBe(1);
|
|
225
|
+
expect(h.drainKicks).toEqual(["abortConversation:no_live_turn"]);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test("a non-interrupt abort discards the queue and closes out each row", () => {
|
|
229
|
+
// GIVEN a live turn with a queued message, torn down by a dispose
|
|
230
|
+
const controller = new AbortController();
|
|
231
|
+
const h = makeContext({
|
|
232
|
+
processing: true,
|
|
233
|
+
controller,
|
|
234
|
+
queued: ["req-a"],
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// WHEN the conversation is disposed rather than interrupted
|
|
238
|
+
abortConversation(
|
|
239
|
+
h.ctx,
|
|
240
|
+
createAbortReason(
|
|
241
|
+
"conversation_disposed",
|
|
242
|
+
"test",
|
|
243
|
+
"abort-null-controller-test",
|
|
244
|
+
),
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
// THEN the queue is dropped, since no turn is left for it to run on, and
|
|
248
|
+
// the sender gets the terminal event that closes the queued row, so no
|
|
249
|
+
// client is left holding a pending indicator nothing will ever settle
|
|
250
|
+
expect(h.queueClearedCount()).toBe(1);
|
|
251
|
+
expect(h.queuedEvents.map((e) => e.type)).toEqual([
|
|
252
|
+
"generation_cancelled",
|
|
253
|
+
"message_queued_deleted",
|
|
254
|
+
]);
|
|
255
|
+
expect(h.queuedEvents[1].requestId).toBe("req-a");
|
|
256
|
+
expect(h.ctx.pendingInterruptRepair).toBe(false);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test("a teardown abort discards the queue even when the flag reads idle", () => {
|
|
260
|
+
// GIVEN a conversation whose turn already cleared the processing flag but
|
|
261
|
+
// is still unwinding: the agent-loop `finally` clears the flag, then awaits
|
|
262
|
+
// the turn-boundary commit before its `kickDrainQueue`. A dispose landing
|
|
263
|
+
// in that window sees an idle conversation with a populated queue.
|
|
264
|
+
const h = makeContext({
|
|
265
|
+
processing: false,
|
|
266
|
+
controller: null,
|
|
267
|
+
queued: ["req-a"],
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// WHEN the conversation is disposed
|
|
271
|
+
abortConversation(
|
|
272
|
+
h.ctx,
|
|
273
|
+
createAbortReason(
|
|
274
|
+
"conversation_disposed",
|
|
275
|
+
"test",
|
|
276
|
+
"abort-null-controller-test",
|
|
277
|
+
),
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
// THEN the queue goes with it, so the pending `kickDrainQueue` finds
|
|
281
|
+
// nothing to run against the disposed conversation, and the queued row
|
|
282
|
+
// still gets its terminal event
|
|
283
|
+
expect(h.ctx.queue.length).toBe(0);
|
|
284
|
+
expect(h.queuedEvents.map((e) => e.type)).toEqual([
|
|
285
|
+
"generation_cancelled",
|
|
286
|
+
"message_queued_deleted",
|
|
287
|
+
]);
|
|
288
|
+
});
|
|
289
|
+
|
|
155
290
|
test("clears the persisted flag when in-memory reads idle (cancel with no live abort)", () => {
|
|
156
291
|
// GIVEN a conversation whose in-memory flag reads idle — e.g. reloaded
|
|
157
292
|
// after its owning turn was interrupted out-of-process, so a persisted
|
|
@@ -166,9 +301,10 @@ describe("abortConversation", () => {
|
|
|
166
301
|
// persisted column, so the row is unwedged for cold readers and the next
|
|
167
302
|
// reload — cancel is not a silent no-op.
|
|
168
303
|
expect(h.setProcessingCalls).toEqual([false]);
|
|
169
|
-
// AND the live-turn teardown (prompters,
|
|
170
|
-
// live turn holding them.
|
|
304
|
+
// AND the live-turn teardown (prompters, surfaces) is left alone: there was
|
|
305
|
+
// no live turn holding them. The queue is the exception, discarded on any
|
|
306
|
+
// non-interrupt abort regardless of the flag.
|
|
171
307
|
expect(h.prompterDisposed()).toBe(false);
|
|
172
|
-
expect(h.
|
|
308
|
+
expect(h.ctx.queue.length).toBe(0);
|
|
173
309
|
});
|
|
174
310
|
});
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
|
|
24
24
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
25
25
|
|
|
26
|
+
import { asConversation } from "../../__tests__/helpers/mock-conversation.js";
|
|
27
|
+
|
|
26
28
|
// ── Module-level mocks ─────────────────────────────────────────────
|
|
27
29
|
|
|
28
30
|
// Hub publish capture — used by the single-emit assertions. We spread
|
|
@@ -123,8 +125,7 @@ mock.module("../process-message.js", () => ({
|
|
|
123
125
|
// before the modules under test are loaded.
|
|
124
126
|
const { createSurfaceMutex, handleSurfaceAction } =
|
|
125
127
|
await import("../conversation-surfaces.js");
|
|
126
|
-
type
|
|
127
|
-
import("../conversation-surfaces.js").SurfaceConversationContext;
|
|
128
|
+
type Conversation = import("../../daemon/conversation.js").Conversation;
|
|
128
129
|
type TrustContext = import("../trust-context-types.js").TrustContext;
|
|
129
130
|
type AssistantEvent = import("../../api/index.js").AssistantEvent;
|
|
130
131
|
type SurfaceType = import("../message-protocol.js").SurfaceType;
|
|
@@ -144,20 +145,18 @@ function resetProcessHarness(): void {
|
|
|
144
145
|
|
|
145
146
|
// ── Surface-context harness ────────────────────────────────────────
|
|
146
147
|
|
|
147
|
-
interface HarnessContext extends
|
|
148
|
+
interface HarnessContext extends Conversation {
|
|
148
149
|
sent: AssistantEvent[];
|
|
149
150
|
enqueueCalls: Array<{ content: string }>;
|
|
150
151
|
processCalls: Array<{ content: string }>;
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
function makeContext(
|
|
154
|
-
overrides?: Partial<SurfaceConversationContext>,
|
|
155
|
-
): HarnessContext {
|
|
154
|
+
function makeContext(overrides?: Partial<Conversation>): HarnessContext {
|
|
156
155
|
const sent: AssistantEvent[] = [];
|
|
157
156
|
const enqueueCalls: Array<{ content: string }> = [];
|
|
158
157
|
const processCalls: Array<{ content: string }> = [];
|
|
159
158
|
|
|
160
|
-
const base
|
|
159
|
+
const base = asConversation({
|
|
161
160
|
conversationId: "origin-conv-id",
|
|
162
161
|
sendToClient: (msg) => sent.push(msg),
|
|
163
162
|
pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
|
|
@@ -182,7 +181,7 @@ function makeContext(
|
|
|
182
181
|
},
|
|
183
182
|
withSurface: createSurfaceMutex(),
|
|
184
183
|
...overrides,
|
|
185
|
-
};
|
|
184
|
+
});
|
|
186
185
|
|
|
187
186
|
return Object.assign(base, {
|
|
188
187
|
sent,
|
|
@@ -196,10 +195,7 @@ function makeContext(
|
|
|
196
195
|
* surfaces (no `pendingSurfaceActions` entry) — matching how the card
|
|
197
196
|
* actually reaches `handleSurfaceAction` after reconstruction.
|
|
198
197
|
*/
|
|
199
|
-
function registerCardSurface(
|
|
200
|
-
ctx: SurfaceConversationContext,
|
|
201
|
-
surfaceId: string,
|
|
202
|
-
): void {
|
|
198
|
+
function registerCardSurface(ctx: Conversation, surfaceId: string): void {
|
|
203
199
|
ctx.surfaceState.set(surfaceId, {
|
|
204
200
|
surfaceType: "card",
|
|
205
201
|
data: { title: "Launch" },
|