@vellumai/assistant 0.4.56 → 0.4.57
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 +10 -10
- package/Dockerfile +3 -0
- package/README.md +11 -11
- package/docs/architecture/integrations.md +2 -2
- package/docs/architecture/memory.md +3 -4
- package/docs/credential-execution-service.md +13 -20
- package/node_modules/@vellumai/ces-contracts/src/error.ts +5 -4
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +7 -7
- package/src/__tests__/anthropic-provider.test.ts +172 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +15 -1
- package/src/__tests__/approval-cascade.test.ts +2 -2
- package/src/__tests__/approval-routes-http.test.ts +3 -4
- package/src/__tests__/asset-materialize-tool.test.ts +5 -5
- package/src/__tests__/asset-search-tool.test.ts +1 -1
- package/src/__tests__/assistant-attachments.test.ts +5 -5
- package/src/__tests__/assistant-events-sse-hardening.test.ts +1 -1
- package/src/__tests__/assistant-feature-flags-integration.test.ts +50 -38
- package/src/__tests__/attachments-store.test.ts +2 -2
- package/src/__tests__/avatar-e2e.test.ts +5 -3
- package/src/__tests__/browser-skill-endstate.test.ts +0 -1
- package/src/__tests__/call-routes-http.test.ts +2 -2
- package/src/__tests__/callback-handoff-copy.test.ts +1 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +158 -0
- package/src/__tests__/channel-readiness-routes.test.ts +0 -1
- package/src/__tests__/channel-readiness-service.test.ts +0 -1
- package/src/__tests__/checker.test.ts +31 -32
- package/src/__tests__/chrome-cdp.test.ts +47 -18
- package/src/__tests__/claude-code-skill-regression.test.ts +2 -2
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +9 -18
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +4 -4
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -2
- package/src/__tests__/conversation-agent-loop.test.ts +11 -4
- package/src/__tests__/conversation-attachments.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +33 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -1
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +1 -1
- package/src/__tests__/conversation-pre-run-repair.test.ts +4 -4
- package/src/__tests__/conversation-provider-retry-repair.test.ts +4 -4
- package/src/__tests__/conversation-queue.test.ts +23 -14
- package/src/__tests__/conversation-routes-slash-commands.test.ts +3 -3
- package/src/__tests__/conversation-runtime-assembly.test.ts +185 -173
- package/src/__tests__/conversation-seed-composer.test.ts +1 -1
- package/src/__tests__/conversation-slash-queue.test.ts +4 -4
- package/src/__tests__/conversation-slash-unknown.test.ts +4 -4
- package/src/__tests__/conversation-starter-routes.test.ts +291 -0
- package/src/__tests__/conversation-wipe.test.ts +438 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -3
- package/src/__tests__/conversation-workspace-injection.test.ts +4 -5
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -5
- package/src/__tests__/credential-security-e2e.test.ts +20 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/credential-vault-unit.test.ts +227 -0
- package/src/__tests__/credentials-cli.test.ts +3 -0
- package/src/__tests__/date-context.test.ts +59 -377
- package/src/__tests__/drop-capability-card-state-migration.test.ts +169 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +11 -45
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
- package/src/__tests__/encrypted-store.test.ts +237 -15
- package/src/__tests__/ephemeral-permissions.test.ts +4 -5
- package/src/__tests__/event-bus.test.ts +3 -3
- package/src/__tests__/gateway-only-enforcement.test.ts +2 -2
- package/src/__tests__/gateway-only-guard.test.ts +1 -0
- package/src/__tests__/gemini-image-service.test.ts +4 -4
- package/src/__tests__/gemini-provider.test.ts +6 -9
- package/src/__tests__/guardian-binding-drift-heal.test.ts +128 -0
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/host-shell-tool.test.ts +6 -6
- package/src/__tests__/http-user-message-parity.test.ts +2 -2
- package/src/__tests__/intent-routing.test.ts +51 -99
- package/src/__tests__/invite-routes-http.test.ts +5 -0
- package/src/__tests__/list-messages-attachments.test.ts +1 -1
- package/src/__tests__/managed-proxy-context.test.ts +2 -5
- package/src/__tests__/managed-skill-lifecycle.test.ts +8 -8
- package/src/__tests__/media-generate-image.test.ts +32 -15
- package/src/__tests__/media-reuse-story.e2e.test.ts +1 -1
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +1 -1
- package/src/__tests__/memory-lifecycle-e2e.test.ts +24 -18
- package/src/__tests__/memory-recall-quality.test.ts +4 -3
- package/src/__tests__/memory-regressions.test.ts +86 -90
- package/src/__tests__/migration-cross-version-compatibility.test.ts +32 -32
- package/src/__tests__/migration-export-http.test.ts +26 -27
- package/src/__tests__/migration-import-commit-http.test.ts +165 -37
- package/src/__tests__/migration-import-preflight-http.test.ts +81 -20
- package/src/__tests__/migration-validate-http.test.ts +16 -16
- package/src/__tests__/model-intents.test.ts +1 -1
- package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +1 -1
- package/src/__tests__/notification-broadcaster.test.ts +1 -1
- package/src/__tests__/notification-decision-fallback.test.ts +2 -2
- package/src/__tests__/notification-decision-identity.test.ts +8 -9
- package/src/__tests__/notification-decision-strategy.test.ts +1 -1
- package/src/__tests__/notification-deep-link.test.ts +1 -1
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/notification-schedule-dedup.test.ts +7 -7
- package/src/__tests__/oauth-store.test.ts +1 -3
- package/src/__tests__/oauth2-gateway-transport.test.ts +6 -1
- package/src/__tests__/onboarding-template-contract.test.ts +23 -59
- package/src/__tests__/provider-error-scenarios.test.ts +154 -0
- package/src/__tests__/provider-fail-open-selection.test.ts +2 -2
- package/src/__tests__/provider-managed-proxy-integration.test.ts +8 -9
- package/src/__tests__/provider-registry-ollama.test.ts +5 -2
- package/src/__tests__/qdrant-manager.test.ts +7 -7
- package/src/__tests__/ratelimit.test.ts +0 -74
- package/src/__tests__/recording-handler.test.ts +0 -1
- package/src/__tests__/require-fresh-approval.test.ts +1 -1
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/scheduler-recurrence.test.ts +46 -2
- package/src/__tests__/schema-transforms.test.ts +114 -54
- package/src/__tests__/secret-onetime-send.test.ts +20 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -2
- package/src/__tests__/secret-scanner-executor.test.ts +1 -2
- package/src/__tests__/send-endpoint-busy.test.ts +63 -4
- package/src/__tests__/send-notification-tool.test.ts +2 -2
- package/src/__tests__/shell-credential-ref.test.ts +0 -1
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -2
- package/src/__tests__/skill-memory.test.ts +547 -0
- package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -2
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -0
- package/src/__tests__/slack-channel-config.test.ts +109 -94
- package/src/__tests__/swarm-conversation-integration.test.ts +2 -2
- package/src/__tests__/swarm-recursion.test.ts +2 -2
- package/src/__tests__/swarm-tool.test.ts +2 -2
- package/src/__tests__/system-prompt.test.ts +19 -66
- package/src/__tests__/telegram-config.test.ts +121 -0
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -2
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
- package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +1 -1
- package/src/__tests__/trace-emitter.test.ts +8 -1
- package/src/__tests__/trust-store.test.ts +7 -8
- package/src/__tests__/twilio-routes.test.ts +1 -18
- package/src/__tests__/user-reference.test.ts +82 -2
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +196 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -1
- package/src/approvals/guardian-request-resolvers.ts +3 -3
- package/src/avatar/ascii-renderer.ts +2 -2
- package/src/avatar/png-renderer.ts +2 -2
- package/src/avatar/resvg-lazy.ts +21 -0
- package/src/calls/guardian-dispatch.ts +1 -1
- package/src/calls/relay-access-wait.ts +2 -2
- package/src/calls/twilio-rest.ts +0 -248
- package/src/cli/AGENTS.md +5 -8
- package/src/cli/__tests__/notifications.test.ts +5 -5
- package/src/cli/commands/avatar.ts +64 -2
- package/src/cli/commands/conversations.ts +131 -1
- package/src/cli/commands/credentials.ts +2 -0
- package/src/cli/commands/notifications.ts +3 -3
- package/src/cli.ts +10 -0
- package/src/config/bundled-skills/acp/SKILL.md +5 -5
- package/src/config/bundled-skills/acp/TOOLS.json +6 -6
- package/src/config/bundled-skills/app-builder/SKILL.md +42 -42
- package/src/config/bundled-skills/app-builder/TOOLS.json +10 -10
- package/src/config/bundled-skills/browser/SKILL.md +15 -15
- package/src/config/bundled-skills/browser/TOOLS.json +14 -14
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +2 -2
- package/src/config/bundled-skills/chatgpt-import/TOOLS.json +1 -1
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
- package/src/config/bundled-skills/claude-code/SKILL.md +5 -5
- package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
- package/src/config/bundled-skills/computer-use/TOOLS.json +15 -15
- package/src/config/bundled-skills/contacts/SKILL.md +3 -3
- package/src/config/bundled-skills/contacts/TOOLS.json +4 -4
- package/src/config/bundled-skills/document/SKILL.md +4 -4
- package/src/config/bundled-skills/document/TOOLS.json +2 -2
- package/src/config/bundled-skills/followups/TOOLS.json +3 -3
- package/src/config/bundled-skills/gmail/SKILL.md +32 -32
- package/src/config/bundled-skills/gmail/TOOLS.json +16 -16
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
- package/src/config/bundled-skills/google-calendar/SKILL.md +1 -1
- package/src/config/bundled-skills/google-calendar/TOOLS.json +5 -5
- package/src/config/bundled-skills/google-calendar/types.ts +1 -1
- package/src/config/bundled-skills/heartbeat/SKILL.md +43 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +3 -3
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -3
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +16 -12
- package/src/config/bundled-skills/media-processing/SKILL.md +40 -40
- package/src/config/bundled-skills/media-processing/TOOLS.json +8 -8
- package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +2 -2
- package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +1 -1
- package/src/config/bundled-skills/media-processing/services/gemini-map.ts +5 -5
- package/src/config/bundled-skills/media-processing/services/gemini-video.ts +2 -2
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -2
- package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -2
- package/src/config/bundled-skills/media-processing/services/reduce.ts +3 -3
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -2
- package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +29 -25
- package/src/config/bundled-skills/messaging/TOOLS.json +11 -11
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +1 -1
- package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
- package/src/config/bundled-skills/notifications/SKILL.md +3 -3
- package/src/config/bundled-skills/notifications/TOOLS.json +2 -2
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +3 -3
- package/src/config/bundled-skills/orchestration/SKILL.md +1 -1
- package/src/config/bundled-skills/orchestration/TOOLS.json +1 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +18 -14
- package/src/config/bundled-skills/phone-calls/TOOLS.json +3 -3
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +1 -1
- package/src/config/bundled-skills/playbooks/TOOLS.json +4 -4
- package/src/config/bundled-skills/schedule/SKILL.md +26 -26
- package/src/config/bundled-skills/schedule/TOOLS.json +5 -5
- package/src/config/bundled-skills/screen-watch/SKILL.md +3 -3
- package/src/config/bundled-skills/screen-watch/TOOLS.json +1 -1
- package/src/config/bundled-skills/sequences/SKILL.md +2 -2
- package/src/config/bundled-skills/sequences/TOOLS.json +10 -10
- package/src/config/bundled-skills/sequences/tools/sequence-analytics.ts +2 -2
- package/src/config/bundled-skills/sequences/tools/sequence-enroll.ts +2 -2
- package/src/config/bundled-skills/sequences/tools/sequence-enrollment-list.ts +1 -1
- package/src/config/bundled-skills/sequences/tools/sequence-get.ts +1 -1
- package/src/config/bundled-skills/sequences/tools/sequence-import.ts +3 -3
- package/src/config/bundled-skills/sequences/tools/sequence-list.ts +1 -1
- package/src/config/bundled-skills/sequences/tools/sequence-update.ts +1 -1
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +5 -5
- package/src/config/bundled-skills/skills-catalog/SKILL.md +84 -0
- package/src/config/bundled-skills/slack/SKILL.md +2 -2
- package/src/config/bundled-skills/slack/TOOLS.json +8 -8
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +3 -3
- package/src/config/bundled-skills/subagent/TOOLS.json +5 -5
- package/src/config/bundled-skills/tasks/SKILL.md +1 -1
- package/src/config/bundled-skills/tasks/TOOLS.json +9 -9
- package/src/config/bundled-skills/transcribe/SKILL.md +5 -5
- package/src/config/bundled-skills/transcribe/TOOLS.json +1 -1
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +10 -10
- package/src/config/bundled-skills/watcher/SKILL.md +4 -4
- package/src/config/bundled-skills/watcher/TOOLS.json +5 -5
- package/src/config/feature-flag-registry.json +33 -17
- package/src/config/schemas/sandbox.ts +1 -1
- package/src/config/schemas/services.ts +13 -3
- package/src/config/schemas/timeouts.ts +0 -10
- package/src/contacts/contact-store.ts +63 -0
- package/src/contacts/contacts-write.ts +1 -1
- package/src/daemon/assistant-attachments.ts +2 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -2
- package/src/daemon/conversation-agent-loop.ts +7 -30
- package/src/daemon/conversation-error.ts +24 -0
- package/src/daemon/conversation-memory.ts +8 -7
- package/src/daemon/conversation-runtime-assembly.ts +139 -274
- package/src/daemon/conversation-slash.ts +7 -26
- package/src/daemon/conversation-surfaces.ts +14 -0
- package/src/daemon/conversation-tool-setup.ts +9 -8
- package/src/daemon/conversation.ts +2 -0
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/date-context.ts +10 -83
- package/src/daemon/handlers/config-channels.ts +12 -2
- package/src/daemon/handlers/config-slack-channel.ts +7 -1
- package/src/daemon/handlers/config-telegram.ts +6 -1
- package/src/daemon/handlers/conversations.ts +2 -2
- package/src/daemon/handlers/skills.ts +4 -0
- package/src/daemon/lifecycle.ts +28 -4
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +1 -5
- package/src/daemon/shutdown-handlers.ts +9 -3
- package/src/daemon/tool-side-effects.ts +40 -0
- package/src/daemon/trace-emitter.ts +25 -2
- package/src/events/domain-events.ts +1 -1
- package/src/events/tool-permission-telemetry-listener.ts +46 -0
- package/src/inbound/platform-callback-registration.ts +0 -18
- package/src/media/app-icon-generator.ts +15 -8
- package/src/media/avatar-router.ts +15 -8
- package/src/media/gemini-image-service.ts +125 -21
- package/src/memory/attachments-store.ts +3 -3
- package/src/memory/channel-verification-sessions.ts +6 -6
- package/src/memory/conversation-crud.ts +196 -1
- package/src/memory/{thread-starters-cadence.ts → conversation-starters-cadence.ts} +9 -42
- package/src/memory/conversation-title-service.ts +2 -3
- package/src/memory/db-init.ts +25 -1
- package/src/memory/invite-store.ts +4 -4
- package/src/memory/items-extractor.ts +4 -4
- package/src/memory/job-handlers/{thread-starters.ts → conversation-starters.ts} +123 -38
- package/src/memory/jobs-store.ts +3 -2
- package/src/memory/jobs-worker.ts +7 -5
- package/src/memory/lifecycle-events-store.ts +63 -0
- package/src/memory/migrations/172-rename-created-by-session-id.ts +27 -0
- package/src/memory/migrations/173-rename-source-session-id.ts +16 -0
- package/src/memory/migrations/174-rename-thread-starters-table.ts +52 -0
- package/src/memory/migrations/175-create-lifecycle-events.ts +15 -0
- package/src/memory/migrations/176-drop-capability-card-state.ts +36 -0
- package/src/memory/migrations/177-create-trace-events-table.ts +40 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +13 -0
- package/src/memory/retriever.test.ts +223 -96
- package/src/memory/retriever.ts +115 -138
- package/src/memory/schema/calls.ts +1 -1
- package/src/memory/schema/contacts.ts +1 -1
- package/src/memory/schema/infrastructure.ts +29 -0
- package/src/memory/schema/memory-core.ts +7 -17
- package/src/memory/schema/notifications.ts +1 -1
- package/src/memory/search/formatting.ts +23 -6
- package/src/memory/search/lexical.ts +2 -0
- package/src/memory/search/semantic.ts +2 -0
- package/src/memory/search/staleness.ts +1 -0
- package/src/memory/search/types.ts +4 -0
- package/src/memory/task-memory-cleanup.ts +96 -6
- package/src/memory/trace-event-store.ts +148 -0
- package/src/notifications/README.md +1 -1
- package/src/notifications/decision-engine.ts +2 -2
- package/src/notifications/emit-signal.ts +4 -4
- package/src/notifications/events-store.ts +4 -4
- package/src/notifications/signal.ts +1 -1
- package/src/oauth/manual-token-connection.ts +49 -25
- package/src/permissions/checker.ts +6 -5
- package/src/permissions/defaults.ts +4 -4
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +9 -90
- package/src/prompts/cache-boundary.ts +8 -0
- package/src/prompts/system-prompt.ts +105 -634
- package/src/prompts/templates/BOOTSTRAP.md +166 -33
- package/src/prompts/templates/IDENTITY.md +8 -23
- package/src/prompts/templates/SOUL.md +20 -41
- package/src/prompts/templates/USER.md +3 -19
- package/src/prompts/user-reference.ts +14 -16
- package/src/providers/anthropic/client.ts +46 -2
- package/src/providers/gemini/client.ts +6 -9
- package/src/providers/managed-proxy/constants.ts +1 -7
- package/src/providers/managed-proxy/context.ts +0 -1
- package/src/providers/model-intents.ts +5 -5
- package/src/providers/openai/client.ts +10 -1
- package/src/providers/openrouter/client.ts +1 -0
- package/src/providers/ratelimit.ts +0 -35
- package/src/providers/registry.ts +3 -5
- package/src/providers/retry.ts +18 -1
- package/src/runtime/access-request-helper.ts +1 -1
- package/src/runtime/auth/route-policy.ts +7 -0
- package/src/runtime/channel-verification-service.ts +1 -1
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/guardian-vellum-migration.ts +63 -1
- package/src/runtime/http-server.ts +8 -4
- package/src/runtime/migrations/vbundle-builder.ts +212 -32
- package/src/runtime/migrations/vbundle-import-analyzer.ts +74 -8
- package/src/runtime/migrations/vbundle-importer.ts +66 -1
- package/src/runtime/migrations/vbundle-validator.ts +17 -3
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +4 -4
- package/src/runtime/routes/attachment-routes.ts +2 -2
- package/src/runtime/routes/btw-routes.ts +9 -0
- package/src/runtime/routes/channel-verification-routes.ts +19 -2
- package/src/runtime/routes/conversation-management-routes.ts +55 -1
- package/src/runtime/routes/conversation-query-routes.ts +1 -1
- package/src/runtime/routes/conversation-routes.ts +49 -5
- package/src/runtime/routes/conversation-starter-routes.ts +207 -0
- package/src/runtime/routes/guardian-bootstrap-routes.ts +13 -9
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -1
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +1 -1
- package/src/runtime/routes/migration-routes.ts +25 -13
- package/src/runtime/routes/secret-routes.ts +18 -0
- package/src/runtime/routes/settings-routes.ts +8 -8
- package/src/runtime/routes/telemetry-routes.ts +53 -0
- package/src/runtime/routes/trace-event-routes.ts +62 -0
- package/src/runtime/tool-grant-request-helper.ts +1 -1
- package/src/runtime/verification-outbound-actions.ts +47 -31
- package/src/security/encrypted-store.ts +263 -78
- package/src/skills/catalog-install.ts +10 -0
- package/src/skills/managed-store.ts +2 -0
- package/src/skills/skill-memory.ts +220 -0
- package/src/subagent/manager.ts +1 -4
- package/src/telemetry/types.ts +10 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
- package/src/telemetry/usage-telemetry-reporter.ts +51 -4
- package/src/tools/AGENTS.md +11 -11
- package/src/tools/acp/spawn.ts +1 -1
- package/src/tools/apps/executors.ts +8 -8
- package/src/tools/apps/registry.ts +1 -1
- package/src/tools/assets/materialize.ts +6 -6
- package/src/tools/assets/search.ts +10 -10
- package/src/tools/browser/__tests__/auth-cache.test.ts +2 -2
- package/src/tools/browser/__tests__/auth-detector.test.ts +4 -4
- package/src/tools/browser/auth-detector.ts +6 -6
- package/src/tools/browser/browser-execution.ts +13 -13
- package/src/tools/browser/browser-manager.ts +3 -3
- package/src/tools/browser/chrome-cdp.ts +5 -5
- package/src/tools/browser/jit-auth.ts +2 -2
- package/src/tools/browser/network-recorder.test.ts +2 -2
- package/src/tools/browser/network-recorder.ts +3 -3
- package/src/tools/browser/runtime-check.ts +3 -3
- package/src/tools/claude-code/claude-code.ts +2 -2
- package/src/tools/computer-use/definitions.ts +18 -18
- package/src/tools/credential-execution/make-authenticated-request.ts +4 -4
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -3
- package/src/tools/credential-execution/run-authenticated-command.ts +4 -4
- package/src/tools/credentials/broker-types.ts +5 -5
- package/src/tools/credentials/broker.ts +15 -15
- package/src/tools/credentials/metadata-store.ts +2 -2
- package/src/tools/credentials/resolve.ts +1 -1
- package/src/tools/credentials/selection.ts +1 -1
- package/src/tools/credentials/tool-policy.ts +1 -1
- package/src/tools/credentials/vault.ts +115 -25
- package/src/tools/execution-target.ts +2 -2
- package/src/tools/executor.ts +7 -7
- package/src/tools/filesystem/edit.ts +2 -2
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +1 -1
- package/src/tools/host-filesystem/edit.ts +2 -1
- package/src/tools/host-filesystem/read.ts +2 -1
- package/src/tools/host-filesystem/write.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +9 -8
- package/src/tools/mcp/mcp-tool-factory.ts +7 -6
- package/src/tools/memory/definitions.ts +6 -5
- package/src/tools/memory/handlers.test.ts +1 -1
- package/src/tools/network/__tests__/web-search.test.ts +3 -3
- package/src/tools/network/domain-normalize.ts +2 -2
- package/src/tools/network/script-proxy/session-manager.ts +10 -10
- package/src/tools/network/web-fetch.ts +1 -1
- package/src/tools/network/web-search.ts +3 -3
- package/src/tools/permission-checker.ts +8 -8
- package/src/tools/registry.ts +7 -7
- package/src/tools/schedule/list.ts +2 -2
- package/src/tools/schema-transforms.ts +31 -21
- package/src/tools/secret-detection-handler.ts +1 -1
- package/src/tools/sensitive-output-placeholders.ts +1 -1
- package/src/tools/shared/filesystem/edit-engine.ts +1 -1
- package/src/tools/shared/filesystem/file-ops-service.ts +3 -3
- package/src/tools/shared/filesystem/image-read.ts +25 -5
- package/src/tools/shared/filesystem/path-policy.ts +2 -2
- package/src/tools/shared/shell-output.ts +1 -1
- package/src/tools/side-effects.ts +1 -1
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/load.ts +3 -3
- package/src/tools/skills/sandbox-runner.ts +3 -3
- package/src/tools/subagent/read.ts +1 -1
- package/src/tools/subagent/spawn.ts +2 -2
- package/src/tools/swarm/delegate.ts +3 -3
- package/src/tools/system/request-permission.ts +5 -4
- package/src/tools/terminal/backends/native.ts +4 -4
- package/src/tools/terminal/parser.ts +6 -6
- package/src/tools/terminal/sandbox-diagnostics.ts +1 -1
- package/src/tools/terminal/shell.ts +16 -16
- package/src/tools/tool-approval-handler.ts +21 -12
- package/src/tools/tool-manifest.ts +4 -4
- package/src/tools/types.ts +3 -3
- package/src/tools/ui-surface/definitions.ts +9 -37
- package/src/tools/watcher/list.ts +1 -1
- package/src/util/logger.ts +7 -2
- package/src/util/retry.ts +29 -1
- package/src/workspace/migrations/007-web-search-provider-rename.ts +37 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/__tests__/cli-help-reference-sync.test.ts +0 -26
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -190
- package/src/cli/reference.ts +0 -38
- package/src/memory/job-handlers/capability-cards.ts +0 -420
- package/src/runtime/routes/thread-starter-routes.ts +0 -294
package/src/calls/twilio-rest.ts
CHANGED
|
@@ -331,254 +331,6 @@ export async function updatePhoneNumberWebhooks(
|
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
-
// ── Toll-Free Verification ──────────────────────────────────────────────
|
|
335
|
-
|
|
336
|
-
/** Twilio Messaging API base URL for toll-free verification endpoints. */
|
|
337
|
-
const TOLLFREE_VERIFICATION_BASE =
|
|
338
|
-
"https://messaging.twilio.com/v1/Tollfree/Verifications";
|
|
339
|
-
|
|
340
|
-
export interface TollFreeVerification {
|
|
341
|
-
sid: string;
|
|
342
|
-
status: string;
|
|
343
|
-
rejectionReason?: string;
|
|
344
|
-
rejectionReasons?: string[];
|
|
345
|
-
errorCode?: string;
|
|
346
|
-
editAllowed?: boolean;
|
|
347
|
-
editExpiration?: string;
|
|
348
|
-
regulationType?: string;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
function parseTollFreeVerification(
|
|
352
|
-
raw: Record<string, unknown>,
|
|
353
|
-
): TollFreeVerification {
|
|
354
|
-
return {
|
|
355
|
-
sid: raw.sid as string,
|
|
356
|
-
status: raw.status as string,
|
|
357
|
-
rejectionReason: (raw.rejection_reason as string) ?? undefined,
|
|
358
|
-
rejectionReasons: (raw.rejection_reasons as string[]) ?? undefined,
|
|
359
|
-
errorCode: raw.error_code != null ? String(raw.error_code) : undefined,
|
|
360
|
-
editAllowed: (raw.edit_allowed as boolean) ?? undefined,
|
|
361
|
-
editExpiration: (raw.edit_expiration as string) ?? undefined,
|
|
362
|
-
regulationType: (raw.regulation_type as string) ?? undefined,
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* Get toll-free verification status for a phone number.
|
|
368
|
-
* If `phoneNumberSid` is provided, filters by that SID; otherwise returns the
|
|
369
|
-
* first verification found.
|
|
370
|
-
*/
|
|
371
|
-
export async function getTollFreeVerificationStatus(
|
|
372
|
-
accountSid: string,
|
|
373
|
-
authToken: string,
|
|
374
|
-
phoneNumberSid?: string,
|
|
375
|
-
): Promise<TollFreeVerification | null> {
|
|
376
|
-
const params = new URLSearchParams();
|
|
377
|
-
if (phoneNumberSid) params.set("TollfreePhoneNumberSid", phoneNumberSid);
|
|
378
|
-
|
|
379
|
-
const url = params.toString()
|
|
380
|
-
? `${TOLLFREE_VERIFICATION_BASE}?${params.toString()}`
|
|
381
|
-
: TOLLFREE_VERIFICATION_BASE;
|
|
382
|
-
|
|
383
|
-
const res = await fetch(url, {
|
|
384
|
-
method: "GET",
|
|
385
|
-
headers: { Authorization: twilioAuthHeader(accountSid, authToken) },
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
if (!res.ok) {
|
|
389
|
-
const text = await res.text();
|
|
390
|
-
throw new ProviderError(
|
|
391
|
-
`Twilio Toll-Free Verification API error ${res.status}: ${text}`,
|
|
392
|
-
"twilio",
|
|
393
|
-
res.status,
|
|
394
|
-
);
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
const data = (await res.json()) as {
|
|
398
|
-
verifications?: Array<Record<string, unknown>>;
|
|
399
|
-
};
|
|
400
|
-
const verifications = data.verifications ?? [];
|
|
401
|
-
if (verifications.length === 0) return null;
|
|
402
|
-
|
|
403
|
-
return parseTollFreeVerification(verifications[0]);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/** Fetch a specific toll-free verification by SID. */
|
|
407
|
-
export async function getTollFreeVerificationBySid(
|
|
408
|
-
accountSid: string,
|
|
409
|
-
authToken: string,
|
|
410
|
-
verificationSid: string,
|
|
411
|
-
): Promise<TollFreeVerification | null> {
|
|
412
|
-
const res = await fetch(
|
|
413
|
-
`${TOLLFREE_VERIFICATION_BASE}/${encodeURIComponent(verificationSid)}`,
|
|
414
|
-
{
|
|
415
|
-
method: "GET",
|
|
416
|
-
headers: { Authorization: twilioAuthHeader(accountSid, authToken) },
|
|
417
|
-
},
|
|
418
|
-
);
|
|
419
|
-
|
|
420
|
-
if (res.status === 404) {
|
|
421
|
-
return null;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
if (!res.ok) {
|
|
425
|
-
const text = await res.text();
|
|
426
|
-
throw new ProviderError(
|
|
427
|
-
`Twilio Toll-Free Verification fetch error ${res.status}: ${text}`,
|
|
428
|
-
"twilio",
|
|
429
|
-
res.status,
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
const data = (await res.json()) as Record<string, unknown>;
|
|
434
|
-
return parseTollFreeVerification(data);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
export interface TollFreeVerificationSubmitParams {
|
|
438
|
-
tollfreePhoneNumberSid: string;
|
|
439
|
-
businessName: string;
|
|
440
|
-
businessWebsite: string;
|
|
441
|
-
notificationEmail: string;
|
|
442
|
-
useCaseCategories: string[];
|
|
443
|
-
useCaseSummary: string;
|
|
444
|
-
productionMessageSample: string;
|
|
445
|
-
optInImageUrls: string[];
|
|
446
|
-
optInType: string;
|
|
447
|
-
messageVolume: string;
|
|
448
|
-
businessType?: string;
|
|
449
|
-
customerProfileSid?: string;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/** Submit a new toll-free verification request. */
|
|
453
|
-
export async function submitTollFreeVerification(
|
|
454
|
-
accountSid: string,
|
|
455
|
-
authToken: string,
|
|
456
|
-
params: TollFreeVerificationSubmitParams,
|
|
457
|
-
): Promise<TollFreeVerification> {
|
|
458
|
-
const body = new URLSearchParams();
|
|
459
|
-
body.set("TollfreePhoneNumberSid", params.tollfreePhoneNumberSid);
|
|
460
|
-
body.set("BusinessName", params.businessName);
|
|
461
|
-
body.set("BusinessWebsite", params.businessWebsite);
|
|
462
|
-
body.set("NotificationEmail", params.notificationEmail);
|
|
463
|
-
body.set("UseCaseSummary", params.useCaseSummary);
|
|
464
|
-
body.set("ProductionMessageSample", params.productionMessageSample);
|
|
465
|
-
body.set("OptInType", params.optInType);
|
|
466
|
-
body.set("MessageVolume", params.messageVolume);
|
|
467
|
-
body.set("BusinessType", params.businessType ?? "SOLE_PROPRIETOR");
|
|
468
|
-
|
|
469
|
-
for (const cat of params.useCaseCategories) {
|
|
470
|
-
body.append("UseCaseCategories", cat);
|
|
471
|
-
}
|
|
472
|
-
for (const url of params.optInImageUrls) {
|
|
473
|
-
body.append("OptInImageUrls", url);
|
|
474
|
-
}
|
|
475
|
-
if (params.customerProfileSid) {
|
|
476
|
-
body.set("CustomerProfileSid", params.customerProfileSid);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
const res = await fetch(TOLLFREE_VERIFICATION_BASE, {
|
|
480
|
-
method: "POST",
|
|
481
|
-
headers: {
|
|
482
|
-
Authorization: twilioAuthHeader(accountSid, authToken),
|
|
483
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
484
|
-
},
|
|
485
|
-
body: body.toString(),
|
|
486
|
-
});
|
|
487
|
-
|
|
488
|
-
if (!res.ok) {
|
|
489
|
-
const text = await res.text();
|
|
490
|
-
throw new ProviderError(
|
|
491
|
-
`Twilio Toll-Free Verification submit error ${res.status}: ${text}`,
|
|
492
|
-
"twilio",
|
|
493
|
-
res.status,
|
|
494
|
-
);
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
const data = (await res.json()) as Record<string, unknown>;
|
|
498
|
-
return parseTollFreeVerification(data);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/** Update an existing toll-free verification. */
|
|
502
|
-
export async function updateTollFreeVerification(
|
|
503
|
-
accountSid: string,
|
|
504
|
-
authToken: string,
|
|
505
|
-
verificationSid: string,
|
|
506
|
-
params: Partial<TollFreeVerificationSubmitParams>,
|
|
507
|
-
): Promise<TollFreeVerification> {
|
|
508
|
-
const body = new URLSearchParams();
|
|
509
|
-
if (params.businessName) body.set("BusinessName", params.businessName);
|
|
510
|
-
if (params.businessWebsite)
|
|
511
|
-
body.set("BusinessWebsite", params.businessWebsite);
|
|
512
|
-
if (params.notificationEmail)
|
|
513
|
-
body.set("NotificationEmail", params.notificationEmail);
|
|
514
|
-
if (params.useCaseSummary) body.set("UseCaseSummary", params.useCaseSummary);
|
|
515
|
-
if (params.productionMessageSample)
|
|
516
|
-
body.set("ProductionMessageSample", params.productionMessageSample);
|
|
517
|
-
if (params.optInType) body.set("OptInType", params.optInType);
|
|
518
|
-
if (params.messageVolume) body.set("MessageVolume", params.messageVolume);
|
|
519
|
-
if (params.businessType) body.set("BusinessType", params.businessType);
|
|
520
|
-
if (params.useCaseCategories) {
|
|
521
|
-
for (const cat of params.useCaseCategories) {
|
|
522
|
-
body.append("UseCaseCategories", cat);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
if (params.optInImageUrls) {
|
|
526
|
-
for (const url of params.optInImageUrls) {
|
|
527
|
-
body.append("OptInImageUrls", url);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
if (params.customerProfileSid)
|
|
531
|
-
body.set("CustomerProfileSid", params.customerProfileSid);
|
|
532
|
-
|
|
533
|
-
const res = await fetch(
|
|
534
|
-
`${TOLLFREE_VERIFICATION_BASE}/${encodeURIComponent(verificationSid)}`,
|
|
535
|
-
{
|
|
536
|
-
method: "POST",
|
|
537
|
-
headers: {
|
|
538
|
-
Authorization: twilioAuthHeader(accountSid, authToken),
|
|
539
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
540
|
-
},
|
|
541
|
-
body: body.toString(),
|
|
542
|
-
},
|
|
543
|
-
);
|
|
544
|
-
|
|
545
|
-
if (!res.ok) {
|
|
546
|
-
const text = await res.text();
|
|
547
|
-
throw new ProviderError(
|
|
548
|
-
`Twilio Toll-Free Verification update error ${res.status}: ${text}`,
|
|
549
|
-
"twilio",
|
|
550
|
-
res.status,
|
|
551
|
-
);
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
const data = (await res.json()) as Record<string, unknown>;
|
|
555
|
-
return parseTollFreeVerification(data);
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
/** Delete a toll-free verification. */
|
|
559
|
-
export async function deleteTollFreeVerification(
|
|
560
|
-
accountSid: string,
|
|
561
|
-
authToken: string,
|
|
562
|
-
verificationSid: string,
|
|
563
|
-
): Promise<void> {
|
|
564
|
-
const res = await fetch(
|
|
565
|
-
`${TOLLFREE_VERIFICATION_BASE}/${encodeURIComponent(verificationSid)}`,
|
|
566
|
-
{
|
|
567
|
-
method: "DELETE",
|
|
568
|
-
headers: { Authorization: twilioAuthHeader(accountSid, authToken) },
|
|
569
|
-
},
|
|
570
|
-
);
|
|
571
|
-
|
|
572
|
-
if (!res.ok) {
|
|
573
|
-
const text = await res.text();
|
|
574
|
-
throw new ProviderError(
|
|
575
|
-
`Twilio Toll-Free Verification delete error ${res.status}: ${text}`,
|
|
576
|
-
"twilio",
|
|
577
|
-
res.status,
|
|
578
|
-
);
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
|
|
582
334
|
/**
|
|
583
335
|
* Get the SID for an incoming phone number.
|
|
584
336
|
* Looks up the number via `IncomingPhoneNumbers.json?PhoneNumber=...`.
|
package/src/cli/AGENTS.md
CHANGED
|
@@ -6,14 +6,11 @@ Commands in `assistant/src/cli/` are scoped to a **single running assistant inst
|
|
|
6
6
|
|
|
7
7
|
This contrasts with `cli/`, which manages the **lifecycle of assistant instances** (create, start, stop, delete) and operates across instances. See `cli/AGENTS.md`.
|
|
8
8
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
| Manages instance-local state (config, memory, etc.) | Manages lifecycle (create, start, stop, delete) |
|
|
15
|
-
| Implicitly scoped to the running assistant | Requires specifying which assistant to target |
|
|
16
|
-
| May require or start the daemon | Works without an assistant process running |
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
Commands here operate on a **single running assistant's** local state — config, memory, contacts, trust rules, conversations, autonomy, etc. They are implicitly scoped to the running assistant and may require or start the daemon.
|
|
12
|
+
|
|
13
|
+
For commands that manage the **lifecycle of assistant instances** (create, start, stop, delete), see `cli/AGENTS.md`.
|
|
17
14
|
|
|
18
15
|
Examples: `config`, `contacts`, `memory`, `autonomy`, `conversations`, `doctor` belong here. `hatch`, `wake`, `sleep`, `retire`, `ps`, `ssh` belong in `cli/`.
|
|
19
16
|
|
|
@@ -337,7 +337,7 @@ describe("notifications list", () => {
|
|
|
337
337
|
id: `evt-${Date.now()}-1`,
|
|
338
338
|
sourceEventName: "user.send_notification",
|
|
339
339
|
sourceChannel: "assistant_tool",
|
|
340
|
-
|
|
340
|
+
sourceContextId: "session-1",
|
|
341
341
|
attentionHints: {
|
|
342
342
|
requiresAction: true,
|
|
343
343
|
urgency: "medium",
|
|
@@ -362,7 +362,7 @@ describe("notifications list", () => {
|
|
|
362
362
|
id: `evt-limit-${Date.now()}-${i}`,
|
|
363
363
|
sourceEventName: "user.send_notification",
|
|
364
364
|
sourceChannel: "assistant_tool",
|
|
365
|
-
|
|
365
|
+
sourceContextId: `session-limit-${i}`,
|
|
366
366
|
attentionHints: {
|
|
367
367
|
requiresAction: true,
|
|
368
368
|
urgency: "medium",
|
|
@@ -386,7 +386,7 @@ describe("notifications list", () => {
|
|
|
386
386
|
id: `evt-filter-notif-${Date.now()}`,
|
|
387
387
|
sourceEventName: "user.send_notification",
|
|
388
388
|
sourceChannel: "assistant_tool",
|
|
389
|
-
|
|
389
|
+
sourceContextId: "session-filter-1",
|
|
390
390
|
attentionHints: {
|
|
391
391
|
requiresAction: true,
|
|
392
392
|
urgency: "medium",
|
|
@@ -400,7 +400,7 @@ describe("notifications list", () => {
|
|
|
400
400
|
id: `evt-filter-reminder-${Date.now()}`,
|
|
401
401
|
sourceEventName: "schedule.notify",
|
|
402
402
|
sourceChannel: "scheduler",
|
|
403
|
-
|
|
403
|
+
sourceContextId: "session-filter-2",
|
|
404
404
|
attentionHints: {
|
|
405
405
|
requiresAction: true,
|
|
406
406
|
urgency: "high",
|
|
@@ -430,7 +430,7 @@ describe("notifications list", () => {
|
|
|
430
430
|
id: `evt-custom-${Date.now()}`,
|
|
431
431
|
sourceEventName: "custom.my_event",
|
|
432
432
|
sourceChannel: "assistant_tool",
|
|
433
|
-
|
|
433
|
+
sourceContextId: "session-custom",
|
|
434
434
|
attentionHints: {
|
|
435
435
|
requiresAction: true,
|
|
436
436
|
urgency: "medium",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
|
|
4
4
|
import type { Command } from "commander";
|
|
@@ -9,6 +9,10 @@ import {
|
|
|
9
9
|
type CharacterTraits,
|
|
10
10
|
writeTraitsAndRenderAvatar,
|
|
11
11
|
} from "../../avatar/traits-png-sync.js";
|
|
12
|
+
import { setPlatformBaseUrl } from "../../config/env.js";
|
|
13
|
+
import { credentialKey } from "../../security/credential-key.js";
|
|
14
|
+
import { getSecureKeyAsync } from "../../security/secure-keys.js";
|
|
15
|
+
import { generateAndSaveAvatar } from "../../tools/system/avatar-generator.js";
|
|
12
16
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
13
17
|
import { log } from "../logger.js";
|
|
14
18
|
import { writeOutput } from "../output.js";
|
|
@@ -39,9 +43,67 @@ Files are stored in ~/.vellum/workspace/data/avatar/:
|
|
|
39
43
|
Examples:
|
|
40
44
|
$ assistant avatar character update --body-shape blob --eye-style curious --color green
|
|
41
45
|
$ assistant avatar character components
|
|
42
|
-
$ assistant avatar character ascii
|
|
46
|
+
$ assistant avatar character ascii
|
|
47
|
+
$ assistant avatar generate --description "a cute blue cat"`,
|
|
43
48
|
);
|
|
44
49
|
|
|
50
|
+
avatar
|
|
51
|
+
.command("generate")
|
|
52
|
+
.description("Generate an AI avatar from a text description")
|
|
53
|
+
.requiredOption(
|
|
54
|
+
"--description <text>",
|
|
55
|
+
"Description of the avatar to generate",
|
|
56
|
+
)
|
|
57
|
+
.addHelpText(
|
|
58
|
+
"after",
|
|
59
|
+
`
|
|
60
|
+
Generates an avatar image using AI based on the provided text description
|
|
61
|
+
and saves it as the assistant's avatar PNG. This replaces any existing
|
|
62
|
+
native character avatar — the character traits and ASCII files are removed.
|
|
63
|
+
|
|
64
|
+
On success, writes avatar-image.png to ~/.vellum/workspace/data/avatar/
|
|
65
|
+
and removes character-traits.json and character-ascii.txt if they exist.
|
|
66
|
+
|
|
67
|
+
Examples:
|
|
68
|
+
$ assistant avatar generate --description "a cute blue cat"
|
|
69
|
+
$ assistant avatar generate --description "a friendly robot with green eyes"`,
|
|
70
|
+
)
|
|
71
|
+
.action(async (opts: { description: string }) => {
|
|
72
|
+
// Rehydrate the platform base URL from the credential store so the
|
|
73
|
+
// managed proxy fallback works. The CLI runs as a separate process
|
|
74
|
+
// without the daemon's in-memory state.
|
|
75
|
+
try {
|
|
76
|
+
const key = credentialKey("vellum", "platform_base_url");
|
|
77
|
+
const persisted = await getSecureKeyAsync(key);
|
|
78
|
+
if (persisted) {
|
|
79
|
+
setPlatformBaseUrl(persisted);
|
|
80
|
+
}
|
|
81
|
+
} catch {
|
|
82
|
+
// Non-fatal — direct Gemini key may still work
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const result = await generateAndSaveAvatar(opts.description);
|
|
86
|
+
|
|
87
|
+
if (result.isError) {
|
|
88
|
+
log.error(result.content);
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Remove native character files since AI-generated image takes precedence
|
|
94
|
+
const avatarDir = join(getWorkspaceDir(), "data", "avatar");
|
|
95
|
+
const traitsPath = join(avatarDir, "character-traits.json");
|
|
96
|
+
const asciiPath = join(avatarDir, "character-ascii.txt");
|
|
97
|
+
try {
|
|
98
|
+
if (existsSync(traitsPath)) unlinkSync(traitsPath);
|
|
99
|
+
if (existsSync(asciiPath)) unlinkSync(asciiPath);
|
|
100
|
+
} catch {
|
|
101
|
+
// Best-effort cleanup
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
log.info(result.content);
|
|
105
|
+
});
|
|
106
|
+
|
|
45
107
|
const character = avatar
|
|
46
108
|
.command("character")
|
|
47
109
|
.description("Manage the native character avatar");
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
getQdrantUrlEnv,
|
|
5
|
+
getRuntimeHttpHost,
|
|
6
|
+
getRuntimeHttpPort,
|
|
7
|
+
} from "../../config/env.js";
|
|
4
8
|
import { getConfig } from "../../config/loader.js";
|
|
5
9
|
import { shouldAutoStartDaemon } from "../../daemon/connection-policy.js";
|
|
10
|
+
import { healthCheckHost, isHttpHealthy } from "../../daemon/daemon-control.js";
|
|
6
11
|
import { ensureDaemonRunning } from "../../daemon/lifecycle.js";
|
|
7
12
|
import { formatJson, formatMarkdown } from "../../export/formatter.js";
|
|
8
13
|
import {
|
|
@@ -10,13 +15,20 @@ import {
|
|
|
10
15
|
createConversation,
|
|
11
16
|
getConversation,
|
|
12
17
|
getMessages,
|
|
18
|
+
wipeConversation,
|
|
13
19
|
} from "../../memory/conversation-crud.js";
|
|
14
20
|
import { listConversations } from "../../memory/conversation-queries.js";
|
|
15
21
|
import {
|
|
16
22
|
selectEmbeddingBackend,
|
|
17
23
|
SPARSE_EMBEDDING_VERSION,
|
|
18
24
|
} from "../../memory/embedding-backend.js";
|
|
25
|
+
import { enqueueMemoryJob } from "../../memory/jobs-store.js";
|
|
19
26
|
import { initQdrantClient } from "../../memory/qdrant-client.js";
|
|
27
|
+
import {
|
|
28
|
+
initAuthSigningKey,
|
|
29
|
+
loadOrCreateSigningKey,
|
|
30
|
+
mintDaemonDeliveryToken,
|
|
31
|
+
} from "../../runtime/auth/token-service.js";
|
|
20
32
|
import { timeAgo } from "../../util/time.js";
|
|
21
33
|
import { initializeDb } from "../db.js";
|
|
22
34
|
import { log } from "../logger.js";
|
|
@@ -253,4 +265,122 @@ Examples:
|
|
|
253
265
|
|
|
254
266
|
log.info("Done.");
|
|
255
267
|
});
|
|
268
|
+
|
|
269
|
+
conversations
|
|
270
|
+
.command("wipe <conversationId>")
|
|
271
|
+
.description("Wipe a conversation and revert all memory changes it made")
|
|
272
|
+
.option("-y, --yes", "Skip confirmation prompt")
|
|
273
|
+
.addHelpText(
|
|
274
|
+
"after",
|
|
275
|
+
`
|
|
276
|
+
Arguments:
|
|
277
|
+
conversationId Conversation ID (or unique prefix). Supports prefix matching.
|
|
278
|
+
|
|
279
|
+
Permanently wipes the conversation and reverts all memory changes it caused:
|
|
280
|
+
restores superseded memory items, deletes conversation summaries, and cancels
|
|
281
|
+
pending memory jobs. This action cannot be undone.
|
|
282
|
+
|
|
283
|
+
Examples:
|
|
284
|
+
$ assistant conversations wipe abc123
|
|
285
|
+
$ assistant conversations wipe abc123 --yes`,
|
|
286
|
+
)
|
|
287
|
+
.action(async (conversationId: string, opts?: { yes?: boolean }) => {
|
|
288
|
+
initializeDb();
|
|
289
|
+
|
|
290
|
+
// Resolve conversation with prefix matching (same pattern as `export`)
|
|
291
|
+
let conversation = getConversation(conversationId);
|
|
292
|
+
if (!conversation) {
|
|
293
|
+
const all = listConversations(Number.MAX_SAFE_INTEGER);
|
|
294
|
+
const match = all.find((c) => c.id.startsWith(conversationId));
|
|
295
|
+
if (match) {
|
|
296
|
+
conversation = match;
|
|
297
|
+
} else {
|
|
298
|
+
log.error(`Conversation not found: ${conversationId}`);
|
|
299
|
+
process.exit(1);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!opts?.yes) {
|
|
304
|
+
const readline = await import("node:readline");
|
|
305
|
+
const rl = readline.createInterface({
|
|
306
|
+
input: process.stdin,
|
|
307
|
+
output: process.stdout,
|
|
308
|
+
});
|
|
309
|
+
const answer = await new Promise<string>((resolve) => {
|
|
310
|
+
rl.question(
|
|
311
|
+
`Wipe conversation "${conversation!.title ?? "Untitled"}" and revert all memory changes? (y/N) `,
|
|
312
|
+
resolve,
|
|
313
|
+
);
|
|
314
|
+
});
|
|
315
|
+
rl.close();
|
|
316
|
+
if (answer.toLowerCase() !== "y") {
|
|
317
|
+
log.info("Cancelled");
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// When the assistant is running, delegate to its HTTP wipe endpoint
|
|
323
|
+
// so it tears down in-memory conversation state before deleting DB
|
|
324
|
+
// rows — preventing FK constraint failures from follow-up writes.
|
|
325
|
+
if (await isHttpHealthy()) {
|
|
326
|
+
const port = getRuntimeHttpPort();
|
|
327
|
+
const host = healthCheckHost(getRuntimeHttpHost());
|
|
328
|
+
initAuthSigningKey(loadOrCreateSigningKey());
|
|
329
|
+
const token = mintDaemonDeliveryToken();
|
|
330
|
+
const res = await fetch(
|
|
331
|
+
`http://${host}:${port}/v1/conversations/${conversation.id}/wipe`,
|
|
332
|
+
{
|
|
333
|
+
method: "POST",
|
|
334
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
335
|
+
},
|
|
336
|
+
);
|
|
337
|
+
if (!res.ok) {
|
|
338
|
+
const body = await res.text();
|
|
339
|
+
log.error(`Assistant wipe failed (${res.status}): ${body}`);
|
|
340
|
+
process.exit(1);
|
|
341
|
+
}
|
|
342
|
+
const json = (await res.json()) as {
|
|
343
|
+
unsupersededItems: number;
|
|
344
|
+
deletedSummaries: number;
|
|
345
|
+
cancelledJobs: number;
|
|
346
|
+
};
|
|
347
|
+
log.info(
|
|
348
|
+
`Wiped conversation "${conversation.title ?? "Untitled"}". ` +
|
|
349
|
+
`Restored ${json.unsupersededItems} memory items, ` +
|
|
350
|
+
`deleted ${json.deletedSummaries} summaries, ` +
|
|
351
|
+
`cancelled ${json.cancelledJobs} jobs.`,
|
|
352
|
+
);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Daemon not running — safe to wipe directly (no in-memory state).
|
|
357
|
+
const result = wipeConversation(conversation.id);
|
|
358
|
+
|
|
359
|
+
// Enqueue Qdrant cleanup
|
|
360
|
+
for (const segId of result.segmentIds) {
|
|
361
|
+
enqueueMemoryJob("delete_qdrant_vectors", {
|
|
362
|
+
targetType: "segment",
|
|
363
|
+
targetId: segId,
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
for (const itemId of result.orphanedItemIds) {
|
|
367
|
+
enqueueMemoryJob("delete_qdrant_vectors", {
|
|
368
|
+
targetType: "item",
|
|
369
|
+
targetId: itemId,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
for (const summaryId of result.deletedSummaryIds) {
|
|
373
|
+
enqueueMemoryJob("delete_qdrant_vectors", {
|
|
374
|
+
targetType: "summary",
|
|
375
|
+
targetId: summaryId,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
log.info(
|
|
380
|
+
`Wiped conversation "${conversation.title ?? "Untitled"}". ` +
|
|
381
|
+
`Restored ${result.unsupersededItemIds.length} memory items, ` +
|
|
382
|
+
`deleted ${result.deletedSummaryIds.length} summaries, ` +
|
|
383
|
+
`cancelled ${result.cancelledJobCount} jobs.`,
|
|
384
|
+
);
|
|
385
|
+
});
|
|
256
386
|
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
fetchManagedCatalog,
|
|
5
5
|
type ManagedCredentialDescriptor,
|
|
6
6
|
} from "../../credential-execution/managed-catalog.js";
|
|
7
|
+
import { syncManualTokenConnection } from "../../oauth/manual-token-connection.js";
|
|
7
8
|
import {
|
|
8
9
|
disconnectOAuthProvider,
|
|
9
10
|
getConnectionByProvider,
|
|
@@ -439,6 +440,7 @@ Examples:
|
|
|
439
440
|
usageDescription: opts.description,
|
|
440
441
|
allowedTools,
|
|
441
442
|
});
|
|
443
|
+
await syncManualTokenConnection(service);
|
|
442
444
|
|
|
443
445
|
writeOutput(cmd, {
|
|
444
446
|
ok: true,
|
|
@@ -252,12 +252,12 @@ Examples:
|
|
|
252
252
|
|
|
253
253
|
initializeDb();
|
|
254
254
|
|
|
255
|
-
const
|
|
255
|
+
const sourceContextId = opts.conversationId ?? `cli-${Date.now()}`;
|
|
256
256
|
|
|
257
257
|
const result = await emitNotificationSignal({
|
|
258
258
|
sourceEventName: opts.sourceEventName,
|
|
259
259
|
sourceChannel: opts.sourceChannel,
|
|
260
|
-
|
|
260
|
+
sourceContextId,
|
|
261
261
|
attentionHints: {
|
|
262
262
|
requiresAction: opts.requiresAction ?? true,
|
|
263
263
|
urgency,
|
|
@@ -374,7 +374,7 @@ Examples:
|
|
|
374
374
|
id: row.id,
|
|
375
375
|
sourceEventName: row.sourceEventName,
|
|
376
376
|
sourceChannel: row.sourceChannel,
|
|
377
|
-
|
|
377
|
+
sourceContextId: row.sourceContextId,
|
|
378
378
|
urgency: (JSON.parse(row.attentionHintsJson) as { urgency: string })
|
|
379
379
|
.urgency,
|
|
380
380
|
dedupeKey: row.dedupeKey,
|
package/src/cli.ts
CHANGED
|
@@ -160,6 +160,7 @@ export async function startCli(): Promise<void> {
|
|
|
160
160
|
let pendingConfirmation = false;
|
|
161
161
|
let pendingCopySession = false;
|
|
162
162
|
let toolStreaming = false;
|
|
163
|
+
let lastDisplayedError: string | null = null;
|
|
163
164
|
let eventSubscription: EventStreamWatcher | null = null;
|
|
164
165
|
const spinner = new Spinner();
|
|
165
166
|
|
|
@@ -842,6 +843,14 @@ export async function startCli(): Promise<void> {
|
|
|
842
843
|
renderConfirmationPrompt(msg);
|
|
843
844
|
break;
|
|
844
845
|
|
|
846
|
+
case "conversation_error":
|
|
847
|
+
spinner.stop();
|
|
848
|
+
if (lastDisplayedError !== msg.userMessage) {
|
|
849
|
+
process.stdout.write(`\n[Error: ${msg.userMessage}]\n`);
|
|
850
|
+
}
|
|
851
|
+
lastDisplayedError = null;
|
|
852
|
+
break;
|
|
853
|
+
|
|
845
854
|
case "error":
|
|
846
855
|
spinner.stop();
|
|
847
856
|
generating = false;
|
|
@@ -852,6 +861,7 @@ export async function startCli(): Promise<void> {
|
|
|
852
861
|
rl.removeAllListeners("line");
|
|
853
862
|
rl.on("line", handleLine);
|
|
854
863
|
}
|
|
864
|
+
lastDisplayedError = msg.message;
|
|
855
865
|
process.stdout.write(`\n[Error: ${msg.message}]\n`);
|
|
856
866
|
prompt();
|
|
857
867
|
break;
|
|
@@ -8,7 +8,7 @@ metadata:
|
|
|
8
8
|
display-name: "ACP"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
ACP agent orchestration
|
|
11
|
+
ACP agent orchestration - spawn external coding agents (Claude Code, Codex, Gemini CLI, etc.) to work on tasks via the Agent Client Protocol.
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
@@ -40,13 +40,13 @@ When the user first tries to use ACP and it's not configured, set it up automati
|
|
|
40
40
|
}
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
3. **Wait a few seconds** for the config watcher to pick up the change (it hot-reloads automatically
|
|
43
|
+
3. **Wait a few seconds** for the config watcher to pick up the change (it hot-reloads automatically - no restart needed).
|
|
44
44
|
|
|
45
|
-
4. Then retry the `acp_spawn` call. Do NOT run `vellum sleep && vellum wake`
|
|
45
|
+
4. Then retry the `acp_spawn` call. Do NOT run `vellum sleep && vellum wake` - that kills the conversation.
|
|
46
46
|
|
|
47
47
|
## Critical: correct agent command
|
|
48
48
|
|
|
49
|
-
- The command MUST be `claude-agent-acp`
|
|
49
|
+
- The command MUST be `claude-agent-acp` - this is the ACP adapter from `@zed-industries/claude-agent-acp`.
|
|
50
50
|
- NEVER use `claude`, `claude -p`, `claude --acp`, or any other command. Only `claude-agent-acp` speaks the ACP JSON-RPC protocol.
|
|
51
51
|
- NEVER change an existing ACP config to use a different command. If the config already has `claude-agent-acp`, leave it alone.
|
|
52
52
|
|
|
@@ -55,4 +55,4 @@ When the user first tries to use ACP and it's not configured, set it up automati
|
|
|
55
55
|
- The spawned agent runs autonomously with its own tools, file editing, and terminal access.
|
|
56
56
|
- Results are streamed back and injected into the conversation when the agent completes.
|
|
57
57
|
- Use `acp_status` to check on running agents and `acp_abort` to stop them.
|
|
58
|
-
- The `cwd` parameter controls where the agent works
|
|
58
|
+
- The `cwd` parameter controls where the agent works - set it to the project root the user wants the agent to operate in.
|