@vellumai/assistant 0.11.2 → 0.11.3-staging.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +58 -3
- package/docs/trusted-contact-access.md +9 -5
- package/docs/vellum-doctor.md +195 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/ces-client/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +19 -2
- package/node_modules/@vellumai/environments/package.json +2 -1
- package/node_modules/@vellumai/environments/src/__tests__/cloud-assistant-hub-url.test.ts +38 -0
- package/node_modules/@vellumai/environments/src/__tests__/install-layout.test.ts +98 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +5 -5
- package/node_modules/@vellumai/environments/src/index.ts +17 -6
- package/node_modules/@vellumai/environments/src/install-layout.ts +49 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +29 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +4 -0
- package/node_modules/@vellumai/gateway-client/src/verification-session-contract.ts +91 -6
- package/node_modules/@vellumai/ipc-server-utils/src/endpoint.test.ts +36 -0
- package/node_modules/@vellumai/ipc-server-utils/src/endpoint.ts +142 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +2 -0
- package/node_modules/@vellumai/ipc-server-utils/src/listen-options.ts +3 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +15 -1
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +17 -2
- package/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
- package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +16 -2
- package/openapi.yaml +589 -30
- package/package.json +1 -1
- package/src/__tests__/agent-image-optimize.test.ts +4 -4
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +113 -66
- package/src/__tests__/agent-loop-override-profile.test.ts +38 -48
- package/src/__tests__/agent-loop-subagent-billing-headers.test.ts +166 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/answered-question-persistence.test.ts +240 -0
- package/src/__tests__/anthropic-provider.test.ts +165 -30
- package/src/__tests__/app-control-flow.test.ts +9 -8
- package/src/__tests__/assistant-event-hub.test.ts +48 -0
- package/src/__tests__/attachments-store-heic-normalize.test.ts +16 -12
- package/src/__tests__/attachments-store.test.ts +130 -68
- package/src/__tests__/attachments.test.ts +36 -36
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/call-start-guardian-guard.test.ts +18 -4
- package/src/__tests__/canned-reply-release.test.ts +86 -0
- package/src/__tests__/channel-guardian.test.ts +59 -29
- package/src/__tests__/channel-readiness-telegram-remote.test.ts +154 -0
- package/src/__tests__/channel-setup-panel-ack.test.ts +6 -5
- package/src/__tests__/client-os-metadata-persistence.test.ts +103 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
- package/src/__tests__/consult-deadline.test.ts +65 -0
- package/src/__tests__/conversation-agent-loop.test.ts +438 -2
- package/src/__tests__/conversation-disk-view-integration.test.ts +5 -1
- package/src/__tests__/conversation-disk-view.test.ts +4 -4
- package/src/__tests__/conversation-error.test.ts +22 -3
- package/src/__tests__/conversation-fork-crud.test.ts +5 -1
- package/src/__tests__/conversation-fork-referential.test.ts +352 -0
- package/src/__tests__/conversation-fork-retrospective.test.ts +5 -1
- package/src/__tests__/conversation-group-tools.test.ts +32 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +27 -1
- package/src/__tests__/conversation-initial-prompt.test.ts +51 -22
- package/src/__tests__/conversation-key-store-bootstrap-cleanup.test.ts +119 -0
- package/src/__tests__/conversation-key-store-origin.test.ts +105 -0
- package/src/__tests__/conversation-list-recency-ordering.test.ts +104 -0
- package/src/__tests__/conversation-origin-at-creation.test.ts +153 -0
- package/src/__tests__/conversation-origin-channel-filter.test.ts +95 -0
- package/src/__tests__/conversation-placement-promotion.test.ts +172 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +123 -0
- package/src/__tests__/conversation-queue.test.ts +433 -1
- package/src/__tests__/conversation-retry-route.test.ts +3 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +64 -1
- package/src/__tests__/conversation-store-ephemeral.test.ts +4 -0
- package/src/__tests__/conversation-store.test.ts +26 -10
- package/src/__tests__/conversation-summarize-route.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +15 -6
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -5
- package/src/__tests__/conversation-surfaces-app-control.test.ts +12 -11
- package/src/__tests__/conversation-surfaces-app-open.test.ts +11 -5
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +5 -4
- package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +967 -0
- package/src/__tests__/conversation-surfaces-persisted-info.test.ts +312 -0
- package/src/__tests__/conversation-surfaces-queued-emit.test.ts +6 -5
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -8
- package/src/__tests__/conversation-surfaces-standalone.test.ts +21 -11
- package/src/__tests__/conversation-surfaces-state-update.test.ts +7 -11
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -6
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +11 -6
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +9 -6
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +70 -7
- package/src/__tests__/conversation-wait-for-idle.test.ts +6 -11
- package/src/__tests__/credential-prompt-route.test.ts +57 -7
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +89 -28
- package/src/__tests__/custom-group-listing-visibility.test.ts +1 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +4 -1
- package/src/__tests__/discord-access-request-privacy.test.ts +366 -0
- package/src/__tests__/discord-requester-notice-privacy.test.ts +87 -0
- package/src/__tests__/disk-pressure-guard.test.ts +55 -55
- package/src/__tests__/disk-pressure-routes.test.ts +10 -10
- package/src/__tests__/disk-pressure-tools.test.ts +2 -2
- package/src/__tests__/disk-usage.test.ts +35 -20
- package/src/__tests__/document-sync-tags.test.ts +379 -0
- package/src/__tests__/document-update-default-surface.test.ts +28 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +2 -2
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -4
- package/src/__tests__/ensure-conversation-exists.test.ts +8 -5
- package/src/__tests__/events-dev-bypass-actor.test.ts +183 -1
- package/src/__tests__/evict-conversations-for-reload.test.ts +90 -0
- package/src/__tests__/file-list-tool.test.ts +12 -10
- package/src/__tests__/file-ops-service.test.ts +151 -44
- package/src/__tests__/file-read-container-boundary.test.ts +137 -0
- package/src/__tests__/file-read-tool.test.ts +21 -9
- package/src/__tests__/file-url-path-guard.test.ts +83 -0
- package/src/__tests__/filesystem-tools.test.ts +82 -66
- package/src/__tests__/guardian-outbound-http.test.ts +8 -8
- package/src/__tests__/helpers/gateway-verification-sessions-stub.ts +14 -1
- package/src/__tests__/helpers/hub-clients.ts +42 -0
- package/src/__tests__/helpers/mock-conversation.ts +46 -0
- package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +61 -57
- package/src/__tests__/history-repair.test.ts +112 -12
- package/src/__tests__/host-bash-proxy.test.ts +10 -5
- package/src/__tests__/host-bash-routes.test.ts +67 -0
- package/src/__tests__/host-browser-proxy.test.ts +2 -2
- package/src/__tests__/host-cu-proxy.test.ts +3 -7
- package/src/__tests__/host-file-proxy.test.ts +3 -7
- package/src/__tests__/host-file-read-tool.test.ts +5 -1
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +6 -4
- package/src/__tests__/http-conversation-lineage.test.ts +2 -5
- package/src/__tests__/http-user-message-parity.test.ts +44 -0
- package/src/__tests__/identity-routes.test.ts +13 -13
- package/src/__tests__/image-conversion.test.ts +29 -26
- package/src/__tests__/image-source-path-reinject.test.ts +2 -2
- package/src/__tests__/inference-profile-session-handler.test.ts +95 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +25 -0
- package/src/__tests__/introduction-card-resolver.test.ts +6 -1
- package/src/__tests__/list-messages-attachments.test.ts +56 -32
- package/src/__tests__/list-messages-background-tool-completion.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +2 -2
- package/src/__tests__/list-messages-hidden-metadata.test.ts +16 -16
- package/src/__tests__/list-messages-page-latest.test.ts +61 -61
- package/src/__tests__/list-messages-provider-error.test.ts +6 -6
- package/src/__tests__/list-messages-queued.test.ts +49 -6
- package/src/__tests__/list-messages-system-card.test.ts +4 -4
- package/src/__tests__/list-messages-tool-merge.test.ts +9 -9
- package/src/__tests__/llm-resolver-override-or-default.test.ts +141 -0
- package/src/__tests__/llm-usage-store.test.ts +55 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +45 -0
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +133 -0
- package/src/__tests__/media-stream-server-integration.test.ts +36 -0
- package/src/__tests__/migration-export-http.test.ts +1 -1
- package/src/__tests__/migration-import-commit-http.test.ts +1 -1
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -1
- package/src/__tests__/migration-validate-http.test.ts +1 -1
- package/src/__tests__/mtime-cache.test.ts +65 -3
- package/src/__tests__/notification-platform-adapter.test.ts +104 -0
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
- package/src/__tests__/oauth-provider-profiles.test.ts +4 -2
- package/src/__tests__/oauth-provider-seed-logos.test.ts +65 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +17 -0
- package/src/__tests__/oauth-providers-routes.test.ts +1 -0
- package/src/__tests__/openai-responses-prompt-cache.test.ts +5 -2
- package/src/__tests__/path-policy.test.ts +164 -1
- package/src/__tests__/persist-media-references.test.ts +2 -2
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +5 -5
- package/src/__tests__/persist-unsendable-image.test.ts +23 -23
- package/src/__tests__/persona-resolver.test.ts +154 -0
- package/src/__tests__/plugin-api-webhook-url.test.ts +170 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +6 -0
- package/src/__tests__/processing-flag-persist-failure.test.ts +15 -10
- package/src/__tests__/profile-availability-incomplete.test.ts +113 -0
- package/src/__tests__/profiler-routes.test.ts +13 -13
- package/src/__tests__/prompt-cache-cross-turn-stability.test.ts +593 -0
- package/src/__tests__/proxy-approval-callback.test.ts +3 -3
- package/src/__tests__/queued-message-cancel-and-steer.test.ts +189 -0
- package/src/__tests__/queued-message-steer-actor-scoping.test.ts +164 -0
- package/src/__tests__/resolve-trust-class.test.ts +20 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +1 -1
- package/src/__tests__/run-due-schedules.test.ts +174 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +15 -7
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +166 -0
- package/src/__tests__/schedule-routes.test.ts +730 -8
- package/src/__tests__/schedule-store.test.ts +540 -0
- package/src/__tests__/schedule-tools.test.ts +103 -0
- package/src/__tests__/scheduler-wake.test.ts +5 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +29 -1
- package/src/__tests__/secure-keys.test.ts +91 -0
- package/src/__tests__/server-history-render.test.ts +97 -7
- package/src/__tests__/size-guard.test.ts +8 -8
- package/src/__tests__/skill-docs-sync-guard.test.ts +3 -2
- package/src/__tests__/skill-tool-factory.test.ts +247 -0
- package/src/__tests__/skills-install-staging.test.ts +15 -6
- package/src/__tests__/slack-edit-ordering-characterization.test.ts +103 -0
- package/src/__tests__/slack-inbound-verification.test.ts +4 -1
- package/src/__tests__/slack-mention-binding-invariance.test.ts +103 -0
- package/src/__tests__/slack-mention-provider-leak-audit.test.ts +135 -0
- package/src/__tests__/starter-task-flow.test.ts +5 -4
- package/src/__tests__/steer-on-enqueue-question.test.ts +3 -2
- package/src/__tests__/stt-language-catalog-parity.test.ts +38 -0
- package/src/__tests__/subagent-allowlist-validation.test.ts +26 -4
- package/src/__tests__/subagent-cron-run-attribution.test.ts +301 -0
- package/src/__tests__/subagent-disposal.test.ts +10 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +10 -0
- package/src/__tests__/subagent-fork-prompt-role.test.ts +85 -11
- package/src/__tests__/subagent-fork-spawn.test.ts +15 -7
- package/src/__tests__/subagent-manager-notify.test.ts +148 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/subagent-persistence.test.ts +141 -0
- package/src/__tests__/subagent-role-registry.test.ts +172 -63
- package/src/__tests__/subagent-role-resolution.test.ts +88 -0
- package/src/__tests__/subagent-spawn-and-await.test.ts +48 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +111 -10
- package/src/__tests__/subagent-terminal-message.test.ts +88 -1
- package/src/__tests__/subagent-tool-gate-mode.test.ts +225 -10
- package/src/__tests__/subagent-tools.test.ts +1901 -108
- package/src/__tests__/surface-completion-compaction-boundary.test.ts +124 -0
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +298 -0
- package/src/__tests__/system-prompt.test.ts +82 -7
- package/src/__tests__/tool-grant-request-escalation.test.ts +40 -1
- package/src/__tests__/tool-result-spool.test.ts +74 -18
- package/src/__tests__/tool-side-effects-documents.test.ts +174 -0
- package/src/__tests__/tool-side-effects-hook-failures.test.ts +129 -0
- package/src/__tests__/tools-audio-read.test.ts +10 -10
- package/src/__tests__/tools-get-route.test.ts +85 -12
- package/src/__tests__/tools-list-cli.test.ts +171 -0
- package/src/__tests__/top-level-renderer.test.ts +54 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +68 -1
- package/src/__tests__/trusted-contact-multichannel.test.ts +4 -1
- package/src/__tests__/turn-tail-chain.test.ts +135 -0
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +6 -4
- package/src/__tests__/ui-visual-surface.test.ts +5 -4
- package/src/__tests__/ui-work-result-surface.test.ts +5 -4
- package/src/__tests__/unified-turn-context-visible-app.test.ts +7 -8
- package/src/__tests__/usage-routes.test.ts +62 -0
- package/src/__tests__/verification-outbound-delivery.test.ts +176 -0
- package/src/__tests__/visible-app-context.test.ts +20 -4
- package/src/__tests__/web-search-history.test.ts +96 -0
- package/src/__tests__/workspace-migration-139-clear-renamed-cost-profile-label.test.ts +6 -6
- package/src/__tests__/workspace-migration-140-repair-seed-pinned-memory-v3-live.test.ts +330 -0
- package/src/acp/failure-error.ts +3 -5
- package/src/agent/attachments.ts +26 -24
- package/src/agent/history-repair/history-repair.ts +27 -26
- package/src/agent/image-optimize.ts +6 -6
- package/src/agent/loop.ts +40 -22
- package/src/agent/message-types.ts +3 -3
- package/src/api/constants/document-tools.ts +55 -0
- package/src/api/events/question-answered.ts +53 -0
- package/src/api/events/tool-result.ts +7 -0
- package/src/api/index.ts +13 -0
- package/src/api/responses/conversation-message.ts +11 -0
- package/src/api/surfaces-oauth-connect.test.ts +96 -0
- package/src/api/surfaces.ts +36 -8
- package/src/approvals/guardian-channel-delivery.ts +83 -0
- package/src/approvals/guardian-expiry-notifier.ts +13 -11
- package/src/approvals/guardian-request-resolvers.ts +222 -135
- package/src/calls/__tests__/voice-session-bridge.test.ts +50 -0
- package/src/calls/media-stream-server.ts +9 -1
- package/src/calls/voice-session-bridge.ts +38 -0
- package/src/channels/__tests__/gateway-verification-sessions.test.ts +3 -3
- package/src/channels/config.ts +7 -2
- package/src/channels/gateway-verification-sessions.ts +7 -2
- package/src/channels/types.ts +7 -1
- package/src/cli/commands/__tests__/cache.test.ts +7 -4
- package/src/cli/commands/__tests__/cli-test-harness.ts +82 -0
- package/src/cli/commands/__tests__/conversations-wake.test.ts +51 -6
- package/src/cli/commands/__tests__/inference-models.test.ts +14 -0
- package/src/cli/commands/__tests__/inference-profiles.test.ts +44 -1
- package/src/cli/commands/__tests__/inference-providers.test.ts +7 -0
- package/src/cli/commands/__tests__/plugins.test.ts +692 -0
- package/src/cli/commands/__tests__/schedules.test.ts +136 -37
- package/src/cli/commands/conversations.ts +7 -3
- package/src/cli/commands/credentials.help.ts +7 -0
- package/src/cli/commands/inference-profiles.ts +9 -3
- package/src/cli/commands/inference.help.ts +16 -2
- package/src/cli/commands/mcp.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +18 -0
- package/src/cli/commands/notifications.ts +3 -6
- package/src/cli/commands/oauth/connect-surface-guidance.test.ts +16 -0
- package/src/cli/commands/oauth/connect-surface-guidance.ts +25 -7
- package/src/cli/commands/oauth/connect.test.ts +26 -1
- package/src/cli/commands/oauth/connect.ts +4 -1
- package/src/cli/commands/oauth/index.help.ts +3 -1
- package/src/cli/commands/oauth/providers.ts +3 -0
- package/src/cli/commands/plugins.help.ts +25 -2
- package/src/cli/commands/plugins.ts +289 -10
- package/src/cli/commands/schedules.help.ts +14 -12
- package/src/cli/commands/schedules.ts +19 -5
- package/src/cli/commands/tools.help.ts +4 -2
- package/src/cli/commands/tools.ts +38 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +1 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +79 -0
- package/src/cli/lib/__tests__/install-from-platform.test.ts +47 -1
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +86 -7
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +122 -0
- package/src/cli/lib/install-from-github.ts +61 -0
- package/src/cli/lib/install-from-platform.ts +13 -2
- package/src/cli/lib/plugin-surfaces.ts +124 -4
- package/src/cli/lib/upgrade-plugin.ts +18 -0
- package/src/cli.ts +1 -1
- package/src/config/__tests__/deployment-context-defaults.test.ts +73 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +40 -0
- package/src/config/__tests__/plugin-updates-schema.test.ts +43 -0
- package/src/config/__tests__/profile-tool-support.test.ts +131 -0
- package/src/config/bundled-skills/AGENTS.md +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +3 -3
- package/src/config/bundled-skills/schedule/SKILL.md +5 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +1 -0
- package/src/config/bundled-skills/subagent/SKILL.md +53 -22
- package/src/config/bundled-skills/subagent/TOOLS.json +14 -13
- package/src/config/bundled-skills/visualize/SKILL.md +1 -1
- package/src/config/default-profile-catalog.ts +6 -2
- package/src/config/feature-flag-registry.json +25 -17
- package/src/config/llm-resolver.ts +45 -15
- package/src/config/loader.ts +70 -1
- package/src/config/profile-tool-support.ts +110 -0
- package/src/config/sanitize-for-transfer.ts +11 -0
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/stt.test.ts +20 -5
- package/src/config/schemas/channels.ts +13 -0
- package/src/config/schemas/memory-retrospective.ts +25 -0
- package/src/config/schemas/plugin-updates.ts +55 -0
- package/src/config/schemas/services.ts +8 -4
- package/src/config/schemas/stt.ts +17 -5
- package/src/config/schemas/timeouts.ts +1 -1
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +16 -0
- package/src/contacts/guardian-delivery-reader.ts +29 -2
- package/src/context/compactor.ts +4 -4
- package/src/context/post-turn-tool-result-truncation.ts +32 -16
- package/src/context/strip-injections.ts +42 -0
- package/src/context/tool-result-spool.ts +32 -18
- package/src/credential-execution/ces-runtime.ts +3 -0
- package/src/credential-execution/client.ts +22 -1
- package/src/credential-execution/process-manager.test.ts +99 -0
- package/src/credential-execution/process-manager.ts +62 -16
- package/src/daemon/__tests__/abort-null-controller.test.ts +141 -5
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +8 -12
- package/src/daemon/__tests__/install-assistant-command.test.ts +234 -0
- package/src/daemon/__tests__/turn-tail-assistant-reply-notify.test.ts +2 -4
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +20 -29
- package/src/daemon/channel-ui-capability.ts +4 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +117 -61
- package/src/daemon/conversation-agent-loop.ts +318 -148
- package/src/daemon/conversation-attachments.ts +1 -1
- package/src/daemon/conversation-error.ts +8 -1
- package/src/daemon/conversation-initial-prompt.ts +16 -38
- package/src/daemon/conversation-lifecycle.ts +154 -32
- package/src/daemon/conversation-messaging.ts +106 -43
- package/src/daemon/conversation-process.ts +131 -33
- package/src/daemon/conversation-queue-manager.ts +10 -0
- package/src/daemon/conversation-runtime-assembly.ts +9 -4
- package/src/daemon/conversation-store.ts +52 -3
- package/src/daemon/conversation-surface-state.ts +9 -0
- package/src/daemon/conversation-surfaces.ts +403 -210
- package/src/daemon/conversation-tool-setup.ts +56 -7
- package/src/daemon/conversation-turn-finalize.ts +134 -89
- package/src/daemon/conversation.ts +111 -27
- package/src/daemon/disk-pressure-guard-lifecycle.ts +2 -2
- package/src/daemon/disk-pressure-guard.ts +3 -3
- package/src/daemon/doordash-steps.ts +5 -5
- package/src/daemon/external-plugins-bootstrap.ts +7 -1
- package/src/daemon/handlers/config-channels.ts +48 -5
- package/src/daemon/handlers/conversation-history.ts +1 -1
- package/src/daemon/handlers/conversations.ts +62 -17
- package/src/daemon/handlers/shared.ts +12 -0
- package/src/daemon/handlers/skills.ts +11 -1
- package/src/daemon/identity-helpers.ts +38 -10
- package/src/daemon/install-assistant-command.ts +322 -0
- package/src/daemon/lifecycle.ts +14 -3
- package/src/daemon/message-types/conversations.ts +6 -7
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/persist-media-references.ts +23 -14
- package/src/daemon/process-message.ts +6 -6
- package/src/daemon/tool-setup-types.ts +19 -122
- package/src/daemon/tool-side-effects.ts +17 -94
- package/src/daemon/trust-context-types.ts +39 -0
- package/src/daemon/trust-context.ts +14 -6
- package/src/daemon/turn-tail-chain.ts +73 -0
- package/src/daemon/web-search-history.ts +47 -33
- package/src/heartbeat/heartbeat-service.ts +6 -6
- package/src/ipc/__tests__/socket-path.test.ts +21 -0
- package/src/ipc/assistant-server.ts +17 -10
- package/src/ipc/cli-client.ts +10 -1
- package/src/ipc/routes/__tests__/documents-sync-ipc-routes.test.ts +56 -0
- package/src/ipc/routes/documents-sync-ipc-routes.ts +42 -0
- package/src/ipc/socket-cleanup.ts +9 -7
- package/src/ipc/socket-path.ts +4 -96
- package/src/live-voice/__tests__/live-voice-archive.test.ts +16 -16
- package/src/live-voice/__tests__/live-voice-attach-image.test.ts +209 -0
- package/src/live-voice/__tests__/live-voice-connection.test.ts +20 -0
- package/src/live-voice/__tests__/live-voice-integration.test.ts +7 -5
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +265 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +6 -1
- package/src/live-voice/__tests__/live-voice-vad.test.ts +35 -15
- package/src/live-voice/__tests__/protocol.test.ts +52 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +3 -0
- package/src/live-voice/live-voice-archive.ts +13 -13
- package/src/live-voice/live-voice-connection.ts +7 -1
- package/src/live-voice/live-voice-photo.ts +169 -0
- package/src/live-voice/live-voice-session.ts +108 -4
- package/src/live-voice/protocol.ts +89 -1
- package/src/mcp/client.ts +10 -0
- package/src/messaging/providers/__tests__/callback-routing.test.ts +5 -1
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +66 -4
- package/src/messaging/providers/callback-routing.ts +1 -0
- package/src/messaging/providers/discord/api.ts +312 -0
- package/src/messaging/providers/discord/dm-delivery.test.ts +204 -0
- package/src/messaging/providers/discord/render.test.ts +204 -0
- package/src/messaging/providers/discord/render.ts +195 -0
- package/src/messaging/providers/discord/send.test.ts +179 -0
- package/src/messaging/providers/discord/send.ts +212 -0
- package/src/messaging/providers/discord/transport.ts +81 -0
- package/src/messaging/providers/index.ts +3 -1
- package/src/messaging/providers/retry-policy.test.ts +247 -0
- package/src/messaging/providers/retry-policy.ts +206 -0
- package/src/messaging/providers/slack/mention-source.test.ts +285 -0
- package/src/messaging/providers/slack/mention-source.ts +287 -0
- package/src/messaging/providers/telegram-bot/api.ts +47 -130
- package/src/messaging/providers/whatsapp/api.ts +47 -136
- package/src/monitoring/__tests__/db-integrity-sample.test.ts +4 -1
- package/src/monitoring/__tests__/plugin-auto-update.test.ts +332 -0
- package/src/monitoring/db-integrity-sample.ts +6 -1
- package/src/monitoring/plugin-auto-update.ts +359 -0
- package/src/monitoring/resource-sampler.ts +21 -5
- package/src/monitoring/worker.ts +13 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +375 -2
- package/src/notifications/__tests__/broadcaster.test.ts +37 -1
- package/src/notifications/__tests__/copy-composer.test.ts +165 -0
- package/src/notifications/__tests__/emit-signal-pipeline-failure.test.ts +205 -0
- package/src/notifications/__tests__/notification-utils.test.ts +249 -0
- package/src/notifications/adapters/platform.ts +31 -2
- package/src/notifications/assistant-reply-producer.ts +79 -32
- package/src/notifications/broadcaster.ts +30 -10
- package/src/notifications/copy-composer.ts +69 -0
- package/src/notifications/emit-signal.ts +82 -15
- package/src/notifications/events-store.ts +10 -2
- package/src/notifications/home-feed-side-effect.ts +6 -3
- package/src/notifications/notification-utils.ts +173 -5
- package/src/notifications/signal.ts +12 -0
- package/src/oauth/AGENTS.md +4 -2
- package/src/oauth/byo-connection.ts +6 -1
- package/src/oauth/credential-token-resolver.ts +3 -10
- package/src/oauth/manual-token-connection.ts +29 -64
- package/src/oauth/manual-token-providers.ts +62 -0
- package/src/oauth/provider-serializer.ts +13 -0
- package/src/oauth/seed-providers.ts +62 -11
- package/src/onboarding/onboarding-events-store.ts +91 -1
- package/src/permissions/question-prompter.test.ts +4 -0
- package/src/permissions/question-prompter.ts +21 -4
- package/src/persistence/__tests__/conversation-lineage.test.ts +248 -0
- package/src/persistence/attachments-store.ts +15 -15
- package/src/persistence/conversation-attention-store.ts +30 -10
- package/src/persistence/conversation-bootstrap.ts +17 -0
- package/src/persistence/conversation-crud.ts +363 -97
- package/src/persistence/conversation-group-migration.ts +1 -1
- package/src/persistence/conversation-key-store.ts +38 -10
- package/src/persistence/conversation-lineage.ts +226 -0
- package/src/persistence/conversation-plugin-facade.ts +28 -3
- package/src/persistence/conversation-queries.ts +207 -33
- package/src/persistence/conversation-types.ts +107 -1
- package/src/persistence/jobs-store.ts +32 -8
- package/src/persistence/llm-usage-store.ts +22 -0
- package/src/persistence/migrations/361-normalize-managed-connection-rows.test.ts +168 -0
- package/src/persistence/migrations/361-normalize-managed-connection-rows.ts +76 -0
- package/src/persistence/migrations/362-add-conversation-subagent-kind.test.ts +187 -0
- package/src/persistence/migrations/362-add-conversation-subagent-kind.ts +93 -0
- package/src/persistence/migrations/363-backfill-schedule-inference-profile.test.ts +229 -0
- package/src/persistence/migrations/363-backfill-schedule-inference-profile.ts +127 -0
- package/src/persistence/migrations/364-add-schedule-source-key.test.ts +120 -0
- package/src/persistence/migrations/364-add-schedule-source-key.ts +43 -0
- package/src/persistence/migrations/365-add-conversation-fork-strategy.ts +27 -0
- package/src/persistence/schema/conversations.ts +32 -0
- package/src/persistence/schema/infrastructure.ts +3 -0
- package/src/persistence/steps.ts +30 -0
- package/src/persistence/subagent-store.ts +148 -6
- package/src/platform/managed-speech.test.ts +20 -0
- package/src/platform/managed-speech.ts +9 -0
- package/src/plugin-api/index.ts +8 -0
- package/src/plugin-api/webhook-url.ts +151 -0
- package/src/plugins/__tests__/installed-plugin-dirs.test.ts +82 -0
- package/src/plugins/__tests__/source-fingerprint.test.ts +5 -1
- package/src/plugins/collect-source-versions.ts +4 -27
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +5 -5
- package/src/plugins/defaults/exploration-drift/package.json +1 -1
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +4 -2
- package/src/plugins/defaults/image-recovery/recover.ts +67 -57
- package/src/plugins/defaults/index.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +64 -18
- package/src/plugins/defaults/memory/__tests__/jobs-worker-outcome-contract.test.ts +242 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-retrospective-sweep.test.ts +24 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +48 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +511 -19
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +39 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +493 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +5 -4
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +5 -1
- package/src/plugins/defaults/memory/job-handlers.ts +87 -5
- package/src/plugins/defaults/memory/jobs-worker.ts +60 -6
- package/src/plugins/defaults/memory/memory-retrospective-constants.ts +11 -0
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +29 -0
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +342 -60
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +23 -3
- package/src/plugins/defaults/memory/substrate/consolidation-lock.ts +9 -4
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +7 -0
- package/src/plugins/defaults/memory/v1/graph/injection.ts +1 -1
- package/src/plugins/defaults/memory/v2/router.ts +8 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +1 -2
- package/src/plugins/external-plugin-loader.ts +17 -8
- package/src/plugins/installed-plugin-dirs.ts +101 -0
- package/src/plugins/mtime-cache.ts +34 -22
- package/src/plugins/types.ts +69 -8
- package/src/prompts/persona-resolver.ts +6 -2
- package/src/prompts/system-prompt.ts +72 -17
- package/src/providers/__tests__/inference.test.ts +40 -0
- package/src/providers/__tests__/preflight-resolved-config.test.ts +58 -1
- package/src/providers/__tests__/retry-callsite.test.ts +67 -0
- package/src/providers/__tests__/vellum-connection-routing.test.ts +42 -11
- package/src/providers/anthropic/client.ts +112 -95
- package/src/providers/connection-resolution.ts +35 -1
- package/src/providers/gemini/client.ts +5 -5
- package/src/providers/inference/adapter-factory.ts +16 -10
- package/src/providers/inference/auth.ts +16 -0
- package/src/providers/inference/connection-availability.ts +164 -12
- package/src/providers/inference/connections.ts +25 -1
- package/src/providers/media-resolve.ts +21 -11
- package/src/providers/model-catalog.ts +15 -0
- package/src/providers/openai/chat-completions-provider.ts +4 -4
- package/src/providers/openai/responses-provider.ts +12 -25
- package/src/providers/registry.ts +9 -4
- package/src/providers/retry.ts +25 -0
- package/src/providers/server-tool-pairing.ts +134 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +187 -6
- package/src/providers/speech-to-text/deepgram.ts +1 -0
- package/src/providers/speech-to-text/resolve.ts +80 -10
- package/src/providers/speech-to-text/vellum-managed.ts +7 -1
- package/src/providers/speech-to-text/vellum-speech-relay-connection.ts +3 -1
- package/src/providers/types.ts +26 -6
- package/src/providers/vellum-model-routing.ts +6 -7
- package/src/runtime/AGENTS.md +2 -0
- package/src/runtime/__tests__/agent-wake.test.ts +16 -16
- package/src/runtime/__tests__/background-job-runner.test.ts +0 -144
- package/src/runtime/__tests__/desktop-presence.test.ts +162 -0
- package/src/runtime/agent-wake.ts +63 -24
- package/src/runtime/assistant-event-hub.ts +87 -12
- package/src/runtime/auth/__tests__/guard-tests.test.ts +2 -0
- package/src/runtime/auth/__tests__/scopes.test.ts +20 -0
- package/src/runtime/auth/same-actor.ts +56 -8
- package/src/runtime/auth/scopes.ts +12 -0
- package/src/runtime/auth/types.ts +2 -0
- package/src/runtime/background-job-runner.ts +5 -27
- package/src/runtime/channel-readiness-service.ts +59 -3
- package/src/runtime/channel-readiness-types.ts +18 -0
- package/src/runtime/desktop-presence.ts +69 -0
- package/src/runtime/http-server.ts +12 -0
- package/src/runtime/local-actor-identity.ts +11 -9
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/client-routes.test.ts +186 -14
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +547 -1
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +162 -7
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +14 -10
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +340 -3
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +28 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +173 -1
- package/src/runtime/routes/__tests__/question-routes.test.ts +64 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +20 -0
- package/src/runtime/routes/__tests__/skill-history-route.test.ts +116 -0
- package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +60 -2
- package/src/runtime/routes/archive-utils.ts +16 -12
- package/src/runtime/routes/attachment-routes.ts +13 -6
- package/src/runtime/routes/canned-reply-release.ts +54 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -27
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +5 -0
- package/src/runtime/routes/client-routes.ts +114 -2
- package/src/runtime/routes/conversation-cli-routes.ts +10 -12
- package/src/runtime/routes/conversation-list-routes.ts +59 -10
- package/src/runtime/routes/conversation-management-routes.ts +47 -18
- package/src/runtime/routes/conversation-query-routes.ts +32 -53
- package/src/runtime/routes/conversation-routes.ts +360 -293
- package/src/runtime/routes/credential-prompt-routes.ts +23 -2
- package/src/runtime/routes/debug-routes.ts +4 -1
- package/src/runtime/routes/default-provider-routes.ts +7 -11
- package/src/runtime/routes/documents-routes.ts +44 -1
- package/src/runtime/routes/events-routes.ts +28 -1
- package/src/runtime/routes/host-app-control-routes.ts +2 -0
- package/src/runtime/routes/host-bash-routes.ts +2 -0
- package/src/runtime/routes/host-browser-routes.ts +2 -0
- package/src/runtime/routes/host-cu-routes.ts +2 -0
- package/src/runtime/routes/host-file-routes.ts +2 -0
- package/src/runtime/routes/host-transfer-routes.ts +4 -0
- package/src/runtime/routes/identity-routes.ts +6 -6
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +7 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +14 -0
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +14 -11
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -17
- package/src/runtime/routes/inference-profile-availability-guard.ts +171 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +26 -2
- package/src/runtime/routes/inference-profile-session-routes.ts +2 -1
- package/src/runtime/routes/inference-profiles-routes.ts +152 -73
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -16
- package/src/runtime/routes/llm-call-sites-routes.ts +13 -0
- package/src/runtime/routes/log-export-routes.ts +1 -1
- package/src/runtime/routes/notification-routes.ts +0 -14
- package/src/runtime/routes/oauth-providers.ts +1 -0
- package/src/runtime/routes/plugins-routes.ts +106 -1
- package/src/runtime/routes/profiler-routes.ts +4 -2
- package/src/runtime/routes/question-routes.ts +28 -10
- package/src/runtime/routes/retrospective-routes.ts +9 -3
- package/src/runtime/routes/schedule-routes.ts +210 -12
- package/src/runtime/routes/secret-routes.ts +40 -23
- package/src/runtime/routes/settings-routes.ts +41 -13
- package/src/runtime/routes/skills-routes.ts +79 -0
- package/src/runtime/routes/ui-snapshot-routes.ts +1 -0
- package/src/runtime/routes/wake-conversation-routes.ts +23 -0
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +1 -0
- package/src/runtime/services/conversation-serializer.ts +24 -9
- package/src/runtime/sync/documents-sidecar-publish.test.ts +101 -0
- package/src/runtime/sync/resource-sync-events.ts +79 -1
- package/src/runtime/sync/worker-daemon-notify.test.ts +34 -0
- package/src/runtime/sync/worker-daemon-notify.ts +44 -6
- package/src/runtime/verification-outbound-actions.ts +250 -222
- package/src/runtime/verification-templates.ts +41 -30
- package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +614 -0
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1066 -0
- package/src/schedule/inference-profile.ts +64 -3
- package/src/schedule/plugin-schedule-declarations.ts +518 -0
- package/src/schedule/plugin-schedule-reconciler.ts +605 -0
- package/src/schedule/plugin-schedules-gate.ts +23 -0
- package/src/schedule/schedule-store.ts +520 -26
- package/src/schedule/scheduler.ts +38 -0
- package/src/security/credential-backend.ts +51 -4
- package/src/security/encrypted-store.ts +64 -42
- package/src/security/secure-keys.ts +55 -7
- package/src/skills/catalog-install.ts +20 -7
- package/src/skills/inline-command-runner.ts +2 -7
- package/src/skills/skill-history.test.ts +269 -0
- package/src/skills/skill-history.ts +250 -0
- package/src/skills/skillssh-registry.ts +1 -1
- package/src/stt/daemon-batch-transcriber.ts +8 -6
- package/src/subagent/__tests__/consult-prompt.test.ts +25 -0
- package/src/subagent/consult-prompt.ts +3 -1
- package/src/subagent/consult-transcript.ts +1 -1
- package/src/subagent/manager.ts +304 -44
- package/src/subagent/progress-events.ts +35 -0
- package/src/subagent/role-resolution.ts +88 -0
- package/src/subagent/types.ts +302 -67
- package/src/subagent/validate-allowlists.ts +3 -4
- package/src/telegram/__tests__/webhook-health.test.ts +73 -1
- package/src/telegram/webhook-health.ts +101 -3
- package/src/telemetry/__tests__/telemetry-event-fixtures.ts +2 -0
- package/src/telemetry/activation-funnel.ts +6 -1
- package/src/telemetry/live-voice-funnel.ts +75 -0
- package/src/telemetry/telemetry-event-sources.ts +6 -0
- package/src/telemetry/telemetry-wire-source.json +1 -1
- package/src/telemetry/telemetry-wire.generated.ts +2 -0
- package/src/telemetry/types.ts +23 -4
- package/src/telemetry/usage-telemetry-reporter.test.ts +4 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +1 -1
- package/src/tools/ask-question/ask-question-tool.test.ts +118 -3
- package/src/tools/ask-question/ask-question-tool.ts +56 -2
- package/src/tools/browser/browser-execution.ts +1 -1
- package/src/tools/calls/call-start.ts +8 -5
- package/src/tools/conversation-groups/move_to_group.ts +10 -12
- package/src/tools/document/document-tool.ts +11 -4
- package/src/tools/execution-timeout.ts +9 -2
- package/src/tools/executor.ts +7 -6
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +7 -13
- package/src/tools/filesystem/search.ts +23 -21
- package/src/tools/filesystem/write.ts +4 -1
- package/src/tools/host-filesystem/edit.ts +7 -2
- package/src/tools/host-filesystem/read.ts +21 -8
- package/src/tools/host-filesystem/write.ts +10 -2
- package/src/tools/host-terminal/host-shell.ts +2 -2
- package/src/tools/mcp/mcp-tool-factory.ts +25 -1
- package/src/tools/permission-checker.ts +8 -3
- package/src/tools/schedule/delete.ts +13 -1
- package/src/tools/schedule/list.ts +14 -3
- package/src/tools/schedule/update.ts +56 -33
- package/src/tools/shared/filesystem/audio-read.ts +6 -4
- package/src/tools/shared/filesystem/file-ops-service.ts +176 -116
- package/src/tools/shared/filesystem/image-read.ts +12 -12
- package/src/tools/shared/filesystem/path-policy.ts +70 -5
- package/src/tools/shared/filesystem/size-guard.ts +6 -6
- package/src/tools/shared/input-misuse.ts +72 -0
- package/src/tools/skills/scaffold-managed.ts +82 -0
- package/src/tools/skills/skill-tool-factory.ts +14 -1
- package/src/tools/subagent/consult-deadline.ts +12 -7
- package/src/tools/subagent/message.ts +3 -1
- package/src/tools/subagent/read.ts +66 -4
- package/src/tools/subagent/spawn.ts +500 -78
- package/src/tools/tool-approval-handler.ts +45 -4
- package/src/tools/types.ts +22 -3
- package/src/tools/ui-surface/surface-shape-docs.ts +1 -1
- package/src/tools/ui-surface/visual-validation.ts +2 -0
- package/src/usage/__tests__/subagent-attribution.test.ts +109 -0
- package/src/usage/subagent-attribution.ts +108 -0
- package/src/util/__tests__/sqlite-retry.test.ts +112 -0
- package/src/util/abort-reasons.ts +16 -0
- package/src/util/ansi.ts +44 -0
- package/src/util/disk-usage.ts +17 -13
- package/src/util/image-conversion.ts +20 -13
- package/src/util/schedule-source-key.ts +23 -0
- package/src/util/worker-process.ts +7 -1
- package/src/workspace/git-service.ts +33 -9
- package/src/workspace/migrations/140-repair-seed-pinned-memory-v3-live.ts +260 -0
- package/src/workspace/migrations/141-stt-english-default-to-multilingual.ts +111 -0
- package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +126 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/workspace/top-level-renderer.ts +15 -2
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +0 -357
- package/src/daemon/install-symlink.ts +0 -207
- package/src/notifications/deferred-emit.ts +0 -147
|
@@ -2,6 +2,9 @@ import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
|
2
2
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
|
|
5
|
+
import type { CliCommandRunResult } from "./cli-test-harness.js";
|
|
6
|
+
import { runCliCommand } from "./cli-test-harness.js";
|
|
7
|
+
|
|
5
8
|
let ipcCalls: Array<{ method: string; params?: Record<string, unknown> }> = [];
|
|
6
9
|
let mockIpcResult: {
|
|
7
10
|
ok: boolean;
|
|
@@ -41,43 +44,8 @@ mock.module("../../../util/logger.js", () => ({
|
|
|
41
44
|
|
|
42
45
|
const { registerSchedulesCommand } = await import("../schedules.js");
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
): Promise<{ stdout: string; exitCode: number }> {
|
|
47
|
-
const originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
48
|
-
const stdoutChunks: string[] = [];
|
|
49
|
-
|
|
50
|
-
process.stdout.write = ((chunk: unknown) => {
|
|
51
|
-
stdoutChunks.push(typeof chunk === "string" ? chunk : String(chunk));
|
|
52
|
-
return true;
|
|
53
|
-
}) as typeof process.stdout.write;
|
|
54
|
-
|
|
55
|
-
process.exitCode = 0;
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
const program = new Command();
|
|
59
|
-
program.exitOverride();
|
|
60
|
-
program.configureOutput({
|
|
61
|
-
writeErr: () => {},
|
|
62
|
-
writeOut: (str: string) => stdoutChunks.push(str),
|
|
63
|
-
});
|
|
64
|
-
registerSchedulesCommand(program);
|
|
65
|
-
await program.parseAsync(["node", "assistant", ...args]);
|
|
66
|
-
} catch {
|
|
67
|
-
if (process.exitCode === 0) {
|
|
68
|
-
process.exitCode = 1;
|
|
69
|
-
}
|
|
70
|
-
} finally {
|
|
71
|
-
process.stdout.write = originalStdoutWrite;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const exitCode = process.exitCode ?? 0;
|
|
75
|
-
process.exitCode = 0;
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
exitCode,
|
|
79
|
-
stdout: stdoutChunks.join(""),
|
|
80
|
-
};
|
|
47
|
+
function runCommand(args: string[]): Promise<CliCommandRunResult> {
|
|
48
|
+
return runCliCommand(registerSchedulesCommand, args);
|
|
81
49
|
}
|
|
82
50
|
|
|
83
51
|
beforeEach(() => {
|
|
@@ -231,6 +199,137 @@ describe("schedules list", () => {
|
|
|
231
199
|
expect(logLines.join("\n")).not.toContain("Authored heartbeat check");
|
|
232
200
|
});
|
|
233
201
|
|
|
202
|
+
test("renders a SOURCE column with the owning plugin's name", async () => {
|
|
203
|
+
mockIpcResult = {
|
|
204
|
+
ok: true,
|
|
205
|
+
result: {
|
|
206
|
+
schedules: [
|
|
207
|
+
{
|
|
208
|
+
id: "schedule-plugin",
|
|
209
|
+
name: "Inbox poll",
|
|
210
|
+
enabled: true,
|
|
211
|
+
syntax: "cron",
|
|
212
|
+
expression: "*/15 * * * *",
|
|
213
|
+
cronExpression: "*/15 * * * *",
|
|
214
|
+
timezone: null,
|
|
215
|
+
message: "poll the inbox",
|
|
216
|
+
script: null,
|
|
217
|
+
nextRunAt: 1_778_800_000_000,
|
|
218
|
+
lastRunAt: null,
|
|
219
|
+
lastStatus: "ok",
|
|
220
|
+
retryCount: 0,
|
|
221
|
+
maxRetries: 3,
|
|
222
|
+
retryBackoffMs: 60_000,
|
|
223
|
+
description: "Polls the inbox",
|
|
224
|
+
cadenceDescription: "Every 15 minutes",
|
|
225
|
+
mode: "execute",
|
|
226
|
+
status: "active",
|
|
227
|
+
routingIntent: "all_channels",
|
|
228
|
+
reuseConversation: false,
|
|
229
|
+
wakeConversationId: null,
|
|
230
|
+
sourceKey: "plugin:gmail/poll-inbox",
|
|
231
|
+
userEnabled: null,
|
|
232
|
+
isOneShot: false,
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
id: "schedule-imperative",
|
|
236
|
+
name: "Heartbeat",
|
|
237
|
+
enabled: true,
|
|
238
|
+
syntax: "cron",
|
|
239
|
+
expression: "*/30 * * * *",
|
|
240
|
+
cronExpression: "*/30 * * * *",
|
|
241
|
+
timezone: null,
|
|
242
|
+
message: "run heartbeat",
|
|
243
|
+
script: null,
|
|
244
|
+
nextRunAt: 1_778_800_100_000,
|
|
245
|
+
lastRunAt: null,
|
|
246
|
+
lastStatus: "ok",
|
|
247
|
+
retryCount: 0,
|
|
248
|
+
maxRetries: 3,
|
|
249
|
+
retryBackoffMs: 60_000,
|
|
250
|
+
description: "Checks the heartbeat",
|
|
251
|
+
cadenceDescription: "Every 30 minutes",
|
|
252
|
+
mode: "execute",
|
|
253
|
+
status: "active",
|
|
254
|
+
routingIntent: "all_channels",
|
|
255
|
+
reuseConversation: false,
|
|
256
|
+
wakeConversationId: null,
|
|
257
|
+
sourceKey: null,
|
|
258
|
+
userEnabled: null,
|
|
259
|
+
isOneShot: false,
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const { exitCode } = await runCommand(["schedules", "list"]);
|
|
266
|
+
|
|
267
|
+
expect(exitCode).toBe(0);
|
|
268
|
+
expect(logLines.join("\n")).toContain("SOURCE");
|
|
269
|
+
const pluginLine = logLines.find((line) =>
|
|
270
|
+
line.includes("schedule-plugin"),
|
|
271
|
+
);
|
|
272
|
+
const imperativeLine = logLines.find((line) =>
|
|
273
|
+
line.includes("schedule-imperative"),
|
|
274
|
+
);
|
|
275
|
+
expect(pluginLine).toContain("gmail");
|
|
276
|
+
expect(imperativeLine).not.toContain("gmail");
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
test("--json passes sourceKey and userEnabled through untouched", async () => {
|
|
280
|
+
mockIpcResult = {
|
|
281
|
+
ok: true,
|
|
282
|
+
result: {
|
|
283
|
+
schedules: [
|
|
284
|
+
{
|
|
285
|
+
id: "schedule-plugin",
|
|
286
|
+
name: "Inbox poll",
|
|
287
|
+
enabled: false,
|
|
288
|
+
syntax: "cron",
|
|
289
|
+
expression: "*/15 * * * *",
|
|
290
|
+
cronExpression: "*/15 * * * *",
|
|
291
|
+
timezone: null,
|
|
292
|
+
message: "poll the inbox",
|
|
293
|
+
script: null,
|
|
294
|
+
nextRunAt: 1_778_800_000_000,
|
|
295
|
+
lastRunAt: null,
|
|
296
|
+
lastStatus: "ok",
|
|
297
|
+
retryCount: 0,
|
|
298
|
+
maxRetries: 3,
|
|
299
|
+
retryBackoffMs: 60_000,
|
|
300
|
+
description: "Polls the inbox",
|
|
301
|
+
cadenceDescription: "Every 15 minutes",
|
|
302
|
+
mode: "execute",
|
|
303
|
+
status: "active",
|
|
304
|
+
routingIntent: "all_channels",
|
|
305
|
+
reuseConversation: false,
|
|
306
|
+
wakeConversationId: null,
|
|
307
|
+
sourceKey: "plugin:gmail/poll-inbox",
|
|
308
|
+
userEnabled: false,
|
|
309
|
+
isOneShot: false,
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const { stdout, exitCode } = await runCommand([
|
|
316
|
+
"schedules",
|
|
317
|
+
"list",
|
|
318
|
+
"--json",
|
|
319
|
+
]);
|
|
320
|
+
|
|
321
|
+
expect(exitCode).toBe(0);
|
|
322
|
+
expect(JSON.parse(stdout)).toEqual({
|
|
323
|
+
schedules: [
|
|
324
|
+
expect.objectContaining({
|
|
325
|
+
id: "schedule-plugin",
|
|
326
|
+
sourceKey: "plugin:gmail/poll-inbox",
|
|
327
|
+
userEnabled: false,
|
|
328
|
+
}),
|
|
329
|
+
],
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
|
|
234
333
|
test("sets exit code on IPC failure", async () => {
|
|
235
334
|
mockIpcResult = { ok: false, error: "daemon unavailable" };
|
|
236
335
|
|
|
@@ -422,10 +422,13 @@ export function registerConversationsCommand(program: Command): void {
|
|
|
422
422
|
json?: boolean;
|
|
423
423
|
},
|
|
424
424
|
) => {
|
|
425
|
-
// A script-mode schedule injects __SCHEDULE_RUN_ID
|
|
426
|
-
// (see schedule/run-script.ts).
|
|
427
|
-
// woken turn's usage
|
|
425
|
+
// A script-mode schedule injects __SCHEDULE_RUN_ID and __SCHEDULE_ID
|
|
426
|
+
// into its env (see schedule/run-script.ts). The run id attributes the
|
|
427
|
+
// woken turn's usage to the firing; the schedule id lets the turn run
|
|
428
|
+
// on the schedule's pinned inference profile, the same profile
|
|
429
|
+
// execute-mode and wake-mode runs of that schedule use.
|
|
428
430
|
const cronRunId = process.env.__SCHEDULE_RUN_ID;
|
|
431
|
+
const scheduleId = process.env.__SCHEDULE_ID;
|
|
429
432
|
|
|
430
433
|
// Fencing only exists on the persisted-event path, so
|
|
431
434
|
// --external-content implies --persist.
|
|
@@ -442,6 +445,7 @@ export function registerConversationsCommand(program: Command): void {
|
|
|
442
445
|
hint: opts.hint,
|
|
443
446
|
source: opts.source,
|
|
444
447
|
...(cronRunId ? { cronRunId } : {}),
|
|
448
|
+
...(scheduleId ? { scheduleId } : {}),
|
|
445
449
|
...(persist ? { persist: true } : {}),
|
|
446
450
|
...(externalContent !== undefined ? { externalContent } : {}),
|
|
447
451
|
},
|
|
@@ -292,6 +292,13 @@ encrypted vault with the specified metadata.
|
|
|
292
292
|
|
|
293
293
|
Requires the assistant to be running with at least one connected client.
|
|
294
294
|
|
|
295
|
+
This command BLOCKS until the user answers the prompt, so it returns only once
|
|
296
|
+
the prompt has already closed. Tell the user what to paste BEFORE running it —
|
|
297
|
+
anything said afterwards reaches them after the input is gone, and pointing
|
|
298
|
+
them at a closed prompt makes them re-submit a value that was already received.
|
|
299
|
+
The --label and --description text renders inside the prompt itself, so put the
|
|
300
|
+
instructions there rather than in a follow-up message.
|
|
301
|
+
|
|
295
302
|
Examples:
|
|
296
303
|
$ assistant credentials prompt --service sentry --field auth_token \\
|
|
297
304
|
--label "Sentry Auth Token" --placeholder "sntrys_..." \\
|
|
@@ -35,6 +35,8 @@ interface ProfileWriteResult {
|
|
|
35
35
|
name: string;
|
|
36
36
|
entry: Record<string, unknown>;
|
|
37
37
|
warnings: string[];
|
|
38
|
+
/** Live-call command the daemon suggests for verifying the written profile. */
|
|
39
|
+
verify?: string;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
type WriteFlags = {
|
|
@@ -48,6 +50,7 @@ type WriteFlags = {
|
|
|
48
50
|
thinking?: string;
|
|
49
51
|
description?: string;
|
|
50
52
|
allowUnlisted?: boolean;
|
|
53
|
+
allowUnavailable?: boolean;
|
|
51
54
|
json?: boolean;
|
|
52
55
|
};
|
|
53
56
|
|
|
@@ -80,6 +83,9 @@ function buildWriteBody(
|
|
|
80
83
|
if (opts.allowUnlisted) {
|
|
81
84
|
body.allowUnlisted = true;
|
|
82
85
|
}
|
|
86
|
+
if (opts.allowUnavailable) {
|
|
87
|
+
body.allowUnavailable = true;
|
|
88
|
+
}
|
|
83
89
|
|
|
84
90
|
if (opts.maxTokens !== undefined) {
|
|
85
91
|
if (!/^\d+$/.test(opts.maxTokens.trim())) {
|
|
@@ -118,9 +124,9 @@ function printWriteResult(
|
|
|
118
124
|
writeLine(`warning: ${warning}`);
|
|
119
125
|
}
|
|
120
126
|
writeLine(`profile ${result.name} ${verb}`);
|
|
121
|
-
|
|
122
|
-
`Verify it works:
|
|
123
|
-
|
|
127
|
+
if (result.verify) {
|
|
128
|
+
writeLine(`Verify it works: ${result.verify}`);
|
|
129
|
+
}
|
|
124
130
|
}
|
|
125
131
|
|
|
126
132
|
export function attachProfilesSubcommand(inference: Command): void {
|
|
@@ -36,6 +36,11 @@ const profileWriteOptions: CliOptionHelp[] = [
|
|
|
36
36
|
flags: "--allow-unlisted",
|
|
37
37
|
description: "Allow a model not in the catalog (warns)",
|
|
38
38
|
},
|
|
39
|
+
{
|
|
40
|
+
flags: "--allow-unavailable",
|
|
41
|
+
description:
|
|
42
|
+
"Allow a profile that cannot dispatch yet (no connection/API key) — for pre-staging config (warns)",
|
|
43
|
+
},
|
|
39
44
|
{ flags: "--json", description: "Output as machine-readable JSON" },
|
|
40
45
|
];
|
|
41
46
|
|
|
@@ -223,6 +228,7 @@ a profile that uses it:
|
|
|
223
228
|
subcommands: [
|
|
224
229
|
{
|
|
225
230
|
name: "list",
|
|
231
|
+
isDefault: true,
|
|
226
232
|
description: "List configured providers",
|
|
227
233
|
options: [
|
|
228
234
|
{ flags: "--provider <p>", description: "Filter by provider" },
|
|
@@ -409,6 +415,7 @@ Examples:
|
|
|
409
415
|
subcommands: [
|
|
410
416
|
{
|
|
411
417
|
name: "list",
|
|
418
|
+
isDefault: true,
|
|
412
419
|
description: "List catalog models (optionally filtered by provider)",
|
|
413
420
|
options: [
|
|
414
421
|
{ flags: "--provider <p>", description: "Filter by provider id" },
|
|
@@ -436,16 +443,21 @@ Profiles are named model configurations. Managed defaults (balanced,
|
|
|
436
443
|
quality-optimized, cost-optimized) are read-only; create your own to
|
|
437
444
|
customize provider, model, and tuning.
|
|
438
445
|
|
|
446
|
+
Create, then verify with a live call, then activate. Activation is refused
|
|
447
|
+
for a profile that cannot dispatch (no provider connection or API key), so
|
|
448
|
+
verify before you switch the chat model over.
|
|
449
|
+
|
|
439
450
|
Examples:
|
|
440
451
|
$ assistant inference profiles list
|
|
441
452
|
$ assistant inference profiles create my-fast --provider anthropic \\
|
|
442
453
|
--model claude-haiku-4-5 --connection anthropic-personal --effort low
|
|
443
|
-
$ assistant inference
|
|
454
|
+
$ assistant inference send --profile my-fast "Reply with OK"
|
|
444
455
|
$ assistant inference profiles active my-fast
|
|
445
456
|
$ assistant inference profiles delete my-fast`,
|
|
446
457
|
subcommands: [
|
|
447
458
|
{
|
|
448
459
|
name: "list",
|
|
460
|
+
isDefault: true,
|
|
449
461
|
description: "List the effective profile catalog",
|
|
450
462
|
options: [
|
|
451
463
|
{
|
|
@@ -500,7 +512,9 @@ Examples:
|
|
|
500
512
|
],
|
|
501
513
|
helpText: `
|
|
502
514
|
With no argument, prints the active profile. With a name, sets it — the
|
|
503
|
-
same deep-merge write the model picker performs.
|
|
515
|
+
same deep-merge write the model picker performs. Setting is refused when
|
|
516
|
+
the named profile cannot dispatch; verify it first with
|
|
517
|
+
'assistant inference send --profile <name> "Reply with OK"'.
|
|
504
518
|
|
|
505
519
|
Examples:
|
|
506
520
|
$ assistant inference profiles active
|
|
@@ -128,8 +128,10 @@ Arguments:
|
|
|
128
128
|
name Name of a configured MCP server to authenticate with
|
|
129
129
|
|
|
130
130
|
Only works with sse or streamable-http transports (stdio servers do not use
|
|
131
|
-
OAuth).
|
|
132
|
-
|
|
131
|
+
OAuth). On desktop, opens a browser for OAuth authorization with the remote
|
|
132
|
+
server. On web, prints the OAuth URL to the terminal — copy and open it in a
|
|
133
|
+
new browser tab manually. The running assistant handles the OAuth callback
|
|
134
|
+
and token exchange in both cases.
|
|
133
135
|
|
|
134
136
|
The command waits up to 2.5 minutes for the user to complete the browser-based
|
|
135
137
|
OAuth flow. If the server already has valid cached tokens, the command succeeds
|
|
@@ -135,6 +135,11 @@ function renderOutcome(outcome: MemoryRetrospectiveOutcome): void {
|
|
|
135
135
|
case "no_new_messages":
|
|
136
136
|
log.info("No new messages to review since the last retrospective.");
|
|
137
137
|
break;
|
|
138
|
+
case "no_user_activity":
|
|
139
|
+
log.info(
|
|
140
|
+
"No user activity in the window since the last retrospective; skipping.",
|
|
141
|
+
);
|
|
142
|
+
break;
|
|
138
143
|
case "source_dormant":
|
|
139
144
|
log.info(
|
|
140
145
|
"Source conversation is dormant beyond the sweep lookback; skipping.",
|
|
@@ -152,6 +157,15 @@ function renderOutcome(outcome: MemoryRetrospectiveOutcome): void {
|
|
|
152
157
|
);
|
|
153
158
|
process.exitCode = 1;
|
|
154
159
|
break;
|
|
160
|
+
case "no_usable_output":
|
|
161
|
+
log.error(
|
|
162
|
+
`Run produced no usable output` +
|
|
163
|
+
`${outcome.reason ? `: ${outcome.reason}` : ""}` +
|
|
164
|
+
(outcome.conversationId ? ` (fork: ${outcome.conversationId})` : "") +
|
|
165
|
+
`. The window stays retryable.`,
|
|
166
|
+
);
|
|
167
|
+
process.exitCode = 1;
|
|
168
|
+
break;
|
|
155
169
|
case "invoked":
|
|
156
170
|
log.info(
|
|
157
171
|
`Retrospective invoked.\n` +
|
|
@@ -163,5 +177,9 @@ function renderOutcome(outcome: MemoryRetrospectiveOutcome): void {
|
|
|
163
177
|
: ""),
|
|
164
178
|
);
|
|
165
179
|
break;
|
|
180
|
+
default: {
|
|
181
|
+
const _exhaustive: never = outcome;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
166
184
|
}
|
|
167
185
|
}
|
|
@@ -258,9 +258,9 @@ export function registerNotificationsCommand(program: Command): void {
|
|
|
258
258
|
return;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
// Picks up __CONVERSATION_ID / __SKILL_CONTEXT_JSON env vars
|
|
262
|
-
//
|
|
263
|
-
//
|
|
261
|
+
// Picks up __CONVERSATION_ID / __SKILL_CONTEXT_JSON env vars so
|
|
262
|
+
// a send invoked from inside an agent turn resolves the
|
|
263
|
+
// conversation it originated from.
|
|
264
264
|
const originatingConversationId = tryResolveConversationId();
|
|
265
265
|
|
|
266
266
|
// The signal's `sourceContextId` doubles as the home-feed's
|
|
@@ -306,9 +306,6 @@ export function registerNotificationsCommand(program: Command): void {
|
|
|
306
306
|
...(conversationId
|
|
307
307
|
? { conversationAffinityHint: { vellum: conversationId } }
|
|
308
308
|
: {}),
|
|
309
|
-
...(originatingConversationId
|
|
310
|
-
? { originatingConversationId }
|
|
311
|
-
: {}),
|
|
312
309
|
throwOnError: true,
|
|
313
310
|
},
|
|
314
311
|
});
|
|
@@ -36,5 +36,21 @@ describe("OAuth connect surface guidance", () => {
|
|
|
36
36
|
expect(hint).toContain('surface_type "oauth_connect"');
|
|
37
37
|
expect(hint).toContain('data.providerKey "google"');
|
|
38
38
|
expect(hint).toContain("paste an OAuth URL");
|
|
39
|
+
expect(hint).not.toContain("requestedScopes");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("hint with scopes teaches the full replacement set semantics", () => {
|
|
43
|
+
const hint = oauthConnectSurfaceHint("google", ["a", "b"]);
|
|
44
|
+
expect(hint).toContain("data.requestedScopes");
|
|
45
|
+
expect(hint).toContain("full replacement set");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("redirect with scopes carries requestedScopes in the next action", () => {
|
|
49
|
+
const redirect = buildOAuthConnectSurfaceRedirect("google", ["a", "b"]);
|
|
50
|
+
expect(redirect.nextAction.data).toEqual({
|
|
51
|
+
providerKey: "google",
|
|
52
|
+
requestedScopes: ["a", "b"],
|
|
53
|
+
});
|
|
54
|
+
expect(redirect.hint).toBe(oauthConnectSurfaceHint("google", ["a", "b"]));
|
|
39
55
|
});
|
|
40
56
|
});
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { OAuthConnectSurfaceData } from "../../../api/surfaces.js";
|
|
2
|
+
|
|
1
3
|
export interface OAuthConnectSurfaceNextAction {
|
|
2
4
|
type: "ui_show";
|
|
3
5
|
surfaceType: "oauth_connect";
|
|
4
|
-
data:
|
|
6
|
+
data: Pick<OAuthConnectSurfaceData, "providerKey" | "requestedScopes">;
|
|
5
7
|
}
|
|
6
8
|
|
|
7
9
|
export interface OAuthConnectSurfaceRedirect {
|
|
@@ -12,35 +14,51 @@ export interface OAuthConnectSurfaceRedirect {
|
|
|
12
14
|
nextAction: OAuthConnectSurfaceNextAction;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
export function oauthConnectSurfaceHint(
|
|
16
|
-
|
|
17
|
+
export function oauthConnectSurfaceHint(
|
|
18
|
+
provider: string,
|
|
19
|
+
requestedScopes?: string[],
|
|
20
|
+
): string {
|
|
21
|
+
const base =
|
|
17
22
|
`To let the user connect, render the connect button: call ` +
|
|
18
23
|
`\`ui_show\` with surface_type "oauth_connect" and ` +
|
|
19
24
|
`data.providerKey "${provider}". That surface is always available — do ` +
|
|
20
25
|
`not run further \`oauth\`/\`channels\` commands, paste an OAuth URL, or ` +
|
|
21
|
-
`load a setup skill just to display it
|
|
26
|
+
`load a setup skill just to display it.`;
|
|
27
|
+
if (!requestedScopes?.length) {
|
|
28
|
+
return base;
|
|
29
|
+
}
|
|
30
|
+
return (
|
|
31
|
+
base +
|
|
32
|
+
` Include data.requestedScopes verbatim from nextAction.data in the ` +
|
|
33
|
+
`\`ui_show\` call: it is a full replacement set, so list every default ` +
|
|
34
|
+
`scope you want to keep, not just the new ones.`
|
|
22
35
|
);
|
|
23
36
|
}
|
|
24
37
|
|
|
25
38
|
export function buildOAuthConnectSurfaceNextAction(
|
|
26
39
|
provider: string,
|
|
40
|
+
requestedScopes?: string[],
|
|
27
41
|
): OAuthConnectSurfaceNextAction {
|
|
28
42
|
return {
|
|
29
43
|
type: "ui_show",
|
|
30
44
|
surfaceType: "oauth_connect",
|
|
31
|
-
data: {
|
|
45
|
+
data: {
|
|
46
|
+
providerKey: provider,
|
|
47
|
+
...(requestedScopes?.length ? { requestedScopes } : {}),
|
|
48
|
+
},
|
|
32
49
|
};
|
|
33
50
|
}
|
|
34
51
|
|
|
35
52
|
export function buildOAuthConnectSurfaceRedirect(
|
|
36
53
|
provider: string,
|
|
54
|
+
requestedScopes?: string[],
|
|
37
55
|
): OAuthConnectSurfaceRedirect {
|
|
38
56
|
return {
|
|
39
57
|
ok: false,
|
|
40
58
|
code: "use_oauth_connect_surface",
|
|
41
59
|
provider,
|
|
42
|
-
hint: oauthConnectSurfaceHint(provider),
|
|
43
|
-
nextAction: buildOAuthConnectSurfaceNextAction(provider),
|
|
60
|
+
hint: oauthConnectSurfaceHint(provider, requestedScopes),
|
|
61
|
+
nextAction: buildOAuthConnectSurfaceNextAction(provider, requestedScopes),
|
|
44
62
|
};
|
|
45
63
|
}
|
|
46
64
|
|
|
@@ -70,7 +70,7 @@ afterEach(() => {
|
|
|
70
70
|
process.exitCode = 0;
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
async function runConnectCommand(): Promise<{
|
|
73
|
+
async function runConnectCommand(extraArgs: string[] = []): Promise<{
|
|
74
74
|
stdout: string;
|
|
75
75
|
exitCode: number;
|
|
76
76
|
}> {
|
|
@@ -94,6 +94,7 @@ async function runConnectCommand(): Promise<{
|
|
|
94
94
|
"--json",
|
|
95
95
|
"connect",
|
|
96
96
|
"google",
|
|
97
|
+
...extraArgs,
|
|
97
98
|
]);
|
|
98
99
|
} catch {
|
|
99
100
|
// Commander may throw under exitOverride for parse errors; the assertions
|
|
@@ -123,4 +124,28 @@ describe("oauth connect", () => {
|
|
|
123
124
|
"oauth_mode_get",
|
|
124
125
|
]);
|
|
125
126
|
});
|
|
127
|
+
|
|
128
|
+
test("managed provider in a conversation shell includes requested scopes in the oauth_connect guidance", async () => {
|
|
129
|
+
const { stdout, exitCode } = await runConnectCommand([
|
|
130
|
+
"--scopes",
|
|
131
|
+
"https://www.googleapis.com/auth/tasks",
|
|
132
|
+
"https://www.googleapis.com/auth/calendar",
|
|
133
|
+
]);
|
|
134
|
+
|
|
135
|
+
expect(exitCode).toBe(1);
|
|
136
|
+
const parsed = JSON.parse(stdout) as Record<string, unknown>;
|
|
137
|
+
expect(parsed.code).toBe("use_oauth_connect_surface");
|
|
138
|
+
expect(parsed.nextAction).toEqual({
|
|
139
|
+
type: "ui_show",
|
|
140
|
+
surfaceType: "oauth_connect",
|
|
141
|
+
data: {
|
|
142
|
+
providerKey: "google",
|
|
143
|
+
requestedScopes: [
|
|
144
|
+
"https://www.googleapis.com/auth/tasks",
|
|
145
|
+
"https://www.googleapis.com/auth/calendar",
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
expect(openedUrls).toEqual([]);
|
|
150
|
+
});
|
|
126
151
|
});
|
|
@@ -141,7 +141,10 @@ export function registerConnectCommand(oauth: Command): void {
|
|
|
141
141
|
// =============================================================
|
|
142
142
|
|
|
143
143
|
if (isModelSpawnedConversationShell()) {
|
|
144
|
-
const redirect = buildOAuthConnectSurfaceRedirect(
|
|
144
|
+
const redirect = buildOAuthConnectSurfaceRedirect(
|
|
145
|
+
provider,
|
|
146
|
+
opts.scopes,
|
|
147
|
+
);
|
|
145
148
|
writeOutput(cmd, redirect);
|
|
146
149
|
process.exitCode = 1;
|
|
147
150
|
return;
|
|
@@ -691,7 +691,9 @@ Important for chat/UI turns: do not run this command just to let the user
|
|
|
691
691
|
connect a managed provider. Render the first-class connect surface instead:
|
|
692
692
|
call \`ui_show\` with surface_type "oauth_connect" and data.providerKey set to
|
|
693
693
|
the provider (for example, "google"). That surface starts the managed OAuth UI
|
|
694
|
-
and avoids pasting raw authorization links into the conversation.
|
|
694
|
+
and avoids pasting raw authorization links into the conversation. If the user
|
|
695
|
+
needs non-default scopes, also pass data.requestedScopes as a full replacement
|
|
696
|
+
set (list every scope the connection should keep, not just the new ones).
|
|
695
697
|
|
|
696
698
|
Examples:
|
|
697
699
|
$ assistant oauth connect google
|
|
@@ -13,6 +13,8 @@ const log = getCliLogger("cli");
|
|
|
13
13
|
|
|
14
14
|
interface SerializedProvider {
|
|
15
15
|
providerKey: string;
|
|
16
|
+
/** Which sense of connected: a grant to act as the user, or a bot. */
|
|
17
|
+
actsAs?: "user" | "assistant";
|
|
16
18
|
displayName?: string | null;
|
|
17
19
|
description?: string | null;
|
|
18
20
|
supportsManagedMode?: boolean;
|
|
@@ -301,6 +303,7 @@ export function registerProviderCommands(oauth: Command): void {
|
|
|
301
303
|
dashboardUrl: p.dashboard_url as string | null,
|
|
302
304
|
clientIdPlaceholder: p.client_id_placeholder as string | null,
|
|
303
305
|
featureFlag: p.feature_flag as string | null,
|
|
306
|
+
actsAs: p.acts_as as "user" | "assistant" | undefined,
|
|
304
307
|
}));
|
|
305
308
|
|
|
306
309
|
if (opts.providerKey) {
|
|
@@ -48,7 +48,11 @@ Examples:
|
|
|
48
48
|
description:
|
|
49
49
|
"Install a plugin by name from the Vellum platform (content is served as a verified tarball from the plugin's pinned commit), or directly from a GitHub URL (untrusted)",
|
|
50
50
|
options: [
|
|
51
|
-
{
|
|
51
|
+
{
|
|
52
|
+
flags: "--force",
|
|
53
|
+
description:
|
|
54
|
+
"Overwrite an existing install and skip the declared-schedules confirmation prompt",
|
|
55
|
+
},
|
|
52
56
|
{
|
|
53
57
|
flags: "--ref <ref>",
|
|
54
58
|
description: `For a marketplace install, the manifest revision to read the pin from (default: ${DEFAULT_PLUGIN_REF}). For a GitHub URL, the git ref (branch/tag/SHA) to clone — states a slash-containing branch (e.g. feature/x) explicitly and skips the remote ref lookup a bare /tree/ URL otherwise does`,
|
|
@@ -70,6 +74,11 @@ Examples:
|
|
|
70
74
|
},
|
|
71
75
|
],
|
|
72
76
|
helpText: `
|
|
77
|
+
A plugin that declares schedules (a schedules/ directory) has them listed
|
|
78
|
+
during the install, and the install asks for confirmation before finalizing:
|
|
79
|
+
schedules run automatically in the background once the plugin is installed.
|
|
80
|
+
Pass --force to skip the prompt (required for non-interactive installs).
|
|
81
|
+
|
|
73
82
|
A GitHub URL (anything containing a slash) installs directly from that repo,
|
|
74
83
|
bypassing the marketplace whitelist. Such a plugin is UNTRUSTED — it has not
|
|
75
84
|
been reviewed and its hooks/tools run with full assistant access — so the
|
|
@@ -121,7 +130,7 @@ Examples:
|
|
|
121
130
|
name: "inspect",
|
|
122
131
|
args: "<name>",
|
|
123
132
|
description:
|
|
124
|
-
"Show a plugin's local install metadata, the marketplace pin, whether an update is available, and the surfaces (skills, hooks, tools) it contributes",
|
|
133
|
+
"Show a plugin's local install metadata, the marketplace pin, whether an update is available, and the surfaces (skills, hooks, tools, schedules) it contributes",
|
|
125
134
|
options: [
|
|
126
135
|
{
|
|
127
136
|
flags: "--json",
|
|
@@ -245,6 +254,11 @@ $ assistant plugins publish --json`,
|
|
|
245
254
|
flags: "--json",
|
|
246
255
|
description: "Emit machine-readable JSON instead of a summary",
|
|
247
256
|
},
|
|
257
|
+
{
|
|
258
|
+
flags: "--force",
|
|
259
|
+
description:
|
|
260
|
+
"Skip the declared-schedules confirmation prompt of a local upgrade (the assistant-applied path never prompts)",
|
|
261
|
+
},
|
|
248
262
|
],
|
|
249
263
|
helpText: `
|
|
250
264
|
A marketplace plugin upgrades to the curated pin. A plugin installed directly
|
|
@@ -253,6 +267,15 @@ whatever its recorded ref resolves to now — a pinned commit SHA is immutable (
|
|
|
253
267
|
no-op), while a branch/tag/HEAD advances as upstream does — and re-materializes
|
|
254
268
|
it verbatim, with no curated adapter overlay.
|
|
255
269
|
|
|
270
|
+
With the assistant running, the upgrade is applied by it immediately, with no
|
|
271
|
+
confirmation prompt: a schedule the new revision declares is armed by the
|
|
272
|
+
assistant and surfaced as a notification, and the upgrade output lists the
|
|
273
|
+
revision's declared schedules with any new ones marked. Only when the
|
|
274
|
+
assistant is unreachable does the upgrade run locally instead; that path
|
|
275
|
+
stages the new revision first, and a revision that declares schedules lists
|
|
276
|
+
them and asks for confirmation before going live (--force skips that prompt,
|
|
277
|
+
as for install).
|
|
278
|
+
|
|
256
279
|
Examples:
|
|
257
280
|
$ assistant plugins upgrade example
|
|
258
281
|
$ assistant plugins upgrade example --dry-run
|