@vellumai/assistant 0.4.46 → 0.4.49
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 +7 -7
- package/README.md +2 -23
- package/docs/architecture/integrations.md +45 -41
- package/docs/architecture/keychain-broker.md +3 -3
- package/docs/architecture/security.md +5 -5
- package/docs/runbook-trusted-contacts.md +3 -8
- package/hook-templates/debug-prompt-logger/hook.json +1 -1
- package/hook-templates/debug-prompt-logger/run.sh +1 -3
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +0 -1
- package/src/__tests__/anthropic-provider.test.ts +156 -0
- package/src/__tests__/approval-cascade.test.ts +810 -0
- package/src/__tests__/approval-primitive.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +2 -0
- package/src/__tests__/assistant-attachments.test.ts +12 -34
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
- package/src/__tests__/browser-fill-credential.test.ts +5 -2
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -1
- package/src/__tests__/channel-guardian.test.ts +0 -2
- package/src/__tests__/channel-readiness-routes.test.ts +35 -25
- package/src/__tests__/channel-readiness-service.test.ts +10 -9
- package/src/__tests__/checker.test.ts +9 -29
- package/src/__tests__/cli.test.ts +23 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-tools.test.ts +2 -19
- package/src/__tests__/config-watcher.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-image-dimensions.test.ts +332 -0
- package/src/__tests__/context-token-estimator.test.ts +196 -13
- package/src/__tests__/conversation-attention-store.test.ts +0 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +144 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/credential-broker-browser-fill.test.ts +23 -22
- package/src/__tests__/credential-broker-server-use.test.ts +22 -21
- package/src/__tests__/credential-broker.test.ts +2 -1
- package/src/__tests__/credential-metadata-store.test.ts +239 -26
- package/src/__tests__/credential-resolve.test.ts +5 -4
- package/src/__tests__/credential-security-e2e.test.ts +8 -8
- package/src/__tests__/credential-security-invariants.test.ts +111 -7
- package/src/__tests__/credential-vault-unit.test.ts +287 -54
- package/src/__tests__/credential-vault.test.ts +406 -12
- package/src/__tests__/credentials-cli.test.ts +82 -6
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/ephemeral-permissions.test.ts +3 -3
- package/src/__tests__/gateway-only-enforcement.test.ts +4 -2
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/gemini-image-service.test.ts +75 -45
- package/src/__tests__/gemini-provider.test.ts +9 -6
- package/src/__tests__/guardian-action-conversation-turn.test.ts +1 -33
- package/src/__tests__/guardian-action-copy-generator.test.ts +0 -20
- package/src/__tests__/guardian-action-followup-executor.test.ts +1 -28
- package/src/__tests__/guardian-action-followup-store.test.ts +1 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
- package/src/__tests__/guardian-grant-minting.test.ts +35 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
- package/src/__tests__/heartbeat-service.test.ts +0 -1
- package/src/__tests__/host-cu-proxy.test.ts +629 -0
- package/src/__tests__/host-shell-tool.test.ts +27 -15
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/ingress-url-consistency.test.ts +14 -21
- package/src/__tests__/integration-status.test.ts +38 -25
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/invite-routes-http.test.ts +10 -9
- package/src/__tests__/keychain-broker-client.test.ts +11 -43
- package/src/__tests__/managed-proxy-context.test.ts +5 -3
- package/src/__tests__/media-generate-image.test.ts +63 -2
- package/src/__tests__/media-reuse-story.e2e.test.ts +7 -3
- package/src/__tests__/messaging-send-tool.test.ts +4 -6
- package/src/__tests__/notification-routing-intent.test.ts +0 -1
- package/src/__tests__/oauth-cli.test.ts +373 -14
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
- package/src/__tests__/oauth-scope-policy.test.ts +4 -6
- package/src/__tests__/oauth-store.test.ts +756 -0
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
- package/src/__tests__/provider-error-scenarios.test.ts +0 -1
- package/src/__tests__/provider-fail-open-selection.test.ts +3 -1
- package/src/__tests__/provider-managed-proxy-integration.test.ts +70 -6
- package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
- package/src/__tests__/public-ingress-urls.test.ts +15 -21
- package/src/__tests__/recording-handler.test.ts +3 -4
- package/src/__tests__/registry.test.ts +2 -2
- package/src/__tests__/runtime-events-sse.test.ts +55 -7
- package/src/__tests__/schedule-store.test.ts +0 -1
- package/src/__tests__/scheduler-recurrence.test.ts +0 -1
- package/src/__tests__/schema-transforms.test.ts +226 -0
- package/src/__tests__/scoped-approval-grants.test.ts +0 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
- package/src/__tests__/script-proxy-injection-runtime.test.ts +23 -13
- package/src/__tests__/script-proxy-policy-runtime.test.ts +1 -1
- package/src/__tests__/script-proxy-session-manager.test.ts +1 -1
- package/src/__tests__/secret-ingress-handler.test.ts +0 -1
- package/src/__tests__/secret-onetime-send.test.ts +5 -3
- package/src/__tests__/send-endpoint-busy.test.ts +21 -6
- package/src/__tests__/sequence-store.test.ts +0 -1
- package/src/__tests__/session-init.benchmark.test.ts +4 -5
- package/src/__tests__/session-messaging-secret-redirect.test.ts +5 -4
- package/src/__tests__/skill-include-graph.test.ts +66 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
- package/src/__tests__/skill-load-tool.test.ts +149 -1
- package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
- package/src/__tests__/skills-uninstall.test.ts +3 -3
- package/src/__tests__/skills.test.ts +3 -12
- package/src/__tests__/slack-channel-config.test.ts +76 -11
- package/src/__tests__/slack-share-routes.test.ts +17 -14
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-bot-username-resolution.test.ts +3 -0
- package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
- package/src/__tests__/terminal-tools.test.ts +4 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/tool-approval-handler.test.ts +0 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
- package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
- package/src/__tests__/trust-store.test.ts +1 -22
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +2 -1
- package/src/__tests__/twilio-provider.test.ts +4 -2
- package/src/__tests__/twilio-routes.test.ts +5 -20
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/agent/ax-tree-compaction.test.ts +235 -0
- package/src/agent/loop.ts +76 -130
- package/src/calls/call-domain.ts +8 -10
- package/src/calls/relay-server.ts +9 -13
- package/src/calls/twilio-config.ts +4 -8
- package/src/calls/twilio-provider.ts +2 -1
- package/src/calls/twilio-rest.ts +2 -1
- package/src/calls/twilio-routes.ts +1 -2
- package/src/calls/voice-ingress-preflight.ts +1 -1
- package/src/cli/commands/browser-relay.ts +46 -15
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/credentials.ts +110 -23
- package/src/cli/commands/oauth/apps.ts +255 -0
- package/src/cli/commands/oauth/connections.ts +299 -0
- package/src/cli/commands/oauth/index.ts +52 -0
- package/src/cli/commands/oauth/providers.ts +242 -0
- package/src/cli/commands/skills.ts +4 -338
- package/src/cli/program.ts +1 -5
- package/src/cli/reference.ts +1 -3
- package/src/cli.ts +3 -2
- package/src/config/assistant-feature-flags.ts +0 -3
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/claude-code/TOOLS.json +0 -4
- package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
- package/src/config/bundled-skills/computer-use/TOOLS.json +22 -4
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +29 -32
- package/src/config/bundled-skills/gmail/SKILL.md +4 -4
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +54 -61
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +25 -28
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +14 -17
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +39 -44
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +61 -58
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +50 -49
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +11 -13
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +148 -146
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +4 -7
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +175 -173
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +4 -7
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +71 -76
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +32 -38
- package/src/config/bundled-skills/google-calendar/SKILL.md +2 -2
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +90 -44
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +9 -10
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +5 -6
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +4 -5
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +14 -15
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +37 -37
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +4 -9
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +24 -3
- package/src/config/bundled-skills/messaging/SKILL.md +6 -6
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +62 -63
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +15 -16
- package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +6 -7
- package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +14 -15
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +128 -128
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +33 -34
- package/src/config/bundled-skills/messaging/tools/shared.ts +12 -15
- package/src/config/bundled-skills/settings/SKILL.md +1 -1
- package/src/config/bundled-skills/settings/TOOLS.json +2 -8
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
- package/src/config/bundled-skills/slack/tools/shared.ts +4 -10
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +15 -16
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +95 -92
- package/src/config/env-registry.ts +14 -83
- package/src/config/env.ts +11 -50
- package/src/config/feature-flag-registry.json +16 -16
- package/src/config/schema.ts +3 -1
- package/src/config/skills.ts +21 -2
- package/src/context/image-dimensions.ts +229 -0
- package/src/context/token-estimator.ts +75 -12
- package/src/context/window-manager.ts +49 -10
- package/src/daemon/assistant-attachments.ts +1 -13
- package/src/daemon/guardian-action-generators.ts +4 -5
- package/src/daemon/handlers/config-ingress.ts +8 -33
- package/src/daemon/handlers/config-slack-channel.ts +76 -56
- package/src/daemon/handlers/config-telegram.ts +53 -24
- package/src/daemon/handlers/sessions.ts +10 -24
- package/src/daemon/handlers/shared.ts +0 -130
- package/src/daemon/host-cu-proxy.ts +401 -0
- package/src/daemon/lifecycle.ts +39 -63
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/computer-use.ts +2 -119
- package/src/daemon/message-types/host-cu.ts +19 -0
- package/src/daemon/message-types/integrations.ts +1 -0
- package/src/daemon/message-types/messages.ts +3 -0
- package/src/daemon/server.ts +14 -21
- package/src/daemon/session-agent-loop-handlers.ts +2 -0
- package/src/daemon/session-attachments.ts +1 -2
- package/src/daemon/session-messaging.ts +3 -1
- package/src/daemon/session-slash.ts +1 -1
- package/src/daemon/session-surfaces.ts +40 -28
- package/src/daemon/session-tool-setup.ts +20 -11
- package/src/daemon/session.ts +139 -16
- package/src/daemon/tool-side-effects.ts +2 -8
- package/src/daemon/watch-handler.ts +2 -2
- package/src/email/providers/index.ts +2 -1
- package/src/events/tool-metrics-listener.ts +2 -2
- package/src/hooks/manager.ts +1 -4
- package/src/inbound/public-ingress-urls.ts +7 -7
- package/src/instrument.ts +15 -1
- package/src/logfire.ts +16 -5
- package/src/media/app-icon-generator.ts +30 -4
- package/src/media/avatar-router.ts +26 -3
- package/src/media/gemini-image-service.ts +28 -2
- package/src/memory/conversation-key-store.ts +21 -0
- package/src/memory/db-init.ts +4 -0
- package/src/memory/guardian-action-store.ts +1 -1
- package/src/memory/migrations/149-oauth-tables.ts +60 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/schema/guardian.ts +1 -1
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/oauth.ts +65 -0
- package/src/messaging/provider.ts +19 -13
- package/src/messaging/providers/gmail/adapter.ts +40 -23
- package/src/messaging/providers/gmail/client.ts +283 -122
- package/src/messaging/providers/gmail/people-client.ts +32 -24
- package/src/messaging/providers/slack/adapter.ts +29 -19
- package/src/messaging/providers/slack/client.ts +265 -78
- package/src/messaging/providers/telegram-bot/adapter.ts +19 -18
- package/src/messaging/providers/whatsapp/adapter.ts +17 -11
- package/src/messaging/registry.ts +2 -31
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/signal.ts +4 -5
- package/src/oauth/byo-connection.test.ts +537 -0
- package/src/oauth/byo-connection.ts +128 -0
- package/src/oauth/connect-orchestrator.ts +139 -56
- package/src/oauth/connect-types.ts +17 -23
- package/src/oauth/connection-resolver.ts +58 -0
- package/src/oauth/connection.ts +38 -0
- package/src/oauth/manual-token-connection.ts +104 -0
- package/src/oauth/oauth-store.ts +496 -0
- package/src/oauth/platform-connection.test.ts +192 -0
- package/src/oauth/platform-connection.ts +111 -0
- package/src/oauth/provider-behaviors.ts +124 -0
- package/src/oauth/scope-policy.ts +9 -2
- package/src/oauth/seed-providers.ts +161 -0
- package/src/oauth/token-persistence.ts +74 -78
- package/src/permissions/checker.ts +8 -4
- package/src/permissions/defaults.ts +0 -1
- package/src/permissions/prompter.ts +10 -1
- package/src/permissions/trust-store.ts +13 -0
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
- package/src/prompts/system-prompt.ts +70 -45
- package/src/providers/anthropic/client.ts +133 -24
- package/src/providers/gemini/client.ts +15 -6
- package/src/providers/managed-proxy/constants.ts +2 -2
- package/src/providers/managed-proxy/context.ts +5 -1
- package/src/providers/ratelimit.ts +17 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +1 -27
- package/src/runtime/AGENTS.md +17 -0
- package/src/runtime/auth/route-policy.ts +0 -3
- package/src/runtime/channel-invite-transports/telegram.ts +2 -1
- package/src/runtime/channel-readiness-service.ts +168 -195
- package/src/runtime/channel-readiness-types.ts +4 -0
- package/src/runtime/channel-reply-delivery.ts +0 -40
- package/src/runtime/gateway-client.ts +0 -7
- package/src/runtime/guardian-action-conversation-turn.ts +1 -3
- package/src/runtime/guardian-action-followup-executor.ts +1 -1
- package/src/runtime/guardian-action-message-composer.ts +3 -23
- package/src/runtime/http-server.ts +17 -10
- package/src/runtime/http-types.ts +2 -3
- package/src/runtime/middleware/rate-limiter.ts +74 -20
- package/src/runtime/middleware/twilio-validation.ts +1 -11
- package/src/runtime/pending-interactions.ts +14 -12
- package/src/runtime/routes/channel-delivery-routes.ts +0 -1
- package/src/runtime/routes/channel-readiness-routes.ts +2 -0
- package/src/runtime/routes/conversation-routes.ts +73 -19
- package/src/runtime/routes/diagnostics-routes.ts +11 -9
- package/src/runtime/routes/events-routes.ts +21 -11
- package/src/runtime/routes/guardian-approval-interception.ts +20 -5
- package/src/runtime/routes/host-cu-routes.ts +97 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
- package/src/runtime/routes/integrations/slack/share.ts +6 -6
- package/src/runtime/routes/integrations/twilio.ts +6 -5
- package/src/runtime/routes/log-export-routes.ts +126 -8
- package/src/runtime/routes/secret-routes.ts +3 -2
- package/src/runtime/routes/settings-routes.ts +113 -48
- package/src/runtime/routes/surface-action-routes.ts +1 -1
- package/src/runtime/routes/watch-routes.ts +128 -0
- package/src/schedule/integration-status.ts +10 -8
- package/src/security/credential-key.ts +14 -0
- package/src/security/keychain-broker-client.ts +5 -6
- package/src/security/oauth2.ts +1 -1
- package/src/security/token-manager.ts +145 -43
- package/src/skills/catalog-install.ts +358 -0
- package/src/skills/include-graph.ts +32 -0
- package/src/telegram/bot-username.ts +2 -3
- package/src/tools/apps/definitions.ts +0 -5
- package/src/tools/assets/materialize.ts +0 -5
- package/src/tools/assets/search.ts +0 -5
- package/src/tools/browser/headless-browser.ts +1 -67
- package/src/tools/browser/network-recorder.ts +1 -1
- package/src/tools/browser/network-recording-types.ts +1 -1
- package/src/tools/claude-code/claude-code.ts +0 -5
- package/src/tools/computer-use/definitions.ts +46 -11
- package/src/tools/computer-use/registry.ts +4 -5
- package/src/tools/credentials/broker.ts +5 -4
- package/src/tools/credentials/metadata-store.ts +22 -74
- package/src/tools/credentials/resolve.ts +2 -1
- package/src/tools/credentials/vault.ts +139 -151
- package/src/tools/filesystem/edit.ts +1 -6
- package/src/tools/filesystem/read.ts +0 -5
- package/src/tools/filesystem/write.ts +1 -6
- package/src/tools/host-filesystem/edit.ts +1 -6
- package/src/tools/host-filesystem/read.ts +1 -6
- package/src/tools/host-filesystem/write.ts +1 -6
- package/src/tools/mcp/mcp-tool-factory.ts +18 -1
- package/src/tools/memory/definitions.ts +0 -5
- package/src/tools/network/web-fetch.ts +0 -5
- package/src/tools/network/web-search.ts +0 -5
- package/src/tools/registry.ts +2 -7
- package/src/tools/schema-transforms.ts +99 -0
- package/src/tools/skills/load.ts +62 -8
- package/src/tools/swarm/delegate.ts +0 -5
- package/src/tools/system/avatar-generator.ts +0 -5
- package/src/tools/ui-surface/definitions.ts +0 -15
- package/src/tools/watch/screen-watch.ts +0 -5
- package/src/tools/watch/watch-state.ts +0 -12
- package/src/util/logger.ts +7 -41
- package/src/util/platform.ts +9 -28
- package/src/version.ts +10 -0
- package/src/watcher/providers/github.ts +51 -52
- package/src/watcher/providers/gmail.ts +88 -80
- package/src/watcher/providers/google-calendar.ts +94 -86
- package/src/watcher/providers/linear.ts +87 -93
- package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
- package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
- package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
- package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
- package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
- package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
- package/src/cli/commands/dev.ts +0 -129
- package/src/cli/commands/map.ts +0 -391
- package/src/cli/commands/oauth.ts +0 -77
- package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +0 -16
- package/src/daemon/computer-use-session.ts +0 -1020
- package/src/daemon/ride-shotgun-handler.ts +0 -567
- package/src/oauth/provider-profiles.ts +0 -192
- package/src/prompts/computer-use-prompt.ts +0 -98
- package/src/runtime/routes/computer-use-routes.ts +0 -641
- package/src/runtime/telegram-streaming-delivery.test.ts +0 -597
- package/src/runtime/telegram-streaming-delivery.ts +0 -383
- package/src/tools/computer-use/request-computer-control.ts +0 -61
|
@@ -8,6 +8,12 @@ import {
|
|
|
8
8
|
registerCallbackRoute,
|
|
9
9
|
shouldUsePlatformCallbacks,
|
|
10
10
|
} from "../../inbound/platform-callback-registration.js";
|
|
11
|
+
import {
|
|
12
|
+
ensureManualTokenConnection,
|
|
13
|
+
removeManualTokenConnection,
|
|
14
|
+
} from "../../oauth/manual-token-connection.js";
|
|
15
|
+
import { getConnectionByProvider } from "../../oauth/oauth-store.js";
|
|
16
|
+
import { credentialKey } from "../../security/credential-key.js";
|
|
11
17
|
import {
|
|
12
18
|
deleteSecureKeyAsync,
|
|
13
19
|
getSecureKey,
|
|
@@ -60,14 +66,18 @@ export type TelegramConfigResult = Omit<TelegramConfigResponse, "type">;
|
|
|
60
66
|
// -- Extracted business logic functions --
|
|
61
67
|
|
|
62
68
|
export function getTelegramConfig(): TelegramConfigResult {
|
|
63
|
-
const hasBotToken = !!getSecureKey("
|
|
64
|
-
const hasWebhookSecret = !!getSecureKey(
|
|
69
|
+
const hasBotToken = !!getSecureKey(credentialKey("telegram", "bot_token"));
|
|
70
|
+
const hasWebhookSecret = !!getSecureKey(
|
|
71
|
+
credentialKey("telegram", "webhook_secret"),
|
|
72
|
+
);
|
|
73
|
+
const conn = getConnectionByProvider("telegram");
|
|
74
|
+
const connected = !!(conn && conn.status === "active");
|
|
65
75
|
const botUsername = getTelegramBotUsername();
|
|
66
76
|
return {
|
|
67
77
|
success: true,
|
|
68
78
|
hasBotToken,
|
|
69
79
|
botUsername,
|
|
70
|
-
connected: hasBotToken && hasWebhookSecret,
|
|
80
|
+
connected: connected && hasBotToken && hasWebhookSecret,
|
|
71
81
|
hasWebhookSecret,
|
|
72
82
|
};
|
|
73
83
|
}
|
|
@@ -79,7 +89,7 @@ export async function setTelegramConfig(
|
|
|
79
89
|
// Track provenance so we only rollback tokens that were freshly provided.
|
|
80
90
|
const isNewToken = !!botToken;
|
|
81
91
|
const resolvedToken =
|
|
82
|
-
botToken || getSecureKey("
|
|
92
|
+
botToken || getSecureKey(credentialKey("telegram", "bot_token"));
|
|
83
93
|
if (!resolvedToken) {
|
|
84
94
|
return {
|
|
85
95
|
success: false,
|
|
@@ -133,7 +143,7 @@ export async function setTelegramConfig(
|
|
|
133
143
|
|
|
134
144
|
// Store bot token securely (async — writes broker + encrypted store)
|
|
135
145
|
const stored = await setSecureKeyAsync(
|
|
136
|
-
"
|
|
146
|
+
credentialKey("telegram", "bot_token"),
|
|
137
147
|
resolvedToken,
|
|
138
148
|
);
|
|
139
149
|
if (!stored) {
|
|
@@ -156,12 +166,14 @@ export async function setTelegramConfig(
|
|
|
156
166
|
invalidateConfigCache();
|
|
157
167
|
|
|
158
168
|
// Ensure webhook secret exists (generate if missing)
|
|
159
|
-
let hasWebhookSecret = !!getSecureKey(
|
|
169
|
+
let hasWebhookSecret = !!getSecureKey(
|
|
170
|
+
credentialKey("telegram", "webhook_secret"),
|
|
171
|
+
);
|
|
160
172
|
if (!hasWebhookSecret) {
|
|
161
173
|
const { randomUUID } = await import("node:crypto");
|
|
162
174
|
const webhookSecret = randomUUID();
|
|
163
175
|
const secretStored = await setSecureKeyAsync(
|
|
164
|
-
"
|
|
176
|
+
credentialKey("telegram", "webhook_secret"),
|
|
165
177
|
webhookSecret,
|
|
166
178
|
);
|
|
167
179
|
if (secretStored) {
|
|
@@ -172,7 +184,7 @@ export async function setTelegramConfig(
|
|
|
172
184
|
// When the token came from secure storage it was already valid
|
|
173
185
|
// configuration; deleting it would destroy working state.
|
|
174
186
|
if (isNewToken) {
|
|
175
|
-
await deleteSecureKeyAsync("
|
|
187
|
+
await deleteSecureKeyAsync(credentialKey("telegram", "bot_token"));
|
|
176
188
|
deleteCredentialMetadata("telegram", "bot_token");
|
|
177
189
|
}
|
|
178
190
|
// Always revert the config write — the botUsername was written
|
|
@@ -195,6 +207,13 @@ export async function setTelegramConfig(
|
|
|
195
207
|
upsertCredentialMetadata("telegram", "webhook_secret", {});
|
|
196
208
|
}
|
|
197
209
|
|
|
210
|
+
// Sync oauth_connection record so getConnectionByProvider("telegram")
|
|
211
|
+
// reflects the current credential state.
|
|
212
|
+
await ensureManualTokenConnection(
|
|
213
|
+
"telegram",
|
|
214
|
+
botUsername ? `@${botUsername}` : undefined,
|
|
215
|
+
);
|
|
216
|
+
|
|
198
217
|
const result: TelegramConfigResult = {
|
|
199
218
|
success: true,
|
|
200
219
|
hasBotToken: true,
|
|
@@ -222,7 +241,7 @@ export async function clearTelegramConfig(): Promise<TelegramConfigResult> {
|
|
|
222
241
|
// The gateway reconcile short-circuits when credentials are absent,
|
|
223
242
|
// so we must call the Telegram API directly while the token is still
|
|
224
243
|
// available.
|
|
225
|
-
const botToken = getSecureKey("
|
|
244
|
+
const botToken = getSecureKey(credentialKey("telegram", "bot_token"));
|
|
226
245
|
if (botToken) {
|
|
227
246
|
try {
|
|
228
247
|
await fetch(`https://api.telegram.org/bot${botToken}/deleteWebhook`);
|
|
@@ -234,13 +253,16 @@ export async function clearTelegramConfig(): Promise<TelegramConfigResult> {
|
|
|
234
253
|
}
|
|
235
254
|
}
|
|
236
255
|
|
|
237
|
-
const r1 = await deleteSecureKeyAsync("
|
|
238
|
-
const r2 = await deleteSecureKeyAsync(
|
|
256
|
+
const r1 = await deleteSecureKeyAsync(credentialKey("telegram", "bot_token"));
|
|
257
|
+
const r2 = await deleteSecureKeyAsync(
|
|
258
|
+
credentialKey("telegram", "webhook_secret"),
|
|
259
|
+
);
|
|
239
260
|
|
|
240
261
|
if (r1 === "error" || r2 === "error") {
|
|
241
|
-
|
|
262
|
+
// Check each key individually so partial deletions report accurate status.
|
|
263
|
+
const hasBotToken = !!getSecureKey(credentialKey("telegram", "bot_token"));
|
|
242
264
|
const hasWebhookSecret = !!getSecureKey(
|
|
243
|
-
"
|
|
265
|
+
credentialKey("telegram", "webhook_secret"),
|
|
244
266
|
);
|
|
245
267
|
return {
|
|
246
268
|
success: false,
|
|
@@ -254,6 +276,9 @@ export async function clearTelegramConfig(): Promise<TelegramConfigResult> {
|
|
|
254
276
|
deleteCredentialMetadata("telegram", "bot_token");
|
|
255
277
|
deleteCredentialMetadata("telegram", "webhook_secret");
|
|
256
278
|
|
|
279
|
+
// Remove the oauth_connection row so getConnectionByProvider returns undefined.
|
|
280
|
+
removeManualTokenConnection("telegram");
|
|
281
|
+
|
|
257
282
|
// Clear bot username from config so getTelegramBotUsername() doesn't
|
|
258
283
|
// return a stale value after disconnect.
|
|
259
284
|
const raw = loadRawConfig();
|
|
@@ -272,7 +297,7 @@ export async function clearTelegramConfig(): Promise<TelegramConfigResult> {
|
|
|
272
297
|
export async function setTelegramCommands(
|
|
273
298
|
commands?: Array<{ command: string; description: string }>,
|
|
274
299
|
): Promise<TelegramConfigResult> {
|
|
275
|
-
const storedToken = getSecureKey("
|
|
300
|
+
const storedToken = getSecureKey(credentialKey("telegram", "bot_token"));
|
|
276
301
|
if (!storedToken) {
|
|
277
302
|
return {
|
|
278
303
|
success: false,
|
|
@@ -299,32 +324,36 @@ export async function setTelegramCommands(
|
|
|
299
324
|
);
|
|
300
325
|
if (!res.ok) {
|
|
301
326
|
const body = await res.text();
|
|
327
|
+
const cmdConn = getConnectionByProvider("telegram");
|
|
328
|
+
const cmdConnected = !!(cmdConn && cmdConn.status === "active");
|
|
302
329
|
return {
|
|
303
330
|
success: false,
|
|
304
331
|
hasBotToken: true,
|
|
305
|
-
connected:
|
|
306
|
-
hasWebhookSecret:
|
|
332
|
+
connected: cmdConnected,
|
|
333
|
+
hasWebhookSecret: cmdConnected,
|
|
307
334
|
error: `Failed to set bot commands: ${body}`,
|
|
308
335
|
};
|
|
309
336
|
}
|
|
310
337
|
} catch (err) {
|
|
311
338
|
const message = summarizeTelegramError(err);
|
|
339
|
+
const cmdConn = getConnectionByProvider("telegram");
|
|
340
|
+
const cmdConnected = !!(cmdConn && cmdConn.status === "active");
|
|
312
341
|
return {
|
|
313
342
|
success: false,
|
|
314
343
|
hasBotToken: true,
|
|
315
|
-
connected:
|
|
316
|
-
hasWebhookSecret:
|
|
344
|
+
connected: cmdConnected,
|
|
345
|
+
hasWebhookSecret: cmdConnected,
|
|
317
346
|
error: `Failed to set bot commands: ${message}`,
|
|
318
347
|
};
|
|
319
348
|
}
|
|
320
349
|
|
|
321
|
-
const
|
|
322
|
-
const
|
|
350
|
+
const cmdConn = getConnectionByProvider("telegram");
|
|
351
|
+
const cmdConnected = !!(cmdConn && cmdConn.status === "active");
|
|
323
352
|
return {
|
|
324
353
|
success: true,
|
|
325
|
-
hasBotToken,
|
|
326
|
-
connected:
|
|
327
|
-
hasWebhookSecret,
|
|
354
|
+
hasBotToken: true,
|
|
355
|
+
connected: cmdConnected,
|
|
356
|
+
hasWebhookSecret: cmdConnected,
|
|
328
357
|
commandsRegistered: resolvedCommands.map((c) => c.command),
|
|
329
358
|
};
|
|
330
359
|
}
|
|
@@ -401,4 +430,4 @@ export async function handleTelegramConfig(
|
|
|
401
430
|
error: message,
|
|
402
431
|
});
|
|
403
432
|
}
|
|
404
|
-
}
|
|
433
|
+
}
|
|
@@ -35,6 +35,7 @@ import * as pendingInteractions from "../../runtime/pending-interactions.js";
|
|
|
35
35
|
import { getSubagentManager } from "../../subagent/index.js";
|
|
36
36
|
import { truncate } from "../../util/truncate.js";
|
|
37
37
|
import { HostBashProxy } from "../host-bash-proxy.js";
|
|
38
|
+
import { HostCuProxy } from "../host-cu-proxy.js";
|
|
38
39
|
import { HostFileProxy } from "../host-file-proxy.js";
|
|
39
40
|
import type {
|
|
40
41
|
CancelRequest,
|
|
@@ -60,7 +61,6 @@ import {
|
|
|
60
61
|
type HandlerContext,
|
|
61
62
|
log,
|
|
62
63
|
pendingStandaloneSecrets,
|
|
63
|
-
wireEscalationHandler,
|
|
64
64
|
} from "./shared.js";
|
|
65
65
|
|
|
66
66
|
/**
|
|
@@ -165,6 +165,12 @@ export function makeEventSender(params: {
|
|
|
165
165
|
conversationId,
|
|
166
166
|
kind: "host_file",
|
|
167
167
|
});
|
|
168
|
+
} else if (event.type === "host_cu_request") {
|
|
169
|
+
pendingInteractions.register(event.requestId, {
|
|
170
|
+
session,
|
|
171
|
+
conversationId,
|
|
172
|
+
kind: "host_cu",
|
|
173
|
+
});
|
|
168
174
|
}
|
|
169
175
|
|
|
170
176
|
ctx.send(event);
|
|
@@ -195,21 +201,6 @@ export function handleConfirmationResponse(
|
|
|
195
201
|
}
|
|
196
202
|
}
|
|
197
203
|
|
|
198
|
-
// Also check computer-use sessions — they have their own PermissionPrompter
|
|
199
|
-
for (const [, cuSession] of ctx.cuSessions) {
|
|
200
|
-
if (cuSession.hasPendingConfirmation(msg.requestId)) {
|
|
201
|
-
cuSession.handleConfirmationResponse(
|
|
202
|
-
msg.requestId,
|
|
203
|
-
msg.decision,
|
|
204
|
-
msg.selectedPattern,
|
|
205
|
-
msg.selectedScope,
|
|
206
|
-
);
|
|
207
|
-
syncCanonicalStatusFromConfirmationDecision(msg.requestId, msg.decision);
|
|
208
|
-
pendingInteractions.resolve(msg.requestId);
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
204
|
log.warn(
|
|
214
205
|
{ requestId: msg.requestId },
|
|
215
206
|
"No session found with pending confirmation for requestId",
|
|
@@ -362,7 +353,6 @@ export async function handleSessionCreate(
|
|
|
362
353
|
maxResponseTokens: msg.maxResponseTokens,
|
|
363
354
|
transport: msg.transport,
|
|
364
355
|
});
|
|
365
|
-
wireEscalationHandler(session, ctx);
|
|
366
356
|
|
|
367
357
|
// Pre-activate skills before sending session_info so they're available
|
|
368
358
|
// for the initial message processing.
|
|
@@ -431,6 +421,8 @@ export async function handleSessionCreate(
|
|
|
431
421
|
pendingInteractions.resolve(requestId);
|
|
432
422
|
});
|
|
433
423
|
session.setHostFileProxy(fileProxy);
|
|
424
|
+
const cuProxy = new HostCuProxy(sendEvent);
|
|
425
|
+
session.setHostCuProxy(cuProxy);
|
|
434
426
|
}
|
|
435
427
|
session.updateClient(sendEvent, false);
|
|
436
428
|
session
|
|
@@ -492,13 +484,7 @@ export async function switchSession(
|
|
|
492
484
|
// Load the session without rebinding the client — the session stays headless
|
|
493
485
|
await ctx.getOrCreateSession(sessionId);
|
|
494
486
|
} else {
|
|
495
|
-
|
|
496
|
-
// Only wire the escalation handler if one isn't already set — handleTaskSubmit
|
|
497
|
-
// sets a handler with the client's actual screen dimensions, and overwriting it
|
|
498
|
-
// here would replace those dimensions with the daemon's defaults.
|
|
499
|
-
if (!session.hasEscalationHandler()) {
|
|
500
|
-
wireEscalationHandler(session, ctx);
|
|
501
|
-
}
|
|
487
|
+
await ctx.getOrCreateSession(sessionId);
|
|
502
488
|
}
|
|
503
489
|
|
|
504
490
|
return {
|
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
import { execSync } from "node:child_process";
|
|
2
|
-
|
|
3
1
|
import { v4 as uuid } from "uuid";
|
|
4
2
|
|
|
5
3
|
import { getConfig } from "../../config/loader.js";
|
|
6
4
|
import type { HeartbeatService } from "../../heartbeat/heartbeat-service.js";
|
|
7
5
|
import type { SecretPromptResult } from "../../permissions/secret-prompter.js";
|
|
8
|
-
import { RateLimitProvider } from "../../providers/ratelimit.js";
|
|
9
|
-
import { getFailoverProvider } from "../../providers/registry.js";
|
|
10
6
|
import type { AuthContext } from "../../runtime/auth/types.js";
|
|
11
7
|
import type { DebouncerMap } from "../../util/debounce.js";
|
|
12
8
|
import { getLogger } from "../../util/logger.js";
|
|
13
9
|
import { estimateBase64Bytes } from "../assistant-attachments.js";
|
|
14
|
-
import { ComputerUseSession } from "../computer-use-session.js";
|
|
15
10
|
import type {
|
|
16
11
|
ServerMessage,
|
|
17
12
|
SessionTransportMetadata,
|
|
@@ -28,9 +23,6 @@ export const CONFIG_RELOAD_DEBOUNCE_MS = 300;
|
|
|
28
23
|
|
|
29
24
|
const HISTORY_ATTACHMENT_TEXT_LIMIT = 500;
|
|
30
25
|
|
|
31
|
-
export const FALLBACK_SCREEN = { width: 1920, height: 1080 };
|
|
32
|
-
let cachedScreenDims: { width: number; height: number } | null = null;
|
|
33
|
-
|
|
34
26
|
// Module-level map for non-session secret prompts (e.g. publish_page)
|
|
35
27
|
export const pendingStandaloneSecrets = new Map<
|
|
36
28
|
string,
|
|
@@ -150,8 +142,6 @@ export interface SessionCreateOptions {
|
|
|
150
142
|
*/
|
|
151
143
|
export interface HandlerContext {
|
|
152
144
|
sessions: Map<string, Session>;
|
|
153
|
-
cuSessions: Map<string, ComputerUseSession>;
|
|
154
|
-
cuObservationParseSequence: Map<string, number>;
|
|
155
145
|
sharedRequestTimestamps: number[];
|
|
156
146
|
debounceTimers: DebouncerMap;
|
|
157
147
|
suppressConfigReload: boolean;
|
|
@@ -170,126 +160,6 @@ export interface HandlerContext {
|
|
|
170
160
|
heartbeatService?: HeartbeatService;
|
|
171
161
|
}
|
|
172
162
|
|
|
173
|
-
/**
|
|
174
|
-
* Query the main display dimensions via CoreGraphics.
|
|
175
|
-
* Cached after the first successful call; falls back to 1920x1080.
|
|
176
|
-
*/
|
|
177
|
-
export function getScreenDimensions(): { width: number; height: number } {
|
|
178
|
-
if (cachedScreenDims) return cachedScreenDims;
|
|
179
|
-
if (process.platform !== "darwin") return FALLBACK_SCREEN;
|
|
180
|
-
try {
|
|
181
|
-
// Use osascript (JXA) instead of `swift` to avoid the
|
|
182
|
-
// "Install Command Line Developer Tools" popup on fresh macOS installs.
|
|
183
|
-
const out = execSync(
|
|
184
|
-
`osascript -l JavaScript -e 'ObjC.import("AppKit"); var f = $.NSScreen.mainScreen.frame; Math.round(f.size.width) + "x" + Math.round(f.size.height)'`,
|
|
185
|
-
{ timeout: 10_000, encoding: "utf-8" },
|
|
186
|
-
).trim();
|
|
187
|
-
const [w, h] = out.split("x").map(Number);
|
|
188
|
-
if (w > 0 && h > 0) {
|
|
189
|
-
cachedScreenDims = { width: w, height: h };
|
|
190
|
-
return cachedScreenDims;
|
|
191
|
-
}
|
|
192
|
-
} catch (err) {
|
|
193
|
-
log.debug({ err }, "Failed to query screen dimensions, using fallback");
|
|
194
|
-
}
|
|
195
|
-
return FALLBACK_SCREEN;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Wire the escalation handler on a text_qa session so that invoking
|
|
200
|
-
* `computer_use_request_control` creates a CU session and notifies the client.
|
|
201
|
-
*
|
|
202
|
-
* In the HTTP-only world, the escalation handler broadcasts events via
|
|
203
|
-
* `ctx.broadcast` instead of targeting a specific socket.
|
|
204
|
-
*/
|
|
205
|
-
export function wireEscalationHandler(
|
|
206
|
-
session: Session,
|
|
207
|
-
ctx: HandlerContext,
|
|
208
|
-
explicitWidth?: number,
|
|
209
|
-
explicitHeight?: number,
|
|
210
|
-
): void {
|
|
211
|
-
const dims =
|
|
212
|
-
explicitWidth && explicitHeight
|
|
213
|
-
? { width: explicitWidth, height: explicitHeight }
|
|
214
|
-
: getScreenDimensions();
|
|
215
|
-
const screenWidth = dims.width;
|
|
216
|
-
const screenHeight = dims.height;
|
|
217
|
-
session.setEscalationHandler(
|
|
218
|
-
(task: string, sourceSessionId: string): boolean => {
|
|
219
|
-
const cuSessionId = uuid();
|
|
220
|
-
|
|
221
|
-
// Inline CU session creation (previously delegated to deleted handlers/computer-use.ts)
|
|
222
|
-
const existingSession = ctx.cuSessions.get(cuSessionId);
|
|
223
|
-
if (existingSession) {
|
|
224
|
-
existingSession.abort();
|
|
225
|
-
ctx.cuSessions.delete(cuSessionId);
|
|
226
|
-
ctx.cuObservationParseSequence.delete(cuSessionId);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const config = getConfig();
|
|
230
|
-
let provider = getFailoverProvider(config.provider, config.providerOrder);
|
|
231
|
-
const { rateLimit } = config;
|
|
232
|
-
if (
|
|
233
|
-
rateLimit.maxRequestsPerMinute > 0 ||
|
|
234
|
-
rateLimit.maxTokensPerSession > 0
|
|
235
|
-
) {
|
|
236
|
-
provider = new RateLimitProvider(
|
|
237
|
-
provider,
|
|
238
|
-
rateLimit,
|
|
239
|
-
ctx.sharedRequestTimestamps,
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const sendToClient = (serverMsg: ServerMessage) => {
|
|
244
|
-
ctx.send(serverMsg);
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
const sessionRef: { current?: ComputerUseSession } = {};
|
|
248
|
-
const onTerminal = (sid: string) => {
|
|
249
|
-
const current = ctx.cuSessions.get(sid);
|
|
250
|
-
if (sessionRef.current && current && current !== sessionRef.current) {
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
ctx.cuSessions.delete(sid);
|
|
254
|
-
ctx.cuObservationParseSequence.delete(sid);
|
|
255
|
-
log.info(
|
|
256
|
-
{ sessionId: sid },
|
|
257
|
-
"Computer-use session cleaned up after terminal state",
|
|
258
|
-
);
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
const cuSession = new ComputerUseSession(
|
|
262
|
-
cuSessionId,
|
|
263
|
-
task,
|
|
264
|
-
screenWidth,
|
|
265
|
-
screenHeight,
|
|
266
|
-
provider,
|
|
267
|
-
sendToClient,
|
|
268
|
-
"computer_use",
|
|
269
|
-
onTerminal,
|
|
270
|
-
);
|
|
271
|
-
sessionRef.current = cuSession;
|
|
272
|
-
|
|
273
|
-
ctx.cuSessions.set(cuSessionId, cuSession);
|
|
274
|
-
|
|
275
|
-
log.info(
|
|
276
|
-
{ sessionId: cuSessionId, taskLength: task.length },
|
|
277
|
-
"Computer-use session created via escalation",
|
|
278
|
-
);
|
|
279
|
-
|
|
280
|
-
ctx.broadcast({
|
|
281
|
-
type: "task_routed",
|
|
282
|
-
sessionId: cuSessionId,
|
|
283
|
-
interactionType: "computer_use",
|
|
284
|
-
task,
|
|
285
|
-
escalatedFrom: sourceSessionId,
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
return true;
|
|
289
|
-
},
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
163
|
export function isRecord(value: unknown): value is Record<string, unknown> {
|
|
294
164
|
return typeof value === "object" && value != null;
|
|
295
165
|
}
|