@vellumai/assistant 0.7.1 → 0.7.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 +32 -49
- package/Dockerfile +1 -0
- package/README.md +1 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
- package/bun.lock +26 -26
- package/docs/architecture/security.md +20 -0
- package/docs/plugins.md +7 -9
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +39 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
- package/node_modules/@vellumai/service-contracts/package.json +2 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +9 -0
- package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
- package/node_modules/@vellumai/twilio-client/package.json +18 -0
- package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
- package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
- package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
- package/openapi.yaml +565 -12
- package/package.json +6 -3
- package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
- package/src/__tests__/app-bundler.test.ts +170 -1
- package/src/__tests__/app-control-flow.test.ts +374 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
- package/src/__tests__/app-executors.test.ts +30 -43
- package/src/__tests__/approval-routes-http.test.ts +23 -6
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
- package/src/__tests__/assistant-event-hub.test.ts +109 -2
- package/src/__tests__/assistant-event.test.ts +10 -0
- package/src/__tests__/assistant-events-sse-hardening.test.ts +7 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -7
- package/src/__tests__/background-shell-host-bash.test.ts +14 -15
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
- package/src/__tests__/btw-routes.test.ts +13 -4
- package/src/__tests__/call-controller.test.ts +49 -1
- package/src/__tests__/call-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/channel-readiness-service.test.ts +59 -1
- package/src/__tests__/checker.test.ts +3 -4
- package/src/__tests__/config-loader-backfill.test.ts +90 -155
- package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +2 -2
- package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-lifecycle.test.ts +36 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-slash-commands.test.ts +0 -4
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +317 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
- package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
- package/src/__tests__/credentials-cli.test.ts +5 -12
- package/src/__tests__/cu-unified-flow.test.ts +185 -23
- package/src/__tests__/daemon-credential-client.test.ts +101 -19
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
- package/src/__tests__/heartbeat-service.test.ts +718 -1
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/host-app-control-proxy.test.ts +602 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +246 -47
- package/src/__tests__/host-bash-routes.test.ts +294 -0
- package/src/__tests__/host-browser-proxy.test.ts +24 -22
- package/src/__tests__/host-browser-routes.test.ts +39 -13
- package/src/__tests__/host-cu-proxy.test.ts +41 -52
- package/src/__tests__/host-cu-routes-targeted.test.ts +300 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +339 -0
- package/src/__tests__/host-file-proxy.test.ts +37 -43
- package/src/__tests__/host-file-read-tool.test.ts +17 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +262 -0
- package/src/__tests__/host-file-write-tool.test.ts +42 -1
- package/src/__tests__/host-proxy-base.test.ts +312 -0
- package/src/__tests__/host-shell-tool.test.ts +22 -4
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +583 -0
- package/src/__tests__/host-transfer-proxy.test.ts +121 -22
- package/src/__tests__/host-transfer-routes-targeted.test.ts +447 -0
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/identity-intro-cache.test.ts +29 -0
- package/src/__tests__/identity-routes.test.ts +103 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
- package/src/__tests__/inline-command-runner.test.ts +0 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
- package/src/__tests__/integration-status.test.ts +85 -5
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/migration-import-commit-http.test.ts +108 -2
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
- package/src/__tests__/prechat-onboarding-contract.test.ts +3 -1
- package/src/__tests__/process-message-background-slack.test.ts +2 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/public-ingress-urls.test.ts +97 -0
- package/src/__tests__/require-fresh-approval.test.ts +0 -1
- package/src/__tests__/retry-backoff.test.ts +87 -0
- package/src/__tests__/runtime-events-sse.test.ts +10 -6
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
- package/src/__tests__/skill-feature-flags.test.ts +43 -41
- package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
- package/src/__tests__/skill-load-inline-command.test.ts +0 -51
- package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
- package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
- package/src/__tests__/slack-channel-config.test.ts +9 -14
- package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/test-preload.ts +8 -0
- package/src/__tests__/tool-approval-handler.test.ts +3 -4
- package/src/__tests__/tool-audit-listener.test.ts +48 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +3 -16
- package/src/__tests__/twilio-routes.test.ts +3 -5
- package/src/__tests__/twilio-validation.test.ts +93 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
- package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
- package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- package/src/backup/__tests__/paths.test.ts +0 -22
- package/src/backup/__tests__/restore.test.ts +51 -151
- package/src/backup/paths.ts +2 -18
- package/src/backup/restore.ts +107 -231
- package/src/bundler/app-bundler.ts +51 -3
- package/src/calls/relay-server.ts +4 -44
- package/src/calls/twilio-config.ts +2 -17
- package/src/calls/twilio-rest.ts +33 -105
- package/src/calls/twilio-routes.ts +11 -12
- package/src/channels/types.ts +8 -7
- package/src/cli/commands/__tests__/backup.test.ts +6 -277
- package/src/cli/commands/__tests__/gateway.test.ts +288 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -1
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/clients.ts +36 -37
- package/src/cli/commands/contacts.ts +73 -0
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +15 -7
- package/src/cli/commands/domain.ts +66 -15
- package/src/cli/commands/gateway.ts +183 -0
- package/src/cli/commands/keys.ts +9 -6
- package/src/cli/commands/mcp.ts +116 -156
- package/src/cli/commands/memory-v2.ts +296 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/status.test.ts +13 -15
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +0 -18
- package/src/cli/lib/daemon-credential-client.ts +110 -28
- package/src/cli/program.ts +2 -0
- package/src/config/assistant-feature-flags.ts +67 -10
- package/src/config/bundled-skills/acp/SKILL.md +6 -0
- package/src/config/bundled-skills/acp/TOOLS.json +1 -22
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
- package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
- package/src/config/bundled-skills/app-control/SKILL.md +75 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
- package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
- package/src/config/bundled-skills/document/TOOLS.json +0 -8
- package/src/config/bundled-skills/followups/TOOLS.json +0 -12
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
- package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
- package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +19 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
- package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
- package/src/config/bundled-skills/settings/SKILL.md +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +0 -12
- package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
- package/src/config/bundled-skills/subagent/SKILL.md +6 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
- package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
- package/src/config/bundled-tool-registry.ts +21 -0
- package/src/config/env-registry.ts +0 -2
- package/src/config/env.ts +19 -12
- package/src/config/feature-flag-registry.json +21 -133
- package/src/config/loader.ts +73 -99
- package/src/config/sanitize-for-transfer.ts +2 -0
- package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +7 -4
- package/src/config/schemas/calls.ts +0 -9
- package/src/config/schemas/heartbeat.ts +63 -0
- package/src/config/schemas/ingress.ts +10 -6
- package/src/config/schemas/llm.ts +5 -10
- package/src/config/schemas/memory-lifecycle.ts +77 -24
- package/src/config/schemas/memory-v2.ts +48 -4
- package/src/config/schemas/platform.ts +6 -0
- package/src/config/schemas/services.ts +1 -15
- package/src/config/schemas/skills.ts +0 -6
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/contacts/contact-store.ts +0 -30
- package/src/contacts/contacts-write.ts +0 -27
- package/src/context/window-manager.ts +1 -2
- package/src/credential-execution/feature-gates.ts +10 -10
- package/src/credential-execution/process-manager.ts +12 -41
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +126 -5
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +4 -3
- package/src/daemon/conversation-agent-loop-handlers.ts +21 -3
- package/src/daemon/conversation-agent-loop.ts +32 -28
- package/src/daemon/conversation-lifecycle.ts +8 -1
- package/src/daemon/conversation-process.ts +16 -11
- package/src/daemon/conversation-runtime-assembly.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +125 -4
- package/src/daemon/conversation-tool-setup.ts +16 -55
- package/src/daemon/conversation.ts +21 -2
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/shared.ts +4 -1
- package/src/daemon/host-app-control-proxy.ts +293 -0
- package/src/daemon/host-bash-proxy.ts +84 -74
- package/src/daemon/host-browser-proxy.ts +67 -82
- package/src/daemon/host-cu-proxy.ts +81 -86
- package/src/daemon/host-file-proxy.ts +93 -69
- package/src/daemon/host-proxy-base.ts +294 -0
- package/src/daemon/host-proxy-preactivation.ts +82 -0
- package/src/daemon/host-transfer-proxy.ts +247 -129
- package/src/daemon/lifecycle.ts +115 -117
- package/src/daemon/message-protocol.ts +3 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +11 -8
- package/src/daemon/message-types/host-app-control.ts +150 -0
- package/src/daemon/message-types/host-bash.ts +4 -0
- package/src/daemon/message-types/host-cu.ts +2 -0
- package/src/daemon/message-types/host-file.ts +4 -0
- package/src/daemon/message-types/host-transfer.ts +3 -0
- package/src/daemon/message-types/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/process-message.ts +18 -1
- package/src/daemon/shutdown-handlers.ts +0 -3
- package/src/daemon/tool-setup-types.ts +51 -0
- package/src/daemon/tool-side-effects.ts +1 -1
- package/src/events/tool-audit-listener.ts +2 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +15 -7
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +216 -0
- package/src/heartbeat/heartbeat-run-store.ts +236 -0
- package/src/heartbeat/heartbeat-service.ts +280 -49
- package/src/home/__tests__/post-connect-feed.test.ts +99 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
- package/src/home/__tests__/suggested-prompts.test.ts +89 -0
- package/src/home/post-connect-feed.ts +68 -0
- package/src/home/relationship-state-writer.ts +17 -92
- package/src/home/suggested-prompts.ts +46 -10
- package/src/inbound/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/assistant-server.ts +14 -1
- package/src/ipc/cli-client.ts +32 -1
- package/src/live-voice/live-voice-metrics.ts +10 -10
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
- package/src/mcp/mcp-auth-orchestrator.ts +213 -0
- package/src/mcp/mcp-auth-state.ts +133 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
- package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
- package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
- package/src/memory/anisotropy.test.ts +247 -0
- package/src/memory/anisotropy.ts +443 -0
- package/src/memory/auto-analysis-constants.ts +17 -0
- package/src/memory/auto-analysis-guard.ts +5 -15
- package/src/memory/canonical-guardian-store.ts +7 -7
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
- package/src/memory/context-search/agent-protocol.ts +6 -6
- package/src/memory/context-search/agent-runner.ts +32 -7
- package/src/memory/context-search/sources/memory-v2.ts +17 -5
- package/src/memory/conversation-crud.ts +1 -1
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/db-init.ts +4 -0
- package/src/memory/embedding-backend.ts +9 -21
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +49 -4
- package/src/memory/graph/conversation-graph-memory.ts +1 -24
- package/src/memory/graph/graph-search.ts +8 -0
- package/src/memory/graph/retriever.ts +28 -0
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
- package/src/memory/jobs/embed-concept-page.ts +28 -2
- package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
- package/src/memory/jobs-store.ts +66 -22
- package/src/memory/jobs-worker.ts +112 -63
- package/src/memory/memory-v2-activation-log-store.ts +1 -1
- package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
- package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +50 -20
- package/src/memory/schema/infrastructure.ts +15 -0
- package/src/memory/search/semantic.ts +7 -0
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/v2/__tests__/activation.test.ts +77 -95
- package/src/memory/v2/__tests__/injection.test.ts +43 -21
- package/src/memory/v2/__tests__/sim.test.ts +166 -6
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +0 -1
- package/src/memory/v2/activation.ts +69 -88
- package/src/memory/v2/consolidation-job.ts +3 -5
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/injection.ts +86 -53
- package/src/memory/v2/prompts/consolidation.ts +312 -91
- package/src/memory/v2/qdrant.ts +99 -1
- package/src/memory/v2/sim.ts +126 -16
- package/src/memory/v2/skill-qdrant.ts +12 -3
- package/src/memory/v2/skill-store.ts +16 -1
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +6 -5
- package/src/messaging/providers/gmail/types.ts +0 -49
- package/src/messaging/providers/slack/adapter.ts +1 -31
- package/src/messaging/providers/slack/types.ts +0 -32
- package/src/notifications/README.md +10 -10
- package/src/notifications/broadcaster.ts +1 -1
- package/src/notifications/guardian-question-mode.ts +5 -5
- package/src/oauth/connect-orchestrator.ts +4 -0
- package/src/oauth/credential-token-resolver.ts +1 -3
- package/src/oauth/manual-token-connection.ts +0 -4
- package/src/outbound-proxy/index.ts +1 -37
- package/src/outbound-proxy/logging.ts +1 -1
- package/src/outbound-proxy/policy.ts +6 -5
- package/src/outbound-proxy/router.ts +2 -1
- package/src/permissions/approval-policy.test.ts +6 -275
- package/src/permissions/approval-policy.ts +0 -51
- package/src/permissions/checker.test.ts +0 -1
- package/src/permissions/checker.ts +3 -17
- package/src/permissions/gateway-threshold-reader.ts +2 -0
- package/src/permissions/prompter.ts +34 -1
- package/src/permissions/secret-prompter.ts +6 -2
- package/src/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/system-prompt.ts +3 -18
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/runtime/assistant-event-hub.ts +118 -96
- package/src/runtime/assistant-event.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/middleware.ts +0 -96
- package/src/runtime/auth/route-policy.ts +19 -0
- package/src/runtime/btw-sidechain.ts +2 -3
- package/src/runtime/channel-invite-transport.ts +2 -48
- package/src/runtime/channel-invite-transports/email.ts +1 -1
- package/src/runtime/channel-invite-transports/slack.ts +1 -1
- package/src/runtime/channel-invite-transports/telegram.ts +1 -1
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
- package/src/runtime/channel-invite-types.ts +54 -0
- package/src/runtime/channel-readiness-service.ts +32 -13
- package/src/runtime/http-server.ts +3 -329
- package/src/runtime/http-types.ts +0 -5
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
- package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
- package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
- package/src/runtime/migrations/migration-transport.ts +7 -7
- package/src/runtime/migrations/vbundle-builder.ts +327 -60
- package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
- package/src/runtime/migrations/vbundle-importer.ts +245 -68
- package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
- package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
- package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
- package/src/runtime/migrations/vbundle-validator.ts +114 -0
- package/src/runtime/pending-interactions.ts +35 -9
- package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
- package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
- package/src/runtime/routes/approval-interception-types.ts +13 -0
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
- package/src/runtime/routes/backup-routes.ts +15 -38
- package/src/runtime/routes/btw-routes.ts +14 -37
- package/src/runtime/routes/client-routes.ts +1 -0
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/conversation-query-routes.ts +36 -1
- package/src/runtime/routes/conversation-routes.ts +30 -13
- package/src/runtime/routes/document-pdf-renderer.ts +165 -0
- package/src/runtime/routes/documents-routes.ts +30 -0
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +12 -6
- package/src/runtime/routes/gateway-log-routes.ts +79 -0
- package/src/runtime/routes/guardian-approval-interception.ts +2 -8
- package/src/runtime/routes/heartbeat-routes.ts +103 -38
- package/src/runtime/routes/host-app-control-routes.ts +134 -0
- package/src/runtime/routes/host-bash-routes.ts +36 -6
- package/src/runtime/routes/host-browser-routes.ts +108 -13
- package/src/runtime/routes/host-cu-routes.ts +44 -14
- package/src/runtime/routes/host-file-routes.ts +33 -10
- package/src/runtime/routes/host-transfer-routes.ts +64 -24
- package/src/runtime/routes/http-adapter.ts +1 -0
- package/src/runtime/routes/identity-intro-cache.ts +30 -0
- package/src/runtime/routes/identity-routes.ts +15 -43
- package/src/runtime/routes/inbound-message-handler.ts +1 -9
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +8 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +441 -1
- package/src/runtime/routes/migration-routes.ts +96 -0
- package/src/runtime/routes/schedule-routes.ts +7 -0
- package/src/runtime/verification-templates.ts +4 -7
- package/src/schedule/integration-status.ts +66 -2
- package/src/schedule/recurrence-engine.ts +4 -1
- package/src/schedule/retry-backoff.ts +18 -0
- package/src/schedule/retry-policy.ts +82 -0
- package/src/schedule/schedule-recovery.ts +64 -0
- package/src/schedule/schedule-store.ts +106 -2
- package/src/schedule/scheduler-types.ts +25 -0
- package/src/schedule/scheduler.ts +63 -38
- package/src/security/oauth-callback-registry.ts +8 -0
- package/src/sequence/analytics.ts +5 -5
- package/src/sequence/engine.ts +1 -1
- package/src/skills/catalog-files.ts +2 -8
- package/src/skills/include-graph.ts +5 -5
- package/src/skills/remote-skill-policy.ts +5 -5
- package/src/skills/skill-file-provider.ts +1 -1
- package/src/skills/skill-file-types.ts +13 -0
- package/src/skills/skillssh-audit-types.ts +28 -0
- package/src/skills/skillssh-registry.ts +8 -21
- package/src/telemetry/types.ts +2 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
- package/src/tools/apps/executors.ts +56 -69
- package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
- package/src/tools/browser/cdp-client/factory.ts +23 -24
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/computer-use/definitions.ts +42 -20
- package/src/tools/executor.ts +2 -0
- package/src/tools/host-filesystem/edit.ts +26 -0
- package/src/tools/host-filesystem/read.ts +26 -0
- package/src/tools/host-filesystem/transfer.ts +31 -1
- package/src/tools/host-filesystem/write.ts +26 -0
- package/src/tools/host-terminal/host-shell.ts +58 -0
- package/src/tools/schedule/create.ts +6 -0
- package/src/tools/schedule/list.ts +2 -0
- package/src/tools/schedule/update.ts +10 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
- package/src/tools/shared/filesystem/path-policy.ts +25 -1
- package/src/tools/skills/load.ts +0 -32
- package/src/tools/tool-approval-handler.ts +1 -5
- package/src/tools/types.ts +4 -0
- package/src/usage/pricing.ts +1 -1
- package/src/workspace/hatched-date.ts +86 -0
- package/src/workspace/migrations/003-seed-device-id.ts +1 -1
- package/src/workspace/migrations/006-services-config.ts +8 -5
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
- package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/utils.ts +21 -0
- package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
- package/src/__tests__/twilio-rest.test.ts +0 -34
- package/src/backup/__tests__/backup-key.test.ts +0 -152
- package/src/backup/__tests__/backup-worker.test.ts +0 -782
- package/src/backup/__tests__/offsite-writer.test.ts +0 -641
- package/src/backup/__tests__/stream-crypt.test.ts +0 -228
- package/src/backup/backup-key.ts +0 -137
- package/src/backup/backup-worker.ts +0 -472
- package/src/backup/offsite-writer.ts +0 -222
- package/src/backup/stream-crypt.ts +0 -263
- package/src/daemon/message-types/pairing.ts +0 -58
- package/src/outbound-proxy/config.ts +0 -20
- package/src/outbound-proxy/health.ts +0 -18
- package/src/outbound-proxy/types.ts +0 -150
- package/src/runtime/capability-tokens.ts +0 -190
- package/src/signals/mcp-reload.ts +0 -18
|
@@ -21,12 +21,6 @@ function proxyExecute(): Promise<ToolExecutionResult> {
|
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
const activityProperty = {
|
|
25
|
-
type: "string" as const,
|
|
26
|
-
description:
|
|
27
|
-
"Brief non-technical explanation of why this tool is being called",
|
|
28
|
-
};
|
|
29
|
-
|
|
30
24
|
// ---------------------------------------------------------------------------
|
|
31
25
|
// click (unified - click_type selects single / double / right)
|
|
32
26
|
// ---------------------------------------------------------------------------
|
|
@@ -69,7 +63,11 @@ export const computerUseClickTool: Tool = {
|
|
|
69
63
|
description:
|
|
70
64
|
"Explanation of what you see and why you are clicking here",
|
|
71
65
|
},
|
|
72
|
-
|
|
66
|
+
target_client_id: {
|
|
67
|
+
type: "string",
|
|
68
|
+
description:
|
|
69
|
+
"ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`.",
|
|
70
|
+
},
|
|
73
71
|
},
|
|
74
72
|
required: ["reasoning"],
|
|
75
73
|
},
|
|
@@ -106,7 +104,11 @@ export const computerUseTypeTextTool: Tool = {
|
|
|
106
104
|
type: "string",
|
|
107
105
|
description: "Explanation of what you are typing and why",
|
|
108
106
|
},
|
|
109
|
-
|
|
107
|
+
target_client_id: {
|
|
108
|
+
type: "string",
|
|
109
|
+
description:
|
|
110
|
+
"ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`.",
|
|
111
|
+
},
|
|
110
112
|
},
|
|
111
113
|
required: ["text", "reasoning"],
|
|
112
114
|
},
|
|
@@ -144,7 +146,11 @@ export const computerUseKeyTool: Tool = {
|
|
|
144
146
|
type: "string",
|
|
145
147
|
description: "Explanation of why you are pressing this key",
|
|
146
148
|
},
|
|
147
|
-
|
|
149
|
+
target_client_id: {
|
|
150
|
+
type: "string",
|
|
151
|
+
description:
|
|
152
|
+
"ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`.",
|
|
153
|
+
},
|
|
148
154
|
},
|
|
149
155
|
required: ["key", "reasoning"],
|
|
150
156
|
},
|
|
@@ -199,7 +205,11 @@ export const computerUseScrollTool: Tool = {
|
|
|
199
205
|
type: "string",
|
|
200
206
|
description: "Explanation of why you are scrolling",
|
|
201
207
|
},
|
|
202
|
-
|
|
208
|
+
target_client_id: {
|
|
209
|
+
type: "string",
|
|
210
|
+
description:
|
|
211
|
+
"ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`.",
|
|
212
|
+
},
|
|
203
213
|
},
|
|
204
214
|
required: ["direction", "amount", "reasoning"],
|
|
205
215
|
},
|
|
@@ -260,7 +270,11 @@ export const computerUseDragTool: Tool = {
|
|
|
260
270
|
type: "string",
|
|
261
271
|
description: "Explanation of what you are dragging and why",
|
|
262
272
|
},
|
|
263
|
-
|
|
273
|
+
target_client_id: {
|
|
274
|
+
type: "string",
|
|
275
|
+
description:
|
|
276
|
+
"ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`.",
|
|
277
|
+
},
|
|
264
278
|
},
|
|
265
279
|
required: ["reasoning"],
|
|
266
280
|
},
|
|
@@ -296,7 +310,11 @@ export const computerUseWaitTool: Tool = {
|
|
|
296
310
|
type: "string",
|
|
297
311
|
description: "Explanation of what you are waiting for",
|
|
298
312
|
},
|
|
299
|
-
|
|
313
|
+
target_client_id: {
|
|
314
|
+
type: "string",
|
|
315
|
+
description:
|
|
316
|
+
"ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`.",
|
|
317
|
+
},
|
|
300
318
|
},
|
|
301
319
|
required: ["duration_ms", "reasoning"],
|
|
302
320
|
},
|
|
@@ -335,7 +353,11 @@ export const computerUseOpenAppTool: Tool = {
|
|
|
335
353
|
description:
|
|
336
354
|
"Explanation of why you need to open or switch to this app",
|
|
337
355
|
},
|
|
338
|
-
|
|
356
|
+
target_client_id: {
|
|
357
|
+
type: "string",
|
|
358
|
+
description:
|
|
359
|
+
"ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`.",
|
|
360
|
+
},
|
|
339
361
|
},
|
|
340
362
|
required: ["app_name", "reasoning"],
|
|
341
363
|
},
|
|
@@ -373,7 +395,11 @@ export const computerUseRunAppleScriptTool: Tool = {
|
|
|
373
395
|
description:
|
|
374
396
|
"Explanation of what this script does and why AppleScript is better than UI interaction for this step",
|
|
375
397
|
},
|
|
376
|
-
|
|
398
|
+
target_client_id: {
|
|
399
|
+
type: "string",
|
|
400
|
+
description:
|
|
401
|
+
"ID of the specific client to target. Required when multiple clients support host_cu; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_cu`.",
|
|
402
|
+
},
|
|
377
403
|
},
|
|
378
404
|
required: ["script", "reasoning"],
|
|
379
405
|
},
|
|
@@ -406,7 +432,6 @@ export const computerUseDoneTool: Tool = {
|
|
|
406
432
|
type: "string",
|
|
407
433
|
description: "Human-readable summary of what was accomplished",
|
|
408
434
|
},
|
|
409
|
-
activity: activityProperty,
|
|
410
435
|
},
|
|
411
436
|
required: ["summary"],
|
|
412
437
|
},
|
|
@@ -443,7 +468,6 @@ export const computerUseRespondTool: Tool = {
|
|
|
443
468
|
type: "string",
|
|
444
469
|
description: "Explanation of how you determined the answer",
|
|
445
470
|
},
|
|
446
|
-
activity: activityProperty,
|
|
447
471
|
},
|
|
448
472
|
required: ["answer", "reasoning"],
|
|
449
473
|
},
|
|
@@ -471,10 +495,8 @@ const computerUseObserveTool: Tool = {
|
|
|
471
495
|
description: this.description,
|
|
472
496
|
input_schema: {
|
|
473
497
|
type: "object",
|
|
474
|
-
properties: {
|
|
475
|
-
|
|
476
|
-
},
|
|
477
|
-
required: ["activity"],
|
|
498
|
+
properties: {},
|
|
499
|
+
required: [],
|
|
478
500
|
},
|
|
479
501
|
};
|
|
480
502
|
},
|
package/src/tools/executor.ts
CHANGED
|
@@ -406,6 +406,8 @@ export class ToolExecutor {
|
|
|
406
406
|
requestId: context.requestId,
|
|
407
407
|
riskLevel,
|
|
408
408
|
matchedTrustRuleId: permMatchedTrustRuleId,
|
|
409
|
+
approvalMode: permApprovalMode,
|
|
410
|
+
approvalReason: permApprovalReason,
|
|
409
411
|
decision,
|
|
410
412
|
durationMs,
|
|
411
413
|
result: safeResult,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { supportsHostProxy } from "../../channels/types.js";
|
|
1
2
|
import { HostFileProxy } from "../../daemon/host-file-proxy.js";
|
|
2
3
|
import { RiskLevel } from "../../permissions/types.js";
|
|
3
4
|
import type { ToolDefinition } from "../../providers/types.js";
|
|
5
|
+
import { assistantEventHub } from "../../runtime/assistant-event-hub.js";
|
|
4
6
|
import { FileSystemOps } from "../shared/filesystem/file-ops-service.js";
|
|
5
7
|
import { formatEditDiff } from "../shared/filesystem/format-diff.js";
|
|
6
8
|
import { hostPolicy } from "../shared/filesystem/path-policy.js";
|
|
@@ -37,6 +39,11 @@ class HostFileEditTool implements Tool {
|
|
|
37
39
|
description:
|
|
38
40
|
"Replace all occurrences instead of requiring a unique match (default: false)",
|
|
39
41
|
},
|
|
42
|
+
target_client_id: {
|
|
43
|
+
type: "string",
|
|
44
|
+
description:
|
|
45
|
+
"ID of the specific client to execute this on. Required when multiple clients support host_file; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_file`.",
|
|
46
|
+
},
|
|
40
47
|
},
|
|
41
48
|
required: ["path", "old_string", "new_string"],
|
|
42
49
|
},
|
|
@@ -84,6 +91,24 @@ class HostFileEditTool implements Tool {
|
|
|
84
91
|
|
|
85
92
|
const replaceAll = input.replace_all === true;
|
|
86
93
|
|
|
94
|
+
const targetClientId =
|
|
95
|
+
typeof input.target_client_id === "string" && input.target_client_id !== ""
|
|
96
|
+
? input.target_client_id
|
|
97
|
+
: undefined;
|
|
98
|
+
|
|
99
|
+
const transportInterface = context.transportInterface;
|
|
100
|
+
if (
|
|
101
|
+
targetClientId == null &&
|
|
102
|
+
transportInterface != null &&
|
|
103
|
+
!supportsHostProxy(transportInterface) &&
|
|
104
|
+
assistantEventHub.listClientsByCapability("host_file").length > 1
|
|
105
|
+
) {
|
|
106
|
+
return {
|
|
107
|
+
content: `Error: multiple clients support host_file. Specify which client to use with \`target_client_id\`. Run \`assistant clients list --capability host_file\` to see client IDs and labels.`,
|
|
108
|
+
isError: true,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
87
112
|
// Proxy to connected client for execution on the user's machine
|
|
88
113
|
// when a capable client is available (managed/cloud-hosted mode).
|
|
89
114
|
if (HostFileProxy.instance.isAvailable()) {
|
|
@@ -94,6 +119,7 @@ class HostFileEditTool implements Tool {
|
|
|
94
119
|
old_string: oldString as string,
|
|
95
120
|
new_string: newString as string,
|
|
96
121
|
replace_all: replaceAll,
|
|
122
|
+
targetClientId,
|
|
97
123
|
},
|
|
98
124
|
context.conversationId,
|
|
99
125
|
context.signal,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { extname } from "node:path";
|
|
2
2
|
|
|
3
|
+
import { supportsHostProxy } from "../../channels/types.js";
|
|
3
4
|
import { HostFileProxy } from "../../daemon/host-file-proxy.js";
|
|
4
5
|
import { RiskLevel } from "../../permissions/types.js";
|
|
5
6
|
import type { ToolDefinition } from "../../providers/types.js";
|
|
7
|
+
import { assistantEventHub } from "../../runtime/assistant-event-hub.js";
|
|
6
8
|
import { FileSystemOps } from "../shared/filesystem/file-ops-service.js";
|
|
7
9
|
import {
|
|
8
10
|
IMAGE_EXTENSIONS,
|
|
@@ -37,6 +39,11 @@ class HostFileReadTool implements Tool {
|
|
|
37
39
|
type: "number",
|
|
38
40
|
description: "Maximum number of lines to read",
|
|
39
41
|
},
|
|
42
|
+
target_client_id: {
|
|
43
|
+
type: "string",
|
|
44
|
+
description:
|
|
45
|
+
"ID of the specific client to execute this on. Required when multiple clients support host_file; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_file`.",
|
|
46
|
+
},
|
|
40
47
|
},
|
|
41
48
|
required: ["path"],
|
|
42
49
|
},
|
|
@@ -55,6 +62,24 @@ class HostFileReadTool implements Tool {
|
|
|
55
62
|
};
|
|
56
63
|
}
|
|
57
64
|
|
|
65
|
+
const targetClientId =
|
|
66
|
+
typeof input.target_client_id === "string" && input.target_client_id !== ""
|
|
67
|
+
? input.target_client_id
|
|
68
|
+
: undefined;
|
|
69
|
+
|
|
70
|
+
const transportInterface = context.transportInterface;
|
|
71
|
+
if (
|
|
72
|
+
targetClientId == null &&
|
|
73
|
+
transportInterface != null &&
|
|
74
|
+
!supportsHostProxy(transportInterface) &&
|
|
75
|
+
assistantEventHub.listClientsByCapability("host_file").length > 1
|
|
76
|
+
) {
|
|
77
|
+
return {
|
|
78
|
+
content: `Error: multiple clients support host_file. Specify which client to use with \`target_client_id\`. Run \`assistant clients list --capability host_file\` to see client IDs and labels.`,
|
|
79
|
+
isError: true,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
58
83
|
// Proxy to connected client for execution on the user's machine
|
|
59
84
|
// when a capable client is available (managed/cloud-hosted mode),
|
|
60
85
|
// including image reads that need the host filesystem view.
|
|
@@ -65,6 +90,7 @@ class HostFileReadTool implements Tool {
|
|
|
65
90
|
path: rawPath,
|
|
66
91
|
offset: typeof input.offset === "number" ? input.offset : undefined,
|
|
67
92
|
limit: typeof input.limit === "number" ? input.limit : undefined,
|
|
93
|
+
targetClientId,
|
|
68
94
|
},
|
|
69
95
|
context.conversationId,
|
|
70
96
|
context.signal,
|
|
@@ -2,16 +2,18 @@ import { constants } from "node:fs";
|
|
|
2
2
|
import { copyFile, lstat, mkdir, realpath } from "node:fs/promises";
|
|
3
3
|
import { dirname, isAbsolute } from "node:path";
|
|
4
4
|
|
|
5
|
+
import { supportsHostProxy } from "../../channels/types.js";
|
|
5
6
|
import { HostTransferProxy } from "../../daemon/host-transfer-proxy.js";
|
|
6
7
|
import { RiskLevel } from "../../permissions/types.js";
|
|
7
8
|
import type { ToolDefinition } from "../../providers/types.js";
|
|
9
|
+
import { assistantEventHub } from "../../runtime/assistant-event-hub.js";
|
|
8
10
|
import { sandboxPolicy } from "../shared/filesystem/path-policy.js";
|
|
9
11
|
import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
|
|
10
12
|
|
|
11
13
|
class HostFileTransferTool implements Tool {
|
|
12
14
|
name = "host_file_transfer";
|
|
13
15
|
description =
|
|
14
|
-
"Copy a file between the assistant's workspace and the user's host machine. Set direction to 'to_host' to send a workspace file to the host, or 'to_sandbox' to pull a host file into the workspace.";
|
|
16
|
+
"Copy a file between the assistant's workspace and the user's host machine. Set direction to 'to_host' to send a workspace file to the host, or 'to_sandbox' to pull a host file into the workspace. When multiple clients support host_file, specify which one to use with target_client_id.";
|
|
15
17
|
category = "host-filesystem";
|
|
16
18
|
defaultRiskLevel = RiskLevel.Medium;
|
|
17
19
|
|
|
@@ -48,6 +50,11 @@ class HostFileTransferTool implements Tool {
|
|
|
48
50
|
description:
|
|
49
51
|
"Brief description of why the file is being transferred (for audit logging)",
|
|
50
52
|
},
|
|
53
|
+
target_client_id: {
|
|
54
|
+
type: "string",
|
|
55
|
+
description:
|
|
56
|
+
"ID of the specific client to transfer files to/from. Required when multiple clients support host_file; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_file`.",
|
|
57
|
+
},
|
|
51
58
|
},
|
|
52
59
|
required: ["source_path", "dest_path", "direction"],
|
|
53
60
|
},
|
|
@@ -85,6 +92,20 @@ class HostFileTransferTool implements Tool {
|
|
|
85
92
|
|
|
86
93
|
const overwrite = input.overwrite === true;
|
|
87
94
|
|
|
95
|
+
const targetClientId =
|
|
96
|
+
typeof input.target_client_id === "string" && input.target_client_id !== ""
|
|
97
|
+
? input.target_client_id
|
|
98
|
+
: undefined;
|
|
99
|
+
|
|
100
|
+
if (
|
|
101
|
+
targetClientId == null &&
|
|
102
|
+
context.transportInterface != null &&
|
|
103
|
+
!supportsHostProxy(context.transportInterface) &&
|
|
104
|
+
assistantEventHub.listClientsByCapability("host_file").length > 1
|
|
105
|
+
) {
|
|
106
|
+
return { content: `Error: multiple clients support host_file. Specify which client to use with \`target_client_id\`. Run \`assistant clients list --capability host_file\` to see client IDs and labels.`, isError: true };
|
|
107
|
+
}
|
|
108
|
+
|
|
88
109
|
// Validate that host-side paths are absolute.
|
|
89
110
|
if (direction === "to_host" && !isAbsolute(destPath)) {
|
|
90
111
|
return {
|
|
@@ -134,6 +155,7 @@ class HostFileTransferTool implements Tool {
|
|
|
134
155
|
destPath,
|
|
135
156
|
overwrite,
|
|
136
157
|
conversationId: context.conversationId,
|
|
158
|
+
targetClientId,
|
|
137
159
|
},
|
|
138
160
|
context.signal,
|
|
139
161
|
);
|
|
@@ -144,11 +166,19 @@ class HostFileTransferTool implements Tool {
|
|
|
144
166
|
destPath: resolvedDestPath,
|
|
145
167
|
overwrite,
|
|
146
168
|
conversationId: context.conversationId,
|
|
169
|
+
targetClientId,
|
|
147
170
|
},
|
|
148
171
|
context.signal,
|
|
149
172
|
);
|
|
150
173
|
}
|
|
151
174
|
|
|
175
|
+
if (targetClientId != null) {
|
|
176
|
+
return {
|
|
177
|
+
content: `Error: target_client_id '${targetClientId}' was specified but no host client is available. Ensure the client is connected.`,
|
|
178
|
+
isError: true,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
152
182
|
// Local mode: direct filesystem copy.
|
|
153
183
|
return this.executeLocal(resolvedSourcePath, resolvedDestPath, overwrite);
|
|
154
184
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { supportsHostProxy } from "../../channels/types.js";
|
|
1
2
|
import { HostFileProxy } from "../../daemon/host-file-proxy.js";
|
|
2
3
|
import { RiskLevel } from "../../permissions/types.js";
|
|
3
4
|
import type { ToolDefinition } from "../../providers/types.js";
|
|
5
|
+
import { assistantEventHub } from "../../runtime/assistant-event-hub.js";
|
|
4
6
|
import { FileSystemOps } from "../shared/filesystem/file-ops-service.js";
|
|
5
7
|
import { formatWriteSummary } from "../shared/filesystem/format-diff.js";
|
|
6
8
|
import { hostPolicy } from "../shared/filesystem/path-policy.js";
|
|
@@ -28,6 +30,11 @@ class HostFileWriteTool implements Tool {
|
|
|
28
30
|
type: "string",
|
|
29
31
|
description: "The content to write to the file",
|
|
30
32
|
},
|
|
33
|
+
target_client_id: {
|
|
34
|
+
type: "string",
|
|
35
|
+
description:
|
|
36
|
+
"ID of the specific client to execute this on. Required when multiple clients support host_file; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_file`.",
|
|
37
|
+
},
|
|
31
38
|
},
|
|
32
39
|
required: ["path", "content"],
|
|
33
40
|
},
|
|
@@ -54,6 +61,24 @@ class HostFileWriteTool implements Tool {
|
|
|
54
61
|
};
|
|
55
62
|
}
|
|
56
63
|
|
|
64
|
+
const targetClientId =
|
|
65
|
+
typeof input.target_client_id === "string" && input.target_client_id !== ""
|
|
66
|
+
? input.target_client_id
|
|
67
|
+
: undefined;
|
|
68
|
+
|
|
69
|
+
const transportInterface = context.transportInterface;
|
|
70
|
+
if (
|
|
71
|
+
targetClientId == null &&
|
|
72
|
+
transportInterface != null &&
|
|
73
|
+
!supportsHostProxy(transportInterface) &&
|
|
74
|
+
assistantEventHub.listClientsByCapability("host_file").length > 1
|
|
75
|
+
) {
|
|
76
|
+
return {
|
|
77
|
+
content: `Error: multiple clients support host_file. Specify which client to use with \`target_client_id\`. Run \`assistant clients list --capability host_file\` to see client IDs and labels.`,
|
|
78
|
+
isError: true,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
57
82
|
// Proxy to connected client for execution on the user's machine
|
|
58
83
|
// when a capable client is available (managed/cloud-hosted mode).
|
|
59
84
|
if (HostFileProxy.instance.isAvailable()) {
|
|
@@ -62,6 +87,7 @@ class HostFileWriteTool implements Tool {
|
|
|
62
87
|
operation: "write",
|
|
63
88
|
path: rawPath,
|
|
64
89
|
content: fileContent,
|
|
90
|
+
targetClientId,
|
|
65
91
|
},
|
|
66
92
|
context.conversationId,
|
|
67
93
|
context.signal,
|
|
@@ -18,6 +18,7 @@ import { existsSync } from "node:fs";
|
|
|
18
18
|
import { homedir } from "node:os";
|
|
19
19
|
import { isAbsolute } from "node:path";
|
|
20
20
|
|
|
21
|
+
import { supportsHostProxy } from "../../channels/types.js";
|
|
21
22
|
import { getConfig } from "../../config/loader.js";
|
|
22
23
|
import { isCesShellLockdownEnabled } from "../../credential-execution/feature-gates.js";
|
|
23
24
|
import { HostBashProxy } from "../../daemon/host-bash-proxy.js";
|
|
@@ -25,6 +26,7 @@ import { RiskLevel } from "../../permissions/types.js";
|
|
|
25
26
|
import type { ToolDefinition } from "../../providers/types.js";
|
|
26
27
|
import { isUntrustedTrustClass } from "../../runtime/actor-trust-resolver.js";
|
|
27
28
|
import { wakeAgentForOpportunity } from "../../runtime/agent-wake.js";
|
|
29
|
+
import { assistantEventHub } from "../../runtime/assistant-event-hub.js";
|
|
28
30
|
import { redactSecrets } from "../../security/secret-scanner.js";
|
|
29
31
|
import { getLogger } from "../../util/logger.js";
|
|
30
32
|
import {
|
|
@@ -131,6 +133,11 @@ class HostShellTool implements Tool {
|
|
|
131
133
|
description:
|
|
132
134
|
"Run the command in the background on the host machine. The tool returns immediately with a background tool ID. When the process exits, its output is delivered to the conversation as a wake.",
|
|
133
135
|
},
|
|
136
|
+
target_client_id: {
|
|
137
|
+
type: "string",
|
|
138
|
+
description:
|
|
139
|
+
"ID of the specific client to execute this command on. Required when multiple clients support host_bash; omit when only one client is connected. Obtain IDs from `assistant clients list --capability host_bash`.",
|
|
140
|
+
},
|
|
134
141
|
},
|
|
135
142
|
required: ["command", "activity"],
|
|
136
143
|
},
|
|
@@ -173,6 +180,11 @@ class HostShellTool implements Tool {
|
|
|
173
180
|
}
|
|
174
181
|
const background = input.background === true;
|
|
175
182
|
|
|
183
|
+
const targetClientId =
|
|
184
|
+
typeof input.target_client_id === "string" && input.target_client_id !== ""
|
|
185
|
+
? input.target_client_id
|
|
186
|
+
: undefined;
|
|
187
|
+
|
|
176
188
|
const config = getConfig();
|
|
177
189
|
const { shellDefaultTimeoutSec, shellMaxTimeoutSec } = config.timeouts;
|
|
178
190
|
|
|
@@ -190,6 +202,50 @@ class HostShellTool implements Tool {
|
|
|
190
202
|
isCesShellLockdownEnabled(config) &&
|
|
191
203
|
isUntrustedTrustClass(context.trustClass);
|
|
192
204
|
|
|
205
|
+
// Guard: non-host-proxy interfaces need an explicit target when multiple
|
|
206
|
+
// capable clients are connected to avoid ambiguous untargeted broadcasts.
|
|
207
|
+
const transportInterface = context.transportInterface;
|
|
208
|
+
if (
|
|
209
|
+
targetClientId == null &&
|
|
210
|
+
transportInterface != null &&
|
|
211
|
+
!supportsHostProxy(transportInterface) &&
|
|
212
|
+
assistantEventHub.listClientsByCapability("host_bash").length > 1
|
|
213
|
+
) {
|
|
214
|
+
return {
|
|
215
|
+
content: `Error: multiple clients support host_bash. Specify which client to use with \`target_client_id\`. Run \`assistant clients list --capability host_bash\` to see client IDs and labels.`,
|
|
216
|
+
isError: true,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Guard: non-host-proxy interfaces with no capable clients connected.
|
|
221
|
+
if (
|
|
222
|
+
targetClientId == null &&
|
|
223
|
+
transportInterface != null &&
|
|
224
|
+
!supportsHostProxy(transportInterface) &&
|
|
225
|
+
!HostBashProxy.instance.isAvailable()
|
|
226
|
+
) {
|
|
227
|
+
return {
|
|
228
|
+
content:
|
|
229
|
+
"Error: no client with host_bash capability is connected. Connect a macOS client to use host_bash from a non-desktop interface.",
|
|
230
|
+
isError: true,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Guard: explicit targetClientId provided but proxy is unavailable (client
|
|
235
|
+
// disconnected between tool-definition and tool-execution). Without this
|
|
236
|
+
// guard both targetClientId != null guards above are bypassed, and the
|
|
237
|
+
// code falls through to local daemon execution — silently running commands
|
|
238
|
+
// inside the Docker container instead of on the intended host machine.
|
|
239
|
+
if (
|
|
240
|
+
targetClientId != null &&
|
|
241
|
+
!HostBashProxy.instance.isAvailable()
|
|
242
|
+
) {
|
|
243
|
+
return {
|
|
244
|
+
content: `Error: target client "${targetClientId}" is no longer connected. The specified client may have disconnected since the tool was called. Run \`assistant clients list --capability host_bash\` to see currently connected clients.`,
|
|
245
|
+
isError: true,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
193
249
|
// Proxy to connected client for execution on the user's machine
|
|
194
250
|
// when a capable client is available (managed/cloud-hosted mode).
|
|
195
251
|
if (HostBashProxy.instance.isAvailable()) {
|
|
@@ -227,6 +283,7 @@ class HostShellTool implements Tool {
|
|
|
227
283
|
working_dir: rawWorkingDir as string | undefined,
|
|
228
284
|
timeout_seconds: normalizedTimeout,
|
|
229
285
|
env: proxyEnv,
|
|
286
|
+
targetClientId,
|
|
230
287
|
},
|
|
231
288
|
context.conversationId,
|
|
232
289
|
abortController.signal,
|
|
@@ -273,6 +330,7 @@ class HostShellTool implements Tool {
|
|
|
273
330
|
working_dir: rawWorkingDir as string | undefined,
|
|
274
331
|
timeout_seconds: normalizedTimeout,
|
|
275
332
|
env: proxyEnv,
|
|
333
|
+
targetClientId,
|
|
276
334
|
},
|
|
277
335
|
context.conversationId,
|
|
278
336
|
context.signal,
|
|
@@ -44,6 +44,8 @@ export async function executeScheduleCreate(
|
|
|
44
44
|
| undefined;
|
|
45
45
|
const quiet = (input.quiet as boolean) ?? false;
|
|
46
46
|
const reuseConversation = (input.reuse_conversation as boolean) ?? false;
|
|
47
|
+
const maxRetries = input.max_retries as number | undefined;
|
|
48
|
+
const retryBackoffMs = input.retry_backoff_ms as number | undefined;
|
|
47
49
|
|
|
48
50
|
if (!name || typeof name !== "string") {
|
|
49
51
|
return {
|
|
@@ -130,6 +132,8 @@ export async function executeScheduleCreate(
|
|
|
130
132
|
routingHints,
|
|
131
133
|
quiet,
|
|
132
134
|
reuseConversation,
|
|
135
|
+
maxRetries,
|
|
136
|
+
retryBackoffMs,
|
|
133
137
|
});
|
|
134
138
|
|
|
135
139
|
const fireDate = formatLocalDate(job.nextRunAt);
|
|
@@ -208,6 +212,8 @@ export async function executeScheduleCreate(
|
|
|
208
212
|
routingHints,
|
|
209
213
|
quiet,
|
|
210
214
|
reuseConversation,
|
|
215
|
+
maxRetries,
|
|
216
|
+
retryBackoffMs,
|
|
211
217
|
});
|
|
212
218
|
|
|
213
219
|
const scheduleDescription =
|
|
@@ -77,6 +77,8 @@ export async function executeScheduleList(
|
|
|
77
77
|
` Last run: ${job.lastRunAt ? formatLocalDate(job.lastRunAt) : "never"}`,
|
|
78
78
|
` Last status: ${job.lastStatus ?? "n/a"}`,
|
|
79
79
|
` Retry count: ${job.retryCount}`,
|
|
80
|
+
` Max retries: ${job.maxRetries}`,
|
|
81
|
+
` Retry backoff: ${job.retryBackoffMs}ms`,
|
|
80
82
|
` Created: ${formatLocalDate(job.createdAt)}`,
|
|
81
83
|
);
|
|
82
84
|
|
|
@@ -108,6 +108,14 @@ export async function executeScheduleUpdate(
|
|
|
108
108
|
updates.reuseConversation = input.reuse_conversation;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
// Retry policy
|
|
112
|
+
if (input.max_retries !== undefined) {
|
|
113
|
+
updates.maxRetries = input.max_retries;
|
|
114
|
+
}
|
|
115
|
+
if (input.retry_backoff_ms !== undefined) {
|
|
116
|
+
updates.retryBackoffMs = input.retry_backoff_ms;
|
|
117
|
+
}
|
|
118
|
+
|
|
111
119
|
// Auto-detect syntax when expression changes without explicit syntax
|
|
112
120
|
if (input.expression !== undefined || input.syntax !== undefined) {
|
|
113
121
|
const resolved = normalizeScheduleSyntax({
|
|
@@ -173,6 +181,8 @@ export async function executeScheduleUpdate(
|
|
|
173
181
|
routingHints?: Record<string, unknown>;
|
|
174
182
|
quiet?: boolean;
|
|
175
183
|
reuseConversation?: boolean;
|
|
184
|
+
maxRetries?: number;
|
|
185
|
+
retryBackoffMs?: number;
|
|
176
186
|
},
|
|
177
187
|
);
|
|
178
188
|
|
|
@@ -11,7 +11,14 @@ import {
|
|
|
11
11
|
/**
|
|
12
12
|
* Result type shared by both sandbox and host path policies.
|
|
13
13
|
*/
|
|
14
|
-
export type PathFailureReason = "not_absolute" | "out_of_bounds";
|
|
14
|
+
export type PathFailureReason = "not_absolute" | "out_of_bounds" | "denied";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Basenames that must never be read or written by the assistant, regardless
|
|
18
|
+
* of where they resolve. Defense-in-depth: even if a key file is accidentally
|
|
19
|
+
* placed inside the workspace boundary, the assistant cannot access it.
|
|
20
|
+
*/
|
|
21
|
+
const DENIED_BASENAMES = new Set([".backup.key", "backup.key"]);
|
|
15
22
|
|
|
16
23
|
export type PathResult =
|
|
17
24
|
| { ok: true; resolved: string }
|
|
@@ -106,6 +113,16 @@ export function sandboxPolicy(
|
|
|
106
113
|
};
|
|
107
114
|
}
|
|
108
115
|
|
|
116
|
+
// Check both the logical path and the symlink-resolved path so a symlink
|
|
117
|
+
// with a non-denied name pointing at a denied file is still caught.
|
|
118
|
+
if (DENIED_BASENAMES.has(basename(resolved)) || DENIED_BASENAMES.has(basename(realResolved))) {
|
|
119
|
+
return {
|
|
120
|
+
ok: false,
|
|
121
|
+
reason: "denied",
|
|
122
|
+
error: `Access to "${basename(resolved)}" is denied`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
109
126
|
return { ok: true, resolved };
|
|
110
127
|
}
|
|
111
128
|
|
|
@@ -125,5 +142,12 @@ export function hostPolicy(rawPath: string): PathResult {
|
|
|
125
142
|
error: `path must be absolute for host file access: ${rawPath}`,
|
|
126
143
|
};
|
|
127
144
|
}
|
|
145
|
+
if (DENIED_BASENAMES.has(basename(rawPath))) {
|
|
146
|
+
return {
|
|
147
|
+
ok: false,
|
|
148
|
+
reason: "denied",
|
|
149
|
+
error: `Access to "${basename(rawPath)}" is denied`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
128
152
|
return { ok: true, resolved: rawPath };
|
|
129
153
|
}
|
package/src/tools/skills/load.ts
CHANGED
|
@@ -29,9 +29,6 @@ import { getWorkspaceDirDisplay } from "../../util/platform.js";
|
|
|
29
29
|
import { registerTool } from "../registry.js";
|
|
30
30
|
import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
|
|
31
31
|
|
|
32
|
-
/** Canonical feature flag key for inline skill command expansion. */
|
|
33
|
-
const INLINE_COMMANDS_FLAG_KEY = "inline-skill-commands";
|
|
34
|
-
|
|
35
32
|
/** Skill sources eligible for inline command expansion in v1. */
|
|
36
33
|
const INLINE_COMMAND_ELIGIBLE_SOURCES = new Set([
|
|
37
34
|
"bundled",
|
|
@@ -300,20 +297,6 @@ export class SkillLoadTool implements Tool {
|
|
|
300
297
|
skill.inlineCommandExpansions && skill.inlineCommandExpansions.length > 0;
|
|
301
298
|
|
|
302
299
|
if (hasInlineCommands) {
|
|
303
|
-
const inlineFlagEnabled = isAssistantFeatureFlagEnabled(
|
|
304
|
-
INLINE_COMMANDS_FLAG_KEY,
|
|
305
|
-
config,
|
|
306
|
-
);
|
|
307
|
-
|
|
308
|
-
if (!inlineFlagEnabled) {
|
|
309
|
-
// Feature flag is off: fail closed instead of leaving live tokens in
|
|
310
|
-
// the prompt that the LLM might try to interpret.
|
|
311
|
-
return {
|
|
312
|
-
content: `Error: skill "${skill.id}" contains inline command expansions but the inline-skill-commands feature flag is disabled. Enable the flag to use this skill.`,
|
|
313
|
-
isError: true,
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
|
|
317
300
|
if (skill.source === "extra") {
|
|
318
301
|
// Third-party extra roots are out of scope for inline command
|
|
319
302
|
// expansion in v1. Reject explicitly so the failure is clear.
|
|
@@ -391,21 +374,6 @@ export class SkillLoadTool implements Tool {
|
|
|
391
374
|
childLoaded.skill.inlineCommandExpansions.length > 0;
|
|
392
375
|
|
|
393
376
|
if (childHasInlineCommands) {
|
|
394
|
-
const childInlineFlagEnabled = isAssistantFeatureFlagEnabled(
|
|
395
|
-
INLINE_COMMANDS_FLAG_KEY,
|
|
396
|
-
config,
|
|
397
|
-
);
|
|
398
|
-
|
|
399
|
-
// Fail closed: if the flag is off, reject the entire skill_load
|
|
400
|
-
// just like we do for root skills. Leaving raw !`...` tokens in
|
|
401
|
-
// the prompt would violate the documented fail-closed contract.
|
|
402
|
-
if (!childInlineFlagEnabled) {
|
|
403
|
-
return {
|
|
404
|
-
content: `Error: included skill "${childId}" contains inline command expansions but the inline-skill-commands feature flag is disabled. Enable the flag to use skill "${skill.id}".`,
|
|
405
|
-
isError: true,
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
|
|
409
377
|
if (childLoaded.skill.source === "extra") {
|
|
410
378
|
return {
|
|
411
379
|
content: `Error: included skill "${childId}" contains inline command expansions but inline commands are not supported for third-party (extra) skill sources.`,
|