@vellumai/assistant 0.6.4 → 0.6.5
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/.prettierignore +5 -0
- package/ARCHITECTURE.md +32 -36
- package/Dockerfile +12 -0
- package/README.md +3 -4
- package/bun.lock +8 -3
- package/docs/architecture/integrations.md +1 -20
- package/docs/architecture/security.md +16 -16
- package/docs/error-handling.md +111 -0
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +2 -1
- package/knip.json +9 -2
- package/node_modules/@vellumai/ces-contracts/package.json +2 -1
- package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
- package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
- package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
- package/node_modules/@vellumai/credential-storage/package.json +2 -2
- package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
- package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
- package/node_modules/@vellumai/egress-proxy/package.json +2 -2
- package/openapi.yaml +123 -11
- package/package.json +6 -3
- package/scripts/generate-openapi.ts +50 -11
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
- package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
- package/src/__tests__/agent-loop.test.ts +112 -1
- package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
- package/src/__tests__/anthropic-provider.test.ts +171 -2
- package/src/__tests__/approval-cascade.test.ts +31 -10
- package/src/__tests__/approval-routes-http.test.ts +134 -10
- package/src/__tests__/assistant-attachments.test.ts +44 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
- package/src/__tests__/browser-skill-endstate.test.ts +51 -182
- package/src/__tests__/btw-routes.test.ts +47 -1
- package/src/__tests__/call-controller.test.ts +1 -2
- package/src/__tests__/call-site-routing-provider.test.ts +214 -0
- package/src/__tests__/catalog-cache.test.ts +27 -4
- package/src/__tests__/channel-approval-routes.test.ts +4 -4
- package/src/__tests__/channel-reply-delivery.test.ts +300 -2
- package/src/__tests__/checker.test.ts +428 -501
- package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
- package/src/__tests__/compaction-circuit-breaker.test.ts +336 -0
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/config-analysis.test.ts +11 -28
- package/src/__tests__/config-loader-backfill.test.ts +174 -0
- package/src/__tests__/config-loader-corrupt.test.ts +183 -0
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
- package/src/__tests__/config-schema-cmd.test.ts +11 -5
- package/src/__tests__/config-schema.test.ts +427 -114
- package/src/__tests__/config-watcher.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +72 -73
- package/src/__tests__/contacts-write.test.ts +4 -4
- package/src/__tests__/context-token-estimator.test.ts +191 -1
- package/src/__tests__/context-window-manager.test.ts +530 -2
- package/src/__tests__/conversation-abort-tool-results.test.ts +30 -16
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +61 -17
- package/src/__tests__/conversation-agent-loop.test.ts +412 -82
- package/src/__tests__/conversation-attachments.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +30 -9
- package/src/__tests__/conversation-error.test.ts +37 -6
- package/src/__tests__/conversation-history-web-search.test.ts +6 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +36 -0
- package/src/__tests__/conversation-lifecycle.test.ts +336 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +30 -16
- package/src/__tests__/conversation-process-callsite.test.ts +306 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +30 -16
- package/src/__tests__/conversation-queue.test.ts +41 -26
- package/src/__tests__/conversation-routes-disk-view.test.ts +29 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
- package/src/__tests__/conversation-runtime-assembly.test.ts +2735 -55
- package/src/__tests__/conversation-runtime-workspace.test.ts +12 -12
- package/src/__tests__/conversation-skill-tools.test.ts +12 -146
- package/src/__tests__/conversation-slash-queue.test.ts +34 -19
- package/src/__tests__/conversation-slash-unknown.test.ts +30 -16
- package/src/__tests__/conversation-speed-override.test.ts +30 -11
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
- package/src/__tests__/conversation-title-service.test.ts +2 -2
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +1 -1
- package/src/__tests__/conversation-unread-route.test.ts +2 -2
- package/src/__tests__/conversation-usage.test.ts +3 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +31 -10
- package/src/__tests__/conversation-workspace-injection.test.ts +43 -15
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +44 -16
- package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
- package/src/__tests__/credential-security-invariants.test.ts +3 -0
- package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
- package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
- package/src/__tests__/credential-vault-unit.test.ts +135 -19
- package/src/__tests__/credentials-cli.test.ts +1 -9
- package/src/__tests__/cross-provider-web-search.test.ts +84 -0
- package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
- package/src/__tests__/delete-propagation.test.ts +437 -0
- package/src/__tests__/dm-backfill.test.ts +417 -0
- package/src/__tests__/dm-persistence.test.ts +227 -0
- package/src/__tests__/edit-propagation.test.ts +280 -0
- package/src/__tests__/ephemeral-permissions.test.ts +93 -3
- package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
- package/src/__tests__/estimator-calibration.test.ts +213 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +26 -7
- package/src/__tests__/file-write-tool.test.ts +151 -1
- package/src/__tests__/filing-service.test.ts +255 -0
- package/src/__tests__/gemini-provider.test.ts +0 -3
- package/src/__tests__/guardian-grant-minting.test.ts +8 -0
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/heartbeat-service.test.ts +96 -15
- package/src/__tests__/host-shell-tool.test.ts +124 -18
- package/src/__tests__/http-user-message-parity.test.ts +29 -1
- package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
- package/src/__tests__/intent-routing.test.ts +1 -40
- package/src/__tests__/llm-catalog-parity.test.ts +174 -0
- package/src/__tests__/llm-context-normalization.test.ts +121 -0
- package/src/__tests__/llm-resolver.test.ts +214 -0
- package/src/__tests__/llm-schema.test.ts +223 -0
- package/src/__tests__/managed-proxy-context.test.ts +6 -2
- package/src/__tests__/messaging-skill-split.test.ts +3 -34
- package/src/__tests__/migration-import-from-url.test.ts +684 -0
- package/src/__tests__/model-intents.test.ts +9 -83
- package/src/__tests__/notification-decision-fallback.test.ts +0 -10
- package/src/__tests__/notification-decision-identity.test.ts +0 -9
- package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
- package/src/__tests__/oauth-store.test.ts +10 -7
- package/src/__tests__/oauth2-gateway-transport.test.ts +8 -3
- package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
- package/src/__tests__/openai-provider.test.ts +7 -0
- package/src/__tests__/openai-responses-provider.test.ts +396 -0
- package/src/__tests__/openrouter-provider-only.test.ts +135 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +1 -1
- package/src/__tests__/permission-mode.test.ts +16 -0
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/persona-resolver.test.ts +13 -13
- package/src/__tests__/pkb-autoinject.test.ts +37 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
- package/src/__tests__/pricing.test.ts +50 -3
- package/src/__tests__/profiler-routes.test.ts +1 -1
- package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
- package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
- package/src/__tests__/provider-error-scenarios.test.ts +135 -6
- package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
- package/src/__tests__/provider-registry-ollama.test.ts +1 -2
- package/src/__tests__/proxy-approval-callback.test.ts +0 -1
- package/src/__tests__/reaction-persistence.test.ts +560 -0
- package/src/__tests__/relay-server.test.ts +1 -1
- package/src/__tests__/require-fresh-approval.test.ts +1 -1
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
- package/src/__tests__/risk-classifier-parity.test.ts +230 -0
- package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
- package/src/__tests__/secret-ingress-http.test.ts +28 -0
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
- package/src/__tests__/secret-scanner-executor.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +29 -1
- package/src/__tests__/server-history-render.test.ts +31 -0
- package/src/__tests__/shell-parser-property.test.ts +13 -13
- package/src/__tests__/skill-cache-store.test.ts +182 -0
- package/src/__tests__/skills.test.ts +19 -33
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-skill.test.ts +3 -8
- package/src/__tests__/starter-bundle.test.ts +35 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
- package/src/__tests__/suggestion-routes.test.ts +160 -3
- package/src/__tests__/system-prompt.test.ts +22 -35
- package/src/__tests__/task-runner.test.ts +3 -1
- package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +2 -52
- package/src/__tests__/thread-backfill.test.ts +941 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -2
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
- package/src/__tests__/tool-executor.test.ts +60 -94
- package/src/__tests__/trust-store.test.ts +442 -109
- package/src/__tests__/update-bulletin-job.test.ts +389 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -22
- package/src/__tests__/voice-session-bridge.test.ts +39 -0
- package/src/__tests__/volume-security-guard.test.ts +3 -2
- package/src/__tests__/web-search-history.test.ts +337 -0
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
- package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
- package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +11 -11
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
- package/src/__tests__/workspace-policy.test.ts +1 -13
- package/src/acp/client-handler.ts +1 -2
- package/src/agent/loop.ts +209 -17
- package/src/avatar/resvg-lazy.test.ts +136 -0
- package/src/avatar/resvg-lazy.ts +82 -9
- package/src/avatar/traits-png-sync.ts +21 -1
- package/src/browser/__tests__/operations.test.ts +163 -0
- package/src/browser/identifiers.ts +51 -0
- package/src/browser/operations.ts +660 -0
- package/src/browser/types.ts +81 -0
- package/src/calls/guardian-question-copy.ts +2 -2
- package/src/calls/telephony-stt-routing.ts +1 -1
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/cli/AGENTS.md +1 -1
- package/src/cli/commands/__tests__/attachment.test.ts +438 -0
- package/src/cli/commands/__tests__/browser.test.ts +554 -0
- package/src/cli/commands/__tests__/cache.test.ts +623 -0
- package/src/cli/commands/__tests__/email-list.test.ts +6 -0
- package/src/cli/commands/__tests__/email-send.test.ts +93 -1
- package/src/cli/commands/__tests__/image-generation.test.ts +666 -0
- package/src/cli/commands/__tests__/inference-send.test.ts +451 -0
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
- package/src/cli/commands/__tests__/task.test.ts +913 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +594 -0
- package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
- package/src/cli/commands/__tests__/ui.test.ts +1215 -0
- package/src/cli/commands/__tests__/watchers.test.ts +716 -0
- package/src/cli/commands/attachment.ts +182 -0
- package/src/cli/commands/browser.ts +350 -0
- package/src/cli/commands/cache.ts +341 -0
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/config.ts +6 -6
- package/src/cli/commands/conversations-import.ts +347 -0
- package/src/cli/commands/conversations.ts +14 -1
- package/src/cli/commands/email.ts +234 -194
- package/src/cli/commands/image-generation.ts +300 -0
- package/src/cli/commands/inference.ts +200 -0
- package/src/cli/commands/memory.ts +127 -17
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +0 -1
- package/src/cli/commands/stt.ts +339 -0
- package/src/cli/commands/task.ts +795 -0
- package/src/cli/commands/trust.ts +50 -19
- package/src/cli/commands/tts.ts +273 -0
- package/src/cli/commands/ui.ts +670 -0
- package/src/cli/commands/watchers.ts +509 -0
- package/src/cli/lib/daemon-credential-client.ts +0 -19
- package/src/cli/program.ts +23 -4
- package/src/cli.ts +0 -37
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +23 -1
- package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +2 -2
- package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +8 -1
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +11 -12
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -8
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-tool-registry.ts +0 -175
- package/src/config/env.ts +7 -2
- package/src/config/feature-flag-registry.json +25 -9
- package/src/config/llm-resolver.ts +128 -0
- package/src/config/loader.ts +194 -10
- package/src/config/raw-config-utils.ts +30 -2
- package/src/config/sanitize-for-transfer.ts +35 -0
- package/src/config/schema.ts +30 -41
- package/src/config/schemas/analysis.ts +3 -22
- package/src/config/schemas/calls.ts +0 -4
- package/src/config/schemas/filing.ts +2 -7
- package/src/config/schemas/heartbeat.ts +0 -5
- package/src/config/schemas/inference.ts +3 -23
- package/src/config/schemas/llm.ts +318 -0
- package/src/config/schemas/memory-processing.ts +1 -9
- package/src/config/schemas/notifications.ts +4 -11
- package/src/config/schemas/platform.ts +3 -9
- package/src/config/schemas/security.ts +33 -0
- package/src/config/schemas/services.ts +9 -4
- package/src/config/schemas/stt.ts +1 -0
- package/src/config/schemas/tts.ts +53 -0
- package/src/config/schemas/updates.ts +1 -1
- package/src/config/schemas/workspace-git.ts +3 -40
- package/src/config/skills.ts +2 -2
- package/src/context/__tests__/compact-prompt.test.ts +45 -0
- package/src/context/__tests__/microcompact.test.ts +805 -0
- package/src/context/estimator-calibration.ts +136 -0
- package/src/context/microcompact.ts +443 -0
- package/src/context/prompts/compact.md +12 -0
- package/src/context/token-estimator.ts +61 -3
- package/src/context/window-manager.ts +229 -25
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/executable-discovery.ts +19 -8
- package/src/credential-execution/process-manager.test.ts +109 -0
- package/src/credential-execution/process-manager.ts +65 -2
- package/src/daemon/approval-generators.ts +29 -4
- package/src/daemon/assistant-attachments.ts +24 -13
- package/src/daemon/classifier.ts +2 -2
- package/src/daemon/config-watcher.ts +0 -1
- package/src/daemon/context-overflow-reducer.ts +4 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +79 -12
- package/src/daemon/conversation-agent-loop.ts +462 -80
- package/src/daemon/conversation-attachments.ts +2 -6
- package/src/daemon/conversation-error.ts +36 -1
- package/src/daemon/conversation-lifecycle.ts +30 -6
- package/src/daemon/conversation-messaging.ts +73 -4
- package/src/daemon/conversation-process.ts +10 -4
- package/src/daemon/conversation-queue-manager.ts +3 -0
- package/src/daemon/conversation-runtime-assembly.ts +760 -29
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +389 -1
- package/src/daemon/conversation-tool-setup.ts +10 -5
- package/src/daemon/conversation-usage.ts +1 -1
- package/src/daemon/conversation.ts +118 -30
- package/src/daemon/external-skills-bootstrap.ts +41 -0
- package/src/daemon/guardian-action-generators.ts +34 -14
- package/src/daemon/handlers/config-model.test.ts +86 -0
- package/src/daemon/handlers/config-model.ts +54 -12
- package/src/daemon/handlers/conversations.ts +9 -2
- package/src/daemon/handlers/shared.ts +39 -11
- package/src/daemon/handlers/skills.ts +2 -2
- package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
- package/src/daemon/lifecycle.ts +76 -14
- package/src/daemon/message-types/conversations.ts +14 -0
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/trust.ts +0 -2
- package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
- package/src/daemon/pkb-context-tracker.test.ts +169 -0
- package/src/daemon/pkb-context-tracker.ts +125 -0
- package/src/daemon/pkb-reminder-builder.test.ts +70 -0
- package/src/daemon/pkb-reminder-builder.ts +31 -0
- package/src/daemon/providers-setup.ts +6 -0
- package/src/daemon/server.ts +117 -9
- package/src/daemon/tool-side-effects.ts +0 -9
- package/src/daemon/watch-handler.ts +4 -4
- package/src/daemon/web-search-history.ts +126 -0
- package/src/events/domain-events.ts +0 -1
- package/src/filing/filing-service.ts +9 -10
- package/src/heartbeat/heartbeat-service.ts +76 -28
- package/src/home/__tests__/feed-scheduler.test.ts +39 -11
- package/src/home/__tests__/rollup-producer.test.ts +44 -0
- package/src/home/assistant-feed-authoring.ts +4 -0
- package/src/home/emit-feed-event.ts +4 -0
- package/src/home/feed-scheduler.ts +20 -4
- package/src/home/feed-types.ts +56 -2
- package/src/home/relationship-state-writer.ts +2 -2
- package/src/home/rollup-producer.ts +34 -5
- package/src/home/suggested-prompts.ts +101 -0
- package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
- package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
- package/src/ipc/__tests__/socket-path.test.ts +73 -0
- package/src/ipc/__tests__/task-ipc.test.ts +577 -0
- package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
- package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
- package/src/ipc/cli-client.ts +2 -1
- package/src/ipc/cli-server.ts +26 -8
- package/src/ipc/gateway-client.ts +4 -4
- package/src/ipc/routes/attachment.ts +114 -0
- package/src/ipc/routes/browser-context.ts +61 -0
- package/src/ipc/routes/browser.ts +96 -0
- package/src/ipc/routes/cache.ts +96 -0
- package/src/ipc/routes/index.ts +17 -1
- package/src/ipc/routes/task-queue.ts +226 -0
- package/src/ipc/routes/task.ts +173 -0
- package/src/ipc/routes/ui-request.ts +50 -0
- package/src/ipc/routes/watcher.ts +203 -0
- package/src/ipc/socket-path.ts +100 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +9 -8
- package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
- package/src/memory/admin.ts +18 -0
- package/src/memory/conversation-analyze-job.ts +14 -13
- package/src/memory/conversation-attention-store.ts +13 -6
- package/src/memory/conversation-crud.ts +103 -3
- package/src/memory/conversation-group-migration.ts +38 -6
- package/src/memory/conversation-title-service.ts +7 -4
- package/src/memory/db-init.ts +2 -0
- package/src/memory/embedding-backend.ts +1 -1
- package/src/memory/graph/compaction.ts +299 -0
- package/src/memory/graph/consolidation.ts +4 -4
- package/src/memory/graph/conversation-graph-memory.ts +89 -29
- package/src/memory/graph/extraction.test.ts +272 -2
- package/src/memory/graph/extraction.ts +173 -51
- package/src/memory/graph/graph-search.test.ts +92 -0
- package/src/memory/graph/graph-search.ts +4 -1
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.test.ts +459 -0
- package/src/memory/graph/retriever.ts +230 -48
- package/src/memory/graph/store.ts +41 -0
- package/src/memory/graph/tool-handlers.ts +27 -0
- package/src/memory/graph/tools.ts +6 -1
- package/src/memory/indexer.ts +5 -5
- package/src/memory/job-handlers/conversation-starters.ts +23 -20
- package/src/memory/job-handlers/summarization.ts +2 -2
- package/src/memory/job-utils.ts +7 -1
- package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
- package/src/memory/jobs/embed-pkb-file.ts +54 -0
- package/src/memory/jobs-store.ts +44 -3
- package/src/memory/jobs-worker.ts +4 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +2 -2
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/pkb/pkb-index.test.ts +368 -0
- package/src/memory/pkb/pkb-index.ts +255 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +251 -0
- package/src/memory/pkb/pkb-reconcile.ts +148 -0
- package/src/memory/pkb/pkb-search.test.ts +438 -0
- package/src/memory/pkb/pkb-search.ts +137 -0
- package/src/memory/pkb/types.ts +53 -0
- package/src/memory/qdrant-client.ts +122 -1
- package/src/memory/slack-thread-store.ts +37 -0
- package/src/messaging/providers/gmail/adapter.ts +6 -16
- package/src/messaging/providers/gmail/client.ts +22 -0
- package/src/messaging/providers/gmail/types.ts +7 -0
- package/src/messaging/providers/slack/adapter.ts +14 -2
- package/src/messaging/providers/slack/backfill.test.ts +257 -0
- package/src/messaging/providers/slack/backfill.ts +101 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
- package/src/messaging/providers/slack/message-metadata.ts +123 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1373 -0
- package/src/messaging/providers/slack/render-transcript.ts +443 -0
- package/src/messaging/style-analyzer.ts +5 -2
- package/src/notifications/README.md +9 -5
- package/src/notifications/decision-engine.ts +3 -9
- package/src/notifications/preference-extractor.ts +2 -6
- package/src/oauth/oauth-store.ts +1 -0
- package/src/oauth/platform-connection.test.ts +47 -0
- package/src/oauth/platform-connection.ts +15 -5
- package/src/oauth/seed-providers.ts +4 -2
- package/src/permissions/approval-policy.test.ts +948 -0
- package/src/permissions/approval-policy.ts +257 -0
- package/src/permissions/bash-risk-classifier.test.ts +1208 -0
- package/src/permissions/bash-risk-classifier.ts +707 -0
- package/src/permissions/checker.ts +217 -708
- package/src/permissions/command-registry.test.ts +535 -0
- package/src/permissions/command-registry.ts +825 -0
- package/src/permissions/defaults.ts +26 -78
- package/src/permissions/file-risk-classifier.test.ts +535 -0
- package/src/permissions/file-risk-classifier.ts +274 -0
- package/src/permissions/risk-types.ts +205 -0
- package/src/permissions/secret-prompter.ts +53 -2
- package/src/permissions/skill-risk-classifier.test.ts +311 -0
- package/src/permissions/skill-risk-classifier.ts +214 -0
- package/src/permissions/trust-client.ts +52 -25
- package/src/permissions/trust-store-interface.ts +1 -6
- package/src/permissions/trust-store.ts +161 -62
- package/src/permissions/types.ts +23 -14
- package/src/permissions/web-risk-classifier.test.ts +170 -0
- package/src/permissions/web-risk-classifier.ts +89 -0
- package/src/permissions/workspace-policy.ts +1 -16
- package/src/platform/client.ts +19 -1
- package/src/prompts/persona-resolver.ts +3 -3
- package/src/prompts/system-prompt.ts +19 -20
- package/src/prompts/templates/SOUL.md +2 -2
- package/src/prompts/update-bulletin-job.ts +190 -0
- package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
- package/src/providers/__tests__/retry-callsite.test.ts +424 -0
- package/src/providers/anthropic/client.ts +183 -14
- package/src/providers/call-site-routing.ts +71 -0
- package/src/providers/gemini/client.ts +65 -2
- package/src/providers/managed-proxy/constants.ts +2 -1
- package/src/providers/model-catalog.ts +501 -33
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/chat-completions-provider.ts +57 -1
- package/src/providers/openai/responses-provider.ts +86 -9
- package/src/providers/openrouter/client.ts +76 -9
- package/src/providers/provider-env-vars.ts +56 -0
- package/src/providers/provider-send-message.ts +22 -5
- package/src/providers/ratelimit.ts +4 -0
- package/src/providers/registry.ts +19 -8
- package/src/providers/retry.ts +174 -39
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +55 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +4 -4
- package/src/providers/speech-to-text/provider-catalog.ts +17 -0
- package/src/providers/speech-to-text/resolve.ts +7 -0
- package/src/providers/speech-to-text/xai-realtime.test.ts +578 -0
- package/src/providers/speech-to-text/xai-realtime.ts +796 -0
- package/src/providers/speech-to-text/xai.test.ts +155 -0
- package/src/providers/speech-to-text/xai.ts +97 -0
- package/src/providers/types.ts +93 -3
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +43 -2
- package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
- package/src/runtime/agent-wake.ts +63 -22
- package/src/runtime/auth/route-policy.ts +4 -0
- package/src/runtime/btw-sidechain.ts +13 -3
- package/src/runtime/channel-reply-delivery.ts +106 -2
- package/src/runtime/decision-token.ts +116 -0
- package/src/runtime/gateway-client.ts +2 -2
- package/src/runtime/http-router.ts +32 -0
- package/src/runtime/http-server.ts +52 -1
- package/src/runtime/http-types.ts +23 -1
- package/src/runtime/interactive-ui.ts +362 -0
- package/src/runtime/invite-instruction-generator.ts +2 -2
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
- package/src/runtime/migrations/gcs-signed-url.ts +162 -0
- package/src/runtime/migrations/vbundle-importer.ts +154 -9
- package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
- package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
- package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
- package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
- package/src/runtime/migrations/vbundle-validator.ts +15 -6
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +111 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +114 -75
- package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +58 -0
- package/src/runtime/routes/approval-routes.ts +12 -17
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
- package/src/runtime/routes/avatar-routes.ts +20 -4
- package/src/runtime/routes/btw-routes.ts +1 -4
- package/src/runtime/routes/conversation-management-routes.ts +20 -2
- package/src/runtime/routes/conversation-routes.ts +133 -27
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/diagnostics-routes.ts +6 -4
- package/src/runtime/routes/events-routes.ts +16 -0
- package/src/runtime/routes/guardian-approval-interception.ts +33 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
- package/src/runtime/routes/home-feed-routes.ts +120 -2
- package/src/runtime/routes/inbound-message-handler.ts +912 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
- package/src/runtime/routes/integrations/slack/channel.ts +25 -3
- package/src/runtime/routes/llm-context-normalization.ts +23 -1
- package/src/runtime/routes/migration-routes.ts +720 -124
- package/src/runtime/routes/settings-routes.ts +4 -2
- package/src/runtime/routes/trust-rules-routes.ts +30 -14
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +3 -2
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +25 -43
- package/src/runtime/services/analyze-conversation.ts +12 -16
- package/src/runtime/skill-route-registry.ts +28 -6
- package/src/schedule/scheduler.ts +8 -0
- package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
- package/src/security/__tests__/untrusted-content.test.ts +109 -0
- package/src/security/oauth2.ts +98 -35
- package/src/security/secure-keys.ts +7 -8
- package/src/security/token-manager.ts +27 -13
- package/src/security/untrusted-content.ts +102 -0
- package/src/skills/catalog-cache.ts +26 -7
- package/src/skills/catalog-install.ts +31 -3
- package/src/skills/skill-cache-store.ts +97 -0
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +76 -0
- package/src/stt/daemon-batch-transcriber.ts +33 -0
- package/src/stt/stt-stream-session.ts +8 -1
- package/src/stt/types.ts +5 -1
- package/src/subagent/manager.ts +41 -13
- package/src/tasks/ephemeral-permissions.ts +9 -4
- package/src/telemetry/usage-telemetry-reporter.ts +27 -5
- package/src/tools/browser/__tests__/browser-status.test.ts +45 -2
- package/src/tools/browser/browser-execution.ts +65 -38
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +22 -0
- package/src/tools/credentials/tool-policy.ts +39 -5
- package/src/tools/credentials/vault.ts +9 -4
- package/src/tools/executor.ts +4 -0
- package/src/tools/filesystem/write.ts +52 -0
- package/src/tools/host-terminal/host-shell.ts +45 -5
- package/src/tools/memory/register.test.ts +185 -0
- package/src/tools/memory/register.ts +3 -1
- package/src/tools/network/web-fetch.ts +20 -10
- package/src/tools/network/web-search.ts +19 -4
- package/src/tools/permission-checker.ts +36 -15
- package/src/tools/policy-context.ts +25 -8
- package/src/tools/registry.ts +55 -3
- package/src/tools/side-effects.ts +0 -11
- package/src/tools/skills/execute.ts +2 -2
- package/src/tools/skills/sandbox-runner.ts +5 -2
- package/src/tools/terminal/backends/native.ts +51 -2
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +1 -0
- package/src/tools/tool-manifest.ts +6 -21
- package/src/tools/types.ts +12 -3
- package/src/tools/verification-control-plane-policy.ts +1 -1
- package/src/tts/__tests__/provider-adapters.test.ts +240 -13
- package/src/tts/provider-catalog.ts +18 -0
- package/src/tts/providers/index.ts +2 -0
- package/src/tts/providers/xai-provider.ts +224 -0
- package/src/tts/types.ts +46 -0
- package/src/types/tar-stream.d.ts +66 -0
- package/src/util/json.ts +17 -0
- package/src/util/platform.ts +2 -2
- package/src/util/pricing.ts +15 -5
- package/src/watcher/engine.ts +1 -1
- package/src/watcher/providers/google-calendar.ts +134 -8
- package/src/watcher/providers/outlook-calendar.ts +42 -2
- package/src/workspace/git-service.ts +23 -4
- package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
- package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +57 -0
- package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
- package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
- package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
- package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/registry.ts +16 -0
- package/src/workspace/provider-commit-message-generator.ts +19 -38
- package/src/__tests__/gmail-archive-fallback.test.ts +0 -193
- package/src/__tests__/gmail-archive-gate.test.ts +0 -246
- package/src/__tests__/gmail-preferences.test.ts +0 -117
- package/src/__tests__/outlook-attachments.test.ts +0 -301
- package/src/__tests__/outlook-automation-tools.test.ts +0 -425
- package/src/__tests__/outlook-categories.test.ts +0 -212
- package/src/__tests__/outlook-compose-tools.test.ts +0 -325
- package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
- package/src/__tests__/outlook-follow-up.test.ts +0 -196
- package/src/__tests__/outlook-trash.test.ts +0 -77
- package/src/__tests__/outlook-unsubscribe.test.ts +0 -279
- package/src/__tests__/update-bulletin-format.test.ts +0 -181
- package/src/__tests__/update-bulletin-state.test.ts +0 -135
- package/src/__tests__/update-bulletin.test.ts +0 -478
- package/src/__tests__/update-template-contract.test.ts +0 -29
- package/src/cli/commands/doctor.ts +0 -341
- package/src/config/bundled-skills/browser/SKILL.md +0 -88
- package/src/config/bundled-skills/browser/TOOLS.json +0 -516
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-status.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -49
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
- package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
- package/src/config/bundled-skills/gmail/SKILL.md +0 -221
- package/src/config/bundled-skills/gmail/TOOLS.json +0 -588
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -256
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +0 -59
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +0 -82
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
- package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
- package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
- package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/google-calendar/types.ts +0 -97
- package/src/config/bundled-skills/outlook/SKILL.md +0 -196
- package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
- package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
- package/src/config/bundled-skills/slack/SKILL.md +0 -108
- package/src/config/bundled-skills/tasks/SKILL.md +0 -37
- package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
- package/src/config/bundled-skills/tasks/icon.svg +0 -34
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
- package/src/config/bundled-skills/watcher/SKILL.md +0 -31
- package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
- package/src/prompts/templates/UPDATES.md +0 -50
- package/src/prompts/update-bulletin-format.ts +0 -85
- package/src/prompts/update-bulletin-state.ts +0 -58
- package/src/prompts/update-bulletin-template-path.ts +0 -13
- package/src/prompts/update-bulletin.ts +0 -139
- package/src/shared/provider-env-vars.ts +0 -19
- package/src/tools/watcher/create.ts +0 -86
- package/src/tools/watcher/delete.ts +0 -36
- package/src/tools/watcher/digest.ts +0 -54
- package/src/tools/watcher/list.ts +0 -83
- package/src/tools/watcher/update.ts +0 -71
|
@@ -78,8 +78,8 @@ async function resolveModelList(): Promise<SlashResolution> {
|
|
|
78
78
|
lines.push(`**${providerName}** ${status}`);
|
|
79
79
|
for (const { id, displayName } of models) {
|
|
80
80
|
const isCurrent =
|
|
81
|
-
config.
|
|
82
|
-
config.
|
|
81
|
+
config.llm.default.provider === provider &&
|
|
82
|
+
config.llm.default.model === id;
|
|
83
83
|
const current = isCurrent ? " **[current]**" : "";
|
|
84
84
|
lines.push(` - ${displayName} (\`${id}\`)${current}`);
|
|
85
85
|
}
|
|
@@ -13,6 +13,10 @@ import {
|
|
|
13
13
|
getMessages,
|
|
14
14
|
updateMessageContent,
|
|
15
15
|
} from "../memory/conversation-crud.js";
|
|
16
|
+
import type {
|
|
17
|
+
InteractiveUiRequest,
|
|
18
|
+
InteractiveUiResult,
|
|
19
|
+
} from "../runtime/interactive-ui.js";
|
|
16
20
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
17
21
|
import { getLogger } from "../util/logger.js";
|
|
18
22
|
import { isPlainObject } from "../util/object.js";
|
|
@@ -21,7 +25,9 @@ import { launchConversation } from "./conversation-launch.js";
|
|
|
21
25
|
import type { TrustContext } from "./conversation-runtime-assembly.js";
|
|
22
26
|
import type {
|
|
23
27
|
CardSurfaceData,
|
|
28
|
+
ConfirmationSurfaceData,
|
|
24
29
|
DynamicPageSurfaceData,
|
|
30
|
+
FormSurfaceData,
|
|
25
31
|
ListSurfaceData,
|
|
26
32
|
ServerMessage,
|
|
27
33
|
SurfaceData,
|
|
@@ -272,6 +278,30 @@ export interface SurfaceConversationContext {
|
|
|
272
278
|
accumulatedSurfaceState: Map<string, Record<string, unknown>>;
|
|
273
279
|
/** Request IDs that originated from surface action button clicks (not regular user messages). */
|
|
274
280
|
surfaceActionRequestIds: Set<string>;
|
|
281
|
+
/**
|
|
282
|
+
* Pending standalone UI requests keyed by surfaceId.
|
|
283
|
+
* These are daemon-driven surfaces (not LLM tool invocations) that block
|
|
284
|
+
* the caller until the user submits, cancels, or the timeout elapses.
|
|
285
|
+
* Optional: only present on conversations that support standalone surfaces.
|
|
286
|
+
*/
|
|
287
|
+
pendingStandaloneSurfaces?: Map<
|
|
288
|
+
string,
|
|
289
|
+
{
|
|
290
|
+
resolve: (result: InteractiveUiResult) => void;
|
|
291
|
+
timer: ReturnType<typeof setTimeout>;
|
|
292
|
+
surfaceType: SurfaceType;
|
|
293
|
+
}
|
|
294
|
+
>;
|
|
295
|
+
/**
|
|
296
|
+
* Short-lived tombstone set of recently-completed standalone surface IDs.
|
|
297
|
+
* Prevents late client actions (arriving after timeout/resolution) from
|
|
298
|
+
* falling through to the history-restored path and triggering an
|
|
299
|
+
* unintended LLM turn. Entries are auto-removed after a TTL.
|
|
300
|
+
*/
|
|
301
|
+
recentlyCompletedStandaloneSurfaces?: Map<
|
|
302
|
+
string,
|
|
303
|
+
ReturnType<typeof setTimeout>
|
|
304
|
+
>;
|
|
275
305
|
currentTurnSurfaces: Array<{
|
|
276
306
|
surfaceId: string;
|
|
277
307
|
surfaceType: SurfaceType;
|
|
@@ -288,6 +318,8 @@ export interface SurfaceConversationContext {
|
|
|
288
318
|
}>;
|
|
289
319
|
/** Optional proxy for delegating computer-use actions to a connected desktop client. */
|
|
290
320
|
hostCuProxy?: import("./host-cu-proxy.js").HostCuProxy;
|
|
321
|
+
/** True when no interactive client is connected (headless / channel-only). */
|
|
322
|
+
readonly hasNoClient?: boolean;
|
|
291
323
|
isProcessing(): boolean;
|
|
292
324
|
enqueueMessage(
|
|
293
325
|
content: string,
|
|
@@ -354,6 +386,266 @@ export function createSurfaceMutex(): SurfaceMutex {
|
|
|
354
386
|
return mutex as SurfaceMutex;
|
|
355
387
|
}
|
|
356
388
|
|
|
389
|
+
// ── Standalone surface lifecycle ────────────────────────────────────
|
|
390
|
+
//
|
|
391
|
+
// Daemon-driven UI surfaces that block the caller (skill, IPC handler)
|
|
392
|
+
// until the user responds or the timeout elapses. Unlike LLM-invoked
|
|
393
|
+
// surfaces (ui_show tool), these never trigger an LLM follow-up turn —
|
|
394
|
+
// the result is returned directly to the requesting code.
|
|
395
|
+
|
|
396
|
+
/** Default timeout for standalone surfaces when the caller does not specify one. */
|
|
397
|
+
const DEFAULT_STANDALONE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* How long a tombstone entry persists after a standalone surface is completed.
|
|
401
|
+
* Late client actions arriving within this window are silently dropped.
|
|
402
|
+
*/
|
|
403
|
+
const STANDALONE_TOMBSTONE_TTL_MS = 30_000; // 30 seconds
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Check whether the conversation can show interactive UI surfaces.
|
|
407
|
+
* Fails closed when no client is connected or the channel doesn't
|
|
408
|
+
* support dynamic UI.
|
|
409
|
+
*/
|
|
410
|
+
export function canShowInteractiveUi(
|
|
411
|
+
ctx: Pick<SurfaceConversationContext, "hasNoClient" | "channelCapabilities">,
|
|
412
|
+
): boolean {
|
|
413
|
+
if (ctx.hasNoClient) return false;
|
|
414
|
+
if (ctx.channelCapabilities && !ctx.channelCapabilities.supportsDynamicUi) {
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Show a standalone UI surface and return a Promise that resolves when
|
|
422
|
+
* the user submits, cancels, or the timeout elapses.
|
|
423
|
+
*
|
|
424
|
+
* This is the core entry point for daemon-driven (non-LLM) UI requests.
|
|
425
|
+
* It performs the fail-closed capability check, emits `ui_surface_show`,
|
|
426
|
+
* stores surface state, arms the timeout, and registers a pending entry
|
|
427
|
+
* so that `handleSurfaceAction` can intercept the callback.
|
|
428
|
+
*/
|
|
429
|
+
export function showStandaloneSurface(
|
|
430
|
+
ctx: SurfaceConversationContext,
|
|
431
|
+
request: InteractiveUiRequest,
|
|
432
|
+
surfaceId: string,
|
|
433
|
+
): Promise<InteractiveUiResult> {
|
|
434
|
+
// ── Fail-closed: no interactive UI capability ──
|
|
435
|
+
if (!canShowInteractiveUi(ctx)) {
|
|
436
|
+
log.warn(
|
|
437
|
+
{
|
|
438
|
+
conversationId: ctx.conversationId,
|
|
439
|
+
surfaceType: request.surfaceType,
|
|
440
|
+
hasNoClient: ctx.hasNoClient,
|
|
441
|
+
channel: ctx.channelCapabilities?.channel,
|
|
442
|
+
},
|
|
443
|
+
"standalone surface: no interactive UI capability; failing closed",
|
|
444
|
+
);
|
|
445
|
+
return Promise.resolve({
|
|
446
|
+
status: "cancelled" as const,
|
|
447
|
+
surfaceId,
|
|
448
|
+
cancellationReason: "no_interactive_surface",
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// The pendingStandaloneSurfaces map must exist on the context.
|
|
453
|
+
// The Conversation class always initializes it; if absent, fail closed.
|
|
454
|
+
if (!ctx.pendingStandaloneSurfaces) {
|
|
455
|
+
log.warn(
|
|
456
|
+
{ conversationId: ctx.conversationId, surfaceType: request.surfaceType },
|
|
457
|
+
"standalone surface: pendingStandaloneSurfaces map missing; failing closed",
|
|
458
|
+
);
|
|
459
|
+
return Promise.resolve({
|
|
460
|
+
status: "cancelled" as const,
|
|
461
|
+
surfaceId,
|
|
462
|
+
cancellationReason: "no_interactive_surface",
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
const pendingMap = ctx.pendingStandaloneSurfaces;
|
|
466
|
+
|
|
467
|
+
const timeoutMs = request.timeoutMs ?? DEFAULT_STANDALONE_TIMEOUT_MS;
|
|
468
|
+
|
|
469
|
+
// Build surface data from the request payload.
|
|
470
|
+
const surfaceType = request.surfaceType as SurfaceType;
|
|
471
|
+
const data = buildStandaloneSurfaceData(request);
|
|
472
|
+
const actions = request.actions?.map((a) => ({
|
|
473
|
+
id: a.id,
|
|
474
|
+
label: a.label,
|
|
475
|
+
style: (a.variant === "danger"
|
|
476
|
+
? "destructive"
|
|
477
|
+
: (a.variant ?? "secondary")) as "primary" | "secondary" | "destructive",
|
|
478
|
+
}));
|
|
479
|
+
|
|
480
|
+
return new Promise<InteractiveUiResult>((resolve) => {
|
|
481
|
+
// ── Arm timeout ──
|
|
482
|
+
const timer = setTimeout(() => {
|
|
483
|
+
// Notify the client BEFORE cleanup so the surface is dismissed on
|
|
484
|
+
// the client side, preventing stale user interactions from reaching
|
|
485
|
+
// handleSurfaceAction and being misrouted to the LLM.
|
|
486
|
+
try {
|
|
487
|
+
const emitTimeout =
|
|
488
|
+
ctx.broadcastToAllClients ?? ctx.sendToClient.bind(ctx);
|
|
489
|
+
emitTimeout({
|
|
490
|
+
type: "ui_surface_complete",
|
|
491
|
+
conversationId: ctx.conversationId,
|
|
492
|
+
surfaceId,
|
|
493
|
+
summary: "Timed out",
|
|
494
|
+
});
|
|
495
|
+
} catch (err) {
|
|
496
|
+
log.warn(
|
|
497
|
+
{ err, conversationId: ctx.conversationId, surfaceId },
|
|
498
|
+
"Failed to emit ui_surface_complete on timeout",
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
cleanupStandaloneSurface(ctx, surfaceId);
|
|
503
|
+
log.info(
|
|
504
|
+
{ conversationId: ctx.conversationId, surfaceId, timeoutMs },
|
|
505
|
+
"standalone surface timed out",
|
|
506
|
+
);
|
|
507
|
+
resolve({ status: "timed_out", surfaceId });
|
|
508
|
+
}, timeoutMs);
|
|
509
|
+
|
|
510
|
+
// ── Register pending entry ──
|
|
511
|
+
pendingMap.set(surfaceId, {
|
|
512
|
+
resolve,
|
|
513
|
+
timer,
|
|
514
|
+
surfaceType,
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
// ── Store surface state ──
|
|
518
|
+
ctx.surfaceState.set(surfaceId, {
|
|
519
|
+
surfaceType,
|
|
520
|
+
data,
|
|
521
|
+
title: request.title,
|
|
522
|
+
actions,
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// ── Emit to client ──
|
|
526
|
+
const emit = ctx.broadcastToAllClients ?? ctx.sendToClient.bind(ctx);
|
|
527
|
+
emit({
|
|
528
|
+
type: "ui_surface_show",
|
|
529
|
+
conversationId: ctx.conversationId,
|
|
530
|
+
surfaceId,
|
|
531
|
+
surfaceType,
|
|
532
|
+
title: request.title,
|
|
533
|
+
data,
|
|
534
|
+
actions,
|
|
535
|
+
display: "inline",
|
|
536
|
+
} as unknown as UiSurfaceShow);
|
|
537
|
+
|
|
538
|
+
log.info(
|
|
539
|
+
{
|
|
540
|
+
conversationId: ctx.conversationId,
|
|
541
|
+
surfaceId,
|
|
542
|
+
surfaceType,
|
|
543
|
+
timeoutMs,
|
|
544
|
+
},
|
|
545
|
+
"standalone surface shown",
|
|
546
|
+
);
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Build a SurfaceData object from an InteractiveUiRequest.
|
|
552
|
+
* Maps the generic `data` payload to the typed shape expected by the
|
|
553
|
+
* surface type.
|
|
554
|
+
*/
|
|
555
|
+
function buildStandaloneSurfaceData(
|
|
556
|
+
request: InteractiveUiRequest,
|
|
557
|
+
): SurfaceData {
|
|
558
|
+
if (request.surfaceType === "confirmation") {
|
|
559
|
+
return {
|
|
560
|
+
message:
|
|
561
|
+
typeof request.data.message === "string"
|
|
562
|
+
? request.data.message
|
|
563
|
+
: (request.title ?? "Please confirm"),
|
|
564
|
+
detail:
|
|
565
|
+
typeof request.data.detail === "string"
|
|
566
|
+
? request.data.detail
|
|
567
|
+
: undefined,
|
|
568
|
+
confirmLabel:
|
|
569
|
+
typeof request.data.confirmLabel === "string"
|
|
570
|
+
? request.data.confirmLabel
|
|
571
|
+
: undefined,
|
|
572
|
+
cancelLabel:
|
|
573
|
+
typeof request.data.cancelLabel === "string"
|
|
574
|
+
? request.data.cancelLabel
|
|
575
|
+
: undefined,
|
|
576
|
+
destructive:
|
|
577
|
+
typeof request.data.destructive === "boolean"
|
|
578
|
+
? request.data.destructive
|
|
579
|
+
: undefined,
|
|
580
|
+
} satisfies ConfirmationSurfaceData;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
if (request.surfaceType === "form") {
|
|
584
|
+
// Preserve the full form payload (pages, pageLabels, and any future
|
|
585
|
+
// additive keys) via spreading. Apply defensive normalization so that
|
|
586
|
+
// `fields` is always a valid array — callers that use `pages` instead
|
|
587
|
+
// of top-level `fields` may omit the latter entirely.
|
|
588
|
+
const raw = request.data as Record<string, unknown>;
|
|
589
|
+
const hasFields = Array.isArray(raw.fields) && raw.fields.length > 0;
|
|
590
|
+
const fields: FormSurfaceData["fields"] = hasFields
|
|
591
|
+
? (raw.fields as FormSurfaceData["fields"])
|
|
592
|
+
: [];
|
|
593
|
+
|
|
594
|
+
return {
|
|
595
|
+
...raw,
|
|
596
|
+
fields,
|
|
597
|
+
} as FormSurfaceData;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Fallback: pass through opaque data
|
|
601
|
+
return request.data as unknown as SurfaceData;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Cleanup a standalone surface entry: clear the timeout timer, remove
|
|
606
|
+
* the pending entry, remove surface state, and record a short-lived
|
|
607
|
+
* tombstone so late client actions are silently dropped instead of
|
|
608
|
+
* falling through to the LLM path. Idempotent — safe to call multiple
|
|
609
|
+
* times for the same surfaceId.
|
|
610
|
+
*/
|
|
611
|
+
export function cleanupStandaloneSurface(
|
|
612
|
+
ctx: Pick<
|
|
613
|
+
SurfaceConversationContext,
|
|
614
|
+
| "pendingStandaloneSurfaces"
|
|
615
|
+
| "recentlyCompletedStandaloneSurfaces"
|
|
616
|
+
| "surfaceState"
|
|
617
|
+
| "pendingSurfaceActions"
|
|
618
|
+
| "lastSurfaceAction"
|
|
619
|
+
| "accumulatedSurfaceState"
|
|
620
|
+
| "surfaceUndoStacks"
|
|
621
|
+
>,
|
|
622
|
+
surfaceId: string,
|
|
623
|
+
): void {
|
|
624
|
+
const entry = ctx.pendingStandaloneSurfaces?.get(surfaceId);
|
|
625
|
+
if (entry) {
|
|
626
|
+
clearTimeout(entry.timer);
|
|
627
|
+
ctx.pendingStandaloneSurfaces?.delete(surfaceId);
|
|
628
|
+
}
|
|
629
|
+
ctx.surfaceState.delete(surfaceId);
|
|
630
|
+
ctx.pendingSurfaceActions.delete(surfaceId);
|
|
631
|
+
ctx.lastSurfaceAction.delete(surfaceId);
|
|
632
|
+
ctx.accumulatedSurfaceState.delete(surfaceId);
|
|
633
|
+
ctx.surfaceUndoStacks.delete(surfaceId);
|
|
634
|
+
|
|
635
|
+
// Record a tombstone so late client actions are silently dropped.
|
|
636
|
+
if (ctx.recentlyCompletedStandaloneSurfaces) {
|
|
637
|
+
// Clear any existing tombstone timer for this surfaceId (idempotency).
|
|
638
|
+
const existingTimer =
|
|
639
|
+
ctx.recentlyCompletedStandaloneSurfaces.get(surfaceId);
|
|
640
|
+
if (existingTimer) clearTimeout(existingTimer);
|
|
641
|
+
|
|
642
|
+
const tombstoneTimer = setTimeout(() => {
|
|
643
|
+
ctx.recentlyCompletedStandaloneSurfaces?.delete(surfaceId);
|
|
644
|
+
}, STANDALONE_TOMBSTONE_TTL_MS);
|
|
645
|
+
ctx.recentlyCompletedStandaloneSurfaces.set(surfaceId, tombstoneTimer);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
357
649
|
/**
|
|
358
650
|
* Handle content_changed action from document editor.
|
|
359
651
|
* Auto-saves the document content to the app store.
|
|
@@ -663,6 +955,85 @@ export async function handleSurfaceAction(
|
|
|
663
955
|
actionId: string,
|
|
664
956
|
data?: Record<string, unknown>,
|
|
665
957
|
): Promise<SurfaceActionResult> {
|
|
958
|
+
// ── Standalone surface interception ──────────────────────────────
|
|
959
|
+
// Daemon-driven surfaces (from `requestInteractiveUi`) register a
|
|
960
|
+
// pending entry in `pendingStandaloneSurfaces`. When the user clicks
|
|
961
|
+
// an action, resolve the caller's Promise directly and return WITHOUT
|
|
962
|
+
// enqueuing a model message — consumed standalone callbacks never
|
|
963
|
+
// trigger an LLM follow-up turn.
|
|
964
|
+
//
|
|
965
|
+
// This block runs BEFORE launch_conversation dispatch so that a
|
|
966
|
+
// standalone form whose submittedData happens to contain
|
|
967
|
+
// `_action: "launch_conversation"` is resolved as a standalone
|
|
968
|
+
// interaction rather than triggering a conversation launch.
|
|
969
|
+
const standalone = ctx.pendingStandaloneSurfaces?.get(surfaceId);
|
|
970
|
+
if (standalone) {
|
|
971
|
+
const stored = ctx.surfaceState.get(surfaceId);
|
|
972
|
+
const summary = buildCompletionSummary(
|
|
973
|
+
standalone.surfaceType,
|
|
974
|
+
actionId,
|
|
975
|
+
data,
|
|
976
|
+
stored?.data as Record<string, unknown> | undefined,
|
|
977
|
+
);
|
|
978
|
+
|
|
979
|
+
// Determine result status from the action.
|
|
980
|
+
const isCancellation = actionId === "cancel" || actionId === "dismiss";
|
|
981
|
+
const status: InteractiveUiResult["status"] = isCancellation
|
|
982
|
+
? "cancelled"
|
|
983
|
+
: "submitted";
|
|
984
|
+
|
|
985
|
+
const result: InteractiveUiResult = {
|
|
986
|
+
status,
|
|
987
|
+
surfaceId,
|
|
988
|
+
actionId,
|
|
989
|
+
...(data ? { submittedData: data } : {}),
|
|
990
|
+
...(isCancellation
|
|
991
|
+
? { cancellationReason: "user_dismissed" as const }
|
|
992
|
+
: {}),
|
|
993
|
+
summary,
|
|
994
|
+
};
|
|
995
|
+
|
|
996
|
+
// Emit ui_surface_complete so the client transitions the surface chip.
|
|
997
|
+
const emit = ctx.broadcastToAllClients ?? ctx.sendToClient.bind(ctx);
|
|
998
|
+
emit({
|
|
999
|
+
type: "ui_surface_complete",
|
|
1000
|
+
conversationId: ctx.conversationId,
|
|
1001
|
+
surfaceId,
|
|
1002
|
+
summary,
|
|
1003
|
+
submittedData: data,
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
// Cleanup and resolve — order matters: cleanup clears the timer
|
|
1007
|
+
// before resolve() unblocks the caller.
|
|
1008
|
+
cleanupStandaloneSurface(ctx, surfaceId);
|
|
1009
|
+
standalone.resolve(result);
|
|
1010
|
+
|
|
1011
|
+
log.info(
|
|
1012
|
+
{
|
|
1013
|
+
conversationId: ctx.conversationId,
|
|
1014
|
+
surfaceId,
|
|
1015
|
+
actionId,
|
|
1016
|
+
status,
|
|
1017
|
+
},
|
|
1018
|
+
"standalone surface resolved by user action",
|
|
1019
|
+
);
|
|
1020
|
+
|
|
1021
|
+
// Return without enqueuing a model message.
|
|
1022
|
+
return { accepted: true, conversationId: ctx.conversationId };
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
// ── Tombstone guard for recently-completed standalone surfaces ────
|
|
1026
|
+
// After a standalone surface times out or is resolved, cleanup removes
|
|
1027
|
+
// all state. Without this guard a late client action would fall through
|
|
1028
|
+
// to the history-restored path below and enqueue a message to the LLM.
|
|
1029
|
+
if (ctx.recentlyCompletedStandaloneSurfaces?.has(surfaceId)) {
|
|
1030
|
+
log.debug(
|
|
1031
|
+
{ conversationId: ctx.conversationId, surfaceId, actionId },
|
|
1032
|
+
"Dropping late action for recently-completed standalone surface",
|
|
1033
|
+
);
|
|
1034
|
+
return { accepted: true, conversationId: ctx.conversationId };
|
|
1035
|
+
}
|
|
1036
|
+
|
|
666
1037
|
// `launch_conversation` actions spawn a fresh conversation inline instead
|
|
667
1038
|
// of round-tripping through the LLM with a `[User action on card surface:
|
|
668
1039
|
// ...]` chat message. This dispatch must run BEFORE the pending-vs-not
|
|
@@ -1279,8 +1650,18 @@ export function buildCompletionSummary(
|
|
|
1279
1650
|
: undefined;
|
|
1280
1651
|
return confirmLabel ? `User chose: "${confirmLabel}"` : "Confirmed";
|
|
1281
1652
|
}
|
|
1653
|
+
if (actionId === "deny") {
|
|
1654
|
+
// The deny button's custom label is passed as cancelLabel in the
|
|
1655
|
+
// confirmation surface data (the deny action reuses the cancel label
|
|
1656
|
+
// since both represent the "reject" path).
|
|
1657
|
+
const denyLabel =
|
|
1658
|
+
typeof surfaceData?.cancelLabel === "string"
|
|
1659
|
+
? surfaceData.cancelLabel
|
|
1660
|
+
: undefined;
|
|
1661
|
+
return denyLabel ? `User chose: "${denyLabel}"` : "Denied";
|
|
1662
|
+
}
|
|
1282
1663
|
// Preserve the actual action ID so the LLM knows the user's exact choice
|
|
1283
|
-
//
|
|
1664
|
+
// rather than misreporting it as confirmed.
|
|
1284
1665
|
return `User selected: ${actionId}`;
|
|
1285
1666
|
}
|
|
1286
1667
|
if (surfaceType === "form") {
|
|
@@ -1332,6 +1713,13 @@ export function buildUserFacingLabel(
|
|
|
1332
1713
|
: undefined;
|
|
1333
1714
|
return confirmLabel ?? "Confirmed";
|
|
1334
1715
|
}
|
|
1716
|
+
if (actionId === "deny") {
|
|
1717
|
+
const denyLabel =
|
|
1718
|
+
typeof surfaceData?.cancelLabel === "string"
|
|
1719
|
+
? surfaceData.cancelLabel
|
|
1720
|
+
: undefined;
|
|
1721
|
+
return denyLabel ?? "Denied";
|
|
1722
|
+
}
|
|
1335
1723
|
return `Selected: ${actionId}`;
|
|
1336
1724
|
}
|
|
1337
1725
|
if (surfaceType === "form") return "Submitted";
|
|
@@ -121,6 +121,8 @@ export interface ToolSetupContext extends SurfaceConversationContext {
|
|
|
121
121
|
cesClient?: CesClient;
|
|
122
122
|
/** The interface ID of the connected client driving the current turn (e.g. "macos", "chrome-extension"). Propagated into ToolContext for browser backend selection. */
|
|
123
123
|
readonly transportInterface?: InterfaceId;
|
|
124
|
+
/** Turn-scoped flag: true when any tool call in the current turn received explicit user approval via interactive prompt. Cleared at turn end. */
|
|
125
|
+
approvedViaPromptThisTurn?: boolean;
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
// ── buildToolDefinitions ─────────────────────────────────────────────
|
|
@@ -195,6 +197,7 @@ export function createToolExecutor(
|
|
|
195
197
|
callSessionId: ctx.callSessionId,
|
|
196
198
|
triggeredBySurfaceAction:
|
|
197
199
|
ctx.surfaceActionRequestIds?.has(ctx.currentRequestId ?? "") ?? false,
|
|
200
|
+
approvedViaPrompt: ctx.approvedViaPromptThisTurn || undefined,
|
|
198
201
|
// A task without required_tools entries (e.g. ad-hoc tasks created with
|
|
199
202
|
// omitted/empty required_tools, or legacy rows where it was never
|
|
200
203
|
// populated) correctly gets no batch authorization — that's the
|
|
@@ -304,6 +307,9 @@ export function createToolExecutor(
|
|
|
304
307
|
}
|
|
305
308
|
|
|
306
309
|
const result = await executor.execute(toolName, toolInput, toolContext);
|
|
310
|
+
if (toolContext.approvedViaPrompt) {
|
|
311
|
+
ctx.approvedViaPromptThisTurn = true;
|
|
312
|
+
}
|
|
307
313
|
|
|
308
314
|
runPostExecutionSideEffects(toolName, toolInput, result, {
|
|
309
315
|
ctx,
|
|
@@ -314,6 +320,9 @@ export function createToolExecutor(
|
|
|
314
320
|
}
|
|
315
321
|
|
|
316
322
|
const result = await executor.execute(name, input, toolContext);
|
|
323
|
+
if (toolContext.approvedViaPrompt) {
|
|
324
|
+
ctx.approvedViaPromptThisTurn = true;
|
|
325
|
+
}
|
|
317
326
|
|
|
318
327
|
runPostExecutionSideEffects(name, input, result, {
|
|
319
328
|
ctx,
|
|
@@ -415,18 +424,15 @@ export function createProxyApprovalCallback(
|
|
|
415
424
|
|
|
416
425
|
// Persist trust rule if the user chose "always allow" or "always deny"
|
|
417
426
|
if (
|
|
418
|
-
|
|
419
|
-
response.decision === "always_allow_high_risk") &&
|
|
427
|
+
response.decision === "always_allow" &&
|
|
420
428
|
response.selectedPattern &&
|
|
421
429
|
response.selectedScope
|
|
422
430
|
) {
|
|
423
|
-
const allowHighRisk = response.decision === "always_allow_high_risk";
|
|
424
431
|
log.info(
|
|
425
432
|
{
|
|
426
433
|
toolName,
|
|
427
434
|
pattern: response.selectedPattern,
|
|
428
435
|
scope: response.selectedScope,
|
|
429
|
-
allowHighRisk,
|
|
430
436
|
},
|
|
431
437
|
"Persisting always-allow trust rule (proxy)",
|
|
432
438
|
);
|
|
@@ -436,7 +442,6 @@ export function createProxyApprovalCallback(
|
|
|
436
442
|
response.selectedScope,
|
|
437
443
|
"allow",
|
|
438
444
|
100,
|
|
439
|
-
allowHighRisk ? { allowHighRisk: true } : undefined,
|
|
440
445
|
);
|
|
441
446
|
}
|
|
442
447
|
if (
|