@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
|
@@ -35,6 +35,13 @@ When the user mentions "email" - sending, reading, checking, decluttering, draft
|
|
|
35
35
|
|
|
36
36
|
Do not offer AgentMail as an option or mention it unless the user specifically asks. If Outlook is not connected, guide them through Outlook setup - do not suggest AgentMail as an alternative.
|
|
37
37
|
|
|
38
|
+
## Connection Setup
|
|
39
|
+
|
|
40
|
+
### Outlook
|
|
41
|
+
|
|
42
|
+
1. **Try connecting directly first.** Run `assistant oauth status outlook`. This will show whether or not the user had previously connected their Outlook/Microsoft account. If so, they are ready to go.
|
|
43
|
+
2. **If no connections are found:** Call `skill_load` with `skill: "vellum-oauth-integrations"`. The skill will evaluate whether managed or your-own mode is appropriate and guide the user accordingly.
|
|
44
|
+
|
|
38
45
|
## Communication Style
|
|
39
46
|
|
|
40
47
|
- **Be action-oriented.** When the user asks to do something ("declutter", "check my email"), start doing it immediately. Don't ask for permission to read their inbox - that's obviously what they want.
|
|
@@ -63,6 +63,24 @@ Only the parent conversation that spawned a subagent can interact with it (check
|
|
|
63
63
|
|
|
64
64
|
Set `send_result_to_user: false` when spawning a subagent whose result is for internal processing only. The parent will still be notified on completion, but the notification will instruct it to read the result without presenting it to the user.
|
|
65
65
|
|
|
66
|
+
## Fork Mode
|
|
67
|
+
|
|
68
|
+
Forks are sub-agents that inherit the parent's full context -- messages, system prompt, and memory -- sharing the KV cache for near-free context inheritance. Use forks when the task benefits from knowing what you've been discussing; use a regular sub-agent when the task is self-contained.
|
|
69
|
+
|
|
70
|
+
**Key behaviors:** Forks always run as `general` role (the `role` parameter is ignored). `send_result_to_user` defaults to `false`. Read fork output with `last_n: 1` to get only the final synthesis.
|
|
71
|
+
|
|
72
|
+
**When to fork vs regular sub-agent:**
|
|
73
|
+
|
|
74
|
+
| Task | Mode |
|
|
75
|
+
|---|---|
|
|
76
|
+
| Single tool call (one search, one file read) | Direct -- don't spawn at all |
|
|
77
|
+
| Multi-page web research needing conversation context | Fork |
|
|
78
|
+
| Exploratory file search informed by prior discussion | Fork |
|
|
79
|
+
| Comparing multiple sources against what was discussed | Parallel forks |
|
|
80
|
+
| Self-contained task with a clear objective | Regular sub-agent |
|
|
81
|
+
|
|
82
|
+
Rule of thumb: "Does this task need to know what we've been talking about?" If yes, fork. If the objective is fully self-describing, use a regular sub-agent with a scoped role.
|
|
83
|
+
|
|
66
84
|
## Tips
|
|
67
85
|
|
|
68
86
|
- Do NOT poll `subagent_status` in a loop. You will be notified automatically when a subagent completes.
|
|
@@ -71,3 +89,6 @@ Set `send_result_to_user: false` when spawning a subagent whose result is for in
|
|
|
71
89
|
- Use `notify_parent` for interim findings instead of waiting for completion. This lets the parent act on partial results early.
|
|
72
90
|
- Use `subagent_message` to send follow-up instructions to a running subagent.
|
|
73
91
|
- Use `subagent_abort` to cancel a subagent that is no longer needed.
|
|
92
|
+
- Default to spawning subagents for any task that involves web research, multi-file exploration, or independent coding work. Serial execution should be the exception, not the rule.
|
|
93
|
+
- When a user request has both an information-gathering component and an action component, spawn a researcher immediately rather than doing the research inline yourself.
|
|
94
|
+
- Prefer spawning 2-3 focused subagents over one large general-purpose subagent. Smaller scopes finish faster and fail more gracefully.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"tools": [
|
|
4
4
|
{
|
|
5
5
|
"name": "subagent_spawn",
|
|
6
|
-
"description": "Spawn an independent subagent to work on a task in parallel. The subagent runs autonomously and its results are reported back when complete.",
|
|
6
|
+
"description": "Spawn an independent subagent to work on a task in parallel. The subagent runs autonomously and its results are reported back when complete.\n\nTwo modes:\n- **Regular sub-agent** (fork: false or omitted): Gets only the objective + context fields. Use for self-contained tasks with clear objectives. Can use scoped roles (researcher, coder, planner).\n- **Fork** (fork: true): Inherits full parent context (messages, system prompt, memory). Shares KV cache for near-free context inheritance. Use when the task benefits from knowing what you've been discussing. Always runs as general role. Results are internal by default (send_result_to_user: false). Read with last_n: 1 to get only the final synthesis.\n\nDecision heuristic: Does the task need to know what we've been talking about? Fork. Is it self-contained? Regular sub-agent.",
|
|
7
7
|
"category": "orchestration",
|
|
8
8
|
"risk": "low",
|
|
9
9
|
"input_schema": {
|
|
@@ -19,16 +19,20 @@
|
|
|
19
19
|
},
|
|
20
20
|
"context": {
|
|
21
21
|
"type": "string",
|
|
22
|
-
"description": "Optional additional context to pass to the subagent"
|
|
22
|
+
"description": "Optional additional context to pass to the subagent. Ignored when fork is true — forks inherit the parent's full context."
|
|
23
|
+
},
|
|
24
|
+
"fork": {
|
|
25
|
+
"type": "boolean",
|
|
26
|
+
"description": "When true, the subagent inherits the parent's full context (messages, system prompt, memory) instead of receiving only the objective + context fields. Fork mode always runs as 'general' role (the role parameter is ignored) and defaults send_result_to_user to false. Use for tasks that benefit from the full conversational context."
|
|
23
27
|
},
|
|
24
28
|
"send_result_to_user": {
|
|
25
29
|
"type": "boolean",
|
|
26
|
-
"description": "Whether to present the subagent's result to the user when it completes. Defaults to true
|
|
30
|
+
"description": "Whether to present the subagent's result to the user when it completes. Defaults to true for regular sub-agents, false for forks. Set explicitly to override."
|
|
27
31
|
},
|
|
28
32
|
"role": {
|
|
29
33
|
"type": "string",
|
|
30
34
|
"enum": ["general", "researcher", "coder", "planner"],
|
|
31
|
-
"description": "Agent specialization that controls tool access. 'researcher': read-only (web, files, memory). 'coder': file and bash access. 'planner': read-only analysis. 'general': full access (default)."
|
|
35
|
+
"description": "Agent specialization that controls tool access. 'researcher': read-only (web, files, memory). 'coder': file and bash access. 'planner': read-only analysis. 'general': full access (default). Ignored when fork: true (forks always use general)."
|
|
32
36
|
},
|
|
33
37
|
"activity": {
|
|
34
38
|
"type": "string",
|
|
@@ -6,6 +6,11 @@ metadata:
|
|
|
6
6
|
emoji: "✅"
|
|
7
7
|
vellum:
|
|
8
8
|
display-name: "Tasks"
|
|
9
|
+
activation-hints:
|
|
10
|
+
- "User wants to add, check, or manage items on their to-do list or task queue"
|
|
11
|
+
- "For one-off action items, not recurring automations (use schedule for those)"
|
|
12
|
+
avoid-when:
|
|
13
|
+
- "User wants recurring/scheduled automation — use the schedule skill instead"
|
|
9
14
|
---
|
|
10
15
|
|
|
11
16
|
Two-layer task system: **task templates** (reusable definitions with input placeholders) and **work items** (instances in the Task Queue with priority tiers and status tracking).
|
|
@@ -86,6 +86,17 @@ export function getWorkspaceDirOverride(): string | undefined {
|
|
|
86
86
|
// profiler mode. The runtime uses them to locate, scope, and budget-limit
|
|
87
87
|
// profiler output on the workspace volume.
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* VELLUM_CPU_LIMIT — string (K8s resource format), default: undefined
|
|
91
|
+
* The CPU resource limit for the container (e.g. "2000m", "2").
|
|
92
|
+
* Set by the platform StatefulSet template to the exact K8s CPU limit.
|
|
93
|
+
* Used by the health endpoint to report accurate CPU core count inside
|
|
94
|
+
* gVisor sandboxes where cgroup files may expose the host node's CPUs.
|
|
95
|
+
*/
|
|
96
|
+
export function getCpuLimit(): string | undefined {
|
|
97
|
+
return str("VELLUM_CPU_LIMIT");
|
|
98
|
+
}
|
|
99
|
+
|
|
89
100
|
/**
|
|
90
101
|
* VELLUM_PROFILER_RUN_ID — string, default: undefined
|
|
91
102
|
* Unique identifier for the current profiler run. When set, the profiler
|
|
@@ -148,6 +159,7 @@ const KNOWN_VELLUM_VARS = new Set([
|
|
|
148
159
|
"VELLUM_DATA_DIR",
|
|
149
160
|
"VELLUM_DESKTOP_APP",
|
|
150
161
|
"VELLUM_DEV",
|
|
162
|
+
"VELLUM_DOCS_BASE_URL",
|
|
151
163
|
"VELLUM_ENABLE_INSECURE_LAN_PAIRING",
|
|
152
164
|
"VELLUM_HATCHED_BY",
|
|
153
165
|
"VELLUM_HOOK_EVENT",
|
|
@@ -164,6 +176,8 @@ const KNOWN_VELLUM_VARS = new Set([
|
|
|
164
176
|
"VELLUM_SSH_USER",
|
|
165
177
|
"VELLUM_UNSAFE_AUTH_BYPASS",
|
|
166
178
|
"VELLUM_WORKSPACE_DIR",
|
|
179
|
+
"VELLUM_CPU_LIMIT",
|
|
180
|
+
"VELLUM_MEMORY_LIMIT",
|
|
167
181
|
]);
|
|
168
182
|
|
|
169
183
|
/**
|
package/src/config/env.ts
CHANGED
|
@@ -164,6 +164,27 @@ export function getPlatformBaseUrl(): string {
|
|
|
164
164
|
);
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Derive the assistant service domain from the platform base URL.
|
|
169
|
+
*
|
|
170
|
+
* - `dev-platform.vellum.ai` → `dev.vellum.me`
|
|
171
|
+
* - `platform.vellum.ai` → `vellum.me`
|
|
172
|
+
* - anything else → `vellum.me` (safe default)
|
|
173
|
+
*/
|
|
174
|
+
export function getAssistantDomain(): string {
|
|
175
|
+
try {
|
|
176
|
+
const url = getPlatformBaseUrl();
|
|
177
|
+
const host = new URL(url).hostname;
|
|
178
|
+
const prefix = host.replace(/[-.]?platform\.vellum\.ai$/, "");
|
|
179
|
+
if (prefix) {
|
|
180
|
+
return `${prefix}.vellum.me`;
|
|
181
|
+
}
|
|
182
|
+
} catch {
|
|
183
|
+
// Fall through to default
|
|
184
|
+
}
|
|
185
|
+
return "vellum.me";
|
|
186
|
+
}
|
|
187
|
+
|
|
167
188
|
let _platformAssistantIdOverride: string | undefined;
|
|
168
189
|
|
|
169
190
|
export function setPlatformAssistantId(value: string | undefined): void {
|
|
@@ -178,11 +178,11 @@
|
|
|
178
178
|
"defaultEnabled": false
|
|
179
179
|
},
|
|
180
180
|
{
|
|
181
|
-
"id": "
|
|
181
|
+
"id": "multi-platform-assistant",
|
|
182
182
|
"scope": "assistant",
|
|
183
|
-
"key": "
|
|
184
|
-
"label": "
|
|
185
|
-
"description": "
|
|
183
|
+
"key": "multi-platform-assistant",
|
|
184
|
+
"label": "Multi-Platform Assistant Switcher",
|
|
185
|
+
"description": "Enable the menu-bar assistant switcher for managing multiple platform-hosted assistants (new/switch/retire)",
|
|
186
186
|
"defaultEnabled": false
|
|
187
187
|
},
|
|
188
188
|
{
|
|
@@ -288,7 +288,46 @@
|
|
|
288
288
|
"label": "Permission Controls V2",
|
|
289
289
|
"description": "Replace risk-level permission system with two independent controls: 'Ask before acting' (LLM behavior toggle) and 'Host access' (system-enforced gate)",
|
|
290
290
|
"defaultEnabled": false
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"id": "apple-container",
|
|
294
|
+
"scope": "macos",
|
|
295
|
+
"key": "apple-container",
|
|
296
|
+
"label": "Apple Container",
|
|
297
|
+
"description": "Enable assistant sandboxing via Apple Containers on macOS 26+, providing a lightweight native sandbox without third-party dependencies",
|
|
298
|
+
"defaultEnabled": false
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"id": "tool-result-truncation",
|
|
302
|
+
"scope": "assistant",
|
|
303
|
+
"key": "tool-result-truncation",
|
|
304
|
+
"label": "Post-Turn Tool Result Truncation",
|
|
305
|
+
"description": "Truncate large tool results after each assistant turn, persisting full content to disk for on-demand re-reads",
|
|
306
|
+
"defaultEnabled": false
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"id": "managed-gemini-embeddings-enabled",
|
|
310
|
+
"scope": "assistant",
|
|
311
|
+
"key": "managed-gemini-embeddings-enabled",
|
|
312
|
+
"label": "Managed Gemini Embeddings Enabled",
|
|
313
|
+
"description": "Route embedding requests through the platform runtime proxy using Vellum-managed Gemini credentials when available",
|
|
314
|
+
"defaultEnabled": false
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"id": "fork-from-message",
|
|
318
|
+
"scope": "macos",
|
|
319
|
+
"key": "fork-from-message",
|
|
320
|
+
"label": "Fork from Message",
|
|
321
|
+
"description": "Show the 'Fork from here' option in message overflow menus",
|
|
322
|
+
"defaultEnabled": false
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"id": "fork-from-message",
|
|
326
|
+
"scope": "macos",
|
|
327
|
+
"key": "fork-from-message",
|
|
328
|
+
"label": "Fork from Message",
|
|
329
|
+
"description": "Show the Fork from here option in message overflow menus",
|
|
330
|
+
"defaultEnabled": false
|
|
291
331
|
}
|
|
292
332
|
]
|
|
293
333
|
}
|
|
294
|
-
|
package/src/config/loader.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { dirname, join } from "node:path";
|
|
|
11
11
|
import { ConfigError } from "../util/errors.js";
|
|
12
12
|
import { getLogger } from "../util/logger.js";
|
|
13
13
|
import { ensureDataDir, getWorkspaceConfigPath } from "../util/platform.js";
|
|
14
|
+
import { isAssistantFeatureFlagEnabled } from "./assistant-feature-flags.js";
|
|
14
15
|
import { AssistantConfigSchema } from "./schema.js";
|
|
15
16
|
import type { AssistantConfig } from "./types.js";
|
|
16
17
|
|
|
@@ -385,7 +386,46 @@ export function loadConfig(): AssistantConfig {
|
|
|
385
386
|
warnAndStripDeprecatedFields(fileConfig, configPath);
|
|
386
387
|
|
|
387
388
|
// Validate and apply defaults via Zod schema
|
|
388
|
-
|
|
389
|
+
let config = validateWithSchema(fileConfig);
|
|
390
|
+
|
|
391
|
+
// Managed Gemini embedding defaults migration.
|
|
392
|
+
// When on a managed platform (IS_PLATFORM=true) with the feature flag
|
|
393
|
+
// enabled and no explicit embedding provider chosen (provider=auto),
|
|
394
|
+
// persist Gemini embedding defaults into the raw config file.
|
|
395
|
+
// Idempotent: once provider=gemini is written, subsequent loads skip this.
|
|
396
|
+
if (config.memory.embeddings.provider === "auto") {
|
|
397
|
+
try {
|
|
398
|
+
if (
|
|
399
|
+
(process.env.IS_PLATFORM === "true" ||
|
|
400
|
+
process.env.IS_PLATFORM === "1") &&
|
|
401
|
+
isManagedGeminiFFEnabled(config)
|
|
402
|
+
) {
|
|
403
|
+
setNestedValue(fileConfig, "memory.embeddings.provider", "gemini");
|
|
404
|
+
setNestedValue(
|
|
405
|
+
fileConfig,
|
|
406
|
+
"memory.embeddings.geminiModel",
|
|
407
|
+
"gemini-embedding-2-preview",
|
|
408
|
+
);
|
|
409
|
+
setNestedValue(
|
|
410
|
+
fileConfig,
|
|
411
|
+
"memory.embeddings.geminiDimensions",
|
|
412
|
+
3072,
|
|
413
|
+
);
|
|
414
|
+
setNestedValue(fileConfig, "memory.qdrant.vectorSize", 3072);
|
|
415
|
+
writeFileSync(configPath, JSON.stringify(fileConfig, null, 2) + "\n");
|
|
416
|
+
log.info(
|
|
417
|
+
"Applied managed Gemini embedding defaults (provider=gemini, model=gemini-embedding-2-preview, dimensions=3072, vectorSize=3072)",
|
|
418
|
+
);
|
|
419
|
+
// Re-validate so the returned config reflects the migration.
|
|
420
|
+
config = validateWithSchema(fileConfig);
|
|
421
|
+
}
|
|
422
|
+
} catch (err) {
|
|
423
|
+
log.warn(
|
|
424
|
+
{ err },
|
|
425
|
+
"Managed Gemini defaults migration failed — continuing with existing config",
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
389
429
|
|
|
390
430
|
// If the config file didn't exist, write the full defaults to disk so
|
|
391
431
|
// users can discover and edit all available options.
|
|
@@ -421,6 +461,21 @@ export function loadConfig(): AssistantConfig {
|
|
|
421
461
|
}
|
|
422
462
|
}
|
|
423
463
|
|
|
464
|
+
/**
|
|
465
|
+
* Check whether the managed-gemini-embeddings-enabled feature flag is on.
|
|
466
|
+
* Wrapped in a try/catch so a flag-resolver failure never breaks config loading.
|
|
467
|
+
*/
|
|
468
|
+
function isManagedGeminiFFEnabled(config: AssistantConfig): boolean {
|
|
469
|
+
try {
|
|
470
|
+
return isAssistantFeatureFlagEnabled(
|
|
471
|
+
"managed-gemini-embeddings-enabled",
|
|
472
|
+
config,
|
|
473
|
+
);
|
|
474
|
+
} catch {
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
424
479
|
export function saveConfig(config: AssistantConfig): void {
|
|
425
480
|
ensureMigratedDataDir();
|
|
426
481
|
const configPath = getConfigPath();
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strips environment-specific fields from config JSON before transferring
|
|
3
|
+
* between local and platform environments (teleport/restore).
|
|
4
|
+
*
|
|
5
|
+
* Fields removed or reset:
|
|
6
|
+
* - `ingress.publicBaseUrl` → set to `""`
|
|
7
|
+
* - `ingress.enabled` → deleted
|
|
8
|
+
* - `daemon` → deleted entirely
|
|
9
|
+
* - `skills.load.extraDirs` → set to `[]`
|
|
10
|
+
*/
|
|
11
|
+
export function sanitizeConfigForTransfer(configJson: string): string {
|
|
12
|
+
let config: Record<string, unknown>;
|
|
13
|
+
try {
|
|
14
|
+
const parsed = JSON.parse(configJson);
|
|
15
|
+
if (
|
|
16
|
+
typeof parsed !== "object" ||
|
|
17
|
+
parsed === null ||
|
|
18
|
+
Array.isArray(parsed)
|
|
19
|
+
) {
|
|
20
|
+
return configJson;
|
|
21
|
+
}
|
|
22
|
+
config = parsed;
|
|
23
|
+
} catch {
|
|
24
|
+
return configJson;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Strip ingress environment-specific fields
|
|
28
|
+
if (config.ingress && typeof config.ingress === "object") {
|
|
29
|
+
const ingress = config.ingress as Record<string, unknown>;
|
|
30
|
+
ingress.publicBaseUrl = "";
|
|
31
|
+
delete ingress.enabled;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Strip daemon entirely
|
|
35
|
+
delete config.daemon;
|
|
36
|
+
|
|
37
|
+
// Strip skills.load.extraDirs
|
|
38
|
+
if (config.skills && typeof config.skills === "object") {
|
|
39
|
+
const skills = config.skills as Record<string, unknown>;
|
|
40
|
+
if (skills.load && typeof skills.load === "object") {
|
|
41
|
+
const load = skills.load as Record<string, unknown>;
|
|
42
|
+
load.extraDirs = [];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return JSON.stringify(config, null, 2) + "\n";
|
|
47
|
+
}
|
package/src/config/schema.ts
CHANGED
|
@@ -49,6 +49,14 @@ export type { FishAudioConfig } from "./schemas/fish-audio.js";
|
|
|
49
49
|
export { FishAudioConfigSchema } from "./schemas/fish-audio.js";
|
|
50
50
|
export type { HeartbeatConfig } from "./schemas/heartbeat.js";
|
|
51
51
|
export { HeartbeatConfigSchema } from "./schemas/heartbeat.js";
|
|
52
|
+
export type {
|
|
53
|
+
HostBrowserCdpInspectConfig,
|
|
54
|
+
HostBrowserConfig,
|
|
55
|
+
} from "./schemas/host-browser.js";
|
|
56
|
+
export {
|
|
57
|
+
HostBrowserCdpInspectConfigSchema,
|
|
58
|
+
HostBrowserConfigSchema,
|
|
59
|
+
} from "./schemas/host-browser.js";
|
|
52
60
|
export type {
|
|
53
61
|
ContextOverflowRecoveryConfig,
|
|
54
62
|
ContextWindowConfig,
|
|
@@ -115,6 +123,7 @@ export {
|
|
|
115
123
|
export type { MemoryRetrievalConfig } from "./schemas/memory-retrieval.js";
|
|
116
124
|
export {
|
|
117
125
|
MemoryDynamicBudgetConfigSchema,
|
|
126
|
+
MemoryInjectionConfigSchema,
|
|
118
127
|
MemoryRetrievalConfigSchema,
|
|
119
128
|
} from "./schemas/memory-retrieval.js";
|
|
120
129
|
export type {
|
|
@@ -139,8 +148,6 @@ export {
|
|
|
139
148
|
PlatformConfigSchema,
|
|
140
149
|
UiConfigSchema,
|
|
141
150
|
} from "./schemas/platform.js";
|
|
142
|
-
export type { SandboxConfig } from "./schemas/sandbox.js";
|
|
143
|
-
export { SandboxConfigSchema } from "./schemas/sandbox.js";
|
|
144
151
|
export type {
|
|
145
152
|
PermissionsConfig,
|
|
146
153
|
SecretDetectionConfig,
|
|
@@ -206,6 +213,7 @@ import { ElevenLabsConfigSchema } from "./schemas/elevenlabs.js";
|
|
|
206
213
|
import { FilingConfigSchema } from "./schemas/filing.js";
|
|
207
214
|
import { FishAudioConfigSchema } from "./schemas/fish-audio.js";
|
|
208
215
|
import { HeartbeatConfigSchema } from "./schemas/heartbeat.js";
|
|
216
|
+
import { HostBrowserConfigSchema } from "./schemas/host-browser.js";
|
|
209
217
|
import {
|
|
210
218
|
ContextWindowConfigSchema,
|
|
211
219
|
EffortSchema,
|
|
@@ -227,7 +235,6 @@ import {
|
|
|
227
235
|
PlatformConfigSchema,
|
|
228
236
|
UiConfigSchema,
|
|
229
237
|
} from "./schemas/platform.js";
|
|
230
|
-
import { SandboxConfigSchema } from "./schemas/sandbox.js";
|
|
231
238
|
import {
|
|
232
239
|
PermissionsConfigSchema,
|
|
233
240
|
SecretDetectionConfigSchema,
|
|
@@ -247,7 +254,7 @@ export const AssistantConfigSchema = z
|
|
|
247
254
|
.number({ error: "maxTokens must be a number" })
|
|
248
255
|
.int("maxTokens must be an integer")
|
|
249
256
|
.positive("maxTokens must be a positive integer")
|
|
250
|
-
.default(
|
|
257
|
+
.default(64000)
|
|
251
258
|
.describe("Maximum number of output tokens per LLM response"),
|
|
252
259
|
effort: EffortSchema,
|
|
253
260
|
speed: SpeedSchema,
|
|
@@ -261,7 +268,6 @@ export const AssistantConfigSchema = z
|
|
|
261
268
|
.default(getDataDir())
|
|
262
269
|
.describe("Directory for storing assistant data (database, logs, etc.)"),
|
|
263
270
|
timeouts: TimeoutConfigSchema.default(TimeoutConfigSchema.parse({})),
|
|
264
|
-
sandbox: SandboxConfigSchema.default(SandboxConfigSchema.parse({})),
|
|
265
271
|
rateLimit: RateLimitConfigSchema.default(RateLimitConfigSchema.parse({})),
|
|
266
272
|
secretDetection: SecretDetectionConfigSchema.default(
|
|
267
273
|
SecretDetectionConfigSchema.parse({}),
|
|
@@ -281,6 +287,9 @@ export const AssistantConfigSchema = z
|
|
|
281
287
|
),
|
|
282
288
|
filing: FilingConfigSchema.default(FilingConfigSchema.parse({})),
|
|
283
289
|
heartbeat: HeartbeatConfigSchema.default(HeartbeatConfigSchema.parse({})),
|
|
290
|
+
hostBrowser: HostBrowserConfigSchema.default(
|
|
291
|
+
HostBrowserConfigSchema.parse({}),
|
|
292
|
+
),
|
|
284
293
|
journal: JournalConfigSchema.default(JournalConfigSchema.parse({})),
|
|
285
294
|
mcp: McpConfigSchema.default(McpConfigSchema.parse({})),
|
|
286
295
|
acp: AcpConfigSchema.default(AcpConfigSchema.parse({})),
|
|
@@ -321,6 +330,13 @@ export const AssistantConfigSchema = z
|
|
|
321
330
|
.max(200, "maxStepsPerSession must be <= 200")
|
|
322
331
|
.default(50)
|
|
323
332
|
.describe("Maximum number of computer-use steps per session"),
|
|
333
|
+
systemPromptPrefix: z
|
|
334
|
+
.string({ error: "systemPromptPrefix must be a string" })
|
|
335
|
+
.nullable()
|
|
336
|
+
.default(null)
|
|
337
|
+
.describe(
|
|
338
|
+
"Custom text injected at the very beginning of the system prompt. Defaults to null (no injection).",
|
|
339
|
+
),
|
|
324
340
|
})
|
|
325
341
|
.superRefine((config, ctx) => {
|
|
326
342
|
if (
|
|
@@ -373,6 +389,31 @@ export const AssistantConfigSchema = z
|
|
|
373
389
|
"memory.retrieval.dynamicBudget.minInjectTokens must be <= memory.retrieval.dynamicBudget.maxInjectTokens",
|
|
374
390
|
});
|
|
375
391
|
}
|
|
392
|
+
const injection = config.memory?.retrieval?.injection;
|
|
393
|
+
const ctxLoad = injection?.contextLoad;
|
|
394
|
+
if (
|
|
395
|
+
ctxLoad &&
|
|
396
|
+
ctxLoad.capabilityReserve + ctxLoad.serendipitySlots >= ctxLoad.maxNodes
|
|
397
|
+
) {
|
|
398
|
+
ctx.addIssue({
|
|
399
|
+
code: z.ZodIssueCode.custom,
|
|
400
|
+
path: ["memory", "retrieval", "injection", "contextLoad"],
|
|
401
|
+
message:
|
|
402
|
+
"memory.retrieval.injection.contextLoad.capabilityReserve + serendipitySlots must be less than maxNodes",
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
const perTurn = injection?.perTurn;
|
|
406
|
+
if (
|
|
407
|
+
perTurn &&
|
|
408
|
+
perTurn.capabilityReserve + perTurn.serendipitySlots >= perTurn.maxNodes
|
|
409
|
+
) {
|
|
410
|
+
ctx.addIssue({
|
|
411
|
+
code: z.ZodIssueCode.custom,
|
|
412
|
+
path: ["memory", "retrieval", "injection", "perTurn"],
|
|
413
|
+
message:
|
|
414
|
+
"memory.retrieval.injection.perTurn.capabilityReserve + serendipitySlots must be less than maxNodes",
|
|
415
|
+
});
|
|
416
|
+
}
|
|
376
417
|
});
|
|
377
418
|
|
|
378
419
|
export type AssistantConfig = z.infer<typeof AssistantConfigSchema>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for the `cdp-inspect` browser backend — connects directly
|
|
5
|
+
* to a host Chrome instance that was launched with `--remote-debugging-port`
|
|
6
|
+
* (e.g. `chrome://inspect`-style remote debugging) as an alternative to the
|
|
7
|
+
* extension or local Playwright backend.
|
|
8
|
+
*/
|
|
9
|
+
export const HostBrowserCdpInspectConfigSchema = z
|
|
10
|
+
.object({
|
|
11
|
+
enabled: z
|
|
12
|
+
.boolean({ error: "hostBrowser.cdpInspect.enabled must be a boolean" })
|
|
13
|
+
.default(false)
|
|
14
|
+
.describe(
|
|
15
|
+
"Whether the cdp-inspect backend is enabled. When true, the factory will route browser tool calls through the configured host/port instead of the local Playwright backend.",
|
|
16
|
+
),
|
|
17
|
+
host: z
|
|
18
|
+
.string({ error: "hostBrowser.cdpInspect.host must be a string" })
|
|
19
|
+
.min(1, "hostBrowser.cdpInspect.host must not be empty")
|
|
20
|
+
.default("localhost")
|
|
21
|
+
.describe(
|
|
22
|
+
"Host name or IP address where the host Chrome instance exposes its remote debugging endpoint.",
|
|
23
|
+
),
|
|
24
|
+
port: z
|
|
25
|
+
.number({ error: "hostBrowser.cdpInspect.port must be a number" })
|
|
26
|
+
.int("hostBrowser.cdpInspect.port must be an integer")
|
|
27
|
+
.min(1, "hostBrowser.cdpInspect.port must be >= 1")
|
|
28
|
+
.max(65535, "hostBrowser.cdpInspect.port must be <= 65535")
|
|
29
|
+
.default(9222)
|
|
30
|
+
.describe(
|
|
31
|
+
"TCP port for the host Chrome remote-debugging endpoint (matches `--remote-debugging-port`).",
|
|
32
|
+
),
|
|
33
|
+
probeTimeoutMs: z
|
|
34
|
+
.number({
|
|
35
|
+
error: "hostBrowser.cdpInspect.probeTimeoutMs must be a number",
|
|
36
|
+
})
|
|
37
|
+
.int("hostBrowser.cdpInspect.probeTimeoutMs must be an integer")
|
|
38
|
+
.min(50, "hostBrowser.cdpInspect.probeTimeoutMs must be >= 50")
|
|
39
|
+
.max(5000, "hostBrowser.cdpInspect.probeTimeoutMs must be <= 5000")
|
|
40
|
+
.default(500)
|
|
41
|
+
.describe(
|
|
42
|
+
"Timeout (in milliseconds) for the backend availability probe. Kept small so browser tool calls fail fast when the endpoint is unreachable.",
|
|
43
|
+
),
|
|
44
|
+
})
|
|
45
|
+
.describe(
|
|
46
|
+
"Settings for the cdp-inspect backend that connects to a host Chrome instance via its remote-debugging endpoint.",
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export type HostBrowserCdpInspectConfig = z.infer<
|
|
50
|
+
typeof HostBrowserCdpInspectConfigSchema
|
|
51
|
+
>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Top-level configuration for host-browser backends. Currently only exposes
|
|
55
|
+
* `cdpInspect`, but the shape leaves room for additional host-browser knobs
|
|
56
|
+
* (e.g. extension-specific settings) without another namespace churn.
|
|
57
|
+
*/
|
|
58
|
+
export const HostBrowserConfigSchema = z
|
|
59
|
+
.object({
|
|
60
|
+
cdpInspect: HostBrowserCdpInspectConfigSchema.default(
|
|
61
|
+
HostBrowserCdpInspectConfigSchema.parse({}),
|
|
62
|
+
),
|
|
63
|
+
})
|
|
64
|
+
.describe("Host-browser backend configuration (cdp-inspect, etc.)");
|
|
65
|
+
|
|
66
|
+
export type HostBrowserConfig = z.infer<typeof HostBrowserConfigSchema>;
|
|
@@ -80,7 +80,7 @@ export const MemoryCleanupConfigSchema = z
|
|
|
80
80
|
.nonnegative(
|
|
81
81
|
"memory.cleanup.llmRequestLogRetentionMs must be non-negative",
|
|
82
82
|
)
|
|
83
|
-
.default(
|
|
83
|
+
.default(1 * 24 * 60 * 60 * 1000)
|
|
84
84
|
.describe(
|
|
85
85
|
"Retention period for LLM request/response logs in milliseconds (0 disables pruning)",
|
|
86
86
|
),
|
|
@@ -184,6 +184,106 @@ const MemoryFreshnessConfigSchema = z
|
|
|
184
184
|
"Freshness-based ranking for memory retrieval — down-ranks old items unless recently reinforced",
|
|
185
185
|
);
|
|
186
186
|
|
|
187
|
+
const MemoryContextLoadInjectionSchema = z
|
|
188
|
+
.object({
|
|
189
|
+
maxNodes: z
|
|
190
|
+
.number({
|
|
191
|
+
error:
|
|
192
|
+
"memory.retrieval.injection.contextLoad.maxNodes must be a number",
|
|
193
|
+
})
|
|
194
|
+
.int("memory.retrieval.injection.contextLoad.maxNodes must be an integer")
|
|
195
|
+
.positive(
|
|
196
|
+
"memory.retrieval.injection.contextLoad.maxNodes must be a positive integer",
|
|
197
|
+
)
|
|
198
|
+
.default(25)
|
|
199
|
+
.describe("Maximum number of memory nodes to load at conversation start"),
|
|
200
|
+
serendipitySlots: z
|
|
201
|
+
.number({
|
|
202
|
+
error:
|
|
203
|
+
"memory.retrieval.injection.contextLoad.serendipitySlots must be a number",
|
|
204
|
+
})
|
|
205
|
+
.int(
|
|
206
|
+
"memory.retrieval.injection.contextLoad.serendipitySlots must be an integer",
|
|
207
|
+
)
|
|
208
|
+
.nonnegative(
|
|
209
|
+
"memory.retrieval.injection.contextLoad.serendipitySlots must be non-negative",
|
|
210
|
+
)
|
|
211
|
+
.default(5)
|
|
212
|
+
.describe("Number of random wildcard memory picks at conversation start"),
|
|
213
|
+
capabilityReserve: z
|
|
214
|
+
.number({
|
|
215
|
+
error:
|
|
216
|
+
"memory.retrieval.injection.contextLoad.capabilityReserve must be a number",
|
|
217
|
+
})
|
|
218
|
+
.int(
|
|
219
|
+
"memory.retrieval.injection.contextLoad.capabilityReserve must be an integer",
|
|
220
|
+
)
|
|
221
|
+
.nonnegative(
|
|
222
|
+
"memory.retrieval.injection.contextLoad.capabilityReserve must be non-negative",
|
|
223
|
+
)
|
|
224
|
+
.default(5)
|
|
225
|
+
.describe(
|
|
226
|
+
"Reserved slots for skill/CLI capability nodes at conversation start",
|
|
227
|
+
),
|
|
228
|
+
})
|
|
229
|
+
.describe("Memory injection limits at conversation start");
|
|
230
|
+
|
|
231
|
+
const MemoryPerTurnInjectionSchema = z
|
|
232
|
+
.object({
|
|
233
|
+
maxNodes: z
|
|
234
|
+
.number({
|
|
235
|
+
error: "memory.retrieval.injection.perTurn.maxNodes must be a number",
|
|
236
|
+
})
|
|
237
|
+
.int("memory.retrieval.injection.perTurn.maxNodes must be an integer")
|
|
238
|
+
.positive(
|
|
239
|
+
"memory.retrieval.injection.perTurn.maxNodes must be a positive integer",
|
|
240
|
+
)
|
|
241
|
+
.default(6)
|
|
242
|
+
.describe(
|
|
243
|
+
"Maximum total memory nodes injected per turn (general + capability + serendipity)",
|
|
244
|
+
),
|
|
245
|
+
serendipitySlots: z
|
|
246
|
+
.number({
|
|
247
|
+
error:
|
|
248
|
+
"memory.retrieval.injection.perTurn.serendipitySlots must be a number",
|
|
249
|
+
})
|
|
250
|
+
.int(
|
|
251
|
+
"memory.retrieval.injection.perTurn.serendipitySlots must be an integer",
|
|
252
|
+
)
|
|
253
|
+
.nonnegative(
|
|
254
|
+
"memory.retrieval.injection.perTurn.serendipitySlots must be non-negative",
|
|
255
|
+
)
|
|
256
|
+
.default(1)
|
|
257
|
+
.describe("Number of random wildcard memory picks per turn"),
|
|
258
|
+
capabilityReserve: z
|
|
259
|
+
.number({
|
|
260
|
+
error:
|
|
261
|
+
"memory.retrieval.injection.perTurn.capabilityReserve must be a number",
|
|
262
|
+
})
|
|
263
|
+
.int(
|
|
264
|
+
"memory.retrieval.injection.perTurn.capabilityReserve must be an integer",
|
|
265
|
+
)
|
|
266
|
+
.nonnegative(
|
|
267
|
+
"memory.retrieval.injection.perTurn.capabilityReserve must be non-negative",
|
|
268
|
+
)
|
|
269
|
+
.default(2)
|
|
270
|
+
.describe("Reserved slots for skill/CLI capability nodes per turn"),
|
|
271
|
+
})
|
|
272
|
+
.describe("Memory injection limits for mid-conversation turns");
|
|
273
|
+
|
|
274
|
+
export const MemoryInjectionConfigSchema = z
|
|
275
|
+
.object({
|
|
276
|
+
contextLoad: MemoryContextLoadInjectionSchema.default(
|
|
277
|
+
MemoryContextLoadInjectionSchema.parse({}),
|
|
278
|
+
),
|
|
279
|
+
perTurn: MemoryPerTurnInjectionSchema.default(
|
|
280
|
+
MemoryPerTurnInjectionSchema.parse({}),
|
|
281
|
+
),
|
|
282
|
+
})
|
|
283
|
+
.describe(
|
|
284
|
+
"Controls how many memory items are injected at conversation start and per turn",
|
|
285
|
+
);
|
|
286
|
+
|
|
187
287
|
export const MemoryRetrievalConfigSchema = z
|
|
188
288
|
.object({
|
|
189
289
|
maxInjectTokens: z
|
|
@@ -209,6 +309,9 @@ export const MemoryRetrievalConfigSchema = z
|
|
|
209
309
|
dynamicBudget: MemoryDynamicBudgetConfigSchema.default(
|
|
210
310
|
MemoryDynamicBudgetConfigSchema.parse({}),
|
|
211
311
|
),
|
|
312
|
+
injection: MemoryInjectionConfigSchema.default(
|
|
313
|
+
MemoryInjectionConfigSchema.parse({}),
|
|
314
|
+
),
|
|
212
315
|
})
|
|
213
316
|
.describe(
|
|
214
317
|
"Controls how memories are retrieved and injected into conversations",
|