@vellumai/assistant 0.12.1 → 0.12.2-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 +4 -0
- package/ARCHITECTURE.md +20 -21
- package/docs/architecture/turn-actor.md +15 -8
- package/docs/guardian-request-flow.md +16 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +13 -8
- package/node_modules/@vellumai/slack-text/src/label-resolution-entities.test.ts +95 -0
- package/openapi.yaml +360 -51
- 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-runtime-assembly.test.ts +28 -0
- 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-point-at-budget.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-point-at-capability.test.ts +1 -0
- 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 +250 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -3
- package/src/__tests__/cu-unified-flow.test.ts +14 -4
- 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 +596 -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 +168 -0
- package/src/__tests__/oauth-provider-profiles.test.ts +18 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +22 -0
- package/src/__tests__/oauth-providers-routes.test.ts +1 -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__/secret-routes-acp-guard.test.ts +59 -1
- 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 +70 -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__/ui-channel-variants.test.ts +1 -56
- 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__/acp-claude-oauth.test.ts +257 -6
- package/src/acp/__tests__/acp-credentials.test.ts +13 -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__/claude-token-refresh.test.ts +257 -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__/prepare-agent-env.test.ts +60 -1
- 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/acp-claude-oauth.ts +328 -14
- package/src/acp/acp-credentials.ts +19 -0
- 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/claude-token-refresh.ts +150 -0
- 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/prepare-agent-env.ts +21 -6
- 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 +120 -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 +56 -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 +155 -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 +92 -72
- package/src/calls/voice-triage-escalate.ts +178 -59
- 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/oauth/status.ts +5 -0
- 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 +29 -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 +33 -13
- package/src/config/loader.ts +2 -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 +18 -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 +20 -7
- package/src/daemon/conversation-skill-tools.ts +13 -31
- package/src/daemon/conversation-store.ts +1 -1
- package/src/daemon/conversation-surfaces.ts +21 -10
- package/src/daemon/conversation-tool-setup.ts +45 -59
- 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 +224 -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-agent-turn.test.ts +121 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +8 -7
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +0 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +94 -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__/protocol.test.ts +39 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +13 -69
- package/src/live-voice/__tests__/session-controls.test.ts +79 -0
- package/src/live-voice/live-voice-photo.ts +25 -6
- package/src/live-voice/live-voice-session.ts +297 -699
- package/src/live-voice/protocol.ts +60 -2
- package/src/live-voice/session-controls.ts +111 -0
- 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 +149 -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 +100 -0
- package/src/oauth/connection-resolver.ts +120 -3
- package/src/oauth/provider-serializer.ts +9 -0
- package/src/oauth/scope-utils.ts +24 -0
- package/src/oauth/seed-providers.ts +314 -27
- 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-claude-auth-routes.test.ts +16 -5
- package/src/runtime/routes/__tests__/acp-routes.test.ts +159 -4
- package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +275 -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-claude-auth-routes.ts +11 -3
- 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 +90 -2
- 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 +20 -14
- 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 +50 -0
- package/src/runtime/routes/oauth-providers.ts +7 -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/ui-surface/channel-variants.ts +10 -59
- 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-retro.ts +6 -8
- 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
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { RiskLevel } from "../../permissions/types.js";
|
|
11
|
+
import { formatDesktopAppRequired } from "../capability-offer.js";
|
|
11
12
|
import type {
|
|
12
13
|
ToolContext,
|
|
13
14
|
ToolDefinition,
|
|
@@ -31,7 +32,7 @@ function proxyExecute(toolName: string) {
|
|
|
31
32
|
): Promise<ToolExecutionResult> => {
|
|
32
33
|
if (!context.proxyToolResolver) {
|
|
33
34
|
return {
|
|
34
|
-
content:
|
|
35
|
+
content: formatDesktopAppRequired("screen"),
|
|
35
36
|
isError: true,
|
|
36
37
|
};
|
|
37
38
|
}
|
|
@@ -381,6 +382,112 @@ export const computerUseRunAppleScriptTool = {
|
|
|
381
382
|
execute: proxyExecute("computer_use_run_applescript"),
|
|
382
383
|
} satisfies ToolDefinition;
|
|
383
384
|
|
|
385
|
+
// ---------------------------------------------------------------------------
|
|
386
|
+
// sequence
|
|
387
|
+
// ---------------------------------------------------------------------------
|
|
388
|
+
|
|
389
|
+
export const computerUseSequenceTool = {
|
|
390
|
+
name: "computer_use_sequence",
|
|
391
|
+
description:
|
|
392
|
+
"Run several computer-use actions you already know, in order, in one step, for example open an app, press cmd+n, type a URL and press enter. Use it when no action depends on seeing the result of the one before; otherwise act one step at a time. Element IDs refer to the latest observation, so use them only for actions that act before the screen changes. Stops at the first action that is refused or fails and reports which one. Returns one observation after the last action.",
|
|
393
|
+
category: "computer-use",
|
|
394
|
+
defaultRiskLevel: RiskLevel.Low,
|
|
395
|
+
executionTarget: "host",
|
|
396
|
+
supportedClientOs: ["macos"],
|
|
397
|
+
|
|
398
|
+
input_schema: {
|
|
399
|
+
type: "object",
|
|
400
|
+
properties: {
|
|
401
|
+
actions: {
|
|
402
|
+
type: "array",
|
|
403
|
+
minItems: 1,
|
|
404
|
+
maxItems: 10,
|
|
405
|
+
description: "The actions to run, in order",
|
|
406
|
+
items: {
|
|
407
|
+
type: "object",
|
|
408
|
+
properties: {
|
|
409
|
+
action: {
|
|
410
|
+
type: "string",
|
|
411
|
+
enum: [
|
|
412
|
+
"key",
|
|
413
|
+
"type_text",
|
|
414
|
+
"type",
|
|
415
|
+
"click",
|
|
416
|
+
"double_click",
|
|
417
|
+
"right_click",
|
|
418
|
+
"scroll",
|
|
419
|
+
"wait",
|
|
420
|
+
"open_app",
|
|
421
|
+
],
|
|
422
|
+
description: "The action to run",
|
|
423
|
+
},
|
|
424
|
+
key: {
|
|
425
|
+
type: "string",
|
|
426
|
+
description:
|
|
427
|
+
"key: key or shortcut to press (e.g. enter, tab, cmd+n)",
|
|
428
|
+
},
|
|
429
|
+
text: {
|
|
430
|
+
type: "string",
|
|
431
|
+
description: "type_text (or type): the text to type",
|
|
432
|
+
},
|
|
433
|
+
element_id: {
|
|
434
|
+
type: "integer",
|
|
435
|
+
description:
|
|
436
|
+
"click, double_click, right_click, scroll: the [ID] of the element from the latest accessibility tree (preferred)",
|
|
437
|
+
},
|
|
438
|
+
x: {
|
|
439
|
+
type: "integer",
|
|
440
|
+
description:
|
|
441
|
+
"click, double_click, right_click, scroll: X coordinate on screen (fallback when no element_id)",
|
|
442
|
+
},
|
|
443
|
+
y: {
|
|
444
|
+
type: "integer",
|
|
445
|
+
description:
|
|
446
|
+
"click, double_click, right_click, scroll: Y coordinate on screen (fallback when no element_id)",
|
|
447
|
+
},
|
|
448
|
+
direction: {
|
|
449
|
+
type: "string",
|
|
450
|
+
enum: ["up", "down", "left", "right"],
|
|
451
|
+
description: "scroll: scroll direction",
|
|
452
|
+
},
|
|
453
|
+
amount: {
|
|
454
|
+
type: "integer",
|
|
455
|
+
description: "scroll: scroll amount (1-10)",
|
|
456
|
+
},
|
|
457
|
+
duration_ms: {
|
|
458
|
+
type: "integer",
|
|
459
|
+
description: "wait: milliseconds to wait",
|
|
460
|
+
},
|
|
461
|
+
app_name: {
|
|
462
|
+
type: "string",
|
|
463
|
+
description:
|
|
464
|
+
'open_app: the name of the application to open (e.g. "Google Chrome")',
|
|
465
|
+
},
|
|
466
|
+
reasoning: {
|
|
467
|
+
type: "string",
|
|
468
|
+
description: "Optional: why this action",
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
required: ["action"],
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
reasoning: {
|
|
475
|
+
type: "string",
|
|
476
|
+
description:
|
|
477
|
+
"Optional: what these actions do together. Reasoning on each action works too",
|
|
478
|
+
},
|
|
479
|
+
target_client_id: {
|
|
480
|
+
type: "string",
|
|
481
|
+
description:
|
|
482
|
+
"ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`.",
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
required: ["actions"],
|
|
486
|
+
},
|
|
487
|
+
|
|
488
|
+
execute: proxyExecute("computer_use_sequence"),
|
|
489
|
+
} satisfies ToolDefinition;
|
|
490
|
+
|
|
384
491
|
// ---------------------------------------------------------------------------
|
|
385
492
|
// done
|
|
386
493
|
// ---------------------------------------------------------------------------
|
|
@@ -456,7 +563,18 @@ export const computerUseObserveTool = {
|
|
|
456
563
|
type: "integer",
|
|
457
564
|
minimum: 1,
|
|
458
565
|
maximum: 4294967295,
|
|
459
|
-
description:
|
|
566
|
+
description:
|
|
567
|
+
"macOS only: capture this native CGWindowID instead of the desktop, including only its accessibility tree. Obtain a current native window ID first; do not guess or use a browser tab ID. Applies to this observation only, not subsequent actions. Requires a desktop helper with window-capture support. Screenshot coordinates are window-relative; use accessibility element IDs for later actions, not desktop scaling.",
|
|
568
|
+
},
|
|
569
|
+
include_screenshot: {
|
|
570
|
+
type: "boolean",
|
|
571
|
+
description:
|
|
572
|
+
"Force a screenshot with this observation. The accessibility tree is returned every step and actions always return a screenshot of their result; ask for pixels on an observation whenever the tree is not enough to act on, such as a canvas, a game, a custom-drawn view, a window with few or unlabeled controls, or a question about layout.",
|
|
573
|
+
},
|
|
574
|
+
full_tree: {
|
|
575
|
+
type: "boolean",
|
|
576
|
+
description:
|
|
577
|
+
"Walk the accessibility tree to full depth. Observations list the tree to a limited depth and say when it was cut off; pass this when the element you need is not in the tree.",
|
|
460
578
|
},
|
|
461
579
|
target_client_id: {
|
|
462
580
|
type: "string",
|
|
@@ -484,6 +602,7 @@ export const allComputerUseTools: ToolDefinition[] = [
|
|
|
484
602
|
computerUseWaitTool,
|
|
485
603
|
computerUseOpenAppTool,
|
|
486
604
|
computerUseRunAppleScriptTool,
|
|
605
|
+
computerUseSequenceTool,
|
|
487
606
|
computerUseDoneTool,
|
|
488
607
|
computerUseRespondTool,
|
|
489
608
|
];
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* the proxy resolver, which forwards the call to the connected desktop client.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { formatDesktopAppRequired } from "../capability-offer.js";
|
|
8
9
|
import { throwIfCancelled } from "../shared/abort.js";
|
|
9
10
|
import type { ToolContext, ToolExecutionResult } from "../types.js";
|
|
10
11
|
|
|
@@ -45,7 +46,7 @@ export function forwardComputerUseProxyTool(
|
|
|
45
46
|
}
|
|
46
47
|
if (!context.proxyToolResolver) {
|
|
47
48
|
return Promise.resolve({
|
|
48
|
-
content:
|
|
49
|
+
content: formatDesktopAppRequired("screen"),
|
|
49
50
|
isError: true,
|
|
50
51
|
});
|
|
51
52
|
}
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from "@vellumai/credential-storage";
|
|
21
21
|
import type { CredentialRecord } from "@vellumai/service-contracts/credential-rpc";
|
|
22
22
|
|
|
23
|
+
import { createCesHttpRecordBackendIfConfigured } from "../../security/ces-http-record-backend.js";
|
|
23
24
|
import type { CredentialRecordBackend } from "../../security/ces-rpc-record-backend.js";
|
|
24
25
|
import { getLogger } from "../../util/logger.js";
|
|
25
26
|
import type { CredentialInjectionTemplate } from "./policy-types.js";
|
|
@@ -55,6 +56,11 @@ const CES_MEMORY_PATH = "ces-in-memory-credential-metadata";
|
|
|
55
56
|
let _store: StaticCredentialMetadataStore | undefined;
|
|
56
57
|
let _overridePath: string | null = null;
|
|
57
58
|
let _recordBackend: CredentialRecordBackend | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Test override for the CES HTTP listing fallback. `undefined` uses the
|
|
61
|
+
* production factory. `null` disables HTTP fallback.
|
|
62
|
+
*/
|
|
63
|
+
let _httpRecordBackendOverride: CredentialRecordBackend | null | undefined;
|
|
58
64
|
let _cesRecordsLoaded = false;
|
|
59
65
|
let _cesLoad: Promise<void> | undefined;
|
|
60
66
|
let _cesLoadGeneration = 0;
|
|
@@ -255,6 +261,93 @@ export function listCredentialMetadata(): CredentialMetadata[] {
|
|
|
255
261
|
return getStore().list() as CredentialMetadata[];
|
|
256
262
|
}
|
|
257
263
|
|
|
264
|
+
export type CredentialRecordListResult = {
|
|
265
|
+
records: CredentialMetadata[];
|
|
266
|
+
unreachable: boolean;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
type ListedCredentialRecords = Array<{
|
|
270
|
+
account: string;
|
|
271
|
+
record: CredentialRecord;
|
|
272
|
+
}>;
|
|
273
|
+
|
|
274
|
+
function backendIsAvailable(backend: CredentialRecordBackend): boolean {
|
|
275
|
+
try {
|
|
276
|
+
return backend.isAvailable();
|
|
277
|
+
} catch {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async function listFromRecordBackend(
|
|
283
|
+
backend: CredentialRecordBackend,
|
|
284
|
+
): Promise<ListedCredentialRecords | null> {
|
|
285
|
+
if (!backendIsAvailable(backend)) {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
return backend.list();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function resolveHttpRecordBackend(): CredentialRecordBackend | null {
|
|
292
|
+
if (_httpRecordBackendOverride !== undefined) {
|
|
293
|
+
return _httpRecordBackendOverride;
|
|
294
|
+
}
|
|
295
|
+
return createCesHttpRecordBackendIfConfigured();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async function listFromHttpFallback(): Promise<ListedCredentialRecords | null> {
|
|
299
|
+
const httpBackend = resolveHttpRecordBackend();
|
|
300
|
+
if (!httpBackend) {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
return listFromRecordBackend(httpBackend);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Live catalog from the credential record backend. Does not read the
|
|
308
|
+
* daemon in-process cache, so an outage cannot be mistaken for an empty
|
|
309
|
+
* vault. `unreachable` is true when the backend is missing, down, or
|
|
310
|
+
* the list RPC fails, and CES HTTP failover is also unavailable.
|
|
311
|
+
*
|
|
312
|
+
* When the attached backend is CES RPC (or none is attached), listing
|
|
313
|
+
* fails over to CES HTTP in containerized deployments so a down RPC
|
|
314
|
+
* socket does not hide a healthy vault sidecar. A successful empty
|
|
315
|
+
* catalog (`[]`) does not fall through to HTTP.
|
|
316
|
+
*
|
|
317
|
+
* The file-backed test store is the catalog when a test override path is set.
|
|
318
|
+
*/
|
|
319
|
+
export async function listCredentialRecordsLive(): Promise<CredentialRecordListResult> {
|
|
320
|
+
if (_overridePath) {
|
|
321
|
+
return {
|
|
322
|
+
records: getStore().list() as CredentialMetadata[],
|
|
323
|
+
unreachable: false,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
if (_recordBackend) {
|
|
327
|
+
const remote = await listFromRecordBackend(_recordBackend);
|
|
328
|
+
if (remote !== null) {
|
|
329
|
+
return {
|
|
330
|
+
records: remote.map((entry) => entry.record as CredentialMetadata),
|
|
331
|
+
unreachable: false,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (_recordBackend.name !== "ces-rpc") {
|
|
335
|
+
return { records: [], unreachable: true };
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
const httpRemote = await listFromHttpFallback();
|
|
339
|
+
if (httpRemote !== null) {
|
|
340
|
+
log.warn(
|
|
341
|
+
"CES RPC credential record list unavailable. Failing over to CES HTTP.",
|
|
342
|
+
);
|
|
343
|
+
return {
|
|
344
|
+
records: httpRemote.map((entry) => entry.record as CredentialMetadata),
|
|
345
|
+
unreachable: false,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
return { records: [], unreachable: true };
|
|
349
|
+
}
|
|
350
|
+
|
|
258
351
|
/**
|
|
259
352
|
* Delete metadata for a credential.
|
|
260
353
|
*/
|
|
@@ -287,3 +380,10 @@ export function _setMetadataPath(path: string | null): void {
|
|
|
287
380
|
}
|
|
288
381
|
}
|
|
289
382
|
}
|
|
383
|
+
|
|
384
|
+
/** @internal Test-only: override the CES HTTP listing fallback. */
|
|
385
|
+
export function _setHttpRecordBackendForTests(
|
|
386
|
+
backend: CredentialRecordBackend | null | undefined,
|
|
387
|
+
): void {
|
|
388
|
+
_httpRecordBackendOverride = backend;
|
|
389
|
+
}
|
|
@@ -5,6 +5,7 @@ import { minimatch } from "minimatch";
|
|
|
5
5
|
import { RE2JS } from "re2js";
|
|
6
6
|
|
|
7
7
|
import { RiskLevel } from "../../permissions/types.js";
|
|
8
|
+
import { safeStringSlice } from "../../util/unicode.js";
|
|
8
9
|
import { declareDaemonActivityField } from "../schema-transforms.js";
|
|
9
10
|
import {
|
|
10
11
|
isDeniedBasename,
|
|
@@ -246,7 +247,7 @@ export const codeSearchTool = {
|
|
|
246
247
|
// emitting a multi-megabyte output line. Normal lines pass through verbatim.
|
|
247
248
|
const truncateForDisplay = (text: string): string =>
|
|
248
249
|
text.length > MAX_DISPLAY_LINE_LENGTH
|
|
249
|
-
? `${text
|
|
250
|
+
? `${safeStringSlice(text, 0, MAX_DISPLAY_LINE_LENGTH)} …[line truncated]`
|
|
250
251
|
: text;
|
|
251
252
|
|
|
252
253
|
// Append an output line, tracking its byte cost. Returns false once the
|
|
@@ -71,8 +71,9 @@ describe("host_file_edit cross-client guards", () => {
|
|
|
71
71
|
);
|
|
72
72
|
expect(result.isError).toBe(true);
|
|
73
73
|
expect(result.content).toContain(
|
|
74
|
-
"
|
|
74
|
+
"The Vellum desktop app is needed to access files on your computer",
|
|
75
75
|
);
|
|
76
|
+
expect(result.content).toContain("https://www.vellum.ai/downloads");
|
|
76
77
|
});
|
|
77
78
|
|
|
78
79
|
test("returns 'specified client disconnected' error when targetClientId set but proxy unavailable on web", async () => {
|
|
@@ -4,7 +4,7 @@ import { supportsHostProxy } from "../../channels/types.js";
|
|
|
4
4
|
import { HostFileProxy } from "../../daemon/host-file-proxy.js";
|
|
5
5
|
import { RiskLevel } from "../../permissions/types.js";
|
|
6
6
|
import { assistantEventHub } from "../../runtime/assistant-event-hub.js";
|
|
7
|
-
import {
|
|
7
|
+
import { formatDesktopAppRequired } from "../capability-offer.js";
|
|
8
8
|
import { FileSystemOps } from "../shared/filesystem/file-ops-service.js";
|
|
9
9
|
import { formatEditDiff } from "../shared/filesystem/format-diff.js";
|
|
10
10
|
import { hostPolicy } from "../shared/filesystem/path-policy.js";
|
|
@@ -115,7 +115,7 @@ export const hostFileEditTool = {
|
|
|
115
115
|
!HostFileProxy.instance.isAvailable()
|
|
116
116
|
) {
|
|
117
117
|
return {
|
|
118
|
-
content:
|
|
118
|
+
content: formatDesktopAppRequired("files"),
|
|
119
119
|
isError: true,
|
|
120
120
|
};
|
|
121
121
|
}
|
|
@@ -67,8 +67,9 @@ describe("host_file_read cross-client guards", () => {
|
|
|
67
67
|
);
|
|
68
68
|
expect(result.isError).toBe(true);
|
|
69
69
|
expect(result.content).toContain(
|
|
70
|
-
"
|
|
70
|
+
"The Vellum desktop app is needed to access files on your computer",
|
|
71
71
|
);
|
|
72
|
+
expect(result.content).toContain("https://www.vellum.ai/downloads");
|
|
72
73
|
});
|
|
73
74
|
|
|
74
75
|
test("returns 'specified client disconnected' error when targetClientId set but proxy unavailable on web", async () => {
|
|
@@ -6,7 +6,7 @@ import { supportsHostProxy } from "../../channels/types.js";
|
|
|
6
6
|
import { HostFileProxy } from "../../daemon/host-file-proxy.js";
|
|
7
7
|
import { RiskLevel } from "../../permissions/types.js";
|
|
8
8
|
import { assistantEventHub } from "../../runtime/assistant-event-hub.js";
|
|
9
|
-
import {
|
|
9
|
+
import { formatDesktopAppRequired } from "../capability-offer.js";
|
|
10
10
|
import {
|
|
11
11
|
AUDIO_EXTENSIONS,
|
|
12
12
|
readAudioFile,
|
|
@@ -121,7 +121,7 @@ export const hostFileReadTool = {
|
|
|
121
121
|
!HostFileProxy.instance.isAvailable()
|
|
122
122
|
) {
|
|
123
123
|
return {
|
|
124
|
-
content:
|
|
124
|
+
content: formatDesktopAppRequired("files"),
|
|
125
125
|
isError: true,
|
|
126
126
|
};
|
|
127
127
|
}
|
|
@@ -335,8 +335,9 @@ describe("host_file_transfer cross-client guards", () => {
|
|
|
335
335
|
|
|
336
336
|
expect(result.isError).toBe(true);
|
|
337
337
|
expect(result.content).toContain(
|
|
338
|
-
"
|
|
338
|
+
"The Vellum desktop app is needed to access files on your computer",
|
|
339
339
|
);
|
|
340
|
+
expect(result.content).toContain("https://www.vellum.ai/downloads");
|
|
340
341
|
expect(toSandboxCalls.length).toBe(0);
|
|
341
342
|
});
|
|
342
343
|
|
|
@@ -6,7 +6,7 @@ import { supportsHostProxy } from "../../channels/types.js";
|
|
|
6
6
|
import { HostTransferProxy } from "../../daemon/host-transfer-proxy.js";
|
|
7
7
|
import { RiskLevel } from "../../permissions/types.js";
|
|
8
8
|
import { assistantEventHub } from "../../runtime/assistant-event-hub.js";
|
|
9
|
-
import {
|
|
9
|
+
import { formatDesktopAppRequired } from "../capability-offer.js";
|
|
10
10
|
import { declareDaemonActivityField } from "../schema-transforms.js";
|
|
11
11
|
import { sandboxPolicy } from "../shared/filesystem/path-policy.js";
|
|
12
12
|
import type {
|
|
@@ -126,7 +126,7 @@ export const hostFileTransferTool = {
|
|
|
126
126
|
!HostTransferProxy.instance.isAvailable()
|
|
127
127
|
) {
|
|
128
128
|
return {
|
|
129
|
-
content:
|
|
129
|
+
content: formatDesktopAppRequired("files"),
|
|
130
130
|
isError: true,
|
|
131
131
|
};
|
|
132
132
|
}
|
|
@@ -67,8 +67,9 @@ describe("host_file_write cross-client guards", () => {
|
|
|
67
67
|
);
|
|
68
68
|
expect(result.isError).toBe(true);
|
|
69
69
|
expect(result.content).toContain(
|
|
70
|
-
"
|
|
70
|
+
"The Vellum desktop app is needed to access files on your computer",
|
|
71
71
|
);
|
|
72
|
+
expect(result.content).toContain("https://www.vellum.ai/downloads");
|
|
72
73
|
});
|
|
73
74
|
|
|
74
75
|
test("returns 'specified client disconnected' error when targetClientId set but proxy unavailable on web", async () => {
|
|
@@ -4,7 +4,7 @@ import { supportsHostProxy } from "../../channels/types.js";
|
|
|
4
4
|
import { HostFileProxy } from "../../daemon/host-file-proxy.js";
|
|
5
5
|
import { RiskLevel } from "../../permissions/types.js";
|
|
6
6
|
import { assistantEventHub } from "../../runtime/assistant-event-hub.js";
|
|
7
|
-
import {
|
|
7
|
+
import { formatDesktopAppRequired } from "../capability-offer.js";
|
|
8
8
|
import { FileSystemOps } from "../shared/filesystem/file-ops-service.js";
|
|
9
9
|
import { formatWriteSummary } from "../shared/filesystem/format-diff.js";
|
|
10
10
|
import { hostPolicy } from "../shared/filesystem/path-policy.js";
|
|
@@ -90,7 +90,7 @@ export const hostFileWriteTool = {
|
|
|
90
90
|
!HostFileProxy.instance.isAvailable()
|
|
91
91
|
) {
|
|
92
92
|
return {
|
|
93
|
-
content:
|
|
93
|
+
content: formatDesktopAppRequired("files"),
|
|
94
94
|
isError: true,
|
|
95
95
|
};
|
|
96
96
|
}
|
|
@@ -170,6 +170,22 @@ afterEach(() => {
|
|
|
170
170
|
mockProxyAvailable = false;
|
|
171
171
|
});
|
|
172
172
|
|
|
173
|
+
describe("host_bash unavailable desktop-app recovery", () => {
|
|
174
|
+
test("offers the desktop app download when a web turn has no host connection", async () => {
|
|
175
|
+
const result = await hostShellTool.execute(
|
|
176
|
+
{ command: "pwd" },
|
|
177
|
+
makeContext({ transportInterface: "web" }),
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
expect(result.isError).toBe(true);
|
|
181
|
+
expect(result.content).toContain(
|
|
182
|
+
"The Vellum desktop app is needed to run commands on your computer",
|
|
183
|
+
);
|
|
184
|
+
expect(result.content).toContain("https://www.vellum.ai/downloads");
|
|
185
|
+
expect(result.content).toContain("Open it, then retry.");
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
173
189
|
// ---------------------------------------------------------------------------
|
|
174
190
|
// Proxy path — background: true
|
|
175
191
|
// ---------------------------------------------------------------------------
|
|
@@ -18,10 +18,7 @@ import { getConfig } from "../../config/loader.js";
|
|
|
18
18
|
import { HostBashProxy } from "../../daemon/host-bash-proxy.js";
|
|
19
19
|
import { RiskLevel } from "../../permissions/types.js";
|
|
20
20
|
import { wakeAgentForOpportunity } from "../../runtime/agent-wake.js";
|
|
21
|
-
import {
|
|
22
|
-
assistantEventHub,
|
|
23
|
-
broadcastMessage,
|
|
24
|
-
} from "../../runtime/assistant-event-hub.js";
|
|
21
|
+
import { broadcastMessage } from "../../runtime/assistant-event-hub.js";
|
|
25
22
|
import { conversationRevealNonce } from "../../runtime/reveal-nonce.js";
|
|
26
23
|
import { redactSecrets } from "../../security/secret-scanner.js";
|
|
27
24
|
import {
|
|
@@ -39,7 +36,7 @@ import {
|
|
|
39
36
|
registerBackgroundTool,
|
|
40
37
|
removeBackgroundTool,
|
|
41
38
|
} from "../background-tool-registry.js";
|
|
42
|
-
import {
|
|
39
|
+
import { formatDesktopAppRequired } from "../capability-offer.js";
|
|
43
40
|
import {
|
|
44
41
|
attachBoundedStdio,
|
|
45
42
|
MAX_OUTPUT_LENGTH,
|
|
@@ -142,7 +139,7 @@ export const hostShellInputSchema = z.looseObject({
|
|
|
142
139
|
target_client_id: z
|
|
143
140
|
.string()
|
|
144
141
|
.describe(
|
|
145
|
-
"ID of the specific client to execute this command on.
|
|
142
|
+
"Optional ID of the specific client to execute this command on. Without it, the most recently active eligible client is used. Obtain IDs from `assistant clients list --capability host_bash`.",
|
|
146
143
|
)
|
|
147
144
|
.optional()
|
|
148
145
|
.catch(undefined),
|
|
@@ -203,20 +200,7 @@ export const hostShellTool = {
|
|
|
203
200
|
const config = getConfig();
|
|
204
201
|
const { shellDefaultTimeoutSec, shellMaxTimeoutSec } = config.timeouts;
|
|
205
202
|
|
|
206
|
-
// Guard: non-host-proxy interfaces need an explicit target when multiple
|
|
207
|
-
// capable clients are connected to avoid ambiguous untargeted broadcasts.
|
|
208
203
|
const transportInterface = context.transportInterface;
|
|
209
|
-
if (
|
|
210
|
-
targetClientId == null &&
|
|
211
|
-
transportInterface != null &&
|
|
212
|
-
!supportsHostProxy(transportInterface) &&
|
|
213
|
-
assistantEventHub.listClientsByCapability("host_bash").length > 1
|
|
214
|
-
) {
|
|
215
|
-
return {
|
|
216
|
-
content: `Error: multiple clients support host_bash. Specify which client to use with \`target_client_id\`. Run \`assistant clients list --capability host_bash\` to see client IDs and labels.`,
|
|
217
|
-
isError: true,
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
204
|
|
|
221
205
|
// Guard: non-host-proxy interfaces with no capable clients connected.
|
|
222
206
|
if (
|
|
@@ -226,7 +210,7 @@ export const hostShellTool = {
|
|
|
226
210
|
!HostBashProxy.instance.isAvailable()
|
|
227
211
|
) {
|
|
228
212
|
return {
|
|
229
|
-
content:
|
|
213
|
+
content: formatDesktopAppRequired("shell"),
|
|
230
214
|
isError: true,
|
|
231
215
|
};
|
|
232
216
|
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
getHttpRetryDelay,
|
|
16
16
|
sleep,
|
|
17
17
|
} from "../../util/retry.js";
|
|
18
|
+
import { safeStringSlice } from "../../util/unicode.js";
|
|
18
19
|
import type {
|
|
19
20
|
ToolContext,
|
|
20
21
|
ToolDefinition,
|
|
@@ -509,7 +510,11 @@ const KEENABLE_SNIPPET_MAX_LENGTH = 500;
|
|
|
509
510
|
* present rather than nullish. */
|
|
510
511
|
function keenableSnippet(result: KeenableSearchResult): string {
|
|
511
512
|
const text = result.snippet || result.description || "";
|
|
512
|
-
return
|
|
513
|
+
return safeStringSlice(
|
|
514
|
+
text.replace(/\s+/g, " ").trim(),
|
|
515
|
+
0,
|
|
516
|
+
KEENABLE_SNIPPET_MAX_LENGTH,
|
|
517
|
+
);
|
|
513
518
|
}
|
|
514
519
|
|
|
515
520
|
function formatKeenableResults(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getConfig } from "../config/loader.js";
|
|
2
|
-
import {
|
|
2
|
+
import { isSkillImprovementActive } from "../config/memory-v3-gate.js";
|
|
3
3
|
import type { ExecutionContext } from "../permissions/approval-policy.js";
|
|
4
4
|
import type { ChannelPermissionCoordinates } from "../permissions/channel-permission-query.js";
|
|
5
5
|
import type { PolicyContext } from "../permissions/types.js";
|
|
@@ -63,12 +63,11 @@ export function buildPolicyContext(
|
|
|
63
63
|
requestOrigin: context?.requestOrigin,
|
|
64
64
|
...channelCoordinatesFromToolContext(context),
|
|
65
65
|
requesterContactId: context?.requesterContactId,
|
|
66
|
-
// Precompute the
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
procToSkillsActive: isV3TierActive(getConfig()),
|
|
66
|
+
// Precompute the retrospective skill-improvement gate here so the
|
|
67
|
+
// permission checker, a leaf module that must not read config, can deny
|
|
68
|
+
// the memory-retrospective skill-authoring grant whenever the feature is
|
|
69
|
+
// inactive just by reading this boolean.
|
|
70
|
+
procToSkillsActive: isSkillImprovementActive(getConfig()),
|
|
72
71
|
};
|
|
73
72
|
|
|
74
73
|
const ownerKind = getToolOwner(tool.name)?.kind;
|