@vellumai/assistant 0.12.1 → 0.12.2-staging.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 +4 -0
- package/ARCHITECTURE.md +20 -21
- package/docs/architecture/turn-actor.md +15 -8
- package/docs/guardian-request-flow.md +16 -0
- package/openapi.yaml +327 -52
- package/package.json +3 -1
- package/scripts/smoke-desktop-window-theme.ts +186 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +18 -10
- package/src/__tests__/anthropic-provider.test.ts +0 -63
- package/src/__tests__/app-compiler.test.ts +6 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +5 -2
- package/src/__tests__/app-dir-path-guard.test.ts +1 -3
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +6 -7
- package/src/__tests__/assistant-event-hub.test.ts +44 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +5 -2
- package/src/__tests__/computer-use-tools.test.ts +19 -7
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +28 -29
- package/src/__tests__/config-watcher.test.ts +23 -8
- 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 +26 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -10
- package/src/__tests__/conversation-queue.test.ts +48 -207
- package/src/__tests__/conversation-retry-discard.test.ts +54 -1
- package/src/__tests__/conversation-skill-tools.test.ts +27 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +8 -3
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +67 -0
- package/src/__tests__/conversation-title-service.test.ts +14 -10
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +3 -5
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +51 -0
- package/src/__tests__/credential-record-retire.test.ts +171 -1
- package/src/__tests__/credential-routes.test.ts +212 -3
- package/src/__tests__/credential-security-invariants.test.ts +4 -2
- package/src/__tests__/cu-unified-flow.test.ts +8 -2
- package/src/__tests__/document-sync-tags.test.ts +25 -0
- package/src/__tests__/drain-kick-guard.test.ts +0 -2
- package/src/__tests__/drain-requeue-on-contention.test.ts +0 -6
- package/src/__tests__/evict-conversations-for-reload.test.ts +1 -1
- package/src/__tests__/git-porcelain.test.ts +47 -0
- package/src/__tests__/heartbeat-service.test.ts +56 -40
- package/src/__tests__/helpers/set-workspace-mcp.ts +11 -0
- package/src/__tests__/host-bash-proxy.test.ts +26 -45
- package/src/__tests__/host-browser-proxy.test.ts +6 -17
- package/src/__tests__/host-cu-proxy.test.ts +539 -0
- package/src/__tests__/host-file-proxy-targeted.test.ts +23 -0
- package/src/__tests__/host-file-proxy.test.ts +11 -23
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +30 -9
- package/src/__tests__/list-messages-camera-frame.test.ts +121 -0
- package/src/__tests__/llm-catalog-parity.test.ts +25 -0
- package/src/__tests__/mcp-auth-routes.test.ts +6 -9
- package/src/__tests__/mcp-config-secret-boundary.test.ts +78 -136
- package/src/__tests__/mcp-health-check.test.ts +8 -11
- package/src/__tests__/mcp-list-plugin-servers.test.ts +8 -10
- package/src/__tests__/message-deleted-hook-dispatch.test.ts +119 -0
- package/src/__tests__/messages-after-tiebreaker.test.ts +91 -0
- package/src/__tests__/messages-read-boundary-guard.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +355 -548
- package/src/__tests__/model-intents.test.ts +3 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +85 -2
- package/src/__tests__/oauth-commands-routes.test.ts +113 -0
- package/src/__tests__/oauth-provider-profiles.test.ts +18 -0
- package/src/__tests__/openai-provider.test.ts +1 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
- package/src/__tests__/platform-callback-registration.test.ts +8 -16
- package/src/__tests__/platform-client-verify-credential.test.ts +2 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +14 -0
- package/src/__tests__/qdrant-manager.test.ts +132 -0
- package/src/__tests__/resolve-app.test.ts +135 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +229 -6
- package/src/__tests__/script-proxy-certs.test.ts +35 -0
- package/src/__tests__/service-account-token.test.ts +247 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skills.test.ts +9 -4
- package/src/__tests__/source-fingerprint.test.ts +184 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +19 -3
- package/src/__tests__/subagent-tools.test.ts +3 -2
- package/src/__tests__/telephony-tts-guard.test.ts +38 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/unicode.test.ts +13 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +4 -0
- package/src/__tests__/watch-retro-tool-availability.test.ts +8 -17
- package/src/__tests__/workspace-git-service.test.ts +26 -0
- package/src/__tests__/workspace-migration-154-repair-retired-codex-gpt-5-4-model-ids.test.ts +336 -0
- package/src/acp/__tests__/agent-process.test.ts +258 -4
- package/src/acp/__tests__/auth-required.test.ts +96 -0
- package/src/acp/__tests__/client-handler.test.ts +90 -2
- package/src/acp/__tests__/helpers/acp-model-option.ts +51 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +5 -1
- package/src/acp/__tests__/session-manager-resume.test.ts +270 -6
- package/src/acp/__tests__/session-manager-usage.test.ts +4 -2
- package/src/acp/__tests__/session-manager.test.ts +895 -4
- package/src/acp/agent-process.test.ts +4 -1
- package/src/acp/agent-process.ts +96 -10
- package/src/acp/auth-required.ts +50 -1
- package/src/acp/auto-install.test.ts +9 -7
- package/src/acp/client-handler.ts +16 -3
- package/src/acp/model-config.test.ts +166 -0
- package/src/acp/model-config.ts +138 -0
- package/src/acp/resolve-agent.test.ts +220 -6
- package/src/acp/resolve-agent.ts +88 -23
- package/src/acp/session-manager.test.ts +196 -3
- package/src/acp/session-manager.ts +441 -18
- package/src/acp/types.ts +50 -5
- package/src/agent/loop.ts +1 -0
- package/src/api/events/acp-session-model-update.test.ts +88 -0
- package/src/api/events/acp-session-model-update.ts +46 -0
- package/src/api/events/app-files-changed.ts +4 -3
- package/src/api/events/notification-intent.ts +2 -0
- package/src/api/events/user-message-echo.ts +7 -1
- package/src/api/index.ts +6 -0
- package/src/api/responses/conversation-message.ts +5 -0
- package/src/apps/app-store.ts +1 -1
- package/src/apps/resolve-app.ts +81 -0
- package/src/apps/source-fingerprint.ts +266 -0
- package/src/avatar/identity-avatar.ts +7 -2
- package/src/bundler/app-compiler.ts +15 -0
- package/src/calls/__tests__/barge-in-guard.test.ts +81 -0
- package/src/{__tests__ → calls/__tests__}/call-controller.test.ts +503 -82
- package/src/{__tests__ → calls/__tests__}/media-stream-audio-transcode.test.ts +1 -1
- package/src/{__tests__ → calls/__tests__}/media-stream-output.test.ts +37 -8
- package/src/{__tests__ → calls/__tests__}/media-stream-parser.test.ts +1 -1
- package/src/{__tests__ → calls/__tests__}/media-stream-server-integration.test.ts +150 -57
- package/src/{__tests__ → calls/__tests__}/media-stream-stt-session.test.ts +5 -5
- package/src/{__tests__ → calls/__tests__}/media-turn-detector.test.ts +1 -1
- package/src/{live-voice → calls}/__tests__/progress-narration.test.ts +4 -4
- package/src/{live-voice → calls}/__tests__/progress-phrases.test.ts +1 -1
- package/src/calls/__tests__/voice-control-protocol.test.ts +58 -25
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +229 -0
- package/src/calls/__tests__/voice-progress-cadence.test.ts +274 -0
- package/src/{__tests__/voice-session-bridge.test.ts → calls/__tests__/voice-session-bridge-turn-flow.test.ts} +20 -12
- package/src/calls/__tests__/voice-session-bridge.test.ts +37 -1
- package/src/calls/__tests__/voice-triage-escalate.test.ts +105 -0
- package/src/calls/barge-in-guard.ts +118 -0
- package/src/calls/call-constants.ts +24 -4
- package/src/calls/call-controller.ts +499 -199
- package/src/calls/call-transport.ts +16 -0
- package/src/calls/media-stream-output.ts +32 -0
- package/src/calls/media-stream-server.ts +82 -30
- package/src/calls/media-stream-stt-session.ts +15 -0
- package/src/{live-voice → calls}/progress-narration.ts +2 -2
- package/src/calls/resolve-call-tts-provider.ts +33 -2
- package/src/calls/tts-call-strategy.ts +9 -5
- package/src/calls/types.ts +2 -0
- package/src/calls/voice-control-protocol.ts +53 -21
- package/src/calls/voice-leg-coordinator.ts +189 -0
- package/src/calls/voice-progress-cadence.ts +423 -0
- package/src/calls/voice-session-bridge.ts +59 -46
- package/src/calls/voice-triage-escalate.ts +175 -56
- package/src/cli/commands/__tests__/apps.test.ts +245 -0
- package/src/cli/commands/__tests__/bash.test.ts +53 -0
- package/src/cli/commands/__tests__/roadmap.help.test.ts +19 -0
- package/src/cli/commands/apps.help.ts +67 -13
- package/src/cli/commands/apps.ts +183 -0
- package/src/cli/commands/bash.help.ts +8 -13
- package/src/cli/commands/bash.ts +7 -25
- package/src/cli/commands/channels/__tests__/send.test.ts +218 -0
- package/src/cli/commands/channels/index.help.ts +70 -2
- package/src/cli/commands/channels/index.ts +16 -3
- package/src/cli/commands/channels/send.ts +128 -0
- package/src/cli/commands/credentials.help.ts +6 -2
- 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 +5 -1
- package/src/cli/commands/roadmap.ts +1 -1
- package/src/cli/lib/bundled-marketplace.json +103 -90
- package/src/config/__tests__/default-profile-catalog.test.ts +22 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +15 -1
- package/src/config/__tests__/platform-identity.test.ts +255 -0
- package/src/config/__tests__/platform-rehydration.test.ts +99 -9
- package/src/config/acp-agent-write.ts +43 -0
- package/src/config/acp-defaults.test.ts +13 -3
- package/src/config/acp-defaults.ts +23 -6
- package/src/config/acp-schema.test.ts +81 -0
- package/src/config/acp-schema.ts +30 -2
- package/src/config/bundled-skills/acp/SKILL.md +22 -14
- package/src/config/bundled-skills/acp/TOOLS.json +5 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +12 -9
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +1 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +20 -2
- package/src/config/bundled-skills/computer-use/TOOLS.json +99 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-sequence.ts +12 -0
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -1
- package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -1
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -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 +67 -139
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +1 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -1
- package/src/config/bundled-skills/schedule/SKILL.md +3 -4
- package/src/config/bundled-skills/screen-annotation/SKILL.md +8 -1
- package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +4 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +6 -2
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +5 -2
- package/src/config/default-profile-catalog.ts +1 -1
- package/src/config/env.ts +2 -2
- package/src/config/feature-flag-registry.json +24 -12
- package/src/config/loader.ts +1 -0
- package/src/config/memory-v3-gate.test.ts +31 -0
- package/src/config/memory-v3-gate.ts +20 -16
- package/src/config/platform-identity.ts +201 -0
- package/src/config/platform-rehydration.ts +11 -27
- package/src/config/schema.ts +2 -2
- package/src/config/schemas/__tests__/live-voice.test.ts +8 -158
- package/src/config/schemas/__tests__/voice.test.ts +148 -0
- package/src/config/schemas/calls.ts +1 -28
- package/src/config/schemas/live-voice.ts +1 -173
- package/src/config/schemas/mcp.ts +1 -1
- package/src/config/schemas/memory-retrospective.ts +10 -0
- package/src/config/schemas/services.ts +8 -0
- package/src/config/schemas/skills.ts +0 -14
- package/src/config/schemas/voice.ts +150 -0
- package/src/credential-execution/process-manager.test.ts +18 -19
- package/src/credential-health/credential-health-service.ts +11 -17
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -121
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +4 -1
- package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +133 -0
- package/src/daemon/app-change-notify.ts +45 -0
- package/src/daemon/config-watcher.ts +13 -194
- package/src/daemon/conversation-error.ts +3 -2
- package/src/daemon/conversation-media-retry.ts +2 -1
- package/src/daemon/conversation-process.ts +35 -64
- package/src/daemon/conversation-runtime-assembly.ts +2 -1
- package/src/daemon/conversation-skill-tools.ts +13 -31
- package/src/daemon/conversation-store.ts +1 -1
- package/src/daemon/conversation-surfaces.ts +15 -9
- package/src/daemon/conversation-tool-setup.ts +37 -43
- package/src/daemon/conversation.ts +0 -3
- package/src/daemon/dictation-profile-store.ts +2 -1
- package/src/daemon/handlers/shared.ts +2 -1
- package/src/daemon/handlers/skills.ts +6 -3
- package/src/daemon/host-bash-proxy.ts +8 -12
- package/src/daemon/host-browser-proxy.ts +15 -1
- package/src/daemon/host-cu-proxy.ts +186 -19
- package/src/daemon/host-file-proxy.ts +8 -10
- package/src/daemon/host-proxy-preactivation.ts +2 -1
- package/src/daemon/host-transfer-proxy.ts +14 -18
- package/src/daemon/lifecycle.ts +0 -5
- package/src/daemon/mcp-reload-service.ts +5 -5
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/orphan-reaper.ts +1 -1
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/reaction-history-render.ts +2 -1
- package/src/daemon/shutdown-handlers.ts +1 -9
- package/src/daemon/skill-memory-refresh.ts +64 -0
- package/src/daemon/tool-side-effects.ts +7 -18
- package/src/desktop/__tests__/fake-desktop.ts +122 -0
- package/src/desktop/desktop-chrome-policy.test.ts +79 -0
- package/src/desktop/desktop-chrome-policy.ts +47 -0
- package/src/desktop/desktop-chrome-session.ts +37 -0
- package/src/desktop/desktop-dependencies.test.ts +102 -0
- package/src/desktop/desktop-dependencies.ts +308 -0
- package/src/desktop/desktop-feature.test.ts +18 -0
- package/src/desktop/desktop-feature.ts +19 -0
- package/src/desktop/desktop-panel-config.test.ts +135 -0
- package/src/desktop/desktop-panel-config.ts +149 -0
- package/src/desktop/desktop-session-manager.test.ts +730 -0
- package/src/desktop/desktop-session-manager.ts +850 -0
- package/src/desktop/desktop-stream-bridge.test.ts +395 -0
- package/src/desktop/desktop-stream-bridge.ts +214 -0
- package/src/desktop/desktop-wallpaper.test.ts +191 -0
- package/src/desktop/desktop-wallpaper.ts +113 -0
- package/src/desktop/desktop-window-drag.ts +177 -0
- package/src/desktop/desktop-window-manager-config.test.ts +230 -0
- package/src/desktop/desktop-window-manager-config.ts +238 -0
- package/src/desktop/desktop-window-theme.ts +170 -0
- package/src/heartbeat/heartbeat-service.ts +21 -3
- package/src/home/__tests__/feed-writer.test.ts +22 -0
- package/src/home/feed-writer.ts +11 -2
- package/src/hooks/types.ts +33 -0
- package/src/i18n/AGENTS.md +22 -0
- package/src/i18n/__tests__/i18n.test.ts +108 -0
- package/src/i18n/index.ts +16 -0
- package/src/i18n/locales.ts +93 -0
- package/src/i18n/messages.ts +61 -0
- package/src/i18n/title.ts +25 -0
- package/src/inbound/platform-callback-registration.ts +4 -5
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +0 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +15 -15
- package/src/live-voice/__tests__/live-voice-sight-frame-echo.test.ts +238 -0
- package/src/live-voice/__tests__/live-voice-vad.test.ts +2 -2
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +13 -69
- package/src/live-voice/live-voice-photo.ts +25 -6
- package/src/live-voice/live-voice-session.ts +213 -693
- package/src/live-voice/protocol.ts +0 -2
- package/src/mcp/__tests__/effective-config.test.ts +2 -2
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +135 -0
- package/src/mcp/effective-config.ts +3 -3
- package/src/mcp/mcp-header-store.ts +29 -45
- package/src/mcp/spec-schema.ts +111 -0
- package/src/mcp/startup.ts +8 -4
- package/src/mcp/workspace-mcp-config.ts +188 -0
- package/src/messaging/provider.ts +10 -3
- package/src/messaging/providers/__tests__/proactive-address.test.ts +95 -0
- package/src/messaging/providers/callback-routing.ts +18 -0
- package/src/messaging/providers/channel-transport.ts +56 -0
- package/src/messaging/providers/discord/transport.ts +17 -0
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +6 -17
- package/src/messaging/providers/slack/adapter.ts +7 -44
- package/src/messaging/providers/slack/transport.ts +16 -0
- package/src/messaging/providers/telegram-bot/adapter.ts +1 -48
- package/src/messaging/providers/telegram-bot/client.ts +0 -26
- package/src/messaging/providers/telegram-bot/transport.ts +20 -0
- package/src/messaging/providers/whatsapp/adapter.ts +1 -48
- package/src/messaging/providers/whatsapp/transport.ts +18 -0
- package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +8 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +55 -0
- package/src/notifications/__tests__/guardian-feed-projection.test.ts +158 -2
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +153 -3
- package/src/notifications/__tests__/schedule-result-producer.test.ts +99 -3
- package/src/notifications/adapters/macos.ts +3 -0
- package/src/notifications/assistant-reply-producer.ts +8 -3
- package/src/notifications/conversation-pairing.ts +36 -16
- package/src/notifications/delivered-post-record.ts +11 -1
- package/src/notifications/guardian-feed-projection.ts +125 -5
- package/src/notifications/home-feed-side-effect.ts +55 -7
- package/src/notifications/schedule-result-producer.ts +66 -22
- package/src/oauth/AGENTS.md +2 -0
- package/src/oauth/__tests__/seed-providers-managed.test.ts +54 -0
- package/src/oauth/byo-connection.test.ts +105 -0
- package/src/oauth/byo-connection.ts +36 -6
- package/src/oauth/connection-resolver.test.ts +73 -0
- package/src/oauth/connection-resolver.ts +95 -2
- package/src/oauth/scope-utils.ts +24 -0
- package/src/oauth/seed-providers.ts +204 -25
- package/src/outbound-proxy/certs.ts +3 -5
- package/src/permissions/checker.test.ts +11 -6
- package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
- package/src/persistence/conversation-crud.ts +71 -63
- package/src/persistence/conversation-lineage.ts +12 -4
- package/src/persistence/conversation-queries.ts +2 -2
- package/src/persistence/conversation-title-placeholders.ts +23 -0
- package/src/persistence/conversation-title-service.ts +9 -26
- package/src/persistence/embeddings/qdrant-manager.ts +163 -18
- 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-cursor.ts +78 -0
- package/src/persistence/message-reads.ts +30 -0
- package/src/persistence/migrations/157-invite-contact-id.ts +18 -6
- package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +149 -0
- package/src/persistence/schema/memory-core.ts +5 -0
- package/src/platform/client.test.ts +4 -2
- package/src/platform/client.ts +2 -10
- package/src/plugin-api/constants.ts +2 -0
- package/src/plugin-api/index.ts +1 -0
- package/src/plugin-api/types.ts +2 -0
- package/src/plugins/defaults/index.ts +2 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +46 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-backfill.test.ts +118 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-preserve.test.ts +83 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +9 -5
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +20 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +5 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +219 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +31 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +63 -0
- package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +4 -0
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +3 -2
- package/src/plugins/defaults/memory/context-search/format.ts +3 -2
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +6 -3
- package/src/plugins/defaults/memory/context-search/sources/workspace.ts +3 -2
- package/src/plugins/defaults/memory/graph/capability-seed.ts +6 -7
- package/src/plugins/defaults/memory/hooks/init.ts +10 -0
- package/src/plugins/defaults/memory/hooks/message-deleted.ts +21 -0
- package/src/plugins/defaults/memory/hooks/shutdown.ts +2 -0
- package/src/plugins/defaults/memory/host-utils.ts +10 -0
- package/src/plugins/defaults/memory/jobs-worker.ts +13 -0
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +34 -60
- package/src/plugins/defaults/memory/memory-retrospective-cursor-backfill.ts +126 -0
- package/src/plugins/defaults/memory/memory-retrospective-cursor-preserve.ts +79 -0
- package/src/plugins/defaults/memory/memory-retrospective-cursor.ts +28 -0
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +3 -5
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +12 -3
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +1 -1
- package/src/plugins/defaults/memory/memory-retrospective-state.ts +312 -71
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +2 -1
- package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +5 -3
- package/src/plugins/defaults/memory/skill-md-mtime-poll.ts +9 -0
- package/src/plugins/defaults/memory/startup.ts +28 -2
- package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +7 -9
- package/src/plugins/defaults/memory/substrate/page-index.ts +6 -1
- package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
- package/src/plugins/defaults/memory/v1/graph/consolidation.ts +4 -2
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +4 -2
- package/src/plugins/defaults/memory/v1/graph/retriever.ts +4 -1
- package/src/plugins/defaults/memory/v2/reranker.ts +6 -1
- package/src/plugins/defaults/memory/v3/__tests__/card.test.ts +24 -0
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +125 -0
- package/src/plugins/defaults/memory/v3/__tests__/sections.test.ts +26 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +30 -0
- package/src/plugins/defaults/memory/v3/card.ts +3 -2
- package/src/plugins/defaults/memory/v3/pool-select.ts +5 -3
- package/src/plugins/defaults/memory/v3/sections.ts +9 -3
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +5 -2
- package/src/plugins/defaults/memory/worker.ts +6 -0
- package/src/plugins/mcp-servers.ts +15 -75
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -3
- package/src/providers/__tests__/retry-callsite.test.ts +41 -0
- package/src/providers/__tests__/retry-outbound-sanitize.test.ts +176 -0
- package/src/providers/anthropic/client.ts +0 -47
- package/src/providers/gemini/client.ts +9 -23
- package/src/providers/gemini-thought-signature.test.ts +63 -0
- package/src/providers/gemini-thought-signature.ts +44 -0
- package/src/providers/inference/__tests__/endpoint-probe.test.ts +42 -3
- package/src/providers/inference/auth.ts +2 -3
- package/src/providers/inference/connection-availability.ts +27 -8
- package/src/providers/inference/endpoint-probe.ts +10 -1
- package/src/providers/inference/resolve-auth.ts +22 -4
- package/src/providers/inference/service-account-token.ts +248 -0
- package/src/providers/model-catalog.ts +34 -0
- package/src/providers/model-intents.ts +10 -5
- package/src/providers/openai/__tests__/chat-completions-output-token-limit.test.ts +141 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +146 -18
- package/src/providers/openai/__tests__/chat-completions-provider-thought-signature.test.ts +613 -0
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +235 -0
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +83 -1
- package/src/providers/openai/chat-completions-provider.ts +212 -79
- package/src/providers/openai/codex-models.ts +0 -4
- package/src/providers/openai/google-thought-signature.ts +320 -0
- package/src/providers/opencode/client.test.ts +73 -4
- package/src/providers/opencode/client.ts +60 -3
- package/src/providers/openrouter/client.ts +20 -0
- package/src/providers/outbound-request-sanitize.ts +96 -0
- package/src/providers/retry.ts +30 -19
- package/src/providers/unparseable-tool-args.ts +5 -1
- package/src/runtime/AGENTS.md +3 -1
- package/src/runtime/__tests__/channel-send.test.ts +443 -0
- package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +89 -0
- package/src/runtime/__tests__/host-observe.test.ts +40 -1
- package/src/runtime/__tests__/live-voice-upgrade.test.ts +58 -0
- package/src/runtime/__tests__/runtime-ws-test-utils.ts +72 -0
- package/src/runtime/__tests__/watch-stream-upgrade.test.ts +59 -0
- package/src/runtime/agent-wake.ts +2 -1
- package/src/runtime/assistant-event-hub.ts +21 -3
- package/src/runtime/auth/same-actor.ts +38 -3
- package/src/runtime/channel-send.ts +316 -0
- package/src/runtime/host-observe.ts +11 -1
- package/src/runtime/http-server.ts +160 -151
- package/src/runtime/routes/__tests__/acp-routes.test.ts +159 -4
- package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +205 -0
- package/src/runtime/routes/__tests__/channel-send-routes.test.ts +127 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +108 -1
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +2 -2
- package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +107 -0
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +16 -12
- package/src/runtime/routes/acp-routes.test.ts +15 -0
- package/src/runtime/routes/acp-routes.ts +72 -9
- package/src/runtime/routes/app-management-routes.ts +73 -0
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/channel-send-routes.ts +85 -0
- package/src/runtime/routes/conversation-list-routes.ts +14 -3
- package/src/runtime/routes/conversation-query-routes.ts +40 -0
- package/src/runtime/routes/conversation-routes.ts +16 -3
- package/src/runtime/routes/credential-routes.ts +19 -10
- package/src/runtime/routes/desktop-setup-routes.test.ts +74 -0
- package/src/runtime/routes/desktop-setup-routes.ts +35 -0
- package/src/runtime/routes/diagnostics-routes.ts +61 -4
- package/src/runtime/routes/events-routes.ts +4 -0
- package/src/runtime/routes/host-cu-routes.ts +6 -0
- package/src/runtime/routes/index.ts +4 -2
- package/src/runtime/routes/log-export-routes.ts +2 -0
- package/src/runtime/routes/mcp-auth-routes.ts +39 -47
- package/src/runtime/routes/migration-routes.ts +6 -20
- package/src/runtime/routes/oauth-commands-routes.ts +36 -0
- package/src/runtime/routes/platform-routes.ts +18 -15
- package/src/runtime/routes/workspace-routes.test.ts +55 -26
- package/src/runtime/routes/workspace-routes.ts +46 -63
- package/src/runtime/routes/workspace-tree-walk.test.ts +244 -0
- package/src/runtime/routes/workspace-tree-walk.ts +240 -0
- package/src/runtime/routes/workspace-utils.ts +17 -0
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +28 -0
- package/src/runtime/services/conversation-serializer.ts +16 -3
- package/src/runtime/sync/resource-sync-events.ts +2 -1
- package/src/schedule/run-script.ts +2 -1
- package/src/schedule/schedule-store.ts +9 -2
- package/src/schedule/worker.ts +1 -1
- package/src/security/__tests__/ces-http-record-backend.test.ts +137 -0
- package/src/security/ces-http-record-backend.ts +120 -0
- package/src/security/ces-rpc-record-backend.ts +7 -0
- package/src/security/untrusted-content.ts +3 -1
- package/src/skills/__tests__/workspace-skill-md-signature.test.ts +60 -0
- package/src/skills/workspace-skill-md-signature.ts +50 -0
- package/src/subagent/consult-context.ts +12 -25
- package/src/tools/__tests__/side-effect-abort-guard.test.ts +1 -0
- package/src/tools/acp/list-agents.test.ts +3 -1
- package/src/tools/acp/spawn.test.ts +146 -11
- package/src/tools/acp/spawn.ts +21 -3
- package/src/tools/acp/status.test.ts +94 -0
- package/src/tools/acp/status.ts +40 -3
- package/src/tools/app-control/skill-proxy-bridge.ts +2 -1
- package/src/tools/browser/browser-execution.ts +1 -1
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +9 -3
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +2 -1
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +3 -2
- package/src/tools/browser/network-recorder.ts +2 -1
- package/src/tools/capability-offer.test.ts +22 -2
- package/src/tools/capability-offer.ts +16 -1
- package/src/tools/computer-use/definitions.ts +121 -2
- package/src/tools/computer-use/skill-proxy-bridge.ts +2 -1
- package/src/tools/credentials/metadata-store.ts +100 -0
- package/src/tools/filesystem/search.ts +2 -1
- package/src/tools/host-filesystem/edit.test.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +2 -2
- package/src/tools/host-filesystem/read.test.ts +2 -1
- package/src/tools/host-filesystem/read.ts +2 -2
- package/src/tools/host-filesystem/transfer.test.ts +2 -1
- package/src/tools/host-filesystem/transfer.ts +2 -2
- package/src/tools/host-filesystem/write.test.ts +2 -1
- package/src/tools/host-filesystem/write.ts +2 -2
- package/src/tools/host-terminal/host-shell.test.ts +16 -0
- package/src/tools/host-terminal/host-shell.ts +4 -20
- package/src/tools/network/web-search.ts +6 -1
- package/src/tools/policy-context.ts +6 -7
- package/src/tools/skills/scaffold-managed.ts +61 -3
- package/src/tools/subagent/spawn.ts +5 -8
- package/src/tools/terminal/__tests__/sanitized-bash.test.ts +57 -0
- package/src/tools/terminal/sanitized-bash.ts +105 -0
- package/src/tools/watch/watch-retro-report.ts +0 -8
- package/src/types/host-capabilities.ts +5 -3
- package/src/util/__tests__/language-subtag.test.ts +23 -1
- package/src/util/ca-bundle.ts +13 -0
- package/src/util/language-subtag.ts +16 -0
- package/src/util/platform.ts +8 -0
- package/src/util/unicode.ts +15 -1
- package/src/watch/watch-timeline.ts +2 -2
- package/src/workflows/run-manager.ts +2 -1
- package/src/workspace/git-porcelain.ts +66 -0
- package/src/workspace/git-service.ts +6 -55
- package/src/workspace/migrations/154-repair-retired-codex-gpt-5-4-model-ids.ts +258 -0
- package/src/workspace/migrations/155-move-front-model-config-to-voice.ts +78 -0
- package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +214 -0
- package/src/workspace/migrations/__tests__/155-move-front-model-config-to-voice.test.ts +102 -0
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +199 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/app-source-watcher.test.ts +0 -218
- package/src/__tests__/config-watcher-skill-reseed.test.ts +0 -359
- package/src/__tests__/speaker-identification.test.ts +0 -56
- package/src/calls/speaker-identification.ts +0 -233
- package/src/daemon/app-source-watcher.ts +0 -218
- package/src/messaging/providers/whatsapp/client.ts +0 -29
- package/src/runtime/routes/debug-bash-routes.ts +0 -173
- package/src/util/fs-watcher-error.ts +0 -36
- /package/src/{live-voice → calls}/progress-phrases.ts +0 -0
|
@@ -24,8 +24,11 @@ import {
|
|
|
24
24
|
AcpResumeError,
|
|
25
25
|
AcpSessionNotFoundError,
|
|
26
26
|
} from "../../acp/session-manager.js";
|
|
27
|
-
import type
|
|
28
|
-
import
|
|
27
|
+
import { type AcpSessionState, isLiveAcpStatus } from "../../acp/types.js";
|
|
28
|
+
import {
|
|
29
|
+
AcpSessionModelUpdateEventSchema,
|
|
30
|
+
type AssistantEvent,
|
|
31
|
+
} from "../../api/index.js";
|
|
29
32
|
import { getConfig } from "../../config/loader.js";
|
|
30
33
|
import { createGuardianRequestForConfirmation } from "../../permissions/confirmation-guardian-request.js";
|
|
31
34
|
import type { UserDecision } from "../../permissions/types.js";
|
|
@@ -53,6 +56,10 @@ const log = getLogger("acp-routes");
|
|
|
53
56
|
const DEFAULT_SESSION_LIMIT = 50;
|
|
54
57
|
const MAX_SESSION_LIMIT = 500;
|
|
55
58
|
|
|
59
|
+
/** The option shape the `acp_session_model_update` event already publishes. */
|
|
60
|
+
const acpModelOptionsSchema =
|
|
61
|
+
AcpSessionModelUpdateEventSchema.shape.availableModels;
|
|
62
|
+
|
|
56
63
|
const sessionEntrySchema = z.object({
|
|
57
64
|
id: z.string(),
|
|
58
65
|
agentId: z.string(),
|
|
@@ -68,6 +75,15 @@ const sessionEntrySchema = z.object({
|
|
|
68
75
|
/** Credential failure that ended the run, when one did. Drives the inline
|
|
69
76
|
* Connect card on reopen; cleared when a replacement token is stored. */
|
|
70
77
|
authErrorCode: z.string().optional(),
|
|
78
|
+
/** Model a live session is running on. Absent for history rows, which have
|
|
79
|
+
* no live process to ask. */
|
|
80
|
+
model: z.string().optional(),
|
|
81
|
+
/** Models a live session could run on. Absent for history rows. */
|
|
82
|
+
availableModels: acpModelOptionsSchema.optional(),
|
|
83
|
+
/** Scopes live model revisions to one assistant process. */
|
|
84
|
+
modelRevisionEpoch: z.string().uuid().optional(),
|
|
85
|
+
/** Orders live model state within `modelRevisionEpoch`. */
|
|
86
|
+
modelRevision: z.number().int().nonnegative().optional(),
|
|
71
87
|
usedTokens: z.number().optional(),
|
|
72
88
|
contextSize: z.number().optional(),
|
|
73
89
|
costAmount: z.number().optional(),
|
|
@@ -214,17 +230,26 @@ async function spawnSession({ body, abortSignal }: RouteHandlerArgs) {
|
|
|
214
230
|
const task = body?.task as string | undefined;
|
|
215
231
|
const conversationId = body?.conversationId as string | undefined;
|
|
216
232
|
const cwd = (body?.cwd as string | undefined) ?? process.cwd();
|
|
233
|
+
const model = body?.model ?? undefined;
|
|
217
234
|
|
|
218
235
|
if (!agent || !task || !conversationId) {
|
|
219
236
|
throw new BadRequestError("agent, task, and conversationId are required");
|
|
220
237
|
}
|
|
238
|
+
if (model !== undefined && typeof model !== "string") {
|
|
239
|
+
throw new BadRequestError("model must be a string when provided");
|
|
240
|
+
}
|
|
221
241
|
|
|
222
242
|
// High-risk approval gate. Block BEFORE any side effects — resolution can
|
|
223
243
|
// trigger a `bun` global install (auto-install.ts) and `manager.spawn`
|
|
224
244
|
// launches the host subprocess — so an unapproved request mutates nothing.
|
|
225
245
|
const decision = await awaitRouteApproval({
|
|
226
246
|
toolName: "acp_spawn",
|
|
227
|
-
input: {
|
|
247
|
+
input: {
|
|
248
|
+
agent,
|
|
249
|
+
task,
|
|
250
|
+
cwd,
|
|
251
|
+
...(model !== undefined ? { model } : {}),
|
|
252
|
+
},
|
|
228
253
|
conversationId,
|
|
229
254
|
signal: abortSignal,
|
|
230
255
|
});
|
|
@@ -262,17 +287,33 @@ async function spawnSession({ body, abortSignal }: RouteHandlerArgs) {
|
|
|
262
287
|
);
|
|
263
288
|
|
|
264
289
|
const manager = getAcpSessionManager();
|
|
265
|
-
const {
|
|
290
|
+
const {
|
|
291
|
+
acpSessionId,
|
|
292
|
+
protocolSessionId,
|
|
293
|
+
requestedModel,
|
|
294
|
+
effectiveModel,
|
|
295
|
+
modelWarning,
|
|
296
|
+
} = await manager.spawn(
|
|
266
297
|
agent,
|
|
267
298
|
agentConfig,
|
|
268
299
|
task,
|
|
269
300
|
cwd,
|
|
270
301
|
conversationId,
|
|
271
302
|
broadcastMessage,
|
|
303
|
+
{ model },
|
|
272
304
|
);
|
|
273
305
|
|
|
274
306
|
log.info({ acpSessionId, protocolSessionId, agent }, "ACP spawn succeeded");
|
|
275
|
-
|
|
307
|
+
// A refused model is a warning, not a failed spawn: the session is live on
|
|
308
|
+
// the agent's own model.
|
|
309
|
+
return {
|
|
310
|
+
acpSessionId,
|
|
311
|
+
protocolSessionId,
|
|
312
|
+
agent,
|
|
313
|
+
requestedModel: requestedModel ?? null,
|
|
314
|
+
effectiveModel: effectiveModel ?? null,
|
|
315
|
+
...(modelWarning ? { modelWarning } : {}),
|
|
316
|
+
};
|
|
276
317
|
}
|
|
277
318
|
|
|
278
319
|
async function steerSession({ pathParams, body }: RouteHandlerArgs) {
|
|
@@ -588,10 +629,7 @@ function deleteSession({ pathParams }: RouteHandlerArgs) {
|
|
|
588
629
|
|
|
589
630
|
try {
|
|
590
631
|
const state = manager.getStatus(id);
|
|
591
|
-
if (
|
|
592
|
-
!Array.isArray(state) &&
|
|
593
|
-
(state.status === "running" || state.status === "initializing")
|
|
594
|
-
) {
|
|
632
|
+
if (!Array.isArray(state) && isLiveAcpStatus(state.status)) {
|
|
595
633
|
throw new ConflictError(
|
|
596
634
|
`ACP session "${id}" is still ${state.status}. Cancel or close it before deleting.`,
|
|
597
635
|
);
|
|
@@ -640,11 +678,32 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
640
678
|
task: z.string().describe("Task description"),
|
|
641
679
|
conversationId: z.string(),
|
|
642
680
|
cwd: z.string().describe("Working directory").optional(),
|
|
681
|
+
model: z
|
|
682
|
+
.string()
|
|
683
|
+
.optional()
|
|
684
|
+
.describe("Optional model id or alias to request for the session."),
|
|
643
685
|
}),
|
|
644
686
|
responseBody: z.object({
|
|
645
687
|
acpSessionId: z.string(),
|
|
646
688
|
protocolSessionId: z.string(),
|
|
647
689
|
agent: z.string(),
|
|
690
|
+
requestedModel: z
|
|
691
|
+
.string()
|
|
692
|
+
.nullable()
|
|
693
|
+
.describe("The model explicitly requested for this spawn, if any."),
|
|
694
|
+
effectiveModel: z
|
|
695
|
+
.string()
|
|
696
|
+
.nullable()
|
|
697
|
+
.describe(
|
|
698
|
+
"The top-level session model reported by the ACP adapter, if any.",
|
|
699
|
+
),
|
|
700
|
+
modelWarning: z
|
|
701
|
+
.string()
|
|
702
|
+
.optional()
|
|
703
|
+
.describe(
|
|
704
|
+
"Why the requested model was not applied. The session is running " +
|
|
705
|
+
"on the agent's own model.",
|
|
706
|
+
),
|
|
648
707
|
}),
|
|
649
708
|
},
|
|
650
709
|
{
|
|
@@ -852,6 +911,10 @@ function listMergedSessions(opts: { limit: number; conversationId?: string }): {
|
|
|
852
911
|
parentToolUseId: s.parentToolUseId,
|
|
853
912
|
authErrorCode: s.authErrorCode,
|
|
854
913
|
authErrorCredential: s.authErrorCredential,
|
|
914
|
+
model: s.model,
|
|
915
|
+
availableModels: s.availableModels,
|
|
916
|
+
modelRevisionEpoch: s.modelRevisionEpoch,
|
|
917
|
+
modelRevision: s.modelRevision,
|
|
855
918
|
usedTokens: s.latestUsage?.usedTokens,
|
|
856
919
|
contextSize: s.latestUsage?.contextSize,
|
|
857
920
|
costAmount: s.latestUsage?.costAmount,
|
|
@@ -51,6 +51,7 @@ import { compileApp, runCompile } from "../../bundler/app-compiler.js";
|
|
|
51
51
|
import { scanBundle } from "../../bundler/bundle-scanner.js";
|
|
52
52
|
import type { SignatureJson } from "../../bundler/bundle-signer.js";
|
|
53
53
|
import { verifyBundleSignature } from "../../bundler/signature-verifier.js";
|
|
54
|
+
import { notifyAppSurfacesChanged } from "../../daemon/app-change-notify.js";
|
|
54
55
|
import { compareSemver } from "../../daemon/handlers/shared.js";
|
|
55
56
|
import { computeContentId } from "../../util/content-id.js";
|
|
56
57
|
import { getLogger } from "../../util/logger.js";
|
|
@@ -128,6 +129,17 @@ const appListItemSchema = z.object({
|
|
|
128
129
|
|
|
129
130
|
type AppListItem = z.infer<typeof appListItemSchema>;
|
|
130
131
|
|
|
132
|
+
const compileDiagnosticSchema = z.object({
|
|
133
|
+
text: z.string(),
|
|
134
|
+
location: z
|
|
135
|
+
.object({
|
|
136
|
+
file: z.string(),
|
|
137
|
+
line: z.number(),
|
|
138
|
+
column: z.number(),
|
|
139
|
+
})
|
|
140
|
+
.optional(),
|
|
141
|
+
});
|
|
142
|
+
|
|
131
143
|
/**
|
|
132
144
|
* The pin route's body. `RouteDefinition.requestBody` is a codegen signal and
|
|
133
145
|
* does not validate, so the handler parses against this too; declaring it once
|
|
@@ -896,6 +908,44 @@ async function handleOpenApp({ pathParams }: RouteHandlerArgs) {
|
|
|
896
908
|
return { ...result, html };
|
|
897
909
|
}
|
|
898
910
|
|
|
911
|
+
/**
|
|
912
|
+
* Compile an app's source into dist/ and refresh open surfaces.
|
|
913
|
+
* Runs in the assistant process so open surfaces, client broadcasts, and
|
|
914
|
+
* published-app redeploy see the new build. Workspace and plugin apps both
|
|
915
|
+
* compile in place so local plugin edits can be rebuilt without waiting for
|
|
916
|
+
* the plugin source watcher.
|
|
917
|
+
*/
|
|
918
|
+
async function handleRefreshApp({ pathParams }: RouteHandlerArgs) {
|
|
919
|
+
const appId = pathParams?.id;
|
|
920
|
+
if (!appId) {
|
|
921
|
+
throw new BadRequestError("App id is required.");
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
const source = resolveAppSource(appId);
|
|
925
|
+
if (!source) {
|
|
926
|
+
throw new NotFoundError(
|
|
927
|
+
`App "${appId}" not found. Run 'assistant apps list' to see available apps.`,
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
const compileResult = await compileApp(source.sourceDir);
|
|
932
|
+
notifyAppSurfacesChanged(source.id, { fileChange: true });
|
|
933
|
+
|
|
934
|
+
return {
|
|
935
|
+
ok: true as const,
|
|
936
|
+
appId: source.id,
|
|
937
|
+
name: source.name,
|
|
938
|
+
compiled: compileResult.ok,
|
|
939
|
+
compile_duration_ms: compileResult.durationMs,
|
|
940
|
+
...(compileResult.ok
|
|
941
|
+
? {}
|
|
942
|
+
: {
|
|
943
|
+
compile_errors: compileResult.errors,
|
|
944
|
+
compile_warnings: compileResult.warnings,
|
|
945
|
+
}),
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
|
|
899
949
|
/**
|
|
900
950
|
* Reject a mutation targeting a plugin-bundled app. Plugin apps are owned by
|
|
901
951
|
* their plugin and are read-only over this surface — their source is not
|
|
@@ -1253,6 +1303,29 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
1253
1303
|
origin: z.string(),
|
|
1254
1304
|
}),
|
|
1255
1305
|
},
|
|
1306
|
+
{
|
|
1307
|
+
operationId: "apps_refresh",
|
|
1308
|
+
endpoint: "apps/:id/refresh",
|
|
1309
|
+
method: "POST",
|
|
1310
|
+
policy: {
|
|
1311
|
+
requiredScopes: ["settings.write"],
|
|
1312
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
1313
|
+
},
|
|
1314
|
+
handler: handleRefreshApp,
|
|
1315
|
+
summary: "Compile an app",
|
|
1316
|
+
description:
|
|
1317
|
+
"Compile workspace or plugin app source into dist/ and refresh open surfaces.",
|
|
1318
|
+
tags: ["apps"],
|
|
1319
|
+
responseBody: z.object({
|
|
1320
|
+
ok: z.literal(true),
|
|
1321
|
+
appId: z.string(),
|
|
1322
|
+
name: z.string(),
|
|
1323
|
+
compiled: z.boolean(),
|
|
1324
|
+
compile_duration_ms: z.number(),
|
|
1325
|
+
compile_errors: z.array(compileDiagnosticSchema).optional(),
|
|
1326
|
+
compile_warnings: z.array(compileDiagnosticSchema).optional(),
|
|
1327
|
+
}),
|
|
1328
|
+
},
|
|
1256
1329
|
{
|
|
1257
1330
|
operationId: "apps_delete",
|
|
1258
1331
|
endpoint: "apps/:id/delete",
|
|
@@ -92,7 +92,7 @@ function serveCompiledApp(
|
|
|
92
92
|
);
|
|
93
93
|
const body = isLegacySingleFileDir(appDir)
|
|
94
94
|
? UNSUPPORTED_LEGACY_APP_HTML
|
|
95
|
-
: `<p>App has not been compiled yet.
|
|
95
|
+
: `<p>App has not been compiled yet. Run <code>assistant apps refresh</code> to build.</p>`;
|
|
96
96
|
return (
|
|
97
97
|
`<!DOCTYPE html><html><head><title>${escapedName}</title></head>` +
|
|
98
98
|
`<body>${body}</body></html>`
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route handler for a model-directed text send to a channel chat.
|
|
3
|
+
*
|
|
4
|
+
* POST /v1/channels/send: deliver text to a chat on a channel through the
|
|
5
|
+
* channel's transport, recorded after acknowledgement. The
|
|
6
|
+
* messaging tool's channel branch runs the same function in-process; this
|
|
7
|
+
* route is the door for the CLI and scripts, so the two doors share one
|
|
8
|
+
* seam and one record.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
13
|
+
import { CHANNEL_IDS } from "../../channels/types.js";
|
|
14
|
+
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
15
|
+
import {
|
|
16
|
+
ChannelNotAddressableError,
|
|
17
|
+
ChannelSendFailedError,
|
|
18
|
+
sendChannelText,
|
|
19
|
+
} from "../channel-send.js";
|
|
20
|
+
import { BadGatewayError, BadRequestError } from "./errors.js";
|
|
21
|
+
import { parseBody } from "./parse-body.js";
|
|
22
|
+
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
23
|
+
|
|
24
|
+
const ProactiveTargetSchema = z.object({
|
|
25
|
+
kind: z.literal("chat"),
|
|
26
|
+
chatId: z.string().min(1).describe("Chat id in the channel's own id space"),
|
|
27
|
+
threadId: z
|
|
28
|
+
.string()
|
|
29
|
+
.min(1)
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("Thread within the chat, in the channel's own id space"),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const ChannelSendRequestSchema = z.object({
|
|
35
|
+
channel: z.enum(CHANNEL_IDS).describe("Channel to send on"),
|
|
36
|
+
target: ProactiveTargetSchema,
|
|
37
|
+
text: z.string().min(1).describe("Text to send"),
|
|
38
|
+
renderRichly: z
|
|
39
|
+
.boolean()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("Ask the channel for its rich rendering, where it has one"),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const ChannelSendResponseSchema = z.object({
|
|
45
|
+
channel: z.enum(CHANNEL_IDS),
|
|
46
|
+
chatId: z.string(),
|
|
47
|
+
threadId: z.string().optional(),
|
|
48
|
+
messageIds: z.array(z.string()),
|
|
49
|
+
lastMessageId: z.string(),
|
|
50
|
+
recordedIn: z.string().optional(),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
async function handleChannelSend({ body }: RouteHandlerArgs) {
|
|
54
|
+
const request = parseBody(ChannelSendRequestSchema, body);
|
|
55
|
+
try {
|
|
56
|
+
return await sendChannelText(request);
|
|
57
|
+
} catch (e) {
|
|
58
|
+
if (e instanceof ChannelNotAddressableError) {
|
|
59
|
+
throw new BadRequestError(e.message);
|
|
60
|
+
}
|
|
61
|
+
if (e instanceof ChannelSendFailedError) {
|
|
62
|
+
throw new BadGatewayError(e.message);
|
|
63
|
+
}
|
|
64
|
+
throw e;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const ROUTES: RouteDefinition[] = [
|
|
69
|
+
{
|
|
70
|
+
operationId: "channels_send_post",
|
|
71
|
+
endpoint: "channels/send",
|
|
72
|
+
method: "POST",
|
|
73
|
+
policy: {
|
|
74
|
+
requiredScopes: ["chat.write"],
|
|
75
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
76
|
+
},
|
|
77
|
+
summary: "Send text to a channel chat",
|
|
78
|
+
description:
|
|
79
|
+
"Deliver text to a chat on a channel through the channel's transport, recorded after the channel acknowledges it.",
|
|
80
|
+
tags: ["channels"],
|
|
81
|
+
handler: handleChannelSend,
|
|
82
|
+
requestBody: ChannelSendRequestSchema,
|
|
83
|
+
responseBody: ChannelSendResponseSchema,
|
|
84
|
+
},
|
|
85
|
+
];
|
|
@@ -14,6 +14,7 @@ import { z } from "zod";
|
|
|
14
14
|
|
|
15
15
|
import { CHANNEL_IDS } from "../../channels/types.js";
|
|
16
16
|
import { isAssistantInitiatedThreadsEnabled } from "../../config/assistant-initiated-threads-gate.js";
|
|
17
|
+
import { localeFromAcceptLanguage } from "../../i18n/index.js";
|
|
17
18
|
import { channelBindingSchema } from "../../messaging/channel-binding-schema.js";
|
|
18
19
|
import {
|
|
19
20
|
type Confidence,
|
|
@@ -244,7 +245,10 @@ function parseEnumQueryParam<const T extends readonly string[]>(
|
|
|
244
245
|
);
|
|
245
246
|
}
|
|
246
247
|
|
|
247
|
-
function handleListConversations({
|
|
248
|
+
function handleListConversations({
|
|
249
|
+
queryParams = {},
|
|
250
|
+
headers,
|
|
251
|
+
}: RouteHandlerArgs) {
|
|
248
252
|
const limit = Number(queryParams.limit ?? 50);
|
|
249
253
|
const offset = Number(queryParams.offset ?? 0);
|
|
250
254
|
// "background" is the back-compat umbrella (background + scheduled); newer
|
|
@@ -365,6 +369,7 @@ function handleListConversations({ queryParams = {} }: RouteHandlerArgs) {
|
|
|
365
369
|
// Checks in-memory flag first (hot path), falls back to the
|
|
366
370
|
// persisted `processing_started_at` column for cold conversations.
|
|
367
371
|
isProcessing: isConversationProcessing(conversation.id),
|
|
372
|
+
locale: localeFromAcceptLanguage(headers?.["accept-language"]),
|
|
368
373
|
}),
|
|
369
374
|
),
|
|
370
375
|
nextOffset,
|
|
@@ -579,8 +584,14 @@ function handleMarkUnread({ body = {}, headers }: RouteHandlerArgs) {
|
|
|
579
584
|
}
|
|
580
585
|
}
|
|
581
586
|
|
|
582
|
-
function handleGetConversation({
|
|
583
|
-
|
|
587
|
+
function handleGetConversation({
|
|
588
|
+
pathParams = {},
|
|
589
|
+
headers,
|
|
590
|
+
}: RouteHandlerArgs) {
|
|
591
|
+
const detail = buildConversationDetailResponse(
|
|
592
|
+
pathParams.id!,
|
|
593
|
+
localeFromAcceptLanguage(headers?.["accept-language"]),
|
|
594
|
+
);
|
|
584
595
|
if (!detail) {
|
|
585
596
|
throw new NotFoundError(`Conversation ${pathParams.id} not found`);
|
|
586
597
|
}
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
LatencyBreakdownSchema,
|
|
30
30
|
LLMRequestLogEntrySchema,
|
|
31
31
|
} from "../../api/responses/llm-request-log-entry.js";
|
|
32
|
+
import { scrubNulledAcpAgentLeaves } from "../../config/acp-agent-write.js";
|
|
32
33
|
import {
|
|
33
34
|
catalogEntryFor,
|
|
34
35
|
type InputModalities,
|
|
@@ -92,6 +93,7 @@ import {
|
|
|
92
93
|
log,
|
|
93
94
|
} from "../../daemon/handlers/shared.js";
|
|
94
95
|
import { rescheduleHeartbeatIfTimezoneChanged } from "../../heartbeat/heartbeat-service.js";
|
|
96
|
+
import { overlayWorkspaceMcpForConfigRead } from "../../mcp/workspace-mcp-config.js";
|
|
95
97
|
import {
|
|
96
98
|
getAssistantMessageIdsInTurn,
|
|
97
99
|
getConversation,
|
|
@@ -687,6 +689,38 @@ function rejectMcpTransportHeaderWrite(patch: unknown): void {
|
|
|
687
689
|
);
|
|
688
690
|
}
|
|
689
691
|
|
|
692
|
+
const MCP_CONFIG_WRITE_MESSAGE =
|
|
693
|
+
"MCP servers are stored in mcp.json. Use assistant mcp add or assistant mcp remove.";
|
|
694
|
+
|
|
695
|
+
function stripMcpFromConfigWrite(patch: Record<string, unknown>): void {
|
|
696
|
+
if (Object.hasOwn(patch, "mcp")) {
|
|
697
|
+
delete patch.mcp;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
function rejectMcpConfigSetPath(path: string, value: unknown): void {
|
|
702
|
+
if (path !== "mcp" && !path.startsWith("mcp.")) {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
const relative =
|
|
706
|
+
path === "mcp" ? value : nestPath(path.slice("mcp.".length), value);
|
|
707
|
+
if (patchContainsMcpTransportHeaders({ mcp: relative })) {
|
|
708
|
+
throw new BadRequestError(
|
|
709
|
+
"MCP authentication headers must be managed through MCP server add/update APIs, not generic config writes.",
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
throw new BadRequestError(MCP_CONFIG_WRITE_MESSAGE);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
function nestPath(path: string, value: unknown): unknown {
|
|
716
|
+
const segments = path.split(".");
|
|
717
|
+
let current: unknown = value;
|
|
718
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
719
|
+
current = { [segments[i]!]: current };
|
|
720
|
+
}
|
|
721
|
+
return current;
|
|
722
|
+
}
|
|
723
|
+
|
|
690
724
|
const WireProfileEntry = ProfileEntry.extend({
|
|
691
725
|
supportsVision: z.boolean().optional(),
|
|
692
726
|
invariant: z.boolean().optional(),
|
|
@@ -893,6 +927,7 @@ const ConfigPatchRequestSchema = z
|
|
|
893
927
|
function handleGetConfig() {
|
|
894
928
|
try {
|
|
895
929
|
const config = applyContextDefaultsToRawConfig(loadRawConfig());
|
|
930
|
+
overlayWorkspaceMcpForConfigRead(config);
|
|
896
931
|
sanitizeMcpTransportHeadersForSettingsRead(config);
|
|
897
932
|
overlayEffectiveProfilesForWire(config);
|
|
898
933
|
enrichProfilesForWire(config);
|
|
@@ -1594,6 +1629,7 @@ async function handlePatchConfig({ body }: RouteHandlerArgs) {
|
|
|
1594
1629
|
normalizeManagedProfileWrites(body);
|
|
1595
1630
|
rejectManagedProfileDeletion(body as Record<string, unknown>);
|
|
1596
1631
|
rejectMcpTransportHeaderWrite(body);
|
|
1632
|
+
stripMcpFromConfigWrite(body as Record<string, unknown>);
|
|
1597
1633
|
|
|
1598
1634
|
const raw = loadRawConfig();
|
|
1599
1635
|
const patch = body as Record<string, unknown>;
|
|
@@ -1603,11 +1639,13 @@ async function handlePatchConfig({ body }: RouteHandlerArgs) {
|
|
|
1603
1639
|
}
|
|
1604
1640
|
deepMergeOverwrite(raw, patch);
|
|
1605
1641
|
scrubRemovedServiceModes(raw);
|
|
1642
|
+
scrubNulledAcpAgentLeaves(raw);
|
|
1606
1643
|
seedSttProviderForSparseBlock(raw);
|
|
1607
1644
|
|
|
1608
1645
|
await commitConfigWrite(raw, "patch");
|
|
1609
1646
|
|
|
1610
1647
|
const merged = applyContextDefaultsToRawConfig(loadRawConfig());
|
|
1648
|
+
overlayWorkspaceMcpForConfigRead(merged);
|
|
1611
1649
|
sanitizeMcpTransportHeadersForSettingsRead(merged);
|
|
1612
1650
|
overlayEffectiveProfilesForWire(merged);
|
|
1613
1651
|
enrichProfilesForWire(merged);
|
|
@@ -1670,6 +1708,7 @@ async function handleSetConfig({ body }: RouteHandlerArgs) {
|
|
|
1670
1708
|
stripWireOnlyProfileKeys(patchShape);
|
|
1671
1709
|
normalizeManagedProfileWrites(patchShape);
|
|
1672
1710
|
rejectManagedProfileDeletion(patchShape);
|
|
1711
|
+
rejectMcpConfigSetPath(path, value);
|
|
1673
1712
|
rejectMcpTransportHeaderWrite(patchShape);
|
|
1674
1713
|
|
|
1675
1714
|
const raw = loadRawConfig();
|
|
@@ -1708,6 +1747,7 @@ async function handleSetConfig({ body }: RouteHandlerArgs) {
|
|
|
1708
1747
|
written.source = "managed";
|
|
1709
1748
|
}
|
|
1710
1749
|
}
|
|
1750
|
+
scrubNulledAcpAgentLeaves(raw);
|
|
1711
1751
|
// A SET can create `services.stt` with a leaf like `language` and no
|
|
1712
1752
|
// `provider`, which SttServiceSchema requires whenever the block exists;
|
|
1713
1753
|
// the same seeding that guards PATCH keeps this write's persisted block
|
|
@@ -140,7 +140,10 @@ import {
|
|
|
140
140
|
getOrCreateConversation,
|
|
141
141
|
} from "../../persistence/conversation-key-store.js";
|
|
142
142
|
import { searchConversations } from "../../persistence/conversation-queries.js";
|
|
143
|
-
import {
|
|
143
|
+
import {
|
|
144
|
+
isNoResponseMetadata,
|
|
145
|
+
messageMetadataIsAmbientSightKeep,
|
|
146
|
+
} from "../../persistence/conversation-types.js";
|
|
144
147
|
import { linkRequestLogsToMessage } from "../../persistence/llm-request-log-store.js";
|
|
145
148
|
import { assistantTextVisibilityOf } from "../../persistence/user-facing-content.js";
|
|
146
149
|
import { MEMORY_RETROSPECTIVE_FORK_SOURCE } from "../../plugins/defaults/memory/memory-retrospective-constants.js";
|
|
@@ -159,6 +162,7 @@ import {
|
|
|
159
162
|
getWorkspaceDir,
|
|
160
163
|
getWorkspacePromptPath,
|
|
161
164
|
} from "../../util/platform.js";
|
|
165
|
+
import { safeStringSlice } from "../../util/unicode.js";
|
|
162
166
|
import { assistantEventHub, broadcastMessage } from "../assistant-event-hub.js";
|
|
163
167
|
import { getCurrentSeq } from "../assistant-stream-state.js";
|
|
164
168
|
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
@@ -1037,6 +1041,9 @@ export async function handleListMessages({
|
|
|
1037
1041
|
let backgroundToolCompletion: ConversationMessage["backgroundToolCompletion"];
|
|
1038
1042
|
let systemCard: boolean | undefined;
|
|
1039
1043
|
let noResponse: boolean | undefined;
|
|
1044
|
+
const cameraFrame = messageMetadataIsAmbientSightKeep(msg.metadata)
|
|
1045
|
+
? true
|
|
1046
|
+
: undefined;
|
|
1040
1047
|
let reaction: ConversationMessage["reaction"];
|
|
1041
1048
|
let providerError: ConversationMessage["providerError"];
|
|
1042
1049
|
let deletedAt: number | undefined;
|
|
@@ -1136,6 +1143,7 @@ export async function handleListMessages({
|
|
|
1136
1143
|
backgroundToolCompletion,
|
|
1137
1144
|
systemCard,
|
|
1138
1145
|
noResponse,
|
|
1146
|
+
cameraFrame,
|
|
1139
1147
|
reaction,
|
|
1140
1148
|
providerError,
|
|
1141
1149
|
slackMessage,
|
|
@@ -1353,6 +1361,7 @@ export async function handleListMessages({
|
|
|
1353
1361
|
: {}),
|
|
1354
1362
|
...(m.systemCard ? { systemCard: true } : {}),
|
|
1355
1363
|
...(m.noResponse ? { noResponse: true } : {}),
|
|
1364
|
+
...(m.cameraFrame ? { cameraFrame: true as const } : {}),
|
|
1356
1365
|
// The row's own marker, so a client gates per-row presentation on what
|
|
1357
1366
|
// this row was written with rather than on the live flag.
|
|
1358
1367
|
...(m.assistantTextVisibility
|
|
@@ -3289,11 +3298,15 @@ async function generateLlmSuggestion(
|
|
|
3289
3298
|
): Promise<string | null> {
|
|
3290
3299
|
const log = (await import("../../util/logger.js")).getLogger("runtime-http");
|
|
3291
3300
|
const truncatedAssistant = escapeXmlContent(
|
|
3292
|
-
assistantText.length > 2000
|
|
3301
|
+
assistantText.length > 2000
|
|
3302
|
+
? safeStringSlice(assistantText, assistantText.length - 2000)
|
|
3303
|
+
: assistantText,
|
|
3293
3304
|
);
|
|
3294
3305
|
const truncatedUser =
|
|
3295
3306
|
priorUserText && priorUserText.length > 500
|
|
3296
|
-
? escapeXmlContent(
|
|
3307
|
+
? escapeXmlContent(
|
|
3308
|
+
safeStringSlice(priorUserText, priorUserText.length - 500),
|
|
3309
|
+
)
|
|
3297
3310
|
: priorUserText
|
|
3298
3311
|
? escapeXmlContent(priorUserText)
|
|
3299
3312
|
: priorUserText;
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
deleteCredentialMetadata,
|
|
44
44
|
getCredentialMetadata,
|
|
45
45
|
getCredentialMetadataById,
|
|
46
|
-
|
|
46
|
+
listCredentialRecordsLive,
|
|
47
47
|
} from "../../tools/credentials/metadata-store.js";
|
|
48
48
|
import type { CredentialInjectionTemplate } from "../../tools/credentials/policy-types.js";
|
|
49
49
|
import {
|
|
@@ -228,6 +228,9 @@ function assertNotPlatformManaged(
|
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
+
const CREDENTIAL_STORE_UNREACHABLE =
|
|
232
|
+
"Credential store is unreachable. Retry in a moment, or check that the credential vault is running.";
|
|
233
|
+
|
|
231
234
|
// ---------------------------------------------------------------------------
|
|
232
235
|
// Handlers
|
|
233
236
|
// ---------------------------------------------------------------------------
|
|
@@ -235,9 +238,14 @@ function assertNotPlatformManaged(
|
|
|
235
238
|
async function handleCredentialsList({ body }: RouteHandlerArgs) {
|
|
236
239
|
const search = (body as { search?: string } | undefined)?.search;
|
|
237
240
|
|
|
241
|
+
const live = await listCredentialRecordsLive();
|
|
242
|
+
if (live.unreachable) {
|
|
243
|
+
throw new InternalError(CREDENTIAL_STORE_UNREACHABLE);
|
|
244
|
+
}
|
|
245
|
+
|
|
238
246
|
// Platform-provisioned credentials are not the user's to act on, so they
|
|
239
247
|
// never become a Settings row (and never a click-to-reveal).
|
|
240
|
-
let allMetadata =
|
|
248
|
+
let allMetadata = live.records.filter(
|
|
241
249
|
(m) => !isPlatformManagedCredential(m.service, m.field),
|
|
242
250
|
);
|
|
243
251
|
|
|
@@ -272,7 +280,12 @@ async function handleCredentialsList({ body }: RouteHandlerArgs) {
|
|
|
272
280
|
|
|
273
281
|
const credentials = await Promise.all(
|
|
274
282
|
allMetadata.map(async (m) => {
|
|
275
|
-
const secret = await
|
|
283
|
+
const { value: secret, unreachable } = await getSecureKeyResultAsync(
|
|
284
|
+
credentialKey(m.service, m.field),
|
|
285
|
+
);
|
|
286
|
+
if (unreachable) {
|
|
287
|
+
throw new InternalError(CREDENTIAL_STORE_UNREACHABLE);
|
|
288
|
+
}
|
|
276
289
|
const connection = connectionsByProvider.get(m.service);
|
|
277
290
|
return buildCredentialOutput(m, secret, connection);
|
|
278
291
|
}),
|
|
@@ -310,9 +323,7 @@ async function handleCredentialsInspect({ body }: RouteHandlerArgs) {
|
|
|
310
323
|
|
|
311
324
|
if (!lookup.metadata && (secret == null || secret.length === 0)) {
|
|
312
325
|
if (unreachable) {
|
|
313
|
-
throw new InternalError(
|
|
314
|
-
"Credential store is unreachable — ensure the assistant is running",
|
|
315
|
-
);
|
|
326
|
+
throw new InternalError(CREDENTIAL_STORE_UNREACHABLE);
|
|
316
327
|
}
|
|
317
328
|
throw new BadRequestError("Credential not found");
|
|
318
329
|
}
|
|
@@ -374,9 +385,7 @@ async function handleCredentialsReveal({ body, headers }: RouteHandlerArgs) {
|
|
|
374
385
|
|
|
375
386
|
if (secret == null || secret.length === 0) {
|
|
376
387
|
if (unreachable) {
|
|
377
|
-
throw new InternalError(
|
|
378
|
-
"Credential store is unreachable — ensure the assistant is running",
|
|
379
|
-
);
|
|
388
|
+
throw new InternalError(CREDENTIAL_STORE_UNREACHABLE);
|
|
380
389
|
}
|
|
381
390
|
throw new BadRequestError("Credential not found");
|
|
382
391
|
}
|
|
@@ -620,7 +629,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
620
629
|
},
|
|
621
630
|
summary: "List all credentials with metadata",
|
|
622
631
|
description:
|
|
623
|
-
"Return
|
|
632
|
+
"Return credentials from the live credential vault, with OAuth connection info and platform-managed credentials. Fails if the vault is unreachable.",
|
|
624
633
|
tags: ["credentials"],
|
|
625
634
|
requestBody: z.object({
|
|
626
635
|
search: z.string().optional().describe("Filter by substring match"),
|