@vellumai/assistant 0.11.2 → 0.11.3-dev.202608080427.92f668a
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 +69 -9
- package/docs/flux-turn-detection-spike.md +243 -0
- package/docs/stt-provider-onboarding.md +3 -1
- 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 +50 -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 +50 -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 +50 -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 +619 -47
- package/package.json +1 -1
- package/scripts/voice-ttft-spike.ts +3 -3
- 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-controller.test.ts +120 -0
- 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-availability-routes.test.ts +14 -1
- 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__/config-loader-backfill.test.ts +19 -0
- package/src/__tests__/config-schema.test.ts +150 -7
- 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 +54 -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 +294 -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-list-plugin-servers.test.ts +250 -0
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +133 -0
- package/src/__tests__/media-stream-output.test.ts +175 -0
- package/src/__tests__/media-stream-server-integration.test.ts +36 -0
- package/src/__tests__/media-stream-stt-session.test.ts +67 -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__/skills.test.ts +32 -0
- 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/__tests__/workspace-migration-142-consolidate-voice-front-door.test.ts +150 -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__/tts-text-sanitizer.test.ts +13 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +131 -12
- package/src/calls/__tests__/voice-triage-escalate.test.ts +106 -0
- package/src/calls/call-controller.ts +30 -2
- package/src/calls/call-speech-output.ts +12 -4
- package/src/calls/call-transport.ts +18 -1
- package/src/calls/media-stream-output.ts +53 -5
- package/src/calls/media-stream-server.ts +21 -1
- package/src/calls/media-stream-stt-session.ts +49 -0
- package/src/calls/telephony-synthesis-language.ts +84 -0
- package/src/calls/tts-text-sanitizer.ts +12 -5
- package/src/calls/voice-session-bridge.ts +86 -17
- package/src/calls/voice-triage-escalate.ts +54 -7
- package/src/channels/__tests__/gateway-verification-sessions.test.ts +3 -3
- package/src/channels/__tests__/plugin-channel-declarations.test.ts +161 -0
- package/src/channels/config.ts +20 -2
- package/src/channels/gateway-verification-sessions.ts +7 -2
- package/src/channels/plugin-channel-declarations.ts +108 -0
- package/src/channels/types.ts +37 -1
- package/src/cli/AGENTS.md +5 -2
- 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 +17 -6
- package/src/cli/commands/mcp.ts +9 -0
- 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/stt.help.ts +27 -2
- 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 +161 -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 +60 -0
- package/src/cli.ts +1 -1
- package/src/config/__tests__/default-profile-catalog.test.ts +11 -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/acp/SKILL.md +6 -7
- 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/media-processing/services/preprocess.ts +14 -4
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +15 -15
- 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 +3 -3
- 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/transcribe/tools/transcribe-media.test.ts +22 -1
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +9 -2
- package/src/config/bundled-skills/visualize/SKILL.md +1 -1
- package/src/config/call-site-defaults.ts +4 -5
- package/src/config/default-profile-catalog.ts +9 -5
- package/src/config/feature-flag-registry.json +25 -17
- package/src/config/llm-resolver.ts +45 -15
- package/src/config/loader.ts +75 -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__/live-voice.test.ts +142 -4
- package/src/config/schemas/__tests__/stt.test.ts +20 -5
- package/src/config/schemas/call-site-catalog.ts +4 -4
- package/src/config/schemas/calls.ts +0 -4
- package/src/config/schemas/channels.ts +13 -0
- package/src/config/schemas/live-voice.ts +82 -23
- package/src/config/schemas/llm.ts +1 -1
- package/src/config/schemas/memory-retrospective.ts +25 -0
- package/src/config/schemas/plugin-updates.ts +59 -0
- package/src/config/schemas/services.ts +8 -4
- package/src/config/schemas/stt.ts +18 -5
- package/src/config/schemas/timeouts.ts +1 -1
- package/src/config/schemas/tts.ts +63 -0
- 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/inbound/__tests__/oauth-callback-url.test.ts +83 -0
- package/src/inbound/oauth-callback-url.ts +61 -0
- 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-agent-turn.test.ts +1 -104
- 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-events.test.ts +7 -8
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +932 -0
- package/src/live-voice/__tests__/live-voice-integration.test.ts +12 -5
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +115 -8
- package/src/live-voice/__tests__/live-voice-photo.test.ts +100 -0
- package/src/live-voice/__tests__/live-voice-progress.test.ts +179 -146
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +265 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +324 -2
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +131 -2
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +0 -483
- package/src/live-voice/__tests__/live-voice-tts.test.ts +148 -2
- package/src/live-voice/__tests__/live-voice-vad.test.ts +313 -32
- package/src/live-voice/__tests__/progress-narration.test.ts +214 -0
- package/src/live-voice/__tests__/progress-phrases.test.ts +167 -0
- 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-metrics.ts +57 -32
- package/src/live-voice/live-voice-photo.ts +168 -0
- package/src/live-voice/live-voice-session.ts +1137 -351
- package/src/live-voice/live-voice-tts.ts +18 -2
- package/src/live-voice/progress-narration.ts +277 -0
- package/src/live-voice/progress-phrases.ts +105 -2
- package/src/live-voice/protocol.ts +110 -2
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
- package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +196 -0
- package/src/mcp/__tests__/mcp-oauth-provider.test.ts +9 -9
- package/src/mcp/client.ts +14 -7
- package/src/mcp/mcp-auth-orchestrator.ts +13 -22
- package/src/mcp/mcp-oauth-provider.ts +195 -240
- 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 +495 -0
- package/src/monitoring/db-integrity-sample.ts +6 -1
- package/src/monitoring/plugin-auto-update.ts +463 -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 +13 -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/__tests__/oauth-callback-url-export.test.ts +29 -0
- package/src/plugin-api/index.ts +28 -5
- package/src/plugin-api/webhook-url.ts +151 -0
- package/src/plugins/__tests__/installed-plugin-dirs.test.ts +82 -0
- package/src/plugins/__tests__/mcp-servers.test.ts +370 -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/skill-content.ts +8 -1
- 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 +64 -8
- package/src/plugins/installed-plugin-dirs.ts +101 -0
- package/src/plugins/mcp-servers.ts +343 -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 +72 -2
- 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__/deepgram-flux-frames.test.ts +433 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +620 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +34 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +472 -12
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +395 -0
- package/src/providers/speech-to-text/deepgram-flux-realtime.ts +719 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +283 -1
- package/src/providers/speech-to-text/deepgram-realtime.ts +117 -3
- package/src/providers/speech-to-text/deepgram.ts +1 -0
- package/src/providers/speech-to-text/provider-catalog.ts +137 -8
- package/src/providers/speech-to-text/resolve.ts +105 -12
- 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/__tests__/local-actor-identity-force-refresh.test.ts +104 -0
- package/src/runtime/agent-wake.ts +63 -24
- package/src/runtime/assistant-event-hub.ts +110 -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 +29 -14
- 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 +217 -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__/sse-actor-principal-heal.test.ts +165 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +25 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +2 -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-availability-routes.ts +32 -14
- 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 +20 -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 +29 -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/mcp-auth-routes.ts +141 -57
- 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 +127 -4
- 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/sse-actor-principal-heal.ts +113 -0
- package/src/runtime/routes/stt-routes.ts +31 -25
- 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/oauth2.ts +6 -22
- 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/__tests__/daemon-batch-transcriber.test.ts +22 -0
- package/src/stt/__tests__/language-metadata.test.ts +85 -0
- package/src/stt/__tests__/speech-energy.test.ts +79 -0
- package/src/stt/__tests__/types.test.ts +94 -0
- package/src/stt/daemon-batch-transcriber.ts +18 -6
- package/src/stt/language-metadata.ts +65 -0
- package/src/stt/speech-energy.ts +115 -12
- package/src/stt/stt-stream-session.ts +8 -4
- package/src/stt/types.ts +119 -0
- 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 +303 -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/tts/__tests__/provider-adapters.test.ts +147 -0
- package/src/tts/__tests__/speakable-segments.test.ts +470 -0
- package/src/tts/language-voices.ts +23 -0
- package/src/tts/providers/deepgram-provider.ts +3 -1
- package/src/tts/providers/elevenlabs-provider.ts +73 -1
- package/src/tts/providers/xai-provider.ts +28 -2
- package/src/tts/speakable-segments.ts +293 -23
- package/src/tts/synthesis-stream.ts +7 -0
- package/src/tts/types.ts +7 -0
- package/src/usage/__tests__/subagent-attribution.test.ts +109 -0
- package/src/usage/subagent-attribution.ts +108 -0
- package/src/util/__tests__/language-subtag.test.ts +54 -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/language-subtag.ts +43 -0
- package/src/util/schedule-source-key.ts +23 -0
- package/src/util/unicode.ts +1 -1
- 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/142-consolidate-voice-front-door.ts +70 -0
- package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +116 -0
- package/src/workspace/migrations/registry.ts +6 -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/live-voice/__tests__/front-decision.test.ts +0 -525
- package/src/live-voice/front-decision.ts +0 -429
- package/src/notifications/deferred-emit.ts +0 -147
|
@@ -137,7 +137,7 @@ import {
|
|
|
137
137
|
startOutbound,
|
|
138
138
|
} from "../runtime/verification-outbound-actions.js";
|
|
139
139
|
import {
|
|
140
|
-
|
|
140
|
+
composeVerificationText,
|
|
141
141
|
GUARDIAN_VERIFY_TEMPLATE_KEYS,
|
|
142
142
|
} from "../runtime/verification-templates.js";
|
|
143
143
|
import { resetDbForTesting } from "./db-test-helpers.js";
|
|
@@ -1640,32 +1640,42 @@ describe("outbound verification sessions", () => {
|
|
|
1640
1640
|
|
|
1641
1641
|
// ── Auto-revoke of prior sessions ──
|
|
1642
1642
|
|
|
1643
|
-
test("
|
|
1643
|
+
test("a second code for the same number revokes the first", async () => {
|
|
1644
1644
|
const { sessionId: firstId } = await createOutboundSession({
|
|
1645
1645
|
channel: "phone",
|
|
1646
|
-
expectedPhoneE164: "+
|
|
1647
|
-
destinationAddress: "+
|
|
1646
|
+
expectedPhoneE164: "+15555550101",
|
|
1647
|
+
destinationAddress: "+15555550101",
|
|
1648
|
+
});
|
|
1649
|
+
const { sessionId: secondId } = await createOutboundSession({
|
|
1650
|
+
channel: "phone",
|
|
1651
|
+
expectedPhoneE164: "+15555550101",
|
|
1652
|
+
destinationAddress: "+15555550101",
|
|
1648
1653
|
});
|
|
1649
1654
|
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1655
|
+
// Read by id rather than through the unfiltered lookup: two live
|
|
1656
|
+
// sessions minted in the same millisecond have no defined order, and
|
|
1657
|
+
// what matters here is each row's status, not which one is "latest".
|
|
1658
|
+
expect(getSessionById(firstId)!.status).toBe("revoked");
|
|
1659
|
+
expect(getSessionById(secondId)!.status).toBe("awaiting_response");
|
|
1660
|
+
});
|
|
1653
1661
|
|
|
1654
|
-
|
|
1662
|
+
test("a code for a different number leaves the first alone", async () => {
|
|
1663
|
+
// Two numbers are two people. Verifying one must not silently kill the
|
|
1664
|
+
// other's code, which they would learn about only by trying to use it
|
|
1665
|
+
// and being told it is "invalid or has expired".
|
|
1666
|
+
const { sessionId: firstId } = await createOutboundSession({
|
|
1667
|
+
channel: "phone",
|
|
1668
|
+
expectedPhoneE164: "+15555550101",
|
|
1669
|
+
destinationAddress: "+15555550101",
|
|
1670
|
+
});
|
|
1655
1671
|
const { sessionId: secondId } = await createOutboundSession({
|
|
1656
1672
|
channel: "phone",
|
|
1657
|
-
expectedPhoneE164: "+
|
|
1658
|
-
destinationAddress: "+
|
|
1673
|
+
expectedPhoneE164: "+15555550102",
|
|
1674
|
+
destinationAddress: "+15555550102",
|
|
1659
1675
|
});
|
|
1660
1676
|
|
|
1661
|
-
|
|
1662
|
-
expect(
|
|
1663
|
-
expect(second!.id).toBe(secondId);
|
|
1664
|
-
|
|
1665
|
-
// First session should no longer be findable as active
|
|
1666
|
-
const firstRow = getSessionById(firstId);
|
|
1667
|
-
expect(firstRow).not.toBeNull();
|
|
1668
|
-
expect(firstRow!.status).toBe("revoked");
|
|
1677
|
+
expect(getSessionById(firstId)!.status).toBe("awaiting_response");
|
|
1678
|
+
expect(getSessionById(secondId)!.status).toBe("awaiting_response");
|
|
1669
1679
|
});
|
|
1670
1680
|
|
|
1671
1681
|
// ── findActiveSession returns correct session ──
|
|
@@ -1772,26 +1782,46 @@ describe("outbound verification sessions", () => {
|
|
|
1772
1782
|
expect(result.success).toBe(true);
|
|
1773
1783
|
});
|
|
1774
1784
|
|
|
1775
|
-
// ── Voice identity
|
|
1785
|
+
// ── Voice identity is the number ──
|
|
1776
1786
|
|
|
1777
|
-
test("
|
|
1787
|
+
test("a voice session is redeemed by the number it was sent to", async () => {
|
|
1788
|
+
// Voice knows the caller by one thing, so the consume path receives that
|
|
1789
|
+
// number as both actor axes. Every voice mint records it in both
|
|
1790
|
+
// identity columns, and either way the session is bound to the number.
|
|
1778
1791
|
const { secret } = await createOutboundSession({
|
|
1779
1792
|
channel: "phone",
|
|
1780
|
-
expectedExternalUserId: "
|
|
1781
|
-
expectedPhoneE164: "+
|
|
1782
|
-
destinationAddress: "+
|
|
1793
|
+
expectedExternalUserId: "+15555550101",
|
|
1794
|
+
expectedPhoneE164: "+15555550101",
|
|
1795
|
+
destinationAddress: "+15555550101",
|
|
1783
1796
|
});
|
|
1784
1797
|
|
|
1785
|
-
// Actor matches expectedExternalUserId
|
|
1786
1798
|
const result = await validateAndConsumeVerification(
|
|
1787
1799
|
"phone",
|
|
1788
1800
|
secret,
|
|
1789
|
-
"
|
|
1790
|
-
"
|
|
1801
|
+
"+15555550101",
|
|
1802
|
+
"+15555550101",
|
|
1791
1803
|
);
|
|
1792
1804
|
|
|
1793
1805
|
expect(result.success).toBe(true);
|
|
1794
1806
|
});
|
|
1807
|
+
|
|
1808
|
+
test("a voice session refuses a caller on a different number", async () => {
|
|
1809
|
+
const { secret } = await createOutboundSession({
|
|
1810
|
+
channel: "phone",
|
|
1811
|
+
expectedExternalUserId: "+15555550101",
|
|
1812
|
+
expectedPhoneE164: "+15555550101",
|
|
1813
|
+
destinationAddress: "+15555550101",
|
|
1814
|
+
});
|
|
1815
|
+
|
|
1816
|
+
const result = await validateAndConsumeVerification(
|
|
1817
|
+
"phone",
|
|
1818
|
+
secret,
|
|
1819
|
+
"+15555550102",
|
|
1820
|
+
"+15555550102",
|
|
1821
|
+
);
|
|
1822
|
+
|
|
1823
|
+
expect(result.success).toBe(false);
|
|
1824
|
+
});
|
|
1795
1825
|
});
|
|
1796
1826
|
|
|
1797
1827
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -2344,7 +2374,7 @@ describe("outbound Telegram verification", () => {
|
|
|
2344
2374
|
});
|
|
2345
2375
|
|
|
2346
2376
|
test("telegram template does not include verification code in message", async () => {
|
|
2347
|
-
const msg =
|
|
2377
|
+
const msg = composeVerificationText(
|
|
2348
2378
|
GUARDIAN_VERIFY_TEMPLATE_KEYS.TELEGRAM_CHALLENGE_REQUEST,
|
|
2349
2379
|
{ code: "abc123", expiresInMinutes: 10 },
|
|
2350
2380
|
);
|
|
@@ -2353,7 +2383,7 @@ describe("outbound Telegram verification", () => {
|
|
|
2353
2383
|
});
|
|
2354
2384
|
|
|
2355
2385
|
test("telegram resend template does not include code and includes (resent) suffix", async () => {
|
|
2356
|
-
const msg =
|
|
2386
|
+
const msg = composeVerificationText(
|
|
2357
2387
|
GUARDIAN_VERIFY_TEMPLATE_KEYS.TELEGRAM_RESEND,
|
|
2358
2388
|
{ code: "xyz789", expiresInMinutes: 5 },
|
|
2359
2389
|
);
|
|
@@ -2363,7 +2393,7 @@ describe("outbound Telegram verification", () => {
|
|
|
2363
2393
|
});
|
|
2364
2394
|
|
|
2365
2395
|
test("telegram template includes Vellum assistant prefix", async () => {
|
|
2366
|
-
const msg =
|
|
2396
|
+
const msg = composeVerificationText(
|
|
2367
2397
|
GUARDIAN_VERIFY_TEMPLATE_KEYS.TELEGRAM_CHALLENGE_REQUEST,
|
|
2368
2398
|
{ code: "999999", expiresInMinutes: 10, assistantName: "MyBot" },
|
|
2369
2399
|
);
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Telegram probe's remote check.
|
|
3
|
+
*
|
|
4
|
+
* Local checks establish that credentials exist. That is a different claim
|
|
5
|
+
* from "messages arrive": a registration that never landed leaves every
|
|
6
|
+
* credential in place and the channel dark, which is how the readiness
|
|
7
|
+
* indicator went green on a channel nobody could reach.
|
|
8
|
+
*
|
|
9
|
+
* The classification lives in `checkTelegramWebhookHealth`, which already
|
|
10
|
+
* handles error recency and the managed-versus-self-hosted recovery text.
|
|
11
|
+
* These tests pin how the probe maps its verdicts across three outcomes, not
|
|
12
|
+
* two: verified pass, hard failure, and the no-evidence statuses that are
|
|
13
|
+
* neither. A probe that cannot see the answer must not report a fault, and
|
|
14
|
+
* must not be counted as proof either.
|
|
15
|
+
*/
|
|
16
|
+
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
17
|
+
|
|
18
|
+
import type { TelegramWebhookHealthResult } from "../telegram/webhook-health.js";
|
|
19
|
+
|
|
20
|
+
let health: TelegramWebhookHealthResult;
|
|
21
|
+
|
|
22
|
+
mock.module("../telegram/webhook-health.js", () => ({
|
|
23
|
+
checkTelegramWebhookHealth: async () => health,
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
mock.module("../calls/twilio-rest.js", () => ({
|
|
27
|
+
hasTwilioCredentials: () => false,
|
|
28
|
+
}));
|
|
29
|
+
mock.module("../calls/twilio-config.js", () => ({
|
|
30
|
+
resolveTwilioPhoneNumber: () => undefined,
|
|
31
|
+
}));
|
|
32
|
+
mock.module("../runtime/channel-invite-transports/whatsapp.js", () => ({
|
|
33
|
+
resolveWhatsAppDisplayNumber: () => undefined,
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
async function runTelegramRemoteProbe() {
|
|
37
|
+
const { createReadinessService } =
|
|
38
|
+
await import("../runtime/channel-readiness-service.js");
|
|
39
|
+
const service = createReadinessService();
|
|
40
|
+
return service.getReadiness("telegram", true);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function deliveryCheck() {
|
|
44
|
+
const [snapshot] = await runTelegramRemoteProbe();
|
|
45
|
+
const remote = snapshot.remoteChecks ?? [];
|
|
46
|
+
const result = remote.find((c) => c.name === "webhook_delivery");
|
|
47
|
+
if (!result) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`no webhook_delivery check ran; got: ${remote.map((c) => c.name).join(", ") || "(none)"}`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
health = { status: "healthy", detail: "ok" };
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
afterEach(() => {
|
|
60
|
+
mock.restore();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe("telegram remote probe (webhook delivery)", () => {
|
|
64
|
+
test("passes when Telegram reports a healthy webhook", async () => {
|
|
65
|
+
health = { status: "healthy", detail: "delivering" };
|
|
66
|
+
|
|
67
|
+
expect((await deliveryCheck()).passed).toBe(true);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("fails when no webhook is registered, carrying the recovery text", async () => {
|
|
71
|
+
health = {
|
|
72
|
+
status: "not_registered",
|
|
73
|
+
detail: "Telegram has no webhook registered. Contact support.",
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const result = await deliveryCheck();
|
|
77
|
+
expect(result.passed).toBe(false);
|
|
78
|
+
// The detail carries fixPath()'s managed-versus-self-hosted guidance, so
|
|
79
|
+
// the probe relays it rather than substituting wording of its own.
|
|
80
|
+
expect(result.message).toBe(health.detail);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("fails when Telegram reports a recent delivery error", async () => {
|
|
84
|
+
health = {
|
|
85
|
+
status: "delivery_failing",
|
|
86
|
+
detail: 'Telegram reported "Connection refused"',
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const result = await deliveryCheck();
|
|
90
|
+
expect(result.passed).toBe(false);
|
|
91
|
+
expect(result.message).toBe(health.detail);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("fails when Telegram holds a webhook this deployment did not register", async () => {
|
|
95
|
+
// The case last_error_date cannot see: on a quiet channel a stale tunnel
|
|
96
|
+
// address or another deployment's callback never produces a delivery
|
|
97
|
+
// error, so before the URL comparison this read as healthy.
|
|
98
|
+
health = {
|
|
99
|
+
status: "url_mismatch",
|
|
100
|
+
detail: "Telegram is registered at a different address",
|
|
101
|
+
registeredUrl: "https://stale.example/webhooks/telegram",
|
|
102
|
+
expectedUrl: "https://current.example/webhooks/telegram",
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const result = await deliveryCheck();
|
|
106
|
+
expect(result.passed).toBe(false);
|
|
107
|
+
expect(result.message).toBe(health.detail);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// The three indeterminate statuses. Each must satisfy BOTH halves: no fault
|
|
111
|
+
// reported (so a network blip does not paint a working channel broken), and
|
|
112
|
+
// not counted as evidence (so nothing can claim delivery from a check that
|
|
113
|
+
// never established it). Asserting only `passed` would let a regression that
|
|
114
|
+
// drops `indeterminate` through, which is exactly the false-success this
|
|
115
|
+
// contract exists to prevent.
|
|
116
|
+
const indeterminateCases = [
|
|
117
|
+
["skipped", "no bot token stored"],
|
|
118
|
+
["unknown", "could not reach Telegram"],
|
|
119
|
+
["unverified", "no record of registering this webhook"],
|
|
120
|
+
] as const;
|
|
121
|
+
|
|
122
|
+
for (const [status, detail] of indeterminateCases) {
|
|
123
|
+
test(`${status} is indeterminate: no fault reported, but not proof of delivery`, async () => {
|
|
124
|
+
health = { status, detail };
|
|
125
|
+
|
|
126
|
+
const result = await deliveryCheck();
|
|
127
|
+
expect(result.passed).toBe(true);
|
|
128
|
+
expect(result.indeterminate).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
test("an untouched install stays not_configured rather than incomplete", async () => {
|
|
133
|
+
// setupStatus separates not_configured from incomplete by asking whether
|
|
134
|
+
// any check passed. Counting an indeterminate check there reported a
|
|
135
|
+
// workspace with no Telegram credentials at all as half-finished, which is
|
|
136
|
+
// what routes the Channels UI to the "finish setup" prompt instead of the
|
|
137
|
+
// normal setup flow.
|
|
138
|
+
health = { status: "skipped", detail: "no bot token stored" };
|
|
139
|
+
|
|
140
|
+
const [snapshot] = await runTelegramRemoteProbe();
|
|
141
|
+
expect(snapshot.setupStatus).toBe("not_configured");
|
|
142
|
+
expect(snapshot.ready).toBe(false);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test("a verified healthy result is not marked indeterminate", async () => {
|
|
146
|
+
// Sensitivity check for the cases above: if `indeterminate` were set
|
|
147
|
+
// unconditionally they would pass while proving nothing.
|
|
148
|
+
health = { status: "healthy", detail: "registered where we set it" };
|
|
149
|
+
|
|
150
|
+
const result = await deliveryCheck();
|
|
151
|
+
expect(result.passed).toBe(true);
|
|
152
|
+
expect(result.indeterminate).toBeFalsy();
|
|
153
|
+
});
|
|
154
|
+
});
|
|
@@ -12,20 +12,21 @@ import { describe, expect, test } from "bun:test";
|
|
|
12
12
|
|
|
13
13
|
import type { OpenPanelEvent } from "../api/events/open-panel.js";
|
|
14
14
|
import type { AssistantEvent } from "../api/index.js";
|
|
15
|
+
import type { Conversation } from "../daemon/conversation.js";
|
|
15
16
|
import {
|
|
16
17
|
createSurfaceMutex,
|
|
17
18
|
handleSurfaceAction,
|
|
18
19
|
openChannelSetupPanel,
|
|
19
|
-
type SurfaceConversationContext,
|
|
20
20
|
surfaceProxyResolver,
|
|
21
21
|
} from "../daemon/conversation-surfaces.js";
|
|
22
22
|
import type { SurfaceType } from "../daemon/message-protocol.js";
|
|
23
|
+
import { asConversation } from "./helpers/mock-conversation.js";
|
|
23
24
|
|
|
24
25
|
function makeContext(
|
|
25
26
|
sent: AssistantEvent[] = [],
|
|
26
|
-
overrides: Partial<
|
|
27
|
-
):
|
|
28
|
-
return {
|
|
27
|
+
overrides: Partial<Conversation> = {},
|
|
28
|
+
): Conversation {
|
|
29
|
+
return asConversation({
|
|
29
30
|
conversationId: "session-1",
|
|
30
31
|
sendToClient: (msg) => sent.push(msg),
|
|
31
32
|
pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
|
|
@@ -46,7 +47,7 @@ function makeContext(
|
|
|
46
47
|
processMessage: async () => "ok",
|
|
47
48
|
withSurface: createSurfaceMutex(),
|
|
48
49
|
...overrides,
|
|
49
|
-
};
|
|
50
|
+
});
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
function findOpenPanel(sent: AssistantEvent[]): OpenPanelEvent | undefined {
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Verifies that `persistQueuedMessageBody` stamps the client-reported OS
|
|
3
3
|
* surface into `metadata.client.os` on persisted user messages.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Browser, mobile, and desktop apps all run the same web renderer and report
|
|
6
6
|
* `userMessageInterface: "web"` (the transport surface, which host-proxy
|
|
7
7
|
* capability gating keys off), so `client.os` is the only per-platform
|
|
8
8
|
* attribution available to turn telemetry (`turn-events-store` forwards
|
|
9
9
|
* `$.client` onto `TurnTelemetryEvent.client`). Without the stamp, desktop
|
|
10
10
|
* and mobile usage are indistinguishable from browser usage downstream.
|
|
11
11
|
*
|
|
12
|
-
* Mirrors the mock harness of `dm-persistence.test.ts`
|
|
12
|
+
* Mirrors the mock harness of `dm-persistence.test.ts` and exercises
|
|
13
13
|
* `persistQueuedMessageBody` directly with a captured `addMessage`.
|
|
14
14
|
*/
|
|
15
15
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
@@ -65,6 +65,7 @@ import type {
|
|
|
65
65
|
import type { MessagingConversationContext } from "../daemon/conversation-messaging.js";
|
|
66
66
|
import { persistQueuedMessageBody } from "../daemon/conversation-messaging.js";
|
|
67
67
|
import type { MessageQueue } from "../daemon/conversation-queue-manager.js";
|
|
68
|
+
import { isMacOriginatedUserMessage } from "../persistence/conversation-types.js";
|
|
68
69
|
|
|
69
70
|
function createWebTurnContext(
|
|
70
71
|
clientOs: string | undefined,
|
|
@@ -110,7 +111,7 @@ describe("client OS surface metadata persistence", () => {
|
|
|
110
111
|
addMessageCalls.length = 0;
|
|
111
112
|
});
|
|
112
113
|
|
|
113
|
-
test.each(["macos", "ios", "android", "web"])(
|
|
114
|
+
test.each(["macos", "windows", "ios", "android", "web"])(
|
|
114
115
|
"stamps client.os = %s from the conversation's clientOs",
|
|
115
116
|
async (os) => {
|
|
116
117
|
const ctx = createWebTurnContext(os);
|
|
@@ -136,7 +137,7 @@ describe("client OS surface metadata persistence", () => {
|
|
|
136
137
|
});
|
|
137
138
|
|
|
138
139
|
test("omits the client bag for values outside the ClientOs vocabulary", async () => {
|
|
139
|
-
const ctx = createWebTurnContext("
|
|
140
|
+
const ctx = createWebTurnContext("linux");
|
|
140
141
|
await persistQueuedMessageBody(ctx, {
|
|
141
142
|
content: "hello",
|
|
142
143
|
requestId: "req-invalid",
|
|
@@ -173,3 +174,101 @@ describe("client OS surface metadata persistence", () => {
|
|
|
173
174
|
});
|
|
174
175
|
});
|
|
175
176
|
});
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* `Conversation.clientOs` is a live field that only a transport-carrying
|
|
180
|
+
* message refreshes, so a transport-less turn stamps whatever an earlier send
|
|
181
|
+
* left there. `clientOsFromRequest` separates the two, and
|
|
182
|
+
* {@link isMacOriginatedUserMessage} (the row-origin read behind the
|
|
183
|
+
* `chat.assistant_reply` presence gate) requires it before letting an attended
|
|
184
|
+
* Mac suppress a push.
|
|
185
|
+
*/
|
|
186
|
+
describe("client OS per-row evidence marker", () => {
|
|
187
|
+
beforeEach(() => {
|
|
188
|
+
addMessageCalls.length = 0;
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test("marks an OS this row's own transport reported", async () => {
|
|
192
|
+
const ctx = createWebTurnContext("macos");
|
|
193
|
+
await persistQueuedMessageBody(ctx, {
|
|
194
|
+
content: "hello",
|
|
195
|
+
requestId: "req-transport-os",
|
|
196
|
+
requestClientOs: "macos",
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
expect(lastUserMetadata().client).toEqual({ os: "macos" });
|
|
200
|
+
expect(lastUserMetadata().clientOsFromRequest).toBe(true);
|
|
201
|
+
expect(isMacOriginatedUserMessage(lastUserMetadata())).toBe(true);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("marks an OS this row's own request headers reported", async () => {
|
|
205
|
+
const ctx = createWebTurnContext(undefined);
|
|
206
|
+
await persistQueuedMessageBody(ctx, {
|
|
207
|
+
content: "hello",
|
|
208
|
+
requestId: "req-header-os",
|
|
209
|
+
metadata: { client: { os: "macos", interface_version: "0.8.2" } },
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
expect(lastUserMetadata().clientOsFromRequest).toBe(true);
|
|
213
|
+
expect(isMacOriginatedUserMessage(lastUserMetadata())).toBe(true);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// The bug shape: a button tapped on the phone reaches a conversation whose
|
|
217
|
+
// last desktop send left `clientOs: "macos"` behind. The row still carries
|
|
218
|
+
// the inherited OS for telemetry, but nothing says this turn came from the
|
|
219
|
+
// Mac, so the reply push must survive.
|
|
220
|
+
test("leaves an inherited OS unmarked and not Mac-originated", async () => {
|
|
221
|
+
const ctx = createWebTurnContext("macos");
|
|
222
|
+
await persistQueuedMessageBody(ctx, {
|
|
223
|
+
content: "[User action on card surface: submit]",
|
|
224
|
+
requestId: "req-inherited-os",
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
expect(lastUserMetadata().client).toEqual({ os: "macos" });
|
|
228
|
+
expect(lastUserMetadata().clientOsFromRequest).toBeUndefined();
|
|
229
|
+
expect(isMacOriginatedUserMessage(lastUserMetadata())).toBe(false);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// The marker vouches for the `client.os` that actually landed, not for
|
|
233
|
+
// whatever the row reported: a reported OS the stamp disagrees with is no
|
|
234
|
+
// evidence at all.
|
|
235
|
+
test("leaves the marker off when the reported OS is not the stamped one", async () => {
|
|
236
|
+
const ctx = createWebTurnContext("macos");
|
|
237
|
+
await persistQueuedMessageBody(ctx, {
|
|
238
|
+
content: "hello",
|
|
239
|
+
requestId: "req-mismatched-os",
|
|
240
|
+
requestClientOs: "ios",
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
expect(lastUserMetadata().client).toEqual({ os: "macos" });
|
|
244
|
+
expect(lastUserMetadata().clientOsFromRequest).toBeUndefined();
|
|
245
|
+
expect(isMacOriginatedUserMessage(lastUserMetadata())).toBe(false);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// The marker is derived from what this persist can see, so a bag value
|
|
249
|
+
// riding in from a caller must not survive the metadata spread and assert an
|
|
250
|
+
// origin the row never reported.
|
|
251
|
+
test("drops a caller-supplied marker from the metadata bag", async () => {
|
|
252
|
+
const ctx = createWebTurnContext("macos");
|
|
253
|
+
await persistQueuedMessageBody(ctx, {
|
|
254
|
+
content: "[User action on card surface: submit]",
|
|
255
|
+
requestId: "req-spoofed-marker",
|
|
256
|
+
metadata: { clientOsFromRequest: true },
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
expect(lastUserMetadata().clientOsFromRequest).toBeUndefined();
|
|
260
|
+
expect(isMacOriginatedUserMessage(lastUserMetadata())).toBe(false);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
test("leaves the marker off for a reported OS outside the vocabulary", async () => {
|
|
264
|
+
const ctx = createWebTurnContext(undefined);
|
|
265
|
+
await persistQueuedMessageBody(ctx, {
|
|
266
|
+
content: "hello",
|
|
267
|
+
requestId: "req-unknown-os",
|
|
268
|
+
requestClientOs: "windows",
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
expect(lastUserMetadata().client).toBeUndefined();
|
|
272
|
+
expect(lastUserMetadata().clientOsFromRequest).toBeUndefined();
|
|
273
|
+
});
|
|
274
|
+
});
|
|
@@ -548,6 +548,25 @@ describe("loadConfig startup behavior", () => {
|
|
|
548
548
|
expect(raw.daemon?.standaloneRecording).toBe(false);
|
|
549
549
|
});
|
|
550
550
|
|
|
551
|
+
test("strips calls.voice.language from existing user configs", () => {
|
|
552
|
+
// `calls.voice.language` is a retired no-op knob: nothing read it.
|
|
553
|
+
// The spoken language lives at `services.stt.language` and per-language
|
|
554
|
+
// TTS voices at `services.tts.providers.<id>.languageVoices`. Existing
|
|
555
|
+
// configs that have it written to disk should load cleanly with the
|
|
556
|
+
// field stripped and its siblings preserved.
|
|
557
|
+
writeConfig({
|
|
558
|
+
provider: "anthropic",
|
|
559
|
+
calls: { voice: { language: "es-ES", telephonyStreaming: false } },
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
loadConfig();
|
|
563
|
+
|
|
564
|
+
const raw = JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
|
|
565
|
+
expect(raw.calls?.voice?.language).toBeUndefined();
|
|
566
|
+
// Sibling fields under calls.voice are preserved
|
|
567
|
+
expect(raw.calls?.voice?.telephonyStreaming).toBe(false);
|
|
568
|
+
});
|
|
569
|
+
|
|
551
570
|
test("still writes a default config on first launch when file is absent", () => {
|
|
552
571
|
// Discoverability: when no config.json exists, write one populated with
|
|
553
572
|
// all schema defaults so users can see and edit available options.
|