@vellumai/assistant 0.12.2 → 0.12.3-staging.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +2 -0
- package/AGENTS.md +1 -1
- package/ARCHITECTURE.md +43 -29
- package/Dockerfile +63 -0
- package/docs/architecture/integrations.md +7 -0
- package/docs/architecture/memory.md +17 -2
- package/docs/architecture/security.md +10 -5
- package/docs/architecture/turn-actor.md +2 -0
- package/docs/credential-execution-service.md +1 -1
- package/docs/desktop-browser-cli.md +50 -5
- package/docs/live-voice-task-outcomes.md +100 -0
- package/docs/mode-sessions.md +183 -0
- package/docs/voice-input-diagnostics.md +58 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
- package/node_modules/@vellumai/environments/src/shell.test.ts +21 -0
- package/node_modules/@vellumai/environments/src/shell.ts +24 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -2
- package/node_modules/@vellumai/gateway-client/src/index.ts +4 -1
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +38 -7
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +5 -6
- package/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
- package/node_modules/@vellumai/slack-text/src/index.ts +4 -8
- package/openapi.yaml +716 -16
- package/package.json +1 -1
- package/scripts/smoke-desktop-browser-cli.ts +11 -26
- package/scripts/smoke-desktop-window-theme.ts +2 -3
- package/scripts/sync-llm-catalog.ts +3 -0
- package/scripts/voice-ttft-spike.ts +2 -2
- package/src/__tests__/agent-loop-output-hooks.test.ts +150 -1
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +87 -19
- package/src/__tests__/agent-loop.test.ts +259 -0
- package/src/__tests__/agent-wake-delegation-prompt.test.ts +64 -2
- package/src/__tests__/annotate-activity-metadata.test.ts +3 -1
- package/src/__tests__/annotate-risk-options.test.ts +2 -0
- package/src/__tests__/answered-question-persistence.test.ts +2 -0
- package/src/__tests__/anthropic-gateway-shared.test.ts +22 -0
- package/src/__tests__/anthropic-provider.test.ts +55 -0
- package/src/__tests__/approval-interception-trust-gates.test.ts +40 -0
- package/src/__tests__/approval-message-composer.test.ts +1 -118
- package/src/__tests__/approval-routes-http.test.ts +3 -0
- package/src/__tests__/assistant-event-hub-connection-history.test.ts +111 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +50 -0
- package/src/__tests__/assistant-event-targeting.test.ts +186 -0
- package/src/__tests__/assistant-stream-state.test.ts +29 -9
- package/src/__tests__/attachments-store.test.ts +22 -3
- package/src/__tests__/browser-fill-credential.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +4 -1
- package/src/__tests__/build-persisted-content.test.ts +1 -1
- package/src/__tests__/call-conversation-messages.test.ts +5 -0
- package/src/__tests__/call-recovery.test.ts +7 -2
- package/src/__tests__/call-routes-http.test.ts +12 -0
- package/src/__tests__/call-store.test.ts +7 -2
- package/src/__tests__/channel-approval.test.ts +9 -14
- package/src/__tests__/channel-reply-delivery.test.ts +56 -0
- package/src/__tests__/channel-retry-sweep.test.ts +9 -0
- package/src/__tests__/chat-credential-redaction.test.ts +23 -0
- package/src/__tests__/chat-reveal-guard-priming.test.ts +2 -0
- package/src/__tests__/checker.test.ts +11 -3
- package/src/__tests__/client-os-metadata-persistence.test.ts +35 -1
- package/src/__tests__/computer-use-screenshot-attachments.test.ts +411 -0
- package/src/__tests__/computer-use-screenshot-selection.test.ts +50 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +0 -25
- package/src/__tests__/computer-use-tools.test.ts +1 -233
- package/src/__tests__/config-model-image-provider.test.ts +39 -0
- package/src/__tests__/config-schema.test.ts +16 -0
- package/src/__tests__/config-watcher.test.ts +24 -0
- package/src/__tests__/context-search-agent-runner.test.ts +260 -1
- package/src/__tests__/context-search-fanout.test.ts +1 -1
- package/src/__tests__/context-search-types.test.ts +7 -7
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +8 -2
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop.test.ts +797 -16
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +53 -1
- package/src/__tests__/conversation-attachments.test.ts +106 -0
- package/src/__tests__/conversation-evictor.test.ts +62 -37
- package/src/__tests__/conversation-fork-crud.test.ts +191 -0
- package/src/__tests__/conversation-history-boundary-repair-failure.test.ts +174 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +2 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +2 -0
- package/src/__tests__/conversation-rendered-delegation-state.test.ts +276 -0
- package/src/__tests__/conversation-retry-route.test.ts +22 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +2 -0
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +2 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +10 -0
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +2 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -0
- package/src/__tests__/conversation-surface-snapshots.test.ts +543 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +151 -0
- package/src/__tests__/conversation-surfaces-point-at-budget.test.ts +63 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +23 -0
- package/src/__tests__/conversation-undo.test.ts +61 -0
- package/src/__tests__/credential-execution-client.test.ts +72 -55
- package/src/__tests__/credential-prompt-route.test.ts +35 -3
- package/src/__tests__/cu-unified-flow.test.ts +82 -1
- package/src/__tests__/db-conversation-tool-surface.test.ts +221 -0
- package/src/__tests__/db-mode-sessions-migration.test.ts +175 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -0
- package/src/__tests__/dm-backfill.test.ts +91 -1
- package/src/__tests__/document-create-route.test.ts +88 -0
- package/src/__tests__/document-sync-tags.test.ts +27 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +142 -2
- package/src/__tests__/events-tail-route.test.ts +58 -0
- package/src/__tests__/evict-conversations-for-reload.test.ts +57 -8
- package/src/__tests__/guardian-action-sweep.test.ts +16 -0
- package/src/__tests__/guardian-dispatch.test.ts +13 -0
- package/src/__tests__/headless-browser-interactions.test.ts +64 -20
- package/src/__tests__/heartbeat-service.test.ts +2 -59
- package/src/__tests__/helpers/mock-conversation.ts +21 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +2 -0
- package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +5 -0
- package/src/__tests__/history-repair.test.ts +53 -0
- package/src/__tests__/host-cu-proxy.test.ts +46 -2
- package/src/__tests__/http-user-message-parity.test.ts +2 -0
- package/src/__tests__/image-credentials.test.ts +49 -0
- package/src/__tests__/image-service-dispatcher.test.ts +45 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +26 -0
- package/src/__tests__/interrupt-on-send.test.ts +57 -43
- package/src/__tests__/interrupt-turn-note.test.ts +5 -6
- package/src/__tests__/list-messages-tool-merge.test.ts +85 -1
- package/src/__tests__/llm-catalog-parity.test.ts +27 -4
- package/src/__tests__/media-generate-image.test.ts +49 -1
- package/src/__tests__/message-provenance-contact-id.test.ts +69 -0
- package/src/__tests__/migration-export-to-gcs.test.ts +142 -0
- package/src/__tests__/mode-session-history.test.ts +245 -0
- package/src/__tests__/mode-session-recovery.test.ts +222 -0
- package/src/__tests__/mode-session-wire.test.ts +141 -0
- package/src/__tests__/notification-guardian-path.test.ts +7 -0
- package/src/__tests__/notification-telegram-adapter.test.ts +2 -2
- package/src/__tests__/notification-vellum-adapter.test.ts +34 -0
- package/src/__tests__/oauth-apps-routes.test.ts +1 -0
- package/src/__tests__/oauth-commands-routes.test.ts +114 -101
- package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +13 -0
- package/src/__tests__/oauth-providers-routes.test.ts +3 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/persist-media-references.test.ts +50 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -0
- package/src/__tests__/plugin-api-provider.test.ts +5 -0
- package/src/__tests__/plugin-api-resolve-credential.test.ts +97 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +9 -1
- package/src/__tests__/process-message-display-content.test.ts +56 -0
- package/src/__tests__/reaction-persistence.test.ts +5 -0
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +25 -9
- package/src/__tests__/run-conversation-turn-persistence.test.ts +138 -1
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +20 -0
- package/src/__tests__/scheduler-result-notification.test.ts +23 -4
- package/src/__tests__/script-proxy-certs.test.ts +1 -1
- package/src/__tests__/scripted-turn-metadata-persistence.test.ts +73 -0
- package/src/__tests__/secret-ingress-http.test.ts +2 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +86 -31
- package/src/__tests__/secret-routes-scrub.test.ts +22 -27
- package/src/__tests__/secret-scanner.test.ts +20 -0
- package/src/__tests__/secure-keys-managed-failover.test.ts +8 -0
- package/src/__tests__/secure-keys.test.ts +50 -4
- package/src/__tests__/send-endpoint-busy.test.ts +163 -1
- package/src/__tests__/server-history-render.test.ts +91 -1
- package/src/__tests__/server-tool-pairing.test.ts +107 -0
- package/src/__tests__/settings-routes.test.ts +50 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +32 -0
- package/src/__tests__/skills.test.ts +5 -4
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -2
- package/src/__tests__/subagent-manager-notify.test.ts +1 -2
- package/src/__tests__/subagent-notify-parent.test.ts +146 -39
- package/src/__tests__/subagent-notify-stale-rebuild.test.ts +2 -4
- package/src/__tests__/subagent-tool-gate-mode.test.ts +226 -0
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +2 -0
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/thread-backfill.test.ts +53 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +2 -0
- package/src/__tests__/tool-result-follow-up.test.ts +99 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +66 -1
- package/src/__tests__/tool-start-timestamp.test.ts +2 -0
- package/src/__tests__/twilio-routes.test.ts +1 -0
- package/src/__tests__/unicode.test.ts +36 -0
- package/src/__tests__/web-search-backend-failure.test.ts +1 -1
- package/src/activation/progress-store.test.ts +12 -7
- package/src/agent/loop.ts +136 -53
- package/src/agent/tool-result-follow-up.ts +70 -0
- package/src/api/attachment-provenance.test.ts +68 -0
- package/src/api/computer-use-tool.test.ts +55 -0
- package/src/api/computer-use-tool.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +3 -0
- package/src/api/events/assistant-turn-start.ts +3 -0
- package/src/api/events/desktop-activity-changed.ts +10 -0
- package/src/api/events/generation-handoff.ts +2 -0
- package/src/api/events/message-complete.ts +2 -0
- package/src/api/events/notification-conversation-created.ts +14 -16
- package/src/api/events/notification-intent.ts +4 -2
- package/src/api/events/question-request.ts +1 -0
- package/src/api/events/tool-result.ts +85 -0
- package/src/api/events/tool-use-start.ts +3 -0
- package/src/api/events/user-message-echo.ts +3 -0
- package/src/api/index.ts +42 -6
- package/src/api/mode-session.test.ts +131 -0
- package/src/api/mode-session.ts +148 -0
- package/src/api/remember-tool.ts +15 -0
- package/src/api/responses/conversation-message.ts +9 -0
- package/src/approvals/AGENTS.md +4 -2
- package/src/approvals/approval-primitive.ts +5 -2
- package/src/approvals/scoped-approval-grants.ts +6 -2
- package/src/browser/__tests__/operations.test.ts +29 -0
- package/src/browser/operation-meta.ts +2 -1
- package/src/browser/operations.ts +29 -0
- package/src/browser/virtual-desktop-target.ts +2 -9
- package/src/bundler/bundle-signer.ts +1 -3
- package/src/calls/__tests__/barge-in-guard.test.ts +3 -0
- package/src/calls/__tests__/call-controller.test.ts +94 -0
- package/src/calls/__tests__/call-funnel-telemetry.test.ts +204 -0
- package/src/calls/__tests__/voice-control-protocol.test.ts +15 -0
- package/src/calls/__tests__/voice-escalation-judge.test.ts +209 -0
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +168 -0
- package/src/{live-voice/__tests__/live-voice-metrics.test.ts → calls/__tests__/voice-metrics.test.ts} +32 -38
- package/src/calls/__tests__/voice-session-bridge.test.ts +576 -122
- package/src/calls/barge-in-guard.ts +5 -0
- package/src/calls/call-controller.ts +196 -1
- package/src/calls/call-domain.ts +4 -0
- package/src/calls/call-store.ts +87 -2
- package/src/calls/guardian-action-sweep.ts +22 -8
- package/src/calls/media-stream-audio-transcode.ts +1 -3
- package/src/calls/typesafe-noul.ts +156 -0
- package/src/calls/voice-control-protocol.ts +6 -0
- package/src/calls/voice-escalation-judge.ts +145 -0
- package/src/calls/voice-escalation-target.ts +10 -0
- package/src/calls/voice-leg-coordinator.ts +121 -3
- package/src/{live-voice/live-voice-metrics.ts → calls/voice-metrics.ts} +94 -87
- package/src/calls/voice-session-bridge.ts +256 -112
- package/src/calls/voice-triage-escalate.ts +7 -0
- package/src/cli/__tests__/roadmap-cli.test.ts +4 -41
- package/src/cli/commands/__tests__/cli-test-harness.ts +21 -3
- package/src/cli/commands/__tests__/notifications.test.ts +35 -10
- package/src/cli/commands/__tests__/plugins.test.ts +20 -1
- package/src/cli/commands/__tests__/schedules.test.ts +14 -0
- package/src/cli/commands/bash.help.ts +4 -3
- package/src/cli/commands/browser.help.ts +9 -6
- package/src/cli/commands/browser.ts +0 -1
- package/src/cli/commands/clients.help.ts +46 -0
- package/src/cli/commands/clients.ts +116 -0
- package/src/cli/commands/credentials.help.ts +9 -4
- package/src/cli/commands/notifications.help.ts +16 -2
- package/src/cli/commands/notifications.ts +30 -8
- package/src/cli/commands/oauth/index.help.ts +10 -0
- package/src/cli/commands/oauth/providers.ts +12 -0
- package/src/cli/commands/oauth/request.test.ts +179 -2
- package/src/cli/commands/oauth/request.ts +41 -10
- package/src/cli/commands/plugins.ts +12 -5
- package/src/cli/commands/roadmap.help.ts +18 -21
- package/src/cli/commands/roadmap.ts +4 -21
- package/src/cli/commands/schedules.ts +2 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +41 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +5 -2
- package/src/cli/lib/__tests__/local-plugin-upgrade.test.ts +133 -51
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +8 -2
- package/src/cli/lib/bundled-marketplace.json +906 -1
- package/src/cli/lib/bundled-plugin-packages.json +783 -1
- package/src/cli/lib/inspect-plugin.ts +11 -4
- package/src/cli/lib/plugin-marketplace.ts +8 -0
- package/src/cli/lib/publish-plugin.ts +1 -2
- package/src/cli/lib/upgrade-plugin.ts +19 -11
- package/src/cli/output.ts +18 -4
- package/src/config/__tests__/default-provider.test.ts +6 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +14 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -1
- package/src/config/bundled-skills/computer-use/TOOLS.json +89 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +17 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +7 -11
- package/src/config/bundled-skills/schedule/SKILL.md +6 -6
- package/src/config/bundled-skills/sequences/TOOLS.json +1 -5
- package/src/config/call-site-defaults.ts +9 -0
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/loader.ts +9 -17
- package/src/config/platform-identity.ts +8 -8
- package/src/config/profile-text-generation.test.ts +51 -0
- package/src/config/profile-text-generation.ts +51 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +12 -0
- package/src/config/schemas/__tests__/tools.test.ts +31 -0
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/channels.ts +0 -18
- package/src/config/schemas/llm.ts +9 -2
- package/src/config/schemas/mcp.ts +6 -1
- package/src/config/schemas/memory-retrospective.ts +11 -2
- package/src/config/schemas/memory-v3.ts +12 -0
- package/src/config/schemas/services.ts +15 -6
- package/src/config/schemas/tools.ts +10 -0
- package/src/config/session-groups-gate.ts +21 -0
- package/src/config/skills.ts +2 -6
- package/src/conversations/__tests__/message-consolidation.test.ts +149 -0
- package/src/conversations/message-consolidation.ts +102 -5
- package/src/credential-execution/ces-connect.test.ts +69 -0
- package/src/credential-execution/ces-connect.ts +115 -0
- package/src/credential-execution/ces-runtime.ts +55 -93
- package/src/credential-execution/executable-discovery.ts +34 -142
- package/src/credential-execution/process-manager.test.ts +20 -24
- package/src/credential-execution/process-manager.ts +24 -19
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +10 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +43 -0
- package/src/daemon/__tests__/inference-profile-notification.test.ts +2 -0
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +36 -0
- package/src/daemon/assistant-attachments.ts +20 -12
- package/src/daemon/browser-mode-session.test.ts +402 -0
- package/src/daemon/browser-mode-session.ts +186 -0
- package/src/daemon/chat-credential-redaction.ts +16 -1
- package/src/daemon/computer-use-mode-session.test.ts +210 -0
- package/src/daemon/computer-use-mode-session.ts +105 -0
- package/src/daemon/config-watcher.ts +10 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +132 -13
- package/src/daemon/conversation-agent-loop.ts +231 -25
- package/src/daemon/conversation-attachments.ts +93 -12
- package/src/daemon/conversation-evictor.ts +5 -24
- package/src/daemon/conversation-history.ts +10 -0
- package/src/daemon/conversation-interrupt-repair.ts +4 -43
- package/src/daemon/conversation-interrupt.ts +7 -11
- package/src/daemon/conversation-messaging.ts +58 -5
- package/src/daemon/conversation-mode-session.test.ts +1667 -0
- package/src/daemon/conversation-mode-session.ts +1008 -0
- package/src/daemon/conversation-process.ts +5 -0
- package/src/daemon/conversation-runtime-assembly.ts +10 -20
- package/src/daemon/conversation-skill-tools.ts +1 -0
- package/src/daemon/conversation-store.ts +4 -4
- package/src/daemon/conversation-surface-snapshots.ts +135 -0
- package/src/daemon/conversation-surfaces.ts +113 -5
- package/src/daemon/conversation-tool-setup.ts +79 -6
- package/src/daemon/conversation-turn-finalize.ts +26 -13
- package/src/daemon/conversation.ts +215 -58
- package/src/daemon/daemon-control.ts +3 -7
- package/src/daemon/handlers/config-model.ts +7 -5
- package/src/daemon/handlers/shared.ts +55 -16
- package/src/daemon/host-cu-proxy.ts +51 -22
- package/src/daemon/lifecycle.ts +30 -13
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/message-protocol.ts +0 -1
- package/src/daemon/message-provenance.ts +28 -4
- package/src/daemon/message-types/shared.ts +1 -0
- package/src/daemon/mode-session-startup-recovery.ts +23 -0
- package/src/daemon/mode-session-tracking.ts +54 -0
- package/src/daemon/orphan-reaper.ts +4 -3
- package/src/daemon/persist-media-references.ts +20 -3
- package/src/daemon/process-message.ts +13 -4
- package/src/daemon/tool-setup-types.ts +6 -0
- package/src/daemon/virtual-desktop-context.ts +21 -0
- package/src/daemon/wake-conversation-ops.ts +50 -15
- package/src/desktop/__tests__/fake-desktop.ts +1 -0
- package/src/desktop/desktop-accessibility-script.ts +88 -0
- package/src/desktop/desktop-accessibility.test.ts +160 -0
- package/src/desktop/desktop-accessibility.ts +169 -0
- package/src/desktop/desktop-automation-lease.test.ts +302 -64
- package/src/desktop/desktop-automation-lease.ts +129 -54
- package/src/desktop/desktop-browser-endpoint.ts +4 -0
- package/src/desktop/desktop-computer-use-routing.test.ts +330 -0
- package/src/desktop/desktop-computer-use.test.ts +449 -0
- package/src/desktop/desktop-computer-use.ts +502 -0
- package/src/desktop/desktop-dependencies.ts +47 -293
- package/src/desktop/desktop-display.ts +2 -2
- package/src/desktop/desktop-help.ts +15 -0
- package/src/desktop/desktop-panel-config.test.ts +13 -3
- package/src/desktop/desktop-panel-config.ts +109 -15
- package/src/desktop/desktop-session-manager.test.ts +69 -21
- package/src/desktop/desktop-session-manager.ts +76 -22
- package/src/desktop/desktop-stream-bridge.test.ts +76 -132
- package/src/desktop/desktop-stream-bridge.ts +9 -11
- package/src/desktop/desktop-wallpaper-renderer.ts +132 -0
- package/src/desktop/desktop-wallpaper-worker.ts +17 -0
- package/src/desktop/desktop-wallpaper.test.ts +48 -7
- package/src/desktop/desktop-wallpaper.ts +34 -102
- package/src/desktop/desktop-window-theme.ts +5 -25
- package/src/desktop/virtual-desktop-feature.ts +53 -3
- package/src/desktop/virtual-desktop-platform.test.ts +5 -9
- package/src/documents/document-store.ts +23 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +22 -26
- package/src/heartbeat/heartbeat-service.ts +5 -33
- package/src/ipc/__tests__/browser-ipc.test.ts +215 -6
- package/src/ipc/assistant-server.ts +2 -0
- package/src/ipc/routes/__tests__/channel-reply-ipc-routes.test.ts +111 -0
- package/src/ipc/routes/channel-reply-ipc-routes.ts +73 -0
- package/src/live-voice/__tests__/continuation-judge.test.ts +151 -0
- package/src/live-voice/__tests__/live-activity-reporter.test.ts +154 -15
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +743 -31
- package/src/live-voice/__tests__/live-voice-look-follow-up.test.ts +191 -10
- package/src/live-voice/__tests__/live-voice-session-groups-gate.test.ts +87 -0
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +5 -1
- package/src/live-voice/__tests__/live-voice-sight-frame-echo.test.ts +41 -0
- package/src/live-voice/__tests__/live-voice-sight-frame.test.ts +1017 -9
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +224 -1
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +101 -0
- package/src/live-voice/__tests__/live-voice-tts.test.ts +44 -0
- package/src/live-voice/__tests__/live-voice-vad.test.ts +939 -75
- package/src/live-voice/__tests__/microphone-idle-gate.test.ts +87 -0
- package/src/live-voice/__tests__/session-controls.test.ts +23 -0
- package/src/live-voice/__tests__/task-outcomes.test.ts +117 -0
- package/src/live-voice/__tests__/voice-input-diagnostics.test.ts +117 -0
- package/src/live-voice/camera-mode-session.test.ts +265 -0
- package/src/live-voice/camera-mode-session.ts +277 -0
- package/src/live-voice/continuation-judge.ts +123 -0
- package/src/live-voice/live-activity-reporter.ts +115 -6
- package/src/live-voice/live-voice-manager.ts +36 -1
- package/src/live-voice/live-voice-photo.ts +88 -7
- package/src/live-voice/live-voice-session-manager.ts +15 -0
- package/src/live-voice/live-voice-session.ts +1443 -747
- package/src/live-voice/live-voice-tts.ts +22 -4
- package/src/live-voice/microphone-idle-gate.ts +56 -0
- package/src/live-voice/protocol.ts +171 -4
- package/src/live-voice/session-controls.ts +11 -3
- package/src/live-voice/task-outcomes.ts +131 -0
- package/src/live-voice/voice-input-diagnostics.ts +117 -0
- package/src/mcp/__tests__/manager-tool-caps.test.ts +156 -0
- package/src/mcp/__tests__/startup.test.ts +30 -7
- package/src/mcp/__tests__/tool-caps.test.ts +134 -0
- package/src/mcp/manager.ts +171 -101
- package/src/mcp/startup.ts +33 -13
- package/src/mcp/tool-caps.ts +184 -0
- package/src/media/__tests__/image-models.test.ts +58 -0
- package/src/media/image-credentials.ts +5 -0
- package/src/media/image-models.ts +52 -0
- package/src/media/image-service.ts +8 -0
- package/src/media/openrouter-image-service.test.ts +133 -0
- package/src/media/openrouter-image-service.ts +153 -0
- package/src/media/types.ts +1 -1
- package/src/messaging/provider-message-metadata.ts +3 -3
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +65 -11
- package/src/messaging/providers/discord/send.ts +4 -17
- package/src/messaging/providers/discord/transport.ts +2 -2
- package/src/messaging/providers/outlook/client.ts +16 -22
- package/src/messaging/providers/telegram-bot/send.test.ts +236 -1
- package/src/messaging/providers/telegram-bot/send.ts +10 -7
- package/src/messaging/providers/telegram-bot/transport.ts +3 -10
- package/src/messaging/providers/whatsapp/send.test.ts +169 -4
- package/src/monitoring/__tests__/control.test.ts +17 -5
- package/src/monitoring/control.ts +15 -5
- package/src/notifications/AGENTS.md +1 -1
- package/src/notifications/README.md +83 -99
- package/src/notifications/__tests__/broadcaster.test.ts +1 -1
- package/src/notifications/__tests__/channel-allowlist.test.ts +39 -0
- package/src/notifications/__tests__/copy-composer.test.ts +71 -1
- package/src/notifications/__tests__/decision-engine.test.ts +79 -2
- package/src/notifications/__tests__/deterministic-checks.test.ts +10 -10
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +93 -4
- package/src/notifications/__tests__/notification-utils.test.ts +18 -0
- package/src/notifications/adapters/macos.ts +37 -46
- package/src/notifications/broadcaster.ts +5 -6
- package/src/notifications/channel-allowlist.ts +44 -0
- package/src/notifications/copy-composer.ts +11 -26
- package/src/notifications/decision-engine.ts +24 -14
- package/src/notifications/deterministic-checks.ts +1 -1
- package/src/notifications/emit-signal.ts +123 -37
- package/src/notifications/home-feed-side-effect.ts +9 -7
- package/src/notifications/notification-utils.ts +19 -0
- package/src/notifications/schedule-result-producer.ts +4 -6
- package/src/notifications/signal.ts +4 -19
- package/src/notifications/types.ts +15 -0
- package/src/oauth/AGENTS.md +2 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +36 -1
- package/src/oauth/connection-resolver.ts +1 -2
- package/src/oauth/identity-verifier.ts +24 -0
- package/src/oauth/oauth-store.ts +12 -4
- package/src/oauth/provider-serializer.ts +8 -0
- package/src/oauth/seed-providers.ts +42 -0
- package/src/onboarding/onboarding-events-store.ts +99 -12
- package/src/permissions/confirmation-guardian-request.test.ts +16 -0
- package/src/permissions/confirmation-guardian-request.ts +2 -3
- package/src/permissions/question-prompter.test.ts +31 -0
- package/src/permissions/question-prompter.ts +2 -0
- package/src/persistence/__tests__/client-connection-events-store.test.ts +322 -0
- package/src/persistence/attachments-store.ts +84 -44
- package/src/persistence/client-connection-events-store.ts +377 -0
- package/src/persistence/conversation-crud.ts +166 -26
- package/src/persistence/conversation-mode-sessions.test.ts +424 -0
- package/src/persistence/conversation-mode-sessions.ts +460 -0
- package/src/persistence/conversation-plugin-facade.ts +30 -0
- package/src/persistence/conversation-queries.ts +6 -19
- package/src/persistence/conversation-tool-surface.ts +135 -0
- package/src/persistence/conversation-types.test.ts +32 -0
- package/src/persistence/conversation-types.ts +26 -4
- package/src/persistence/llm-usage-store.ts +3 -9
- package/src/persistence/message-metadata.ts +25 -0
- package/src/persistence/migrations/378-create-conversation-tool-surfaces.test.ts +78 -0
- package/src/persistence/migrations/378-create-conversation-tool-surfaces.ts +29 -0
- package/src/persistence/migrations/379-oauth-providers-response-ok-field.test.ts +92 -0
- package/src/persistence/migrations/379-oauth-providers-response-ok-field.ts +32 -0
- package/src/persistence/migrations/380-conversation-tool-surfaces-delegate-independent-tasks.test.ts +90 -0
- package/src/persistence/migrations/380-conversation-tool-surfaces-delegate-independent-tasks.ts +34 -0
- package/src/persistence/migrations/381-create-conversation-mode-sessions.ts +41 -0
- package/src/persistence/migrations/382-create-client-connection-events.ts +40 -0
- package/src/persistence/migrations/__tests__/382-create-client-connection-events.test.ts +56 -0
- package/src/persistence/schema/conversation-tool-surfaces.ts +32 -0
- package/src/persistence/schema/conversations.ts +67 -0
- package/src/persistence/schema/index.ts +1 -0
- package/src/persistence/schema/infrastructure.ts +29 -0
- package/src/persistence/schema/oauth.ts +1 -0
- package/src/persistence/steps.ts +41 -3
- package/src/plugin-api/__tests__/plugin-name-env.test.ts +249 -0
- package/src/plugin-api/conversation-turn.ts +31 -7
- package/src/plugin-api/effective-context-window.ts +33 -0
- package/src/plugin-api/index.ts +35 -6
- package/src/plugin-api/plugin-channel-turn-trust.test.ts +133 -0
- package/src/plugin-api/plugin-channel-turn-trust.ts +71 -0
- package/src/plugin-api/plugin-name-env.ts +125 -0
- package/src/plugin-api/resolve-credential.ts +79 -20
- package/src/plugin-api/vision-support.test.ts +22 -0
- package/src/plugin-api/vision-support.ts +17 -5
- package/src/plugins/__tests__/active-plugin-env.test.ts +136 -0
- package/src/plugins/active-plugin-env.ts +51 -0
- package/src/plugins/defaults/index.ts +24 -0
- package/src/plugins/defaults/memory/AGENTS.md +39 -5
- package/src/plugins/defaults/memory/__tests__/archive-removal-framing.test.ts +64 -0
- package/src/plugins/defaults/memory/__tests__/buffer-file.test.ts +365 -0
- package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +43 -0
- package/src/plugins/defaults/memory/__tests__/conversation-memory-purge.test.ts +1 -0
- package/src/plugins/defaults/memory/__tests__/db-memory-attach.test.ts +2 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/buffer-appender.ts +17 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +74 -0
- package/src/plugins/defaults/memory/__tests__/memory-run-evidence.test.ts +161 -0
- package/src/plugins/defaults/memory/__tests__/relocated-memory-test-rows.ts +10 -0
- package/src/plugins/defaults/memory/__tests__/worker-control.test.ts +19 -6
- package/src/plugins/defaults/memory/buffer-file.ts +354 -0
- package/src/plugins/defaults/memory/buffer-format.ts +40 -0
- package/src/plugins/defaults/memory/context-search/agent-protocol.ts +9 -12
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +77 -22
- package/src/plugins/defaults/memory/context-search/format.ts +53 -8
- package/src/plugins/defaults/memory/context-search/limits.ts +10 -12
- package/src/plugins/defaults/memory/context-search/recall-input.ts +38 -0
- package/src/plugins/defaults/memory/context-search/search.ts +8 -14
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +1 -0
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +2 -1
- package/src/plugins/defaults/memory/context-search/sources/workspace.ts +2 -1
- package/src/plugins/defaults/memory/context-search/types.ts +1 -11
- package/src/plugins/defaults/memory/conversation-memory-purge.ts +4 -0
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +11 -4
- package/src/plugins/defaults/memory/graph/capability-seed.ts +1 -2
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +13 -63
- package/src/plugins/defaults/memory/graph/tools.ts +35 -64
- package/src/plugins/defaults/memory/host-utils.ts +0 -10
- package/src/plugins/defaults/memory/injectors.ts +4 -3
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +72 -183
- package/src/plugins/defaults/memory/memory-run-evidence.ts +213 -0
- package/src/plugins/defaults/memory/src/memory-eval-routes.ts +2 -3
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +6 -1
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +2 -1
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +407 -99
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +10 -0
- package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +107 -7
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +307 -86
- package/src/plugins/defaults/memory/substrate/consolidation-tool-surface.ts +34 -0
- package/src/plugins/defaults/memory/substrate/page-index.ts +2 -1
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +91 -51
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +1 -1
- package/src/plugins/defaults/memory/tools.test.ts +124 -9
- package/src/plugins/defaults/memory/tools.ts +38 -11
- package/src/plugins/defaults/memory/v1/graph/consolidation.ts +2 -2
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +2 -1
- package/src/plugins/defaults/memory/v1/graph/retriever.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +5 -0
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +5 -2
- package/src/plugins/defaults/memory/v2/reranker.ts +2 -1
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +81 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +87 -0
- package/src/plugins/defaults/memory/v3/__tests__/plugin-schema.test.ts +12 -0
- package/src/plugins/defaults/memory/v3/__tests__/pool-log-store.test.ts +332 -15
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +626 -27
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +148 -28
- package/src/plugins/defaults/memory/v3/card.ts +2 -1
- package/src/plugins/defaults/memory/v3/injector.ts +212 -178
- package/src/plugins/defaults/memory/v3/orchestrate.ts +159 -32
- package/src/plugins/defaults/memory/v3/plugin-schema.ts +54 -4
- package/src/plugins/defaults/memory/v3/pool-log-store.ts +275 -37
- package/src/plugins/defaults/memory/v3/pool-select.test.ts +47 -5
- package/src/plugins/defaults/memory/v3/pool-select.ts +710 -59
- package/src/plugins/defaults/memory/v3/sections.ts +2 -1
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +41 -14
- package/src/plugins/defaults/memory/worker-control.ts +15 -5
- package/src/plugins/defaults/task-progress/__tests__/registration.test.ts +70 -0
- package/src/plugins/defaults/task-progress/__tests__/task-progress-context.test.ts +380 -0
- package/src/plugins/defaults/task-progress/hooks/post-compact.ts +19 -0
- package/src/plugins/defaults/task-progress/hooks/user-prompt-submit.ts +24 -0
- package/src/plugins/defaults/task-progress/package.json +14 -0
- package/src/plugins/defaults/task-progress/src/apply-task-progress-context.ts +93 -0
- package/src/plugins/defaults/task-progress/src/format-task-progress-context.ts +67 -0
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +4 -1
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +1 -46
- package/src/prompts/__tests__/parallel-tasks-section.test.ts +25 -0
- package/src/prompts/delegation-gate.ts +57 -0
- package/src/prompts/system-prompt.ts +14 -32
- package/src/providers/__tests__/context-overflow-error.test.ts +10 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +18 -0
- package/src/providers/anthropic/client.ts +10 -1
- package/src/providers/anthropic-gateway-shared.ts +6 -0
- package/src/providers/fetch-provider-catalog.ts +11 -0
- package/src/providers/gemini/client.ts +25 -8
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/jev/client.test.ts +270 -0
- package/src/providers/jev/client.ts +534 -0
- package/src/providers/model-catalog.ts +59 -3
- package/src/providers/openai/__tests__/chat-completions-extra-body.test.ts +94 -1
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +106 -1
- package/src/providers/openai/__tests__/chat-template-flatten.test.ts +24 -0
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +1 -2
- package/src/providers/openai/chat-completions-provider.ts +100 -29
- package/src/providers/openai/google-thought-signature.ts +0 -6
- package/src/providers/openai/responses-provider.ts +23 -1
- package/src/providers/ratelimit.ts +1 -3
- package/src/providers/search-provider-catalog.ts +24 -0
- package/src/providers/server-tool-pairing.ts +16 -7
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +24 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +7 -1
- package/src/providers/speech-to-text/__tests__/vellum-managed-realtime.test.ts +50 -1
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +11 -0
- package/src/providers/speech-to-text/vellum-managed-flux-realtime.ts +13 -0
- package/src/providers/types.ts +5 -0
- package/src/routes/control.ts +7 -5
- package/src/runtime/AGENTS.md +6 -4
- package/src/runtime/__tests__/agent-wake.test.ts +94 -1
- package/src/runtime/actor-trust-resolver.ts +3 -3
- package/src/runtime/agent-wake.ts +32 -5
- package/src/runtime/approval-message-composer.ts +3 -69
- package/src/runtime/assistant-event-hub.ts +73 -75
- package/src/runtime/assistant-event-publish-options.ts +7 -0
- package/src/runtime/assistant-event-targeting.ts +79 -0
- package/src/runtime/assistant-stream-state.ts +13 -100
- package/src/runtime/background-job-runner.ts +5 -5
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/guardian-action-message-composer.ts +8 -161
- package/src/runtime/guardian-action-service.ts +2 -17
- package/src/runtime/guardian-reply-router.ts +29 -40
- package/src/runtime/http-server.ts +2 -2
- package/src/runtime/http-types.ts +6 -0
- package/src/runtime/message-composer-types.ts +3 -61
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +67 -1
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +89 -0
- package/src/runtime/migrations/vbundle-builder.ts +24 -1
- package/src/runtime/migrations/vbundle-import-analyzer.ts +13 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +43 -11
- package/src/runtime/migrations/vbundle-importer.ts +4 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +4 -1
- package/src/runtime/migrations/vbundle-validator.ts +1 -0
- package/src/runtime/pending-interactions-mode-session.test.ts +62 -0
- package/src/runtime/pending-interactions.ts +29 -0
- package/src/runtime/routes/__tests__/client-history-routes.test.ts +104 -0
- package/src/runtime/routes/__tests__/image-generation-routes.test.ts +97 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +24 -2
- package/src/runtime/routes/__tests__/roadmap-routes.test.ts +29 -6
- package/src/runtime/routes/browser-context.ts +31 -11
- package/src/runtime/routes/browser-routes.ts +43 -4
- package/src/runtime/routes/btw-routes.ts +9 -4
- package/src/runtime/routes/channel-route-shared.ts +1 -9
- package/src/runtime/routes/client-routes.ts +108 -0
- package/src/runtime/routes/conversation-management-routes.ts +4 -1
- package/src/runtime/routes/conversation-routes.ts +125 -14
- package/src/runtime/routes/credential-prompt-routes.ts +4 -3
- package/src/runtime/routes/credential-routes.ts +1 -2
- package/src/runtime/routes/desktop-setup-routes.test.ts +9 -18
- package/src/runtime/routes/desktop-setup-routes.ts +8 -7
- package/src/runtime/routes/documents-routes.ts +51 -0
- package/src/runtime/routes/email-routes.ts +3 -7
- package/src/runtime/routes/events-routes.ts +75 -54
- package/src/runtime/routes/guardian-approval-interception.ts +24 -0
- package/src/runtime/routes/identity-routes.ts +1 -5
- package/src/runtime/routes/image-generation-routes.ts +8 -14
- package/src/runtime/routes/inbound-message-handler.ts +37 -41
- package/src/runtime/routes/inbound-stages/backfill-sender-provenance.test.ts +168 -0
- package/src/runtime/routes/inbound-stages/backfill-sender-provenance.ts +96 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +39 -10
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +9 -9
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +2 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +11 -1
- package/src/runtime/routes/inference-profiles-routes.ts +9 -0
- package/src/runtime/routes/llm-context-normalization.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +73 -2
- package/src/runtime/routes/notification-routes.ts +10 -0
- package/src/runtime/routes/oauth-commands-routes.ts +57 -54
- package/src/runtime/routes/oauth-providers.ts +11 -0
- package/src/runtime/routes/oauth-request-hints.test.ts +246 -0
- package/src/runtime/routes/oauth-request-hints.ts +149 -0
- package/src/runtime/routes/plugins-routes.ts +6 -0
- package/src/runtime/routes/roadmap-routes.ts +47 -8
- package/src/runtime/routes/schedule-routes.ts +2 -0
- package/src/runtime/routes/secret-routes.ts +99 -119
- package/src/runtime/routes/settings-routes.ts +10 -4
- package/src/runtime/routes/watcher-routes.ts +1 -3
- package/src/runtime/trust-class.test.ts +7 -6
- package/src/runtime/trust-class.ts +9 -17
- package/src/schedule/__tests__/worker-control.test.ts +36 -5
- package/src/schedule/__tests__/worker-mcp-bootstrap.test.ts +107 -0
- package/src/schedule/__tests__/worker-mcp-readiness.test.ts +173 -0
- package/src/schedule/__tests__/worker-mcp-tools.test.ts +13 -47
- package/src/schedule/run-script.ts +2 -2
- package/src/schedule/scheduler.ts +47 -11
- package/src/schedule/tool-surface-readiness.ts +65 -0
- package/src/schedule/worker-control.ts +15 -5
- package/src/schedule/worker-mcp.ts +85 -0
- package/src/schedule/worker.ts +9 -31
- package/src/security/secure-keys.ts +74 -112
- package/src/skills/clawhub.ts +3 -8
- package/src/skills/managed-store.ts +1 -5
- package/src/stt/types.ts +4 -0
- package/src/subagent/notify.ts +54 -34
- package/src/subagent/parent-notification.ts +6 -0
- package/src/telemetry/__tests__/phone-call-funnel.test.ts +72 -0
- package/src/telemetry/phone-call-funnel.ts +144 -0
- package/src/tools/__tests__/tool-schema-root-combinator-guard.test.ts +81 -0
- package/src/tools/ask-question/ask-question-tool.test.ts +167 -5
- package/src/tools/ask-question/ask-question-tool.ts +120 -22
- package/src/tools/browser/browser-execution.ts +29 -60
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +561 -39
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +435 -39
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +1 -8
- package/src/tools/client-os.ts +15 -0
- package/src/tools/computer-use/skill-proxy-bridge.ts +1 -1
- package/src/tools/computer-use/target.ts +42 -0
- package/src/tools/document/document-tool.ts +13 -18
- package/src/tools/execution-target.ts +14 -16
- package/src/tools/host-terminal/host-shell.ts +16 -7
- package/src/tools/network/__tests__/web-fetch-tinyfish.test.ts +250 -0
- package/src/tools/network/__tests__/web-search.test.ts +203 -0
- package/src/tools/network/web-fetch.ts +274 -7
- package/src/tools/network/web-search.ts +468 -6
- package/src/tools/permission-checker.ts +3 -3
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/shared/filesystem/file-ops-service.ts +1 -31
- package/src/tools/shared/shell-output.test.ts +10 -0
- package/src/tools/shared/shell-output.ts +14 -2
- package/src/tools/skills/load.ts +2 -1
- package/src/tools/skills/sandbox-runner.ts +24 -4
- package/src/tools/skills/scaffold-managed.ts +2 -1
- package/src/tools/skills/skill-script-runner.ts +7 -0
- package/src/tools/skills/skill-tool-factory.ts +15 -1
- package/src/tools/terminal/__tests__/safe-env.test.ts +44 -4
- package/src/tools/terminal/__tests__/sanitized-bash.test.ts +0 -14
- package/src/tools/terminal/safe-env.ts +39 -24
- package/src/tools/terminal/sanitized-bash.ts +15 -2
- package/src/tools/terminal/shell-launch.test.ts +162 -0
- package/src/tools/terminal/shell.test.ts +29 -0
- package/src/tools/terminal/shell.ts +15 -7
- package/src/tools/tool-approval-handler.ts +5 -1
- package/src/tools/tool-types.ts +3 -3
- package/src/tools/types.ts +8 -2
- package/src/util/__tests__/worker-process-command.test.ts +5 -4
- package/src/util/abort-reasons.ts +18 -26
- package/src/util/browser-human-verification.ts +14 -0
- package/src/util/canonicalize-identity.test.ts +21 -0
- package/src/util/canonicalize-identity.ts +16 -0
- package/src/util/errors.ts +13 -3
- package/src/util/host-process.test.ts +17 -1
- package/src/util/host-process.ts +24 -0
- package/src/util/provider-error-patterns.ts +3 -0
- package/src/util/unicode.ts +29 -0
- package/src/util/worker-process.ts +77 -35
- package/src/workspace/migrations/157-add-desktop-files-launcher.ts +94 -0
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +4 -10
- package/src/workspace/migrations/__tests__/157-add-desktop-files-launcher.test.ts +113 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/__tests__/computer-use-window-schema.test.ts +0 -24
- package/src/api/events/heartbeat-alert.ts +0 -20
- package/src/daemon/message-types/web-activity.ts +0 -65
- package/src/desktop/desktop-dependencies.test.ts +0 -131
- package/src/tools/computer-use/definitions.ts +0 -607
|
@@ -1,182 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Guardian action message composition.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Follows the same pattern as approval-message-composer.ts.
|
|
4
|
+
* Returns the deterministic, voice-friendly copy for a guardian action
|
|
5
|
+
* notice. The only notice left is the one the expiry sweep
|
|
6
|
+
* (`calls/guardian-action-sweep.ts`) sends to each place a guardian request
|
|
7
|
+
* was delivered once the request expires unanswered.
|
|
10
8
|
*/
|
|
11
|
-
import type {
|
|
12
|
-
ComposeGuardianActionMessageOptions,
|
|
13
|
-
GuardianActionMessageContext,
|
|
14
|
-
} from "./message-composer-types.js";
|
|
9
|
+
import type { GuardianActionMessageContext } from "./message-composer-types.js";
|
|
15
10
|
|
|
16
11
|
export type {
|
|
17
|
-
ComposeGuardianActionMessageOptions,
|
|
18
12
|
GuardianActionMessageContext,
|
|
19
13
|
GuardianActionMessageScenario,
|
|
20
14
|
} from "./message-composer-types.js";
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// ---------------------------------------------------------------------------
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Compose user-facing guardian action copy using the daemon-injected generator
|
|
28
|
-
* when available, with deterministic fallback for reliability.
|
|
29
|
-
*
|
|
30
|
-
* The generator parameter is the daemon-provided function that knows about
|
|
31
|
-
* providers. When absent (or in test env), only the deterministic fallback
|
|
32
|
-
* is used.
|
|
33
|
-
*/
|
|
34
|
-
export async function composeGuardianActionMessageGenerative(
|
|
35
|
-
context: GuardianActionMessageContext,
|
|
36
|
-
options: ComposeGuardianActionMessageOptions = {},
|
|
37
|
-
): Promise<string> {
|
|
38
|
-
const fallbackText =
|
|
39
|
-
options.fallbackText?.trim() || getGuardianActionFallbackMessage(context);
|
|
40
|
-
|
|
41
|
-
if (process.env.NODE_ENV === "test") {
|
|
42
|
-
return fallbackText;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return fallbackText;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** @internal Exported for use by the daemon-injected generator implementation. */
|
|
49
|
-
export function includesRequiredKeywords(
|
|
50
|
-
text: string,
|
|
51
|
-
requiredKeywords: string[] | undefined,
|
|
52
|
-
): boolean {
|
|
53
|
-
if (!requiredKeywords || requiredKeywords.length === 0) {
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
return requiredKeywords.every((keyword) => {
|
|
57
|
-
const re = new RegExp(`\\b${RegExp.escape(keyword)}\\b`, "i");
|
|
58
|
-
return re.test(text);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
|
-
// Deterministic fallback templates
|
|
64
|
-
// ---------------------------------------------------------------------------
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Return a scenario-specific deterministic fallback message.
|
|
68
|
-
*
|
|
69
|
-
* Each template produces natural, conversational text suitable for voice
|
|
70
|
-
* delivery.
|
|
71
|
-
*/
|
|
72
|
-
export function getGuardianActionFallbackMessage(
|
|
16
|
+
/** Compose the user-facing copy for a guardian action notice. */
|
|
17
|
+
export function composeGuardianActionMessage(
|
|
73
18
|
context: GuardianActionMessageContext,
|
|
74
19
|
): string {
|
|
75
|
-
const listedCodes = formatGuardianRequestCodes(context.requestCodes);
|
|
76
|
-
|
|
77
20
|
switch (context.scenario) {
|
|
78
|
-
case "caller_timeout_acknowledgment":
|
|
79
|
-
return context.guardianIdentifier
|
|
80
|
-
? `I wasn't able to reach ${context.guardianIdentifier} right now. I'm sorry about that.`
|
|
81
|
-
: "I wasn't able to reach the guardian right now. I'm sorry about that.";
|
|
82
|
-
|
|
83
|
-
case "caller_timeout_continue":
|
|
84
|
-
return "Would you like me to leave a message for them to get back to you, or is there anything else I can help with?";
|
|
85
|
-
|
|
86
|
-
case "guardian_late_answer_followup":
|
|
87
|
-
return context.callerIdentifier
|
|
88
|
-
? `${context.callerIdentifier} called earlier with a question, but I wasn't able to connect them. Would you like to call them back?`
|
|
89
|
-
: "Someone called earlier with a question, but I wasn't able to connect them. Would you like to call them back?";
|
|
90
|
-
|
|
91
|
-
case "guardian_followup_dispatching":
|
|
92
|
-
return context.followupAction
|
|
93
|
-
? `Got it, I'll ${context.followupAction} now.`
|
|
94
|
-
: "Got it, I'm taking care of that now.";
|
|
95
|
-
|
|
96
|
-
case "guardian_followup_completed":
|
|
97
|
-
return context.followupAction
|
|
98
|
-
? `Done! I've ${context.followupAction} successfully.`
|
|
99
|
-
: "Done! That's been taken care of.";
|
|
100
|
-
|
|
101
|
-
case "guardian_followup_failed":
|
|
102
|
-
return context.failureReason
|
|
103
|
-
? `I'm sorry, I wasn't able to complete that. ${context.failureReason}`
|
|
104
|
-
: "I'm sorry, I wasn't able to complete that. Please try again later.";
|
|
105
|
-
|
|
106
|
-
case "guardian_followup_declined_ack":
|
|
107
|
-
return "No problem. Let me know if you change your mind or need anything else.";
|
|
108
|
-
|
|
109
|
-
case "guardian_followup_clarification":
|
|
110
|
-
return "Sorry, I didn't quite catch that. Would you like to call them back or skip it for now?";
|
|
111
|
-
|
|
112
|
-
case "guardian_pending_disambiguation":
|
|
113
|
-
return listedCodes
|
|
114
|
-
? `You have multiple pending guardian questions. Please prefix your reply with the reference code (${listedCodes}) so I know which question you're answering.`
|
|
115
|
-
: "You have multiple pending guardian questions. Please prefix your reply with the reference code so I know which question you're answering.";
|
|
116
|
-
|
|
117
|
-
case "guardian_expired_disambiguation":
|
|
118
|
-
return listedCodes
|
|
119
|
-
? `You have multiple expired guardian questions. Please prefix your reply with the reference code (${listedCodes}) so I know which question you're answering.`
|
|
120
|
-
: "You have multiple expired guardian questions. Please prefix your reply with the reference code so I know which question you're answering.";
|
|
121
|
-
|
|
122
|
-
case "guardian_followup_disambiguation":
|
|
123
|
-
return listedCodes
|
|
124
|
-
? `You have multiple pending follow-up questions. Please prefix your reply with the reference code (${listedCodes}) so I know which question you're responding to.`
|
|
125
|
-
: "You have multiple pending follow-up questions. Please prefix your reply with the reference code so I know which question you're responding to.";
|
|
126
|
-
|
|
127
|
-
case "guardian_stale_answered":
|
|
128
|
-
return "This question has already been answered from another channel.";
|
|
129
|
-
|
|
130
21
|
case "guardian_stale_expired":
|
|
131
22
|
return "That request has already expired. No further action is needed.";
|
|
132
23
|
|
|
133
|
-
case "guardian_stale_followup":
|
|
134
|
-
return "It looks like this follow-up has already been handled. No further action is needed.";
|
|
135
|
-
|
|
136
|
-
case "guardian_stale_superseded":
|
|
137
|
-
return "This request is no longer active. The call has ended and no further action is needed.";
|
|
138
|
-
|
|
139
|
-
case "guardian_unknown_code":
|
|
140
|
-
return context.unknownCode
|
|
141
|
-
? `I don't recognize the code "${context.unknownCode}". Please check the reference code and try again.`
|
|
142
|
-
: "I don't recognize that reference code. Please check the code and try again.";
|
|
143
|
-
|
|
144
|
-
case "guardian_auto_matched":
|
|
145
|
-
return "Got it, routing your answer to the active request.";
|
|
146
|
-
|
|
147
|
-
case "guardian_superseded_remap":
|
|
148
|
-
return context.questionText
|
|
149
|
-
? `Got it! Your answer has been applied to the current active request: "${context.questionText}"`
|
|
150
|
-
: "Got it! Your answer has been applied to the current active request on the call.";
|
|
151
|
-
|
|
152
|
-
case "followup_call_started":
|
|
153
|
-
return context.counterpartyPhone
|
|
154
|
-
? `Got it! I'm calling ${context.counterpartyPhone} back now to relay your answer.`
|
|
155
|
-
: "Got it! I'm calling them back now to relay your answer.";
|
|
156
|
-
|
|
157
|
-
case "followup_action_failed":
|
|
158
|
-
return context.failureReason
|
|
159
|
-
? `I'm sorry, I wasn't able to complete that. ${context.failureReason}`
|
|
160
|
-
: "I'm sorry, something went wrong and I couldn't complete that action. Please try again later.";
|
|
161
|
-
|
|
162
|
-
case "guardian_answer_delivery_failed":
|
|
163
|
-
return "I wasn't able to deliver your answer to the call. The call may have ended. Please try again or follow up directly.";
|
|
164
|
-
|
|
165
24
|
default: {
|
|
166
25
|
const _exhaustive: never = context.scenario;
|
|
167
26
|
return `Guardian action update. ${String(_exhaustive)}`;
|
|
168
27
|
}
|
|
169
28
|
}
|
|
170
29
|
}
|
|
171
|
-
|
|
172
|
-
function formatGuardianRequestCodes(
|
|
173
|
-
requestCodes: string[] | undefined,
|
|
174
|
-
): string {
|
|
175
|
-
if (!Array.isArray(requestCodes)) {
|
|
176
|
-
return "";
|
|
177
|
-
}
|
|
178
|
-
const cleaned = requestCodes
|
|
179
|
-
.map((code) => code.trim())
|
|
180
|
-
.filter((code) => code.length > 0);
|
|
181
|
-
return cleaned.join(", ");
|
|
182
|
-
}
|
|
@@ -16,21 +16,6 @@ import {
|
|
|
16
16
|
isApprovalAction,
|
|
17
17
|
} from "./channel-approval-types.js";
|
|
18
18
|
|
|
19
|
-
// ---------------------------------------------------------------------------
|
|
20
|
-
// Constants
|
|
21
|
-
// ---------------------------------------------------------------------------
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Legacy actions that map to canonical ones during client rollout.
|
|
25
|
-
* All temporal/persistent approval variants collapse to approve_once.
|
|
26
|
-
* Keep until all clients are updated and no in-flight buttons remain.
|
|
27
|
-
*/
|
|
28
|
-
const LEGACY_ACTION_MAP: Record<string, string> = {
|
|
29
|
-
approve_10m: "approve_once",
|
|
30
|
-
approve_conversation: "approve_once",
|
|
31
|
-
approve_always: "approve_once",
|
|
32
|
-
};
|
|
33
|
-
|
|
34
19
|
// ---------------------------------------------------------------------------
|
|
35
20
|
// Types
|
|
36
21
|
// ---------------------------------------------------------------------------
|
|
@@ -98,8 +83,8 @@ export async function processGuardianDecision(
|
|
|
98
83
|
): Promise<ProcessGuardianDecisionResult> {
|
|
99
84
|
const { requestId, conversationId, channel, actorContext } = params;
|
|
100
85
|
|
|
101
|
-
// 1.
|
|
102
|
-
const action =
|
|
86
|
+
// 1. Validate the action
|
|
87
|
+
const action = params.action;
|
|
103
88
|
if (!isApprovalAction(action)) {
|
|
104
89
|
return {
|
|
105
90
|
ok: false,
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared guardian reply router
|
|
2
|
+
* Shared guardian reply router.
|
|
3
3
|
*
|
|
4
|
-
* Provides a single entry point (`routeGuardianReply`) for
|
|
5
|
-
*
|
|
4
|
+
* Provides a single entry point (`routeGuardianReply`) for every guardian
|
|
5
|
+
* reply typed in the app (`daemon/conversation-process.ts`,
|
|
6
|
+
* `routes/conversation-routes.ts`) and every reply or button press arriving
|
|
7
|
+
* on a channel (`routes/inbound-stages/guardian-reply-intercept.ts`). App
|
|
8
|
+
* card buttons decide through `processGuardianDecision()` instead. Routes
|
|
6
9
|
* through a priority-ordered pipeline:
|
|
7
10
|
*
|
|
8
|
-
* 1. Deterministic callback/ref parsing (button presses with `apr:<requestId>:<action>`)
|
|
11
|
+
* 1. Deterministic callback/ref parsing (channel button presses with `apr:<requestId>:<action>`)
|
|
9
12
|
* 2. Request code parsing (6-char alphanumeric prefix matching)
|
|
10
|
-
*
|
|
13
|
+
* 2.5. Invite handoff: "open invite flow" with a pending access request
|
|
14
|
+
* passes through to the normal assistant turn
|
|
15
|
+
* 2.55. Bare-text answer to the single pending question, in the
|
|
16
|
+
* conversation it was asked in
|
|
17
|
+
* 2.6. Explicit approve/reject phrase: applied when exactly one request is
|
|
18
|
+
* pending, answered with a disambiguation reply when several are
|
|
19
|
+
* 3. NL classification via the conversational approval engine, only when
|
|
20
|
+
* the caller passes an `approvalConversationGenerator` (app sessions do
|
|
21
|
+
* not, so for them 2.6 is the last plain-text stage)
|
|
11
22
|
*
|
|
12
23
|
* All decisions flow through `applyGuardianDecision`, which handles identity
|
|
13
24
|
* validation, expiry checks, the atomic gateway CAS+outcome commit,
|
|
@@ -153,12 +164,6 @@ export interface GuardianReplyResult {
|
|
|
153
164
|
// Callback data parser — format: "apr:<requestId>:<action>"
|
|
154
165
|
// ---------------------------------------------------------------------------
|
|
155
166
|
|
|
156
|
-
const LEGACY_CALLBACK_MAP: Record<string, string> = {
|
|
157
|
-
approve_10m: "approve_once",
|
|
158
|
-
approve_conversation: "approve_once",
|
|
159
|
-
approve_always: "approve_once",
|
|
160
|
-
};
|
|
161
|
-
|
|
162
167
|
interface ParsedCallback {
|
|
163
168
|
requestId: string;
|
|
164
169
|
action: ApprovalAction;
|
|
@@ -170,8 +175,7 @@ function parseCallbackAction(data: string): ParsedCallback | null {
|
|
|
170
175
|
return null;
|
|
171
176
|
}
|
|
172
177
|
const requestId = parts[1];
|
|
173
|
-
const
|
|
174
|
-
const action = LEGACY_CALLBACK_MAP[rawAction] ?? rawAction;
|
|
178
|
+
const action = parts.slice(2).join(":");
|
|
175
179
|
if (!requestId || !isApprovalAction(action)) {
|
|
176
180
|
return null;
|
|
177
181
|
}
|
|
@@ -324,17 +328,8 @@ function notConsumed(): GuardianReplyResult {
|
|
|
324
328
|
// ---------------------------------------------------------------------------
|
|
325
329
|
|
|
326
330
|
/**
|
|
327
|
-
* Route
|
|
328
|
-
*
|
|
329
|
-
* This is the single entry point for all inbound guardian reply processing.
|
|
330
|
-
* It handles messages from any channel (Telegram, WhatsApp) and
|
|
331
|
-
* routes through priority-ordered matching:
|
|
332
|
-
*
|
|
333
|
-
* 1. Deterministic callback parsing (button presses)
|
|
334
|
-
* 2. Request code parsing (6-char alphanumeric prefix)
|
|
335
|
-
* 3. NL classification via the conversational approval engine
|
|
336
|
-
*
|
|
337
|
-
* All decisions flow through `applyGuardianDecision`.
|
|
331
|
+
* Route a guardian reply through the priority-ordered pipeline described in
|
|
332
|
+
* the file header. All decisions flow through `applyGuardianDecision`.
|
|
338
333
|
*/
|
|
339
334
|
export async function routeGuardianReply(
|
|
340
335
|
ctx: GuardianReplyContext,
|
|
@@ -395,7 +390,7 @@ export async function routeGuardianReply(
|
|
|
395
390
|
const request = await getGuardianRequestOrNull(answerTap.requestId);
|
|
396
391
|
if (
|
|
397
392
|
request &&
|
|
398
|
-
|
|
393
|
+
resolveGuardianInstructionModeForRequest(request) === "answer" &&
|
|
399
394
|
parseQuestionAnswerActionId(answerTap.token) &&
|
|
400
395
|
!request.callSessionId &&
|
|
401
396
|
hasLiveQuestionInteraction(request.id)
|
|
@@ -588,7 +583,7 @@ export async function routeGuardianReply(
|
|
|
588
583
|
if (messageText.length > 0 && pendingRequests.length === 1) {
|
|
589
584
|
const soleRequest = pendingRequests[0];
|
|
590
585
|
if (
|
|
591
|
-
|
|
586
|
+
resolveGuardianInstructionModeForRequest(soleRequest) === "answer" &&
|
|
592
587
|
!soleRequest.callSessionId &&
|
|
593
588
|
soleRequest.sourceConversationId === conversationId &&
|
|
594
589
|
hasLiveQuestionInteraction(soleRequest.id)
|
|
@@ -670,11 +665,11 @@ export async function routeGuardianReply(
|
|
|
670
665
|
);
|
|
671
666
|
|
|
672
667
|
if (engineResult.disposition === "keep_pending") {
|
|
673
|
-
//
|
|
674
|
-
//
|
|
675
|
-
//
|
|
676
|
-
//
|
|
677
|
-
// a generic "I couldn't process that" message.
|
|
668
|
+
// keep_pending covers model indecision and every fail-closed path in
|
|
669
|
+
// runApprovalConversationTurn (generator error, malformed output, a
|
|
670
|
+
// decision without the targetRequestId that multi-pending requires).
|
|
671
|
+
// With several requests pending, answer with a disambiguation reply
|
|
672
|
+
// instead of a generic "I couldn't process that" message.
|
|
678
673
|
if (pendingRequestsForClassification.length > 1) {
|
|
679
674
|
log.info(
|
|
680
675
|
{
|
|
@@ -1012,12 +1007,6 @@ function inferActionFromText(
|
|
|
1012
1007
|
return "approve_once";
|
|
1013
1008
|
}
|
|
1014
1009
|
|
|
1015
|
-
function resolveRequestInstructionMode(
|
|
1016
|
-
request?: Pick<GuardianRequestWire, "kind" | "toolName"> | null,
|
|
1017
|
-
): "approval" | "answer" {
|
|
1018
|
-
return resolveGuardianInstructionModeForRequest(request);
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
1010
|
// ---------------------------------------------------------------------------
|
|
1022
1011
|
// Failure reason reply text
|
|
1023
1012
|
// ---------------------------------------------------------------------------
|
|
@@ -1051,7 +1040,7 @@ function failureReplyText(
|
|
|
1051
1040
|
return "Something went wrong with this request on our end, so I couldn't apply your decision.";
|
|
1052
1041
|
case "invalid_action":
|
|
1053
1042
|
return buildGuardianInvalidActionReply(
|
|
1054
|
-
|
|
1043
|
+
resolveGuardianInstructionModeForRequest(request),
|
|
1055
1044
|
requestCode ?? undefined,
|
|
1056
1045
|
);
|
|
1057
1046
|
default:
|
|
@@ -1070,7 +1059,7 @@ function failureReplyText(
|
|
|
1070
1059
|
*/
|
|
1071
1060
|
function composeCodeOnlyClarification(request: GuardianRequestWire): string {
|
|
1072
1061
|
const code = request.requestCode ?? "unknown";
|
|
1073
|
-
const mode =
|
|
1062
|
+
const mode = resolveGuardianInstructionModeForRequest(request);
|
|
1074
1063
|
return buildGuardianCodeOnlyClarification(mode, {
|
|
1075
1064
|
requestCode: code,
|
|
1076
1065
|
questionText: request.questionText,
|
|
@@ -1094,7 +1083,7 @@ function composeDisambiguationReply(
|
|
|
1094
1083
|
const lines: string[] = [];
|
|
1095
1084
|
const requestsWithMode = pendingRequests.map((request) => ({
|
|
1096
1085
|
request,
|
|
1097
|
-
mode:
|
|
1086
|
+
mode: resolveGuardianInstructionModeForRequest(request),
|
|
1098
1087
|
}));
|
|
1099
1088
|
|
|
1100
1089
|
if (engineReplyText) {
|
|
@@ -254,9 +254,9 @@ type AllWebSocketData =
|
|
|
254
254
|
|
|
255
255
|
function virtualDesktopEnabled(): boolean {
|
|
256
256
|
try {
|
|
257
|
-
return isVirtualDesktopEnabled(
|
|
257
|
+
return isVirtualDesktopEnabled();
|
|
258
258
|
} catch (err) {
|
|
259
|
-
log.warn({ err }, "Failed to
|
|
259
|
+
log.warn({ err }, "Failed to check desktop stream gate");
|
|
260
260
|
return false;
|
|
261
261
|
}
|
|
262
262
|
}
|
|
@@ -70,6 +70,12 @@ export interface RuntimeMessageConversationOptions {
|
|
|
70
70
|
};
|
|
71
71
|
assistantId?: string;
|
|
72
72
|
trustContext?: TrustContext;
|
|
73
|
+
/**
|
|
74
|
+
* The person whose own inbound message this turn persists. Channel ingress
|
|
75
|
+
* and its retry replay pass the sender's trust; it names the persisted user
|
|
76
|
+
* row's author (`PersistMessageOptions.author`).
|
|
77
|
+
*/
|
|
78
|
+
author?: TrustContext;
|
|
73
79
|
/**
|
|
74
80
|
* Whether this turn should permit interactive approval prompts.
|
|
75
81
|
* Channel ingress sets this true so confirmations can be resolved
|
|
@@ -13,36 +13,18 @@ export type ApprovalMessageScenario =
|
|
|
13
13
|
| "standard_prompt"
|
|
14
14
|
| "guardian_prompt"
|
|
15
15
|
| "reminder_prompt"
|
|
16
|
-
| "guardian_delivery_failed"
|
|
17
|
-
| "guardian_request_forwarded"
|
|
18
|
-
| "guardian_disambiguation"
|
|
19
16
|
| "guardian_identity_mismatch"
|
|
20
17
|
| "request_pending_guardian"
|
|
21
|
-
| "guardian_decision_outcome"
|
|
22
|
-
| "guardian_expired_requester"
|
|
23
|
-
| "guardian_expired_guardian"
|
|
24
|
-
| "guardian_verify_success"
|
|
25
18
|
| "guardian_verify_failed"
|
|
26
19
|
| "guardian_verify_challenge_setup"
|
|
27
|
-
| "
|
|
28
|
-
| "guardian_verify_status_unbound"
|
|
29
|
-
| "guardian_deny_no_identity"
|
|
30
|
-
| "guardian_deny_no_binding"
|
|
31
|
-
| "requester_cancel"
|
|
32
|
-
| "approval_already_resolved"
|
|
33
|
-
| "guardian_text_unavailable";
|
|
20
|
+
| "approval_already_resolved";
|
|
34
21
|
|
|
35
22
|
export interface ApprovalMessageContext {
|
|
36
23
|
scenario: ApprovalMessageScenario;
|
|
37
24
|
channel?: string;
|
|
38
25
|
toolName?: string;
|
|
39
26
|
requesterIdentifier?: string;
|
|
40
|
-
guardianIdentifier?: string;
|
|
41
|
-
pendingCount?: number;
|
|
42
|
-
decision?: "approved" | "denied";
|
|
43
27
|
richUi?: boolean;
|
|
44
|
-
/** Pre-existing assistant text to reuse (macOS parity). */
|
|
45
|
-
assistantPreface?: string;
|
|
46
28
|
verifyCommand?: string;
|
|
47
29
|
ttlSeconds?: number;
|
|
48
30
|
failureReason?: string;
|
|
@@ -77,49 +59,9 @@ export type ApprovalCopyGenerator = (
|
|
|
77
59
|
// Guardian action message types
|
|
78
60
|
// ---------------------------------------------------------------------------
|
|
79
61
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
| "caller_timeout_continue"
|
|
83
|
-
| "guardian_late_answer_followup"
|
|
84
|
-
| "guardian_followup_dispatching"
|
|
85
|
-
| "guardian_followup_completed"
|
|
86
|
-
| "guardian_followup_failed"
|
|
87
|
-
| "guardian_followup_declined_ack"
|
|
88
|
-
| "guardian_followup_clarification"
|
|
89
|
-
| "guardian_pending_disambiguation"
|
|
90
|
-
| "guardian_expired_disambiguation"
|
|
91
|
-
| "guardian_followup_disambiguation"
|
|
92
|
-
| "guardian_stale_answered"
|
|
93
|
-
| "guardian_stale_expired"
|
|
94
|
-
| "guardian_stale_followup"
|
|
95
|
-
| "guardian_stale_superseded"
|
|
96
|
-
| "guardian_superseded_remap"
|
|
97
|
-
| "guardian_unknown_code"
|
|
98
|
-
| "guardian_auto_matched"
|
|
99
|
-
| "followup_call_started"
|
|
100
|
-
| "followup_action_failed"
|
|
101
|
-
| "guardian_answer_delivery_failed";
|
|
62
|
+
/** The one guardian-action notice still sent: a request expired unanswered. */
|
|
63
|
+
export type GuardianActionMessageScenario = "guardian_stale_expired";
|
|
102
64
|
|
|
103
65
|
export interface GuardianActionMessageContext {
|
|
104
66
|
scenario: GuardianActionMessageScenario;
|
|
105
|
-
channel?: string;
|
|
106
|
-
questionText?: string;
|
|
107
|
-
callerIdentifier?: string;
|
|
108
|
-
guardianIdentifier?: string;
|
|
109
|
-
lateAnswerText?: string;
|
|
110
|
-
followupAction?: string;
|
|
111
|
-
failureReason?: string;
|
|
112
|
-
counterpartyPhone?: string;
|
|
113
|
-
requestCodes?: string[];
|
|
114
|
-
/** The code the guardian provided that was not recognized. */
|
|
115
|
-
unknownCode?: string;
|
|
116
|
-
/** The code of the active request that supersedes the one the guardian targeted. */
|
|
117
|
-
activeRequestCode?: string;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface ComposeGuardianActionMessageOptions {
|
|
121
|
-
fallbackText?: string;
|
|
122
|
-
requiredKeywords?: string[];
|
|
123
|
-
maxTokens?: number;
|
|
124
|
-
timeoutMs?: number;
|
|
125
67
|
}
|
|
@@ -33,7 +33,10 @@ import { Readable } from "node:stream";
|
|
|
33
33
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
34
34
|
|
|
35
35
|
import { buildVBundle } from "../vbundle-builder.js";
|
|
36
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
analyzeImport,
|
|
38
|
+
DefaultPathResolver,
|
|
39
|
+
} from "../vbundle-import-analyzer.js";
|
|
37
40
|
import { commitImport } from "../vbundle-importer.js";
|
|
38
41
|
import { streamCommitImport } from "../vbundle-streaming-importer.js";
|
|
39
42
|
import { defaultV1Options } from "./v1-test-helpers.js";
|
|
@@ -416,4 +419,67 @@ describe("vbundle import parity (buffer vs streaming)", () => {
|
|
|
416
419
|
expect(bufferMap.has("marker.txt")).toBe(true);
|
|
417
420
|
expect(streamMap.has("marker.txt")).toBe(true);
|
|
418
421
|
});
|
|
422
|
+
|
|
423
|
+
test("F — debug-profile gateway entry: both importers drain it and write nothing", async () => {
|
|
424
|
+
const configJson = JSON.stringify({ version: 1 });
|
|
425
|
+
const { archive, manifest } = buildVBundle({
|
|
426
|
+
files: [
|
|
427
|
+
{ path: "workspace/data/db/assistant.db", data: new Uint8Array(8) },
|
|
428
|
+
{
|
|
429
|
+
path: "workspace/config.json",
|
|
430
|
+
data: new TextEncoder().encode(configJson),
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
path: "gateway/export.tar.gz",
|
|
434
|
+
data: new TextEncoder().encode("not-a-real-tarball"),
|
|
435
|
+
},
|
|
436
|
+
],
|
|
437
|
+
...defaultV1Options(),
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
// Preflight must not block on the gateway entry, or the CLI would
|
|
441
|
+
// refuse the restore before either importer runs.
|
|
442
|
+
const preflight = analyzeImport({
|
|
443
|
+
manifest,
|
|
444
|
+
pathResolver: new DefaultPathResolver(bufferWs),
|
|
445
|
+
});
|
|
446
|
+
expect(preflight.can_import).toBe(true);
|
|
447
|
+
expect(preflight.conflicts).toEqual([]);
|
|
448
|
+
|
|
449
|
+
mkdirSync(bufferWs, { recursive: true });
|
|
450
|
+
mkdirSync(streamWs, { recursive: true });
|
|
451
|
+
|
|
452
|
+
const bufferResult = commitImport({
|
|
453
|
+
archiveData: archive,
|
|
454
|
+
pathResolver: new DefaultPathResolver(bufferWs),
|
|
455
|
+
workspaceDir: bufferWs,
|
|
456
|
+
});
|
|
457
|
+
const streamResult = await streamCommitImport({
|
|
458
|
+
source: Readable.from([Buffer.from(archive)]),
|
|
459
|
+
pathResolver: new DefaultPathResolver(streamWs),
|
|
460
|
+
workspaceDir: streamWs,
|
|
461
|
+
});
|
|
462
|
+
if (!bufferResult.ok || !streamResult.ok) {
|
|
463
|
+
throw new Error("import unexpectedly failed");
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const bufferMap = walkDiskTree(bufferWs);
|
|
467
|
+
const streamMap = walkDiskTree(streamWs);
|
|
468
|
+
|
|
469
|
+
expect(streamMap).toEqual(bufferMap);
|
|
470
|
+
expect(bufferMap.has("config.json")).toBe(true);
|
|
471
|
+
expect(bufferMap.has("data/db/assistant.db")).toBe(true);
|
|
472
|
+
for (const relPath of bufferMap.keys()) {
|
|
473
|
+
expect(relPath.startsWith("gateway")).toBe(false);
|
|
474
|
+
}
|
|
475
|
+
// Skipped silently, like a retired path: counted, but no
|
|
476
|
+
// "no known disk target" warning.
|
|
477
|
+
for (const { report } of [bufferResult, streamResult]) {
|
|
478
|
+
expect(report.warnings).toEqual([]);
|
|
479
|
+
const gateway = report.files.find(
|
|
480
|
+
(f) => f.path === "gateway/export.tar.gz",
|
|
481
|
+
);
|
|
482
|
+
expect(gateway?.action).toBe("skipped");
|
|
483
|
+
}
|
|
484
|
+
});
|
|
419
485
|
});
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
isConfigArchivePath,
|
|
16
16
|
isCredentialMetadataArchivePath,
|
|
17
17
|
isLegacyPersonaArchivePath,
|
|
18
|
+
isLocalDevRuntimeVersion,
|
|
18
19
|
isWorkspaceNamespacedArchivePath,
|
|
19
20
|
LEGACY_USER_MD_ARCHIVE_PATH,
|
|
20
21
|
partitionWorkspacePreserveSkipDirs,
|
|
@@ -257,4 +258,92 @@ describe("evaluateRuntimeCompatibility", () => {
|
|
|
257
258
|
),
|
|
258
259
|
).toEqual({ ok: true });
|
|
259
260
|
});
|
|
261
|
+
|
|
262
|
+
// A `vel up` minikube assistant image is stamped
|
|
263
|
+
// `<pkg.version>-local.<ts>.<sha>` from the checkout's package.json,
|
|
264
|
+
// which only moves on release cuts, so the minimum bound cannot be
|
|
265
|
+
// decided from it; the explicit maximum ceiling still applies.
|
|
266
|
+
test("local dev runtime build skips the minimum bound", () => {
|
|
267
|
+
expect(
|
|
268
|
+
evaluateRuntimeCompatibility(
|
|
269
|
+
{ min_runtime_version: "0.12.2-staging.4", max_runtime_version: null },
|
|
270
|
+
"0.12.1-local.20260916144827.2f409056e6",
|
|
271
|
+
),
|
|
272
|
+
).toEqual({ ok: true });
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test("local dev runtime build within an explicit range passes", () => {
|
|
276
|
+
expect(
|
|
277
|
+
evaluateRuntimeCompatibility(
|
|
278
|
+
{ min_runtime_version: "0.12.2", max_runtime_version: "0.12.5" },
|
|
279
|
+
"0.12.1-local.20260916144827.2f409056e6",
|
|
280
|
+
),
|
|
281
|
+
).toEqual({ ok: true });
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
test("local dev runtime build above max still fails", () => {
|
|
285
|
+
const compat = {
|
|
286
|
+
min_runtime_version: "0.7.0",
|
|
287
|
+
max_runtime_version: "0.7.5",
|
|
288
|
+
};
|
|
289
|
+
const runtime = "0.12.1-local.20260916144827.2f409056e6";
|
|
290
|
+
expect(evaluateRuntimeCompatibility(compat, runtime)).toEqual({
|
|
291
|
+
ok: false,
|
|
292
|
+
reason: "version_incompatible",
|
|
293
|
+
bundle_compat: compat,
|
|
294
|
+
runtime_version: runtime,
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test("local dev runtime build with unparsable max fails open", () => {
|
|
299
|
+
expect(
|
|
300
|
+
evaluateRuntimeCompatibility(
|
|
301
|
+
{ min_runtime_version: "0.7.0", max_runtime_version: "garbage" },
|
|
302
|
+
"0.12.1-local.20260916144827.2f409056e6",
|
|
303
|
+
),
|
|
304
|
+
).toEqual({ ok: true });
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
test("other prerelease builds are still gated", () => {
|
|
308
|
+
const compat = {
|
|
309
|
+
min_runtime_version: "0.12.2-staging.4",
|
|
310
|
+
max_runtime_version: null,
|
|
311
|
+
};
|
|
312
|
+
for (const runtime of [
|
|
313
|
+
"0.12.1-dev.202609151913.a151da3",
|
|
314
|
+
"0.12.1-staging.9",
|
|
315
|
+
"0.12.1",
|
|
316
|
+
]) {
|
|
317
|
+
expect(evaluateRuntimeCompatibility(compat, runtime)).toEqual({
|
|
318
|
+
ok: false,
|
|
319
|
+
reason: "version_incompatible",
|
|
320
|
+
bundle_compat: compat,
|
|
321
|
+
runtime_version: runtime,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
describe("isLocalDevRuntimeVersion", () => {
|
|
328
|
+
test("matches the local hatch / minikube version stamp", () => {
|
|
329
|
+
expect(
|
|
330
|
+
isLocalDevRuntimeVersion("0.12.1-local.20260916144827.2f409056e6"),
|
|
331
|
+
).toBe(true);
|
|
332
|
+
expect(isLocalDevRuntimeVersion("0.0.0-local.1789584535000")).toBe(true);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
test("rejects release, dev and staging builds and lookalikes", () => {
|
|
336
|
+
for (const version of [
|
|
337
|
+
"0.12.1",
|
|
338
|
+
"0.12.1-dev.202609151913.a151da3",
|
|
339
|
+
"0.12.2-staging.4",
|
|
340
|
+
"0.0.0-dev",
|
|
341
|
+
"0.0.0-legacy",
|
|
342
|
+
"0.12.1-localhost.1",
|
|
343
|
+
"local.0.12.1",
|
|
344
|
+
"",
|
|
345
|
+
]) {
|
|
346
|
+
expect(isLocalDevRuntimeVersion(version)).toBe(false);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
260
349
|
});
|