@vellumai/assistant 0.11.4 → 0.11.5-staging.1
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/AGENTS.md +2 -2
- package/ARCHITECTURE.md +29 -4
- package/README.md +1 -1
- package/docs/architecture/memory.md +17 -5
- package/docs/architecture/security.md +96 -152
- package/docs/guardian-request-flow.md +13 -2
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +166 -1
- package/node_modules/@vellumai/gateway-client/src/http-delivery.ts +7 -14
- package/node_modules/@vellumai/gateway-client/src/index.ts +2 -0
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +29 -31
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/openapi.yaml +193 -3
- package/package.json +1 -1
- package/src/__tests__/anthropic-provider.test.ts +10 -3
- package/src/__tests__/approval-interception-trust-gates.test.ts +40 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +4 -0
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -6
- package/src/__tests__/channel-reply-delivery.test.ts +26 -13
- package/src/__tests__/checker.test.ts +20 -314
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +6 -2
- package/src/__tests__/client-os-metadata-persistence.test.ts +16 -0
- package/src/__tests__/compactor-retained-image-validation.test.ts +142 -0
- package/src/__tests__/container-cpu-sampler.test.ts +153 -0
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
- package/src/__tests__/conversation-attachments.test.ts +0 -1
- package/src/__tests__/conversation-error.test.ts +17 -0
- package/src/__tests__/conversation-lifecycle.test.ts +20 -26
- package/src/__tests__/conversation-pairing.test.ts +186 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +21 -2
- package/src/__tests__/credential-broker-server-use.test.ts +24 -5
- package/src/__tests__/credential-routes.test.ts +22 -3
- package/src/__tests__/credential-security-invariants.test.ts +2 -1
- package/src/__tests__/daemon-credential-client.test.ts +88 -0
- package/src/__tests__/default-plugin-names-guard.test.ts +12 -1
- package/src/__tests__/dm-backfill.test.ts +63 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +0 -2
- package/src/__tests__/edit-propagation.test.ts +107 -4
- package/src/__tests__/events-client-registration.test.ts +28 -0
- package/src/__tests__/file-write-tool.test.ts +4 -2
- package/src/__tests__/guardian-prompt-notice-privacy.test.ts +133 -0
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +143 -97
- package/src/__tests__/helpers/gateway-classify-mock.ts +27 -6
- package/src/__tests__/host-proxy-interface.test.ts +11 -1
- package/src/__tests__/host-shell-tool.test.ts +23 -4
- package/src/__tests__/image-conversion.test.ts +143 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +47 -36
- package/src/__tests__/input-repairs.test.ts +207 -0
- package/src/__tests__/live-workspace-guard.test.ts +75 -0
- package/src/__tests__/mcp-abort-signal.test.ts +1 -1
- package/src/__tests__/mcp-client-auth.test.ts +1 -1
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +1 -1
- package/src/__tests__/media-resolve-image-validation.test.ts +310 -0
- package/src/__tests__/mtime-cache.test.ts +2 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +124 -1
- package/src/__tests__/openai-provider.test.ts +22 -0
- package/src/__tests__/personal-memory-auth-bypass.test.ts +22 -6
- package/src/__tests__/platform-bash-auto-approve.test.ts +0 -4
- package/src/__tests__/platform.test.ts +16 -1
- package/src/__tests__/plugin-api-resolve-credential.test.ts +22 -13
- package/src/__tests__/plugin-api-shim.test.ts +5 -0
- package/src/__tests__/plugin-api-store-credential.test.ts +268 -0
- package/src/__tests__/plugin-config-data-migration.test.ts +8 -1
- package/src/__tests__/plugin-disabled-state.test.ts +2 -0
- package/src/__tests__/plugin-effective-enabled-set.test.ts +55 -3
- package/src/__tests__/plugin-execution-context.test.ts +73 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +0 -1
- package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +0 -1
- package/src/__tests__/reaction-persistence.test.ts +200 -7
- package/src/__tests__/require-fresh-approval.test.ts +0 -4
- package/src/__tests__/resource-pressure-guard.test.ts +428 -0
- package/src/__tests__/resource-pressure-routes.test.ts +113 -0
- package/src/__tests__/risk-classification-boundary-guard.test.ts +115 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +27 -1
- package/src/__tests__/secret-routes-platform-proxy.test.ts +7 -0
- package/src/__tests__/skill-tool-factory.test.ts +161 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +132 -5
- package/src/__tests__/tool-executor.test.ts +63 -38
- package/src/__tests__/tool-policy.test.ts +97 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +7 -4
- package/src/__tests__/user-plugin-loader.test.ts +2 -0
- package/src/__tests__/validate-input.test.ts +243 -7
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/acp/__tests__/acp-claude-oauth.test.ts +97 -29
- package/src/acp/__tests__/prepare-agent-env.test.ts +376 -153
- package/src/acp/acp-claude-oauth.ts +38 -21
- package/src/acp/prepare-agent-env.ts +146 -55
- package/src/agent/loop-tool-dedup.test.ts +161 -0
- package/src/agent/loop.ts +68 -22
- package/src/api/constants/app-tools.ts +34 -0
- package/src/api/events/resource-pressure-status-changed.ts +53 -0
- package/src/api/index.ts +19 -0
- package/src/api/responses/resource-pressure-status.ts +25 -0
- package/src/approvals/guardian-channel-delivery.ts +70 -6
- package/src/approvals/guardian-request-resolvers.ts +32 -66
- package/src/channels/__tests__/message-audience.test.ts +49 -0
- package/src/channels/__tests__/types.test.ts +17 -3
- package/src/channels/message-audience.ts +40 -0
- package/src/channels/types.ts +16 -12
- package/src/cli/__tests__/catalog-search-help.test.ts +50 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +31 -0
- package/src/cli/commands/__tests__/conversations-search.test.ts +289 -0
- package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -0
- package/src/cli/commands/__tests__/inference-providers.test.ts +68 -0
- package/src/cli/commands/__tests__/keys.test.ts +89 -8
- package/src/cli/commands/__tests__/plugins.test.ts +57 -1
- package/src/cli/commands/channel-verification-sessions.help.ts +11 -9
- package/src/cli/commands/channel-verification-sessions.ts +11 -21
- package/src/cli/commands/conversations.help.ts +34 -0
- package/src/cli/commands/conversations.ts +125 -0
- package/src/cli/commands/inference-providers.ts +9 -4
- package/src/cli/commands/inference.help.ts +9 -4
- package/src/cli/commands/keys.help.ts +13 -1
- package/src/cli/commands/keys.ts +26 -15
- package/src/cli/commands/memory/__tests__/memory-v2.test.ts +57 -7
- package/src/cli/commands/memory/index.help.ts +41 -27
- package/src/cli/commands/memory/index.ts +2 -0
- package/src/cli/commands/memory/memory-v2.ts +58 -54
- package/src/cli/commands/memory/memory-validate.ts +18 -0
- package/src/cli/commands/monitoring.ts +1 -0
- package/src/cli/commands/plugins.help.ts +28 -31
- package/src/cli/commands/plugins.ts +10 -0
- package/src/cli/commands/skills.help.ts +13 -16
- package/src/cli/commands/trust.ts +3 -14
- package/src/cli/lib/__tests__/install-from-github.test.ts +38 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +34 -0
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +32 -1
- package/src/cli/lib/__tests__/toggle-plugin.test.ts +2 -1
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +64 -0
- package/src/cli/lib/bundled-marketplace.json +13 -0
- package/src/cli/lib/daemon-credential-client.ts +25 -3
- package/src/cli/lib/install-from-github.ts +35 -24
- package/src/cli/lib/merge-plugin-tree.ts +22 -4
- package/src/cli/lib/plugin-surfaces.ts +27 -0
- package/src/config/feature-flag-registry.json +35 -19
- package/src/config/webhook-routing.ts +8 -0
- package/src/context/compactor.ts +31 -2
- package/src/daemon/__tests__/provider-rejection-log-fields.test.ts +272 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +4 -1
- package/src/daemon/conversation-error.ts +13 -0
- package/src/daemon/conversation-messaging.ts +22 -2
- package/src/daemon/conversation-process.ts +11 -0
- package/src/daemon/conversation-store.ts +10 -0
- package/src/daemon/conversation-surfaces.ts +21 -8
- package/src/daemon/conversation.ts +12 -10
- package/src/daemon/lifecycle.ts +6 -2
- package/src/daemon/message-types/conversations.ts +5 -7
- package/src/daemon/provider-rejection-log-fields.ts +124 -0
- package/src/daemon/resource-pressure-guard-lifecycle.ts +66 -0
- package/src/daemon/resource-pressure-guard.ts +387 -0
- package/src/daemon/shutdown-handlers.ts +2 -0
- package/src/daemon/startup-error.ts +16 -0
- package/src/daemon/trust-context.ts +14 -10
- package/src/daemon/unsendable-image-notice.ts +76 -0
- package/src/hooks/registry.ts +65 -51
- package/src/ipc/__tests__/socket-path.test.ts +15 -7
- package/src/ipc/gateway-client.test.ts +1 -1
- package/src/ipc/gateway-client.ts +14 -21
- package/src/ipc/socket-cleanup.ts +2 -11
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +1 -1
- package/src/messaging/provider-message-metadata.ts +128 -0
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +116 -68
- package/src/messaging/providers/channel-transport.ts +90 -13
- package/src/messaging/providers/discord/send.ts +16 -0
- package/src/messaging/providers/discord/transport.ts +11 -1
- package/src/messaging/providers/index.ts +109 -16
- package/src/messaging/providers/slack/message-metadata.ts +45 -0
- package/src/messaging/providers/slack/render-transcript.ts +1 -4
- package/src/messaging/providers/slack/send.test.ts +6 -9
- package/src/messaging/providers/slack/send.ts +40 -28
- package/src/messaging/providers/slack/transport.ts +22 -26
- package/src/messaging/providers/telegram-bot/send.test.ts +2 -8
- package/src/messaging/providers/telegram-bot/transport.ts +3 -6
- package/src/messaging/read-provider-metadata.test.ts +157 -0
- package/src/messaging/read-provider-metadata.ts +51 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +94 -0
- package/src/notifications/__tests__/edit-notification.test.ts +174 -2
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +536 -4
- package/src/notifications/adapters/macos.ts +55 -0
- package/src/notifications/adapters/slack.ts +10 -5
- package/src/notifications/assistant-reply-producer.ts +37 -4
- package/src/notifications/conversation-pairing.ts +111 -21
- package/src/notifications/edit-notification.ts +38 -8
- package/src/notifications/emit-signal.ts +12 -14
- package/src/notifications/home-feed-side-effect.ts +218 -15
- package/src/notifications/types.ts +5 -0
- package/src/permissions/AGENTS.md +16 -0
- package/src/permissions/checker.test.ts +75 -122
- package/src/permissions/checker.ts +44 -560
- package/src/permissions/confirmation-guardian-request.test.ts +28 -3
- package/src/permissions/confirmation-guardian-request.ts +5 -1
- package/src/persistence/conversation-crud.ts +23 -20
- package/src/persistence/conversation-queries.ts +14 -1
- package/src/persistence/conversation-types.ts +22 -0
- package/src/persistence/delivery-crud.ts +122 -15
- package/src/plugin-api/__tests__/import-graph-partial-mock.test.ts +67 -0
- package/src/plugin-api/conversation-turn.ts +27 -0
- package/src/plugin-api/credential-scope.test.ts +15 -0
- package/src/plugin-api/credential-scope.ts +14 -0
- package/src/plugin-api/index.ts +19 -1
- package/src/plugin-api/resolve-credential.ts +15 -10
- package/src/plugin-api/store-credential.ts +148 -0
- package/src/plugin-api/system-card.ts +36 -0
- package/src/plugin-api/vision-support.test.ts +82 -0
- package/src/plugin-api/vision-support.ts +14 -2
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +361 -110
- package/src/plugins/defaults/image-fallback/__tests__/vision-recovery.test.ts +4 -0
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +58 -0
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +64 -23
- package/src/plugins/defaults/image-recovery/detect.ts +24 -1
- package/src/plugins/defaults/main.ts +15 -0
- package/src/plugins/defaults/memory/AGENTS.md +11 -3
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +0 -1
- package/src/plugins/defaults/memory/graph-topology/pending-buffer.ts +9 -12
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +1 -1
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +12 -10
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +114 -0
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +8 -0
- package/src/plugins/defaults/memory/substrate/__tests__/edge-index.test.ts +0 -30
- package/src/plugins/defaults/memory/substrate/__tests__/ingest.test.ts +73 -1
- package/src/plugins/defaults/memory/substrate/__tests__/page-index.test.ts +37 -0
- package/src/plugins/defaults/memory/substrate/__tests__/page-links.test.ts +208 -0
- package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +158 -1
- package/src/plugins/defaults/memory/substrate/__tests__/static-context.test.ts +1 -61
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +68 -6
- package/src/plugins/defaults/memory/substrate/edge-index.ts +0 -31
- package/src/plugins/defaults/memory/substrate/ingest.ts +59 -0
- package/src/plugins/defaults/memory/substrate/page-index.ts +35 -8
- package/src/plugins/defaults/memory/substrate/page-links.ts +133 -0
- package/src/plugins/defaults/memory/substrate/page-store.ts +10 -0
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +124 -34
- package/src/plugins/defaults/memory/substrate/static-context.ts +0 -29
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +3 -1
- package/src/plugins/defaults/memory/v3/card.ts +9 -9
- package/src/plugins/defaults/memory/v3/core-set.test.ts +7 -0
- package/src/plugins/defaults/memory/v3/core-set.ts +5 -1
- package/src/plugins/defaults/memory/v3/edge.ts +13 -57
- package/src/plugins/mtime-cache.ts +1 -1
- package/src/plugins/pipeline.ts +14 -7
- package/src/plugins/plugin-execution-context.ts +35 -11
- package/src/plugins/plugin-tree-walk.ts +63 -4
- package/src/providers/anthropic/__tests__/pause-turn-continuation.test.ts +170 -0
- package/src/providers/anthropic/client.ts +332 -241
- package/src/providers/connection-resolution.ts +2 -1
- package/src/providers/content-blocks.ts +22 -0
- package/src/providers/gemini/client.ts +5 -2
- package/src/providers/inference/__tests__/adapter-factory-litellm.test.ts +47 -1
- package/src/providers/inference/__tests__/adapter-factory-ollama.test.ts +83 -0
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +98 -1
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +38 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +10 -0
- package/src/providers/inference/__tests__/connections-ollama.test.ts +90 -0
- package/src/providers/inference/__tests__/missing-credential-guard.test.ts +117 -0
- package/src/providers/inference/adapter-factory.ts +33 -2
- package/src/providers/inference/auth.ts +13 -2
- package/src/providers/inference/credential-usage.ts +37 -0
- package/src/providers/inference/missing-credential-guard.ts +110 -0
- package/src/providers/inference/resolve-auth.ts +7 -7
- package/src/providers/media-resolve.ts +176 -15
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +576 -46
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +125 -2
- package/src/providers/openai/chat-completions-provider.ts +322 -42
- package/src/routes/route-host-protocol.ts +7 -0
- package/src/routes/worker.ts +31 -10
- package/src/runtime/AGENTS.md +35 -0
- package/src/runtime/__tests__/runtime-http-port-collision.test.ts +131 -0
- package/src/runtime/__tests__/web-presence.test.ts +234 -0
- package/src/runtime/assistant-event-hub.ts +38 -0
- package/src/runtime/channel-reply-delivery.ts +54 -31
- package/src/runtime/channel-retry-sweep.ts +6 -4
- package/src/runtime/effective-capabilities.test.ts +19 -0
- package/src/runtime/effective-capabilities.ts +25 -0
- package/src/runtime/guardian-reply-router.ts +6 -2
- package/src/runtime/http-errors.ts +1 -0
- package/src/runtime/http-server.ts +20 -5
- package/src/runtime/routes/__tests__/client-routes.test.ts +150 -0
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +133 -0
- package/src/runtime/routes/__tests__/credential-delete-in-use.test.ts +155 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +52 -1
- package/src/runtime/routes/__tests__/monitoring-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/pending-interactions-route.test.ts +175 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +88 -35
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +55 -6
- package/src/runtime/routes/__tests__/system-card-turn-termination.test.ts +107 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher-host.test.ts +52 -1
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +75 -4
- package/src/runtime/routes/approval-routes.ts +37 -4
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +16 -22
- package/src/runtime/routes/canned-message-complete.ts +68 -29
- package/src/runtime/routes/client-routes.ts +113 -0
- package/src/runtime/routes/conversation-list-routes.ts +22 -7
- package/src/runtime/routes/conversation-management-routes.ts +15 -9
- package/src/runtime/routes/conversation-routes.ts +36 -22
- package/src/runtime/routes/credential-in-use.ts +85 -0
- package/src/runtime/routes/credential-routes.ts +55 -85
- package/src/runtime/routes/guardian-approval-interception.ts +22 -22
- package/src/runtime/routes/guardian-approval-reply-helpers.ts +14 -12
- package/src/runtime/routes/identity-routes.ts +5 -121
- package/src/runtime/routes/inbound-message-handler.ts +71 -27
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +16 -17
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +77 -50
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -97
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +101 -77
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +17 -8
- package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +91 -7
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +72 -70
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +9 -7
- package/src/runtime/routes/monitoring-routes.ts +9 -1
- package/src/runtime/routes/plugins-routes.ts +17 -5
- package/src/runtime/routes/resource-pressure-routes.ts +22 -0
- package/src/runtime/routes/secret-routes.ts +39 -8
- package/src/runtime/routes/settings-routes.ts +6 -6
- package/src/runtime/routes/surface-action-routes.ts +20 -19
- package/src/runtime/routes/user-route-dispatcher.ts +31 -2
- package/src/runtime/routes/user-route-resolution.ts +18 -1
- package/src/runtime/slack-reply-session.test.ts +23 -13
- package/src/runtime/slack-reply-session.ts +38 -55
- package/src/runtime/web-presence.ts +90 -0
- package/src/skills/validate-input.ts +177 -40
- package/src/subagent/__tests__/consult-context-gating.test.ts +6 -10
- package/src/subagent/consult-context.ts +7 -23
- package/src/tools/credentials/broker.ts +24 -79
- package/src/tools/credentials/ref-parse.ts +35 -0
- package/src/tools/credentials/resolve.ts +4 -10
- package/src/tools/credentials/store.ts +168 -0
- package/src/tools/credentials/tool-policy.ts +67 -0
- package/src/tools/executor.ts +53 -15
- package/src/tools/network/__tests__/web-search.test.ts +41 -1
- package/src/tools/network/url-safety.ts +9 -16
- package/src/tools/network/web-search.ts +21 -3
- package/src/tools/permission-checker.ts +43 -52
- package/src/tools/schema-transforms.ts +40 -5
- package/src/tools/shared/input-repairs.ts +160 -0
- package/src/tools/skills/skill-tool-factory.ts +18 -4
- package/src/tools/subagent/spawn.ts +0 -1
- package/src/tools/tool-approval-handler.ts +16 -10
- package/src/tools/tool-types.ts +26 -13
- package/src/tools/types.ts +6 -6
- package/src/util/__tests__/cgroup-memory.test.ts +3 -0
- package/src/util/cgroup-memory.ts +3 -0
- package/src/util/container-cpu-sampler.ts +250 -0
- package/src/util/image-conversion.ts +178 -14
- package/src/util/platform.ts +93 -10
- package/src/permissions/ipc-risk-types.ts +0 -143
- package/src/permissions/risk-types.ts +0 -76
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
* - under --json the consent listing, the prompt, and the cancellation line
|
|
17
17
|
* all go to stderr, leaving stdout a pure JSON document
|
|
18
18
|
* - inspect renders the schedules surface block
|
|
19
|
+
* - install prints a setup-skill hint when `skills/setup` or
|
|
20
|
+
* `skills/<name>-setup` is present on the installed tree
|
|
19
21
|
*
|
|
20
22
|
* The installers are replaced by fakes that stage a fixture tree and run the
|
|
21
23
|
* real `confirmStagedOrAbort` gate, so the command's consent callback is
|
|
@@ -76,6 +78,10 @@ let ipcResults: Array<{
|
|
|
76
78
|
|
|
77
79
|
let inspectResult: PluginInspection | null = null;
|
|
78
80
|
|
|
81
|
+
/** On-disk tree returned as the fake install `target` so post-install walks work. */
|
|
82
|
+
let installTarget: string | null = null;
|
|
83
|
+
const installTargetDirs: string[] = [];
|
|
84
|
+
|
|
79
85
|
// ---------------------------------------------------------------------------
|
|
80
86
|
// Mocks
|
|
81
87
|
// ---------------------------------------------------------------------------
|
|
@@ -123,7 +129,7 @@ async function runFakeInstall(
|
|
|
123
129
|
await stageAndConfirm(name, deps?.confirmStaged);
|
|
124
130
|
return {
|
|
125
131
|
name,
|
|
126
|
-
target: `/plugins/${name}`,
|
|
132
|
+
target: installTarget ?? `/plugins/${name}`,
|
|
127
133
|
fileCount: 3,
|
|
128
134
|
ref: "main",
|
|
129
135
|
commit: "a".repeat(40),
|
|
@@ -253,6 +259,7 @@ beforeEach(() => {
|
|
|
253
259
|
upgradePluginCalls = [];
|
|
254
260
|
ipcResults = [];
|
|
255
261
|
inspectResult = null;
|
|
262
|
+
installTarget = null;
|
|
256
263
|
// Platform features on by default, so a plain name install takes the
|
|
257
264
|
// platform-tarball branch.
|
|
258
265
|
delete process.env.VELLUM_DISABLE_PLATFORM;
|
|
@@ -260,6 +267,10 @@ beforeEach(() => {
|
|
|
260
267
|
});
|
|
261
268
|
|
|
262
269
|
afterEach(() => {
|
|
270
|
+
for (const dir of installTargetDirs) {
|
|
271
|
+
rmSync(dir, { recursive: true, force: true });
|
|
272
|
+
}
|
|
273
|
+
installTargetDirs.length = 0;
|
|
263
274
|
if (savedDisablePlatform === undefined) {
|
|
264
275
|
delete process.env.VELLUM_DISABLE_PLATFORM;
|
|
265
276
|
} else {
|
|
@@ -346,6 +357,7 @@ describe("plugins install - declared-schedules consent", () => {
|
|
|
346
357
|
expect(confirmCalls.length).toBe(0);
|
|
347
358
|
expect(r.stdout).not.toContain("declares");
|
|
348
359
|
expect(r.stdout).not.toContain("schedule");
|
|
360
|
+
expect(r.stdout).not.toContain("to help set up this plugin");
|
|
349
361
|
expect(r.stdout).toContain('Installed plugin "example"');
|
|
350
362
|
expect(r.exitCode).toBe(0);
|
|
351
363
|
});
|
|
@@ -690,3 +702,47 @@ describe("plugins inspect - schedules surface", () => {
|
|
|
690
702
|
expect(r.exitCode).toBe(0);
|
|
691
703
|
});
|
|
692
704
|
});
|
|
705
|
+
|
|
706
|
+
describe("plugins install - setup skill hint", () => {
|
|
707
|
+
function writeSetupSkill(skillId: string): void {
|
|
708
|
+
const dir = mkdtempSync(join(tmpdir(), "plugins-cmd-target-"));
|
|
709
|
+
installTargetDirs.push(dir);
|
|
710
|
+
mkdirSync(join(dir, "skills", skillId), { recursive: true });
|
|
711
|
+
writeFileSync(
|
|
712
|
+
join(dir, "skills", skillId, "SKILL.md"),
|
|
713
|
+
"---\nname: setup\ndescription: Set up the plugin.\n---\n",
|
|
714
|
+
);
|
|
715
|
+
installTarget = dir;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
test("points at skills/setup after a successful install", async () => {
|
|
719
|
+
writeSetupSkill("setup");
|
|
720
|
+
|
|
721
|
+
const r = await runCommand(["plugins", "install", "example"]);
|
|
722
|
+
|
|
723
|
+
expect(r.stdout).toContain('Installed plugin "example"');
|
|
724
|
+
expect(r.stdout).toContain(
|
|
725
|
+
"Load the setup skill to help set up this plugin",
|
|
726
|
+
);
|
|
727
|
+
expect(r.exitCode).toBe(0);
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
test("points at skills/<name>-setup when that is the shipped id", async () => {
|
|
731
|
+
writeSetupSkill("imessage-setup");
|
|
732
|
+
|
|
733
|
+
const r = await runCommand(["plugins", "install", "imessage"]);
|
|
734
|
+
|
|
735
|
+
expect(r.stdout).toContain(
|
|
736
|
+
"Load the imessage-setup skill to help set up this plugin",
|
|
737
|
+
);
|
|
738
|
+
expect(r.exitCode).toBe(0);
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
test("prints no setup hint when the plugin ships no setup skill", async () => {
|
|
742
|
+
const r = await runCommand(["plugins", "install", "example"]);
|
|
743
|
+
|
|
744
|
+
expect(r.stdout).toContain('Installed plugin "example"');
|
|
745
|
+
expect(r.stdout).not.toContain("to help set up this plugin");
|
|
746
|
+
expect(r.exitCode).toBe(0);
|
|
747
|
+
});
|
|
748
|
+
});
|
|
@@ -10,15 +10,16 @@ export const channelVerificationSessionsHelp: CliCommandHelp = {
|
|
|
10
10
|
],
|
|
11
11
|
helpText: `
|
|
12
12
|
Verification sessions are used to verify guardian bindings and trusted
|
|
13
|
-
contacts across channels (telegram, phone, slack, email). Three
|
|
13
|
+
contacts across channels (telegram, phone, slack, discord, email). Three
|
|
14
|
+
flows exist:
|
|
14
15
|
|
|
15
16
|
1. Inbound challenge — the assistant generates a secret code and waits
|
|
16
17
|
for the guardian to send it back on the channel. Used when the
|
|
17
18
|
guardian can already message the assistant.
|
|
18
19
|
|
|
19
20
|
2. Outbound verification — the assistant sends a verification code to
|
|
20
|
-
a destination (Telegram handle, phone number, Slack
|
|
21
|
-
waits for confirmation. Used when bootstrapping a new channel.
|
|
21
|
+
a destination (Telegram handle, phone number, Slack or Discord user
|
|
22
|
+
ID) and waits for confirmation. Used when bootstrapping a new channel.
|
|
22
23
|
|
|
23
24
|
3. Trusted contact verification — verifies a contact channel that
|
|
24
25
|
already exists in the contact graph, sending a code to the channel
|
|
@@ -36,7 +37,7 @@ Examples:
|
|
|
36
37
|
options: [
|
|
37
38
|
{
|
|
38
39
|
flags: "--channel <channel>",
|
|
39
|
-
description: "Channel type (telegram, phone, slack, email)",
|
|
40
|
+
description: "Channel type (telegram, phone, slack, discord, email)",
|
|
40
41
|
},
|
|
41
42
|
{
|
|
42
43
|
flags: "--destination <destination>",
|
|
@@ -72,8 +73,8 @@ Routes between three creation modes based on the provided options:
|
|
|
72
73
|
|
|
73
74
|
2. Outbound: --channel <ch> --destination <dest>
|
|
74
75
|
Sends a verification code to the given destination. Supports telegram
|
|
75
|
-
(handle or chat ID), phone (E.164 number), slack (user ID),
|
|
76
|
-
Use --rebind to replace an existing guardian binding.
|
|
76
|
+
(handle or chat ID), phone (E.164 number), slack and discord (user ID),
|
|
77
|
+
and email. Use --rebind to replace an existing guardian binding.
|
|
77
78
|
|
|
78
79
|
3. Inbound: --channel <ch> (no --destination)
|
|
79
80
|
Generates a challenge secret for the guardian to send back on the
|
|
@@ -91,7 +92,8 @@ Examples:
|
|
|
91
92
|
options: [
|
|
92
93
|
{
|
|
93
94
|
flags: "--channel <channel>",
|
|
94
|
-
description:
|
|
95
|
+
description:
|
|
96
|
+
"Channel type (telegram, phone, slack, discord, email). Defaults to telegram.",
|
|
95
97
|
},
|
|
96
98
|
],
|
|
97
99
|
helpText: `
|
|
@@ -113,7 +115,7 @@ Examples:
|
|
|
113
115
|
options: [
|
|
114
116
|
{
|
|
115
117
|
flags: "--channel <channel>",
|
|
116
|
-
description: "Channel type (telegram, phone, slack, email)",
|
|
118
|
+
description: "Channel type (telegram, phone, slack, discord, email)",
|
|
117
119
|
required: true,
|
|
118
120
|
},
|
|
119
121
|
{
|
|
@@ -137,7 +139,7 @@ Examples:
|
|
|
137
139
|
options: [
|
|
138
140
|
{
|
|
139
141
|
flags: "--channel <channel>",
|
|
140
|
-
description: "Channel type (telegram, phone, slack, email)",
|
|
142
|
+
description: "Channel type (telegram, phone, slack, discord, email)",
|
|
141
143
|
required: true,
|
|
142
144
|
},
|
|
143
145
|
],
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
// `cli/no-daemon-internals` forbids hoisting `channels/types.js`, so the CLI
|
|
2
|
+
// reads the vocabulary straight from the contract package that file re-exports.
|
|
3
|
+
// Both sides then validate `--channel` against the same set.
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
CHANNEL_IDS,
|
|
7
|
+
type ChannelId,
|
|
8
|
+
isChannelId,
|
|
9
|
+
} from "@vellumai/service-contracts/channels";
|
|
1
10
|
import type { Command } from "commander";
|
|
2
11
|
|
|
3
12
|
import { cliIpcCall, exitFromIpcResult } from "../../ipc/cli-client.js";
|
|
@@ -6,25 +15,6 @@ import { registerCommand } from "../lib/register-command.js";
|
|
|
6
15
|
import { writeOutput } from "../output.js";
|
|
7
16
|
import { channelVerificationSessionsHelp } from "./channel-verification-sessions.help.js";
|
|
8
17
|
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
// Local channel validation (replaces daemon-internal channels/types.js import)
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
|
|
13
|
-
const VALID_CHANNEL_IDS = [
|
|
14
|
-
"telegram",
|
|
15
|
-
"phone",
|
|
16
|
-
"vellum",
|
|
17
|
-
"whatsapp",
|
|
18
|
-
"slack",
|
|
19
|
-
"email",
|
|
20
|
-
"platform",
|
|
21
|
-
] as const;
|
|
22
|
-
type ChannelId = (typeof VALID_CHANNEL_IDS)[number];
|
|
23
|
-
|
|
24
|
-
function isChannelId(raw: string): raw is ChannelId {
|
|
25
|
-
return (VALID_CHANNEL_IDS as readonly string[]).includes(raw);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
18
|
/**
|
|
29
19
|
* Validate the --channel option. Returns the validated ChannelId or writes an
|
|
30
20
|
* error and returns `false`. When `required` is false an absent value is fine
|
|
@@ -49,7 +39,7 @@ function validateChannelOpt(
|
|
|
49
39
|
if (required) {
|
|
50
40
|
writeOutput(cmd, {
|
|
51
41
|
ok: false,
|
|
52
|
-
error: `The "channel" option is required. Valid values: ${
|
|
42
|
+
error: `The "channel" option is required. Valid values: ${CHANNEL_IDS.join(", ")}`,
|
|
53
43
|
});
|
|
54
44
|
process.exitCode = 1;
|
|
55
45
|
return false;
|
|
@@ -59,7 +49,7 @@ function validateChannelOpt(
|
|
|
59
49
|
if (!isChannelId(raw)) {
|
|
60
50
|
writeOutput(cmd, {
|
|
61
51
|
ok: false,
|
|
62
|
-
error: `Invalid channel "${raw}". Valid values: ${
|
|
52
|
+
error: `Invalid channel "${raw}". Valid values: ${CHANNEL_IDS.join(", ")}`,
|
|
63
53
|
});
|
|
64
54
|
process.exitCode = 1;
|
|
65
55
|
return false;
|
|
@@ -12,6 +12,7 @@ running.
|
|
|
12
12
|
|
|
13
13
|
Examples:
|
|
14
14
|
$ assistant conversations list
|
|
15
|
+
$ assistant conversations search "project planning"
|
|
15
16
|
$ assistant conversations new "Project planning"
|
|
16
17
|
$ assistant conversations export
|
|
17
18
|
$ assistant conversations clear`,
|
|
@@ -168,6 +169,39 @@ include them.
|
|
|
168
169
|
Examples:
|
|
169
170
|
$ assistant conversations list
|
|
170
171
|
$ assistant conversations list --include-archived`,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: "search",
|
|
175
|
+
args: "<term>",
|
|
176
|
+
description: "Search conversations by title and message content",
|
|
177
|
+
options: [
|
|
178
|
+
{
|
|
179
|
+
flags: "--limit <n>",
|
|
180
|
+
description: "Maximum number of conversations to return (default 20)",
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
flags: "--json",
|
|
184
|
+
description: "Output result as machine-readable JSON",
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
helpText: `
|
|
188
|
+
Arguments:
|
|
189
|
+
term Search query. Quote multi-word terms so the shell keeps them as one
|
|
190
|
+
argument. Matches conversation titles (substring) and message
|
|
191
|
+
content (full-text). Archived conversations are excluded, matching
|
|
192
|
+
'assistant conversations list'.
|
|
193
|
+
|
|
194
|
+
Requires the assistant to be running. Communicates via IPC socket.
|
|
195
|
+
|
|
196
|
+
Results are grouped by conversation, ordered by most recently updated, and
|
|
197
|
+
capped at 20 conversations unless --limit is set. Each result includes the
|
|
198
|
+
conversation ID, title, relative timestamp, and up to three matching
|
|
199
|
+
message excerpts. Use the ID with rename, export, or wake.
|
|
200
|
+
|
|
201
|
+
Examples:
|
|
202
|
+
$ assistant conversations search "project planning"
|
|
203
|
+
$ assistant conversations search flux --limit 5
|
|
204
|
+
$ assistant conversations search "quarterly metrics" --json`,
|
|
171
205
|
},
|
|
172
206
|
{
|
|
173
207
|
name: "new",
|
|
@@ -11,6 +11,7 @@ import { applyCommandHelp, subcommand } from "../lib/cli-command-help.js";
|
|
|
11
11
|
import { registerCommand } from "../lib/register-command.js";
|
|
12
12
|
import { timeAgo } from "../lib/time-ago.js";
|
|
13
13
|
import { log } from "../logger.js";
|
|
14
|
+
import { shouldOutputJson, writeError, writeOutput } from "../output.js";
|
|
14
15
|
import { tryResolveConversationId } from "../utils/conversation-id.js";
|
|
15
16
|
import { conversationsHelp } from "./conversations.help.js";
|
|
16
17
|
import { registerConversationsDeferCommand } from "./conversations-defer.js";
|
|
@@ -29,6 +30,66 @@ type SlackDetachCliResult = {
|
|
|
29
30
|
conversationId?: string;
|
|
30
31
|
};
|
|
31
32
|
|
|
33
|
+
type ConversationSearchMessage = {
|
|
34
|
+
messageId: string;
|
|
35
|
+
role: string;
|
|
36
|
+
excerpt: string;
|
|
37
|
+
createdAt: number;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type ConversationSearchResult = {
|
|
41
|
+
conversationId: string;
|
|
42
|
+
conversationTitle: string | null;
|
|
43
|
+
conversationUpdatedAt: number;
|
|
44
|
+
matchingMessages: ConversationSearchMessage[];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type ConversationSearchResponse = {
|
|
48
|
+
query: string;
|
|
49
|
+
results: ConversationSearchResult[];
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
function parsePositiveLimit(
|
|
53
|
+
raw: string | undefined,
|
|
54
|
+
): { ok: true; value: number | undefined } | { ok: false; error: string } {
|
|
55
|
+
if (raw === undefined) {
|
|
56
|
+
return { ok: true, value: undefined };
|
|
57
|
+
}
|
|
58
|
+
const trimmed = raw.trim();
|
|
59
|
+
if (!/^\d+$/.test(trimmed)) {
|
|
60
|
+
return {
|
|
61
|
+
ok: false,
|
|
62
|
+
error:
|
|
63
|
+
"Invalid --limit value. Must be a positive integer, e.g. --limit 10.",
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const value = Number(trimmed);
|
|
67
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
68
|
+
return {
|
|
69
|
+
ok: false,
|
|
70
|
+
error:
|
|
71
|
+
"Invalid --limit value. Must be a positive integer, e.g. --limit 10.",
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return { ok: true, value };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function formatSearchResultLines(
|
|
78
|
+
results: ConversationSearchResult[],
|
|
79
|
+
): string[] {
|
|
80
|
+
const lines: string[] = [];
|
|
81
|
+
for (const result of results) {
|
|
82
|
+
lines.push(
|
|
83
|
+
` ${result.conversationId} ${result.conversationTitle ?? "Untitled"} ${timeAgo(result.conversationUpdatedAt)}`,
|
|
84
|
+
);
|
|
85
|
+
for (const message of result.matchingMessages) {
|
|
86
|
+
const excerpt = message.excerpt.replace(/\s+/g, " ").trim();
|
|
87
|
+
lines.push(` ${message.role} ${excerpt}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return lines;
|
|
91
|
+
}
|
|
92
|
+
|
|
32
93
|
function outputSlackDetachError(message: string, json?: boolean): void {
|
|
33
94
|
if (json) {
|
|
34
95
|
process.stdout.write(JSON.stringify({ ok: false, error: message }) + "\n");
|
|
@@ -200,6 +261,70 @@ export function registerConversationsCommand(program: Command): void {
|
|
|
200
261
|
},
|
|
201
262
|
);
|
|
202
263
|
|
|
264
|
+
// -------------------------------------------------------------------
|
|
265
|
+
// search
|
|
266
|
+
// -------------------------------------------------------------------
|
|
267
|
+
|
|
268
|
+
subcommand(conversations, "search").action(
|
|
269
|
+
async (term: string, opts: { limit?: string }, cmd: Command) => {
|
|
270
|
+
const trimmed = term.trim();
|
|
271
|
+
if (!trimmed) {
|
|
272
|
+
writeError(
|
|
273
|
+
cmd,
|
|
274
|
+
'Search term must be a non-empty string. Quote multi-word queries, e.g. assistant conversations search "project planning".',
|
|
275
|
+
);
|
|
276
|
+
process.exitCode = 1;
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const parsedLimit = parsePositiveLimit(opts.limit);
|
|
281
|
+
if (!parsedLimit.ok) {
|
|
282
|
+
writeError(cmd, parsedLimit.error);
|
|
283
|
+
process.exitCode = 1;
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const queryParams: Record<string, string> = { q: trimmed };
|
|
288
|
+
if (parsedLimit.value !== undefined) {
|
|
289
|
+
queryParams.limit = String(parsedLimit.value);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const result = await cliIpcCall<ConversationSearchResponse>(
|
|
293
|
+
"conversations_search",
|
|
294
|
+
{ queryParams },
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
if (!result.ok) {
|
|
298
|
+
if (shouldOutputJson(cmd)) {
|
|
299
|
+
writeOutput(cmd, {
|
|
300
|
+
ok: false,
|
|
301
|
+
error: result.error ?? "Conversation search failed",
|
|
302
|
+
});
|
|
303
|
+
process.exitCode = exitCodeFromIpcResult(result);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
return exitFromIpcResult(result);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const payload = result.result!;
|
|
310
|
+
if (shouldOutputJson(cmd)) {
|
|
311
|
+
writeOutput(cmd, payload);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (payload.results.length === 0) {
|
|
316
|
+
process.stdout.write(
|
|
317
|
+
`No conversations matched "${payload.query}"\n`,
|
|
318
|
+
);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
process.stdout.write(
|
|
323
|
+
formatSearchResultLines(payload.results).join("\n") + "\n",
|
|
324
|
+
);
|
|
325
|
+
},
|
|
326
|
+
);
|
|
327
|
+
|
|
203
328
|
// -------------------------------------------------------------------
|
|
204
329
|
// new
|
|
205
330
|
// -------------------------------------------------------------------
|
|
@@ -38,6 +38,7 @@ interface ProviderConnection {
|
|
|
38
38
|
name: string;
|
|
39
39
|
provider: string;
|
|
40
40
|
auth: AuthInfo;
|
|
41
|
+
baseUrl?: string | null;
|
|
41
42
|
createdAt: string;
|
|
42
43
|
updatedAt: string;
|
|
43
44
|
}
|
|
@@ -129,10 +130,11 @@ function collectRepeatable(value: string, previous: string[]): string[] {
|
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
/**
|
|
132
|
-
* Build the
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
133
|
+
* Build the custom-provider fields (`base_url`, `models`) from CLI flags,
|
|
134
|
+
* forwarded to the connection route under its exact field names. The daemon
|
|
135
|
+
* stays authoritative on whether they are required or allowed (openai-compatible
|
|
136
|
+
* requires both; ollama accepts an optional base URL); the CLI only
|
|
137
|
+
* shape-forwards what the user passed.
|
|
136
138
|
*/
|
|
137
139
|
function buildCustomProviderFields(opts: {
|
|
138
140
|
baseUrl?: string;
|
|
@@ -219,6 +221,9 @@ function attachGetSubcommand(parent: Command): void {
|
|
|
219
221
|
process.stdout.write(`name: ${conn.name}\n`);
|
|
220
222
|
process.stdout.write(`provider: ${conn.provider}\n`);
|
|
221
223
|
process.stdout.write(`auth: ${formatAuth(conn.auth)}\n`);
|
|
224
|
+
if (conn.baseUrl) {
|
|
225
|
+
process.stdout.write(`base_url: ${conn.baseUrl}\n`);
|
|
226
|
+
}
|
|
222
227
|
process.stdout.write(
|
|
223
228
|
`created: ${new Date(conn.createdAt).toISOString()}\n`,
|
|
224
229
|
);
|
|
@@ -218,8 +218,12 @@ Examples:
|
|
|
218
218
|
$ assistant inference providers create local-llm \\
|
|
219
219
|
--provider openai-compatible \\
|
|
220
220
|
--base-url http://localhost:1234/v1 --model my-model
|
|
221
|
+
$ assistant inference providers create ollama-home \\
|
|
222
|
+
--provider ollama --base-url http://192.168.1.50:11434/v1
|
|
221
223
|
$ assistant inference providers update anthropic-personal \\
|
|
222
224
|
--credential credential/anthropic/api_key
|
|
225
|
+
$ assistant inference providers update ollama \\
|
|
226
|
+
--base-url http://127.0.0.1:11434/v1
|
|
223
227
|
$ assistant inference providers delete anthropic-personal
|
|
224
228
|
|
|
225
229
|
After creating or updating a provider, validate it with a live call through
|
|
@@ -268,7 +272,7 @@ a profile that uses it:
|
|
|
268
272
|
{
|
|
269
273
|
flags: "--base-url <url>",
|
|
270
274
|
description:
|
|
271
|
-
"Endpoint base URL (required for
|
|
275
|
+
"Endpoint base URL (required for openai-compatible; optional for ollama)",
|
|
272
276
|
},
|
|
273
277
|
],
|
|
274
278
|
},
|
|
@@ -290,7 +294,8 @@ a profile that uses it:
|
|
|
290
294
|
},
|
|
291
295
|
{
|
|
292
296
|
flags: "--base-url <url>",
|
|
293
|
-
description:
|
|
297
|
+
description:
|
|
298
|
+
"Endpoint base URL (openai-compatible or ollama)",
|
|
294
299
|
},
|
|
295
300
|
],
|
|
296
301
|
},
|
|
@@ -345,7 +350,7 @@ matching \`assistant inference providers <verb>\` command.`,
|
|
|
345
350
|
{
|
|
346
351
|
flags: "--base-url <url>",
|
|
347
352
|
description:
|
|
348
|
-
"Endpoint base URL (required for
|
|
353
|
+
"Endpoint base URL (required for openai-compatible; optional for ollama)",
|
|
349
354
|
},
|
|
350
355
|
],
|
|
351
356
|
},
|
|
@@ -367,7 +372,7 @@ matching \`assistant inference providers <verb>\` command.`,
|
|
|
367
372
|
{
|
|
368
373
|
flags: "--base-url <url>",
|
|
369
374
|
description:
|
|
370
|
-
"Endpoint base URL (openai-compatible
|
|
375
|
+
"Endpoint base URL (openai-compatible or ollama)",
|
|
371
376
|
},
|
|
372
377
|
],
|
|
373
378
|
},
|
|
@@ -46,6 +46,13 @@ Examples:
|
|
|
46
46
|
name: "delete",
|
|
47
47
|
args: "<provider>",
|
|
48
48
|
description: "Delete a stored API key",
|
|
49
|
+
options: [
|
|
50
|
+
{
|
|
51
|
+
flags: "--force",
|
|
52
|
+
description:
|
|
53
|
+
"Delete even when LLM provider connections resolve their auth through the key; those connections stop answering until a new key is stored",
|
|
54
|
+
},
|
|
55
|
+
],
|
|
49
56
|
helpText: `
|
|
50
57
|
Arguments:
|
|
51
58
|
provider Provider name whose key should be removed from secure storage
|
|
@@ -53,9 +60,14 @@ Arguments:
|
|
|
53
60
|
Removes the API key for the given provider from secure local storage. If
|
|
54
61
|
no key exists for the provider, exits with an error.
|
|
55
62
|
|
|
63
|
+
The delete is refused while an LLM provider connection resolves its auth
|
|
64
|
+
through the key; the error names the connections that depend on it. Run
|
|
65
|
+
'assistant inference providers list' to inspect them, and pass --force to delete
|
|
66
|
+
anyway.
|
|
67
|
+
|
|
56
68
|
Examples:
|
|
57
69
|
$ assistant keys delete openai
|
|
58
|
-
$ assistant keys delete anthropic`,
|
|
70
|
+
$ assistant keys delete anthropic --force`,
|
|
59
71
|
},
|
|
60
72
|
],
|
|
61
73
|
};
|
package/src/cli/commands/keys.ts
CHANGED
|
@@ -123,21 +123,32 @@ Examples:
|
|
|
123
123
|
},
|
|
124
124
|
);
|
|
125
125
|
|
|
126
|
-
subcommand(keys, "delete").action(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
126
|
+
subcommand(keys, "delete").action(
|
|
127
|
+
async (provider: string, opts: { force?: boolean }) => {
|
|
128
|
+
const { deleteSecureKeyViaDaemon } =
|
|
129
|
+
await import("../lib/daemon-credential-client.js");
|
|
130
|
+
const delResult = await deleteSecureKeyViaDaemon(
|
|
131
|
+
"api_key",
|
|
132
|
+
provider,
|
|
133
|
+
opts.force === true,
|
|
134
|
+
);
|
|
135
|
+
if (delResult.result === "deleted") {
|
|
136
|
+
log.info(`Deleted API key for "${provider}"`);
|
|
137
|
+
} else if (delResult.result === "error") {
|
|
138
|
+
const detail = delResult.error ? `: ${delResult.error}` : "";
|
|
139
|
+
log.error(`Failed to delete API key for "${provider}"${detail}`);
|
|
140
|
+
if (delResult.code === "CREDENTIAL_IN_USE") {
|
|
141
|
+
log.error(
|
|
142
|
+
`Run 'assistant inference providers list' to inspect those connections, or 'assistant keys delete ${provider} --force' to delete the key anyway.`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
process.exit(1);
|
|
146
|
+
} else {
|
|
147
|
+
log.error(`No API key found for "${provider}"`);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
);
|
|
141
152
|
},
|
|
142
153
|
});
|
|
143
154
|
}
|