@vellumai/assistant 0.12.1-staging.1 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +0 -4
- package/ARCHITECTURE.md +12 -11
- package/docs/architecture/turn-actor.md +8 -15
- package/openapi.yaml +1 -291
- package/package.json +1 -1
- package/src/__tests__/always-loaded-tools-guard.test.ts +10 -18
- package/src/__tests__/app-compiler.test.ts +0 -6
- package/src/__tests__/app-control-tool-schemas.test.ts +2 -5
- package/src/__tests__/app-dir-path-guard.test.ts +3 -1
- package/src/__tests__/app-source-watcher.test.ts +218 -0
- package/src/{calls/__tests__ → __tests__}/call-controller.test.ts +82 -503
- package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +2 -5
- package/src/__tests__/computer-use-tools.test.ts +5 -17
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +29 -28
- package/src/__tests__/config-watcher-skill-reseed.test.ts +359 -0
- package/src/__tests__/config-watcher.test.ts +8 -23
- package/src/__tests__/connection-model-compat.test.ts +2 -2
- package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +0 -26
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +10 -4
- package/src/__tests__/conversation-queue.test.ts +207 -48
- package/src/__tests__/conversation-retry-discard.test.ts +1 -54
- package/src/__tests__/conversation-skill-tools.test.ts +0 -27
- package/src/__tests__/conversation-surfaces-app-control.test.ts +3 -8
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -67
- package/src/__tests__/conversation-title-service.test.ts +10 -14
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +5 -3
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -51
- package/src/__tests__/credential-record-retire.test.ts +1 -171
- package/src/__tests__/credential-routes.test.ts +3 -212
- package/src/__tests__/credential-security-invariants.test.ts +1 -2
- package/src/__tests__/cu-unified-flow.test.ts +2 -8
- package/src/__tests__/drain-kick-guard.test.ts +2 -0
- package/src/__tests__/drain-requeue-on-contention.test.ts +6 -0
- package/src/__tests__/evict-conversations-for-reload.test.ts +1 -1
- package/src/__tests__/host-bash-proxy.test.ts +45 -26
- package/src/__tests__/host-browser-proxy.test.ts +17 -6
- package/src/__tests__/host-file-proxy-targeted.test.ts +0 -23
- package/src/__tests__/host-file-proxy.test.ts +23 -11
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +9 -30
- package/src/__tests__/llm-catalog-parity.test.ts +0 -25
- package/src/__tests__/mcp-auth-routes.test.ts +9 -6
- package/src/__tests__/mcp-config-secret-boundary.test.ts +136 -78
- package/src/__tests__/mcp-health-check.test.ts +11 -8
- package/src/__tests__/mcp-list-plugin-servers.test.ts +10 -8
- package/src/{calls/__tests__ → __tests__}/media-stream-audio-transcode.test.ts +1 -1
- package/src/{calls/__tests__ → __tests__}/media-stream-output.test.ts +8 -37
- package/src/{calls/__tests__ → __tests__}/media-stream-parser.test.ts +1 -1
- package/src/{calls/__tests__ → __tests__}/media-stream-server-integration.test.ts +57 -150
- package/src/{calls/__tests__ → __tests__}/media-stream-stt-session.test.ts +5 -5
- package/src/{calls/__tests__ → __tests__}/media-turn-detector.test.ts +1 -1
- package/src/__tests__/messages-after-tiebreaker.test.ts +0 -91
- package/src/__tests__/messages-read-boundary-guard.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +548 -355
- package/src/__tests__/model-intents.test.ts +0 -3
- package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
- package/src/__tests__/platform-client-verify-credential.test.ts +0 -2
- package/src/__tests__/plugin-import-boundary-guard.test.ts +0 -13
- package/src/__tests__/script-proxy-certs.test.ts +0 -35
- package/src/__tests__/skill-feature-flags-integration.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/speaker-identification.test.ts +56 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +3 -19
- package/src/__tests__/subagent-tools.test.ts +2 -3
- package/src/__tests__/telephony-tts-guard.test.ts +3 -38
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +0 -4
- package/src/{calls/__tests__/voice-session-bridge-turn-flow.test.ts → __tests__/voice-session-bridge.test.ts} +12 -20
- package/src/__tests__/watch-retro-tool-availability.test.ts +17 -8
- package/src/__tests__/workspace-git-service.test.ts +0 -26
- package/src/acp/__tests__/agent-process.test.ts +4 -258
- package/src/acp/__tests__/auth-required.test.ts +0 -96
- package/src/acp/__tests__/client-handler.test.ts +2 -90
- package/src/acp/__tests__/session-manager-persistence.test.ts +1 -5
- package/src/acp/__tests__/session-manager-resume.test.ts +6 -270
- package/src/acp/__tests__/session-manager-usage.test.ts +2 -4
- package/src/acp/__tests__/session-manager.test.ts +4 -895
- package/src/acp/agent-process.test.ts +1 -4
- package/src/acp/agent-process.ts +9 -94
- package/src/acp/auth-required.ts +1 -50
- package/src/acp/auto-install.test.ts +7 -9
- package/src/acp/client-handler.ts +3 -16
- package/src/acp/resolve-agent.test.ts +6 -220
- package/src/acp/resolve-agent.ts +23 -88
- package/src/acp/session-manager.test.ts +3 -196
- package/src/acp/session-manager.ts +18 -441
- package/src/acp/types.ts +5 -50
- package/src/api/events/app-files-changed.ts +3 -4
- package/src/api/index.ts +0 -6
- package/src/apps/app-store.ts +1 -1
- package/src/bundler/app-compiler.ts +0 -15
- package/src/calls/__tests__/voice-control-protocol.test.ts +25 -58
- package/src/calls/__tests__/voice-session-bridge.test.ts +1 -37
- package/src/calls/__tests__/voice-triage-escalate.test.ts +0 -105
- package/src/calls/call-constants.ts +4 -24
- package/src/calls/call-controller.ts +199 -499
- package/src/calls/call-transport.ts +0 -16
- package/src/calls/media-stream-output.ts +0 -32
- package/src/calls/media-stream-server.ts +30 -82
- package/src/calls/media-stream-stt-session.ts +0 -15
- package/src/calls/resolve-call-tts-provider.ts +2 -33
- package/src/calls/speaker-identification.ts +233 -0
- package/src/calls/tts-call-strategy.ts +5 -9
- package/src/calls/types.ts +0 -2
- package/src/calls/voice-control-protocol.ts +21 -53
- package/src/calls/voice-session-bridge.ts +46 -59
- package/src/calls/voice-triage-escalate.ts +56 -175
- package/src/cli/commands/apps.help.ts +13 -67
- package/src/cli/commands/apps.ts +0 -183
- package/src/cli/commands/channels/index.help.ts +2 -70
- package/src/cli/commands/channels/index.ts +3 -16
- package/src/cli/commands/credentials.help.ts +2 -6
- package/src/cli/commands/credentials.ts +2 -2
- package/src/cli/commands/mcp.help.ts +8 -8
- package/src/cli/commands/mcp.ts +1 -1
- package/src/cli/commands/roadmap.help.ts +1 -5
- package/src/cli/commands/roadmap.ts +1 -1
- package/src/cli/lib/bundled-marketplace.json +90 -103
- package/src/config/__tests__/default-profile-catalog.test.ts +0 -22
- package/src/config/__tests__/memory-retrospective-schema.test.ts +1 -15
- package/src/config/__tests__/platform-rehydration.test.ts +0 -93
- package/src/config/acp-defaults.test.ts +3 -13
- package/src/config/acp-defaults.ts +6 -23
- package/src/config/acp-schema.ts +2 -30
- package/src/config/bundled-skills/acp/SKILL.md +14 -22
- package/src/config/bundled-skills/acp/TOOLS.json +1 -5
- package/src/config/bundled-skills/app-builder/SKILL.md +9 -12
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +1 -1
- package/src/config/bundled-skills/messaging/TOOLS.json +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +139 -67
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +1 -1
- package/src/config/bundled-skills/screen-annotation/SKILL.md +1 -8
- package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +1 -4
- package/src/config/bundled-skills/skill-management/TOOLS.json +2 -2
- package/src/config/default-profile-catalog.ts +1 -1
- package/src/config/env.ts +2 -2
- package/src/config/feature-flag-registry.json +12 -8
- package/src/config/memory-v3-gate.test.ts +0 -31
- package/src/config/memory-v3-gate.ts +16 -20
- package/src/config/platform-rehydration.ts +21 -75
- package/src/config/schema.ts +2 -2
- package/src/config/schemas/__tests__/live-voice.test.ts +158 -8
- package/src/config/schemas/calls.ts +28 -1
- package/src/config/schemas/live-voice.ts +173 -1
- package/src/config/schemas/mcp.ts +1 -1
- package/src/config/schemas/memory-retrospective.ts +0 -10
- package/src/config/schemas/skills.ts +14 -0
- package/src/credential-execution/process-manager.test.ts +19 -18
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +121 -66
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +1 -4
- package/src/daemon/app-source-watcher.ts +218 -0
- package/src/daemon/config-watcher.ts +194 -13
- package/src/daemon/conversation-process.ts +64 -35
- package/src/daemon/conversation-skill-tools.ts +31 -13
- package/src/daemon/conversation-store.ts +1 -1
- package/src/daemon/conversation-surfaces.ts +8 -10
- package/src/daemon/conversation-tool-setup.ts +43 -37
- package/src/daemon/conversation.ts +3 -0
- package/src/daemon/host-bash-proxy.ts +12 -8
- package/src/daemon/host-browser-proxy.ts +1 -15
- package/src/daemon/host-file-proxy.ts +10 -8
- package/src/daemon/host-transfer-proxy.ts +18 -14
- package/src/daemon/lifecycle.ts +5 -0
- package/src/daemon/mcp-reload-service.ts +5 -5
- package/src/daemon/message-types/sync.ts +0 -1
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/shutdown-handlers.ts +9 -1
- package/src/daemon/skill-memory-refresh.ts +0 -64
- package/src/daemon/tool-side-effects.ts +18 -7
- package/src/hooks/types.ts +0 -33
- package/src/inbound/platform-callback-registration.ts +5 -4
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +3 -0
- package/src/live-voice/__tests__/live-voice-progress.test.ts +15 -15
- package/src/live-voice/__tests__/live-voice-vad.test.ts +2 -2
- package/src/{calls → live-voice}/__tests__/progress-narration.test.ts +4 -4
- package/src/{calls → live-voice}/__tests__/progress-phrases.test.ts +1 -1
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +69 -13
- package/src/live-voice/live-voice-session.ts +693 -213
- package/src/{calls → live-voice}/progress-narration.ts +2 -2
- package/src/live-voice/protocol.ts +2 -0
- package/src/mcp/__tests__/effective-config.test.ts +2 -2
- package/src/mcp/effective-config.ts +3 -3
- package/src/mcp/mcp-header-store.ts +45 -29
- package/src/mcp/startup.ts +4 -8
- package/src/messaging/provider.ts +3 -10
- package/src/messaging/providers/callback-routing.ts +0 -18
- package/src/messaging/providers/channel-transport.ts +0 -56
- package/src/messaging/providers/discord/transport.ts +0 -17
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +17 -6
- package/src/messaging/providers/slack/adapter.ts +44 -7
- package/src/messaging/providers/slack/transport.ts +0 -16
- package/src/messaging/providers/telegram-bot/adapter.ts +48 -1
- package/src/messaging/providers/telegram-bot/client.ts +26 -0
- package/src/messaging/providers/telegram-bot/transport.ts +0 -20
- package/src/messaging/providers/whatsapp/adapter.ts +48 -1
- package/src/messaging/providers/whatsapp/client.ts +29 -0
- package/src/messaging/providers/whatsapp/transport.ts +0 -18
- package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +0 -8
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +0 -55
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +3 -153
- package/src/notifications/assistant-reply-producer.ts +3 -8
- package/src/notifications/conversation-pairing.ts +16 -36
- package/src/notifications/delivered-post-record.ts +1 -11
- package/src/notifications/home-feed-side-effect.ts +7 -55
- package/src/outbound-proxy/certs.ts +5 -3
- package/src/permissions/checker.test.ts +6 -11
- package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
- package/src/persistence/conversation-crud.ts +63 -71
- package/src/persistence/conversation-lineage.ts +4 -12
- package/src/persistence/conversation-title-service.ts +26 -9
- package/src/persistence/llm-request-log-sink-clickhouse.ts +3 -3
- package/src/persistence/llm-request-log-source-clickhouse.ts +3 -3
- package/src/persistence/message-reads.ts +0 -30
- package/src/persistence/migrations/157-invite-contact-id.ts +6 -18
- package/src/persistence/schema/memory-core.ts +0 -5
- package/src/platform/client.test.ts +0 -2
- package/src/platform/client.ts +10 -2
- package/src/plugin-api/constants.ts +0 -2
- package/src/plugin-api/index.ts +0 -1
- package/src/plugin-api/types.ts +0 -2
- package/src/plugins/defaults/index.ts +0 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +0 -46
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +5 -9
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +10 -20
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +0 -219
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +0 -31
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +0 -63
- package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +0 -4
- package/src/plugins/defaults/memory/graph/capability-seed.ts +6 -4
- package/src/plugins/defaults/memory/hooks/init.ts +0 -10
- package/src/plugins/defaults/memory/hooks/shutdown.ts +0 -2
- package/src/plugins/defaults/memory/jobs-worker.ts +0 -13
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +60 -34
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +5 -3
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +3 -12
- package/src/plugins/defaults/memory/memory-retrospective-state.ts +71 -312
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +1 -2
- package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +3 -5
- package/src/plugins/defaults/memory/startup.ts +1 -6
- package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +9 -7
- package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +0 -89
- package/src/plugins/defaults/memory/worker.ts +0 -6
- package/src/plugins/mcp-servers.ts +75 -15
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -3
- package/src/providers/gemini/client.ts +23 -9
- package/src/providers/model-catalog.ts +0 -34
- package/src/providers/model-intents.ts +5 -10
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +18 -146
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +1 -83
- package/src/providers/openai/chat-completions-provider.ts +78 -192
- package/src/providers/openai/codex-models.ts +4 -0
- package/src/runtime/AGENTS.md +0 -2
- package/src/runtime/auth/same-actor.ts +3 -38
- package/src/runtime/http-server.ts +151 -160
- package/src/runtime/routes/__tests__/acp-routes.test.ts +4 -159
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -108
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +12 -16
- package/src/runtime/routes/acp-routes.test.ts +0 -15
- package/src/runtime/routes/acp-routes.ts +9 -72
- package/src/runtime/routes/app-management-routes.ts +0 -73
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +3 -14
- package/src/runtime/routes/conversation-query-routes.ts +0 -40
- package/src/runtime/routes/credential-routes.ts +10 -19
- package/src/runtime/routes/diagnostics-routes.ts +3 -55
- package/src/runtime/routes/index.ts +0 -4
- package/src/runtime/routes/log-export-routes.ts +0 -2
- package/src/runtime/routes/mcp-auth-routes.ts +47 -39
- package/src/runtime/routes/migration-routes.ts +21 -8
- package/src/runtime/routes/platform-routes.ts +15 -18
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -28
- package/src/runtime/services/conversation-serializer.ts +3 -16
- package/src/runtime/sync/resource-sync-events.ts +1 -2
- package/src/schedule/worker.ts +1 -1
- package/src/security/ces-rpc-record-backend.ts +0 -7
- package/src/subagent/consult-context.ts +25 -12
- package/src/tools/acp/list-agents.test.ts +1 -3
- package/src/tools/acp/spawn.test.ts +11 -146
- package/src/tools/acp/spawn.ts +3 -21
- package/src/tools/acp/status.ts +3 -40
- package/src/tools/app-control/skill-proxy-bridge.ts +1 -2
- package/src/tools/capability-offer.test.ts +2 -22
- package/src/tools/capability-offer.ts +1 -16
- package/src/tools/computer-use/definitions.ts +2 -4
- package/src/tools/computer-use/skill-proxy-bridge.ts +1 -2
- package/src/tools/credentials/metadata-store.ts +0 -100
- package/src/tools/host-filesystem/edit.test.ts +1 -2
- package/src/tools/host-filesystem/edit.ts +2 -2
- package/src/tools/host-filesystem/read.test.ts +1 -2
- package/src/tools/host-filesystem/read.ts +2 -2
- package/src/tools/host-filesystem/transfer.test.ts +1 -2
- package/src/tools/host-filesystem/transfer.ts +2 -2
- package/src/tools/host-filesystem/write.test.ts +1 -2
- package/src/tools/host-filesystem/write.ts +2 -2
- package/src/tools/host-terminal/host-shell.test.ts +0 -16
- package/src/tools/host-terminal/host-shell.ts +20 -4
- package/src/tools/policy-context.ts +7 -6
- package/src/tools/subagent/spawn.ts +8 -5
- package/src/tools/watch/watch-retro-report.ts +8 -0
- package/src/util/__tests__/language-subtag.test.ts +1 -23
- package/src/util/fs-watcher-error.ts +36 -0
- package/src/util/language-subtag.ts +0 -16
- package/src/util/platform.ts +0 -8
- package/src/workspace/git-service.ts +54 -5
- package/src/workspace/migrations/registry.ts +0 -6
- package/scripts/smoke-desktop-window-theme.ts +0 -186
- package/src/__tests__/git-porcelain.test.ts +0 -47
- package/src/__tests__/helpers/set-workspace-mcp.ts +0 -11
- package/src/__tests__/message-deleted-hook-dispatch.test.ts +0 -119
- package/src/__tests__/resolve-app.test.ts +0 -135
- package/src/__tests__/source-fingerprint.test.ts +0 -184
- package/src/__tests__/workspace-migration-154-repair-retired-codex-gpt-5-4-model-ids.test.ts +0 -336
- package/src/acp/__tests__/helpers/acp-model-option.ts +0 -51
- package/src/acp/model-config.test.ts +0 -166
- package/src/acp/model-config.ts +0 -138
- package/src/api/events/acp-session-model-update.test.ts +0 -88
- package/src/api/events/acp-session-model-update.ts +0 -46
- package/src/apps/resolve-app.ts +0 -81
- package/src/apps/source-fingerprint.ts +0 -266
- package/src/calls/__tests__/barge-in-guard.test.ts +0 -81
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +0 -229
- package/src/calls/__tests__/voice-progress-cadence.test.ts +0 -274
- package/src/calls/barge-in-guard.ts +0 -118
- package/src/calls/voice-leg-coordinator.ts +0 -189
- package/src/calls/voice-progress-cadence.ts +0 -423
- package/src/cli/commands/__tests__/apps.test.ts +0 -245
- package/src/cli/commands/__tests__/roadmap.help.test.ts +0 -19
- package/src/cli/commands/channels/__tests__/send.test.ts +0 -218
- package/src/cli/commands/channels/send.ts +0 -128
- package/src/config/__tests__/platform-identity.test.ts +0 -117
- package/src/config/acp-agent-write.ts +0 -43
- package/src/config/acp-schema.test.ts +0 -81
- package/src/config/platform-identity.ts +0 -144
- package/src/config/schemas/__tests__/voice.test.ts +0 -148
- package/src/config/schemas/voice.ts +0 -150
- package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +0 -133
- package/src/daemon/app-change-notify.ts +0 -45
- package/src/desktop/__tests__/fake-desktop.ts +0 -119
- package/src/desktop/desktop-chrome-policy.test.ts +0 -71
- package/src/desktop/desktop-chrome-policy.ts +0 -42
- package/src/desktop/desktop-dependencies.test.ts +0 -102
- package/src/desktop/desktop-dependencies.ts +0 -306
- package/src/desktop/desktop-feature.test.ts +0 -18
- package/src/desktop/desktop-feature.ts +0 -19
- package/src/desktop/desktop-panel-config.test.ts +0 -135
- package/src/desktop/desktop-panel-config.ts +0 -149
- package/src/desktop/desktop-session-manager.test.ts +0 -627
- package/src/desktop/desktop-session-manager.ts +0 -814
- package/src/desktop/desktop-stream-bridge.test.ts +0 -395
- package/src/desktop/desktop-stream-bridge.ts +0 -214
- package/src/desktop/desktop-wallpaper.test.ts +0 -191
- package/src/desktop/desktop-wallpaper.ts +0 -113
- package/src/desktop/desktop-window-theme.ts +0 -170
- package/src/i18n/AGENTS.md +0 -22
- package/src/i18n/__tests__/i18n.test.ts +0 -108
- package/src/i18n/index.ts +0 -16
- package/src/i18n/locales.ts +0 -93
- package/src/i18n/messages.ts +0 -61
- package/src/i18n/title.ts +0 -25
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +0 -135
- package/src/mcp/spec-schema.ts +0 -111
- package/src/mcp/workspace-mcp-config.ts +0 -188
- package/src/messaging/providers/__tests__/proactive-address.test.ts +0 -95
- package/src/persistence/conversation-title-placeholders.ts +0 -23
- package/src/persistence/message-cursor.ts +0 -78
- package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +0 -149
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-backfill.test.ts +0 -118
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-preserve.test.ts +0 -83
- package/src/plugins/defaults/memory/hooks/message-deleted.ts +0 -21
- package/src/plugins/defaults/memory/memory-retrospective-cursor-backfill.ts +0 -126
- package/src/plugins/defaults/memory/memory-retrospective-cursor-preserve.ts +0 -79
- package/src/plugins/defaults/memory/memory-retrospective-cursor.ts +0 -28
- package/src/plugins/defaults/memory/skill-md-mtime-poll.ts +0 -9
- package/src/providers/gemini-thought-signature.test.ts +0 -63
- package/src/providers/gemini-thought-signature.ts +0 -44
- package/src/providers/openai/__tests__/chat-completions-provider-thought-signature.test.ts +0 -613
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +0 -235
- package/src/providers/openai/google-thought-signature.ts +0 -320
- package/src/runtime/__tests__/channel-send.test.ts +0 -443
- package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +0 -89
- package/src/runtime/__tests__/live-voice-upgrade.test.ts +0 -58
- package/src/runtime/__tests__/runtime-ws-test-utils.ts +0 -72
- package/src/runtime/__tests__/watch-stream-upgrade.test.ts +0 -59
- package/src/runtime/channel-send.ts +0 -316
- package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +0 -205
- package/src/runtime/routes/__tests__/channel-send-routes.test.ts +0 -127
- package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +0 -107
- package/src/runtime/routes/channel-send-routes.ts +0 -85
- package/src/runtime/routes/desktop-setup-routes.test.ts +0 -74
- package/src/runtime/routes/desktop-setup-routes.ts +0 -35
- package/src/security/__tests__/ces-http-record-backend.test.ts +0 -137
- package/src/security/ces-http-record-backend.ts +0 -120
- package/src/skills/__tests__/workspace-skill-md-signature.test.ts +0 -60
- package/src/skills/workspace-skill-md-signature.ts +0 -50
- package/src/tools/acp/status.test.ts +0 -94
- package/src/util/ca-bundle.ts +0 -13
- package/src/workspace/git-porcelain.ts +0 -66
- package/src/workspace/migrations/154-repair-retired-codex-gpt-5-4-model-ids.ts +0 -258
- package/src/workspace/migrations/155-move-front-model-config-to-voice.ts +0 -78
- package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +0 -214
- package/src/workspace/migrations/__tests__/155-move-front-model-config-to-voice.test.ts +0 -102
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +0 -199
- /package/src/{calls → live-voice}/progress-phrases.ts +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { getConfig } from "../config/loader.js";
|
|
2
2
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
3
3
|
import {
|
|
4
|
+
ambiguousSameUserError,
|
|
4
5
|
enforceSameActorOrErrorResult,
|
|
5
|
-
|
|
6
|
-
unavailableSameUserClientError,
|
|
6
|
+
pickSameUserAutoResolve,
|
|
7
7
|
} from "../runtime/auth/same-actor.js";
|
|
8
8
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
9
9
|
import { formatShellOutput } from "../tools/shared/shell-output.js";
|
|
@@ -93,17 +93,21 @@ export class HostBashProxy extends HostProxyBase<
|
|
|
93
93
|
}
|
|
94
94
|
resolvedTargetClientId = input.targetClientId;
|
|
95
95
|
} else {
|
|
96
|
-
|
|
96
|
+
// Auto-resolve to the unique same-user client. Reject (rather than
|
|
97
|
+
// broadcast) when multiple same-user clients are connected so that
|
|
98
|
+
// a single targeted-style request cannot fan out across every one
|
|
99
|
+
// of the user's machines. Zero same-user matches falls through to
|
|
100
|
+
// the existing untargeted code path.
|
|
101
|
+
const resolved = pickSameUserAutoResolve({
|
|
97
102
|
hub: assistantEventHub,
|
|
98
103
|
capability: "host_bash",
|
|
99
104
|
sourceActorPrincipalId,
|
|
100
105
|
});
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
sourceActorPrincipalId !== undefined
|
|
104
|
-
) {
|
|
105
|
-
return unavailableSameUserClientError("host_bash");
|
|
106
|
+
if (resolved.kind === "ambiguous") {
|
|
107
|
+
return ambiguousSameUserError("host_bash");
|
|
106
108
|
}
|
|
109
|
+
resolvedTargetClientId =
|
|
110
|
+
resolved.kind === "match" ? resolved.clientId : undefined;
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
// Targeted requests must be bound to the same authenticated user as the
|
|
@@ -5,10 +5,7 @@ import {
|
|
|
5
5
|
assistantEventHub,
|
|
6
6
|
broadcastMessage,
|
|
7
7
|
} from "../runtime/assistant-event-hub.js";
|
|
8
|
-
import {
|
|
9
|
-
enforceSameActorOrErrorResult,
|
|
10
|
-
unavailableSameUserClientError,
|
|
11
|
-
} from "../runtime/auth/same-actor.js";
|
|
8
|
+
import { enforceSameActorOrErrorResult } from "../runtime/auth/same-actor.js";
|
|
12
9
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
13
10
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
14
11
|
import { AssistantError, ErrorCode } from "../util/errors.js";
|
|
@@ -287,17 +284,6 @@ export class HostBrowserProxy {
|
|
|
287
284
|
targetClientId,
|
|
288
285
|
);
|
|
289
286
|
|
|
290
|
-
if (
|
|
291
|
-
preferredClient === undefined &&
|
|
292
|
-
sourceActorPrincipalId !== undefined &&
|
|
293
|
-
targetClientId === undefined
|
|
294
|
-
) {
|
|
295
|
-
if (isExtensionOnlyMethod(input.cdpMethod)) {
|
|
296
|
-
return Promise.resolve(extensionRequiredResult(input.cdpMethod));
|
|
297
|
-
}
|
|
298
|
-
return Promise.resolve(unavailableSameUserClientError("host_browser"));
|
|
299
|
-
}
|
|
300
|
-
|
|
301
287
|
// Same-user enforcement: when the caller's actor is known, refuse to
|
|
302
288
|
// dispatch to a client owned by a different actor. This covers the
|
|
303
289
|
// cross-client exposure case where a web/iOS turn for actor A would
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
broadcastMessage,
|
|
7
7
|
} from "../runtime/assistant-event-hub.js";
|
|
8
8
|
import {
|
|
9
|
+
ambiguousSameUserError,
|
|
9
10
|
enforceSameActorOrErrorResult,
|
|
10
|
-
|
|
11
|
+
pickSameUserAutoResolve,
|
|
11
12
|
snapshotHostProxyActorPrincipalId,
|
|
12
|
-
unavailableSameUserClientError,
|
|
13
13
|
} from "../runtime/auth/same-actor.js";
|
|
14
14
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
15
15
|
import { readAudioBase64 } from "../tools/shared/filesystem/audio-read.js";
|
|
@@ -102,17 +102,19 @@ export class HostFileProxy {
|
|
|
102
102
|
});
|
|
103
103
|
}
|
|
104
104
|
} else {
|
|
105
|
-
|
|
105
|
+
// Auto-resolve to the unique same-user client. Reject ambiguous
|
|
106
|
+
// (multi-machine) cases so a single targeted-style request cannot
|
|
107
|
+
// fan out across the user's machines.
|
|
108
|
+
const resolved = pickSameUserAutoResolve({
|
|
106
109
|
hub: assistantEventHub,
|
|
107
110
|
capability: "host_file",
|
|
108
111
|
sourceActorPrincipalId,
|
|
109
112
|
});
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
sourceActorPrincipalId !== undefined
|
|
113
|
-
) {
|
|
114
|
-
return Promise.resolve(unavailableSameUserClientError("host_file"));
|
|
113
|
+
if (resolved.kind === "ambiguous") {
|
|
114
|
+
return Promise.resolve(ambiguousSameUserError("host_file"));
|
|
115
115
|
}
|
|
116
|
+
resolvedTargetClientId =
|
|
117
|
+
resolved.kind === "match" ? resolved.clientId : undefined;
|
|
116
118
|
}
|
|
117
119
|
|
|
118
120
|
// Same-user check: targeted host_file requests must be bound to the same
|
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
broadcastMessage,
|
|
11
11
|
} from "../runtime/assistant-event-hub.js";
|
|
12
12
|
import {
|
|
13
|
+
ambiguousSameUserError,
|
|
13
14
|
enforceSameActorOrErrorResult,
|
|
14
|
-
|
|
15
|
+
pickSameUserAutoResolve,
|
|
15
16
|
snapshotHostProxyActorPrincipalId,
|
|
16
|
-
unavailableSameUserClientError,
|
|
17
17
|
} from "../runtime/auth/same-actor.js";
|
|
18
18
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
19
19
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
@@ -162,17 +162,19 @@ export class HostTransferProxy {
|
|
|
162
162
|
});
|
|
163
163
|
}
|
|
164
164
|
} else {
|
|
165
|
-
|
|
165
|
+
// Auto-resolve to the unique same-user client; reject ambiguous
|
|
166
|
+
// (multi-machine) cases so a single targeted-style transfer cannot
|
|
167
|
+
// fan out across the user's machines.
|
|
168
|
+
const resolved = pickSameUserAutoResolve({
|
|
166
169
|
hub: assistantEventHub,
|
|
167
170
|
capability: "host_file",
|
|
168
171
|
sourceActorPrincipalId,
|
|
169
172
|
});
|
|
170
|
-
if (
|
|
171
|
-
|
|
172
|
-
sourceActorPrincipalId !== undefined
|
|
173
|
-
) {
|
|
174
|
-
return Promise.resolve(unavailableSameUserClientError("host_file"));
|
|
173
|
+
if (resolved.kind === "ambiguous") {
|
|
174
|
+
return Promise.resolve(ambiguousSameUserError("host_file"));
|
|
175
175
|
}
|
|
176
|
+
resolvedTargetClientId =
|
|
177
|
+
resolved.kind === "match" ? resolved.clientId : undefined;
|
|
176
178
|
}
|
|
177
179
|
|
|
178
180
|
if (resolvedTargetClientId != null) {
|
|
@@ -362,17 +364,19 @@ export class HostTransferProxy {
|
|
|
362
364
|
});
|
|
363
365
|
}
|
|
364
366
|
} else {
|
|
365
|
-
|
|
367
|
+
// Auto-resolve to the unique same-user client; reject ambiguous
|
|
368
|
+
// (multi-machine) cases so a single targeted-style transfer cannot
|
|
369
|
+
// fan out across the user's machines.
|
|
370
|
+
const resolved = pickSameUserAutoResolve({
|
|
366
371
|
hub: assistantEventHub,
|
|
367
372
|
capability: "host_file",
|
|
368
373
|
sourceActorPrincipalId,
|
|
369
374
|
});
|
|
370
|
-
if (
|
|
371
|
-
|
|
372
|
-
sourceActorPrincipalId !== undefined
|
|
373
|
-
) {
|
|
374
|
-
return Promise.resolve(unavailableSameUserClientError("host_file"));
|
|
375
|
+
if (resolved.kind === "ambiguous") {
|
|
376
|
+
return Promise.resolve(ambiguousSameUserError("host_file"));
|
|
375
377
|
}
|
|
378
|
+
resolvedTargetClientId =
|
|
379
|
+
resolved.kind === "match" ? resolved.clientId : undefined;
|
|
376
380
|
}
|
|
377
381
|
|
|
378
382
|
if (resolvedTargetClientId != null) {
|
package/src/daemon/lifecycle.ts
CHANGED
|
@@ -71,6 +71,7 @@ import { ensureCompleteCustomProfiles } from "../workspace/custom-profile-ensure
|
|
|
71
71
|
import { ensureDefaultProvider } from "../workspace/default-provider-ensure.js";
|
|
72
72
|
import { WORKSPACE_MIGRATIONS } from "../workspace/migrations/registry.js";
|
|
73
73
|
import { runWorkspaceMigrations } from "../workspace/migrations/runner.js";
|
|
74
|
+
import { startAppSourceWatcher } from "./app-source-watcher.js";
|
|
74
75
|
import { startConfigWatcher } from "./config-watcher.js";
|
|
75
76
|
import { startConversationEvictor } from "./conversation-evictor.js";
|
|
76
77
|
import { writePid } from "./daemon-control.js";
|
|
@@ -705,6 +706,10 @@ export async function runDaemon(): Promise<void> {
|
|
|
705
706
|
// config, and broadcast the relevant resource-changed events to clients.
|
|
706
707
|
startConfigWatcher();
|
|
707
708
|
|
|
709
|
+
// Watch app source directories so edits recompile + refresh surfaces across
|
|
710
|
+
// all conversations.
|
|
711
|
+
startAppSourceWatcher();
|
|
712
|
+
|
|
708
713
|
// Start the CLI IPC server. Throws on EADDRINUSE to abort startup when another
|
|
709
714
|
// daemon already holds the socket, so this process never runs background jobs
|
|
710
715
|
// against the shared database as an unmanageable duplicate.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared MCP reload business logic.
|
|
3
3
|
*
|
|
4
|
-
* Called by the ConfigWatcher when
|
|
4
|
+
* Called by the ConfigWatcher when config.json changes or a reload signal
|
|
5
5
|
* file is detected, so the daemon automatically reconnects MCP servers.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { invalidateConfigCache } from "../config/loader.js";
|
|
8
|
+
import { getConfig, invalidateConfigCache } from "../config/loader.js";
|
|
9
9
|
import {
|
|
10
10
|
buildEffectiveMcpConfig,
|
|
11
11
|
pluginMcpServersChangedSinceLastBuild,
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
import { getMcpServerManager } from "../mcp/manager.js";
|
|
14
14
|
import { migrateLegacyMcpHeaders } from "../mcp/mcp-header-store.js";
|
|
15
15
|
import { signalMcpReloaded } from "../mcp/reload-signal.js";
|
|
16
|
-
import { loadWorkspaceMcpConfig } from "../mcp/workspace-mcp-config.js";
|
|
17
16
|
import { createMcpToolsFromServer } from "../tools/mcp/mcp-tool-factory.js";
|
|
18
17
|
import { registerMcpTools, unregisterAllMcpTools } from "../tools/registry.js";
|
|
19
18
|
import { getLogger } from "../util/logger.js";
|
|
@@ -96,15 +95,16 @@ async function doReload(): Promise<McpReloadResult> {
|
|
|
96
95
|
// If the config is broken we abort early, preserving the current
|
|
97
96
|
// working MCP setup instead of leaving zero servers.
|
|
98
97
|
invalidateConfigCache();
|
|
98
|
+
const config = getConfig();
|
|
99
99
|
|
|
100
100
|
// 2. Stop existing MCP servers + unregister their tools
|
|
101
101
|
await manager.stop();
|
|
102
102
|
unregisterAllMcpTools();
|
|
103
103
|
|
|
104
104
|
// Plugins are re-read here too: installing or removing one changes the
|
|
105
|
-
// server set exactly like editing
|
|
105
|
+
// server set exactly like editing config.json does, and both arrive
|
|
106
106
|
// through this same reload.
|
|
107
|
-
const mcpConfig = buildEffectiveMcpConfig(
|
|
107
|
+
const mcpConfig = buildEffectiveMcpConfig(config.mcp);
|
|
108
108
|
const serverIds = Object.keys(mcpConfig.servers);
|
|
109
109
|
|
|
110
110
|
// 3. Restart MCP servers
|
|
@@ -13,7 +13,6 @@ export const SYNC_TAGS = {
|
|
|
13
13
|
assistantConfig: "assistant:self:config",
|
|
14
14
|
assistantSounds: "assistant:self:sounds",
|
|
15
15
|
assistantSchedules: "assistant:self:schedules",
|
|
16
|
-
assistantDesktop: "assistant:self:desktop",
|
|
17
16
|
assistantTheme: "assistant:self:theme",
|
|
18
17
|
appsList: "apps:list",
|
|
19
18
|
documentsList: "documents:list",
|
|
@@ -63,7 +63,7 @@ export async function initializeProvidersAndTools(
|
|
|
63
63
|
// Start MCP servers — workspace-configured and plugin-declared alike —
|
|
64
64
|
// and register their tools. Shared with the schedule worker, which hosts
|
|
65
65
|
// agent turns in its own process and so needs its own connections.
|
|
66
|
-
await startConfiguredMcpServers();
|
|
66
|
+
await startConfiguredMcpServers(config.mcp);
|
|
67
67
|
|
|
68
68
|
log.info("Daemon startup: providers and tools initialized");
|
|
69
69
|
}
|
|
@@ -24,7 +24,11 @@ import { browserManager } from "../tools/browser/browser-manager.js";
|
|
|
24
24
|
import { getLogger } from "../util/logger.js";
|
|
25
25
|
import { APP_VERSION } from "../version.js";
|
|
26
26
|
import { getEnrichmentService } from "../workspace/commit-message-enrichment-service.js";
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
commitAllPendingWorkspaceChanges,
|
|
29
|
+
stopWorkspaceHeartbeatService,
|
|
30
|
+
} from "../workspace/heartbeat-service.js";
|
|
31
|
+
import { stopAppSourceWatcher } from "./app-source-watcher.js";
|
|
28
32
|
import { stopConfigWatcher } from "./config-watcher.js";
|
|
29
33
|
import { stopConversationEvictor } from "./conversation-evictor.js";
|
|
30
34
|
import { stopConversations } from "./conversation-store.js";
|
|
@@ -94,6 +98,9 @@ async function shutdown(): Promise<void> {
|
|
|
94
98
|
}, 30_000);
|
|
95
99
|
forceTimer.unref();
|
|
96
100
|
|
|
101
|
+
// Workspace git heartbeat timer lives in the monitor process. This
|
|
102
|
+
// in-process stop is a no-op unless the singleton was started here.
|
|
103
|
+
await stopWorkspaceHeartbeatService();
|
|
97
104
|
await stopHeartbeatService();
|
|
98
105
|
|
|
99
106
|
// Stop the periodic consent-cache refresh (a daemon-owned interval).
|
|
@@ -127,6 +134,7 @@ async function shutdown(): Promise<void> {
|
|
|
127
134
|
disposeAcpSessionManager();
|
|
128
135
|
stopConversationEvictor();
|
|
129
136
|
stopConfigWatcher();
|
|
137
|
+
stopAppSourceWatcher();
|
|
130
138
|
stopCliIpcServer();
|
|
131
139
|
stopConversations();
|
|
132
140
|
await stopCes();
|
|
@@ -8,24 +8,16 @@ import {
|
|
|
8
8
|
maybeSeedCapabilitySkills,
|
|
9
9
|
maybeSeedCliCommandCards,
|
|
10
10
|
} from "../plugins/defaults/memory/substrate/boot-maintenance.js";
|
|
11
|
-
import { readWorkspaceSkillMdSignature } from "../skills/workspace-skill-md-signature.js";
|
|
12
11
|
import { getLogger } from "../util/logger.js";
|
|
13
12
|
|
|
14
13
|
const log = getLogger("skill-memory-refresh");
|
|
15
14
|
|
|
16
|
-
/** Poll interval for workspace `SKILL.md` mtimes. Stats only, no tree walk. */
|
|
17
|
-
export const SKILL_MD_MTIME_POLL_MS = 1_500;
|
|
18
|
-
|
|
19
|
-
let lastSignature: string | undefined;
|
|
20
|
-
let pollTimer: ReturnType<typeof setInterval> | undefined;
|
|
21
|
-
|
|
22
15
|
export function refreshSkillCapabilityMemories(
|
|
23
16
|
config: AssistantConfig = getConfig(),
|
|
24
17
|
): void {
|
|
25
18
|
seedSkillGraphNodes();
|
|
26
19
|
maybeSeedCapabilitySkills(config);
|
|
27
20
|
maybeSeedCliCommandCards(config);
|
|
28
|
-
lastSignature = readWorkspaceSkillMdSignature();
|
|
29
21
|
void seedUninstalledCatalogSkillMemories()
|
|
30
22
|
.then(() => {
|
|
31
23
|
// Re-run after the async catalog fetch populates the cache so stale
|
|
@@ -39,59 +31,3 @@ export function refreshSkillCapabilityMemories(
|
|
|
39
31
|
),
|
|
40
32
|
);
|
|
41
33
|
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Reseed skill capability memories when the workspace `SKILL.md` set or
|
|
45
|
-
* mtimes have changed since the last refresh in this process. No-op when the
|
|
46
|
-
* signature is unchanged. First call in a process always reseeds so the
|
|
47
|
-
* memory worker, whose in-process skill cache starts empty, picks up the
|
|
48
|
-
* catalog without waiting for an install path.
|
|
49
|
-
*/
|
|
50
|
-
export function maybeRefreshSkillCapabilityMemoriesFromMtime(): boolean {
|
|
51
|
-
const signature = readWorkspaceSkillMdSignature();
|
|
52
|
-
if (lastSignature !== undefined && signature === lastSignature) {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
if (lastSignature !== undefined) {
|
|
56
|
-
log.info("Workspace SKILL.md set changed, reseeding capability memories");
|
|
57
|
-
}
|
|
58
|
-
refreshSkillCapabilityMemories();
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function pollOnce(): void {
|
|
63
|
-
try {
|
|
64
|
-
maybeRefreshSkillCapabilityMemoriesFromMtime();
|
|
65
|
-
} catch (err) {
|
|
66
|
-
log.warn({ err }, "SKILL.md mtime poll failed");
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Start a per-process poll of workspace `SKILL.md` mtimes. Idempotent.
|
|
72
|
-
* The memory worker and the assistant each run this against their own
|
|
73
|
-
* in-process skill caches. Runs once immediately so a worker that has never
|
|
74
|
-
* seeded picks up the catalog without waiting a tick.
|
|
75
|
-
*/
|
|
76
|
-
export function startWorkspaceSkillMdMtimePoll(): void {
|
|
77
|
-
if (pollTimer !== undefined) {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
pollOnce();
|
|
81
|
-
pollTimer = setInterval(pollOnce, SKILL_MD_MTIME_POLL_MS);
|
|
82
|
-
pollTimer.unref?.();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function stopWorkspaceSkillMdMtimePoll(): void {
|
|
86
|
-
if (pollTimer === undefined) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
clearInterval(pollTimer);
|
|
90
|
-
pollTimer = undefined;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** @internal Test-only: clear the in-process signature and poll timer. */
|
|
94
|
-
export function _resetSkillMdMtimeStateForTests(): void {
|
|
95
|
-
lastSignature = undefined;
|
|
96
|
-
stopWorkspaceSkillMdMtimePoll();
|
|
97
|
-
}
|
|
@@ -18,15 +18,17 @@ import { invalidateEdgeIndex } from "../plugins/defaults/memory/substrate/edge-i
|
|
|
18
18
|
import { invalidatePageIndex } from "../plugins/defaults/memory/substrate/page-index.js";
|
|
19
19
|
import { getConceptsDir } from "../plugins/defaults/memory/substrate/page-store.js";
|
|
20
20
|
import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
publishAppsChanged,
|
|
23
|
+
publishDocumentsChanged,
|
|
24
|
+
} from "../runtime/sync/resource-sync-events.js";
|
|
25
|
+
import { updatePublishedAppDeployment } from "../services/published-app-updater.js";
|
|
22
26
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
23
27
|
import { getLogger } from "../util/logger.js";
|
|
24
28
|
import { getWorkspaceDir } from "../util/platform.js";
|
|
25
|
-
import {
|
|
26
|
-
broadcastAppFilesChanged,
|
|
27
|
-
notifyAppSurfacesChanged,
|
|
28
|
-
} from "./app-change-notify.js";
|
|
29
|
+
import { ensureAppSourceWatcher } from "./app-source-watcher.js";
|
|
29
30
|
import type { Conversation } from "./conversation.js";
|
|
31
|
+
import { refreshSurfacesForApp } from "./conversation-surfaces.js";
|
|
30
32
|
import { isDoordashCommand, updateDoordashProgress } from "./doordash-steps.js";
|
|
31
33
|
|
|
32
34
|
const log = getLogger("tool-side-effects");
|
|
@@ -52,7 +54,7 @@ export type PostExecutionHook = (
|
|
|
52
54
|
* Compilation is the responsibility of the tool executor (see
|
|
53
55
|
* `executeAppCreate`, `executeAppRefresh`): executors own the source→dist
|
|
54
56
|
* transform and surface `compile_errors` in their result when it fails.
|
|
55
|
-
* Post-execution hooks only observe the outcome and notify
|
|
57
|
+
* Post-execution hooks only observe the outcome and notify — they must
|
|
56
58
|
* not re-run a compile because `compileApp()` begins with `rm -rf dist/`
|
|
57
59
|
* and would race with the executor's own output (LUM-1153).
|
|
58
60
|
*/
|
|
@@ -61,7 +63,14 @@ function notifyAppChanged(
|
|
|
61
63
|
appId: string,
|
|
62
64
|
opts?: { fileChange?: boolean; status?: string },
|
|
63
65
|
): void {
|
|
64
|
-
|
|
66
|
+
refreshSurfacesForApp(ctx, appId, opts);
|
|
67
|
+
broadcastAppFilesChanged(appId);
|
|
68
|
+
void updatePublishedAppDeployment(appId);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function broadcastAppFilesChanged(appId: string): void {
|
|
72
|
+
broadcastMessage({ type: "app_files_changed", appId });
|
|
73
|
+
publishAppsChanged();
|
|
65
74
|
}
|
|
66
75
|
|
|
67
76
|
/**
|
|
@@ -119,6 +128,8 @@ registerHook("app_create", (_name, _input, result, { ctx }) => {
|
|
|
119
128
|
log.warn({ err, appId }, "Failed to track conversation ID on app_create");
|
|
120
129
|
}
|
|
121
130
|
|
|
131
|
+
ensureAppSourceWatcher();
|
|
132
|
+
|
|
122
133
|
notifyAppChanged(ctx, appId);
|
|
123
134
|
|
|
124
135
|
// Seed background icon generation from the created app's canonical record
|
package/src/hooks/types.ts
CHANGED
|
@@ -679,36 +679,3 @@ export interface ConversationDeletedContext
|
|
|
679
679
|
* {@link BaseHookContext}.
|
|
680
680
|
*/
|
|
681
681
|
export type ConversationsClearedContext = BaseHookContext;
|
|
682
|
-
|
|
683
|
-
// ─── Message-deleted hook context ────────────────────────────────────────────
|
|
684
|
-
|
|
685
|
-
/**
|
|
686
|
-
* Context passed to the `message-deleted` hook. Fires once per deleted
|
|
687
|
-
* message row, from the shared single-message delete primitive, after the row
|
|
688
|
-
* is removed. Whole-conversation deletes dispatch `conversation-deleted`
|
|
689
|
-
* instead.
|
|
690
|
-
*
|
|
691
|
-
* Fire-and-forget like `conversation-deleted`: the primitive is synchronous
|
|
692
|
-
* and does not wait for the chain. The row is gone by the time a hook runs,
|
|
693
|
-
* so the context carries the row's `createdAt` alongside its id. Together
|
|
694
|
-
* they are the `(createdAt, id)` position the row held, which is what a hook
|
|
695
|
-
* keeping a cursor on that row needs to record once the row can no longer be
|
|
696
|
-
* looked up. The default memory plugin contributes a hook here that stamps
|
|
697
|
-
* its retrospective cursor.
|
|
698
|
-
*/
|
|
699
|
-
export interface MessageDeletedInputContext {
|
|
700
|
-
/** ID of the conversation that owned the row. */
|
|
701
|
-
readonly conversationId: string;
|
|
702
|
-
/** ID of the deleted message row. */
|
|
703
|
-
readonly messageId: string;
|
|
704
|
-
/** The deleted row's `createdAt`. */
|
|
705
|
-
readonly createdAt: number;
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
/**
|
|
709
|
-
* The full `message-deleted` context a hook receives: the dispatching call
|
|
710
|
-
* site's {@link MessageDeletedInputContext} plus the pipeline-stamped
|
|
711
|
-
* {@link BaseHookContext} capabilities.
|
|
712
|
-
*/
|
|
713
|
-
export interface MessageDeletedContext
|
|
714
|
-
extends MessageDeletedInputContext, BaseHookContext {}
|
|
@@ -18,10 +18,9 @@
|
|
|
18
18
|
* the platform can register a route that points at this instance.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import { getPlatformBaseUrl } from "../config/env.js";
|
|
21
|
+
import { getPlatformAssistantId, getPlatformBaseUrl } from "../config/env.js";
|
|
22
22
|
import { getIsPlatform } from "../config/env-registry.js";
|
|
23
23
|
import { getConfig } from "../config/loader.js";
|
|
24
|
-
import { resolvePlatformAssistantId } from "../config/platform-identity.js";
|
|
25
24
|
import { ipcRegisterWebhookRoute } from "../ipc/gateway-client.js";
|
|
26
25
|
import { credentialKey } from "../security/credential-key.js";
|
|
27
26
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
@@ -46,11 +45,11 @@ export interface PlatformCallbackRegistrationContext {
|
|
|
46
45
|
|
|
47
46
|
export async function resolvePlatformCallbackRegistrationContext(): Promise<PlatformCallbackRegistrationContext> {
|
|
48
47
|
const platform = getIsPlatform();
|
|
49
|
-
const [storedBaseUrlRaw,
|
|
48
|
+
const [storedBaseUrlRaw, storedAssistantIdRaw, storedAssistantApiKeyRaw] =
|
|
50
49
|
await Promise.all([
|
|
51
50
|
getSecureKeyAsync(credentialKey("vellum", "platform_base_url")),
|
|
51
|
+
getSecureKeyAsync(credentialKey("vellum", "platform_assistant_id")),
|
|
52
52
|
getSecureKeyAsync(credentialKey("vellum", "assistant_api_key")),
|
|
53
|
-
resolvePlatformAssistantId(),
|
|
54
53
|
]);
|
|
55
54
|
|
|
56
55
|
const storedBaseUrl = storedBaseUrlRaw?.trim();
|
|
@@ -58,6 +57,8 @@ export async function resolvePlatformCallbackRegistrationContext(): Promise<Plat
|
|
|
58
57
|
/\/+$/,
|
|
59
58
|
"",
|
|
60
59
|
);
|
|
60
|
+
const assistantId =
|
|
61
|
+
getPlatformAssistantId().trim() || storedAssistantIdRaw?.trim() || "";
|
|
61
62
|
const envAssistantCredential = process.env.ASSISTANT_API_KEY?.trim();
|
|
62
63
|
const assistantCredential =
|
|
63
64
|
storedAssistantApiKeyRaw?.trim() || envAssistantCredential || undefined;
|
|
@@ -329,6 +329,7 @@ describe("LiveVoiceMetricsCollector", () => {
|
|
|
329
329
|
endpointHoldCount: 0,
|
|
330
330
|
endpointDecisionMaxLatencyMs: 95,
|
|
331
331
|
});
|
|
332
|
+
expect(completed).not.toHaveProperty("ackSpoken");
|
|
332
333
|
});
|
|
333
334
|
|
|
334
335
|
test("decisions without a source are attributed to the front door", () => {
|
|
@@ -434,6 +435,7 @@ describe("LiveVoiceMetricsCollector", () => {
|
|
|
434
435
|
expect(completed).not.toHaveProperty("endpointHoldCount");
|
|
435
436
|
expect(completed).not.toHaveProperty("endpointDecisionMaxLatencyMs");
|
|
436
437
|
expect(completed).not.toHaveProperty("endpointDecisionSource");
|
|
438
|
+
expect(completed).not.toHaveProperty("ackSpoken");
|
|
437
439
|
expect(completed).not.toHaveProperty("progressUpdatesSpoken");
|
|
438
440
|
|
|
439
441
|
const aggregateFields = getLiveVoiceMetricsAggregateFields(
|
|
@@ -444,6 +446,7 @@ describe("LiveVoiceMetricsCollector", () => {
|
|
|
444
446
|
expect(aggregateFields).not.toHaveProperty("endpointHoldCount");
|
|
445
447
|
expect(aggregateFields).not.toHaveProperty("endpointDecisionMaxLatencyMs");
|
|
446
448
|
expect(aggregateFields).not.toHaveProperty("endpointDecisionSource");
|
|
449
|
+
expect(aggregateFields).not.toHaveProperty("ackSpoken");
|
|
447
450
|
expect(aggregateFields).not.toHaveProperty("progressUpdatesSpoken");
|
|
448
451
|
});
|
|
449
452
|
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
import { describe, expect, mock, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
VoiceProgressNarrator,
|
|
5
|
-
VoiceProgressTextInput,
|
|
6
|
-
} from "../../calls/progress-narration.js";
|
|
7
|
-
import {
|
|
8
|
-
pickProgressPhrase,
|
|
9
|
-
PROGRESS_FALLBACK_PHRASES,
|
|
10
|
-
PROGRESS_FALLBACK_PHRASES_BY_LANGUAGE,
|
|
11
|
-
} from "../../calls/progress-phrases.js";
|
|
12
3
|
import { sanitizeForTts } from "../../calls/tts-text-sanitizer.js";
|
|
13
4
|
import type {
|
|
14
5
|
VoiceTurnCallbacks,
|
|
@@ -16,9 +7,9 @@ import type {
|
|
|
16
7
|
} from "../../calls/voice-session-bridge.js";
|
|
17
8
|
import { loadRawConfig, saveRawConfig } from "../../config/loader.js";
|
|
18
9
|
import type {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
} from "../../config/schemas/voice.js";
|
|
10
|
+
LiveVoiceFrontModelConfig,
|
|
11
|
+
LiveVoiceProgressConfig,
|
|
12
|
+
} from "../../config/schemas/live-voice.js";
|
|
22
13
|
import type {
|
|
23
14
|
StreamingTranscriber,
|
|
24
15
|
SttStreamServerEvent,
|
|
@@ -30,6 +21,15 @@ import {
|
|
|
30
21
|
} from "../live-voice-session.js";
|
|
31
22
|
import type { LiveVoiceSessionFactoryContext } from "../live-voice-session-manager.js";
|
|
32
23
|
import type { LiveVoiceTtsOptions } from "../live-voice-tts.js";
|
|
24
|
+
import type {
|
|
25
|
+
VoiceProgressNarrator,
|
|
26
|
+
VoiceProgressTextInput,
|
|
27
|
+
} from "../progress-narration.js";
|
|
28
|
+
import {
|
|
29
|
+
pickProgressPhrase,
|
|
30
|
+
PROGRESS_FALLBACK_PHRASES,
|
|
31
|
+
PROGRESS_FALLBACK_PHRASES_BY_LANGUAGE,
|
|
32
|
+
} from "../progress-phrases.js";
|
|
33
33
|
import {
|
|
34
34
|
createLiveVoiceServerFrameSequencer,
|
|
35
35
|
type LiveVoiceClientStartFrame,
|
|
@@ -142,8 +142,8 @@ function makeProgressNarrator(
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
function progressConfig(
|
|
145
|
-
overrides: Partial<
|
|
146
|
-
): Partial<
|
|
145
|
+
overrides: Partial<LiveVoiceProgressConfig> = {},
|
|
146
|
+
): Partial<LiveVoiceFrontModelConfig> {
|
|
147
147
|
const idleIntervalMs = overrides.idleIntervalMs ?? 60_000;
|
|
148
148
|
return {
|
|
149
149
|
progress: {
|
|
@@ -163,7 +163,7 @@ function progressConfig(
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
function createProgressHarness(options: {
|
|
166
|
-
frontModelConfig: Partial<
|
|
166
|
+
frontModelConfig: Partial<LiveVoiceFrontModelConfig>;
|
|
167
167
|
progressNarrator: VoiceProgressNarrator;
|
|
168
168
|
emitMetrics?: boolean;
|
|
169
169
|
gateTtsText?: (text: string) => Promise<void> | null;
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
loadRawConfig,
|
|
13
13
|
saveRawConfig,
|
|
14
14
|
} from "../../config/loader.js";
|
|
15
|
-
import type {
|
|
15
|
+
import type { LiveVoiceFrontModelConfig } from "../../config/schemas/live-voice.js";
|
|
16
16
|
import type {
|
|
17
17
|
StreamingTranscriber,
|
|
18
18
|
SttStreamServerEvent,
|
|
@@ -183,7 +183,7 @@ function createHarness(options: {
|
|
|
183
183
|
echoBargeInMargin?: number;
|
|
184
184
|
echoEmaHalfLifeMs?: number;
|
|
185
185
|
echoDrainSlackMs?: number;
|
|
186
|
-
frontModelConfig?: Partial<
|
|
186
|
+
frontModelConfig?: Partial<LiveVoiceFrontModelConfig>;
|
|
187
187
|
emitMetrics?: boolean;
|
|
188
188
|
metricsClock?: () => number;
|
|
189
189
|
// Return a promise to hold a frame's transport write open (a backed-up
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { LiveVoiceProgressConfigSchema } from "../../config/schemas/live-voice.js";
|
|
4
4
|
import type { Provider, ProviderResponse } from "../../providers/types.js";
|
|
5
5
|
import {
|
|
6
6
|
createVoiceProgressNarrator,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type VoiceProgressTextInput,
|
|
9
9
|
} from "../progress-narration.js";
|
|
10
10
|
|
|
11
|
-
const config =
|
|
11
|
+
const config = LiveVoiceProgressConfigSchema.parse({});
|
|
12
12
|
const progressInput: VoiceProgressTextInput = {
|
|
13
13
|
transcriptSoFar: "compare flight prices for next month",
|
|
14
14
|
completedOps: [
|
|
@@ -177,7 +177,7 @@ describe("createVoiceProgressNarrator", () => {
|
|
|
177
177
|
|
|
178
178
|
test("bounds provider resolution by the configured timeout", async () => {
|
|
179
179
|
const narrator = createVoiceProgressNarrator({
|
|
180
|
-
config:
|
|
180
|
+
config: LiveVoiceProgressConfigSchema.parse({ generationTimeoutMs: 20 }),
|
|
181
181
|
getProvider: () => new Promise<Provider | null>(() => {}),
|
|
182
182
|
});
|
|
183
183
|
const startedAt = Date.now();
|
|
@@ -187,7 +187,7 @@ describe("createVoiceProgressNarrator", () => {
|
|
|
187
187
|
|
|
188
188
|
test("a caller abort settles promptly", async () => {
|
|
189
189
|
const narrator = createVoiceProgressNarrator({
|
|
190
|
-
config:
|
|
190
|
+
config: LiveVoiceProgressConfigSchema.parse({
|
|
191
191
|
generationTimeoutMs: 60_000,
|
|
192
192
|
}),
|
|
193
193
|
getProvider: async () =>
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { describe, expect, test } from "bun:test";
|
|
10
10
|
|
|
11
|
+
import { BRIDGE_SENTENCE_END_REGEX } from "../../calls/voice-triage-escalate.js";
|
|
11
12
|
import { DEEPGRAM_MULTI_LANGUAGE_CODES } from "../../providers/speech-to-text/deepgram.js";
|
|
12
13
|
import {
|
|
13
14
|
APPROVAL_PENDING_PHRASE,
|
|
@@ -17,7 +18,6 @@ import {
|
|
|
17
18
|
PROGRESS_FALLBACK_PHRASES,
|
|
18
19
|
PROGRESS_FALLBACK_PHRASES_BY_LANGUAGE,
|
|
19
20
|
} from "../progress-phrases.js";
|
|
20
|
-
import { BRIDGE_SENTENCE_END_REGEX } from "../voice-triage-escalate.js";
|
|
21
21
|
|
|
22
22
|
// Scripts without space-delimited words, where a word budget is
|
|
23
23
|
// meaningless and length is asserted instead.
|