@vellumai/assistant 0.11.6 → 0.11.7-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/ARCHITECTURE.md +31 -19
- package/Dockerfile +1 -0
- package/docs/architecture/security.md +3 -3
- package/docs/flux-turn-detection-spike.md +8 -7
- package/docs/runbook-trusted-contacts.md +14 -0
- package/docs/stt-provider-onboarding.md +8 -4
- package/knip.json +1 -0
- package/node_modules/@vellumai/avatar-manifest/package.json +18 -0
- package/node_modules/@vellumai/avatar-manifest/src/__tests__/manifest.test.ts +173 -0
- package/node_modules/@vellumai/avatar-manifest/src/__tests__/read.test.ts +114 -0
- package/node_modules/@vellumai/avatar-manifest/src/index.ts +29 -0
- package/node_modules/@vellumai/avatar-manifest/src/layout.ts +18 -0
- package/node_modules/@vellumai/avatar-manifest/src/manifest.ts +156 -0
- package/node_modules/@vellumai/avatar-manifest/src/read.ts +109 -0
- package/node_modules/@vellumai/avatar-manifest/tsconfig.json +20 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +37 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/remote-web-pairing.test.ts +389 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/ingress.ts +22 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +508 -18
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/rpc.ts +174 -0
- package/node_modules/@vellumai/ces-client/src/http-credentials.ts +161 -0
- package/node_modules/@vellumai/ces-client/src/index.ts +1 -0
- package/node_modules/@vellumai/environments/package.json +2 -1
- package/node_modules/@vellumai/environments/src/shell.test.ts +56 -0
- package/node_modules/@vellumai/environments/src/shell.ts +65 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +37 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/remote-web-pairing.test.ts +389 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/ingress.ts +22 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +508 -18
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/rpc.ts +174 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +32 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/gateway-client.test.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/inbound-event-kind.test.ts +82 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/plugin-admission-denied-contract.test.ts +56 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +18 -0
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +5 -11
- package/node_modules/@vellumai/gateway-client/src/channel-permission-contract.ts +3 -1
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +9 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +4 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-event-kind.ts +75 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +17 -0
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +8 -0
- package/node_modules/@vellumai/gateway-client/src/plugin-admission-denied-contract.ts +47 -0
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +11 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +37 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/remote-web-pairing.test.ts +389 -0
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +22 -0
- package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +508 -18
- package/node_modules/@vellumai/service-contracts/src/rpc.ts +174 -0
- package/openapi.yaml +419 -55
- package/package.json +4 -1
- package/scripts/sync-llm-catalog.ts +6 -0
- package/src/__tests__/approval-card-edit-inbound-handoff.test.ts +199 -0
- package/src/__tests__/approval-card-edit.test.ts +153 -0
- package/src/__tests__/attachments-store-heic-normalize.test.ts +1 -1
- package/src/__tests__/available-skills.test.ts +54 -0
- package/src/__tests__/avatar-identity-sync.test.ts +5 -1
- package/src/__tests__/catalog-install-normalize.test.ts +9 -1
- package/src/__tests__/channel-policy.test.ts +1 -3
- package/src/__tests__/channel-readiness-discord.test.ts +9 -70
- package/src/__tests__/compactor-call-site-logging.test.ts +61 -0
- package/src/__tests__/config-loader-backfill.test.ts +69 -0
- package/src/__tests__/config-schema.test.ts +2 -3
- package/src/__tests__/conversation-agent-loop.test.ts +238 -0
- package/src/__tests__/conversation-attachments.test.ts +0 -1
- package/src/__tests__/conversation-error.test.ts +44 -0
- package/src/__tests__/conversation-evictor.test.ts +19 -0
- package/src/__tests__/conversation-fork-referential.test.ts +73 -63
- package/src/__tests__/conversation-fork-retrospective.test.ts +99 -74
- package/src/__tests__/conversation-runtime-assembly.test.ts +23 -0
- package/src/__tests__/conversation-slash.test.ts +9 -0
- package/src/__tests__/conversation-title-service.test.ts +97 -0
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +16 -0
- package/src/__tests__/credential-broker-server-use.test.ts +0 -218
- package/src/__tests__/credential-broker.test.ts +43 -420
- package/src/__tests__/credential-record-write-through.test.ts +78 -0
- package/src/__tests__/credential-routes.test.ts +17 -1
- package/src/__tests__/credential-security-invariants.test.ts +8 -9
- package/src/__tests__/default-profile-catalog-fallback.test.ts +289 -0
- package/src/__tests__/delete-propagation.test.ts +92 -2
- package/src/__tests__/discord-callback-round-trip.test.ts +93 -0
- package/src/__tests__/discord-channel-config.test.ts +237 -0
- package/src/__tests__/edit-propagation.test.ts +42 -2
- package/src/__tests__/evict-conversations-for-reload.test.ts +51 -1
- package/src/__tests__/fallback-breaker.test.ts +1335 -0
- package/src/__tests__/gateway-threshold-reader-mock.ts +6 -0
- package/src/__tests__/guardian-card-withdrawal.test.ts +30 -0
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -2
- package/src/__tests__/image-conversion.test.ts +38 -4
- package/src/__tests__/install-skill-routing.test.ts +25 -0
- package/src/__tests__/llm-catalog-parity.test.ts +4 -0
- package/src/__tests__/llm-resolver.test.ts +74 -0
- package/src/__tests__/llm-schema-fallback-profile.test.ts +359 -0
- package/src/__tests__/managed-fallback-dispatch.test.ts +430 -0
- package/src/__tests__/managed-profile-guard.test.ts +28 -0
- package/src/__tests__/managed-speech-defaults.test.ts +196 -1
- package/src/__tests__/mcp-cli.test.ts +23 -1
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +43 -34
- package/src/__tests__/media-stream-stt-session.test.ts +2 -0
- package/src/__tests__/notification-decision-fallback.test.ts +106 -0
- package/src/__tests__/notification-discord-adapter.test.ts +162 -0
- package/src/__tests__/oauth-connect-orchestrator.test.ts +95 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +6 -8
- package/src/__tests__/persist-unsendable-image.test.ts +3 -3
- package/src/__tests__/platform.test.ts +19 -1
- package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -1
- package/src/__tests__/provider-catalog-visibility.test.ts +17 -0
- package/src/__tests__/provider-platform-proxy-integration.test.ts +8 -1
- package/src/__tests__/provider-usage-tracking.test.ts +56 -0
- package/src/__tests__/require-fresh-approval.test.ts +5 -2
- package/src/__tests__/retry-fallback-escalation.test.ts +1093 -0
- package/src/__tests__/schedule-retry.test.ts +183 -4
- package/src/__tests__/scheduler-reuse-conversation.test.ts +6 -6
- package/src/__tests__/secret-routes-platform-proxy.test.ts +55 -0
- package/src/__tests__/skill-load-tool.test.ts +34 -0
- package/src/__tests__/skill-tool-factory.test.ts +6 -1
- package/src/__tests__/skill-tool-manifest.test.ts +20 -0
- package/src/__tests__/skills.test.ts +25 -0
- package/src/__tests__/subagent-manager-notify.test.ts +38 -0
- package/src/__tests__/terminal-tools.test.ts +2 -0
- package/src/__tests__/tool-approval-handler.test.ts +146 -2
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +108 -2
- package/src/__tests__/tool-audit.test.ts +111 -40
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +228 -18
- package/src/__tests__/ui-shape-teaching.test.ts +1 -1
- package/src/__tests__/verification-control-plane-policy.test.ts +6 -2
- package/src/__tests__/voice-config-update.test.ts +43 -0
- package/src/__tests__/workspace-migration-147-rename-colliding-backup-profile-names.test.ts +480 -0
- package/src/__tests__/workspace-migration-148-strip-unsupported-fallback-profiles.test.ts +167 -0
- package/src/__tests__/workspace-migration-149-repoint-backup-profile-selections.test.ts +144 -0
- package/src/agent/loop.ts +31 -2
- package/src/approvals/guardian-card-withdrawal.ts +22 -0
- package/src/avatar/__tests__/ensure-raster.test.ts +291 -0
- package/src/avatar/avatar-manifest.ts +48 -100
- package/src/avatar/avatar-store.ts +7 -7
- package/src/avatar/ensure-raster.ts +146 -0
- package/src/avatar/resvg-lazy.test.ts +0 -1
- package/src/avatar/traits-png-sync.ts +9 -10
- package/src/background-wake/wake-intent-hooks.test.ts +0 -1
- package/src/backup/__tests__/paths.test.ts +6 -2
- package/src/backup/paths.ts +6 -4
- package/src/bundler/app-compiler.ts +2 -2
- package/src/bundler/compiler-tools.test.ts +36 -0
- package/src/bundler/compiler-tools.ts +54 -18
- package/src/calls/__tests__/telephony-synthesis-language.test.ts +81 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +57 -0
- package/src/calls/media-stream-stt-session.ts +2 -1
- package/src/calls/telephony-synthesis-language.ts +13 -5
- package/src/calls/voice-session-bridge.ts +19 -4
- package/src/channels/config.ts +23 -12
- package/src/cli/AGENTS.md +3 -1
- package/src/cli/commands/backup.help.ts +10 -13
- package/src/cli/commands/contacts.help.ts +16 -4
- package/src/cli/commands/contacts.ts +5 -1
- package/src/cli/commands/credentials.help.ts +1 -1
- package/src/cli/commands/inference-providers.ts +18 -53
- package/src/cli/commands/mcp.help.ts +6 -5
- package/src/cli/commands/mcp.ts +1 -1
- package/src/cli/commands/memory/memory-retrospective.ts +1 -0
- package/src/cli/commands/stt.help.ts +2 -2
- package/src/config/__tests__/backup-schema.test.ts +1 -1
- package/src/config/__tests__/default-profile-catalog.test.ts +83 -2
- package/src/config/__tests__/loader-sparse-array-cleanup.test.ts +1 -1
- package/src/config/__tests__/memory-retrospective-schema.test.ts +12 -15
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -6
- package/src/config/bundled-skills/computer-use/TOOLS.json +9 -6
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +3 -1
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +1 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +16 -15
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +2 -1
- package/src/config/bundled-skills/settings/TOOLS.json +11 -5
- package/src/config/bundled-skills/settings/tools/open-system-settings.test.ts +85 -0
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +33 -8
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +54 -3
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +1 -1
- package/src/config/default-profile-catalog.ts +195 -10
- package/src/config/default-profile-names.ts +41 -0
- package/src/config/feature-flag-registry.json +34 -2
- package/src/config/inference-profile-validation.ts +11 -2
- package/src/config/llm-resolver.ts +25 -0
- package/src/config/loader.ts +3 -0
- package/src/config/managed-speech-defaults.ts +160 -10
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/live-voice.test.ts +7 -6
- package/src/config/schemas/__tests__/stt.test.ts +94 -0
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/channels.ts +32 -0
- package/src/config/schemas/live-voice.ts +13 -4
- package/src/config/schemas/llm.ts +263 -15
- package/src/config/schemas/mcp.ts +10 -2
- package/src/config/schemas/memory-retrospective.ts +1 -19
- package/src/config/schemas/services.ts +24 -0
- package/src/config/schemas/stt.ts +128 -5
- package/src/config/seed-inference-profiles.ts +32 -3
- package/src/config/skill-state.ts +5 -0
- package/src/config/skills.ts +21 -0
- package/src/contacts/notify-contacts-changed.ts +5 -2
- package/src/context/compactor.ts +74 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +138 -1
- package/src/daemon/config-watcher.ts +2 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +27 -0
- package/src/daemon/conversation-agent-loop.ts +86 -10
- package/src/daemon/conversation-error.ts +25 -0
- package/src/daemon/conversation-evictor.ts +2 -4
- package/src/daemon/conversation-runtime-assembly.ts +19 -7
- package/src/daemon/conversation-skill-tools.ts +5 -1
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-store.ts +8 -1
- package/src/daemon/conversation-tool-setup.ts +37 -0
- package/src/daemon/conversation.ts +0 -4
- package/src/daemon/handlers/channel-config-result.ts +30 -0
- package/src/daemon/handlers/config-discord-channel.ts +301 -0
- package/src/daemon/handlers/config-ingress.ts +9 -0
- package/src/daemon/handlers/config-slack-channel.ts +13 -15
- package/src/daemon/handlers/config-telegram.ts +2 -5
- package/src/daemon/handlers/conversations.ts +0 -2
- package/src/daemon/handlers/skills.ts +25 -7
- package/src/daemon/lifecycle.ts +3 -1
- package/src/daemon/message-types/messages.ts +0 -2
- package/src/daemon/tool-setup-types.ts +5 -3
- package/src/daemon/trust-context-types.test.ts +33 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -1
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +58 -4
- package/src/live-voice/__tests__/live-voice-managed-speech-fallback.test.ts +8 -3
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +73 -11
- package/src/live-voice/__tests__/live-voice-session-preflight.test.ts +148 -2
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +64 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +3 -0
- package/src/live-voice/__tests__/live-voice-text-turn.test.ts +391 -0
- package/src/live-voice/__tests__/protocol.test.ts +224 -0
- package/src/live-voice/live-voice-credential-preflight.ts +5 -1
- package/src/live-voice/live-voice-session-manager.ts +39 -2
- package/src/live-voice/live-voice-session.ts +224 -9
- package/src/live-voice/protocol.ts +187 -1
- package/src/messaging/providers/discord/api.ts +2 -1
- package/src/messaging/providers/discord/withdraw.ts +62 -0
- package/src/messaging/read-provider-metadata.ts +32 -0
- package/src/monitoring/__tests__/file-descriptors.test.ts +32 -0
- package/src/monitoring/__tests__/process-memory.test.ts +34 -1
- package/src/monitoring/db-integrity-sample.ts +1 -0
- package/src/monitoring/file-descriptors.ts +39 -6
- package/src/monitoring/process-memory.ts +37 -5
- package/src/monitoring/resource-sampler.ts +25 -8
- package/src/notifications/__tests__/activity-failed-dedupe.test.ts +161 -0
- package/src/notifications/__tests__/background-failure-signal.test.ts +107 -0
- package/src/notifications/__tests__/connected-channels.test.ts +12 -0
- package/src/notifications/__tests__/copy-composer.test.ts +83 -0
- package/src/notifications/__tests__/destination-resolver.test.ts +38 -0
- package/src/notifications/activity-failed-dedupe.ts +95 -0
- package/src/notifications/adapters/discord.ts +132 -0
- package/src/notifications/adapters/shared.ts +16 -0
- package/src/notifications/adapters/slack.ts +6 -1
- package/src/notifications/adapters/telegram.ts +5 -8
- package/src/notifications/approval-card-data.ts +94 -1
- package/src/notifications/background-failure-signal.ts +116 -0
- package/src/notifications/broadcaster.ts +3 -9
- package/src/notifications/copy-composer.ts +41 -8
- package/src/notifications/decision-engine.ts +55 -0
- package/src/notifications/destination-resolver.ts +45 -5
- package/src/notifications/emit-signal.ts +19 -5
- package/src/notifications/guardian-question-mode.ts +57 -0
- package/src/notifications/types.ts +2 -8
- package/src/oauth/__tests__/seed-providers-managed.test.ts +18 -0
- package/src/oauth/connect-orchestrator.ts +16 -0
- package/src/oauth/seed-providers.ts +262 -0
- package/src/permissions/checker.test.ts +21 -0
- package/src/permissions/checker.ts +6 -0
- package/src/permissions/gateway-threshold-reader.test.ts +184 -0
- package/src/permissions/gateway-threshold-reader.ts +144 -10
- package/src/permissions/prompter.ts +0 -6
- package/src/permissions/types.ts +5 -4
- package/src/persistence/__tests__/bulk-write-gate.test.ts +0 -38
- package/src/persistence/bulk-write-gate.ts +9 -10
- package/src/persistence/conversation-crud.ts +88 -134
- package/src/persistence/conversation-title-service.ts +43 -29
- package/src/persistence/embeddings/embedding-local.ts +14 -85
- package/src/persistence/embeddings/embedding-runtime-manager.ts +1 -0
- package/src/persistence/lifecycle-events-store.test.ts +50 -0
- package/src/persistence/lifecycle-events-store.ts +75 -5
- package/src/platform/platform-patch-queue.test.ts +368 -0
- package/src/platform/platform-patch-queue.ts +190 -0
- package/src/platform/sync-avatar.test.ts +527 -0
- package/src/platform/sync-avatar.ts +209 -0
- package/src/platform/sync-identity.test.ts +75 -0
- package/src/platform/sync-identity.ts +17 -110
- package/src/plugin-api/model-profiles.test.ts +2 -2
- package/src/plugin-api/model-profiles.ts +7 -7
- package/src/plugin-api/transcription-session.ts +1 -1
- package/src/plugins/defaults/compaction/window-manager.ts +4 -0
- package/src/plugins/defaults/image-recovery/recover.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +133 -34
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +21 -31
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +13 -9
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +31 -4
- package/src/plugins/defaults/memory/memory-retrospective-constants.ts +0 -11
- package/src/plugins/defaults/memory/memory-retrospective-fork-boundary.ts +27 -13
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +183 -113
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +13 -13
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +2 -2
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +1 -1
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +4 -2
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +9 -42
- package/src/plugins/defaults/memory/v2/rerank-local.ts +1 -0
- package/src/plugins/defaults/memory/worker.ts +7 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +55 -0
- package/src/providers/__tests__/vellum-connection-routing.test.ts +21 -3
- package/src/providers/connection-resolution.ts +2 -17
- package/src/providers/fallback-breaker.ts +389 -0
- package/src/providers/inference/__tests__/adapter-factory-opencode.test.ts +92 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +16 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +12 -0
- package/src/providers/inference/adapter-factory.ts +246 -3
- package/src/providers/inference/auth.ts +15 -14
- package/src/providers/inference/chatgpt-subscription-auth.ts +70 -0
- package/src/providers/inference/chatgpt-subscription-credentials.ts +84 -0
- package/src/providers/inference/resolve-auth.ts +1 -1
- package/src/providers/media-resolve.ts +2 -3
- package/src/providers/model-catalog.ts +100 -0
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +22 -0
- package/src/providers/openai/__tests__/chat-template-flatten.test.ts +198 -0
- package/src/providers/openai/api-error-normalization.ts +13 -0
- package/src/providers/openai/chat-completions-provider.ts +84 -0
- package/src/providers/opencode/client.test.ts +150 -0
- package/src/providers/opencode/client.ts +61 -0
- package/src/providers/platform-proxy/constants.ts +5 -0
- package/src/providers/provider-resolvability.ts +20 -0
- package/src/providers/provider-secret-catalog.ts +3 -2
- package/src/providers/retry.ts +956 -68
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +42 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +136 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +120 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +316 -12
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +83 -3
- package/src/providers/speech-to-text/deepgram-flux-realtime.ts +132 -4
- package/src/providers/speech-to-text/provider-catalog.ts +191 -3
- package/src/providers/speech-to-text/resolve.ts +132 -24
- package/src/providers/speech-to-text/vellum-managed-flux-realtime.ts +296 -0
- package/src/providers/types.ts +39 -0
- package/src/providers/usage-tracking.ts +12 -1
- package/src/providers/vellum/client.ts +29 -0
- package/src/providers/vellum-model-routing.test.ts +2 -0
- package/src/providers/vellum-model-routing.ts +3 -3
- package/src/runtime/AGENTS.md +1 -2
- package/src/runtime/__tests__/agent-wake.test.ts +105 -3
- package/src/runtime/__tests__/background-job-runner.test.ts +89 -3
- package/src/runtime/agent-wake.ts +44 -5
- package/src/runtime/background-job-runner.ts +68 -50
- package/src/runtime/channel-readiness-service.ts +0 -39
- package/src/runtime/http-server.ts +12 -4
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +18 -18
- package/src/runtime/routes/__tests__/backup-routes.test.ts +9 -5
- package/src/runtime/routes/__tests__/chatgpt-subscription-auth-routes.test.ts +372 -0
- package/src/runtime/routes/__tests__/contact-routes.test.ts +7 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +96 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +37 -0
- package/src/runtime/routes/__tests__/ingress-status-routes.test.ts +2 -1
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +87 -0
- package/src/runtime/routes/acp-claude-auth-routes.ts +25 -54
- package/src/runtime/routes/approval-routes.ts +0 -12
- package/src/runtime/routes/avatar-routes.ts +17 -30
- package/src/runtime/routes/backup-routes.ts +2 -2
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +296 -113
- package/src/runtime/routes/contact-prompt-routes.ts +65 -6
- package/src/runtime/routes/contact-routes.ts +20 -15
- package/src/runtime/routes/conversation-query-routes.ts +98 -10
- package/src/runtime/routes/conversation-routes.ts +2 -2
- package/src/runtime/routes/credential-routes.ts +2 -1
- package/src/runtime/routes/guardian-approval-interception.ts +12 -9
- package/src/runtime/routes/inbound-message-handler.ts +47 -48
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +18 -13
- package/src/runtime/routes/inbound-stages/admission-policy.ts +2 -2
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +20 -2
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +9 -8
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +1 -1
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +2 -2
- package/src/runtime/routes/inference-profiles-routes.ts +12 -7
- package/src/runtime/routes/inference-provider-connection-routes.ts +2 -2
- package/src/runtime/routes/inference-send-routes.ts +2 -2
- package/src/runtime/routes/ingress-status-routes.ts +2 -2
- package/src/runtime/routes/integrations/discord.ts +119 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +2 -2
- package/src/runtime/routes/mcp-auth-routes.ts +12 -6
- package/src/runtime/routes/migration-routes.ts +3 -1
- package/src/runtime/routes/oauth-pending-flows.ts +136 -0
- package/src/runtime/routes/secret-routes.ts +7 -0
- package/src/runtime/routes/stt-routes.ts +38 -6
- package/src/runtime/routes/wake-conversation-routes.ts +8 -1
- package/src/runtime/routes/watch-routes.ts +9 -5
- package/src/runtime/sync/resource-sync-events.ts +2 -0
- package/src/runtime/trust-verdict-consumer.ts +3 -3
- package/src/schedule/__tests__/worker-feature-flags.test.ts +58 -0
- package/src/schedule/retry-policy.ts +8 -8
- package/src/schedule/run-script.ts +14 -23
- package/src/schedule/schedule-recovery.ts +0 -1
- package/src/schedule/scheduler.ts +89 -51
- package/src/schedule/worker.ts +57 -0
- package/src/security/__tests__/openai-device-auth.test.ts +355 -0
- package/src/security/ces-rpc-record-backend.ts +123 -0
- package/src/security/oauth2.ts +7 -0
- package/src/security/openai-device-auth.ts +364 -0
- package/src/security/secure-keys.ts +15 -0
- package/src/skills/available-skills.ts +10 -1
- package/src/skills/catalog-install.ts +19 -1
- package/src/skills/inline-command-runner.ts +6 -2
- package/src/skills/platform-compatibility.test.ts +49 -0
- package/src/skills/platform-compatibility.ts +65 -0
- package/src/skills/tool-manifest.ts +20 -0
- package/src/stt/__tests__/roles.test.ts +152 -0
- package/src/stt/daemon-batch-transcriber.ts +4 -1
- package/src/stt/roles.ts +180 -0
- package/src/stt/stt-stream-session.ts +3 -2
- package/src/stt/types.ts +33 -3
- package/src/subagent/manager.ts +12 -0
- package/src/telemetry/__tests__/live-voice-funnel.test.ts +34 -0
- package/src/telemetry/live-voice-funnel.ts +12 -2
- package/src/telemetry/telemetry-wire.generated.ts +6 -0
- package/src/telemetry/tool-audit.ts +83 -30
- package/src/telemetry/tool-executed-events-store.test.ts +0 -1
- package/src/telemetry/turn-outcome.ts +75 -4
- package/src/tools/client-os.ts +115 -0
- package/src/tools/computer-use/definitions.ts +11 -7
- package/src/tools/computer-use/skill-proxy-bridge.ts +2 -2
- package/src/tools/credentials/broker-types.ts +0 -71
- package/src/tools/credentials/broker.ts +6 -201
- package/src/tools/credentials/metadata-store.ts +65 -16
- package/src/tools/credentials/store.ts +2 -0
- package/src/tools/executor.ts +2 -8
- package/src/tools/host-shell.test.ts +75 -0
- package/src/tools/host-shell.ts +24 -0
- package/src/tools/host-terminal/host-shell.ts +15 -44
- package/src/tools/mcp/mcp-tool-factory.ts +44 -9
- package/src/tools/permission-checker.ts +73 -21
- package/src/tools/policy-context.ts +1 -0
- package/src/tools/shared/filesystem/image-read.ts +1 -1
- package/src/tools/skills/find-similar-skills.ts +10 -2
- package/src/tools/skills/load.ts +41 -6
- package/src/tools/skills/sandbox-runner.ts +8 -16
- package/src/tools/skills/skill-tool-factory.ts +1 -0
- package/src/tools/terminal/__tests__/safe-env.test.ts +64 -1
- package/src/tools/terminal/safe-env.ts +39 -9
- package/src/tools/terminal/shell.ts +12 -31
- package/src/tools/tool-approval-handler.ts +64 -10
- package/src/tools/tool-types.ts +10 -0
- package/src/tools/types.ts +19 -3
- package/src/tools/ui-surface/surface-shape-docs.ts +4 -3
- package/src/tools/workflows/manage-workflows.ts +2 -2
- package/src/tools/workflows/run-workflow.test.ts +2 -1
- package/src/util/__tests__/file-use.test.ts +61 -0
- package/src/util/__tests__/process-table.test.ts +66 -0
- package/src/util/__tests__/process-tree.test.ts +46 -0
- package/src/util/errors.ts +1 -0
- package/src/util/file-use.ts +91 -0
- package/src/util/host-process.test.ts +17 -0
- package/src/util/host-process.ts +75 -0
- package/src/util/image-conversion.ts +39 -7
- package/src/util/platform.ts +32 -13
- package/src/util/process-table.ts +249 -0
- package/src/util/process-tree.ts +85 -129
- package/src/util/provider-error-patterns.ts +20 -0
- package/src/util/spawn.ts +9 -2
- package/src/watch/__tests__/watch-retro.test.ts +48 -1
- package/src/watch/watch-retro.ts +46 -4
- package/src/workspace/git-service.ts +4 -14
- package/src/workspace/migrations/147-rename-colliding-backup-profile-names.ts +360 -0
- package/src/workspace/migrations/148-strip-unsupported-fallback-profiles.ts +117 -0
- package/src/workspace/migrations/149-repoint-backup-profile-selections.ts +204 -0
- package/src/workspace/migrations/150-stt-flux-provider-to-model-family.ts +139 -0
- package/src/workspace/migrations/__tests__/150-stt-flux-provider-to-model-family.test.ts +160 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/permission-types.test.ts +0 -17
- package/src/channels/gateway-discord-admission.ts +0 -32
- package/src/persistence/fork-message-copy.ts +0 -239
- package/src/plugins/defaults/memory/__tests__/fork-message-copy.test.ts +0 -221
- package/src/security/__tests__/oauth2-device-code.test.ts +0 -431
- package/src/security/oauth2-device-code.ts +0 -312
|
@@ -7,10 +7,12 @@
|
|
|
7
7
|
*
|
|
8
8
|
* - `recordToolExecuted` / `recordToolError` / `recordToolDenied` write the
|
|
9
9
|
* always-on `tool_invocations` audit row (redacting secrets from the
|
|
10
|
-
* stored input/result)
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* stored input/result).
|
|
11
|
+
* - `recordToolPermissionPrompted` / `recordToolPermissionDecided` write the
|
|
12
|
+
* consent-gated `permission_prompt` and `permission_decided`
|
|
13
|
+
* lifecycle-telemetry rows. Both are called from the one site that owns an
|
|
14
|
+
* interactive prompt (`tools/permission-checker.ts`), so every prompt has
|
|
15
|
+
* exactly one decision and the two series reconcile.
|
|
14
16
|
* - `logToolFailure` emits the operator-facing failure log.
|
|
15
17
|
*
|
|
16
18
|
* The telemetry-only columns (payload sizes + model attribution) are the
|
|
@@ -24,8 +26,10 @@
|
|
|
24
26
|
* are unaffected — `tool_invocations` is a local always-on audit log.
|
|
25
27
|
*/
|
|
26
28
|
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
+
import {
|
|
30
|
+
type LifecycleEventAttributes,
|
|
31
|
+
recordLifecycleEvent,
|
|
32
|
+
} from "../persistence/lifecycle-events-store.js";
|
|
29
33
|
import { getRawShareAnalytics } from "../platform/consent-cache.js";
|
|
30
34
|
import { redactJsonStringLeaves } from "../security/redact-json.js";
|
|
31
35
|
import { redactSensitiveFields } from "../security/redaction.js";
|
|
@@ -62,8 +66,6 @@ interface ExecutedAuditEntry {
|
|
|
62
66
|
durationMs: number;
|
|
63
67
|
/** Model attribution at invocation time; `null` when unavailable. */
|
|
64
68
|
attribution: UsageAttributionSnapshot | null;
|
|
65
|
-
/** True when this call was interactively approved via a permission prompt. */
|
|
66
|
-
wasPrompted: boolean;
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
interface ErrorAuditEntry {
|
|
@@ -90,8 +92,6 @@ interface DeniedAuditEntry {
|
|
|
90
92
|
riskLevel: string;
|
|
91
93
|
matchedTrustRuleId?: string;
|
|
92
94
|
durationMs: number;
|
|
93
|
-
/** True when the denial followed an interactive permission prompt. */
|
|
94
|
-
wasPrompted: boolean;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/** Record an audit row for a tool that ran to completion. */
|
|
@@ -111,10 +111,6 @@ export function recordToolExecuted(entry: ExecutedAuditEntry): void {
|
|
|
111
111
|
durationMs: entry.durationMs,
|
|
112
112
|
...telemetryColumns(entry.attribution, rawInput, entry.resultBytes),
|
|
113
113
|
});
|
|
114
|
-
|
|
115
|
-
if (entry.wasPrompted && isAllowDecision(entry.decision as UserDecision)) {
|
|
116
|
-
recordToolPermissionDecided(entry.toolName, entry.decision);
|
|
117
|
-
}
|
|
118
114
|
}
|
|
119
115
|
|
|
120
116
|
/** Record an audit row and operator log for a tool that failed. */
|
|
@@ -156,32 +152,89 @@ export function recordToolDenied(entry: DeniedAuditEntry): void {
|
|
|
156
152
|
// No telemetry columns: the tool never executed, and denied rows are
|
|
157
153
|
// filtered out of the tool_executed projection anyway.
|
|
158
154
|
});
|
|
155
|
+
}
|
|
159
156
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
157
|
+
/**
|
|
158
|
+
* How an interactive permission prompt ended.
|
|
159
|
+
*
|
|
160
|
+
* `allow` / `deny` are answers a human gave. `abandoned` covers every way a
|
|
161
|
+
* prompt stops without one: it timed out, a new user message superseded it,
|
|
162
|
+
* the turn was cancelled, or the prompter was disposed (client disconnect /
|
|
163
|
+
* conversation teardown). The daemon resolves all of those to a deny for the
|
|
164
|
+
* agent loop, so without this bucket they are indistinguishable from a human
|
|
165
|
+
* saying no.
|
|
166
|
+
*/
|
|
167
|
+
export type PermissionPromptOutcome = "allow" | "deny" | "abandoned";
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Grouping dimensions recorded on both halves of a permission-prompt pair.
|
|
171
|
+
* The tool and its risk are always known at the prompt site, so they tighten
|
|
172
|
+
* to required; the rest are the lifecycle attributes as declared. Metadata
|
|
173
|
+
* only: never a file path, a command string, or any tool input.
|
|
174
|
+
*/
|
|
175
|
+
export interface PermissionPromptTelemetry extends LifecycleEventAttributes {
|
|
176
|
+
toolName: string;
|
|
177
|
+
riskLevel: string;
|
|
163
178
|
}
|
|
164
179
|
|
|
165
|
-
/**
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Server bounds on the lifecycle `event_name` and `tool_name`. A field over
|
|
182
|
+
* its bound fails validation, and a failed event is acked and discarded rather
|
|
183
|
+
* than retried, so both are clamped here. `event_name` has one variable-length
|
|
184
|
+
* part (the tool name, which can be a long `mcp__server__tool` id) and is much
|
|
185
|
+
* the tighter of the two, which is why `tool_name` carries the full-length
|
|
186
|
+
* value consumers join a prompt to its decision on.
|
|
187
|
+
*/
|
|
188
|
+
const LIFECYCLE_EVENT_NAME_LIMIT = 64;
|
|
189
|
+
const LIFECYCLE_TOOL_NAME_LIMIT = 255;
|
|
190
|
+
|
|
191
|
+
function permissionEventName(
|
|
192
|
+
prefix: string,
|
|
193
|
+
toolName: string,
|
|
194
|
+
suffix: string,
|
|
195
|
+
): string {
|
|
196
|
+
const budget = LIFECYCLE_EVENT_NAME_LIMIT - prefix.length - suffix.length;
|
|
197
|
+
return `${prefix}${toolName.slice(0, Math.max(budget, 0))}${suffix}`;
|
|
172
198
|
}
|
|
173
199
|
|
|
174
|
-
function
|
|
200
|
+
function recordPermissionLifecycleEvent(
|
|
201
|
+
eventName: string,
|
|
202
|
+
entry: PermissionPromptTelemetry,
|
|
203
|
+
failureMessage: string,
|
|
204
|
+
): void {
|
|
175
205
|
try {
|
|
176
|
-
recordLifecycleEvent(
|
|
206
|
+
recordLifecycleEvent(eventName, {
|
|
207
|
+
...entry,
|
|
208
|
+
toolName: entry.toolName.slice(0, LIFECYCLE_TOOL_NAME_LIMIT),
|
|
209
|
+
});
|
|
177
210
|
} catch (err) {
|
|
178
|
-
log.warn(
|
|
179
|
-
{ err, toolName, decision },
|
|
180
|
-
"Failed to record permission decision telemetry",
|
|
181
|
-
);
|
|
211
|
+
log.warn({ err, eventName, toolName: entry.toolName }, failureMessage);
|
|
182
212
|
}
|
|
183
213
|
}
|
|
184
214
|
|
|
215
|
+
/** Record the consent-gated telemetry row for an interactive permission prompt. */
|
|
216
|
+
export function recordToolPermissionPrompted(
|
|
217
|
+
entry: PermissionPromptTelemetry,
|
|
218
|
+
): void {
|
|
219
|
+
recordPermissionLifecycleEvent(
|
|
220
|
+
permissionEventName("permission_prompt:", entry.toolName, ""),
|
|
221
|
+
entry,
|
|
222
|
+
"Failed to record permission prompt telemetry",
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** Record the consent-gated telemetry row for how that prompt ended. */
|
|
227
|
+
export function recordToolPermissionDecided(
|
|
228
|
+
entry: PermissionPromptTelemetry,
|
|
229
|
+
outcome: PermissionPromptOutcome,
|
|
230
|
+
): void {
|
|
231
|
+
recordPermissionLifecycleEvent(
|
|
232
|
+
permissionEventName("permission_decided:", entry.toolName, `:${outcome}`),
|
|
233
|
+
entry,
|
|
234
|
+
"Failed to record permission decision telemetry",
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
185
238
|
/** Operator-facing failure log: warn for expected failures, error otherwise. */
|
|
186
239
|
function logToolFailure(entry: ErrorAuditEntry): void {
|
|
187
240
|
const meta = {
|
|
@@ -31,6 +31,26 @@ export interface TurnOutcomeExtras {
|
|
|
31
31
|
batchedInto?: string;
|
|
32
32
|
/** For `"failed"`: stable classified error code (never free-form text). */
|
|
33
33
|
failureCode?: string;
|
|
34
|
+
/**
|
|
35
|
+
* For `"failed"`: the classification's authored user-facing message
|
|
36
|
+
* (`classifyConversationError(...).userMessage`), so downstream failure
|
|
37
|
+
* reporting (background-job alerts) can render the actionable prose the
|
|
38
|
+
* chat banner shows instead of reconstructing degraded text from the code.
|
|
39
|
+
*/
|
|
40
|
+
failureMessage?: string;
|
|
41
|
+
/** For `"failed"`: the classification's machine-readable category. */
|
|
42
|
+
failureCategory?: string;
|
|
43
|
+
/**
|
|
44
|
+
* For `"failed"`: name of the `provider_connections` row in play when the
|
|
45
|
+
* failure occurred, when the classifier had it in scope.
|
|
46
|
+
*/
|
|
47
|
+
failureConnection?: string;
|
|
48
|
+
/**
|
|
49
|
+
* For `"failed"`: the resolved profile key the failing call ran under,
|
|
50
|
+
* when the classifier had it in scope. This is dispatch's own attribution,
|
|
51
|
+
* so consumers scope failure identity by it instead of re-resolving.
|
|
52
|
+
*/
|
|
53
|
+
failureProfile?: string;
|
|
34
54
|
}
|
|
35
55
|
|
|
36
56
|
/**
|
|
@@ -49,10 +69,25 @@ export function stampTurnOutcome(
|
|
|
49
69
|
extras: TurnOutcomeExtras = {},
|
|
50
70
|
): void {
|
|
51
71
|
try {
|
|
72
|
+
// The failure* keys are read back by `readTurnFailure` only; the turn
|
|
73
|
+
// telemetry projection (`queryUnreportedTurnEvents`) extracts none of
|
|
74
|
+
// them, so nothing here changes the platform wire contract.
|
|
52
75
|
updateMessageMetadata(userMessageId, {
|
|
53
76
|
turnOutcome: outcome,
|
|
54
77
|
...(extras.batchedInto ? { turnBatchedInto: extras.batchedInto } : {}),
|
|
55
78
|
...(extras.failureCode ? { turnFailureCode: extras.failureCode } : {}),
|
|
79
|
+
...(extras.failureMessage
|
|
80
|
+
? { turnFailureMessage: extras.failureMessage }
|
|
81
|
+
: {}),
|
|
82
|
+
...(extras.failureCategory
|
|
83
|
+
? { turnFailureCategory: extras.failureCategory }
|
|
84
|
+
: {}),
|
|
85
|
+
...(extras.failureConnection
|
|
86
|
+
? { turnFailureConnection: extras.failureConnection }
|
|
87
|
+
: {}),
|
|
88
|
+
...(extras.failureProfile
|
|
89
|
+
? { turnFailureProfile: extras.failureProfile }
|
|
90
|
+
: {}),
|
|
56
91
|
});
|
|
57
92
|
} catch (err) {
|
|
58
93
|
log.warn(
|
|
@@ -75,6 +110,14 @@ export function stampTurnOutcome(
|
|
|
75
110
|
export interface TurnFailure {
|
|
76
111
|
/** Stable classified error code (never free-form text). */
|
|
77
112
|
failureCode?: string;
|
|
113
|
+
/** The classification's authored user-facing message, when stamped. */
|
|
114
|
+
userMessage?: string;
|
|
115
|
+
/** The classification's machine-readable category, when stamped. */
|
|
116
|
+
errorCategory?: string;
|
|
117
|
+
/** Connection row in play when the failure occurred, when stamped. */
|
|
118
|
+
connectionName?: string;
|
|
119
|
+
/** Resolved profile key the failing call ran under, when stamped. */
|
|
120
|
+
profileName?: string;
|
|
78
121
|
}
|
|
79
122
|
|
|
80
123
|
/**
|
|
@@ -106,11 +149,39 @@ export function readTurnFailure(userMessageId: string): TurnFailure | null {
|
|
|
106
149
|
if (typeof parsed !== "object" || parsed === null) {
|
|
107
150
|
return null;
|
|
108
151
|
}
|
|
109
|
-
const meta = parsed as {
|
|
152
|
+
const meta = parsed as {
|
|
153
|
+
turnOutcome?: unknown;
|
|
154
|
+
turnFailureCode?: unknown;
|
|
155
|
+
turnFailureMessage?: unknown;
|
|
156
|
+
turnFailureCategory?: unknown;
|
|
157
|
+
turnFailureConnection?: unknown;
|
|
158
|
+
turnFailureProfile?: unknown;
|
|
159
|
+
};
|
|
110
160
|
if (meta.turnOutcome !== "failed") {
|
|
111
161
|
return null;
|
|
112
162
|
}
|
|
113
|
-
|
|
114
|
-
?
|
|
115
|
-
|
|
163
|
+
const str = (value: unknown): string | undefined =>
|
|
164
|
+
typeof value === "string" ? value : undefined;
|
|
165
|
+
const failure: TurnFailure = {};
|
|
166
|
+
const failureCode = str(meta.turnFailureCode);
|
|
167
|
+
if (failureCode !== undefined) {
|
|
168
|
+
failure.failureCode = failureCode;
|
|
169
|
+
}
|
|
170
|
+
const userMessage = str(meta.turnFailureMessage);
|
|
171
|
+
if (userMessage !== undefined) {
|
|
172
|
+
failure.userMessage = userMessage;
|
|
173
|
+
}
|
|
174
|
+
const errorCategory = str(meta.turnFailureCategory);
|
|
175
|
+
if (errorCategory !== undefined) {
|
|
176
|
+
failure.errorCategory = errorCategory;
|
|
177
|
+
}
|
|
178
|
+
const connectionName = str(meta.turnFailureConnection);
|
|
179
|
+
if (connectionName !== undefined) {
|
|
180
|
+
failure.connectionName = connectionName;
|
|
181
|
+
}
|
|
182
|
+
const profileName = str(meta.turnFailureProfile);
|
|
183
|
+
if (profileName !== undefined) {
|
|
184
|
+
failure.profileName = profileName;
|
|
185
|
+
}
|
|
186
|
+
return failure;
|
|
116
187
|
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ClientOs,
|
|
3
|
+
type HostProxyCapability,
|
|
4
|
+
type InterfaceId,
|
|
5
|
+
parseClientOs,
|
|
6
|
+
supportsHostProxy,
|
|
7
|
+
} from "../channels/types.js";
|
|
8
|
+
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
9
|
+
|
|
10
|
+
interface HostClientContext {
|
|
11
|
+
clientOs?: ClientOs;
|
|
12
|
+
transportInterface?: InterfaceId;
|
|
13
|
+
sourceActorPrincipalId?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function supportsClientOs(
|
|
17
|
+
supportedClientOs: readonly ClientOs[] | undefined,
|
|
18
|
+
clientOs: ClientOs | undefined,
|
|
19
|
+
): boolean {
|
|
20
|
+
return (
|
|
21
|
+
clientOs === undefined ||
|
|
22
|
+
supportedClientOs === undefined ||
|
|
23
|
+
supportedClientOs.includes(clientOs)
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getSkillToolHostCapability(
|
|
28
|
+
toolName: string,
|
|
29
|
+
): HostProxyCapability | undefined {
|
|
30
|
+
if (toolName.startsWith("computer_use_")) {
|
|
31
|
+
return "host_cu";
|
|
32
|
+
}
|
|
33
|
+
if (toolName.startsWith("app_control_")) {
|
|
34
|
+
return "host_app_control";
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getEligibleHostClientOs(
|
|
40
|
+
capability: HostProxyCapability,
|
|
41
|
+
context: HostClientContext,
|
|
42
|
+
): Set<ClientOs> {
|
|
43
|
+
const eligible = new Set<ClientOs>();
|
|
44
|
+
const sourceClientOs =
|
|
45
|
+
context.transportInterface === "macos" ||
|
|
46
|
+
context.transportInterface === "windows"
|
|
47
|
+
? context.transportInterface
|
|
48
|
+
: context.clientOs;
|
|
49
|
+
if (
|
|
50
|
+
sourceClientOs !== undefined &&
|
|
51
|
+
context.transportInterface !== undefined &&
|
|
52
|
+
supportsHostProxy(context.transportInterface, capability)
|
|
53
|
+
) {
|
|
54
|
+
eligible.add(sourceClientOs);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (context.sourceActorPrincipalId !== undefined) {
|
|
58
|
+
for (const client of assistantEventHub.listClientsByCapability(
|
|
59
|
+
capability,
|
|
60
|
+
)) {
|
|
61
|
+
if (client.actorPrincipalId !== context.sourceActorPrincipalId) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const clientOs = parseClientOs(client.interfaceId);
|
|
65
|
+
if (clientOs !== null) {
|
|
66
|
+
eligible.add(clientOs);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return eligible;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function supportsClientOsForSkillTool(
|
|
74
|
+
supportedClientOs: readonly ClientOs[] | undefined,
|
|
75
|
+
toolName: string,
|
|
76
|
+
context: HostClientContext,
|
|
77
|
+
): boolean {
|
|
78
|
+
if (supportedClientOs === undefined) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
const capability = getSkillToolHostCapability(toolName);
|
|
82
|
+
if (capability === undefined) {
|
|
83
|
+
return supportsClientOs(supportedClientOs, context.clientOs);
|
|
84
|
+
}
|
|
85
|
+
const eligible = getEligibleHostClientOs(capability, context);
|
|
86
|
+
if (eligible.size === 0) {
|
|
87
|
+
return supportsClientOs(supportedClientOs, context.clientOs);
|
|
88
|
+
}
|
|
89
|
+
for (const clientOs of eligible) {
|
|
90
|
+
if (supportedClientOs.includes(clientOs)) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function resolveInvocationHostClientOs(
|
|
98
|
+
capability: HostProxyCapability,
|
|
99
|
+
input: Record<string, unknown>,
|
|
100
|
+
context: HostClientContext,
|
|
101
|
+
): ClientOs | undefined {
|
|
102
|
+
const targetClientId =
|
|
103
|
+
typeof input.target_client_id === "string" && input.target_client_id !== ""
|
|
104
|
+
? input.target_client_id
|
|
105
|
+
: undefined;
|
|
106
|
+
if (targetClientId !== undefined) {
|
|
107
|
+
const client = assistantEventHub.getClientById(targetClientId);
|
|
108
|
+
return client?.capabilities.includes(capability)
|
|
109
|
+
? (parseClientOs(client.interfaceId) ?? undefined)
|
|
110
|
+
: undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const eligible = getEligibleHostClientOs(capability, context);
|
|
114
|
+
return eligible.size === 1 ? eligible.values().next().value : undefined;
|
|
115
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Computer-use tool definitions.
|
|
3
3
|
*
|
|
4
|
-
* These tools mirror the
|
|
4
|
+
* These tools mirror the desktop client's computer-use schemas, prefixed
|
|
5
5
|
* with `computer_use_` to avoid collisions with existing daemon tools. They are all
|
|
6
|
-
* proxy tools
|
|
6
|
+
* proxy tools. Execution is forwarded to a connected desktop client and never
|
|
7
7
|
* handled locally by the daemon.
|
|
8
8
|
*/
|
|
9
9
|
|
|
@@ -19,7 +19,7 @@ import type {
|
|
|
19
19
|
// ---------------------------------------------------------------------------
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Forward execution to the connected
|
|
22
|
+
* Forward execution to the connected desktop client via the request-bound
|
|
23
23
|
* `proxyToolResolver`. Returns a structured error when no resolver is
|
|
24
24
|
* configured (e.g. no client connected) so callers see a normal tool
|
|
25
25
|
* failure rather than an unhandled throw.
|
|
@@ -31,7 +31,7 @@ function proxyExecute(toolName: string) {
|
|
|
31
31
|
): Promise<ToolExecutionResult> => {
|
|
32
32
|
if (!context.proxyToolResolver) {
|
|
33
33
|
return {
|
|
34
|
-
content: `No proxy resolver configured for proxy tool "${toolName}". This tool requires
|
|
34
|
+
content: `No proxy resolver configured for proxy tool "${toolName}". This tool requires a connected desktop client.`,
|
|
35
35
|
isError: true,
|
|
36
36
|
};
|
|
37
37
|
}
|
|
@@ -131,7 +131,7 @@ export const computerUseTypeTextTool = {
|
|
|
131
131
|
export const computerUseKeyTool = {
|
|
132
132
|
name: "computer_use_key",
|
|
133
133
|
description:
|
|
134
|
-
"Press a key or keyboard shortcut. Supported: enter, tab, escape, backspace, delete, up, down, left, right, space, cmd+a, cmd+c, cmd+v, cmd+z, cmd+tab, cmd+w, shift+tab, option+tab",
|
|
134
|
+
"Press a key or keyboard shortcut. Supported: enter, tab, escape, backspace, delete, up, down, left, right, space, cmd+a, cmd+c, cmd+v, cmd+z, cmd+tab, cmd+w, shift+tab, option+tab. On Windows use ctrl/alt in place of cmd/option.",
|
|
135
135
|
category: "computer-use",
|
|
136
136
|
defaultRiskLevel: RiskLevel.Low,
|
|
137
137
|
executionTarget: "host",
|
|
@@ -141,7 +141,8 @@ export const computerUseKeyTool = {
|
|
|
141
141
|
properties: {
|
|
142
142
|
key: {
|
|
143
143
|
type: "string",
|
|
144
|
-
description:
|
|
144
|
+
description:
|
|
145
|
+
"Key or shortcut to press (e.g. enter, tab, ctrl+c, cmd+c)",
|
|
145
146
|
},
|
|
146
147
|
reasoning: {
|
|
147
148
|
type: "string",
|
|
@@ -223,6 +224,7 @@ export const computerUseDragTool = {
|
|
|
223
224
|
category: "computer-use",
|
|
224
225
|
defaultRiskLevel: RiskLevel.Low,
|
|
225
226
|
executionTarget: "host",
|
|
227
|
+
supportedClientOs: ["macos", "windows"],
|
|
226
228
|
|
|
227
229
|
input_schema: {
|
|
228
230
|
type: "object",
|
|
@@ -311,10 +313,11 @@ export const computerUseWaitTool = {
|
|
|
311
313
|
export const computerUseOpenAppTool = {
|
|
312
314
|
name: "computer_use_open_app",
|
|
313
315
|
description:
|
|
314
|
-
"Open or switch to a
|
|
316
|
+
"Open or switch to a desktop application by name. Preferred over cmd+tab / alt+tab for switching apps - more reliable and explicit.",
|
|
315
317
|
category: "computer-use",
|
|
316
318
|
defaultRiskLevel: RiskLevel.Low,
|
|
317
319
|
executionTarget: "host",
|
|
320
|
+
supportedClientOs: ["macos", "windows"],
|
|
318
321
|
|
|
319
322
|
input_schema: {
|
|
320
323
|
type: "object",
|
|
@@ -352,6 +355,7 @@ export const computerUseRunAppleScriptTool = {
|
|
|
352
355
|
category: "computer-use",
|
|
353
356
|
defaultRiskLevel: RiskLevel.Low,
|
|
354
357
|
executionTarget: "host",
|
|
358
|
+
supportedClientOs: ["macos"],
|
|
355
359
|
|
|
356
360
|
input_schema: {
|
|
357
361
|
type: "object",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Shared helper for computer-use skill wrapper scripts.
|
|
3
3
|
*
|
|
4
4
|
* Each wrapper calls forwardComputerUseProxyTool() to delegate execution to
|
|
5
|
-
* the proxy resolver, which forwards the call to the connected
|
|
5
|
+
* the proxy resolver, which forwards the call to the connected desktop client.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { ToolContext, ToolExecutionResult } from "../types.js";
|
|
@@ -20,7 +20,7 @@ export function forwardComputerUseProxyTool(
|
|
|
20
20
|
): Promise<ToolExecutionResult> {
|
|
21
21
|
if (!context.proxyToolResolver) {
|
|
22
22
|
return Promise.resolve({
|
|
23
|
-
content: `Cannot execute ${toolName}: no proxy resolver available. This tool requires a connected
|
|
23
|
+
content: `Cannot execute ${toolName}: no proxy resolver available. This tool requires a connected desktop client.`,
|
|
24
24
|
isError: true,
|
|
25
25
|
});
|
|
26
26
|
}
|
|
@@ -1,51 +1,3 @@
|
|
|
1
|
-
/** Opaque token representing a policy-checked authorization to use a credential. */
|
|
2
|
-
import type { CredentialInjectionTemplate } from "./policy-types.js";
|
|
3
|
-
export interface UsageToken {
|
|
4
|
-
tokenId: string;
|
|
5
|
-
credentialId: string;
|
|
6
|
-
service: string;
|
|
7
|
-
field: string;
|
|
8
|
-
toolName: string;
|
|
9
|
-
/** Timestamp (epoch ms) when this token was created. */
|
|
10
|
-
createdAt: number;
|
|
11
|
-
/** Whether this token has been consumed (single-use). */
|
|
12
|
-
consumed: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** Request to authorize the use of a credential. */
|
|
16
|
-
export interface AuthorizeRequest {
|
|
17
|
-
service: string;
|
|
18
|
-
field: string;
|
|
19
|
-
toolName: string;
|
|
20
|
-
/** Optional domain for domain-policy checking (used by browser tools). */
|
|
21
|
-
domain?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** Successful authorization result. */
|
|
25
|
-
export interface AuthorizeSuccess {
|
|
26
|
-
authorized: true;
|
|
27
|
-
token: UsageToken;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Denied authorization result. */
|
|
31
|
-
export interface AuthorizeDenied {
|
|
32
|
-
authorized: false;
|
|
33
|
-
reason: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export type AuthorizeResult = AuthorizeSuccess | AuthorizeDenied;
|
|
37
|
-
|
|
38
|
-
/** Result of consuming a token. */
|
|
39
|
-
export interface ConsumeResult {
|
|
40
|
-
success: boolean;
|
|
41
|
-
/** The storage key to read the secret from (only present on success). */
|
|
42
|
-
storageKey?: string;
|
|
43
|
-
/** The resolved value when a transient (one-time) credential was consumed. */
|
|
44
|
-
value?: string;
|
|
45
|
-
/** Error reason if consumption failed. */
|
|
46
|
-
reason?: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
1
|
/** Request for the broker to fill a browser field without exposing plaintext. */
|
|
50
2
|
export interface BrowserFillRequest {
|
|
51
3
|
service: string;
|
|
@@ -83,26 +35,3 @@ export interface ServerUseResult<T> {
|
|
|
83
35
|
result?: T;
|
|
84
36
|
reason?: string;
|
|
85
37
|
}
|
|
86
|
-
|
|
87
|
-
/** Request to look up a credential by ID for proxy injection (no secret exposed). */
|
|
88
|
-
export interface ServerUseByIdRequest {
|
|
89
|
-
credentialId: string;
|
|
90
|
-
requestingTool: string;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** Successful by-id lookup result - metadata + injection templates, never plaintext. */
|
|
94
|
-
export interface ServerUseByIdSuccess {
|
|
95
|
-
success: true;
|
|
96
|
-
credentialId: string;
|
|
97
|
-
service: string;
|
|
98
|
-
field: string;
|
|
99
|
-
injectionTemplates: CredentialInjectionTemplate[];
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/** Denied or not-found by-id lookup result. */
|
|
103
|
-
export interface ServerUseByIdDenied {
|
|
104
|
-
success: false;
|
|
105
|
-
reason: string;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export type ServerUseByIdResult = ServerUseByIdSuccess | ServerUseByIdDenied;
|