@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
|
@@ -27,8 +27,6 @@ const {
|
|
|
27
27
|
setPlatformOrganizationId,
|
|
28
28
|
setPlatformUserId,
|
|
29
29
|
} = await import("../env.js");
|
|
30
|
-
const { _resetPlatformIdentityEnsureForTests } =
|
|
31
|
-
await import("../platform-identity.js");
|
|
32
30
|
const { rehydratePlatformCredentials } =
|
|
33
31
|
await import("../platform-rehydration.js");
|
|
34
32
|
|
|
@@ -41,44 +39,23 @@ describe("rehydratePlatformCredentials", () => {
|
|
|
41
39
|
const originalPlatformUrlEnv = process.env.VELLUM_PLATFORM_URL;
|
|
42
40
|
const originalOrgEnv = process.env.PLATFORM_ORGANIZATION_ID;
|
|
43
41
|
const originalUserEnv = process.env.PLATFORM_USER_ID;
|
|
44
|
-
const originalAssistantApiKeyEnv = process.env.ASSISTANT_API_KEY;
|
|
45
|
-
const originalFetch = globalThis.fetch;
|
|
46
|
-
const fetchCalls: Array<{ url: string; init?: RequestInit }> = [];
|
|
47
|
-
let fetchImpl: (
|
|
48
|
-
input: RequestInfo | URL,
|
|
49
|
-
init?: RequestInit,
|
|
50
|
-
) => Promise<Response> = async () =>
|
|
51
|
-
new Response("not found", { status: 404 });
|
|
52
42
|
|
|
53
43
|
beforeEach(() => {
|
|
54
44
|
mockSecureKeys = {};
|
|
55
45
|
throwForKey = undefined;
|
|
56
|
-
fetchCalls.length = 0;
|
|
57
|
-
fetchImpl = async () => new Response("not found", { status: 404 });
|
|
58
|
-
globalThis.fetch = (async (
|
|
59
|
-
input: RequestInfo | URL,
|
|
60
|
-
init?: RequestInit,
|
|
61
|
-
) => {
|
|
62
|
-
const url = typeof input === "string" ? input : input.toString();
|
|
63
|
-
fetchCalls.push({ url, init });
|
|
64
|
-
return fetchImpl(input, init);
|
|
65
|
-
}) as unknown as typeof fetch;
|
|
66
46
|
// Env vars take precedence over the rehydrated overrides for some fields;
|
|
67
47
|
// clear them so the credential-store values are what we observe.
|
|
68
48
|
delete process.env.VELLUM_PLATFORM_URL;
|
|
69
49
|
delete process.env.PLATFORM_ORGANIZATION_ID;
|
|
70
50
|
delete process.env.PLATFORM_USER_ID;
|
|
71
|
-
delete process.env.ASSISTANT_API_KEY;
|
|
72
51
|
// Reset in-memory overrides between tests.
|
|
73
52
|
setPlatformBaseUrl(undefined);
|
|
74
53
|
setPlatformAssistantId(undefined);
|
|
75
54
|
setPlatformOrganizationId(undefined);
|
|
76
55
|
setPlatformUserId(undefined);
|
|
77
|
-
_resetPlatformIdentityEnsureForTests();
|
|
78
56
|
});
|
|
79
57
|
|
|
80
58
|
afterEach(() => {
|
|
81
|
-
globalThis.fetch = originalFetch;
|
|
82
59
|
if (originalPlatformUrlEnv === undefined) {
|
|
83
60
|
delete process.env.VELLUM_PLATFORM_URL;
|
|
84
61
|
} else {
|
|
@@ -94,18 +71,13 @@ describe("rehydratePlatformCredentials", () => {
|
|
|
94
71
|
} else {
|
|
95
72
|
process.env.PLATFORM_USER_ID = originalUserEnv;
|
|
96
73
|
}
|
|
97
|
-
if (originalAssistantApiKeyEnv === undefined) {
|
|
98
|
-
delete process.env.ASSISTANT_API_KEY;
|
|
99
|
-
} else {
|
|
100
|
-
process.env.ASSISTANT_API_KEY = originalAssistantApiKeyEnv;
|
|
101
|
-
}
|
|
102
74
|
setPlatformBaseUrl(undefined);
|
|
103
75
|
setPlatformAssistantId(undefined);
|
|
104
76
|
setPlatformOrganizationId(undefined);
|
|
105
77
|
setPlatformUserId(undefined);
|
|
106
78
|
});
|
|
107
79
|
|
|
108
|
-
test("rehydrates
|
|
80
|
+
test("rehydrates base URL and all platform IDs from the credential store", async () => {
|
|
109
81
|
mockSecureKeys[credentialKey("vellum", "platform_base_url")] = PROD_URL;
|
|
110
82
|
mockSecureKeys[credentialKey("vellum", "platform_assistant_id")] =
|
|
111
83
|
ASSISTANT_ID;
|
|
@@ -116,18 +88,21 @@ describe("rehydratePlatformCredentials", () => {
|
|
|
116
88
|
await rehydratePlatformCredentials();
|
|
117
89
|
|
|
118
90
|
expect(getPlatformBaseUrl()).toBe(PROD_URL);
|
|
119
|
-
expect(getPlatformAssistantId()).toBe(
|
|
120
|
-
expect(getPlatformOrganizationId()).toBe(
|
|
121
|
-
expect(getPlatformUserId()).toBe(
|
|
91
|
+
expect(getPlatformAssistantId()).toBe(ASSISTANT_ID);
|
|
92
|
+
expect(getPlatformOrganizationId()).toBe(ORG_ID);
|
|
93
|
+
expect(getPlatformUserId()).toBe(USER_ID);
|
|
122
94
|
});
|
|
123
95
|
|
|
124
96
|
test("trims stored values before applying them", async () => {
|
|
125
97
|
mockSecureKeys[credentialKey("vellum", "platform_base_url")] =
|
|
126
98
|
` ${PROD_URL} `;
|
|
99
|
+
mockSecureKeys[credentialKey("vellum", "platform_assistant_id")] =
|
|
100
|
+
`\n${ASSISTANT_ID}\n`;
|
|
127
101
|
|
|
128
102
|
await rehydratePlatformCredentials();
|
|
129
103
|
|
|
130
104
|
expect(getPlatformBaseUrl()).toBe(PROD_URL);
|
|
105
|
+
expect(getPlatformAssistantId()).toBe(ASSISTANT_ID);
|
|
131
106
|
});
|
|
132
107
|
|
|
133
108
|
test("leaves overrides untouched when nothing is stored", async () => {
|
|
@@ -138,78 +113,13 @@ describe("rehydratePlatformCredentials", () => {
|
|
|
138
113
|
expect(getPlatformUserId()).toBe("");
|
|
139
114
|
});
|
|
140
115
|
|
|
141
|
-
test("a
|
|
116
|
+
test("a per-field read failure does not block the remaining fields", async () => {
|
|
142
117
|
throwForKey = credentialKey("vellum", "platform_base_url");
|
|
143
|
-
|
|
144
|
-
await expect(rehydratePlatformCredentials()).resolves.toBeUndefined();
|
|
145
|
-
expect(getPlatformAssistantId()).toBe("");
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("trades the assistant API key for ids via platform validate", async () => {
|
|
149
|
-
mockSecureKeys[credentialKey("vellum", "platform_base_url")] = PROD_URL;
|
|
150
|
-
mockSecureKeys[credentialKey("vellum", "assistant_api_key")] =
|
|
151
|
-
"assistant-key";
|
|
152
|
-
fetchImpl = async () =>
|
|
153
|
-
new Response(
|
|
154
|
-
JSON.stringify({
|
|
155
|
-
assistant_id: ASSISTANT_ID,
|
|
156
|
-
organization_id: ORG_ID,
|
|
157
|
-
user_id: USER_ID,
|
|
158
|
-
}),
|
|
159
|
-
{ status: 200 },
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
await rehydratePlatformCredentials();
|
|
163
|
-
|
|
164
|
-
expect(fetchCalls).toHaveLength(1);
|
|
165
|
-
expect(fetchCalls[0]?.url).toBe(
|
|
166
|
-
`${PROD_URL}/v1/internal/assistants/validate/`,
|
|
167
|
-
);
|
|
168
|
-
const headers = new Headers(fetchCalls[0]?.init?.headers);
|
|
169
|
-
expect(headers.get("Authorization")).toBe("Api-Key assistant-key");
|
|
170
|
-
expect(getPlatformAssistantId()).toBe(ASSISTANT_ID);
|
|
171
|
-
expect(getPlatformOrganizationId()).toBe(ORG_ID);
|
|
172
|
-
expect(getPlatformUserId()).toBe(USER_ID);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
test("validate ids are used when the vault also has a copy", async () => {
|
|
176
|
-
mockSecureKeys[credentialKey("vellum", "platform_base_url")] = PROD_URL;
|
|
177
|
-
mockSecureKeys[credentialKey("vellum", "assistant_api_key")] =
|
|
178
|
-
"assistant-key";
|
|
179
|
-
mockSecureKeys[credentialKey("vellum", "platform_assistant_id")] =
|
|
180
|
-
"asst-from-vault";
|
|
181
|
-
fetchImpl = async () =>
|
|
182
|
-
new Response(
|
|
183
|
-
JSON.stringify({
|
|
184
|
-
assistant_id: ASSISTANT_ID,
|
|
185
|
-
organization_id: ORG_ID,
|
|
186
|
-
user_id: USER_ID,
|
|
187
|
-
}),
|
|
188
|
-
{ status: 200 },
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
await rehydratePlatformCredentials();
|
|
192
|
-
|
|
193
|
-
expect(getPlatformAssistantId()).toBe(ASSISTANT_ID);
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
test("does not populate ids from the vault when validate is unreachable", async () => {
|
|
197
|
-
mockSecureKeys[credentialKey("vellum", "platform_base_url")] = PROD_URL;
|
|
198
|
-
mockSecureKeys[credentialKey("vellum", "assistant_api_key")] =
|
|
199
|
-
"assistant-key";
|
|
200
118
|
mockSecureKeys[credentialKey("vellum", "platform_assistant_id")] =
|
|
201
119
|
ASSISTANT_ID;
|
|
202
|
-
mockSecureKeys[credentialKey("vellum", "platform_organization_id")] =
|
|
203
|
-
ORG_ID;
|
|
204
|
-
mockSecureKeys[credentialKey("vellum", "platform_user_id")] = USER_ID;
|
|
205
|
-
fetchImpl = async () => {
|
|
206
|
-
throw new Error("network down");
|
|
207
|
-
};
|
|
208
120
|
|
|
209
121
|
await rehydratePlatformCredentials();
|
|
210
122
|
|
|
211
|
-
expect(getPlatformAssistantId()).toBe(
|
|
212
|
-
expect(getPlatformOrganizationId()).toBe("");
|
|
213
|
-
expect(getPlatformUserId()).toBe("");
|
|
123
|
+
expect(getPlatformAssistantId()).toBe(ASSISTANT_ID);
|
|
214
124
|
});
|
|
215
125
|
});
|
|
@@ -13,17 +13,15 @@ describe("DEFAULT_ACP_AGENT_PROFILES", () => {
|
|
|
13
13
|
]);
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
test("claude profile uses the @agentclientprotocol adapter binary
|
|
16
|
+
test("claude profile uses the @agentclientprotocol adapter binary", () => {
|
|
17
17
|
expect(DEFAULT_ACP_AGENT_PROFILES.claude).toEqual({
|
|
18
18
|
command: "claude-agent-acp",
|
|
19
19
|
args: [],
|
|
20
20
|
description: "Claude Code (via @agentclientprotocol/claude-agent-acp)",
|
|
21
|
-
model: "opus",
|
|
22
21
|
});
|
|
23
22
|
});
|
|
24
23
|
|
|
25
24
|
test("codex profile uses the @agentclientprotocol adapter binary", () => {
|
|
26
|
-
// No model: Codex aliases are its own, so the adapter's default stands.
|
|
27
25
|
expect(DEFAULT_ACP_AGENT_PROFILES.codex).toEqual({
|
|
28
26
|
command: "codex-acp",
|
|
29
27
|
args: [],
|
|
@@ -46,19 +44,11 @@ describe("DEFAULT_ACP_AGENT_PROFILES", () => {
|
|
|
46
44
|
describe("DEFAULT_AGENT_NPM_PACKAGES", () => {
|
|
47
45
|
test("is keyed by command name with the canonical npm package", () => {
|
|
48
46
|
expect(DEFAULT_AGENT_NPM_PACKAGES).toEqual({
|
|
49
|
-
"claude-agent-acp": "@agentclientprotocol/claude-agent-acp
|
|
50
|
-
"codex-acp": "@agentclientprotocol/codex-acp
|
|
47
|
+
"claude-agent-acp": "@agentclientprotocol/claude-agent-acp",
|
|
48
|
+
"codex-acp": "@agentclientprotocol/codex-acp",
|
|
51
49
|
});
|
|
52
50
|
});
|
|
53
51
|
|
|
54
|
-
test("every package spec pins an exact version", () => {
|
|
55
|
-
// A bare name would let a clean install resolve whatever npm calls
|
|
56
|
-
// latest, which is what the repo's pinning rule exists to prevent.
|
|
57
|
-
for (const spec of Object.values(DEFAULT_AGENT_NPM_PACKAGES)) {
|
|
58
|
-
expect(spec).toMatch(/^@?[^@]+@\d+\.\d+\.\d+$/);
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
52
|
test("every default profile's command has a matching npm package", () => {
|
|
63
53
|
for (const profile of Object.values(DEFAULT_ACP_AGENT_PROFILES)) {
|
|
64
54
|
expect(DEFAULT_AGENT_NPM_PACKAGES[profile.command]).toBeDefined();
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { AcpAgentConfig } from "./acp-schema.js";
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* A bundled profile always names its command; a user entry for the same id
|
|
5
|
-
* may omit `command` and inherit this one.
|
|
6
|
-
*/
|
|
7
|
-
export type AcpAgentProfile = AcpAgentConfig & { command: string };
|
|
8
|
-
|
|
9
3
|
// Shared frozen empty args array — these defaults are read by every ACP spawn,
|
|
10
4
|
// so a single accidental `args.push(...)` from one caller would corrupt every
|
|
11
5
|
// subsequent read. Cast through `unknown` because `AcpAgentConfig.args` is
|
|
@@ -19,22 +13,17 @@ const FROZEN_EMPTY_ARGS = Object.freeze([] as string[]) as unknown as string[];
|
|
|
19
13
|
* falls back to this map so common agents like `claude` and `codex` Just Work
|
|
20
14
|
* without requiring per-user config.
|
|
21
15
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* entry that names a model overrides it, one that omits it inherits it.
|
|
25
|
-
*
|
|
26
|
-
* Keyed by agent id. Deeply frozen: the outer object, each profile, and the
|
|
27
|
-
* `args` arrays, so mutation throws in strict mode rather than silently
|
|
16
|
+
* Keyed by agent id. Deeply frozen — the outer object, each profile, and the
|
|
17
|
+
* `args` arrays — so mutation throws in strict mode rather than silently
|
|
28
18
|
* corrupting the shared defaults.
|
|
29
19
|
*/
|
|
30
20
|
export const DEFAULT_ACP_AGENT_PROFILES: Readonly<
|
|
31
|
-
Record<string,
|
|
21
|
+
Record<string, AcpAgentConfig>
|
|
32
22
|
> = Object.freeze({
|
|
33
23
|
claude: Object.freeze({
|
|
34
24
|
command: "claude-agent-acp",
|
|
35
25
|
args: FROZEN_EMPTY_ARGS,
|
|
36
26
|
description: "Claude Code (via @agentclientprotocol/claude-agent-acp)",
|
|
37
|
-
model: "opus",
|
|
38
27
|
}),
|
|
39
28
|
codex: Object.freeze({
|
|
40
29
|
command: "codex-acp",
|
|
@@ -44,21 +33,15 @@ export const DEFAULT_ACP_AGENT_PROFILES: Readonly<
|
|
|
44
33
|
});
|
|
45
34
|
|
|
46
35
|
/**
|
|
47
|
-
* Single source of truth for adapter binary → npm package
|
|
36
|
+
* Single source of truth for adapter binary → npm package name. Automatic
|
|
48
37
|
* installation and the resolver's install hints use this map, so a new
|
|
49
38
|
* adapter only needs one entry here.
|
|
50
39
|
*
|
|
51
40
|
* Keyed by command name (not agent id) so the mapping follows the binary
|
|
52
41
|
* regardless of how a user's config aliases an agent.
|
|
53
|
-
*
|
|
54
|
-
* Values carry an exact version, so a clean install lands the adapter version
|
|
55
|
-
* the daemon was tested against instead of whatever npm calls latest today.
|
|
56
|
-
* An adapter already on PATH is left alone: installation runs only when
|
|
57
|
-
* preflight found no binary at all, so this never moves a version the user
|
|
58
|
-
* installed themselves.
|
|
59
42
|
*/
|
|
60
43
|
export const DEFAULT_AGENT_NPM_PACKAGES: Readonly<Record<string, string>> =
|
|
61
44
|
Object.freeze({
|
|
62
|
-
"claude-agent-acp": "@agentclientprotocol/claude-agent-acp
|
|
63
|
-
"codex-acp": "@agentclientprotocol/codex-acp
|
|
45
|
+
"claude-agent-acp": "@agentclientprotocol/claude-agent-acp",
|
|
46
|
+
"codex-acp": "@agentclientprotocol/codex-acp",
|
|
64
47
|
});
|
package/src/config/acp-schema.ts
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export const AcpAgentConfigSchema = z
|
|
3
|
+
const AcpAgentConfigSchema = z
|
|
6
4
|
.object({
|
|
7
|
-
command: z
|
|
8
|
-
.string()
|
|
9
|
-
.optional()
|
|
10
|
-
.describe(
|
|
11
|
-
"Command to spawn the ACP agent process. Required unless the id has a bundled profile, whose command is inherited when this is unset",
|
|
12
|
-
),
|
|
5
|
+
command: z.string().describe("Command to spawn the ACP agent process"),
|
|
13
6
|
args: z
|
|
14
7
|
.array(z.string())
|
|
15
8
|
.default([])
|
|
@@ -22,12 +15,6 @@ export const AcpAgentConfigSchema = z
|
|
|
22
15
|
.record(z.string(), z.string())
|
|
23
16
|
.optional()
|
|
24
17
|
.describe("Environment variables set for the agent process"),
|
|
25
|
-
model: z
|
|
26
|
-
.string()
|
|
27
|
-
.optional()
|
|
28
|
-
.describe(
|
|
29
|
-
"Model sessions of this agent start on when the ask names none (an adapter-reported alias such as 'opus' or 'sonnet' for Claude, not an Assistant catalog id). Overrides the bundled profile's value; unset inherits it.",
|
|
30
|
-
),
|
|
31
18
|
})
|
|
32
19
|
.describe("Configuration for an individual ACP agent");
|
|
33
20
|
|
|
@@ -43,21 +30,6 @@ export const AcpConfigSchema = z
|
|
|
43
30
|
),
|
|
44
31
|
agents: z
|
|
45
32
|
.record(z.string(), AcpAgentConfigSchema)
|
|
46
|
-
.superRefine((agents, ctx) => {
|
|
47
|
-
for (const [id, agent] of Object.entries(agents)) {
|
|
48
|
-
if (
|
|
49
|
-
agent.command !== undefined ||
|
|
50
|
-
Object.hasOwn(DEFAULT_ACP_AGENT_PROFILES, id)
|
|
51
|
-
) {
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
ctx.addIssue({
|
|
55
|
-
code: "custom",
|
|
56
|
-
path: [id, "command"],
|
|
57
|
-
message: `acp.agents.${id} needs a command: only the bundled ids (${Object.keys(DEFAULT_ACP_AGENT_PROFILES).join(", ")}) inherit one`,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
33
|
.default({})
|
|
62
34
|
.describe("Map of agent names to their configurations"),
|
|
63
35
|
})
|
|
@@ -23,18 +23,6 @@ Use `acp_spawn` to delegate a coding task to an external agent. The agent runs a
|
|
|
23
23
|
|
|
24
24
|
Users can refer to agents by natural names: "claude code", "codex cli", and "openai codex" all resolve to the canonical `claude` and `codex` ids (unless the user's config defines an agent literally keyed by that name, which always wins).
|
|
25
25
|
|
|
26
|
-
## Choosing a model
|
|
27
|
-
|
|
28
|
-
Claude runs on Opus unless the user names a model; every other agent starts on its own default.
|
|
29
|
-
|
|
30
|
-
When the user does name one, pass it as `model` on `acp_spawn`. Model names are the agent's own vocabulary, not Assistant model ids: an alias such as `default`, `sonnet`, `opus`, `haiku`, `fable`, or `opusplan` for Claude, or a full model id. Pass what the user said and let the agent resolve it.
|
|
31
|
-
|
|
32
|
-
The spawn result reports `requestedModel` and `effectiveModel`. Treat `effectiveModel` as authoritative for the top-level ACP session. Never infer that model from the task text or from a nested subagent. When `requestedModel` is non-null and differs from `effectiveModel`, state which model the session is actually running on and relay `modelWarning` when present.
|
|
33
|
-
|
|
34
|
-
If the agent refuses the model, or advertises no model selector, the spawn result says so: relay it in one sentence and carry on, because the session is live on the agent's own model.
|
|
35
|
-
|
|
36
|
-
A session runs on the model it started on, so a different model means a new `acp_spawn`. A standing default per agent lives in the config at `acp.agents.<id>.model`.
|
|
37
|
-
|
|
38
26
|
## When the user names Claude Code or Codex
|
|
39
27
|
|
|
40
28
|
If they name Claude Code or Codex without asking you to run it here (for example they say that tool will do the work), offer once, in one short sentence, that you can connect and run it in this conversation. Then continue with whatever they were doing.
|
|
@@ -47,23 +35,21 @@ If they name Claude Code or Codex without asking you to run it here (for example
|
|
|
47
35
|
|
|
48
36
|
ACP is always available - default profiles for `claude` and `codex` ship out-of-box, so no config edit is needed to start. First-time setup is just making the adapter binary available, then spawning:
|
|
49
37
|
|
|
50
|
-
1. Install the adapter binary if it's missing. This happens automatically: when `acp_spawn` finds the agent's binary missing from PATH, the assistant installs
|
|
38
|
+
1. Install the adapter binary if it's missing. This happens automatically: when `acp_spawn` finds the agent's binary missing from PATH, the assistant installs it once via a sandboxed bun global install and proceeds in the same call (see "Automatic adapter availability" below).
|
|
51
39
|
|
|
52
40
|
2. Call `acp_spawn`. Do NOT run `vellum sleep && vellum wake` - that kills the conversation.
|
|
53
41
|
|
|
54
42
|
## Automatic adapter availability
|
|
55
43
|
|
|
56
|
-
When
|
|
57
|
-
|
|
58
|
-
An adapter already on PATH is left alone, whoever installed it: the install runs only when preflight found no binary at all.
|
|
44
|
+
When `acp_spawn` finds the agent's binary missing from PATH, the assistant installs it once via a sandboxed bun global install and then runs the real installed binary. The install runs in a fresh empty temporary directory (never the task's project directory), with known secrets stripped from the installer environment and the registry pinned to the public npm registry, so a malicious project directory cannot hijack package resolution or capture a token. After this one-time install, the adapter is a normal trusted binary on PATH and every later spawn (and resume) uses it directly.
|
|
59
45
|
|
|
60
46
|
Only the allowlisted out-of-box packages are ever installed this way (`@agentclientprotocol/claude-agent-acp`, `@agentclientprotocol/codex-acp`); user-configured agents with custom commands are never installed automatically.
|
|
61
47
|
|
|
62
|
-
Manual installation is fallback guidance for unusual setups: bun unavailable, restricted global installs, or an auto-install failure (the failure reason is surfaced in the tool result).
|
|
48
|
+
Manual installation is fallback guidance for unusual setups: bun unavailable, restricted global installs, or an auto-install failure (the failure reason is surfaced in the tool result).
|
|
63
49
|
|
|
64
50
|
```bash
|
|
65
|
-
bun add -g @agentclientprotocol/claude-agent-acp
|
|
66
|
-
bun add -g @agentclientprotocol/codex-acp
|
|
51
|
+
bun add -g @agentclientprotocol/claude-agent-acp # claude
|
|
52
|
+
bun add -g @agentclientprotocol/codex-acp # codex
|
|
67
53
|
```
|
|
68
54
|
|
|
69
55
|
## Claude setup
|
|
@@ -98,14 +84,20 @@ Do NOT put API keys (or any secret) in the workspace config file - secrets never
|
|
|
98
84
|
|
|
99
85
|
- Two agents are supported out-of-box: `claude` (via the `claude-agent-acp` adapter) and `codex` (via the `codex-acp` adapter).
|
|
100
86
|
- NEVER use `claude`, `claude -p`, `claude --acp`, or the bare `codex` CLI as the ACP `command`. Claude and Codex only speak the protocol through their dedicated `*-acp` adapters.
|
|
101
|
-
- Default profiles for both ship out-of-box. Users only need an `agents.<id>` entry in config if they want to override the defaults (e.g. point to a custom binary path or pass extra args/env). An entry
|
|
87
|
+
- Default profiles for both ship out-of-box. Users only need an `agents.<id>` entry in config if they want to override the defaults (e.g. point to a custom binary path or pass extra args/env). An `acp.agents.<id>` entry replaces the bundled default entirely (no field merge), so any override must spell out the full `command` and `args`, not just the field being changed.
|
|
102
88
|
- NEVER change an existing ACP config to use a different command. If the config already has `claude-agent-acp` or `codex-acp`, leave it alone.
|
|
103
89
|
|
|
104
90
|
## Updating an adapter
|
|
105
91
|
|
|
106
|
-
|
|
92
|
+
Adapters are installed automatically when missing. To update an installed adapter, ask the user first and use its owning package manager. For bun installations:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
bun add -g @agentclientprotocol/claude-agent-acp@latest
|
|
96
|
+
# or
|
|
97
|
+
bun add -g @agentclientprotocol/codex-acp@latest
|
|
98
|
+
```
|
|
107
99
|
|
|
108
|
-
Codex uses the adapter's bundled dependency by default, within the version range declared by the adapter. If `CODEX_PATH` selects a separate CLI, update that installation separately.
|
|
100
|
+
Codex uses the adapter's bundled dependency by default, within the version range declared by the adapter. If `CODEX_PATH` selects a separate CLI, update that installation separately. Verify the required model with a fresh `acp_spawn` call after updating.
|
|
109
101
|
|
|
110
102
|
## When to use acp_steer vs acp_spawn
|
|
111
103
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"tools": [
|
|
4
4
|
{
|
|
5
5
|
"name": "acp_spawn",
|
|
6
|
-
"description": "Spawn an external coding agent (e.g. Claude Code, Codex) via ACP to work on a task. Default profiles ship for `claude` (`claude-agent-acp`) and `codex` (`codex-acp`); the assistant resolves the agent id to the right binary. The
|
|
6
|
+
"description": "Spawn an external coding agent (e.g. Claude Code, Codex) via ACP to work on a task. Default profiles ship for `claude` (`claude-agent-acp`) and `codex` (`codex-acp`); the assistant resolves the agent id to the right binary. The agent runs as a subprocess and streams results back. Use this when you want to delegate a coding task to an external agent that has its own tools, file editing, and terminal access. If a default agent's binary is missing, the assistant installs it once via a sandboxed bun global install and proceeds in the same call; if that fails (e.g. bun unavailable), an actionable install hint is returned - do NOT alter `agents.<id>.command` to swap binaries.",
|
|
7
7
|
"category": "orchestration",
|
|
8
8
|
"risk": "high",
|
|
9
9
|
"input_schema": {
|
|
@@ -20,10 +20,6 @@
|
|
|
20
20
|
"cwd": {
|
|
21
21
|
"type": "string",
|
|
22
22
|
"description": "Working directory for the agent. This determines where the agent runs and where its session is stored. Set this to the project/repo root the user wants the agent to work in. Defaults to current conversation's working directory."
|
|
23
|
-
},
|
|
24
|
-
"model": {
|
|
25
|
-
"type": "string",
|
|
26
|
-
"description": "Model the agent should run on, passed ONLY when the user named one (e.g. 'opus' for Claude). Left off, a Claude session runs on Opus and every other agent on its own default. If the agent refuses the value, or advertises no model selector, the result says so and the session runs on its own model."
|
|
27
23
|
}
|
|
28
24
|
},
|
|
29
25
|
"required": ["task"]
|
|
@@ -60,7 +60,7 @@ Apps live under `/workspace/data/apps/`:
|
|
|
60
60
|
<slug>.json # App metadata
|
|
61
61
|
<slug>/
|
|
62
62
|
src/ # Source files (TSX) — what you write
|
|
63
|
-
dist/ # Compiled output
|
|
63
|
+
dist/ # Compiled output — auto-generated by app_refresh
|
|
64
64
|
records/ # Data records (one JSON file per record)
|
|
65
65
|
<slug>.preview # Preview image (auto-generated)
|
|
66
66
|
```
|
|
@@ -156,9 +156,9 @@ Calculators, single-page tools, landing pages, and slide decks skip this — pas
|
|
|
156
156
|
|
|
157
157
|
### 3 — Create the app (scaffold, then expand)
|
|
158
158
|
|
|
159
|
-
⚠️ **`app_create` is ONE-SHOT per build.** Call it exactly once. After it returns an `app_id`, all further changes go through `file_write` / `file_edit`
|
|
159
|
+
⚠️ **`app_create` is ONE-SHOT per build.** Call it exactly once. After it returns an `app_id`, all further changes go through `file_write` / `file_edit` + `app_refresh`. To start over: `app_delete(app_id)` first, then a fresh `app_create`.
|
|
160
160
|
|
|
161
|
-
Apps are multi-file Preact + TSX projects; esbuild bundles
|
|
161
|
+
Apps are multi-file Preact + TSX projects; esbuild bundles automatically. Structure:
|
|
162
162
|
|
|
163
163
|
```
|
|
164
164
|
src/
|
|
@@ -179,9 +179,9 @@ render(<App />, document.getElementById("app")!);
|
|
|
179
179
|
|
|
180
180
|
1. **`app_create`** with a **4-file scaffold**: `src/index.html`, `src/main.tsx`, a **placeholder** `src/components/App.tsx` (`<div>Loading...</div>`), and an **empty** `src/styles.css`. The placeholders make the first compile clean — a 2-file scaffold leaves broken imports.
|
|
181
181
|
2. **`file_write`** each real file, one per tool call, overwriting the placeholders and adding components.
|
|
182
|
-
3.
|
|
182
|
+
3. **`app_refresh`** ONCE at the end to compile.
|
|
183
183
|
|
|
184
|
-
**Actually write the files.** Source code in reasoning/thinking is invisible to the app sandbox and is not a file write. Put every real file body in an `app_create.source_files`, `file_write`, `file_edit`, or `app_update.source_files` tool call, then verify the files exist before
|
|
184
|
+
**Actually write the files.** Source code in reasoning/thinking is invisible to the app sandbox and is not a file write. Put every real file body in an `app_create.source_files`, `file_write`, `file_edit`, or `app_update.source_files` tool call, then verify the files exist before `app_refresh` when there is any doubt.
|
|
185
185
|
|
|
186
186
|
**Allowed packages** (esbuild-resolved, no CDN): `date-fns`, `chart.js`, `lodash-es`, `zod`, `clsx`. For icons, write inline `<svg>` markup directly — no icon package is bundled.
|
|
187
187
|
|
|
@@ -221,14 +221,11 @@ app_create({ app_create({
|
|
|
221
221
|
|
|
222
222
|
### 4 — Compile
|
|
223
223
|
|
|
224
|
-
File edits do not compile on their own. After ALL file writes, compile once:
|
|
225
|
-
|
|
226
224
|
```
|
|
227
|
-
|
|
228
|
-
assistant apps refresh <name>
|
|
225
|
+
app_refresh(app_id)
|
|
229
226
|
```
|
|
230
227
|
|
|
231
|
-
|
|
228
|
+
Call it ONCE, after ALL file writes — batching is required. If it fails, the response has error details; fix with `file_edit`, then `app_refresh` again.
|
|
232
229
|
|
|
233
230
|
### 5 — Show the preview card
|
|
234
231
|
|
|
@@ -247,7 +244,7 @@ Editing an existing app means reusing its `app_id` — never `app_create`. Resol
|
|
|
247
244
|
- **`app_update`** — rename or change description/schema, and/or rewrite files via `source_files`, in one call. It recompiles for you, so no separate `app_refresh` is needed. Use this instead of editing `<slug>.json` by hand.
|
|
248
245
|
- **Full rebrand** — still iteration, edit the existing files.
|
|
249
246
|
|
|
250
|
-
Then
|
|
247
|
+
Then `app_refresh(app_id)` ONCE (unless you used `app_update`, which already recompiled). If the change is substantial, `app_open(app_id, open_mode: "preview")` for a fresh card; for small tweaks the existing card stays valid.
|
|
251
248
|
|
|
252
249
|
> ⚠️ **`skill_load("app-builder")` is required before every `app_*` call** (including the first `app_create`). The skill can auto-unload between turns; without the reload, `app_refresh` / `app_open` error with "not currently active." It's idempotent — call it every time.
|
|
253
250
|
|
|
@@ -353,7 +350,7 @@ Slide decks are a different domain — skip app patterns (contextual headers, se
|
|
|
353
350
|
## SKILL COMPLETE WHEN
|
|
354
351
|
|
|
355
352
|
- [ ] Request was scoped: personal build (sandbox) or complex/shippable (handed off to a project folder + coding agent)
|
|
356
|
-
- [ ] **Sandbox path:** `app_create` returned an `app_id`; all files written via `file_write`;
|
|
353
|
+
- [ ] **Sandbox path:** `app_create` returned an `app_id`; all files written via `file_write`; `app_refresh` ran ONCE clean; `app_open(open_mode: "preview")` rendered the card; user told what was built (3-6 bullets); iterations reflected live
|
|
357
354
|
- [ ] **Handoff path:** project folder established; coding agent spawned via `acp_spawn({ task, cwd })`; user told work continues in the folder
|
|
358
355
|
|
|
359
356
|
---
|
|
@@ -143,7 +143,7 @@ Older routes were written with a second `context` argument (`context.assistantEv
|
|
|
143
143
|
|
|
144
144
|
## Key rules
|
|
145
145
|
|
|
146
|
-
- Always create the route handler files via `file_write` before
|
|
146
|
+
- Always create the route handler files via `file_write` before calling `app_refresh`
|
|
147
147
|
- Export an optional `description` string for CLI discoverability (`assistant routes list`)
|
|
148
148
|
- Handlers have full Node.js API access — `fs`, `path`, `crypto`, etc.
|
|
149
149
|
- Handlers get a 30-second timeout per request
|
|
@@ -14,7 +14,7 @@ metadata:
|
|
|
14
14
|
|
|
15
15
|
You are a unified messaging assistant with access to multiple platforms (Gmail, Outlook, Telegram, and more). Use the messaging tools to help users read, search, organize, draft, and send messages across all connected platforms.
|
|
16
16
|
|
|
17
|
-
**
|
|
17
|
+
**Slack is not handled by this skill.** Slack messaging (send, read, search) is handled by the **slack** skill, which uses the Slack Web API directly via CLI. Do not use messaging tools with `platform: "slack"`.
|
|
18
18
|
|
|
19
19
|
## External Identity
|
|
20
20
|
|
|
@@ -34,7 +34,7 @@ When a platform is connected (auth test succeeds), always use the messaging API
|
|
|
34
34
|
|
|
35
35
|
On Gmail and Outlook, `messaging_send` creates a real mailbox draft for review. It does not send. Recipients are optional on Outlook: if the user has not named a To address, still create the draft (use a non-email `conversation_id` such as `drafts`) and tell them only after the tool returns a draft ID. If draft creation fails or is interrupted, say so and offer the email copy in chat. Do not claim a draft exists until the tool succeeds.
|
|
36
36
|
|
|
37
|
-
**
|
|
37
|
+
**Exception: Slack.** Slack messaging should use the Slack Web API directly via CLI, not messaging tools. See the **slack** skill for details.
|
|
38
38
|
|
|
39
39
|
## Connection Setup
|
|
40
40
|
|
|
@@ -64,7 +64,7 @@ When the user asks to "connect my email", "set up email", "manage my email", or
|
|
|
64
64
|
|
|
65
65
|
### Slack
|
|
66
66
|
|
|
67
|
-
For Slack setup, load the **slack-app-setup** skill directly.
|
|
67
|
+
Slack is **not** handled by this skill. For Slack setup, load the **slack-app-setup** skill directly. For Slack messaging, use the **slack** skill which accesses the Slack Web API via CLI.
|
|
68
68
|
|
|
69
69
|
### Telegram
|
|
70
70
|
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
"name": "messaging_send",
|
|
128
|
-
"description": "Send a message, reply to a thread, or create a draft. On Gmail and Outlook, always creates a real mailbox draft for review (recipients optional on Outlook).
|
|
128
|
+
"description": "Send a message, reply to a thread, or create a draft. On Gmail and Outlook, always creates a real mailbox draft for review (recipients optional on Outlook). Supports replies (via thread_id), attachments (via attachment_paths, Gmail and Outlook), and all messaging platforms.",
|
|
129
129
|
"category": "messaging",
|
|
130
130
|
"risk": "high",
|
|
131
131
|
"input_schema": {
|
|
@@ -133,11 +133,11 @@
|
|
|
133
133
|
"properties": {
|
|
134
134
|
"platform": {
|
|
135
135
|
"type": "string",
|
|
136
|
-
"description": "Platform (e.g. \"gmail\"
|
|
136
|
+
"description": "Platform (e.g. \"gmail\"). Auto-detected if only one is connected. Slack is not supported — use the Slack Web API directly."
|
|
137
137
|
},
|
|
138
138
|
"account": {
|
|
139
139
|
"type": "string",
|
|
140
|
-
"description": "Email address of the account to use. Required when multiple accounts are connected for the same
|
|
140
|
+
"description": "Email address of the account to use. Required when multiple accounts are connected for the same platform. If omitted, uses the most recently connected account."
|
|
141
141
|
},
|
|
142
142
|
"conversation_id": {
|
|
143
143
|
"type": "string",
|