@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
|
@@ -55,6 +55,7 @@ import {
|
|
|
55
55
|
isActivationMomentParam,
|
|
56
56
|
} from "../telemetry/activation-funnel.js";
|
|
57
57
|
import { resolveAppId } from "../tools/apps/resolve-app-id.js";
|
|
58
|
+
import { formatDesktopAppRequired } from "../tools/capability-offer.js";
|
|
58
59
|
import { POINT_AT_PROXY_TOOL } from "../tools/computer-use/skill-proxy-bridge.js";
|
|
59
60
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
60
61
|
import { getLogger } from "../util/logger.js";
|
|
@@ -100,6 +101,7 @@ export {
|
|
|
100
101
|
type SurfaceShowPair,
|
|
101
102
|
type SurfaceStateEntry,
|
|
102
103
|
} from "./conversation-surface-state.js";
|
|
104
|
+
import { safeStringSlice } from "../util/unicode.js";
|
|
103
105
|
import type { HostAppControlInput } from "./message-types/host-app-control.js";
|
|
104
106
|
import type { UserMessageAttachment } from "./message-types/shared.js";
|
|
105
107
|
|
|
@@ -1486,7 +1488,10 @@ function handleDocumentContentChanged(
|
|
|
1486
1488
|
updateApp(appId, {
|
|
1487
1489
|
name: title || app.name,
|
|
1488
1490
|
description: `Document with ${wordCount ?? 0} words`,
|
|
1489
|
-
preview:
|
|
1491
|
+
preview:
|
|
1492
|
+
content === undefined
|
|
1493
|
+
? undefined
|
|
1494
|
+
: safeStringSlice(content, 0, 200),
|
|
1490
1495
|
htmlDefinition: updatedHtml,
|
|
1491
1496
|
});
|
|
1492
1497
|
|
|
@@ -2936,7 +2941,7 @@ export function buildAppOpenPreview(
|
|
|
2936
2941
|
function describeComputerUseUnavailable(ctx: Conversation): string {
|
|
2937
2942
|
const capable = assistantEventHub.listClientsByCapability("host_cu");
|
|
2938
2943
|
if (capable.length === 0) {
|
|
2939
|
-
return "
|
|
2944
|
+
return formatDesktopAppRequired("screen");
|
|
2940
2945
|
}
|
|
2941
2946
|
return `Computer use is not available for this conversation — ${capable.length} desktop client(s) advertise host_cu, but none of them can be driven from this conversation's interface (${ctx.transportInterface ?? "unknown"}) as its current user.`;
|
|
2942
2947
|
}
|
|
@@ -3175,7 +3180,7 @@ export async function surfaceProxyResolver(
|
|
|
3175
3180
|
: typeof input.answer === "string"
|
|
3176
3181
|
? input.answer
|
|
3177
3182
|
: "Task complete";
|
|
3178
|
-
hostCuProxy.
|
|
3183
|
+
hostCuProxy.endTask(ctx.conversationId);
|
|
3179
3184
|
return { content: summary, isError: false };
|
|
3180
3185
|
}
|
|
3181
3186
|
|
|
@@ -3251,8 +3256,7 @@ export async function surfaceProxyResolver(
|
|
|
3251
3256
|
|
|
3252
3257
|
if (!ctx.hostAppControlProxy || !ctx.hostAppControlProxy.isAvailable()) {
|
|
3253
3258
|
return {
|
|
3254
|
-
content:
|
|
3255
|
-
"App control is not available — enable the `app-control` feature flag and connect a macOS client.",
|
|
3259
|
+
content: formatDesktopAppRequired("apps"),
|
|
3256
3260
|
isError: true,
|
|
3257
3261
|
};
|
|
3258
3262
|
}
|
|
@@ -3342,8 +3346,14 @@ export async function surfaceProxyResolver(
|
|
|
3342
3346
|
|
|
3343
3347
|
if (toolName === "ui_show" || toolName === "ui_update") {
|
|
3344
3348
|
const caps = ctx.channelCapabilities;
|
|
3349
|
+
// Live non-dynamic channels reject unsupported surfaces. Clientless turns
|
|
3350
|
+
// skip this gate so surfaces persist for a later capable client.
|
|
3351
|
+
// `canShowInteractiveUi` fails closed on clientless turns because
|
|
3352
|
+
// standalone surfaces have nobody to answer them, so it is not the
|
|
3353
|
+
// predicate here.
|
|
3345
3354
|
if (
|
|
3346
3355
|
caps &&
|
|
3356
|
+
!ctx.hasNoClient &&
|
|
3347
3357
|
!caps.supportsDynamicUi &&
|
|
3348
3358
|
!isSlackTaskProgressUiException(ctx, toolName, input)
|
|
3349
3359
|
) {
|
|
@@ -3552,11 +3562,12 @@ export async function surfaceProxyResolver(
|
|
|
3552
3562
|
: surfaceType === "table"
|
|
3553
3563
|
? hasActions
|
|
3554
3564
|
: INTERACTIVE_SURFACE_TYPES.includes(surfaceType);
|
|
3555
|
-
//
|
|
3556
|
-
// actionless surface has nothing to await
|
|
3557
|
-
const awaitAction =
|
|
3558
|
-
|
|
3559
|
-
|
|
3565
|
+
// Background turns persist surfaces for a later conversation open and
|
|
3566
|
+
// return immediately. An actionless surface also has nothing to await.
|
|
3567
|
+
const awaitAction =
|
|
3568
|
+
!ctx.hasNoClient &&
|
|
3569
|
+
!isActionless &&
|
|
3570
|
+
((input.await_action as boolean) ?? isInteractive);
|
|
3560
3571
|
|
|
3561
3572
|
// Only one non-persistent interactive surface at a time. If another
|
|
3562
3573
|
// surface is already awaiting user input, reject this one so the LLM
|
|
@@ -28,7 +28,6 @@ import { getAllDefaultPluginNames } from "../plugins/defaults/main.js";
|
|
|
28
28
|
import { isActivationSession } from "../plugins/defaults/memory/activation-session-store.js";
|
|
29
29
|
import { isPluginDisabled } from "../plugins/disabled-state.js";
|
|
30
30
|
import type { Message, ToolDefinition } from "../providers/types.js";
|
|
31
|
-
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
32
31
|
import { registerConversationSender } from "../tools/browser/browser-screencast.js";
|
|
33
32
|
import { supportsClientOsForSkillTool } from "../tools/client-os.js";
|
|
34
33
|
import type { ToolExecutor } from "../tools/executor.js";
|
|
@@ -63,10 +62,7 @@ import {
|
|
|
63
62
|
type ToolContext,
|
|
64
63
|
type ToolExecutionResult,
|
|
65
64
|
} from "../tools/types.js";
|
|
66
|
-
import {
|
|
67
|
-
injectActivationMomentParam,
|
|
68
|
-
projectUiToolsForChannel,
|
|
69
|
-
} from "../tools/ui-surface/channel-variants.js";
|
|
65
|
+
import { injectActivationMomentParam } from "../tools/ui-surface/channel-variants.js";
|
|
70
66
|
import { loadWorkspaceTools } from "../tools/workspace-tools/loader.js";
|
|
71
67
|
import {
|
|
72
68
|
resolveUsageAttribution,
|
|
@@ -260,6 +256,24 @@ export function createToolExecutor(
|
|
|
260
256
|
// see {@link SubagentToolGateMode}): rejects non-allowlisted calls BEFORE
|
|
261
257
|
// any executor dispatch, so a non-allowlisted tool's executor never runs.
|
|
262
258
|
// The error tool_result lets the model continue or finish.
|
|
259
|
+
const rejectUnattendedHostTool = (
|
|
260
|
+
toolName: string,
|
|
261
|
+
): ToolExecutionResult | null => {
|
|
262
|
+
const { transportInterface } = resolveTurnClientOs(ctx);
|
|
263
|
+
const isUnattended = ctx.currentTurnIsNonInteractive ?? ctx.hasNoClient;
|
|
264
|
+
if (
|
|
265
|
+
HOST_TOOL_NAMES.has(toolName) &&
|
|
266
|
+
isUnattended &&
|
|
267
|
+
transportInterface !== "chrome-extension"
|
|
268
|
+
) {
|
|
269
|
+
return {
|
|
270
|
+
content: `The "${toolName}" tool requires an interactive user turn and cannot run in the background.`,
|
|
271
|
+
isError: true,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return null;
|
|
275
|
+
};
|
|
276
|
+
|
|
263
277
|
const rejectNonAllowlistedTool = (
|
|
264
278
|
toolName: string,
|
|
265
279
|
): ToolExecutionResult | null => {
|
|
@@ -387,6 +401,10 @@ export function createToolExecutor(
|
|
|
387
401
|
if (rejection) {
|
|
388
402
|
return rejection;
|
|
389
403
|
}
|
|
404
|
+
const unattendedRejection = rejectUnattendedHostTool(executionName);
|
|
405
|
+
if (unattendedRejection) {
|
|
406
|
+
return unattendedRejection;
|
|
407
|
+
}
|
|
390
408
|
}
|
|
391
409
|
|
|
392
410
|
if (isDoordashCommand(executionName, executionInput)) {
|
|
@@ -550,6 +568,10 @@ export function createToolExecutor(
|
|
|
550
568
|
if (innerRejection) {
|
|
551
569
|
return innerRejection;
|
|
552
570
|
}
|
|
571
|
+
const unattendedRejection = rejectUnattendedHostTool(toolName);
|
|
572
|
+
if (unattendedRejection) {
|
|
573
|
+
return unattendedRejection;
|
|
574
|
+
}
|
|
553
575
|
|
|
554
576
|
// Per-chat plugin scope: reject the resolved inner tool when it belongs
|
|
555
577
|
// to a plugin outside the conversation's effective set.
|
|
@@ -628,7 +650,6 @@ export const DEFAULT_PREACTIVATED_SKILL_IDS = ["notifications", "subagent"];
|
|
|
628
650
|
// ── Conditional tool sets ────────────────────────────────────────────
|
|
629
651
|
|
|
630
652
|
const UI_SURFACE_TOOL_NAMES = new Set(["ui_show", "ui_update", "ui_dismiss"]);
|
|
631
|
-
const SLACK_TASK_PROGRESS_UI_TOOL_NAMES = new Set(["ui_show", "ui_update"]);
|
|
632
653
|
/**
|
|
633
654
|
* Single source of truth for which tools are host tools and the capability
|
|
634
655
|
* each one requires from the connected client interface. Adding a tool here
|
|
@@ -856,56 +877,26 @@ export function isToolActiveForContext(
|
|
|
856
877
|
return supportsChannelReaction(turnChannel);
|
|
857
878
|
}
|
|
858
879
|
if (UI_SURFACE_TOOL_NAMES.has(name)) {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
return !hasNoClient;
|
|
864
|
-
}
|
|
865
|
-
return channelCapabilities?.supportsDynamicUi ?? !hasNoClient;
|
|
880
|
+
// Surface calls write conversation content. Background turns persist that
|
|
881
|
+
// content for the next client that opens the conversation, so presence
|
|
882
|
+
// cannot change whether the model receives these definitions.
|
|
883
|
+
return true;
|
|
866
884
|
}
|
|
867
885
|
if (HOST_TOOL_NAMES.has(name)) {
|
|
868
886
|
const capability = HOST_TOOL_TO_CAPABILITY.get(name);
|
|
869
887
|
const transport = transportInterface;
|
|
870
888
|
|
|
871
|
-
//
|
|
872
|
-
//
|
|
889
|
+
// A transport that does not implement a capability can invoke it through
|
|
890
|
+
// an eligible same-user client. Client selection happens when the call
|
|
891
|
+
// runs, so the wire schema stays stable across live and background turns.
|
|
873
892
|
if (transport && capability && !supportsHostProxy(transport, capability)) {
|
|
874
|
-
|
|
875
|
-
// cross-client routing infrastructure (Phases 1–3 plus host_browser
|
|
876
|
-
// via PR #27489) to be exposed for non-host-proxy transports (e.g.
|
|
877
|
-
// "web", "ios") when at least one capable client is connected via
|
|
878
|
-
// the event hub. Members of CROSS_CLIENT_EXPOSED_CAPABILITIES
|
|
879
|
-
// (host_bash, host_file, host_browser) qualify.
|
|
880
|
-
// chrome-extension transport is excluded as a security boundary
|
|
881
|
-
// (extension only gets host_browser via its own executor path);
|
|
882
|
-
// hasNoClient turns are excluded (no interactive approval UI
|
|
883
|
-
// available).
|
|
884
|
-
if (
|
|
885
|
-
capability &&
|
|
893
|
+
return (
|
|
886
894
|
CROSS_CLIENT_EXPOSED_CAPABILITIES.has(capability) &&
|
|
887
|
-
transport !== "chrome-extension"
|
|
888
|
-
|
|
889
|
-
assistantEventHub.listClientsByCapability(capability).length > 0
|
|
890
|
-
) {
|
|
891
|
-
return true;
|
|
892
|
-
}
|
|
893
|
-
return false;
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
// chrome-extension is its own executor — the extension's popup gates
|
|
897
|
-
// commands via its own UI, and the transport does not use an SSE-level
|
|
898
|
-
// interactive approval channel. hasNoClient is intentionally `true` for
|
|
899
|
-
// chrome-extension turns (chrome-extension is not in INTERACTIVE_INTERFACES)
|
|
900
|
-
// and must not gate host_browser. Trust the per-capability check.
|
|
901
|
-
if (transport === "chrome-extension") {
|
|
902
|
-
return true;
|
|
895
|
+
transport !== "chrome-extension"
|
|
896
|
+
);
|
|
903
897
|
}
|
|
904
898
|
|
|
905
|
-
|
|
906
|
-
// fallback), deny when no client is present so the guardian auto-approve
|
|
907
|
-
// path cannot execute host commands unattended.
|
|
908
|
-
return !hasNoClient;
|
|
899
|
+
return true;
|
|
909
900
|
}
|
|
910
901
|
if (CLIENT_CAPABILITY_TOOL_NAMES.has(name)) {
|
|
911
902
|
if (name === "ask_question" && channelCapabilities?.clientOS === "macos") {
|
|
@@ -1153,18 +1144,13 @@ export function createResolveToolsCallback(
|
|
|
1153
1144
|
: currentWorkspaceDefs
|
|
1154
1145
|
).filter((d) => !readOnlyHidesFromWire(d.name));
|
|
1155
1146
|
const excluded = new Set(getConfig().tools.exclude);
|
|
1156
|
-
//
|
|
1157
|
-
//
|
|
1158
|
-
//
|
|
1159
|
-
//
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
let allBaseDefs = projectUiToolsForChannel(
|
|
1164
|
-
[...scopedCoreDefs, ...scopedWorkspaceDefs, ...scopedMcpDefs].filter(
|
|
1165
|
-
(d) => !excluded.has(d.name),
|
|
1166
|
-
),
|
|
1167
|
-
channelForUiTools,
|
|
1147
|
+
// UI definitions stay identical across channel and background turns.
|
|
1148
|
+
// Channel renderers enforce their supported surface subset at execution,
|
|
1149
|
+
// while background calls persist the full surface content for the next
|
|
1150
|
+
// capable client that opens the conversation. Skill tools stay off this
|
|
1151
|
+
// list (`skill_execute` dispatch) and are a separate disclosure path.
|
|
1152
|
+
let allBaseDefs = [...scopedCoreDefs, ...scopedWorkspaceDefs, ...scopedMcpDefs].filter(
|
|
1153
|
+
(d) => !excluded.has(d.name),
|
|
1168
1154
|
);
|
|
1169
1155
|
// Activation-rail conversations carry the optional `activation_moment`
|
|
1170
1156
|
// telemetry param on ui_show. The marker is written before the first
|
|
@@ -2366,9 +2366,6 @@ export class Conversation {
|
|
|
2366
2366
|
|
|
2367
2367
|
markStale(): void {
|
|
2368
2368
|
this.stale = true;
|
|
2369
|
-
// Invalidate the cached skill catalog so the next projection picks up
|
|
2370
|
-
// filesystem changes (e.g. a skill created during this run).
|
|
2371
|
-
this.skillProjectionCache.catalog = undefined;
|
|
2372
2369
|
}
|
|
2373
2370
|
|
|
2374
2371
|
isStale(): boolean {
|
|
@@ -10,6 +10,7 @@ import { join } from "node:path";
|
|
|
10
10
|
|
|
11
11
|
import { getLogger } from "../util/logger.js";
|
|
12
12
|
import { getWorkspaceDir } from "../util/platform.js";
|
|
13
|
+
import { safeStringSlice } from "../util/unicode.js";
|
|
13
14
|
|
|
14
15
|
const log = getLogger("dictation-profile-store");
|
|
15
16
|
|
|
@@ -130,7 +131,7 @@ function validateAndClampConfig(raw: unknown): DictationProfilesConfig {
|
|
|
130
131
|
{ profileId: profile.id },
|
|
131
132
|
`stylePrompt exceeds ${MAX_STYLE_PROMPT_LENGTH} chars, truncating`,
|
|
132
133
|
);
|
|
133
|
-
stylePrompt = stylePrompt
|
|
134
|
+
stylePrompt = safeStringSlice(stylePrompt, 0, MAX_STYLE_PROMPT_LENGTH);
|
|
134
135
|
}
|
|
135
136
|
|
|
136
137
|
// Validate dictionary entries
|
|
@@ -32,6 +32,7 @@ import { unwrapExternalContentForDisplay } from "../../security/untrusted-conten
|
|
|
32
32
|
import type { CredentialInjectionTemplate } from "../../tools/credentials/policy-types.js";
|
|
33
33
|
import { getLogger } from "../../util/logger.js";
|
|
34
34
|
import { joinWithSpacing } from "../../util/text-spacing.js";
|
|
35
|
+
import { safeStringSlice } from "../../util/unicode.js";
|
|
35
36
|
import { estimateBase64Bytes } from "../assistant-attachments.js";
|
|
36
37
|
import { conversationSupportsDynamicUi } from "../channel-ui-capability.js";
|
|
37
38
|
import { findConversation } from "../conversation-registry.js";
|
|
@@ -264,7 +265,7 @@ function clampAttachmentText(text: string): string {
|
|
|
264
265
|
if (text.length <= HISTORY_ATTACHMENT_TEXT_LIMIT) {
|
|
265
266
|
return text;
|
|
266
267
|
}
|
|
267
|
-
return `${text
|
|
268
|
+
return `${safeStringSlice(text, 0, HISTORY_ATTACHMENT_TEXT_LIMIT)}<truncated />`;
|
|
268
269
|
}
|
|
269
270
|
|
|
270
271
|
interface FileBlockMetadata {
|
|
@@ -82,6 +82,7 @@ import {
|
|
|
82
82
|
searchSkillsRegistry,
|
|
83
83
|
} from "../../skills/skillssh-registry.js";
|
|
84
84
|
import { getWorkspaceSkillsDir } from "../../util/platform.js";
|
|
85
|
+
import { safeStringSlice } from "../../util/unicode.js";
|
|
85
86
|
import { getConfigWatcher } from "../config-watcher.js";
|
|
86
87
|
import type {
|
|
87
88
|
SkillDetailResponse,
|
|
@@ -237,9 +238,11 @@ function heuristicDraft(body: string): {
|
|
|
237
238
|
const lines = body.split("\n").filter((l) => l.trim());
|
|
238
239
|
const firstLine = lines[0]?.trim() ?? "";
|
|
239
240
|
const name =
|
|
240
|
-
firstLine.replace(/^#+\s*/, "")
|
|
241
|
+
safeStringSlice(firstLine.replace(/^#+\s*/, ""), 0, 100) ||
|
|
242
|
+
"Untitled Skill";
|
|
241
243
|
const skillId = toSkillSlug(name) || "untitled-skill";
|
|
242
|
-
const description =
|
|
244
|
+
const description =
|
|
245
|
+
safeStringSlice(body.trim(), 0, 200) || "No description provided";
|
|
243
246
|
return { skillId, name, description, emoji: "\u{1F4DD}" };
|
|
244
247
|
}
|
|
245
248
|
|
|
@@ -1732,7 +1735,7 @@ export async function draftSkill(params: {
|
|
|
1732
1735
|
"- emoji: a single emoji character representing the skill",
|
|
1733
1736
|
"",
|
|
1734
1737
|
"Skill body:",
|
|
1735
|
-
body
|
|
1738
|
+
safeStringSlice(body, 0, 2000),
|
|
1736
1739
|
].join("\n");
|
|
1737
1740
|
|
|
1738
1741
|
const response = await provider.sendMessage([userMessage(prompt)], {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { getConfig } from "../config/loader.js";
|
|
2
2
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
3
3
|
import {
|
|
4
|
-
ambiguousSameUserError,
|
|
5
4
|
enforceSameActorOrErrorResult,
|
|
6
|
-
|
|
5
|
+
pickMostRecentSameUserClient,
|
|
6
|
+
unavailableSameUserClientError,
|
|
7
7
|
} from "../runtime/auth/same-actor.js";
|
|
8
8
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
9
9
|
import { formatShellOutput } from "../tools/shared/shell-output.js";
|
|
@@ -93,21 +93,17 @@ export class HostBashProxy extends HostProxyBase<
|
|
|
93
93
|
}
|
|
94
94
|
resolvedTargetClientId = input.targetClientId;
|
|
95
95
|
} else {
|
|
96
|
-
|
|
97
|
-
// broadcast) when multiple same-user clients are connected so that
|
|
98
|
-
// a single targeted-style request cannot fan out across every one
|
|
99
|
-
// of the user's machines. Zero same-user matches falls through to
|
|
100
|
-
// the existing untargeted code path.
|
|
101
|
-
const resolved = pickSameUserAutoResolve({
|
|
96
|
+
resolvedTargetClientId = pickMostRecentSameUserClient({
|
|
102
97
|
hub: assistantEventHub,
|
|
103
98
|
capability: "host_bash",
|
|
104
99
|
sourceActorPrincipalId,
|
|
105
100
|
});
|
|
106
|
-
if (
|
|
107
|
-
|
|
101
|
+
if (
|
|
102
|
+
resolvedTargetClientId === undefined &&
|
|
103
|
+
sourceActorPrincipalId !== undefined
|
|
104
|
+
) {
|
|
105
|
+
return unavailableSameUserClientError("host_bash");
|
|
108
106
|
}
|
|
109
|
-
resolvedTargetClientId =
|
|
110
|
-
resolved.kind === "match" ? resolved.clientId : undefined;
|
|
111
107
|
}
|
|
112
108
|
|
|
113
109
|
// Targeted requests must be bound to the same authenticated user as the
|
|
@@ -5,7 +5,10 @@ import {
|
|
|
5
5
|
assistantEventHub,
|
|
6
6
|
broadcastMessage,
|
|
7
7
|
} from "../runtime/assistant-event-hub.js";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
enforceSameActorOrErrorResult,
|
|
10
|
+
unavailableSameUserClientError,
|
|
11
|
+
} from "../runtime/auth/same-actor.js";
|
|
9
12
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
10
13
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
11
14
|
import { AssistantError, ErrorCode } from "../util/errors.js";
|
|
@@ -284,6 +287,17 @@ export class HostBrowserProxy {
|
|
|
284
287
|
targetClientId,
|
|
285
288
|
);
|
|
286
289
|
|
|
290
|
+
if (
|
|
291
|
+
preferredClient === undefined &&
|
|
292
|
+
sourceActorPrincipalId !== undefined &&
|
|
293
|
+
targetClientId === undefined
|
|
294
|
+
) {
|
|
295
|
+
if (isExtensionOnlyMethod(input.cdpMethod)) {
|
|
296
|
+
return Promise.resolve(extensionRequiredResult(input.cdpMethod));
|
|
297
|
+
}
|
|
298
|
+
return Promise.resolve(unavailableSameUserClientError("host_browser"));
|
|
299
|
+
}
|
|
300
|
+
|
|
287
301
|
// Same-user enforcement: when the caller's actor is known, refuse to
|
|
288
302
|
// dispatch to a client owned by a different actor. This covers the
|
|
289
303
|
// cross-client exposure case where a web/iOS turn for actor A would
|