@vellumai/assistant 0.6.2 → 0.6.3
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/bun.lock +40 -40
- package/bunfig.toml +3 -0
- package/docs/architecture/memory.md +1 -1
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
- package/openapi.yaml +184 -69
- package/package.json +41 -41
- package/scripts/generate-openapi.ts +1 -2
- package/src/__tests__/acp-session.test.ts +43 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +1 -0
- package/src/__tests__/app-source-watcher.test.ts +37 -11
- package/src/__tests__/approval-routes-http.test.ts +178 -1
- package/src/__tests__/browser-fill-credential.test.ts +229 -94
- package/src/__tests__/browser-manager.test.ts +40 -27
- package/src/__tests__/catalog-files.test.ts +862 -0
- package/src/__tests__/channel-approvals.test.ts +53 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +326 -0
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +125 -48
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
- package/src/__tests__/context-overflow-approval.test.ts +16 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop.test.ts +1 -1
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +155 -0
- package/src/__tests__/conversation-fork-crud.test.ts +17 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
- package/src/__tests__/conversation-inject-context.test.ts +103 -0
- package/src/__tests__/conversation-queue.test.ts +45 -2
- package/src/__tests__/conversation-routes-disk-view.test.ts +5 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +269 -46
- package/src/__tests__/conversation-starter-routes.test.ts +126 -0
- package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
- package/src/__tests__/conversation-store.test.ts +195 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
- package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -1
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/credential-vault-unit.test.ts +4 -4
- package/src/__tests__/credential-vault.test.ts +152 -13
- package/src/__tests__/credentials-cli.test.ts +2 -2
- package/src/__tests__/date-context.test.ts +4 -4
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +155 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +375 -0
- package/src/__tests__/gateway-only-guard.test.ts +3 -0
- package/src/__tests__/gemini-provider.test.ts +2 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
- package/src/__tests__/headless-browser-interactions.test.ts +707 -371
- package/src/__tests__/headless-browser-navigate.test.ts +389 -47
- package/src/__tests__/headless-browser-read-tools.test.ts +266 -103
- package/src/__tests__/headless-browser-snapshot.test.ts +240 -77
- package/src/__tests__/host-bash-proxy.test.ts +150 -1
- package/src/__tests__/host-browser-e2e-cloud.test.ts +462 -0
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
- package/src/__tests__/host-browser-event-routes.test.ts +350 -0
- package/src/__tests__/host-browser-proxy.test.ts +444 -0
- package/src/__tests__/host-browser-routes.test.ts +198 -0
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +320 -0
- package/src/__tests__/host-cu-proxy.test.ts +171 -1
- package/src/__tests__/host-file-proxy.test.ts +185 -1
- package/src/__tests__/host-file-read-tool.test.ts +52 -0
- package/src/__tests__/host-proxy-interface.test.ts +165 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -11
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- package/src/__tests__/mcp-client-auth.test.ts +40 -4
- package/src/__tests__/mcp-health-check.test.ts +10 -3
- package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
- package/src/__tests__/migration-export-http.test.ts +61 -2
- package/src/__tests__/migration-export-streaming.test.ts +66 -0
- package/src/__tests__/migration-import-commit-http.test.ts +101 -1
- package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
- package/src/__tests__/oauth-apps-routes.test.ts +17 -12
- package/src/__tests__/oauth-cli.test.ts +707 -60
- package/src/__tests__/oauth-connect-orchestrator.test.ts +116 -24
- package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +146 -10
- package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
- package/src/__tests__/oauth-providers-routes.test.ts +50 -14
- package/src/__tests__/oauth-store.test.ts +1386 -182
- package/src/__tests__/oauth2-gateway-transport.test.ts +211 -20
- package/src/__tests__/onboarding-template-contract.test.ts +75 -57
- package/src/__tests__/openai-provider.test.ts +2 -2
- package/src/__tests__/outlook-categories.test.ts +1 -1
- package/src/__tests__/outlook-client-automation.test.ts +1 -1
- package/src/__tests__/outlook-compose-tools.test.ts +1 -1
- package/src/__tests__/outlook-email-watcher.test.ts +1 -1
- package/src/__tests__/outlook-follow-up.test.ts +1 -1
- package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
- package/src/__tests__/outlook-trash.test.ts +1 -1
- package/src/__tests__/outlook-unsubscribe.test.ts +1 -1
- package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
- package/src/__tests__/permission-mode.test.ts +28 -56
- package/src/__tests__/platform-callback-registration.test.ts +19 -0
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +296 -0
- package/src/__tests__/proxy-approval-callback.test.ts +18 -0
- package/src/__tests__/require-fresh-approval.test.ts +40 -1
- package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
- package/src/__tests__/schedule-routes.test.ts +162 -0
- package/src/__tests__/secret-detection-handler.test.ts +84 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/set-permission-mode.test.ts +13 -250
- package/src/__tests__/skills-file-content-endpoint.test.ts +670 -0
- package/src/__tests__/skills-files-catalog-fallback.test.ts +450 -0
- package/src/__tests__/slack-channel-config.test.ts +12 -15
- package/src/__tests__/subagent-detail.test.ts +44 -2
- package/src/__tests__/subagent-disposal.test.ts +1 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
- package/src/__tests__/subagent-manager-notify.test.ts +1 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
- package/src/__tests__/subagent-tools.test.ts +1 -0
- package/src/__tests__/subagent-types.test.ts +1 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
- package/src/__tests__/system-prompt.test.ts +72 -1
- package/src/__tests__/task-scheduler.test.ts +32 -6
- package/src/__tests__/telegram-config.test.ts +10 -13
- package/src/__tests__/terminal-tools.test.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +22 -0
- package/src/__tests__/top-level-renderer.test.ts +73 -1
- package/src/__tests__/transport-hints-queue.test.ts +14 -29
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- package/src/__tests__/v2-consent-policy.test.ts +103 -0
- package/src/acp/client-handler.ts +30 -4
- package/src/agent/loop.ts +12 -6
- package/src/approvals/guardian-request-resolvers.ts +21 -15
- package/src/browser-session/__tests__/manager.test.ts +297 -0
- package/src/browser-session/backends/cdp-inspect.ts +30 -0
- package/src/browser-session/backends/extension.ts +26 -0
- package/src/browser-session/backends/local.ts +24 -0
- package/src/browser-session/events.ts +164 -0
- package/src/browser-session/index.ts +27 -0
- package/src/browser-session/manager.ts +159 -0
- package/src/browser-session/types.ts +28 -0
- package/src/channels/__tests__/types.test.ts +134 -0
- package/src/channels/types.ts +53 -3
- package/src/cli/commands/browser-relay.ts +339 -409
- package/src/cli/commands/credentials.ts +3 -3
- package/src/cli/commands/email.ts +18 -13
- package/src/cli/commands/mcp.ts +16 -4
- package/src/cli/commands/oauth/__tests__/connect.test.ts +44 -44
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
- package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
- package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +31 -33
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +329 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +116 -12
- package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
- package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
- package/src/cli/commands/oauth/apps.ts +7 -4
- package/src/cli/commands/oauth/connect.ts +6 -3
- package/src/cli/commands/oauth/disconnect.ts +1 -1
- package/src/cli/commands/oauth/providers.ts +200 -36
- package/src/cli/commands/oauth/shared.ts +5 -5
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +259 -0
- package/src/cli/commands/platform/index.ts +107 -10
- package/src/cli/commands/usage.ts +10 -9
- package/src/cli/lib/daemon-credential-client.ts +4 -0
- package/src/cli/program.ts +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +26 -249
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +105 -0
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
- package/src/config/bundled-skills/contacts/SKILL.md +3 -0
- package/src/config/bundled-skills/document/SKILL.md +4 -0
- package/src/config/bundled-skills/gmail/SKILL.md +1 -1
- package/src/config/bundled-skills/outlook/SKILL.md +7 -0
- package/src/config/bundled-skills/subagent/SKILL.md +21 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
- package/src/config/bundled-skills/tasks/SKILL.md +5 -0
- package/src/config/env-registry.ts +14 -0
- package/src/config/env.ts +21 -0
- package/src/config/feature-flag-registry.json +44 -5
- package/src/config/loader.ts +56 -1
- package/src/config/sanitize-for-transfer.ts +47 -0
- package/src/config/schema.ts +46 -5
- package/src/config/schemas/host-browser.ts +66 -0
- package/src/config/schemas/memory-lifecycle.ts +1 -1
- package/src/config/schemas/memory-retrieval.ts +103 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +8 -0
- package/src/config/types.ts +0 -1
- package/src/context/post-turn-tool-result-truncation.ts +176 -0
- package/src/context/window-manager.ts +19 -1
- package/src/credential-execution/approval-bridge.ts +49 -15
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +186 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/context-overflow-approval.ts +5 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +17 -2
- package/src/daemon/conversation-agent-loop.ts +58 -24
- package/src/daemon/conversation-attachments.ts +40 -0
- package/src/daemon/conversation-process.ts +48 -1
- package/src/daemon/conversation-runtime-assembly.ts +118 -36
- package/src/daemon/conversation-surfaces.ts +37 -36
- package/src/daemon/conversation-tool-setup.ts +74 -8
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +226 -8
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/conversations.ts +9 -140
- package/src/daemon/handlers/shared.ts +58 -0
- package/src/daemon/handlers/skills.ts +232 -37
- package/src/daemon/host-bash-proxy.ts +48 -13
- package/src/daemon/host-browser-proxy.ts +191 -0
- package/src/daemon/host-cu-proxy.ts +36 -11
- package/src/daemon/host-file-proxy.ts +57 -9
- package/src/daemon/lifecycle.ts +65 -11
- package/src/daemon/message-protocol.ts +7 -0
- package/src/daemon/message-types/conversations.ts +55 -13
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/messages.ts +5 -5
- package/src/daemon/message-types/skills.ts +10 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/server.ts +92 -12
- package/src/daemon/tool-side-effects.ts +6 -0
- package/src/daemon/transport-hints.ts +5 -24
- package/src/inbound/platform-callback-registration.ts +18 -17
- package/src/mcp/client.ts +59 -24
- package/src/memory/app-store.ts +31 -1
- package/src/memory/conversation-crud.ts +23 -0
- package/src/memory/conversation-starters-cadence.ts +76 -0
- package/src/memory/conversation-title-service.ts +5 -2
- package/src/memory/db-init.ts +12 -0
- package/src/memory/embedding-backend.test.ts +75 -0
- package/src/memory/embedding-backend.ts +131 -5
- package/src/memory/embedding-gemini.test.ts +54 -0
- package/src/memory/embedding-gemini.ts +20 -9
- package/src/memory/embedding-local.ts +176 -17
- package/src/memory/graph/consolidation.ts +10 -23
- package/src/memory/graph/extraction-job.ts +15 -0
- package/src/memory/graph/retriever.ts +40 -22
- package/src/memory/graph/store.test.ts +7 -3
- package/src/memory/graph/store.ts +47 -12
- package/src/memory/llm-usage-store.ts +45 -4
- package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
- package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
- package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
- package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
- package/src/memory/migrations/217-conversation-host-access.ts +40 -0
- package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +1 -0
- package/src/memory/schema/oauth.ts +18 -13
- package/src/oauth/AGENTS.md +76 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +24 -19
- package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
- package/src/oauth/byo-connection.test.ts +8 -8
- package/src/oauth/byo-connection.ts +7 -7
- package/src/oauth/connect-orchestrator.ts +23 -21
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/connection-resolver.test.ts +17 -4
- package/src/oauth/connection-resolver.ts +16 -16
- package/src/oauth/connection.ts +1 -1
- package/src/oauth/manual-token-connection.ts +13 -13
- package/src/oauth/oauth-store.ts +214 -100
- package/src/oauth/platform-connection.test.ts +3 -3
- package/src/oauth/platform-connection.ts +4 -4
- package/src/oauth/provider-serializer.ts +31 -5
- package/src/oauth/revoke.ts +76 -0
- package/src/oauth/seed-providers.ts +126 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -1
- package/src/permissions/v2-consent-policy.ts +87 -0
- package/src/prompts/system-prompt.ts +18 -21
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -105
- package/src/providers/anthropic/client.ts +1 -0
- package/src/providers/types.ts +1 -1
- package/src/runtime/AGENTS.md +23 -0
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
- package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -0
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +8 -0
- package/src/runtime/auth/middleware.ts +98 -0
- package/src/runtime/auth/route-policy.ts +6 -7
- package/src/runtime/capability-tokens.ts +414 -0
- package/src/runtime/channel-approvals.ts +18 -5
- package/src/runtime/chrome-extension-registry.ts +332 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
- package/src/runtime/guardian-decision-types.ts +7 -0
- package/src/runtime/http-server.ts +425 -70
- package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +162 -0
- package/src/runtime/migrations/migration-transport.ts +6 -0
- package/src/runtime/migrations/migration-wizard.ts +22 -2
- package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
- package/src/runtime/migrations/vbundle-builder.ts +145 -38
- package/src/runtime/migrations/vbundle-import-analyzer.ts +19 -0
- package/src/runtime/migrations/vbundle-importer.ts +55 -5
- package/src/runtime/pending-interactions.ts +29 -13
- package/src/runtime/routes/approval-routes.ts +90 -16
- package/src/runtime/routes/browser-cdp-routes.ts +229 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +497 -0
- package/src/runtime/routes/conversation-analysis-routes.ts +2 -1
- package/src/runtime/routes/conversation-management-routes.ts +108 -0
- package/src/runtime/routes/conversation-routes.ts +301 -27
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/guardian-action-routes.ts +24 -13
- package/src/runtime/routes/host-browser-routes.ts +279 -0
- package/src/runtime/routes/host-file-routes.ts +9 -1
- package/src/runtime/routes/identity-routes.ts +259 -16
- package/src/runtime/routes/log-export-routes.ts +42 -22
- package/src/runtime/routes/memory-item-routes.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +87 -2
- package/src/runtime/routes/oauth-apps.ts +15 -17
- package/src/runtime/routes/oauth-providers.ts +4 -0
- package/src/runtime/routes/schedule-routes.ts +24 -11
- package/src/runtime/routes/settings-routes.ts +9 -97
- package/src/runtime/routes/skills-routes.ts +52 -2
- package/src/runtime/routes/subagents-routes.ts +14 -10
- package/src/runtime/routes/usage-routes.ts +8 -7
- package/src/runtime/routes/workspace-routes.test.ts +22 -0
- package/src/runtime/routes/workspace-routes.ts +8 -1
- package/src/runtime/routes/workspace-utils.ts +2 -0
- package/src/schedule/scheduler.ts +7 -5
- package/src/security/ces-credential-client.ts +20 -0
- package/src/security/ces-rpc-credential-backend.ts +17 -0
- package/src/security/credential-backend.ts +5 -0
- package/src/security/oauth2.ts +42 -25
- package/src/security/secure-keys.ts +118 -25
- package/src/security/token-manager.ts +23 -10
- package/src/skills/catalog-files.ts +492 -0
- package/src/subagent/manager.ts +131 -26
- package/src/subagent/types.ts +19 -0
- package/src/tools/apps/executors.ts +11 -2
- package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
- package/src/tools/browser/auth-detector.ts +43 -12
- package/src/tools/browser/browser-execution.ts +645 -340
- package/src/tools/browser/browser-manager.ts +36 -12
- package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +318 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +870 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +330 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +377 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
- package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +743 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +578 -0
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +635 -0
- package/src/tools/browser/cdp-client/errors.ts +34 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +125 -0
- package/src/tools/browser/cdp-client/factory.ts +204 -0
- package/src/tools/browser/cdp-client/index.ts +14 -0
- package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
- package/src/tools/browser/cdp-client/types.ts +52 -0
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +1 -1
- package/src/tools/host-filesystem/read.ts +12 -15
- package/src/tools/host-filesystem/write.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +21 -16
- package/src/tools/permission-checker.ts +77 -82
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -0
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- package/src/tools/subagent/spawn.ts +47 -3
- package/src/tools/subagent/status.ts +2 -0
- package/src/tools/system/register.ts +2 -16
- package/src/tools/terminal/safe-env.ts +7 -0
- package/src/tools/terminal/shell.ts +21 -16
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/types.ts +2 -0
- package/src/util/platform.ts +14 -19
- package/src/workspace/top-level-renderer.ts +19 -1
- package/src/__tests__/chrome-cdp.test.ts +0 -419
- package/src/__tests__/permission-mode-sse.test.ts +0 -418
- package/src/__tests__/permission-mode-store.test.ts +0 -277
- package/src/browser-extension-relay/protocol.ts +0 -63
- package/src/browser-extension-relay/server.ts +0 -203
- package/src/config/schemas/sandbox.ts +0 -14
- package/src/permissions/permission-mode-store.ts +0 -180
- package/src/tools/browser/chrome-cdp.ts +0 -239
- package/src/tools/system/set-permission-mode.ts +0 -103
|
@@ -49,6 +49,7 @@ const MAX_LOG_PAYLOAD_BYTES = 10 * 1024 * 1024;
|
|
|
49
49
|
interface ExportRequestBody {
|
|
50
50
|
auditLimit?: number;
|
|
51
51
|
conversationId?: string; // scope to a single conversation
|
|
52
|
+
full?: boolean; // include all conversation data (messages + LLM logs) — use for test data debugging
|
|
52
53
|
startTime?: number; // epoch ms — lower bound (inclusive)
|
|
53
54
|
endTime?: number; // epoch ms — upper bound (inclusive)
|
|
54
55
|
}
|
|
@@ -67,7 +68,7 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
|
|
|
67
68
|
const staging = mkdtempSync(join(tmpdir(), "vellum-export-"));
|
|
68
69
|
|
|
69
70
|
try {
|
|
70
|
-
const { conversationId, startTime, endTime } = body;
|
|
71
|
+
const { conversationId, full, startTime, endTime } = body;
|
|
71
72
|
|
|
72
73
|
// --- Audit data ---
|
|
73
74
|
const limit = body.auditLimit ?? 1000;
|
|
@@ -98,14 +99,19 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
|
|
|
98
99
|
"utf-8",
|
|
99
100
|
);
|
|
100
101
|
|
|
101
|
-
// --- Conversation
|
|
102
|
-
|
|
102
|
+
// --- Conversation data tables ---
|
|
103
|
+
// Included when scoped to a single conversation OR when all conversations are requested.
|
|
104
|
+
if (conversationId || full) {
|
|
105
|
+
const conversationFilter = conversationId
|
|
106
|
+
? [eq(messages.conversationId, conversationId)]
|
|
107
|
+
: [];
|
|
108
|
+
|
|
103
109
|
const messageRows = db
|
|
104
110
|
.select()
|
|
105
111
|
.from(messages)
|
|
106
112
|
.where(
|
|
107
113
|
and(
|
|
108
|
-
|
|
114
|
+
...conversationFilter,
|
|
109
115
|
startTime ? gte(messages.createdAt, startTime) : undefined,
|
|
110
116
|
endTime ? lte(messages.createdAt, endTime) : undefined,
|
|
111
117
|
),
|
|
@@ -118,12 +124,16 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
|
|
|
118
124
|
"utf-8",
|
|
119
125
|
);
|
|
120
126
|
|
|
127
|
+
const llmConversationFilter = conversationId
|
|
128
|
+
? [eq(llmRequestLogs.conversationId, conversationId)]
|
|
129
|
+
: [];
|
|
130
|
+
|
|
121
131
|
const llmLogRows = db
|
|
122
132
|
.select()
|
|
123
133
|
.from(llmRequestLogs)
|
|
124
134
|
.where(
|
|
125
135
|
and(
|
|
126
|
-
|
|
136
|
+
...llmConversationFilter,
|
|
127
137
|
startTime ? gte(llmRequestLogs.createdAt, startTime) : undefined,
|
|
128
138
|
endTime ? lte(llmRequestLogs.createdAt, endTime) : undefined,
|
|
129
139
|
),
|
|
@@ -136,12 +146,16 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
|
|
|
136
146
|
"utf-8",
|
|
137
147
|
);
|
|
138
148
|
|
|
149
|
+
const usageConversationFilter = conversationId
|
|
150
|
+
? [eq(llmUsageEvents.conversationId, conversationId)]
|
|
151
|
+
: [];
|
|
152
|
+
|
|
139
153
|
const usageRows = db
|
|
140
154
|
.select()
|
|
141
155
|
.from(llmUsageEvents)
|
|
142
156
|
.where(
|
|
143
157
|
and(
|
|
144
|
-
|
|
158
|
+
...usageConversationFilter,
|
|
145
159
|
startTime ? gte(llmUsageEvents.createdAt, startTime) : undefined,
|
|
146
160
|
endTime ? lte(llmUsageEvents.createdAt, endTime) : undefined,
|
|
147
161
|
),
|
|
@@ -265,22 +279,21 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
|
|
|
265
279
|
}
|
|
266
280
|
|
|
267
281
|
// --- Export manifest ---
|
|
268
|
-
const
|
|
269
|
-
?
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
:
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
};
|
|
282
|
+
const manifestType = conversationId
|
|
283
|
+
? ("conversation-export" as const)
|
|
284
|
+
: full
|
|
285
|
+
? ("full-export" as const)
|
|
286
|
+
: ("global-export" as const);
|
|
287
|
+
const manifest = {
|
|
288
|
+
type: manifestType,
|
|
289
|
+
...(conversationId ? { conversationId } : {}),
|
|
290
|
+
...(full ? { full: true } : {}),
|
|
291
|
+
assistantVersion: APP_VERSION,
|
|
292
|
+
commitSha: COMMIT_SHA,
|
|
293
|
+
...(startTime !== undefined ? { startTime } : {}),
|
|
294
|
+
...(endTime !== undefined ? { endTime } : {}),
|
|
295
|
+
exportedAt: new Date().toISOString(),
|
|
296
|
+
};
|
|
284
297
|
writeFileSync(
|
|
285
298
|
join(staging, "export-manifest.json"),
|
|
286
299
|
JSON.stringify(manifest, null, 2),
|
|
@@ -294,6 +307,7 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
|
|
|
294
307
|
totalBytes,
|
|
295
308
|
hasConfig: configSnapshot !== undefined,
|
|
296
309
|
conversationId: conversationId ?? null,
|
|
310
|
+
full: full ?? false,
|
|
297
311
|
workspaceEntries: workspaceResult.entries.length,
|
|
298
312
|
workspaceBytes: workspaceResult.totalBytes,
|
|
299
313
|
},
|
|
@@ -441,6 +455,12 @@ export function logExportRouteDefinitions(): RouteDefinition[] {
|
|
|
441
455
|
.string()
|
|
442
456
|
.optional()
|
|
443
457
|
.describe("Scope to a single conversation"),
|
|
458
|
+
full: z
|
|
459
|
+
.boolean()
|
|
460
|
+
.optional()
|
|
461
|
+
.describe(
|
|
462
|
+
"Full export — include messages, LLM request logs, and usage events for all conversations. Use for test data debugging.",
|
|
463
|
+
),
|
|
444
464
|
startTime: z.number().optional().describe("Lower bound epoch ms"),
|
|
445
465
|
endTime: z.number().optional().describe("Upper bound epoch ms"),
|
|
446
466
|
});
|
|
@@ -712,15 +712,9 @@ export async function handleDeleteMemoryItem(
|
|
|
712
712
|
return httpError("NOT_FOUND", "Memory item not found", 404);
|
|
713
713
|
}
|
|
714
714
|
|
|
715
|
-
//
|
|
715
|
+
// Soft-delete the node (deleteNode sets fidelity='gone' and enqueues Qdrant cleanup)
|
|
716
716
|
deleteNode(id);
|
|
717
717
|
|
|
718
|
-
// Clean up Qdrant vectors asynchronously
|
|
719
|
-
enqueueMemoryJob("delete_qdrant_vectors", {
|
|
720
|
-
targetType: "graph_node",
|
|
721
|
-
targetId: id,
|
|
722
|
-
});
|
|
723
|
-
|
|
724
718
|
return new Response(null, { status: 204 });
|
|
725
719
|
}
|
|
726
720
|
|
|
@@ -21,6 +21,11 @@ import { invalidateConfigCache } from "../../config/loader.js";
|
|
|
21
21
|
import { getDb, resetDb } from "../../memory/db-connection.js";
|
|
22
22
|
import { validateMigrationState } from "../../memory/migrations/validate-migration-state.js";
|
|
23
23
|
import { clearCache as clearTrustCache } from "../../permissions/trust-store.js";
|
|
24
|
+
import {
|
|
25
|
+
bulkSetSecureKeysAsync,
|
|
26
|
+
getSecureKeyResultAsync,
|
|
27
|
+
listSecureKeysAsync,
|
|
28
|
+
} from "../../security/secure-keys.js";
|
|
24
29
|
import { getLogger } from "../../util/logger.js";
|
|
25
30
|
import {
|
|
26
31
|
getDbPath,
|
|
@@ -34,7 +39,10 @@ import {
|
|
|
34
39
|
analyzeImport,
|
|
35
40
|
DefaultPathResolver,
|
|
36
41
|
} from "../migrations/vbundle-import-analyzer.js";
|
|
37
|
-
import {
|
|
42
|
+
import {
|
|
43
|
+
commitImport,
|
|
44
|
+
extractCredentialsFromBundle,
|
|
45
|
+
} from "../migrations/vbundle-importer.js";
|
|
38
46
|
import { validateVBundle } from "../migrations/vbundle-validator.js";
|
|
39
47
|
|
|
40
48
|
const log = getLogger("migration-routes");
|
|
@@ -146,6 +154,27 @@ export async function handleMigrationExport(req: Request): Promise<Response> {
|
|
|
146
154
|
let cleanup: (() => Promise<void>) | undefined;
|
|
147
155
|
|
|
148
156
|
try {
|
|
157
|
+
// Read all stored credentials to include in the export bundle
|
|
158
|
+
const credentialList = await listSecureKeysAsync();
|
|
159
|
+
const credentials: Array<{ account: string; value: string }> = [];
|
|
160
|
+
if (credentialList.unreachable) {
|
|
161
|
+
log.warn(
|
|
162
|
+
"Credential store is unreachable — export will not include credentials",
|
|
163
|
+
);
|
|
164
|
+
} else {
|
|
165
|
+
for (const account of credentialList.accounts) {
|
|
166
|
+
const result = await getSecureKeyResultAsync(account);
|
|
167
|
+
if (result.unreachable) {
|
|
168
|
+
log.warn(
|
|
169
|
+
{ account },
|
|
170
|
+
"Credential store unreachable when reading credential — skipping",
|
|
171
|
+
);
|
|
172
|
+
} else if (result.value != null) {
|
|
173
|
+
credentials.push({ account, value: result.value });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
149
178
|
const result = await streamExportVBundle({
|
|
150
179
|
// hooksDir is intentionally omitted — hooks now live under workspace/hooks/
|
|
151
180
|
// and are included in the workspace walk. Passing hooksDir separately would
|
|
@@ -153,6 +182,7 @@ export async function handleMigrationExport(req: Request): Promise<Response> {
|
|
|
153
182
|
workspaceDir: getWorkspaceDir(),
|
|
154
183
|
source: "runtime-export",
|
|
155
184
|
description,
|
|
185
|
+
credentials,
|
|
156
186
|
checkpoint: () => {
|
|
157
187
|
const dbPath = getDbPath();
|
|
158
188
|
try {
|
|
@@ -196,6 +226,7 @@ export async function handleMigrationExport(req: Request): Promise<Response> {
|
|
|
196
226
|
"Content-Length": String(size),
|
|
197
227
|
"X-Vbundle-Schema-Version": manifest.schema_version,
|
|
198
228
|
"X-Vbundle-Manifest-Sha256": manifest.manifest_sha256,
|
|
229
|
+
"X-Vbundle-Credentials-Included": String(credentials.length),
|
|
199
230
|
},
|
|
200
231
|
});
|
|
201
232
|
} catch (err) {
|
|
@@ -444,6 +475,57 @@ export async function handleMigrationImport(req: Request): Promise<Response> {
|
|
|
444
475
|
);
|
|
445
476
|
}
|
|
446
477
|
|
|
478
|
+
// Import credentials from the bundle into CES (non-blocking — failures
|
|
479
|
+
// are logged as warnings but do not fail the overall import).
|
|
480
|
+
let credentialsImported:
|
|
481
|
+
| {
|
|
482
|
+
total: number;
|
|
483
|
+
succeeded: number;
|
|
484
|
+
failed: number;
|
|
485
|
+
failedAccounts: string[];
|
|
486
|
+
}
|
|
487
|
+
| undefined;
|
|
488
|
+
|
|
489
|
+
if (validation.entries) {
|
|
490
|
+
const bundleCredentials = extractCredentialsFromBundle(
|
|
491
|
+
validation.entries,
|
|
492
|
+
validation.manifest!,
|
|
493
|
+
);
|
|
494
|
+
if (bundleCredentials.length > 0) {
|
|
495
|
+
try {
|
|
496
|
+
const credResults = await bulkSetSecureKeysAsync(bundleCredentials);
|
|
497
|
+
const failedResults = credResults.filter((r) => !r.ok);
|
|
498
|
+
if (failedResults.length > 0) {
|
|
499
|
+
log.warn(
|
|
500
|
+
{ failed: failedResults.map((f) => f.account) },
|
|
501
|
+
"Some credentials failed to import",
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
log.info(
|
|
505
|
+
{ total: bundleCredentials.length, failed: failedResults.length },
|
|
506
|
+
"Credential import complete",
|
|
507
|
+
);
|
|
508
|
+
const succeeded = bundleCredentials.length - failedResults.length;
|
|
509
|
+
credentialsImported = {
|
|
510
|
+
total: bundleCredentials.length,
|
|
511
|
+
succeeded,
|
|
512
|
+
failed: failedResults.length,
|
|
513
|
+
failedAccounts: failedResults.map((f) => f.account),
|
|
514
|
+
};
|
|
515
|
+
if (failedResults.length > 0) {
|
|
516
|
+
result.report.warnings.push(
|
|
517
|
+
`Imported ${succeeded} credential(s), ${failedResults.length} failed`,
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
} catch (err) {
|
|
521
|
+
log.warn({ err }, "Credential import failed entirely");
|
|
522
|
+
result.report.warnings.push(
|
|
523
|
+
`Credential import failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
447
529
|
// Invalidate in-process caches so imported settings.json and trust.json take effect
|
|
448
530
|
invalidateConfigCache();
|
|
449
531
|
clearTrustCache();
|
|
@@ -463,7 +545,10 @@ export async function handleMigrationImport(req: Request): Promise<Response> {
|
|
|
463
545
|
// Don't fail the import if validation itself errors
|
|
464
546
|
}
|
|
465
547
|
|
|
466
|
-
return Response.json(
|
|
548
|
+
return Response.json({
|
|
549
|
+
...result.report,
|
|
550
|
+
...(credentialsImported ? { credentialsImported } : {}),
|
|
551
|
+
});
|
|
467
552
|
} catch (err) {
|
|
468
553
|
log.error({ err }, "Unexpected error during import commit");
|
|
469
554
|
return httpError(
|
|
@@ -60,8 +60,8 @@ export function oauthAppsRouteDefinitions(): RouteDefinition[] {
|
|
|
60
60
|
endpoint: "oauth/apps",
|
|
61
61
|
method: "GET",
|
|
62
62
|
handler: ({ url }) => {
|
|
63
|
-
const
|
|
64
|
-
if (!
|
|
63
|
+
const provider = url.searchParams.get("provider_key");
|
|
64
|
+
if (!provider) {
|
|
65
65
|
return httpError(
|
|
66
66
|
"BAD_REQUEST",
|
|
67
67
|
"provider_key query parameter is required",
|
|
@@ -70,20 +70,18 @@ export function oauthAppsRouteDefinitions(): RouteDefinition[] {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
const allApps = listApps();
|
|
73
|
-
const filtered = allApps.filter(
|
|
74
|
-
(row) => row.providerKey === providerKey,
|
|
75
|
-
);
|
|
73
|
+
const filtered = allApps.filter((row) => row.provider === provider);
|
|
76
74
|
|
|
77
|
-
const providerRow = getProvider(
|
|
78
|
-
const
|
|
75
|
+
const providerRow = getProvider(provider);
|
|
76
|
+
const providerSummary = providerRow
|
|
79
77
|
? serializeProviderSummary(providerRow)
|
|
80
78
|
: null;
|
|
81
79
|
|
|
82
80
|
return Response.json({
|
|
83
|
-
provider,
|
|
81
|
+
provider: providerSummary,
|
|
84
82
|
apps: filtered.map((row) => ({
|
|
85
83
|
id: row.id,
|
|
86
|
-
provider_key: row.
|
|
84
|
+
provider_key: row.provider,
|
|
87
85
|
client_id: row.clientId,
|
|
88
86
|
created_at: row.createdAt,
|
|
89
87
|
updated_at: row.updatedAt,
|
|
@@ -138,7 +136,7 @@ export function oauthAppsRouteDefinitions(): RouteDefinition[] {
|
|
|
138
136
|
{
|
|
139
137
|
app: {
|
|
140
138
|
id: app.id,
|
|
141
|
-
provider_key: app.
|
|
139
|
+
provider_key: app.provider,
|
|
142
140
|
client_id: app.clientId,
|
|
143
141
|
created_at: app.createdAt,
|
|
144
142
|
updated_at: app.updatedAt,
|
|
@@ -165,9 +163,9 @@ export function oauthAppsRouteDefinitions(): RouteDefinition[] {
|
|
|
165
163
|
}
|
|
166
164
|
|
|
167
165
|
// Disconnect all connections for this app first to clean up tokens.
|
|
168
|
-
const connections = listConnections(app.
|
|
166
|
+
const connections = listConnections(app.provider, app.clientId);
|
|
169
167
|
for (const conn of connections) {
|
|
170
|
-
await disconnectOAuthProvider(app.
|
|
168
|
+
await disconnectOAuthProvider(app.provider, app.clientId, conn.id);
|
|
171
169
|
}
|
|
172
170
|
|
|
173
171
|
await deleteApp(params.id);
|
|
@@ -190,12 +188,12 @@ export function oauthAppsRouteDefinitions(): RouteDefinition[] {
|
|
|
190
188
|
);
|
|
191
189
|
}
|
|
192
190
|
|
|
193
|
-
const connections = listConnections(app.
|
|
191
|
+
const connections = listConnections(app.provider, app.clientId);
|
|
194
192
|
|
|
195
193
|
return Response.json({
|
|
196
194
|
connections: connections.map((row) => ({
|
|
197
195
|
id: row.id,
|
|
198
|
-
provider_key: row.
|
|
196
|
+
provider_key: row.provider,
|
|
199
197
|
account_info: row.accountInfo,
|
|
200
198
|
granted_scopes: parseGrantedScopes(row.grantedScopes),
|
|
201
199
|
status: row.status,
|
|
@@ -223,7 +221,7 @@ export function oauthAppsRouteDefinitions(): RouteDefinition[] {
|
|
|
223
221
|
}
|
|
224
222
|
|
|
225
223
|
const result = await disconnectOAuthProvider(
|
|
226
|
-
conn.
|
|
224
|
+
conn.provider,
|
|
227
225
|
undefined,
|
|
228
226
|
conn.id,
|
|
229
227
|
);
|
|
@@ -282,7 +280,7 @@ export function oauthAppsRouteDefinitions(): RouteDefinition[] {
|
|
|
282
280
|
const clientSecret = await getAppClientSecret(app);
|
|
283
281
|
|
|
284
282
|
const result = await orchestrateOAuthConnect({
|
|
285
|
-
service: app.
|
|
283
|
+
service: app.provider,
|
|
286
284
|
clientId: app.clientId,
|
|
287
285
|
clientSecret,
|
|
288
286
|
requestedScopes: body.scopes,
|
|
@@ -292,7 +290,7 @@ export function oauthAppsRouteDefinitions(): RouteDefinition[] {
|
|
|
292
290
|
|
|
293
291
|
if (result.success && result.deferred) {
|
|
294
292
|
return Response.json({
|
|
295
|
-
auth_url: result.
|
|
293
|
+
auth_url: result.authorizeUrl,
|
|
296
294
|
state: result.state,
|
|
297
295
|
});
|
|
298
296
|
}
|
|
@@ -44,6 +44,10 @@ export function oauthProvidersRouteDefinitions(): RouteDefinition[] {
|
|
|
44
44
|
},
|
|
45
45
|
|
|
46
46
|
// GET /v1/oauth/providers/:providerKey — Get a single provider.
|
|
47
|
+
// The path parameter name `providerKey` is preserved for backward
|
|
48
|
+
// compatibility with the published OpenAPI spec (operationId
|
|
49
|
+
// `oauth_providers_by_providerKey_get`). The actual URL the client hits
|
|
50
|
+
// (`/v1/oauth/providers/google`) is unchanged either way.
|
|
47
51
|
{
|
|
48
52
|
endpoint: "oauth/providers/:providerKey",
|
|
49
53
|
method: "GET",
|
|
@@ -25,6 +25,10 @@ import type { RouteDefinition } from "../http-router.js";
|
|
|
25
25
|
import type { SendMessageDeps } from "../http-types.js";
|
|
26
26
|
|
|
27
27
|
const log = getLogger("schedule-routes");
|
|
28
|
+
const SCHEDULE_GUARDIAN_TRUST_CONTEXT = {
|
|
29
|
+
sourceChannel: "vellum",
|
|
30
|
+
trustClass: "guardian",
|
|
31
|
+
} as const;
|
|
28
32
|
|
|
29
33
|
// ---------------------------------------------------------------------------
|
|
30
34
|
// Handlers
|
|
@@ -202,17 +206,23 @@ async function handleRunScheduleNow(
|
|
|
202
206
|
);
|
|
203
207
|
}
|
|
204
208
|
const conversation =
|
|
205
|
-
await sendMessageDeps.getOrCreateConversation(conversationId
|
|
209
|
+
await sendMessageDeps.getOrCreateConversation(conversationId, {
|
|
210
|
+
trustContext: SCHEDULE_GUARDIAN_TRUST_CONTEXT,
|
|
211
|
+
});
|
|
206
212
|
conversation.taskRunId = taskRunId;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
try {
|
|
214
|
+
await conversation.processMessage(
|
|
215
|
+
message,
|
|
216
|
+
[],
|
|
217
|
+
() => {}, // no event callback for HTTP mode
|
|
218
|
+
undefined,
|
|
219
|
+
undefined,
|
|
220
|
+
undefined,
|
|
221
|
+
{ isInteractive: false },
|
|
222
|
+
);
|
|
223
|
+
} finally {
|
|
224
|
+
conversation.taskRunId = undefined;
|
|
225
|
+
}
|
|
216
226
|
},
|
|
217
227
|
);
|
|
218
228
|
|
|
@@ -276,7 +286,10 @@ async function handleRunScheduleNow(
|
|
|
276
286
|
throw new Error("sendMessageDeps not available for schedule execution");
|
|
277
287
|
}
|
|
278
288
|
const activeConversation =
|
|
279
|
-
await sendMessageDeps.getOrCreateConversation(conversationId
|
|
289
|
+
await sendMessageDeps.getOrCreateConversation(conversationId, {
|
|
290
|
+
trustContext: SCHEDULE_GUARDIAN_TRUST_CONTEXT,
|
|
291
|
+
});
|
|
292
|
+
activeConversation.taskRunId = undefined;
|
|
280
293
|
await activeConversation.processMessage(
|
|
281
294
|
schedule.message,
|
|
282
295
|
[],
|
|
@@ -12,16 +12,11 @@ import { join } from "node:path";
|
|
|
12
12
|
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
|
|
15
|
-
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
16
15
|
import {
|
|
17
16
|
getPlatformBaseUrl,
|
|
18
17
|
setIngressPublicBaseUrl,
|
|
19
18
|
} from "../../config/env.js";
|
|
20
|
-
import {
|
|
21
|
-
getConfig,
|
|
22
|
-
loadRawConfig,
|
|
23
|
-
saveRawConfig,
|
|
24
|
-
} from "../../config/loader.js";
|
|
19
|
+
import { loadRawConfig, saveRawConfig } from "../../config/loader.js";
|
|
25
20
|
import { loadSkillCatalog } from "../../config/skills.js";
|
|
26
21
|
import {
|
|
27
22
|
computeGatewayTarget,
|
|
@@ -41,12 +36,6 @@ import {
|
|
|
41
36
|
generateAllowlistOptions,
|
|
42
37
|
generateScopeOptions,
|
|
43
38
|
} from "../../permissions/checker.js";
|
|
44
|
-
import {
|
|
45
|
-
getMode,
|
|
46
|
-
onModeChanged,
|
|
47
|
-
setAskBeforeActing,
|
|
48
|
-
setHostAccess,
|
|
49
|
-
} from "../../permissions/permission-mode-store.js";
|
|
50
39
|
import { getSecureKeyAsync } from "../../security/secure-keys.js";
|
|
51
40
|
import { parseToolManifestFile } from "../../skills/tool-manifest.js";
|
|
52
41
|
import {
|
|
@@ -72,24 +61,6 @@ import { resolveWorkspacePath } from "./workspace-utils.js";
|
|
|
72
61
|
|
|
73
62
|
const log = getLogger("settings-routes");
|
|
74
63
|
|
|
75
|
-
// ---------------------------------------------------------------------------
|
|
76
|
-
// Permission mode SSE broadcast
|
|
77
|
-
// ---------------------------------------------------------------------------
|
|
78
|
-
|
|
79
|
-
onModeChanged((mode) => {
|
|
80
|
-
assistantEventHub
|
|
81
|
-
.publish(
|
|
82
|
-
buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
|
|
83
|
-
type: "permission_mode_update",
|
|
84
|
-
askBeforeActing: mode.askBeforeActing,
|
|
85
|
-
hostAccess: mode.hostAccess,
|
|
86
|
-
}),
|
|
87
|
-
)
|
|
88
|
-
.catch((err) => {
|
|
89
|
-
log.warn({ err }, "Failed to publish permission_mode_update event");
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
64
|
// ---------------------------------------------------------------------------
|
|
94
65
|
// Voice config
|
|
95
66
|
// ---------------------------------------------------------------------------
|
|
@@ -240,7 +211,7 @@ async function handleOAuthConnectStart(body: {
|
|
|
240
211
|
try {
|
|
241
212
|
// For HTTP, we cannot send `open_url` mid-request. The auth URL is
|
|
242
213
|
// returned to the client to open.
|
|
243
|
-
let
|
|
214
|
+
let authorizeUrl: string | undefined;
|
|
244
215
|
|
|
245
216
|
const result = await orchestrateOAuthConnect({
|
|
246
217
|
service,
|
|
@@ -250,7 +221,7 @@ async function handleOAuthConnectStart(body: {
|
|
|
250
221
|
callbackTransport: "loopback",
|
|
251
222
|
isInteractive: true,
|
|
252
223
|
openUrl: (url: string) => {
|
|
253
|
-
|
|
224
|
+
authorizeUrl = url;
|
|
254
225
|
},
|
|
255
226
|
onDeferredComplete: (deferredResult) => {
|
|
256
227
|
// Prefer accountInfo from oauth-store when available.
|
|
@@ -309,7 +280,9 @@ async function handleOAuthConnectStart(body: {
|
|
|
309
280
|
return Response.json({
|
|
310
281
|
ok: true,
|
|
311
282
|
deferred: true,
|
|
312
|
-
authUrl
|
|
283
|
+
// Wire key stays `authUrl` for backward compatibility with existing
|
|
284
|
+
// clients; the internal field on `result` is `authorizeUrl`.
|
|
285
|
+
authUrl: result.authorizeUrl,
|
|
313
286
|
});
|
|
314
287
|
}
|
|
315
288
|
|
|
@@ -326,7 +299,9 @@ async function handleOAuthConnectStart(body: {
|
|
|
326
299
|
ok: true,
|
|
327
300
|
grantedScopes: result.grantedScopes,
|
|
328
301
|
accountInfo: responseAccountInfo,
|
|
329
|
-
|
|
302
|
+
// Wire key stays `authUrl` for backward compatibility with existing
|
|
303
|
+
// clients; the local variable was renamed to `authorizeUrl`.
|
|
304
|
+
...(authorizeUrl ? { authUrl: authorizeUrl } : {}),
|
|
330
305
|
});
|
|
331
306
|
} catch (err) {
|
|
332
307
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -921,68 +896,5 @@ export function settingsRouteDefinitions(): RouteDefinition[] {
|
|
|
921
896
|
}
|
|
922
897
|
},
|
|
923
898
|
},
|
|
924
|
-
|
|
925
|
-
// Permission mode (GET always available; PUT gated on feature flag)
|
|
926
|
-
{
|
|
927
|
-
endpoint: "permission-mode",
|
|
928
|
-
method: "GET",
|
|
929
|
-
policyKey: "permission-mode:GET",
|
|
930
|
-
summary: "Get permission mode",
|
|
931
|
-
description:
|
|
932
|
-
"Return the current two-axis permission mode (askBeforeActing, hostAccess).",
|
|
933
|
-
tags: ["settings"],
|
|
934
|
-
responseBody: z.object({
|
|
935
|
-
askBeforeActing: z.boolean(),
|
|
936
|
-
hostAccess: z.boolean(),
|
|
937
|
-
}),
|
|
938
|
-
handler: () => {
|
|
939
|
-
const mode = getMode();
|
|
940
|
-
return Response.json({
|
|
941
|
-
askBeforeActing: mode.askBeforeActing,
|
|
942
|
-
hostAccess: mode.hostAccess,
|
|
943
|
-
});
|
|
944
|
-
},
|
|
945
|
-
},
|
|
946
|
-
{
|
|
947
|
-
endpoint: "permission-mode",
|
|
948
|
-
method: "PUT",
|
|
949
|
-
policyKey: "permission-mode",
|
|
950
|
-
summary: "Update permission mode",
|
|
951
|
-
description:
|
|
952
|
-
"Update the two-axis permission mode. Requires the permission-controls-v2 feature flag.",
|
|
953
|
-
tags: ["settings"],
|
|
954
|
-
requestBody: z.object({
|
|
955
|
-
askBeforeActing: z.boolean().optional(),
|
|
956
|
-
hostAccess: z.boolean().optional(),
|
|
957
|
-
}),
|
|
958
|
-
responseBody: z.object({
|
|
959
|
-
askBeforeActing: z.boolean(),
|
|
960
|
-
hostAccess: z.boolean(),
|
|
961
|
-
}),
|
|
962
|
-
handler: async ({ req }) => {
|
|
963
|
-
const config = getConfig();
|
|
964
|
-
if (!isAssistantFeatureFlagEnabled("permission-controls-v2", config)) {
|
|
965
|
-
return httpError("NOT_FOUND", "Not found", 404);
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
const body = (await req.json()) as {
|
|
969
|
-
askBeforeActing?: boolean;
|
|
970
|
-
hostAccess?: boolean;
|
|
971
|
-
};
|
|
972
|
-
|
|
973
|
-
if (typeof body.askBeforeActing === "boolean") {
|
|
974
|
-
setAskBeforeActing(body.askBeforeActing);
|
|
975
|
-
}
|
|
976
|
-
if (typeof body.hostAccess === "boolean") {
|
|
977
|
-
setHostAccess(body.hostAccess);
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
const mode = getMode();
|
|
981
|
-
return Response.json({
|
|
982
|
-
askBeforeActing: mode.askBeforeActing,
|
|
983
|
-
hostAccess: mode.hostAccess,
|
|
984
|
-
});
|
|
985
|
-
},
|
|
986
|
-
},
|
|
987
899
|
];
|
|
988
900
|
}
|