@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
|
@@ -194,10 +194,7 @@ describe("AcpAgentProcess.createSession auth_required handling", () => {
|
|
|
194
194
|
},
|
|
195
195
|
});
|
|
196
196
|
|
|
197
|
-
await expect(proc.createSession("/tmp")).resolves.
|
|
198
|
-
sessionId: "session-1",
|
|
199
|
-
configOptions: [],
|
|
200
|
-
});
|
|
197
|
+
await expect(proc.createSession("/tmp")).resolves.toBe("session-1");
|
|
201
198
|
expect(authenticateCalls()).toBe(1);
|
|
202
199
|
});
|
|
203
200
|
|
package/src/acp/agent-process.ts
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { type ChildProcess, spawn } from "node:child_process";
|
|
9
|
-
import { basename } from "node:path";
|
|
10
9
|
import { Readable, Writable } from "node:stream";
|
|
11
10
|
|
|
12
11
|
import type {
|
|
@@ -15,24 +14,14 @@ import type {
|
|
|
15
14
|
AuthMethodEnvVar,
|
|
16
15
|
Client,
|
|
17
16
|
InitializeResponse,
|
|
18
|
-
LoadSessionResponse,
|
|
19
17
|
NewSessionResponse,
|
|
20
18
|
PromptResponse,
|
|
21
|
-
ResumeSessionResponse,
|
|
22
|
-
SessionConfigOption,
|
|
23
|
-
SetSessionConfigOptionRequest,
|
|
24
19
|
} from "@agentclientprotocol/sdk";
|
|
25
20
|
import * as acp from "@agentclientprotocol/sdk";
|
|
26
21
|
|
|
27
22
|
import { getLogger } from "../util/logger.js";
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
CLAUDE_ACP_COMMAND,
|
|
31
|
-
isAcpAuthRequired,
|
|
32
|
-
isClaudeAuthFailureMessage,
|
|
33
|
-
requestErrorReason,
|
|
34
|
-
} from "./auth-required.js";
|
|
35
|
-
import { type AcpAgentConfig, AcpConfigOptionRefusedError } from "./types.js";
|
|
23
|
+
import { AcpAuthRequiredError, isAcpAuthRequired } from "./auth-required.js";
|
|
24
|
+
import type { AcpAgentConfig } from "./types.js";
|
|
36
25
|
|
|
37
26
|
const log = getLogger("acp");
|
|
38
27
|
|
|
@@ -43,16 +32,6 @@ const log = getLogger("acp");
|
|
|
43
32
|
*/
|
|
44
33
|
const STDERR_RETENTION_BYTES = 4096;
|
|
45
34
|
|
|
46
|
-
/**
|
|
47
|
-
* Normalizes the SDK's optional-and-nullable config-option field to an array,
|
|
48
|
-
* so every session call hands its caller the same shape.
|
|
49
|
-
*/
|
|
50
|
-
function normalizeConfigOptions(
|
|
51
|
-
configOptions: SessionConfigOption[] | null | undefined,
|
|
52
|
-
): SessionConfigOption[] {
|
|
53
|
-
return configOptions ?? [];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
35
|
function isEnvVarMethod(
|
|
57
36
|
method: AuthMethod,
|
|
58
37
|
): method is AuthMethodEnvVar & { type: "env_var" } {
|
|
@@ -376,21 +355,16 @@ export class AcpAgentProcess {
|
|
|
376
355
|
|
|
377
356
|
/**
|
|
378
357
|
* Creates a new ACP session in the specified working directory.
|
|
379
|
-
* Returns the session ID
|
|
358
|
+
* Returns the session ID.
|
|
380
359
|
*/
|
|
381
|
-
async createSession(
|
|
382
|
-
cwd: string,
|
|
383
|
-
): Promise<{ sessionId: string; configOptions: SessionConfigOption[] }> {
|
|
360
|
+
async createSession(cwd: string): Promise<string> {
|
|
384
361
|
log.info({ agentId: this.agentId, cwd }, "Creating ACP session");
|
|
385
362
|
|
|
386
363
|
const result: NewSessionResponse = await this.withAuthRetry(() =>
|
|
387
364
|
this.requireConnection().newSession({ cwd, mcpServers: [] }),
|
|
388
365
|
);
|
|
389
366
|
|
|
390
|
-
return
|
|
391
|
-
sessionId: result.sessionId,
|
|
392
|
-
configOptions: normalizeConfigOptions(result.configOptions),
|
|
393
|
-
};
|
|
367
|
+
return result.sessionId;
|
|
394
368
|
}
|
|
395
369
|
|
|
396
370
|
/**
|
|
@@ -401,17 +375,12 @@ export class AcpAgentProcess {
|
|
|
401
375
|
* callers should suppress forwarding of those replayed updates (see
|
|
402
376
|
* VellumAcpClientHandler.beginReplaySuppression).
|
|
403
377
|
*/
|
|
404
|
-
async loadSession(
|
|
405
|
-
sessionId: string,
|
|
406
|
-
cwd: string,
|
|
407
|
-
): Promise<{ configOptions: SessionConfigOption[] }> {
|
|
378
|
+
async loadSession(sessionId: string, cwd: string): Promise<void> {
|
|
408
379
|
log.info({ agentId: this.agentId, sessionId, cwd }, "Loading ACP session");
|
|
409
380
|
|
|
410
|
-
|
|
381
|
+
await this.withAuthRetry(() =>
|
|
411
382
|
this.requireConnection().loadSession({ sessionId, cwd, mcpServers: [] }),
|
|
412
383
|
);
|
|
413
|
-
|
|
414
|
-
return { configOptions: normalizeConfigOptions(result.configOptions) };
|
|
415
384
|
}
|
|
416
385
|
|
|
417
386
|
/**
|
|
@@ -421,70 +390,16 @@ export class AcpAgentProcess {
|
|
|
421
390
|
* preferred when the agent advertises the capability
|
|
422
391
|
* (see supportsSessionResume).
|
|
423
392
|
*/
|
|
424
|
-
async resumeSession(
|
|
425
|
-
sessionId: string,
|
|
426
|
-
cwd: string,
|
|
427
|
-
): Promise<{ configOptions: SessionConfigOption[] }> {
|
|
393
|
+
async resumeSession(sessionId: string, cwd: string): Promise<void> {
|
|
428
394
|
log.info({ agentId: this.agentId, sessionId, cwd }, "Resuming ACP session");
|
|
429
395
|
|
|
430
|
-
|
|
396
|
+
await this.withAuthRetry(() =>
|
|
431
397
|
this.requireConnection().resumeSession({
|
|
432
398
|
sessionId,
|
|
433
399
|
cwd,
|
|
434
400
|
mcpServers: [],
|
|
435
401
|
}),
|
|
436
402
|
);
|
|
437
|
-
|
|
438
|
-
return { configOptions: normalizeConfigOptions(result.configOptions) };
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Sets one session config option (e.g. the model selector) via
|
|
443
|
-
* `session/set_config_option`. The agent answers with the full refreshed
|
|
444
|
-
* option set, which is returned to the caller.
|
|
445
|
-
*
|
|
446
|
-
* A boolean value sends the `type: "boolean"` request variant; a string
|
|
447
|
-
* sends the value-id variant.
|
|
448
|
-
*/
|
|
449
|
-
async setConfigOption(
|
|
450
|
-
sessionId: string,
|
|
451
|
-
configId: string,
|
|
452
|
-
value: string | boolean,
|
|
453
|
-
): Promise<SessionConfigOption[]> {
|
|
454
|
-
log.info(
|
|
455
|
-
{ agentId: this.agentId, sessionId, configId, value },
|
|
456
|
-
"Setting ACP session config option",
|
|
457
|
-
);
|
|
458
|
-
|
|
459
|
-
const request: SetSessionConfigOptionRequest =
|
|
460
|
-
typeof value === "boolean"
|
|
461
|
-
? { sessionId, configId, type: "boolean", value }
|
|
462
|
-
: { sessionId, configId, value };
|
|
463
|
-
|
|
464
|
-
const response = await this.withAuthRetry(async () => {
|
|
465
|
-
try {
|
|
466
|
-
return await this.requireConnection().setSessionConfigOption(request);
|
|
467
|
-
} catch (err) {
|
|
468
|
-
// Wrapped here, at the request itself, so `withAuthRetry` still sees
|
|
469
|
-
// an auth_required answer and a caller cannot confuse the adapter's
|
|
470
|
-
// refusal with a transport or authentication failure. Claude's
|
|
471
|
-
// expired-token failure travels as a generic error whose reason is
|
|
472
|
-
// the only signal, so under the Claude adapter it is left for the
|
|
473
|
-
// caller to classify.
|
|
474
|
-
if (err instanceof acp.RequestError && !isAcpAuthRequired(err)) {
|
|
475
|
-
const reason = requestErrorReason(err);
|
|
476
|
-
const claudeAuthFailure =
|
|
477
|
-
basename(this.config.command) === CLAUDE_ACP_COMMAND &&
|
|
478
|
-
isClaudeAuthFailureMessage(reason);
|
|
479
|
-
if (!claudeAuthFailure) {
|
|
480
|
-
throw new AcpConfigOptionRefusedError(reason);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
throw err;
|
|
484
|
-
}
|
|
485
|
-
});
|
|
486
|
-
|
|
487
|
-
return normalizeConfigOptions(response.configOptions);
|
|
488
403
|
}
|
|
489
404
|
|
|
490
405
|
/**
|
package/src/acp/auth-required.ts
CHANGED
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
* 2. Credentials present but rejected (the expired/revoked case): the CLI
|
|
9
9
|
* surfaces the API 401 as an error message it authors, and the adapter
|
|
10
10
|
* relays it as a generic -32603 internal error, NOT as `auth_required`.
|
|
11
|
-
* {@link isClaudeAuthFailureMessage}
|
|
12
|
-
* {@link requestErrorReason} decodes out of the rejection.
|
|
11
|
+
* {@link isClaudeAuthFailureMessage}.
|
|
13
12
|
*
|
|
14
13
|
* A positive detection becomes {@link ACP_CLAUDE_AUTH_REQUIRED_CODE} on the
|
|
15
14
|
* `acp_auth_required` event, which the client turns into the inline
|
|
@@ -82,54 +81,6 @@ export function isClaudeAuthFailureMessage(
|
|
|
82
81
|
);
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
/** Messages the SDK's `RequestError` factories build when given no text. */
|
|
86
|
-
const GENERIC_RPC_MESSAGES: ReadonlySet<string> = new Set([
|
|
87
|
-
"Parse error",
|
|
88
|
-
"Invalid request",
|
|
89
|
-
"Invalid params",
|
|
90
|
-
"Internal error",
|
|
91
|
-
"Request cancelled",
|
|
92
|
-
"Authentication required",
|
|
93
|
-
"Resource not found",
|
|
94
|
-
]);
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* The sentence behind a JSON-RPC rejection. An adapter that throws a plain
|
|
98
|
-
* Error reaches the client as a bare "Internal error" whose real text the
|
|
99
|
-
* agent-side SDK moved into `data.details`. An adapter that raises
|
|
100
|
-
* `RequestError.internalError(data, text)` keeps its words in the message and
|
|
101
|
-
* only supplemental context in `data`, so a specific message wins. Behind a
|
|
102
|
-
* generic message such as "Invalid params", `data.details` or the serialized
|
|
103
|
-
* payload supplies the reason instead. Duck-typed like
|
|
104
|
-
* {@link isAcpAuthRequired}:
|
|
105
|
-
* `message` is read as a property, so a rejection that arrives as a plain
|
|
106
|
-
* object off the wire decodes the same as an `Error` instance.
|
|
107
|
-
*/
|
|
108
|
-
export function requestErrorReason(err: unknown): string {
|
|
109
|
-
if (typeof err !== "object" || err === null) {
|
|
110
|
-
return String(err);
|
|
111
|
-
}
|
|
112
|
-
const { data, message } = err as { data?: unknown; message?: unknown };
|
|
113
|
-
const own = typeof message === "string" ? message : String(err);
|
|
114
|
-
if (data == null) {
|
|
115
|
-
return own;
|
|
116
|
-
}
|
|
117
|
-
if (
|
|
118
|
-
typeof message === "string" &&
|
|
119
|
-
message.length > 0 &&
|
|
120
|
-
!GENERIC_RPC_MESSAGES.has(message)
|
|
121
|
-
) {
|
|
122
|
-
return message;
|
|
123
|
-
}
|
|
124
|
-
const details = (data as { details?: unknown }).details;
|
|
125
|
-
if (typeof details === "string" && details.length > 0) {
|
|
126
|
-
return details;
|
|
127
|
-
}
|
|
128
|
-
// JSON.stringify answers undefined for a value it cannot represent.
|
|
129
|
-
const serialized: string | undefined = JSON.stringify(data);
|
|
130
|
-
return serialized ?? own;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
84
|
/** The adapter whose auth failures the Connect Claude flow can repair. */
|
|
134
85
|
export const CLAUDE_ACP_COMMAND = "claude-agent-acp";
|
|
135
86
|
|
|
@@ -78,7 +78,7 @@ describe("ensureAdapterInstalled", () => {
|
|
|
78
78
|
expect(args).toEqual([
|
|
79
79
|
"add",
|
|
80
80
|
"--global",
|
|
81
|
-
"@agentclientprotocol/claude-agent-acp
|
|
81
|
+
"@agentclientprotocol/claude-agent-acp",
|
|
82
82
|
]);
|
|
83
83
|
});
|
|
84
84
|
|
|
@@ -198,8 +198,8 @@ describe("ensureAdapterInstalled", () => {
|
|
|
198
198
|
(call) => (call[1] as string[])[2],
|
|
199
199
|
);
|
|
200
200
|
expect(installedPackages.sort()).toEqual([
|
|
201
|
-
"@agentclientprotocol/claude-agent-acp
|
|
202
|
-
"@agentclientprotocol/codex-acp
|
|
201
|
+
"@agentclientprotocol/claude-agent-acp",
|
|
202
|
+
"@agentclientprotocol/codex-acp",
|
|
203
203
|
]);
|
|
204
204
|
});
|
|
205
205
|
});
|
|
@@ -232,7 +232,7 @@ describe("resolveAgentWithAutoInstall - resolution order", () => {
|
|
|
232
232
|
// The resolved command is the REAL binary, not a `bun x` wrapper.
|
|
233
233
|
expect(result.resolved.agent.command).toBe("claude-agent-acp");
|
|
234
234
|
expect(result.autoInstalledPackage).toBe(
|
|
235
|
-
"@agentclientprotocol/claude-agent-acp
|
|
235
|
+
"@agentclientprotocol/claude-agent-acp",
|
|
236
236
|
);
|
|
237
237
|
expect(result.failureMessage).toBeUndefined();
|
|
238
238
|
expect(execFileMock).toHaveBeenCalledTimes(1);
|
|
@@ -264,14 +264,12 @@ describe("resolveAgentWithAutoInstall - resolution order", () => {
|
|
|
264
264
|
return;
|
|
265
265
|
}
|
|
266
266
|
expect(result.resolved.agent.command).toBe("codex-acp");
|
|
267
|
-
expect(result.autoInstalledPackage).toBe(
|
|
268
|
-
"@agentclientprotocol/codex-acp@1.10.0",
|
|
269
|
-
);
|
|
267
|
+
expect(result.autoInstalledPackage).toBe("@agentclientprotocol/codex-acp");
|
|
270
268
|
expect(execFileMock).toHaveBeenCalledTimes(1);
|
|
271
269
|
expect(execFileMock.mock.calls[0][1]).toEqual([
|
|
272
270
|
"add",
|
|
273
271
|
"--global",
|
|
274
|
-
"@agentclientprotocol/codex-acp
|
|
272
|
+
"@agentclientprotocol/codex-acp",
|
|
275
273
|
]);
|
|
276
274
|
});
|
|
277
275
|
|
|
@@ -297,7 +295,7 @@ describe("resolveAgentWithAutoInstall - resolution order", () => {
|
|
|
297
295
|
expect(result.resolved.ok).toBe(false);
|
|
298
296
|
expect(result.failureMessage).toContain("claude-agent-acp is not on PATH");
|
|
299
297
|
expect(result.failureMessage).toContain(
|
|
300
|
-
"bun add -g @agentclientprotocol/claude-agent-acp
|
|
298
|
+
"bun add -g @agentclientprotocol/claude-agent-acp",
|
|
301
299
|
);
|
|
302
300
|
expect(result.failureMessage).toContain("network is down");
|
|
303
301
|
for (const call of execFileMock.mock.calls) {
|
|
@@ -21,7 +21,6 @@ import type {
|
|
|
21
21
|
ReleaseTerminalResponse,
|
|
22
22
|
RequestPermissionRequest,
|
|
23
23
|
RequestPermissionResponse,
|
|
24
|
-
SessionConfigOption,
|
|
25
24
|
SessionNotification,
|
|
26
25
|
TerminalOutputRequest,
|
|
27
26
|
TerminalOutputResponse,
|
|
@@ -104,9 +103,6 @@ export class VellumAcpClientHandler implements Client {
|
|
|
104
103
|
private readonly acpSessionId: string,
|
|
105
104
|
private readonly sendToVellum: (msg: AssistantEvent) => void,
|
|
106
105
|
private readonly parentConversationId: string,
|
|
107
|
-
private readonly onConfigOptions?: (
|
|
108
|
-
configOptions: SessionConfigOption[],
|
|
109
|
-
) => void,
|
|
110
106
|
) {}
|
|
111
107
|
|
|
112
108
|
/** Forwards an update to Vellum, stamping a contiguous per-session `seq`. */
|
|
@@ -186,12 +182,7 @@ export class VellumAcpClientHandler implements Client {
|
|
|
186
182
|
async sessionUpdate(params: SessionNotification): Promise<void> {
|
|
187
183
|
const update = params.update;
|
|
188
184
|
|
|
189
|
-
|
|
190
|
-
// are applied even while a replay is being suppressed.
|
|
191
|
-
if (
|
|
192
|
-
this.suppressForwarding &&
|
|
193
|
-
update.sessionUpdate !== "config_option_update"
|
|
194
|
-
) {
|
|
185
|
+
if (this.suppressForwarding) {
|
|
195
186
|
log.debug(
|
|
196
187
|
{ acpSessionId: this.acpSessionId, updateType: update.sessionUpdate },
|
|
197
188
|
"Dropping replayed session update during suppression",
|
|
@@ -295,14 +286,10 @@ export class VellumAcpClientHandler implements Client {
|
|
|
295
286
|
break;
|
|
296
287
|
}
|
|
297
288
|
|
|
298
|
-
case "config_option_update": {
|
|
299
|
-
this.onConfigOptions?.(update.configOptions);
|
|
300
|
-
break;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
289
|
default: {
|
|
304
290
|
// Other update types (available_commands_update, current_mode_update,
|
|
305
|
-
// session_info_update) are not forwarded to
|
|
291
|
+
// config_option_update, session_info_update) are not forwarded to
|
|
292
|
+
// Vellum.
|
|
306
293
|
log.debug(
|
|
307
294
|
{
|
|
308
295
|
acpSessionId: this.acpSessionId,
|
|
@@ -56,9 +56,7 @@ describe("resolveAcpAgent", () => {
|
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
58
|
expect(result.agent.command).toBe("codex-acp");
|
|
59
|
-
expect(result.agent.description).toContain(
|
|
60
|
-
"@agentclientprotocol/codex-acp",
|
|
61
|
-
);
|
|
59
|
+
expect(result.agent.description).toContain("@agentclientprotocol/codex-acp");
|
|
62
60
|
});
|
|
63
61
|
|
|
64
62
|
test("falls back to default profile for claude when no user entry", () => {
|
|
@@ -193,7 +191,7 @@ describe("resolveAcpAgent", () => {
|
|
|
193
191
|
return;
|
|
194
192
|
}
|
|
195
193
|
expect(result.hint).toBe(
|
|
196
|
-
"bun add -g @agentclientprotocol/claude-agent-acp
|
|
194
|
+
"bun add -g @agentclientprotocol/claude-agent-acp",
|
|
197
195
|
);
|
|
198
196
|
expect(result.command).toBe("claude-agent-acp");
|
|
199
197
|
});
|
|
@@ -242,9 +240,7 @@ describe("resolveAcpAgent", () => {
|
|
|
242
240
|
if (result.reason !== "binary_not_found") {
|
|
243
241
|
return;
|
|
244
242
|
}
|
|
245
|
-
expect(result.hint).toBe(
|
|
246
|
-
"bun add -g @agentclientprotocol/codex-acp@1.10.0",
|
|
247
|
-
);
|
|
243
|
+
expect(result.hint).toBe("bun add -g @agentclientprotocol/codex-acp");
|
|
248
244
|
});
|
|
249
245
|
|
|
250
246
|
test("binary preflight honors agent.env.PATH override (matches spawn env)", () => {
|
|
@@ -289,178 +285,6 @@ describe("resolveAcpAgent", () => {
|
|
|
289
285
|
expect(result.agent.args).toEqual(["--verbose"]);
|
|
290
286
|
});
|
|
291
287
|
|
|
292
|
-
test("the bundled claude profile carries its model", () => {
|
|
293
|
-
config.setConfig({ agents: {} });
|
|
294
|
-
|
|
295
|
-
const result = resolveAcpAgent("claude");
|
|
296
|
-
|
|
297
|
-
expect(result.ok).toBe(true);
|
|
298
|
-
if (!result.ok) {
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
expect(result.agent.model).toBe("opus");
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
test("a user entry that names a model overrides the bundled one", () => {
|
|
305
|
-
config.setConfig({
|
|
306
|
-
agents: {
|
|
307
|
-
claude: { command: "claude-agent-acp", args: [], model: "sonnet" },
|
|
308
|
-
},
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
const result = resolveAcpAgent("claude");
|
|
312
|
-
|
|
313
|
-
expect(result.ok).toBe(true);
|
|
314
|
-
if (!result.ok) {
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
expect(result.agent.model).toBe("sonnet");
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
test("a user entry keeping the profile command and omitting model inherits it", () => {
|
|
321
|
-
config.setConfig({
|
|
322
|
-
agents: {
|
|
323
|
-
claude: { command: "claude-agent-acp", args: ["--my-flag"] },
|
|
324
|
-
},
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
const result = resolveAcpAgent("claude");
|
|
328
|
-
|
|
329
|
-
expect(result.ok).toBe(true);
|
|
330
|
-
if (!result.ok) {
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
expect(result.agent.args).toEqual(["--my-flag"]);
|
|
334
|
-
expect(result.agent.model).toBe("opus");
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
test("a user entry that omits command entirely still inherits the model", () => {
|
|
338
|
-
// The schema admits a command-less entry for a bundled id; the profile's
|
|
339
|
-
// command is inherited with the rest.
|
|
340
|
-
config.setConfig({
|
|
341
|
-
agents: {
|
|
342
|
-
claude: JSON.parse('{"args": ["--my-flag"]}'),
|
|
343
|
-
},
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
const result = resolveAcpAgent("claude");
|
|
347
|
-
|
|
348
|
-
expect(result.ok).toBe(true);
|
|
349
|
-
if (!result.ok) {
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
expect(result.agent.command).toBe("claude-agent-acp");
|
|
353
|
-
expect(result.agent.model).toBe("opus");
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
test("a user entry running the profile adapter by full path still inherits the model", () => {
|
|
357
|
-
config.setConfig({
|
|
358
|
-
agents: {
|
|
359
|
-
claude: { command: "/opt/bin/claude-agent-acp", args: [] },
|
|
360
|
-
},
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
const result = resolveAcpAgent("claude");
|
|
364
|
-
|
|
365
|
-
expect(result.ok).toBe(true);
|
|
366
|
-
if (!result.ok) {
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
expect(result.agent.command).toBe("/opt/bin/claude-agent-acp");
|
|
370
|
-
expect(result.agent.model).toBe("opus");
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
test("a user entry pointing the id at another adapter inherits no model", () => {
|
|
374
|
-
// The bundled aliases are Claude's own vocabulary, so an unrelated
|
|
375
|
-
// adapter under the `claude` id must not be handed `opus`.
|
|
376
|
-
config.setConfig({
|
|
377
|
-
agents: {
|
|
378
|
-
claude: { command: "my-custom-claude", args: ["--my-flag"] },
|
|
379
|
-
},
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
const result = resolveAcpAgent("claude");
|
|
383
|
-
|
|
384
|
-
expect(result.ok).toBe(true);
|
|
385
|
-
if (!result.ok) {
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
expect(result.agent.command).toBe("my-custom-claude");
|
|
389
|
-
expect(result.agent.model).toBeUndefined();
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
test("a user entry naming its own model keeps it across a replaced command", () => {
|
|
393
|
-
config.setConfig({
|
|
394
|
-
agents: {
|
|
395
|
-
claude: {
|
|
396
|
-
command: "my-custom-claude",
|
|
397
|
-
args: [],
|
|
398
|
-
model: "my-fork-large",
|
|
399
|
-
},
|
|
400
|
-
},
|
|
401
|
-
});
|
|
402
|
-
|
|
403
|
-
const result = resolveAcpAgent("claude");
|
|
404
|
-
|
|
405
|
-
expect(result.ok).toBe(true);
|
|
406
|
-
if (!result.ok) {
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
expect(result.agent.command).toBe("my-custom-claude");
|
|
410
|
-
expect(result.agent.model).toBe("my-fork-large");
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
test("a user entry pointing the id at another adapter inherits no description", () => {
|
|
414
|
-
config.setConfig({
|
|
415
|
-
agents: {
|
|
416
|
-
claude: { command: "my-custom-claude", args: [] },
|
|
417
|
-
},
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
const result = resolveAcpAgent("claude");
|
|
421
|
-
|
|
422
|
-
expect(result.ok).toBe(true);
|
|
423
|
-
if (!result.ok) {
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
expect(result.agent.description).toBeUndefined();
|
|
427
|
-
const listed = listAcpAgents().agents.find(
|
|
428
|
-
(entry) => entry.id === "claude",
|
|
429
|
-
);
|
|
430
|
-
expect(listed?.command).toBe("my-custom-claude");
|
|
431
|
-
expect(listed?.description).toBeUndefined();
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
test("a user entry running the profile adapter by full path inherits its description", () => {
|
|
435
|
-
config.setConfig({
|
|
436
|
-
agents: {
|
|
437
|
-
claude: { command: "/opt/bin/claude-agent-acp", args: [] },
|
|
438
|
-
},
|
|
439
|
-
});
|
|
440
|
-
|
|
441
|
-
const result = resolveAcpAgent("claude");
|
|
442
|
-
|
|
443
|
-
expect(result.ok).toBe(true);
|
|
444
|
-
if (!result.ok) {
|
|
445
|
-
return;
|
|
446
|
-
}
|
|
447
|
-
expect(result.agent.description).toContain(
|
|
448
|
-
"@agentclientprotocol/claude-agent-acp",
|
|
449
|
-
);
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
test("a bundled profile with no model leaves the resolved agent without one", () => {
|
|
453
|
-
config.setConfig({ agents: {} });
|
|
454
|
-
|
|
455
|
-
const result = resolveAcpAgent("codex");
|
|
456
|
-
|
|
457
|
-
expect(result.ok).toBe(true);
|
|
458
|
-
if (!result.ok) {
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
expect(result.agent.model).toBeUndefined();
|
|
462
|
-
});
|
|
463
|
-
|
|
464
288
|
test("resolves a full-path command directly without rewriting it", () => {
|
|
465
289
|
config.setConfig({
|
|
466
290
|
agents: {
|
|
@@ -508,7 +332,7 @@ describe("resolveAcpAgent - missing binary", () => {
|
|
|
508
332
|
}
|
|
509
333
|
expect(result.command).toBe("claude-agent-acp");
|
|
510
334
|
expect(result.hint).toBe(
|
|
511
|
-
"bun add -g @agentclientprotocol/claude-agent-acp
|
|
335
|
+
"bun add -g @agentclientprotocol/claude-agent-acp",
|
|
512
336
|
);
|
|
513
337
|
});
|
|
514
338
|
|
|
@@ -527,7 +351,7 @@ describe("resolveAcpAgent - missing binary", () => {
|
|
|
527
351
|
return;
|
|
528
352
|
}
|
|
529
353
|
expect(result.hint).toBe(
|
|
530
|
-
"bun add -g @agentclientprotocol/claude-agent-acp
|
|
354
|
+
"bun add -g @agentclientprotocol/claude-agent-acp",
|
|
531
355
|
);
|
|
532
356
|
});
|
|
533
357
|
});
|
|
@@ -606,9 +430,7 @@ describe("listAcpAgents", () => {
|
|
|
606
430
|
const codex = result.agents.find((a) => a.id === "codex");
|
|
607
431
|
expect(codex?.available).toBe(false);
|
|
608
432
|
expect(codex?.unavailableReason).toBe("'codex-acp' is not on PATH");
|
|
609
|
-
expect(codex?.setupHint).toBe(
|
|
610
|
-
"bun add -g @agentclientprotocol/codex-acp@1.10.0",
|
|
611
|
-
);
|
|
433
|
+
expect(codex?.setupHint).toBe("bun add -g @agentclientprotocol/codex-acp");
|
|
612
434
|
});
|
|
613
435
|
|
|
614
436
|
test("aliases are resolution sugar, not catalog entries", () => {
|
|
@@ -667,39 +489,3 @@ describe("listAcpAgents", () => {
|
|
|
667
489
|
);
|
|
668
490
|
});
|
|
669
491
|
});
|
|
670
|
-
|
|
671
|
-
describe("agent ids that name Object.prototype members", () => {
|
|
672
|
-
// An id read off the prototype chain would resolve as a configured agent
|
|
673
|
-
// that does not exist, and a spawn would start a process for a config
|
|
674
|
-
// nobody wrote.
|
|
675
|
-
for (const id of ["__proto__", "constructor", "prototype"]) {
|
|
676
|
-
test(`"${id}" resolves to nothing`, () => {
|
|
677
|
-
config.setConfig({ agents: {} });
|
|
678
|
-
|
|
679
|
-
const resolved = resolveAcpAgent(id);
|
|
680
|
-
expect(resolved.ok).toBe(false);
|
|
681
|
-
if (resolved.ok) {
|
|
682
|
-
return;
|
|
683
|
-
}
|
|
684
|
-
expect(resolved.reason).toBe("unknown_agent");
|
|
685
|
-
if (resolved.reason !== "unknown_agent") {
|
|
686
|
-
return;
|
|
687
|
-
}
|
|
688
|
-
expect(resolved.available).toEqual(["claude", "codex"]);
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
test("the catalog never lists one, even when config carries the key", () => {
|
|
693
|
-
config.setConfig({
|
|
694
|
-
agents: {
|
|
695
|
-
...JSON.parse('{"__proto__": {"command": "evil", "args": []}}'),
|
|
696
|
-
claude: { command: "claude-agent-acp", args: [] },
|
|
697
|
-
},
|
|
698
|
-
});
|
|
699
|
-
|
|
700
|
-
expect(listAcpAgents().agents.map((a) => a.id)).toEqual([
|
|
701
|
-
"claude",
|
|
702
|
-
"codex",
|
|
703
|
-
]);
|
|
704
|
-
});
|
|
705
|
-
});
|