@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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
3
|
import { TTS_PROVIDER_IDS } from "../../tts/types.js";
|
|
4
|
+
import { baseLanguageSubtag } from "../../util/language-subtag.js";
|
|
4
5
|
import {
|
|
5
6
|
DEFAULT_ELEVENLABS_VOICE_ID,
|
|
6
7
|
VALID_CONVERSATION_TIMEOUTS,
|
|
@@ -14,6 +15,53 @@ import {
|
|
|
14
15
|
* legacy top-level schemas (`elevenlabs.*`, `fishAudio.*`) so that
|
|
15
16
|
* migration can copy values 1:1.
|
|
16
17
|
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Optional per-language voice override map for a TTS provider block.
|
|
21
|
+
* Keys parse to lowercase base language subtags (e.g. "hi", "ja"); values
|
|
22
|
+
* are provider voice identifiers. Live voice consults the map when a turn's
|
|
23
|
+
* spoken language is known and no explicit voice was requested.
|
|
24
|
+
*
|
|
25
|
+
* Key normalization happens at parse time so runtime lookups are a single
|
|
26
|
+
* exact match: each key is lowercased, cut at the first `-`/`_`, and
|
|
27
|
+
* trimmed ("hi-IN" and "HI" both store as "hi"). Keys that normalize to
|
|
28
|
+
* the empty string are dropped; when two keys normalize to the same
|
|
29
|
+
* subtag, the first entry wins.
|
|
30
|
+
*/
|
|
31
|
+
function languageVoicesSchema(providerId: string, valuesDescription: string) {
|
|
32
|
+
return z
|
|
33
|
+
.record(
|
|
34
|
+
z.string({
|
|
35
|
+
error: `services.tts.providers.${providerId}.languageVoices keys must be strings`,
|
|
36
|
+
}),
|
|
37
|
+
z.string({
|
|
38
|
+
error: `services.tts.providers.${providerId}.languageVoices values must be strings`,
|
|
39
|
+
}),
|
|
40
|
+
{
|
|
41
|
+
error: `services.tts.providers.${providerId}.languageVoices must be an object mapping language subtags to voice identifiers`,
|
|
42
|
+
},
|
|
43
|
+
)
|
|
44
|
+
.transform((map) => {
|
|
45
|
+
const normalized = new Map<string, string>();
|
|
46
|
+
for (const [key, voice] of Object.entries(map)) {
|
|
47
|
+
const subtag = baseLanguageSubtag(key);
|
|
48
|
+
if (!subtag || normalized.has(subtag)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
normalized.set(subtag, voice);
|
|
52
|
+
}
|
|
53
|
+
return Object.fromEntries(normalized);
|
|
54
|
+
})
|
|
55
|
+
.optional()
|
|
56
|
+
.describe(
|
|
57
|
+
"Per-language voice overrides for live voice. Keys are normalized on " +
|
|
58
|
+
'save to lowercase base language subtags ("hi-IN" and "HI" both ' +
|
|
59
|
+
`store as "hi"); ${valuesDescription} ` +
|
|
60
|
+
"Applied when the turn's spoken language matches an entry and no " +
|
|
61
|
+
"explicit voice is requested.",
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
17
65
|
export const TtsElevenLabsProviderConfigSchema = z
|
|
18
66
|
.object({
|
|
19
67
|
voiceId: z
|
|
@@ -79,6 +127,10 @@ export const TtsElevenLabsProviderConfigSchema = z
|
|
|
79
127
|
)
|
|
80
128
|
.default(30)
|
|
81
129
|
.describe("Seconds of silence before voice conversation auto-ends"),
|
|
130
|
+
languageVoices: languageVoicesSchema(
|
|
131
|
+
"elevenlabs",
|
|
132
|
+
"values are ElevenLabs voice IDs.",
|
|
133
|
+
),
|
|
82
134
|
})
|
|
83
135
|
.describe("ElevenLabs provider configuration under services.tts");
|
|
84
136
|
|
|
@@ -150,6 +202,10 @@ export const TtsDeepgramProviderConfigSchema = z
|
|
|
150
202
|
})
|
|
151
203
|
.default("mp3")
|
|
152
204
|
.describe("Output audio format for call/runtime playback"),
|
|
205
|
+
languageVoices: languageVoicesSchema(
|
|
206
|
+
"deepgram",
|
|
207
|
+
"values are Deepgram TTS model identifiers (e.g. an aura-2 voice).",
|
|
208
|
+
),
|
|
153
209
|
})
|
|
154
210
|
.describe("Deepgram provider configuration under services.tts");
|
|
155
211
|
|
|
@@ -221,6 +277,13 @@ const TtsVellumProviderConfigSchema = z
|
|
|
221
277
|
.describe(
|
|
222
278
|
"Managed TTS voice model (e.g. aura-2-thalia-en). Unset means the platform's default voice. The platform rejects voices it does not offer.",
|
|
223
279
|
),
|
|
280
|
+
languageVoices: languageVoicesSchema(
|
|
281
|
+
"vellum",
|
|
282
|
+
"values are managed TTS voice models (e.g. aura-2-thalia-en) and must " +
|
|
283
|
+
"be voices offered by the platform rate card: an unpriced model is " +
|
|
284
|
+
"rejected by the relay (missing_price), the same contract as " +
|
|
285
|
+
"services.tts.providers.vellum.model.",
|
|
286
|
+
),
|
|
224
287
|
})
|
|
225
288
|
.describe("Vellum managed provider configuration under services.tts");
|
|
226
289
|
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
getGuardianDeliveryFresh,
|
|
45
45
|
guardianForChannel,
|
|
46
46
|
invalidateGuardianDeliveryCache,
|
|
47
|
+
warmGuardianBindings,
|
|
47
48
|
} from "../guardian-delivery-reader.js";
|
|
48
49
|
|
|
49
50
|
const METHOD = "resolve_guardian_delivery";
|
|
@@ -299,3 +300,18 @@ describe("selectors", () => {
|
|
|
299
300
|
expect(anyGuardian([])).toBeUndefined();
|
|
300
301
|
});
|
|
301
302
|
});
|
|
303
|
+
|
|
304
|
+
describe("warmGuardianBindings", () => {
|
|
305
|
+
test("warms both the vellum-channel key and the unfiltered fallback key", async () => {
|
|
306
|
+
const keys: string[] = [];
|
|
307
|
+
await warmGuardianBindings(async (input) => {
|
|
308
|
+
keys.push(input?.channelTypes?.join(",") ?? "ALL");
|
|
309
|
+
return null;
|
|
310
|
+
});
|
|
311
|
+
// Both keys the sync persona resolvers read — peekGuardianForChannel
|
|
312
|
+
// ("vellum") and the peekAnyGuardian() fallback — must be warmed;
|
|
313
|
+
// warming only the channel key leaves the any-channel fallback cold for
|
|
314
|
+
// guardians bound on non-vellum channels.
|
|
315
|
+
expect(keys.sort()).toEqual(["ALL", "vellum"]);
|
|
316
|
+
});
|
|
317
|
+
});
|
|
@@ -151,8 +151,8 @@ export async function getGuardianDelivery(input?: {
|
|
|
151
151
|
* Returns the fresh cached list for the given channel filter, or `undefined`
|
|
152
152
|
* when the cache is cold or expired. Used by sync hot paths (SSE subscribe)
|
|
153
153
|
* that cannot await {@link getGuardianDelivery} but must resolve the SAME
|
|
154
|
-
* gateway-owned principal the async paths land on.
|
|
155
|
-
*
|
|
154
|
+
* gateway-owned principal the async paths land on. There is no fallback
|
|
155
|
+
* fetch: on a cold/expired cache the caller proceeds without a principal.
|
|
156
156
|
*/
|
|
157
157
|
export function peekCachedGuardianDelivery(input?: {
|
|
158
158
|
channelTypes?: string[];
|
|
@@ -181,6 +181,33 @@ export async function getGuardianDeliveryFresh(input?: {
|
|
|
181
181
|
});
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
type GuardianDeliveryFetch = (input?: {
|
|
185
|
+
channelTypes?: string[];
|
|
186
|
+
}) => Promise<unknown>;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Warm both guardian-binding cache keys the sync persona resolvers read: the
|
|
190
|
+
* `"vellum"`-channel key for `peekGuardianForChannel("vellum")` and the
|
|
191
|
+
* unfiltered key for the `peekAnyGuardian()` fallback. Warming only one key
|
|
192
|
+
* still resolves `users/default.md` when the guardian lives on a non-vellum
|
|
193
|
+
* channel (phone / Telegram).
|
|
194
|
+
*
|
|
195
|
+
* Uses the FRESH reader so warmup bypasses a stale/empty cached entry: a
|
|
196
|
+
* gateway-side binding write (onboarding, rebind) does not invalidate the
|
|
197
|
+
* daemon cache, so a non-fresh read could return an empty binding cached
|
|
198
|
+
* before the guardian existed and freeze `users/default.md` until the TTL
|
|
199
|
+
* expires. The fresh reads repopulate the cache the sync `peek*` resolvers
|
|
200
|
+
* then read. Best-effort: the reader swallows failures.
|
|
201
|
+
*/
|
|
202
|
+
export async function warmGuardianBindings(
|
|
203
|
+
fetchDelivery: GuardianDeliveryFetch = getGuardianDeliveryFresh,
|
|
204
|
+
): Promise<void> {
|
|
205
|
+
await Promise.all([
|
|
206
|
+
fetchDelivery({ channelTypes: ["vellum"] }),
|
|
207
|
+
fetchDelivery(),
|
|
208
|
+
]);
|
|
209
|
+
}
|
|
210
|
+
|
|
184
211
|
/**
|
|
185
212
|
* Clear ALL cached guardian deliveries so contact mutations refetch on the next
|
|
186
213
|
* read. Called by {@link notifyContactsChanged} after a contact write, and
|
package/src/context/compactor.ts
CHANGED
|
@@ -865,10 +865,10 @@ function resolveTailFloorIndex(messages: Message[], tailIndex: number): number {
|
|
|
865
865
|
// Retained-image hydration
|
|
866
866
|
// ---------------------------------------------------------------------------
|
|
867
867
|
|
|
868
|
-
function buildRetainedImageBlocks(
|
|
868
|
+
async function buildRetainedImageBlocks(
|
|
869
869
|
filenames: string[],
|
|
870
870
|
manifest: ManifestEntry[],
|
|
871
|
-
): { blocks: ImageContent[]; resolved: string[]; missing: string[] } {
|
|
871
|
+
): Promise<{ blocks: ImageContent[]; resolved: string[]; missing: string[] }> {
|
|
872
872
|
const blocks: ImageContent[] = [];
|
|
873
873
|
const resolved: string[] = [];
|
|
874
874
|
const missing: string[] = [];
|
|
@@ -887,7 +887,7 @@ function buildRetainedImageBlocks(
|
|
|
887
887
|
// Run the same downscale pass the agent uses when first sending an
|
|
888
888
|
// image. Without this, attachments that exceed the provider's per-image
|
|
889
889
|
// byte limit (Anthropic: 5 MB) crash the next turn after compaction.
|
|
890
|
-
const optimized = optimizeImageForTransport(
|
|
890
|
+
const optimized = await optimizeImageForTransport(
|
|
891
891
|
content.toString("base64"),
|
|
892
892
|
sourceMime,
|
|
893
893
|
);
|
|
@@ -1393,7 +1393,7 @@ export async function runAssistantDrivenCompaction(
|
|
|
1393
1393
|
blocks: retainedImageBlocks,
|
|
1394
1394
|
resolved,
|
|
1395
1395
|
missing,
|
|
1396
|
-
} = buildRetainedImageBlocks(parsed.retainedImageFilenames, manifest);
|
|
1396
|
+
} = await buildRetainedImageBlocks(parsed.retainedImageFilenames, manifest);
|
|
1397
1397
|
if (missing.length > 0) {
|
|
1398
1398
|
log.warn(
|
|
1399
1399
|
{ missing },
|
|
@@ -37,20 +37,43 @@ export const TRUNCATION_MARKER = "\u2014 full result:";
|
|
|
37
37
|
export const TRUNCATION_EXEMPT_TOOLS = new Set<string>(["skill_load"]);
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* File-read tools that page spooled `.tool-results/` content back into
|
|
41
|
-
* `file_read` reads inside the workspace; `host_file_read` reads
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* paged back at all — and (b) recognized by {@link derefToolResultReReads}, so a
|
|
45
|
-
* re-read of a spooled file collapses to a stub instead of duplicating content
|
|
46
|
-
* already in context. Sharing one set keeps the two passes from drifting if a
|
|
47
|
-
* new file-read tool is added.
|
|
40
|
+
* File-read tools that can page spooled `.tool-results/` content back into
|
|
41
|
+
* context. `file_read` reads inside the workspace; `host_file_read` reads
|
|
42
|
+
* anywhere on the host. A new file-read tool belongs here so
|
|
43
|
+
* {@link isSpooledToolResultRead} recognizes it.
|
|
48
44
|
*/
|
|
49
45
|
export const FILE_READ_TOOL_NAMES = new Set<string>([
|
|
50
46
|
"file_read",
|
|
51
47
|
"host_file_read",
|
|
52
48
|
]);
|
|
53
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Whether a tool call is a file read aimed at a spooled `.tool-results/` file.
|
|
52
|
+
*
|
|
53
|
+
* Such a read is the model paging content back in, so both passes treat it
|
|
54
|
+
* specially: the result-time spool pass leaves it alone (re-stubbing it would
|
|
55
|
+
* write a fresh copy and hand back another stub, putting the content out of
|
|
56
|
+
* reach for good), and {@link derefToolResultReReads} collapses it at turn end
|
|
57
|
+
* (its prefix and suffix are already in context above). A file read aimed
|
|
58
|
+
* anywhere else is ordinary tool output and gets no such treatment.
|
|
59
|
+
*/
|
|
60
|
+
export function isSpooledToolResultRead(
|
|
61
|
+
toolName: string | undefined,
|
|
62
|
+
input: Record<string, unknown> | undefined,
|
|
63
|
+
): boolean {
|
|
64
|
+
if (toolName === undefined || !FILE_READ_TOOL_NAMES.has(toolName)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const filePath = input?.path ?? input?.file_path;
|
|
68
|
+
if (typeof filePath !== "string") {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
// The path in the stub comes from `join`, so it is backslash-separated on
|
|
72
|
+
// Windows. Compare on a normalized form: a missed match would let the spool
|
|
73
|
+
// pass stub this read and put the saved content permanently out of reach.
|
|
74
|
+
return filePath.replace(/\\/g, "/").includes(`/${TOOL_RESULT_DIR}/`);
|
|
75
|
+
}
|
|
76
|
+
|
|
54
77
|
/**
|
|
55
78
|
* Build a map of tool_use_id -> originating tool name by walking the tool_use
|
|
56
79
|
* blocks in assistant messages. A tool_result only carries `tool_use_id`, so
|
|
@@ -329,14 +352,7 @@ export function derefToolResultReReads(messages: Message[]): {
|
|
|
329
352
|
continue;
|
|
330
353
|
}
|
|
331
354
|
const tu = block as ToolUseContent;
|
|
332
|
-
if (
|
|
333
|
-
continue;
|
|
334
|
-
}
|
|
335
|
-
const filePath = tu.input.path ?? tu.input.file_path;
|
|
336
|
-
if (typeof filePath !== "string") {
|
|
337
|
-
continue;
|
|
338
|
-
}
|
|
339
|
-
if (filePath.includes(`/${TOOL_RESULT_DIR}/`)) {
|
|
355
|
+
if (isSpooledToolResultRead(tu.name, tu.input)) {
|
|
340
356
|
reReadToolUseIds.add(tu.id);
|
|
341
357
|
}
|
|
342
358
|
}
|
|
@@ -136,6 +136,48 @@ export function stripSpotlightInjections(messages: Message[]): Message[] {
|
|
|
136
136
|
return stripUserTextBlocksByPrefix(messages, [MEMORY_SPOTLIGHT_MATCHER]);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Whether the TURN-STARTING user message carries a memory-v3
|
|
141
|
+
* `<memory_spotlight>` block.
|
|
142
|
+
*
|
|
143
|
+
* The spotlight is the only injected block that is strip-and-replaced from
|
|
144
|
+
* every user message each turn, so its presence is exactly what makes that
|
|
145
|
+
* message volatile across turns. Every other injected block (turn context,
|
|
146
|
+
* workspace, `<info>`, `<memory>` cards, NOW.md) is frozen into history and
|
|
147
|
+
* re-renders byte-identically, so a message without a spotlight is a stable
|
|
148
|
+
* cache anchor. Providers consume this through the `mutableLatestUserMessage`
|
|
149
|
+
* config field when placing cache breakpoints.
|
|
150
|
+
*
|
|
151
|
+
* The turn start is the most recent user message carrying TEXT content, which
|
|
152
|
+
* is the same message the Anthropic client anchors on. Tool-result messages
|
|
153
|
+
* are skipped: they are user-role but carry no injected blocks, and letting
|
|
154
|
+
* them answer this question would flip the signal to `false` partway through a
|
|
155
|
+
* tool loop. The provider would then mark the very same turn-start block at a
|
|
156
|
+
* different TTL than it did on the turn's first request, billing a second
|
|
157
|
+
* write for one reusable prefix. Anchoring on the turn start keeps the signal
|
|
158
|
+
* constant for every request in the turn.
|
|
159
|
+
*
|
|
160
|
+
* Detection uses {@link MEMORY_SPOTLIGHT_MATCHER}, the same full-wrapper
|
|
161
|
+
* matcher {@link stripSpotlightInjections} strips with, so the two can never
|
|
162
|
+
* disagree about which blocks are ephemeral.
|
|
163
|
+
*/
|
|
164
|
+
export function turnStartUserMessageHasSpotlight(messages: Message[]): boolean {
|
|
165
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
166
|
+
const message = messages[i];
|
|
167
|
+
if (message.role !== "user") {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const textBlocks = message.content.filter((block) => block.type === "text");
|
|
171
|
+
if (textBlocks.length === 0) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
return textBlocks.some((block) =>
|
|
175
|
+
textBlockMatchesInjection(block.text, [MEMORY_SPOTLIGHT_MATCHER]),
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
|
|
139
181
|
/** `<NOW.md>` scratchpad prefixes (current tag, pre-line-limit variant, legacy `<now_scratchpad>`) — shared with `stripNowScratchpad` so the two strip paths can't drift. */
|
|
140
182
|
export const NOW_SCRATCHPAD_STRIP_PREFIXES: InjectionMatcher[] = [
|
|
141
183
|
"<NOW.md Always keep this up to date",
|
|
@@ -4,8 +4,8 @@ import { join } from "node:path";
|
|
|
4
4
|
import type { ContentBlock, ToolResultContent } from "../providers/types.js";
|
|
5
5
|
import {
|
|
6
6
|
buildTruncatedContent,
|
|
7
|
-
FILE_READ_TOOL_NAMES,
|
|
8
7
|
getToolResultFilePath,
|
|
8
|
+
isSpooledToolResultRead,
|
|
9
9
|
isTruncationEligible,
|
|
10
10
|
TOOL_RESULT_DIR,
|
|
11
11
|
} from "./post-turn-tool-result-truncation.js";
|
|
@@ -32,27 +32,32 @@ export const RESULT_TIME_SPOOL_EXEMPT_TOOLS = new Set<string>(["web_fetch"]);
|
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Whether a tool result is eligible for the result-time spool/stub pass: the
|
|
35
|
-
* post-turn pass's shared rules plus the AX-tree exemption, minus
|
|
36
|
-
*
|
|
37
|
-
* ({@link RESULT_TIME_SPOOL_EXEMPT_TOOLS}).
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
35
|
+
* post-turn pass's shared rules plus the AX-tree exemption, minus reads of
|
|
36
|
+
* already-spooled `.tool-results/` files ({@link isSpooledToolResultRead}) and
|
|
37
|
+
* the explicit self-sized reads ({@link RESULT_TIME_SPOOL_EXEMPT_TOOLS}).
|
|
38
|
+
*
|
|
39
|
+
* The spooled-read exemption is what keeps paging possible: a file read is the
|
|
40
|
+
* model's only way to pull spooled content back into context, so stubbing a
|
|
41
|
+
* read of a `.tool-results/` file would write a fresh copy and hand back
|
|
42
|
+
* another stub, putting that content out of reach for good. It is scoped by
|
|
43
|
+
* target path rather than by tool name, because a file read aimed anywhere
|
|
44
|
+
* else is ordinary oversized output with no such circularity, and exempting it
|
|
45
|
+
* keeps a whole file inline on every LLM call for the rest of the turn.
|
|
46
|
+
* Explicit self-sized reads are honored in full; the post-turn pass still
|
|
47
|
+
* truncates them at turn end, after the model has consumed the content.
|
|
43
48
|
*/
|
|
44
49
|
function isSpoolEligible(
|
|
45
50
|
tr: ToolResultContent,
|
|
46
51
|
toolName: string | undefined,
|
|
52
|
+
toolInput: Record<string, unknown> | undefined,
|
|
47
53
|
): boolean {
|
|
48
54
|
if (!isTruncationEligible(tr, toolName)) {
|
|
49
55
|
return false;
|
|
50
56
|
}
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
) {
|
|
57
|
+
if (isSpooledToolResultRead(toolName, toolInput)) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
if (toolName !== undefined && RESULT_TIME_SPOOL_EXEMPT_TOOLS.has(toolName)) {
|
|
56
61
|
return false;
|
|
57
62
|
}
|
|
58
63
|
if (tr.content.includes(AX_TREE_TAG)) {
|
|
@@ -72,8 +77,8 @@ function isSpoolEligible(
|
|
|
72
77
|
* rewriting an earlier message between calls would invalidate the cache from
|
|
73
78
|
* that point on every iteration. The model still gets the head/tail preview
|
|
74
79
|
* plus the on-disk path, so it can page the full content back in with
|
|
75
|
-
* `file_read` or `host_file_read` (
|
|
76
|
-
* when it actually needs it.
|
|
80
|
+
* `file_read` or `host_file_read` (a read of a `.tool-results/` path is exempt
|
|
81
|
+
* from this pass) when it actually needs it.
|
|
77
82
|
*
|
|
78
83
|
* Uses the same file paths, stub bytes, and eligibility rules as
|
|
79
84
|
* `postTurnTruncateToolResults`, whose `TRUNCATION_MARKER` guard then skips
|
|
@@ -89,7 +94,15 @@ export function spoolAndStubOversizedToolResults(
|
|
|
89
94
|
blocks: ContentBlock[],
|
|
90
95
|
options: {
|
|
91
96
|
conversationDir: string;
|
|
92
|
-
|
|
97
|
+
/**
|
|
98
|
+
* The originating call for a `tool_use_id`. A `tool_result` carries only
|
|
99
|
+
* the id, and eligibility turns on both the tool's name and the path it
|
|
100
|
+
* was pointed at, so the two travel together rather than as separate
|
|
101
|
+
* lookups that could disagree.
|
|
102
|
+
*/
|
|
103
|
+
toolCallById: (
|
|
104
|
+
toolUseId: string,
|
|
105
|
+
) => { name: string; input: Record<string, unknown> } | undefined;
|
|
93
106
|
},
|
|
94
107
|
): number {
|
|
95
108
|
let stubbedCount = 0;
|
|
@@ -98,7 +111,8 @@ export function spoolAndStubOversizedToolResults(
|
|
|
98
111
|
if (block.type !== "tool_result") {
|
|
99
112
|
continue;
|
|
100
113
|
}
|
|
101
|
-
|
|
114
|
+
const toolCall = options.toolCallById(block.tool_use_id);
|
|
115
|
+
if (!isSpoolEligible(block, toolCall?.name, toolCall?.input)) {
|
|
102
116
|
continue;
|
|
103
117
|
}
|
|
104
118
|
|
|
@@ -176,6 +176,9 @@ export async function startCes(config: AssistantConfig): Promise<void> {
|
|
|
176
176
|
},
|
|
177
177
|
});
|
|
178
178
|
if (client) {
|
|
179
|
+
log.info(
|
|
180
|
+
"CES client injected into credential resolver at startup; credential reads route through CES RPC",
|
|
181
|
+
);
|
|
179
182
|
setCesClient(client);
|
|
180
183
|
} else {
|
|
181
184
|
// The handshake lost the startup race, so provider init proceeds on the
|
|
@@ -9,6 +9,15 @@
|
|
|
9
9
|
* delegated to the shared package.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import {
|
|
13
|
+
type CesRpcClient,
|
|
14
|
+
type CesRpcClientConfig,
|
|
15
|
+
type CesTransport,
|
|
16
|
+
createCesRpcClient,
|
|
17
|
+
} from "@vellumai/ces-client/rpc-client";
|
|
18
|
+
|
|
19
|
+
import { getLogger } from "../util/logger.js";
|
|
20
|
+
|
|
12
21
|
export {
|
|
13
22
|
type CesRpcClient as CesClient,
|
|
14
23
|
type CesRpcClientConfig as CesClientConfig,
|
|
@@ -17,5 +26,17 @@ export {
|
|
|
17
26
|
CesHandshakeError,
|
|
18
27
|
type CesTransport,
|
|
19
28
|
CesTransportError,
|
|
20
|
-
createCesRpcClient as createCesClient,
|
|
21
29
|
} from "@vellumai/ces-client/rpc-client";
|
|
30
|
+
|
|
31
|
+
const log = getLogger("ces-rpc-client");
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Construct a CES RPC client wired to the assistant logger so handshake-ready
|
|
35
|
+
* and close transitions are visible in the daemon logs.
|
|
36
|
+
*/
|
|
37
|
+
export function createCesClient(
|
|
38
|
+
transport: CesTransport,
|
|
39
|
+
config?: CesRpcClientConfig,
|
|
40
|
+
): CesRpcClient {
|
|
41
|
+
return createCesRpcClient(transport, { logger: log, ...config });
|
|
42
|
+
}
|
|
@@ -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
|
+
});
|