@vellumai/assistant 0.12.1-dev.202609141913.5e16607 → 0.12.1-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/AGENTS.md +0 -4
- package/ARCHITECTURE.md +12 -11
- package/docs/architecture/turn-actor.md +8 -15
- package/docs/guardian-request-flow.md +0 -16
- package/openapi.yaml +49 -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 +2 -4
- package/src/__tests__/cu-unified-flow.test.ts +2 -8
- package/src/__tests__/document-sync-tags.test.ts +0 -25
- 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__/notification-vellum-adapter.test.ts +2 -85
- package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
- package/src/__tests__/platform-callback-registration.test.ts +16 -8
- 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/events/notification-intent.ts +0 -2
- 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/bash.help.ts +13 -8
- package/src/cli/commands/bash.ts +25 -7
- 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 +9 -99
- 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/SKILL.md +3 -3
- 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/schedule/SKILL.md +4 -3
- 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 -24
- package/src/config/loader.ts +0 -1
- 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 +27 -11
- 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/services.ts +0 -8
- 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/orphan-reaper.ts +1 -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/home/__tests__/feed-writer.test.ts +0 -22
- package/src/home/feed-writer.ts +2 -11
- 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__/guardian-feed-projection.test.ts +2 -158
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +3 -153
- package/src/notifications/__tests__/schedule-result-producer.test.ts +3 -99
- package/src/notifications/adapters/macos.ts +0 -3
- 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/guardian-feed-projection.ts +5 -125
- package/src/notifications/home-feed-side-effect.ts +7 -55
- package/src/notifications/schedule-result-producer.ts +22 -66
- package/src/oauth/__tests__/seed-providers-managed.test.ts +0 -54
- package/src/oauth/byo-connection.test.ts +0 -45
- package/src/oauth/byo-connection.ts +6 -36
- package/src/oauth/connection-resolver.test.ts +0 -73
- package/src/oauth/connection-resolver.ts +2 -95
- package/src/oauth/seed-providers.ts +0 -165
- 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 +2 -4
- 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/inference/auth.ts +3 -2
- package/src/providers/inference/connection-availability.ts +8 -27
- package/src/providers/inference/resolve-auth.ts +4 -22
- 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__/default-provider-routes.test.ts +2 -2
- 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/debug-bash-routes.ts +173 -0
- package/src/runtime/routes/diagnostics-routes.ts +3 -55
- package/src/runtime/routes/index.ts +2 -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 +20 -6
- 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__/service-account-token.test.ts +0 -247
- 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__/bash.test.ts +0 -53
- 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 -255
- 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 -201
- 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/inference/service-account-token.ts +0 -248
- 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/tools/terminal/__tests__/sanitized-bash.test.ts +0 -57
- package/src/tools/terminal/sanitized-bash.ts +0 -105
- 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
|
@@ -1329,171 +1329,6 @@ export const PROVIDER_SEED_DATA: Record<
|
|
|
1329
1329
|
identityUrl: "https://api.link.com/userinfo",
|
|
1330
1330
|
identityResponsePaths: ["email", "phone"],
|
|
1331
1331
|
},
|
|
1332
|
-
shopify: {
|
|
1333
|
-
provider: "shopify",
|
|
1334
|
-
// Shopify is per-tenant: every OAuth endpoint lives on the merchant's own
|
|
1335
|
-
// myshopify.com domain, so these carry a {tenant_host} placeholder the
|
|
1336
|
-
// platform fills in from the shop domain the user supplies at connect
|
|
1337
|
-
// time. There is no global Shopify authorization host to point at.
|
|
1338
|
-
authorizeUrl: "https://{tenant_host}/admin/oauth/authorize",
|
|
1339
|
-
tokenExchangeUrl: "https://{tenant_host}/admin/oauth/access_token",
|
|
1340
|
-
// Requesting `expiring=1` at token exchange yields a short-lived access
|
|
1341
|
-
// token plus a refresh token, which is refreshed against the same
|
|
1342
|
-
// per-shop endpoint.
|
|
1343
|
-
refreshUrl: "https://{tenant_host}/admin/oauth/access_token",
|
|
1344
|
-
pingUrl: "https://{tenant_host}/admin/api/2026-07/shop.json",
|
|
1345
|
-
baseUrl: "https://{tenant_host}",
|
|
1346
|
-
displayLabel: "Shopify",
|
|
1347
|
-
description: "Products, orders, customers, and inventory",
|
|
1348
|
-
dashboardUrl: "https://shopify.dev/dashboard",
|
|
1349
|
-
clientIdPlaceholder: null,
|
|
1350
|
-
logoUrl: "https://cdn.simpleicons.org/shopify",
|
|
1351
|
-
// Shopify parses `scope` as a comma-separated list. A space-separated
|
|
1352
|
-
// list is read as one malformed scope and the request is rejected.
|
|
1353
|
-
scopeSeparator: ",",
|
|
1354
|
-
// Admin API scopes only: Storefront, Customer Account and Shop APIs are
|
|
1355
|
-
// buyer-facing surfaces an assistant has no use for. Every scope here is
|
|
1356
|
-
// grantable without Shopify approval -- the approval-gated ones
|
|
1357
|
-
// (read_all_orders, customer payment methods, subscription contracts,
|
|
1358
|
-
// dispute evidence) are deliberately absent, because Shopify rejects the
|
|
1359
|
-
// whole authorization request if the app cannot grant a requested scope.
|
|
1360
|
-
// A write_* grant implies its read_* counterpart, so the response may
|
|
1361
|
-
// name only the write scope.
|
|
1362
|
-
defaultScopes: [
|
|
1363
|
-
"read_products",
|
|
1364
|
-
"write_products",
|
|
1365
|
-
"read_orders",
|
|
1366
|
-
"write_orders",
|
|
1367
|
-
"read_draft_orders",
|
|
1368
|
-
"write_draft_orders",
|
|
1369
|
-
"read_customers",
|
|
1370
|
-
"write_customers",
|
|
1371
|
-
"read_inventory",
|
|
1372
|
-
"read_locations",
|
|
1373
|
-
"read_fulfillments",
|
|
1374
|
-
"read_discounts",
|
|
1375
|
-
"write_discounts",
|
|
1376
|
-
"read_price_rules",
|
|
1377
|
-
],
|
|
1378
|
-
availableScopes: [
|
|
1379
|
-
{
|
|
1380
|
-
scope: "read_products",
|
|
1381
|
-
description: "Read products, variants, and collections",
|
|
1382
|
-
},
|
|
1383
|
-
{
|
|
1384
|
-
scope: "write_products",
|
|
1385
|
-
description: "Create and update products, variants, and collections",
|
|
1386
|
-
},
|
|
1387
|
-
{
|
|
1388
|
-
scope: "read_orders",
|
|
1389
|
-
description: "Read orders, transactions, and abandoned checkouts",
|
|
1390
|
-
},
|
|
1391
|
-
{
|
|
1392
|
-
scope: "write_orders",
|
|
1393
|
-
description: "Create and update orders and fulfillments",
|
|
1394
|
-
},
|
|
1395
|
-
{ scope: "read_draft_orders", description: "Read draft orders" },
|
|
1396
|
-
{
|
|
1397
|
-
scope: "write_draft_orders",
|
|
1398
|
-
description: "Create and update draft orders",
|
|
1399
|
-
},
|
|
1400
|
-
{
|
|
1401
|
-
scope: "read_customers",
|
|
1402
|
-
description: "Read customers, segments, and companies",
|
|
1403
|
-
},
|
|
1404
|
-
{
|
|
1405
|
-
scope: "write_customers",
|
|
1406
|
-
description: "Create and update customers and segments",
|
|
1407
|
-
},
|
|
1408
|
-
{
|
|
1409
|
-
scope: "read_inventory",
|
|
1410
|
-
description: "Read inventory levels and items",
|
|
1411
|
-
},
|
|
1412
|
-
{
|
|
1413
|
-
scope: "write_inventory",
|
|
1414
|
-
description: "Adjust inventory levels and items",
|
|
1415
|
-
},
|
|
1416
|
-
{ scope: "read_locations", description: "Read store locations" },
|
|
1417
|
-
{ scope: "read_fulfillments", description: "Read fulfillment services" },
|
|
1418
|
-
{
|
|
1419
|
-
scope: "write_fulfillments",
|
|
1420
|
-
description: "Create and update fulfillment services",
|
|
1421
|
-
},
|
|
1422
|
-
{ scope: "read_discounts", description: "Read discounts" },
|
|
1423
|
-
{ scope: "write_discounts", description: "Create and update discounts" },
|
|
1424
|
-
{ scope: "read_price_rules", description: "Read price rules" },
|
|
1425
|
-
{
|
|
1426
|
-
scope: "write_price_rules",
|
|
1427
|
-
description: "Create and update price rules",
|
|
1428
|
-
},
|
|
1429
|
-
{ scope: "read_files", description: "Read files uploaded to the store" },
|
|
1430
|
-
{ scope: "write_files", description: "Upload and update files" },
|
|
1431
|
-
{ scope: "read_gift_cards", description: "Read gift cards" },
|
|
1432
|
-
{
|
|
1433
|
-
scope: "write_gift_cards",
|
|
1434
|
-
description: "Create and update gift cards",
|
|
1435
|
-
},
|
|
1436
|
-
{ scope: "read_returns", description: "Read returns" },
|
|
1437
|
-
{ scope: "write_returns", description: "Create and update returns" },
|
|
1438
|
-
{ scope: "read_markets", description: "Read markets" },
|
|
1439
|
-
{ scope: "read_locales", description: "Read shop locales" },
|
|
1440
|
-
{
|
|
1441
|
-
scope: "read_shipping",
|
|
1442
|
-
description: "Read shipping and delivery carrier services",
|
|
1443
|
-
},
|
|
1444
|
-
{ scope: "read_analytics", description: "Read analytics and reports" },
|
|
1445
|
-
{
|
|
1446
|
-
scope: "read_marketing_events",
|
|
1447
|
-
description: "Read marketing events and activities",
|
|
1448
|
-
},
|
|
1449
|
-
{ scope: "read_order_edits", description: "Read order edits" },
|
|
1450
|
-
{
|
|
1451
|
-
scope: "write_order_edits",
|
|
1452
|
-
description: "Create and apply order edits",
|
|
1453
|
-
},
|
|
1454
|
-
{
|
|
1455
|
-
scope: "read_metaobjects",
|
|
1456
|
-
description: "Read metaobjects and their definitions",
|
|
1457
|
-
},
|
|
1458
|
-
{
|
|
1459
|
-
scope: "write_metaobjects",
|
|
1460
|
-
description: "Create and update metaobjects",
|
|
1461
|
-
},
|
|
1462
|
-
{ scope: "read_translations", description: "Read translated content" },
|
|
1463
|
-
{
|
|
1464
|
-
scope: "read_shopify_payments_payouts",
|
|
1465
|
-
description: "Read Shopify Payments payouts and balance",
|
|
1466
|
-
},
|
|
1467
|
-
{
|
|
1468
|
-
scope: "read_shopify_payments_disputes",
|
|
1469
|
-
description: "Read Shopify Payments disputes",
|
|
1470
|
-
},
|
|
1471
|
-
],
|
|
1472
|
-
loopbackPort: 17341,
|
|
1473
|
-
managedServiceConfigKey: "shopify-oauth",
|
|
1474
|
-
injectionTemplates: [
|
|
1475
|
-
{
|
|
1476
|
-
hostPattern: "*.myshopify.com",
|
|
1477
|
-
injectionType: "header",
|
|
1478
|
-
headerName: "X-Shopify-Access-Token",
|
|
1479
|
-
valuePrefix: "",
|
|
1480
|
-
},
|
|
1481
|
-
],
|
|
1482
|
-
appType: "App",
|
|
1483
|
-
setupNotes: [
|
|
1484
|
-
"Shopify OAuth is per-shop: the authorize, token and API endpoints all live on the merchant's own myshopify.com domain, so connecting requires the shop domain (for example your-store.myshopify.com) alongside the usual credentials.",
|
|
1485
|
-
"The Admin API authenticates with the X-Shopify-Access-Token header rather than an Authorization Bearer header.",
|
|
1486
|
-
],
|
|
1487
|
-
// The Admin API's shop endpoint nests its payload under "shop"; the
|
|
1488
|
-
// myshopify domain is the stable, human-recognisable handle.
|
|
1489
|
-
identityUrl: "https://{tenant_host}/admin/api/2026-07/shop.json",
|
|
1490
|
-
identityResponsePaths: ["shop.myshopify_domain", "shop.name"],
|
|
1491
|
-
// Gated like monday/figma/stripe-link: the platform side and the
|
|
1492
|
-
// shop-domain input in the clients land separately, and until both are
|
|
1493
|
-
// in place a visible Shopify tile would offer a connect flow that
|
|
1494
|
-
// cannot complete.
|
|
1495
|
-
featureFlag: "shopify-oauth",
|
|
1496
|
-
},
|
|
1497
1332
|
};
|
|
1498
1333
|
|
|
1499
1334
|
export const SEEDED_PROVIDER_KEYS = new Set(Object.keys(PROVIDER_SEED_DATA));
|
|
@@ -2,8 +2,6 @@ import { X509Certificate } from "node:crypto";
|
|
|
2
2
|
import { chmod, mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
|
|
5
|
-
import { writeCombinedCABundle } from "../util/ca-bundle.js";
|
|
6
|
-
|
|
7
5
|
const CA_CERT_FILENAME = "ca.pem";
|
|
8
6
|
const CA_KEY_FILENAME = "ca-key.pem";
|
|
9
7
|
const COMBINED_CA_FILENAME = "combined-ca-bundle.pem";
|
|
@@ -265,7 +263,11 @@ export async function ensureCombinedCABundle(
|
|
|
265
263
|
}
|
|
266
264
|
|
|
267
265
|
try {
|
|
268
|
-
|
|
266
|
+
const [systemCAs, proxyCACert] = await Promise.all([
|
|
267
|
+
readFile(systemBundlePath, "utf-8"),
|
|
268
|
+
readFile(caCertPath, "utf-8"),
|
|
269
|
+
]);
|
|
270
|
+
await writeFile(combinedPath, systemCAs + "\n" + proxyCACert);
|
|
269
271
|
return combinedPath;
|
|
270
272
|
} catch {
|
|
271
273
|
return null;
|
|
@@ -15,16 +15,13 @@ mock.module("../config/assistant-feature-flags.js", () => ({
|
|
|
15
15
|
}));
|
|
16
16
|
|
|
17
17
|
// `buildPolicyContext` (used by the integration tests below) precomputes the
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
// opt-out rather than the old v3 condition.
|
|
18
|
+
// proc-to-skills gate via `isV3TierActive`. Drive it through this slot so a
|
|
19
|
+
// test can put the production threading path in the active / inactive state.
|
|
21
20
|
let mockV3TierActive = true;
|
|
22
|
-
let mockSkillImprovementActive = true;
|
|
23
21
|
mock.module("../config/memory-v3-gate.js", () => ({
|
|
24
22
|
isMemoryEnabled: (config?: { memory?: { enabled?: boolean } }) =>
|
|
25
23
|
config?.memory?.enabled !== false,
|
|
26
24
|
isV3TierActive: () => mockV3TierActive,
|
|
27
|
-
isSkillImprovementActive: () => mockSkillImprovementActive,
|
|
28
25
|
isMemoryV3Live: () => mockV3TierActive,
|
|
29
26
|
usesConceptPageMemory: (memory?: {
|
|
30
27
|
enabled?: boolean;
|
|
@@ -222,7 +219,6 @@ describe("Permission Checker (gateway IPC)", () => {
|
|
|
222
219
|
mockCachedThreshold = "low";
|
|
223
220
|
mockRefreshedThreshold = null;
|
|
224
221
|
mockV3TierActive = true;
|
|
225
|
-
mockSkillImprovementActive = true;
|
|
226
222
|
thresholdCallLog.length = 0;
|
|
227
223
|
mockSkillCatalog = [];
|
|
228
224
|
mockResolvedSkill = null;
|
|
@@ -1177,11 +1173,10 @@ describe("Permission Checker (gateway IPC)", () => {
|
|
|
1177
1173
|
});
|
|
1178
1174
|
|
|
1179
1175
|
test("grant does NOT fire when proc-to-skills is inactive, even for the retrospective turn", async () => {
|
|
1180
|
-
//
|
|
1181
|
-
//
|
|
1182
|
-
// grant is dead and the high-risk scaffold prompts.
|
|
1183
|
-
mockV3TierActive =
|
|
1184
|
-
mockSkillImprovementActive = false;
|
|
1176
|
+
// Same retrospective ToolContext, but the feature is inactive (flag off
|
|
1177
|
+
// or v3 not live). buildPolicyContext stamps `procToSkillsActive: false`,
|
|
1178
|
+
// so the grant is dead and the high-risk scaffold prompts.
|
|
1179
|
+
mockV3TierActive = false;
|
|
1185
1180
|
mockIpcClassifyRiskResult = {
|
|
1186
1181
|
risk: "high",
|
|
1187
1182
|
reason: "Skill scaffold",
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
*/
|
|
27
27
|
import type { AgentEvent } from "../agent/loop.js";
|
|
28
28
|
import { getConfig } from "../config/loader.js";
|
|
29
|
-
import { resolvePlatformAssistantIdOrNull } from "../config/platform-identity.js";
|
|
30
29
|
import type { CompactionLogsClickHouseConfig } from "../config/schemas/compaction-logs.js";
|
|
31
30
|
import { credentialKey } from "../security/credential-key.js";
|
|
32
31
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
@@ -137,7 +136,7 @@ export interface ClickHouseCompactionLogStoreDeps {
|
|
|
137
136
|
resolveUrl?: () => Promise<string | null>;
|
|
138
137
|
/** Override the credential read for `clickhouse:password`. */
|
|
139
138
|
resolvePassword?: () => Promise<string | null>;
|
|
140
|
-
/** Override the
|
|
139
|
+
/** Override the credential read for `vellum:platform_assistant_id`. */
|
|
141
140
|
resolveAssistantId?: () => Promise<string | null>;
|
|
142
141
|
/** Override fetch for testing. */
|
|
143
142
|
fetchImpl?: CompactionLogFetch;
|
|
@@ -164,7 +163,8 @@ export class ClickHouseCompactionLogStore {
|
|
|
164
163
|
deps.resolvePassword ??
|
|
165
164
|
(() => readCredentialOrNull("clickhouse", "password"));
|
|
166
165
|
this.resolveAssistantId =
|
|
167
|
-
deps.resolveAssistantId ??
|
|
166
|
+
deps.resolveAssistantId ??
|
|
167
|
+
(() => readCredentialOrNull("vellum", "platform_assistant_id"));
|
|
168
168
|
this.fetchImpl = deps.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
169
169
|
}
|
|
170
170
|
|
|
@@ -35,10 +35,7 @@ import { findConversation } from "../daemon/conversation-registry.js";
|
|
|
35
35
|
import { conversationMetadataSyncTag } from "../daemon/message-types/sync.js";
|
|
36
36
|
import type { TrustContext } from "../daemon/trust-context-types.js";
|
|
37
37
|
import { clearAllConversationIds } from "../home/feed-writer.js";
|
|
38
|
-
import type {
|
|
39
|
-
ConversationDeletedInputContext,
|
|
40
|
-
MessageDeletedInputContext,
|
|
41
|
-
} from "../hooks/types.js";
|
|
38
|
+
import type { ConversationDeletedInputContext } from "../hooks/types.js";
|
|
42
39
|
import { readProviderMetadata } from "../messaging/read-provider-metadata.js";
|
|
43
40
|
import { HOOKS } from "../plugin-api/constants.js";
|
|
44
41
|
import { forkConversationMemory } from "../plugins/defaults/memory/fork-conversation-memory.js";
|
|
@@ -84,6 +81,7 @@ import { ensureDisplayOrderMigration } from "./conversation-display-order-migrat
|
|
|
84
81
|
import { ensureGroupMigration } from "./conversation-group-migration.js";
|
|
85
82
|
import {
|
|
86
83
|
isReferentialFork,
|
|
84
|
+
type LineageBound,
|
|
87
85
|
type LineageConversationRow,
|
|
88
86
|
lineageMessageFilter,
|
|
89
87
|
lineageMessagesAfterFilter,
|
|
@@ -123,11 +121,6 @@ import {
|
|
|
123
121
|
} from "./job-handlers/message-lexical.js";
|
|
124
122
|
import { buildLifecycleTelemetryEvent } from "./lifecycle-events-store.js";
|
|
125
123
|
import { resolveMessageContentBlocks } from "./message-content-file.js";
|
|
126
|
-
import {
|
|
127
|
-
loadMessageBound,
|
|
128
|
-
type MessagesAfterRef,
|
|
129
|
-
resolveMessagesAfterBound,
|
|
130
|
-
} from "./message-cursor.js";
|
|
131
124
|
import { mergeMessageMetadata } from "./message-metadata.js";
|
|
132
125
|
import {
|
|
133
126
|
rawAll,
|
|
@@ -2648,6 +2641,16 @@ function loadLineageRow(id: string): LineageConversationRow | null {
|
|
|
2648
2641
|
return row ?? null;
|
|
2649
2642
|
}
|
|
2650
2643
|
|
|
2644
|
+
/** The `(createdAt, id)` bound of a single message, or null when it is gone. */
|
|
2645
|
+
function loadMessageBound(messageId: string): LineageBound | null {
|
|
2646
|
+
const row = getDb()
|
|
2647
|
+
.select({ createdAt: messages.createdAt, id: messages.id })
|
|
2648
|
+
.from(messages)
|
|
2649
|
+
.where(eq(messages.id, messageId))
|
|
2650
|
+
.get();
|
|
2651
|
+
return row ?? null;
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2651
2654
|
/**
|
|
2652
2655
|
* The segments making up a conversation's logical message set. Non-forks and
|
|
2653
2656
|
* copied forks resolve to a single unbounded segment after one row lookup, so
|
|
@@ -2969,67 +2972,81 @@ export function selectNewestSightFrameCapture(
|
|
|
2969
2972
|
}
|
|
2970
2973
|
|
|
2971
2974
|
/**
|
|
2972
|
-
* Count messages in a conversation created strictly after the
|
|
2973
|
-
* reference. `
|
|
2974
|
-
*
|
|
2975
|
-
*
|
|
2976
|
-
*
|
|
2977
|
-
*
|
|
2978
|
-
* defensible starting point, and the conservative answer is "no new work."
|
|
2975
|
+
* Count messages in a conversation that were created strictly after the
|
|
2976
|
+
* `afterMessageId` reference message. If `afterMessageId` is `null` or empty,
|
|
2977
|
+
* counts all messages in the conversation. If the referenced message no
|
|
2978
|
+
* longer exists (e.g. deleted by a separate flow), returns 0 — callers
|
|
2979
|
+
* decide how to react to a vanished reference, and the conservative answer
|
|
2980
|
+
* here is "no new work."
|
|
2979
2981
|
*
|
|
2980
2982
|
* Used by the memory-retrospective trigger check to decide whether to fire
|
|
2981
2983
|
* the message-count trigger without loading message bodies.
|
|
2982
2984
|
*/
|
|
2983
2985
|
export function countMessagesAfter(
|
|
2984
2986
|
conversationId: string,
|
|
2985
|
-
|
|
2987
|
+
afterMessageId: string | null,
|
|
2986
2988
|
): number {
|
|
2987
2989
|
const db = getDb();
|
|
2988
2990
|
const segments = resolveLineage(conversationId);
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
+
if (afterMessageId === null || afterMessageId === "") {
|
|
2992
|
+
const row = db
|
|
2993
|
+
.select({ c: count() })
|
|
2994
|
+
.from(messages)
|
|
2995
|
+
.where(lineageMessageFilter(segments))
|
|
2996
|
+
.get();
|
|
2997
|
+
return row?.c ?? 0;
|
|
2998
|
+
}
|
|
2999
|
+
const ref = loadMessageBound(afterMessageId);
|
|
3000
|
+
if (!ref) {
|
|
2991
3001
|
return 0;
|
|
2992
3002
|
}
|
|
3003
|
+
// Tie-breaker on `messages.id` so rows that share a millisecond timestamp
|
|
3004
|
+
// with the reference are not permanently skipped. Mirrors the
|
|
3005
|
+
// `(createdAt, id)` cursor pattern used by the backfill job-handler and
|
|
3006
|
+
// turn-events-store.
|
|
2993
3007
|
const row = db
|
|
2994
3008
|
.select({ c: count() })
|
|
2995
3009
|
.from(messages)
|
|
2996
|
-
.where(
|
|
2997
|
-
start.kind === "all"
|
|
2998
|
-
? lineageMessageFilter(segments)
|
|
2999
|
-
: lineageMessagesAfterFilter(segments, start.bound),
|
|
3000
|
-
)
|
|
3010
|
+
.where(lineageMessagesAfterFilter(segments, ref))
|
|
3001
3011
|
.get();
|
|
3002
3012
|
return row?.c ?? 0;
|
|
3003
3013
|
}
|
|
3004
3014
|
|
|
3005
3015
|
/**
|
|
3006
|
-
* Return messages in a conversation created strictly after the
|
|
3007
|
-
*
|
|
3008
|
-
*
|
|
3009
|
-
*
|
|
3010
|
-
* processes.
|
|
3016
|
+
* Return messages in a conversation created strictly after the
|
|
3017
|
+
* `afterMessageId` reference. If the reference is `null`/empty, returns all
|
|
3018
|
+
* messages. If the reference doesn't exist, returns an empty array (mirrors
|
|
3019
|
+
* `countMessagesAfter`'s conservative semantics). Used by the
|
|
3020
|
+
* memory-retrospective job handler to load the message slice it processes.
|
|
3011
3021
|
*/
|
|
3012
3022
|
export function getMessagesAfter(
|
|
3013
3023
|
conversationId: string,
|
|
3014
|
-
|
|
3024
|
+
afterMessageId: string | null,
|
|
3015
3025
|
): MessageRow[] {
|
|
3016
3026
|
const db = getDb();
|
|
3017
3027
|
const segments = resolveLineage(conversationId);
|
|
3018
|
-
|
|
3019
|
-
|
|
3028
|
+
if (afterMessageId === null || afterMessageId === "") {
|
|
3029
|
+
// Secondary `asc(messages.id)` matches the non-null path's cursor
|
|
3030
|
+
// ordering, so callers tracking `cutoffMessageId` across runs see a
|
|
3031
|
+
// consistent ordering when multiple rows share a millisecond timestamp.
|
|
3032
|
+
return db
|
|
3033
|
+
.select()
|
|
3034
|
+
.from(messages)
|
|
3035
|
+
.where(lineageMessageFilter(segments))
|
|
3036
|
+
.orderBy(asc(messages.createdAt), asc(messages.id))
|
|
3037
|
+
.all()
|
|
3038
|
+
.map(parseMessage);
|
|
3039
|
+
}
|
|
3040
|
+
const ref = loadMessageBound(afterMessageId);
|
|
3041
|
+
if (!ref) {
|
|
3020
3042
|
return [];
|
|
3021
3043
|
}
|
|
3022
|
-
//
|
|
3023
|
-
//
|
|
3024
|
-
// multiple rows share a millisecond timestamp.
|
|
3044
|
+
// Same `(createdAt, id)` cursor as `countMessagesAfter` — rows sharing
|
|
3045
|
+
// the reference's millisecond timestamp would otherwise be skipped.
|
|
3025
3046
|
return db
|
|
3026
3047
|
.select()
|
|
3027
3048
|
.from(messages)
|
|
3028
|
-
.where(
|
|
3029
|
-
start.kind === "all"
|
|
3030
|
-
? lineageMessageFilter(segments)
|
|
3031
|
-
: lineageMessagesAfterFilter(segments, start.bound),
|
|
3032
|
-
)
|
|
3049
|
+
.where(lineageMessagesAfterFilter(segments, ref))
|
|
3033
3050
|
.orderBy(asc(messages.createdAt), asc(messages.id))
|
|
3034
3051
|
.all()
|
|
3035
3052
|
.map(parseMessage);
|
|
@@ -4287,12 +4304,12 @@ export function deleteLastExchange(conversationId: string): number {
|
|
|
4287
4304
|
|
|
4288
4305
|
// Collect attachment IDs linked to the messages being deleted so we can
|
|
4289
4306
|
// scope orphan cleanup to only those candidates (not freshly uploaded ones).
|
|
4290
|
-
const
|
|
4291
|
-
.select({ id: messages.id
|
|
4307
|
+
const messageIds = db
|
|
4308
|
+
.select({ id: messages.id })
|
|
4292
4309
|
.from(messages)
|
|
4293
4310
|
.where(condition)
|
|
4294
|
-
.all()
|
|
4295
|
-
|
|
4311
|
+
.all()
|
|
4312
|
+
.map((r) => r.id);
|
|
4296
4313
|
const candidateAttachmentIds =
|
|
4297
4314
|
messageIds.length > 0
|
|
4298
4315
|
? db
|
|
@@ -4339,17 +4356,6 @@ export function deleteLastExchange(conversationId: string): number {
|
|
|
4339
4356
|
enqueueDeleteMessageLexical(deletedMessageId);
|
|
4340
4357
|
}
|
|
4341
4358
|
|
|
4342
|
-
// Notify `message-deleted` hooks for each removed row, as the
|
|
4343
|
-
// single-message primitive does: undo removes the same tail a regenerate
|
|
4344
|
-
// does, and a hook keeping a cursor on one of these rows needs its position.
|
|
4345
|
-
for (const row of deletedRows) {
|
|
4346
|
-
void runHook(HOOKS.MESSAGE_DELETED, {
|
|
4347
|
-
conversationId,
|
|
4348
|
-
messageId: row.id,
|
|
4349
|
-
createdAt: row.createdAt,
|
|
4350
|
-
} satisfies MessageDeletedInputContext);
|
|
4351
|
-
}
|
|
4352
|
-
|
|
4353
4359
|
return deleted;
|
|
4354
4360
|
}
|
|
4355
4361
|
|
|
@@ -4588,13 +4594,9 @@ export function deleteMessageById(
|
|
|
4588
4594
|
.map((r) => r.attachmentId)
|
|
4589
4595
|
.filter((id): id is string => id !== undefined);
|
|
4590
4596
|
|
|
4591
|
-
// Look up the conversation before the transaction so we can recalculate
|
|
4592
|
-
// lastMessageAt, and the row's createdAt for the `message-deleted` hook.
|
|
4597
|
+
// Look up the conversation before the transaction so we can recalculate lastMessageAt.
|
|
4593
4598
|
const msgRow = db
|
|
4594
|
-
.select({
|
|
4595
|
-
conversationId: messages.conversationId,
|
|
4596
|
-
createdAt: messages.createdAt,
|
|
4597
|
-
})
|
|
4599
|
+
.select({ conversationId: messages.conversationId })
|
|
4598
4600
|
.from(messages)
|
|
4599
4601
|
.where(eq(messages.id, messageId))
|
|
4600
4602
|
.get();
|
|
@@ -4650,16 +4652,6 @@ export function deleteMessageById(
|
|
|
4650
4652
|
// not go through the conversation-level purge.
|
|
4651
4653
|
if (msgRow) {
|
|
4652
4654
|
enqueueDeleteMessageLexical(messageId);
|
|
4653
|
-
|
|
4654
|
-
// Notify `message-deleted` hooks (e.g. the memory plugin stamping a
|
|
4655
|
-
// retrospective cursor that sat on this row). Fire-and-forget from this
|
|
4656
|
-
// synchronous primitive, like `conversation-deleted`; the context carries
|
|
4657
|
-
// the row's position because the row itself is gone.
|
|
4658
|
-
void runHook(HOOKS.MESSAGE_DELETED, {
|
|
4659
|
-
conversationId: msgRow.conversationId,
|
|
4660
|
-
messageId,
|
|
4661
|
-
createdAt: msgRow.createdAt,
|
|
4662
|
-
} satisfies MessageDeletedInputContext);
|
|
4663
4655
|
}
|
|
4664
4656
|
|
|
4665
4657
|
return result;
|
|
@@ -227,17 +227,9 @@ export function lineageMessagesAfterFilter(
|
|
|
227
227
|
): SQL {
|
|
228
228
|
return and(
|
|
229
229
|
lineageMessageFilter(segments),
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Predicate for rows strictly after a `(createdAt, id)` bound, with the id
|
|
236
|
-
* tie-breaker so rows sharing the bound's millisecond keep their order.
|
|
237
|
-
*/
|
|
238
|
-
export function messagesAfterBoundFilter(after: LineageBound): SQL {
|
|
239
|
-
return or(
|
|
240
|
-
gt(messages.createdAt, after.createdAt),
|
|
241
|
-
and(eq(messages.createdAt, after.createdAt), gt(messages.id, after.id)),
|
|
230
|
+
or(
|
|
231
|
+
gt(messages.createdAt, after.createdAt),
|
|
232
|
+
and(eq(messages.createdAt, after.createdAt), gt(messages.id, after.id)),
|
|
233
|
+
),
|
|
242
234
|
) as SQL;
|
|
243
235
|
}
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { SEND_USER_MESSAGE_DELIVERED_ACK } from "../config/send-user-message-constants.js";
|
|
11
|
-
import { MESSAGE_KEYS } from "../i18n/index.js";
|
|
12
11
|
import {
|
|
13
12
|
requestShortLabel,
|
|
14
13
|
type ShortLabelTool,
|
|
@@ -25,11 +24,8 @@ import {
|
|
|
25
24
|
type MessageRow,
|
|
26
25
|
updateConversationTitle,
|
|
27
26
|
} from "./conversation-crud.js";
|
|
28
|
-
import { isReplaceableTitle } from "./conversation-title-placeholders.js";
|
|
29
27
|
import { projectPersistedAssistantContent } from "./user-facing-content.js";
|
|
30
28
|
|
|
31
|
-
export { isReplaceableTitle } from "./conversation-title-placeholders.js";
|
|
32
|
-
|
|
33
29
|
const log = getLogger("conversation-title-service");
|
|
34
30
|
|
|
35
31
|
// ── Types ────────────────────────────────────────────────────────────
|
|
@@ -69,8 +65,8 @@ export interface TitleContext {
|
|
|
69
65
|
|
|
70
66
|
// ── Placeholder / loading state ──────────────────────────────────────
|
|
71
67
|
|
|
72
|
-
export const GENERATING_TITLE =
|
|
73
|
-
const UNTITLED_FALLBACK =
|
|
68
|
+
export const GENERATING_TITLE = "Generating title...";
|
|
69
|
+
const UNTITLED_FALLBACK = "Untitled Conversation";
|
|
74
70
|
|
|
75
71
|
// ── `conversations.isAutoTitle` values ───────────────────────────────
|
|
76
72
|
//
|
|
@@ -87,6 +83,28 @@ export const AUTO_TITLE_LLM = 1;
|
|
|
87
83
|
*/
|
|
88
84
|
export const AUTO_TITLE_DETERMINISTIC = 2;
|
|
89
85
|
|
|
86
|
+
// ── Replaceability check ─────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
const REPLACEABLE_PATTERNS = [
|
|
89
|
+
/^Runtime:\s/,
|
|
90
|
+
/^New Conversation$/,
|
|
91
|
+
/^Untitled$/,
|
|
92
|
+
/^Untitled Conversation$/,
|
|
93
|
+
/^Generating title\.\.\.$/,
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Check whether a title is a system-generated placeholder that can be
|
|
98
|
+
* safely overwritten by auto-generated titles. Returns `false` for
|
|
99
|
+
* user-provided custom titles.
|
|
100
|
+
*/
|
|
101
|
+
export function isReplaceableTitle(title: string | null): boolean {
|
|
102
|
+
if (title == null || title.trim() === "") {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
return REPLACEABLE_PATTERNS.some((pattern) => pattern.test(title));
|
|
106
|
+
}
|
|
107
|
+
|
|
90
108
|
/**
|
|
91
109
|
* Whether auto-generation may overwrite the conversation's current title.
|
|
92
110
|
* True for placeholder/system titles and for deterministic bootstrap titles
|
|
@@ -237,7 +255,7 @@ function settleForDeterministicTitle(
|
|
|
237
255
|
* conversation creation (e.g. 5 new chats in quick succession) fires N
|
|
238
256
|
* concurrent requests that can hit provider rate limits or contend for
|
|
239
257
|
* API capacity, causing later calls to time out and fall back to
|
|
240
|
-
*
|
|
258
|
+
* "Untitled Conversation".
|
|
241
259
|
*
|
|
242
260
|
* A serial queue ensures at most one title-generation LLM call is
|
|
243
261
|
* in-flight at a time. Each call is lightweight (~1–3 s for a ≤5-word
|
|
@@ -271,7 +289,7 @@ export function queueGenerateConversationTitle(
|
|
|
271
289
|
// Replace loading placeholder with a retryable fallback.
|
|
272
290
|
try {
|
|
273
291
|
const conversation = getConversation(params.conversationId);
|
|
274
|
-
if (conversation &&
|
|
292
|
+
if (conversation && conversation.title === GENERATING_TITLE) {
|
|
275
293
|
const fallback =
|
|
276
294
|
deriveFallbackTitle(params.context) ?? UNTITLED_FALLBACK;
|
|
277
295
|
updateConversationTitle(
|
|
@@ -406,7 +424,6 @@ function buildTitleSystemPrompt(): string {
|
|
|
406
424
|
"- Think: what would make a scannable sidebar label?",
|
|
407
425
|
"- Do NOT echo back what the user asked you to do",
|
|
408
426
|
"- Do NOT respond to the conversation content",
|
|
409
|
-
"- Write the title in the same language as the conversation content",
|
|
410
427
|
"- Do NOT assess feasibility or comment on capabilities",
|
|
411
428
|
"- If input is sparse or references external context, extract a topic from the words that ARE present (e.g. 'so about that t-shirt...' → 'T-Shirt Discussion'). Never describe the absence, emptiness, or insufficiency of context — titles like 'Missing Context', 'Unclear Request', 'No Topic' are forbidden",
|
|
412
429
|
].join("\n");
|
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
* can never abort a turn.
|
|
31
31
|
*/
|
|
32
32
|
import { getConfigReadOnly } from "../config/loader.js";
|
|
33
|
-
import { resolvePlatformAssistantIdOrNull } from "../config/platform-identity.js";
|
|
34
33
|
import type { LlmRequestLogsClickHouseConfig } from "../config/schemas/llm-request-logs.js";
|
|
35
34
|
import { credentialKey } from "../security/credential-key.js";
|
|
36
35
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
@@ -72,7 +71,7 @@ export interface ClickHouseLlmRequestLogSinkDeps {
|
|
|
72
71
|
resolveUrl?: () => Promise<string | null>;
|
|
73
72
|
/** Override the credential read for `clickhouse:password`. */
|
|
74
73
|
resolvePassword?: () => Promise<string | null>;
|
|
75
|
-
/** Override the
|
|
74
|
+
/** Override the credential read for `vellum:platform_assistant_id`. */
|
|
76
75
|
resolveAssistantId?: () => Promise<string | null>;
|
|
77
76
|
/** Override fetch for testing. */
|
|
78
77
|
fetchImpl?: ClickHouseSinkFetch;
|
|
@@ -99,7 +98,8 @@ export class ClickHouseLlmRequestLogSink implements LlmRequestLogWriter {
|
|
|
99
98
|
deps.resolvePassword ??
|
|
100
99
|
(() => readCredentialOrNull("clickhouse", "password"));
|
|
101
100
|
this.resolveAssistantId =
|
|
102
|
-
deps.resolveAssistantId ??
|
|
101
|
+
deps.resolveAssistantId ??
|
|
102
|
+
(() => readCredentialOrNull("vellum", "platform_assistant_id"));
|
|
103
103
|
this.fetchImpl = deps.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
* than the local source. Acceptable for the "internal use while we
|
|
16
16
|
* finetune prompts" use case; revisit when mirror updates are added.
|
|
17
17
|
*/
|
|
18
|
-
import { resolvePlatformAssistantIdOrNull } from "../config/platform-identity.js";
|
|
19
18
|
import type { LlmRequestLogsClickHouseConfig } from "../config/schemas/llm-request-logs.js";
|
|
20
19
|
import { credentialKey } from "../security/credential-key.js";
|
|
21
20
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
@@ -105,7 +104,7 @@ export interface ClickHouseLlmRequestLogSourceDeps {
|
|
|
105
104
|
resolveUrl?: () => Promise<string | null>;
|
|
106
105
|
/** Override the credential read for `clickhouse:password`. */
|
|
107
106
|
resolvePassword?: () => Promise<string | null>;
|
|
108
|
-
/** Override the
|
|
107
|
+
/** Override the credential read for `vellum:platform_assistant_id`. */
|
|
109
108
|
resolveAssistantId?: () => Promise<string | null>;
|
|
110
109
|
/** Override the turn-id resolver (default: `getAssistantMessageIdsInTurn`). */
|
|
111
110
|
resolveTurnMessageIds?: (messageId: string) => string[];
|
|
@@ -139,7 +138,8 @@ export class ClickHouseLlmRequestLogSource implements LlmRequestLogSource {
|
|
|
139
138
|
deps.resolvePassword ??
|
|
140
139
|
(() => readCredentialOrNull("clickhouse", "password"));
|
|
141
140
|
this.resolveAssistantId =
|
|
142
|
-
deps.resolveAssistantId ??
|
|
141
|
+
deps.resolveAssistantId ??
|
|
142
|
+
(() => readCredentialOrNull("vellum", "platform_assistant_id"));
|
|
143
143
|
this.resolveTurnMessageIds =
|
|
144
144
|
deps.resolveTurnMessageIds ?? getAssistantMessageIdsInTurn;
|
|
145
145
|
this.resolveMessage = deps.resolveMessage ?? getMessageById;
|