@vellumai/assistant 0.4.10 → 0.4.12

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.
Files changed (203) hide show
  1. package/ARCHITECTURE.md +418 -378
  2. package/Dockerfile +1 -1
  3. package/README.md +16 -9
  4. package/package.json +1 -1
  5. package/src/__tests__/account-registry.test.ts +1 -0
  6. package/src/__tests__/actor-token-service.test.ts +1 -0
  7. package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
  8. package/src/__tests__/asset-materialize-tool.test.ts +7 -0
  9. package/src/__tests__/asset-search-tool.test.ts +7 -0
  10. package/src/__tests__/browser-fill-credential.test.ts +1 -0
  11. package/src/__tests__/call-start-guardian-guard.test.ts +1 -0
  12. package/src/__tests__/channel-approval-routes.test.ts +29 -0
  13. package/src/__tests__/channel-guardian.test.ts +2143 -1546
  14. package/src/__tests__/channel-retry-sweep.test.ts +169 -14
  15. package/src/__tests__/claude-code-tool-profiles.test.ts +1 -0
  16. package/src/__tests__/computer-use-tools.test.ts +1 -0
  17. package/src/__tests__/contacts-tools.test.ts +1 -0
  18. package/src/__tests__/conversation-attention-telegram.test.ts +1 -0
  19. package/src/__tests__/credential-policy-validate.test.ts +97 -0
  20. package/src/__tests__/credential-security-e2e.test.ts +1 -0
  21. package/src/__tests__/credential-vault-unit.test.ts +1 -0
  22. package/src/__tests__/credential-vault.test.ts +1 -0
  23. package/src/__tests__/delete-managed-skill-tool.test.ts +1 -0
  24. package/src/__tests__/file-edit-tool.test.ts +1 -0
  25. package/src/__tests__/file-read-tool.test.ts +1 -0
  26. package/src/__tests__/file-write-tool.test.ts +1 -0
  27. package/src/__tests__/followup-tools.test.ts +1 -0
  28. package/src/__tests__/gateway-only-guard.test.ts +1 -1
  29. package/src/__tests__/guardian-control-plane-policy.test.ts +5 -4
  30. package/src/__tests__/guardian-grant-minting.test.ts +3 -0
  31. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +4 -3
  32. package/src/__tests__/guardian-routing-state.test.ts +8 -0
  33. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +75 -61
  34. package/src/__tests__/headless-browser-interactions.test.ts +1 -0
  35. package/src/__tests__/headless-browser-navigate.test.ts +1 -0
  36. package/src/__tests__/headless-browser-read-tools.test.ts +1 -0
  37. package/src/__tests__/headless-browser-snapshot.test.ts +1 -0
  38. package/src/__tests__/host-file-edit-tool.test.ts +1 -0
  39. package/src/__tests__/host-file-read-tool.test.ts +1 -0
  40. package/src/__tests__/host-file-write-tool.test.ts +1 -0
  41. package/src/__tests__/host-shell-tool.test.ts +1 -0
  42. package/src/__tests__/lifecycle-docs-guard.test.ts +207 -0
  43. package/src/__tests__/managed-skill-lifecycle.test.ts +1 -0
  44. package/src/__tests__/media-reuse-story.e2e.test.ts +8 -0
  45. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  46. package/src/__tests__/playbook-execution.test.ts +1 -0
  47. package/src/__tests__/playbook-tools.test.ts +1 -0
  48. package/src/__tests__/registry.test.ts +235 -187
  49. package/src/__tests__/relay-server.test.ts +4 -0
  50. package/src/__tests__/scaffold-managed-skill-tool.test.ts +1 -0
  51. package/src/__tests__/schedule-tools.test.ts +1 -0
  52. package/src/__tests__/secret-onetime-send.test.ts +4 -0
  53. package/src/__tests__/secret-scanner-executor.test.ts +2 -0
  54. package/src/__tests__/secure-keys.test.ts +27 -0
  55. package/src/__tests__/send-notification-tool.test.ts +2 -0
  56. package/src/__tests__/session-agent-loop.test.ts +521 -256
  57. package/src/__tests__/session-surfaces-task-progress.test.ts +1 -0
  58. package/src/__tests__/session-tool-setup-app-refresh.test.ts +1 -0
  59. package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -0
  60. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -0
  61. package/src/__tests__/shell-credential-ref.test.ts +1 -0
  62. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -0
  63. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  64. package/src/__tests__/skill-load-tool.test.ts +1 -0
  65. package/src/__tests__/skill-script-runner-host.test.ts +1 -0
  66. package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -0
  67. package/src/__tests__/skill-script-runner.test.ts +1 -0
  68. package/src/__tests__/skill-tool-factory.test.ts +1 -0
  69. package/src/__tests__/skills.test.ts +334 -276
  70. package/src/__tests__/starter-task-flow.test.ts +7 -17
  71. package/src/__tests__/subagent-tools.test.ts +1 -1
  72. package/src/__tests__/swarm-recursion.test.ts +1 -0
  73. package/src/__tests__/swarm-session-integration.test.ts +1 -0
  74. package/src/__tests__/swarm-tool.test.ts +1 -0
  75. package/src/__tests__/task-management-tools.test.ts +1 -0
  76. package/src/__tests__/task-tools.test.ts +1 -0
  77. package/src/__tests__/terminal-tools.test.ts +1 -0
  78. package/src/__tests__/tool-approval-handler.test.ts +2 -2
  79. package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -0
  80. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
  81. package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -0
  82. package/src/__tests__/tool-executor-shell-integration.test.ts +1 -0
  83. package/src/__tests__/tool-executor.test.ts +1 -0
  84. package/src/__tests__/trust-context-guards.test.ts +218 -0
  85. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +6 -0
  86. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +6 -0
  87. package/src/__tests__/trusted-contact-multichannel.test.ts +1 -0
  88. package/src/__tests__/trusted-contact-verification.test.ts +1 -0
  89. package/src/__tests__/view-image-tool.test.ts +1 -0
  90. package/src/agent/loop.ts +9 -2
  91. package/src/calls/guardian-dispatch.ts +4 -4
  92. package/src/cli/mcp.ts +183 -3
  93. package/src/config/bundled-skills/agentmail/SKILL.md +4 -4
  94. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +449 -0
  95. package/src/config/bundled-skills/doordash/SKILL.md +171 -0
  96. package/src/config/bundled-skills/doordash/__tests__/doordash-client.test.ts +203 -0
  97. package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +164 -0
  98. package/src/config/bundled-skills/doordash/doordash-cli.ts +1193 -0
  99. package/src/config/bundled-skills/doordash/doordash-entry.ts +22 -0
  100. package/src/config/bundled-skills/doordash/lib/cart-queries.ts +787 -0
  101. package/src/config/bundled-skills/doordash/lib/client.ts +1071 -0
  102. package/src/config/bundled-skills/doordash/lib/order-queries.ts +85 -0
  103. package/src/config/bundled-skills/doordash/lib/queries.ts +28 -0
  104. package/src/config/bundled-skills/doordash/lib/query-extractor.ts +94 -0
  105. package/src/config/bundled-skills/doordash/lib/search-queries.ts +203 -0
  106. package/src/config/bundled-skills/doordash/lib/session.ts +93 -0
  107. package/src/config/bundled-skills/doordash/lib/shared/errors.ts +61 -0
  108. package/src/config/bundled-skills/doordash/lib/shared/ipc.ts +32 -0
  109. package/src/config/bundled-skills/doordash/lib/shared/network-recorder.ts +380 -0
  110. package/src/config/bundled-skills/doordash/lib/shared/platform.ts +35 -0
  111. package/src/config/bundled-skills/doordash/lib/shared/recording-store.ts +43 -0
  112. package/src/config/bundled-skills/doordash/lib/shared/recording-types.ts +49 -0
  113. package/src/config/bundled-skills/doordash/lib/shared/truncate.ts +6 -0
  114. package/src/config/bundled-skills/doordash/lib/store-queries.ts +246 -0
  115. package/src/config/bundled-skills/doordash/lib/types.ts +367 -0
  116. package/src/config/bundled-skills/google-calendar/SKILL.md +4 -5
  117. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +42 -41
  118. package/src/config/bundled-skills/messaging/SKILL.md +59 -42
  119. package/src/config/bundled-skills/messaging/TOOLS.json +2 -2
  120. package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +5 -1
  121. package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +11 -2
  122. package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +10 -3
  123. package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +5 -1
  124. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +5 -1
  125. package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +2 -1
  126. package/src/config/bundled-skills/notion/SKILL.md +240 -0
  127. package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +127 -0
  128. package/src/config/bundled-skills/oauth-setup/SKILL.md +144 -0
  129. package/src/config/bundled-skills/phone-calls/SKILL.md +91 -162
  130. package/src/config/bundled-skills/skills-catalog/SKILL.md +32 -29
  131. package/src/config/{vellum-skills → bundled-skills}/sms-setup/SKILL.md +29 -22
  132. package/src/config/{vellum-skills → bundled-skills}/telegram-setup/SKILL.md +17 -14
  133. package/src/config/{vellum-skills → bundled-skills}/twilio-setup/SKILL.md +21 -6
  134. package/src/config/bundled-tool-registry.ts +281 -267
  135. package/src/config/system-prompt.ts +4 -2
  136. package/src/daemon/computer-use-session.ts +1 -0
  137. package/src/daemon/handlers/skills.ts +334 -234
  138. package/src/daemon/ipc-contract/messages.ts +2 -0
  139. package/src/daemon/ipc-contract/surfaces.ts +2 -0
  140. package/src/daemon/lifecycle.ts +358 -221
  141. package/src/daemon/response-tier.ts +2 -0
  142. package/src/daemon/server.ts +453 -193
  143. package/src/daemon/session-agent-loop-handlers.ts +42 -2
  144. package/src/daemon/session-agent-loop.ts +4 -1
  145. package/src/daemon/session-lifecycle.ts +3 -0
  146. package/src/daemon/session-memory.ts +2 -2
  147. package/src/daemon/session-process.ts +1 -0
  148. package/src/daemon/session-runtime-assembly.ts +2 -2
  149. package/src/daemon/session-surfaces.ts +22 -20
  150. package/src/daemon/session-tool-setup.ts +2 -1
  151. package/src/daemon/session.ts +5 -2
  152. package/src/mcp/client.ts +55 -6
  153. package/src/mcp/manager.ts +9 -0
  154. package/src/mcp/mcp-oauth-provider.ts +347 -0
  155. package/src/memory/channel-delivery-store.ts +1 -0
  156. package/src/memory/db-init.ts +4 -0
  157. package/src/memory/delivery-status.ts +43 -0
  158. package/src/memory/guardian-bindings.ts +3 -3
  159. package/src/memory/migrations/127-guardian-principal-id-not-null.ts +108 -0
  160. package/src/memory/migrations/index.ts +1 -0
  161. package/src/memory/migrations/registry.ts +6 -0
  162. package/src/memory/schema.ts +1 -1
  163. package/src/messaging/outreach-classifier.ts +12 -5
  164. package/src/messaging/provider-types.ts +2 -0
  165. package/src/messaging/providers/gmail/adapter.ts +9 -3
  166. package/src/messaging/providers/gmail/client.ts +2 -0
  167. package/src/runtime/actor-trust-resolver.ts +13 -4
  168. package/src/runtime/channel-retry-sweep.ts +31 -14
  169. package/src/runtime/guardian-context-resolver.ts +25 -64
  170. package/src/runtime/guardian-outbound-actions.ts +399 -108
  171. package/src/runtime/guardian-vellum-migration.ts +1 -23
  172. package/src/runtime/guardian-verification-templates.ts +66 -30
  173. package/src/runtime/http-errors.ts +33 -20
  174. package/src/runtime/http-server.ts +706 -291
  175. package/src/runtime/http-types.ts +26 -16
  176. package/src/runtime/local-actor-identity.ts +4 -6
  177. package/src/runtime/middleware/actor-token.ts +2 -8
  178. package/src/runtime/routes/channel-route-shared.ts +0 -1
  179. package/src/runtime/routes/inbound-message-handler.ts +3 -4
  180. package/src/runtime/routes/secret-routes.ts +57 -2
  181. package/src/runtime/routes/surface-action-routes.ts +66 -0
  182. package/src/runtime/routes/trust-rules-routes.ts +140 -0
  183. package/src/runtime/tool-grant-request-helper.ts +1 -1
  184. package/src/security/keychain-to-encrypted-migration.ts +59 -0
  185. package/src/security/secure-keys.ts +17 -0
  186. package/src/skills/frontmatter.ts +9 -7
  187. package/src/tools/apps/executors.ts +2 -1
  188. package/src/tools/credentials/policy-validate.ts +22 -0
  189. package/src/tools/guardian-control-plane-policy.ts +2 -2
  190. package/src/tools/tool-manifest.ts +44 -42
  191. package/src/tools/types.ts +10 -1
  192. package/src/__tests__/skill-mirror-parity.test.ts +0 -176
  193. package/src/config/vellum-skills/catalog.json +0 -63
  194. package/src/config/vellum-skills/chatgpt-import/tools/chatgpt-import.ts +0 -295
  195. package/src/skills/vellum-catalog-remote.ts +0 -166
  196. package/src/tools/skills/vellum-catalog.ts +0 -168
  197. /package/src/config/{vellum-skills → bundled-skills}/chatgpt-import/SKILL.md +0 -0
  198. /package/src/config/{vellum-skills → bundled-skills}/chatgpt-import/TOOLS.json +0 -0
  199. /package/src/config/{vellum-skills → bundled-skills}/deploy-fullstack-vercel/SKILL.md +0 -0
  200. /package/src/config/{vellum-skills → bundled-skills}/document-writer/SKILL.md +0 -0
  201. /package/src/config/{vellum-skills → bundled-skills}/guardian-verify-setup/SKILL.md +0 -0
  202. /package/src/config/{vellum-skills → bundled-skills}/slack-oauth-setup/SKILL.md +0 -0
  203. /package/src/config/{vellum-skills → bundled-skills}/trusted-contacts/SKILL.md +0 -0
@@ -2,30 +2,12 @@
2
2
  name: "Phone Calls"
3
3
  description: "Set up Twilio for AI-powered voice calls — both outgoing calls on behalf of the user and incoming calls where the assistant answers as a receptionist"
4
4
  user-invocable: true
5
- metadata: {"vellum": {"emoji": "📞", "requires": {"config": ["calls.enabled"]}}}
5
+ metadata:
6
+ { "vellum": { "emoji": "📞", "requires": { "config": ["calls.enabled"] } } }
6
7
  includes: ["public-ingress"]
7
8
  ---
8
9
 
9
- You are helping the user set up and manage phone calls via Twilio. This skill covers the full lifecycle: Twilio account setup, credential storage, public ingress configuration, enabling the calls feature, placing outbound calls, receiving inbound calls, and monitoring live transcripts.
10
-
11
- ## Prerequisites — Shared Twilio Setup
12
-
13
- Twilio credentials and phone number configuration are shared between voice calls and SMS messaging. If Twilio is not yet configured, install and load the **twilio-setup** skill first:
14
-
15
- - Call `vellum_skills_catalog` with `action: "install"`, `skill_id: "twilio-setup"`, and `overwrite: true` (so it succeeds even if already installed).
16
- - Then call `skill_load` with `skill: "twilio-setup"`.
17
-
18
- The twilio-setup skill handles credential storage, phone number provisioning/assignment, and public ingress setup. Once complete, return here to enable the calls feature and start making calls.
19
-
20
- Check if Twilio is already configured:
21
-
22
- ```bash
23
- TOKEN=$(cat ~/.vellum/http-token)
24
- curl -s "$INTERNAL_GATEWAY_BASE_URL/v1/integrations/twilio/config" \
25
- -H "Authorization: Bearer $TOKEN"
26
- ```
27
-
28
- If `hasCredentials` is `true` and `phoneNumber` is set, skip directly to **Step 5: Enable Calls** below.
10
+ You are helping the user set up and manage phone calls via Twilio. This skill covers enabling the calls feature, placing outbound calls, receiving inbound calls, and interacting with live calls. Twilio credential storage, phone number provisioning, and public ingress are handled by the **twilio-setup** skill.
29
11
 
30
12
  ## Overview
31
13
 
@@ -39,7 +21,7 @@ When a call is placed:
39
21
  2. Twilio connects to the gateway's voice webhook, which returns TwiML
40
22
  3. Twilio opens a ConversationRelay WebSocket for real-time voice streaming
41
23
  4. An LLM-driven orchestrator manages the conversation — receiving caller speech (transcribed by Deepgram), generating responses via Claude, and streaming text back for TTS playback
42
- 5. The transcript is relayed live to the user's conversation thread
24
+ 5. The full transcript is stored in the database for later retrieval
43
25
 
44
26
  ### Inbound calls
45
27
 
@@ -53,6 +35,7 @@ When someone dials the assistant's Twilio phone number:
53
35
  6. The assistant converses naturally, using ASK_GUARDIAN to consult the user when needed, just like outbound calls.
54
36
 
55
37
  Three voice quality modes are available:
38
+
56
39
  - **`twilio_standard`** (default) — Fully supported. Standard Twilio TTS with Google voices. No extra setup required.
57
40
  - **`twilio_elevenlabs_tts`** — Fully supported. Uses ElevenLabs voices through Twilio ConversationRelay for more natural speech.
58
41
  - **`elevenlabs_agent`** — **Experimental/restricted.** Full ElevenLabs conversational agent mode. Consultation bridging (`waiting_on_user`) is not yet supported in this mode; the runtime guard blocks it before any ElevenLabs API calls are made. See the "Runtime behavior" section below for fallback and strict-fail details.
@@ -61,9 +44,9 @@ You can keep using Twilio only — no changes needed. Enabling ElevenLabs can im
61
44
 
62
45
  The user's assistant gets its own personal phone number through Twilio. All implicit calls (without an explicit mode) always use this assistant number. Optionally, users can call from their own phone number if it's authorized with the Twilio account — this must be explicitly requested per call via `caller_identity_mode="user_number"`.
63
46
 
64
- ## Step 1: Check Current Configuration
47
+ ## Step 1: Verify Twilio Setup
65
48
 
66
- First, check whether Twilio is already configured:
49
+ Check whether Twilio credentials, phone number, and public ingress are already configured:
67
50
 
68
51
  ```bash
69
52
  TOKEN=$(cat ~/.vellum/http-token)
@@ -71,73 +54,19 @@ curl -s "$INTERNAL_GATEWAY_BASE_URL/v1/integrations/twilio/config" \
71
54
  -H "Authorization: Bearer $TOKEN"
72
55
  ```
73
56
 
74
- Also check calls feature status:
75
-
76
57
  ```bash
77
58
  vellum config get calls.enabled
78
59
  ```
79
60
 
80
- If the config response shows `hasCredentials: true` and `phoneNumber` is set, and `calls.enabled` is `true`, skip to the **Making Calls** section. If credentials are partially configured, skip to whichever step is still needed.
81
-
82
- ## Step 2: Create a Twilio Account
83
-
84
- If the user doesn't have a Twilio account yet, guide them through setup:
85
-
86
- 1. Tell the user: **"You'll need a Twilio account to make phone calls. Sign up at https://www.twilio.com/try-twilio — it's free to start and includes trial credit."**
87
- 2. Once they have an account, they need two pieces of information:
88
- - **Account SID** — found on the Twilio Console dashboard at https://console.twilio.com
89
- - **Auth Token** — found on the same dashboard (click "Show" to reveal it)
90
-
91
- Tell the user: **"The assistant will get its own personal phone number through Twilio — the number that shows up on caller ID when calls are placed."**
92
-
93
- ## Step 3: Store Twilio Credentials
94
-
95
- **IMPORTANT — Secure credential collection only:** Never use credentials pasted in plaintext chat. Always collect credentials through the secure credential prompt flow:
96
-
97
- - Call `credential_store` with `action: "prompt"`, `service: "twilio"`, `field: "account_sid"`, `label: "Twilio Account SID"`, `description: "Enter your Account SID from the Twilio Console dashboard"`, and `placeholder: "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"`.
98
- - Call `credential_store` with `action: "prompt"`, `service: "twilio"`, `field: "auth_token"`, `label: "Twilio Auth Token"`, `description: "Enter your Auth Token from the Twilio Console dashboard"`, and `placeholder: "your_auth_token"`.
99
-
100
- After both credentials are collected, send them to the gateway:
101
-
102
- ```bash
103
- TOKEN=$(cat ~/.vellum/http-token)
104
- curl -s -X POST "$INTERNAL_GATEWAY_BASE_URL/v1/integrations/twilio/credentials" \
105
- -H "Authorization: Bearer $TOKEN" \
106
- -H "Content-Type: application/json" \
107
- -d '{"accountSid":"<value from credential_store for twilio/account_sid>","authToken":"<value from credential_store for twilio/auth_token>"}'
108
- ```
109
-
110
- The endpoint validates the credentials against the Twilio API before storing them. If credentials are invalid, ask the user to re-enter via the secure prompt.
111
-
112
- **Important:** Credentials are stored in the OS keychain (macOS Keychain / Linux secret-service) or encrypted at rest. They are never logged or exposed in plaintext.
113
-
114
- ## Step 4: Set Up Public Ingress
115
-
116
- Twilio needs a publicly reachable URL to send voice webhooks and establish the ConversationRelay WebSocket. The **public-ingress** skill handles this via ngrok.
117
-
118
- Check if ingress is already configured:
119
-
120
- ```bash
121
- vellum config get ingress.publicBaseUrl
122
- vellum config get ingress.enabled
123
- ```
124
-
125
- If not configured, load and run the public-ingress skill:
61
+ If `hasCredentials` is `true`, `phoneNumber` is set, and `calls.enabled` is `true`, skip to the **Making Outbound Calls** section.
126
62
 
127
- ```
128
- skill_load skill=public-ingress
129
- ```
130
-
131
- Follow the public-ingress skill's instructions to set up the ngrok tunnel. Once complete, the gateway will be reachable at the configured `ingress.publicBaseUrl`.
63
+ If Twilio is not yet configured, load the **twilio-setup** skill — it handles credential storage, phone number provisioning, and public ingress setup:
132
64
 
133
- **Twilio needs these webhook endpoints (handled automatically by the gateway):**
134
- - Voice webhook: `{publicBaseUrl}/webhooks/twilio/voice`
135
- - Status callback: `{publicBaseUrl}/webhooks/twilio/status`
136
- - ConversationRelay WebSocket: `{publicBaseUrl}/webhooks/twilio/relay` (wss://)
65
+ - Call `skill_load` with `skill_id: "twilio-setup"` to load the dependency skill.
137
66
 
138
- No manual Twilio webhook configuration is needed — the assistant registers webhook URLs dynamically when placing each call.
67
+ Once twilio-setup completes, return here to enable calls.
139
68
 
140
- ## Step 5: Enable Calls
69
+ ## Step 2: Enable Calls
141
70
 
142
71
  Enable the calls feature:
143
72
 
@@ -146,11 +75,12 @@ vellum config set calls.enabled true
146
75
  ```
147
76
 
148
77
  Verify:
78
+
149
79
  ```bash
150
80
  vellum config get calls.enabled
151
81
  ```
152
82
 
153
- ## Step 6: Verify Setup (Test Call)
83
+ ## Step 3: Verify Setup (Test Call)
154
84
 
155
85
  Before making real calls, offer a quick verification:
156
86
 
@@ -176,14 +106,14 @@ If the user wants a specific call to appear as coming from their own phone numbe
176
106
  credential_store action=store service=twilio field=user_phone_number value=+14155559999
177
107
  ```
178
108
 
179
- **To use it for a specific call**, pass `caller_identity_mode: 'user_number'` when calling `call_start` — see the Making Calls section for examples. User-number mode cannot be set as a global default; it must be requested explicitly per call.
109
+ **To use it for a specific call**, pass `caller_identity_mode: 'user_number'` when calling `call_start` — see the Making Outbound Calls section for examples. User-number mode cannot be set as a global default; it must be requested explicitly per call.
180
110
 
181
111
  ### Configuration reference
182
112
 
183
- | Setting | Description | Default |
184
- |---|---|---|
185
- | `calls.callerIdentity.allowPerCallOverride` | Whether per-call mode selection is allowed | `true` |
186
- | `calls.callerIdentity.userNumber` | Optional E.164 phone number for user-number mode (alternative to storing via `credential_store`) | *(empty)* |
113
+ | Setting | Description | Default |
114
+ | ------------------------------------------- | ------------------------------------------------------------------------------------------------ | --------- |
115
+ | `calls.callerIdentity.allowPerCallOverride` | Whether per-call mode selection is allowed | `true` |
116
+ | `calls.callerIdentity.userNumber` | Optional E.164 phone number for user-number mode (alternative to storing via `credential_store`) | _(empty)_ |
187
117
 
188
118
  ## DTMF Callee Verification
189
119
 
@@ -199,10 +129,10 @@ An optional verification step where the callee must enter a numeric code via the
199
129
 
200
130
  ### Configuration
201
131
 
202
- | Setting | Description | Default |
203
- |---|---|---|
204
- | `calls.verification.enabled` | Enable DTMF callee verification | `false` |
205
- | `calls.verification.codeLength` | Number of digits in the verification code | `6` |
132
+ | Setting | Description | Default |
133
+ | ------------------------------- | ----------------------------------------- | ------- |
134
+ | `calls.verification.enabled` | Enable DTMF callee verification | `false` |
135
+ | `calls.verification.codeLength` | Number of digits in the verification code | `6` |
206
136
 
207
137
  ## Optional: Higher Quality Voice with ElevenLabs
208
138
 
@@ -290,6 +220,7 @@ vellum config set calls.voice.mode twilio_standard
290
220
  ## Making Outbound Calls
291
221
 
292
222
  Use the `call_start` tool to place outbound calls. Every call requires:
223
+
293
224
  - **phone_number**: The number to call in E.164 format (e.g. `+14155551234`)
294
225
  - **task**: What the call should accomplish — this becomes the AI voice agent's objective
295
226
  - **context** (optional): Additional background information for the conversation
@@ -297,16 +228,19 @@ Use the `call_start` tool to place outbound calls. Every call requires:
297
228
  ### Example calls:
298
229
 
299
230
  **Making a reservation:**
231
+
300
232
  ```
301
233
  call_start phone_number="+14155551234" task="Make a dinner reservation for 2 people tonight at 7pm" context="The user's name is John Smith. Prefer a table by the window if available."
302
234
  ```
303
235
 
304
236
  **Calling a business:**
237
+
305
238
  ```
306
239
  call_start phone_number="+18005551234" task="Check if they have a specific product in stock" context="Looking for a 65-inch Samsung OLED TV, model QN65S95D. Ask about availability and price."
307
240
  ```
308
241
 
309
242
  **Following up on an appointment:**
243
+
310
244
  ```
311
245
  call_start phone_number="+12125551234" task="Confirm the dentist appointment scheduled for next Tuesday at 2pm" context="The appointment is under the name Jane Doe, DOB 03/15/1990."
312
246
  ```
@@ -316,11 +250,13 @@ call_start phone_number="+12125551234" task="Confirm the dentist appointment sch
316
250
  Implicit calls always use the assistant's Twilio number (`assistant_number`). Only specify `caller_identity_mode` when the user explicitly requests a different identity for a specific call.
317
251
 
318
252
  **Default call (assistant number):**
253
+
319
254
  ```
320
255
  call_start phone_number="+14155551234" task="Check store hours for today"
321
256
  ```
322
257
 
323
258
  **Call from the user's own number:**
259
+
324
260
  ```
325
261
  call_start phone_number="+14155551234" task="Check store hours for today" caller_identity_mode="user_number"
326
262
  ```
@@ -330,6 +266,7 @@ call_start phone_number="+14155551234" task="Check store hours for today" caller
330
266
  ### Phone number format
331
267
 
332
268
  Phone numbers MUST be in E.164 format: `+` followed by country code and number with no spaces, dashes, or parentheses.
269
+
333
270
  - US/Canada: `+1XXXXXXXXXX` (e.g. `+14155551234`)
334
271
  - UK: `+44XXXXXXXXXX` (e.g. `+442071234567`)
335
272
  - International: `+{country_code}{number}`
@@ -339,6 +276,7 @@ If the user provides a number in a different format, convert it to E.164 before
339
276
  ### Trial account limitations
340
277
 
341
278
  On Twilio trial accounts, outbound calls can ONLY be made to **verified numbers**. If a call fails with a "not verified" error:
279
+
342
280
  1. Tell the user they need to verify the number at https://console.twilio.com/us1/develop/phone-numbers/manage/verified
343
281
  2. Or upgrade to a paid Twilio account to call any number
344
282
 
@@ -351,41 +289,19 @@ Once Twilio is configured and the assistant has a phone number, inbound calls wo
351
289
  3. The LLM-driven orchestrator answers in receptionist mode — greeting the caller warmly and asking how it can help
352
290
  4. The conversation proceeds naturally, with ASK_GUARDIAN dispatches to consult the user when needed
353
291
 
354
- No additional configuration is needed beyond the standard Twilio setup (Steps 1-5 above). As long as `calls.enabled` is `true` and the phone number has been provisioned/assigned, inbound calls are handled automatically.
292
+ No additional configuration is needed beyond Twilio setup and `calls.enabled` being `true`. As long as the phone number has been provisioned/assigned, inbound calls are handled automatically.
355
293
 
356
294
  ### Guardian voice verification for inbound calls
357
295
 
358
- For guardian verification setup, first install the skill via `vellum_skills_catalog` with `action: "install"` and `skill_id: "guardian-verify-setup"`, then load it with `skill_load` using `skill: "guardian-verify-setup"`. This skill handles the full outbound verification flow; `phone-calls` does not orchestrate it inline. Do not use `call_start` to place guardian verification calls — the guardian outbound verification endpoints already place those calls.
296
+ For guardian verification setup, load the skill by calling `skill_load` with `skill_id: "guardian-verify-setup"`. This skill handles the full outbound verification flow; `phone-calls` does not orchestrate it inline. Do not use `call_start` to place guardian verification calls — the guardian outbound verification endpoints already place those calls.
359
297
 
360
298
  Once a guardian binding exists for the voice channel, inbound callers may be prompted for verification before calls proceed. The relay server detects pending challenges and prompts callers: "Please enter your six-digit verification code using your keypad, or speak the digits now." If verification fails after 3 attempts, the call ends with "Verification failed. Goodbye."
361
299
 
362
300
  This feature is separate from the outbound DTMF callee verification. It uses the channel guardian verification system rather than the per-call verification config.
363
301
 
364
- ## Live Call Monitoring
365
-
366
- ### Showing the live transcript
367
-
368
- By default, always show the live transcript of the call as it happens. When a call is in progress:
369
-
370
- 1. After placing the call with `call_start`, immediately begin polling with `call_status` to track the call state
371
- 2. The system fires transcript notifications as the conversation unfolds — both caller speech and assistant responses appear in real time in the conversation thread
372
- 3. Present each transcript entry clearly as it arrives:
302
+ ## Interacting with a Live Call
373
303
 
374
- ```
375
- 📞 Call in progress...
376
-
377
- 🗣️ Assistant: "Hi, I'm calling on behalf of John to make a dinner reservation for tonight."
378
- 👤 Caller: "Sure, what time would you like?"
379
- 🗣️ Assistant: "We'd like a table for two at 7pm, please."
380
- 👤 Caller: "Let me check... yes, we have availability at 7pm."
381
- 🗣️ Assistant: "Wonderful! The reservation would be under John Smith."
382
- ```
383
-
384
- 4. Continue monitoring until the call completes or fails
385
-
386
- ### Interacting with a live call
387
-
388
- During an active call, the user can interact with the AI voice agent via the HTTP API endpoints:
304
+ During an active call, the user can interact with the AI voice agent via the HTTP API endpoints. After placing a call with `call_start`, use `call_status` to poll the call state.
389
305
 
390
306
  #### Answering questions
391
307
 
@@ -424,7 +340,7 @@ When there is **no pending question** but the call is still active, the user can
424
340
 
425
341
  The instruction is injected into the AI voice agent's conversation context as high-priority input, and the agent adjusts its behavior accordingly.
426
342
 
427
- **Note:** Mid-call steering via the desktop chat thread is no longer supported. The desktop thread only receives pointer/status messages about the call. To steer a call, use the HTTP API endpoints directly.
343
+ **Note:** Steering is done via the HTTP API, not the desktop chat thread. The desktop thread only receives pointer/status messages about the call.
428
344
 
429
345
  ### Call status values
430
346
 
@@ -439,6 +355,7 @@ The instruction is injected into the AI voice agent's conversation context as hi
439
355
  ### Ending a call early
440
356
 
441
357
  Use `call_end` with the call session ID to terminate an active call:
358
+
442
359
  ```
443
360
  call_end call_session_id="<session_id>" reason="User requested to end the call"
444
361
  ```
@@ -465,6 +382,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
465
382
  ```
466
383
 
467
384
  This returns all messages in chronological order with:
385
+
468
386
  - `role: "user"` — caller speech (prefixed with `[SPEAKER]` tags) and system events
469
387
  - `role: "assistant"` — assistant responses, including `text` content and any `tool_use`/`tool_result` blocks
470
388
 
@@ -479,22 +397,22 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
479
397
 
480
398
  ### Additional tables for call metadata
481
399
 
482
- | Table | What it contains |
483
- |---|---|
484
- | `call_sessions` | Session metadata (start time, duration, phone numbers, status) |
485
- | `call_events` | Granular event log for the call lifecycle |
486
- | `notification_decisions` | Whether notifications were evaluated during the call |
487
- | `notification_deliveries` | Notification delivery attempts |
400
+ | Table | What it contains |
401
+ | ------------------------- | -------------------------------------------------------------- |
402
+ | `call_sessions` | Session metadata (start time, duration, phone numbers, status) |
403
+ | `call_events` | Granular event log for the call lifecycle |
404
+ | `notification_decisions` | Whether notifications were evaluated during the call |
405
+ | `notification_deliveries` | Notification delivery attempts |
488
406
 
489
407
  ### Key paths
490
408
 
491
- | Resource | Path |
492
- |---|---|
409
+ | Resource | Path |
410
+ | ------------------------------------------ | ------------------------------------------ |
493
411
  | Daemon logs (caller-side transcripts only) | `~/.vellum/workspace/data/logs/vellum.log` |
494
- | Full conversation database | `~/.vellum/workspace/data/db/assistant.db` |
495
- | Messages table | `messages` (keyed by `conversation_id`) |
496
- | Call sessions table | `call_sessions` |
497
- | Call events table | `call_events` |
412
+ | Full conversation database | `~/.vellum/workspace/data/db/assistant.db` |
413
+ | Messages table | `messages` (keyed by `conversation_id`) |
414
+ | Call sessions table | `call_sessions` |
415
+ | Call events table | `call_events` |
498
416
 
499
417
  ### Important
500
418
 
@@ -523,6 +441,7 @@ The `context` field is powerful — use it to give the agent background that hel
523
441
  ### Things the AI voice agent handles well
524
442
 
525
443
  **Outbound calls:**
444
+
526
445
  - Making reservations and appointments
527
446
  - Checking business hours, availability, or pricing
528
447
  - Confirming or rescheduling existing appointments
@@ -531,6 +450,7 @@ The `context` field is powerful — use it to give the agent background that hel
531
450
  - Leaving voicemails (it will speak the message if voicemail picks up)
532
451
 
533
452
  **Inbound calls:**
453
+
534
454
  - Answering as a receptionist and routing caller requests to the user via ASK_GUARDIAN
535
455
  - Taking messages when the user is unavailable
536
456
  - Answering questions the assistant already knows from memory/context
@@ -547,27 +467,27 @@ The `context` field is powerful — use it to give the agent background that hel
547
467
 
548
468
  All call-related settings can be managed via `vellum config`:
549
469
 
550
- | Setting | Description | Default |
551
- |---|---|---|
552
- | `calls.enabled` | Master switch for the calling feature | `false` |
553
- | `calls.provider` | Voice provider (currently only `twilio`) | `twilio` |
554
- | `calls.maxDurationSeconds` | Maximum call length in seconds | `3600` (1 hour) |
555
- | `calls.userConsultTimeoutSeconds` | How long to wait for user answers | `120` (2 min) |
556
- | `calls.disclosure.enabled` | Whether the AI announces itself at call start | `true` |
557
- | `calls.disclosure.text` | The disclosure message spoken at call start | `"At the very beginning of the call, introduce yourself as an assistant calling on behalf of my human."` |
558
- | `calls.model` | Override LLM model for call orchestration | *(uses default model)* |
559
- | `calls.callerIdentity.allowPerCallOverride` | Allow per-call caller identity selection | `true` |
560
- | `calls.callerIdentity.userNumber` | E.164 phone number for user-number mode | *(empty)* |
561
- | `calls.voice.mode` | Voice quality mode (`twilio_standard`, `twilio_elevenlabs_tts`, `elevenlabs_agent`) | `twilio_standard` |
562
- | `calls.voice.language` | Language code for TTS and transcription | `en-US` |
563
- | `calls.voice.transcriptionProvider` | Speech-to-text provider (`Deepgram`, `Google`) | `Deepgram` |
564
- | `calls.voice.fallbackToStandardOnError` | Auto-fallback to standard Twilio TTS on ElevenLabs errors | `true` |
565
- | `calls.voice.elevenlabs.voiceId` | Advanced/internal ElevenLabs voice identifier. Usually set by the assistant based on requested voice style | *(empty)* |
566
- | `calls.voice.elevenlabs.voiceModelId` | Optional Twilio ConversationRelay model suffix. Leave empty to send bare `voiceId` | *(empty)* |
567
- | `calls.voice.elevenlabs.agentId` | ElevenLabs agent ID (for `elevenlabs_agent` mode) | *(empty)* |
568
- | `calls.voice.elevenlabs.speed` | Playback speed (`0.7` – `1.2`) | `1.0` |
569
- | `calls.voice.elevenlabs.stability` | Voice stability (`0.0` – `1.0`) | `0.5` |
570
- | `calls.voice.elevenlabs.similarityBoost` | Voice similarity boost (`0.0` – `1.0`) | `0.75` |
470
+ | Setting | Description | Default |
471
+ | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
472
+ | `calls.enabled` | Master switch for the calling feature | `false` |
473
+ | `calls.provider` | Voice provider (currently only `twilio`) | `twilio` |
474
+ | `calls.maxDurationSeconds` | Maximum call length in seconds | `3600` (1 hour) |
475
+ | `calls.userConsultTimeoutSeconds` | How long to wait for user answers | `120` (2 min) |
476
+ | `calls.disclosure.enabled` | Whether the AI announces itself at call start | `true` |
477
+ | `calls.disclosure.text` | The disclosure message spoken at call start | `"At the very beginning of the call, introduce yourself as an assistant calling on behalf of my human."` |
478
+ | `calls.model` | Override LLM model for call orchestration | _(uses default model)_ |
479
+ | `calls.callerIdentity.allowPerCallOverride` | Allow per-call caller identity selection | `true` |
480
+ | `calls.callerIdentity.userNumber` | E.164 phone number for user-number mode | _(empty)_ |
481
+ | `calls.voice.mode` | Voice quality mode (`twilio_standard`, `twilio_elevenlabs_tts`, `elevenlabs_agent`) | `twilio_standard` |
482
+ | `calls.voice.language` | Language code for TTS and transcription | `en-US` |
483
+ | `calls.voice.transcriptionProvider` | Speech-to-text provider (`Deepgram`, `Google`) | `Deepgram` |
484
+ | `calls.voice.fallbackToStandardOnError` | Auto-fallback to standard Twilio TTS on ElevenLabs errors | `true` |
485
+ | `calls.voice.elevenlabs.voiceId` | Advanced/internal ElevenLabs voice identifier. Usually set by the assistant based on requested voice style | _(empty)_ |
486
+ | `calls.voice.elevenlabs.voiceModelId` | Optional Twilio ConversationRelay model suffix. Leave empty to send bare `voiceId` | _(empty)_ |
487
+ | `calls.voice.elevenlabs.agentId` | ElevenLabs agent ID (for `elevenlabs_agent` mode) | _(empty)_ |
488
+ | `calls.voice.elevenlabs.speed` | Playback speed (`0.7` – `1.2`) | `1.0` |
489
+ | `calls.voice.elevenlabs.stability` | Voice stability (`0.0` – `1.0`) | `0.5` |
490
+ | `calls.voice.elevenlabs.similarityBoost` | Voice similarity boost (`0.0` – `1.0`) | `0.75` |
571
491
 
572
492
  ### Adjusting settings
573
493
 
@@ -585,71 +505,80 @@ vellum config set calls.disclosure.text "Just so you know, this is an assistant
585
505
  vellum config set calls.userConsultTimeoutSeconds 300
586
506
  ```
587
507
 
588
- ## Accepted Regressions
589
-
590
- The following behavioral changes were introduced with the cross-channel guardian architecture (voice-cross-guardian):
591
-
592
- - **No more mid-call steering via desktop chat.** The call bridge that routed desktop chat messages to the active call has been removed. The desktop chat thread only receives pointer/status messages about the call. To steer a call, use the HTTP API endpoints directly (`POST /v1/calls/:id/instruction`).
593
- - **No live transcript mirror in the initiating chat.** The initiating desktop conversation no longer receives a real-time mirror of the call transcript. The initiating chat only gets pointer/status messages (call started, call ended, question asked, etc.).
594
- - **Guardian questions are dispatched cross-channel.** Rather than appearing only in the initiating desktop thread, ASK_GUARDIAN questions are now dispatched to all configured guardian channels (mac desktop, Telegram, SMS) simultaneously. The first channel to respond wins.
595
-
596
508
  ## Troubleshooting
597
509
 
598
510
  ### "Twilio credentials not configured"
599
- Run Step 3 to store your Account SID and Auth Token via the secure credential prompt flow, or load the `twilio-setup` skill.
511
+
512
+ Load the `twilio-setup` skill to store your Account SID and Auth Token.
600
513
 
601
514
  ### "Calls feature is disabled"
515
+
602
516
  Run `vellum config set calls.enabled true`.
603
517
 
604
518
  ### "No public base URL configured"
519
+
605
520
  Run the **public-ingress** skill to set up ngrok and configure `ingress.publicBaseUrl`.
606
521
 
607
522
  ### Call fails immediately after initiating
523
+
608
524
  - Check that the phone number is in E.164 format
609
525
  - Verify Twilio credentials are correct (wrong auth token causes API errors)
610
526
  - On trial accounts, ensure the destination number is verified
611
527
  - Check that the ngrok tunnel is still running (`curl -s http://127.0.0.1:4040/api/tunnels`)
612
528
 
613
529
  ### Call connects but no audio / one-way audio
530
+
614
531
  - The ConversationRelay WebSocket may not be connecting. Check that `ingress.publicBaseUrl` is correct and the tunnel is active
615
532
  - Verify the gateway is running at `$GATEWAY_BASE_URL`
616
533
 
617
534
  ### "Number not eligible for caller identity"
535
+
618
536
  The user's phone number is not owned by or verified with the Twilio account. The number must be either purchased through Twilio or added as a verified caller ID at https://console.twilio.com/us1/develop/phone-numbers/manage/verified.
619
537
 
620
538
  ### "Per-call caller identity override is disabled"
539
+
621
540
  The setting `calls.callerIdentity.allowPerCallOverride` is set to `false`, so per-call `caller_identity_mode` selection is not allowed. Re-enable overrides with `vellum config set calls.callerIdentity.allowPerCallOverride true`.
622
541
 
623
542
  ### Caller identity call fails on trial account
543
+
624
544
  Twilio trial accounts can only place calls to verified numbers, regardless of caller identity mode. The user's phone number must also be verified with Twilio. Upgrade to a paid account or verify both the source and destination numbers.
625
545
 
626
546
  ### "This phone number is not allowed to be called"
547
+
627
548
  Emergency numbers (911, 112, 999, 000, 110, 119) are permanently blocked for safety.
628
549
 
629
550
  ### ngrok tunnel URL changed
551
+
630
552
  If you restarted ngrok, the public URL has changed. Update it:
553
+
631
554
  ```bash
632
555
  vellum config set ingress.publicBaseUrl "<new-url>"
633
556
  ```
557
+
634
558
  Or re-run the public-ingress skill to auto-detect and save the new URL.
635
559
 
636
560
  ### Call drops after 30 seconds of silence
561
+
637
562
  The system has a 30-second silence timeout. If nobody speaks for 30 seconds, the agent will ask "Are you still there?" This is expected behavior.
638
563
 
639
564
  ### Call quality didn't improve after enabling ElevenLabs
565
+
640
566
  - Verify `calls.voice.mode` is set to `twilio_elevenlabs_tts` or `elevenlabs_agent` (not still `twilio_standard`)
641
567
  - Ask for the desired voice style again and try a different voice selection
642
568
  - If configuring manually: check that `calls.voice.elevenlabs.voiceId` contains a valid ElevenLabs voice ID
643
569
  - If mode is `elevenlabs_agent`, ensure `calls.voice.elevenlabs.agentId` is also set
644
570
 
645
571
  ### Twilio says "application error" right after answer
572
+
646
573
  - This often means ConversationRelay rejected voice configuration after TwiML fetch
647
574
  - Keep `calls.voice.elevenlabs.voiceModelId` empty first (bare `voiceId` mode)
648
575
  - If you set `voiceModelId`, try clearing it and retesting:
649
576
  `vellum config set calls.voice.elevenlabs.voiceModelId ""`
650
577
 
651
578
  ### ElevenLabs mode falls back to standard
579
+
652
580
  When `calls.voice.fallbackToStandardOnError` is `true` (the default), the system silently falls back to standard Twilio TTS if ElevenLabs encounters an error or restriction. Check:
581
+
653
582
  - For `elevenlabs_agent` mode: this mode is currently restricted (consultation bridging not yet supported) and will always fall back to standard when fallback is enabled. If fallback is disabled, the voice webhook returns HTTP 501.
654
583
  - For `twilio_elevenlabs_tts` mode: verify `calls.voice.elevenlabs.voiceId` is set to a valid voice ID
655
584
  - For invalid configs (missing voiceId/agentId): if fallback is disabled, the voice webhook returns HTTP 500 with the config error
@@ -1,52 +1,55 @@
1
1
  ---
2
2
  name: "Skills Catalog"
3
- description: "Browse and install skills from the Vellum catalog using the vellum skills CLI"
3
+ description: "Discover bundled skills and search/install community skills from Clawhub"
4
4
  user-invocable: true
5
- metadata: {"vellum": {"emoji": "🧩"}}
5
+ metadata: { "vellum": { "emoji": "🧩" } }
6
6
  ---
7
7
 
8
- You can help the user discover and install skills from the Vellum first-party catalog using the `vellum skills` CLI.
8
+ You can help the user discover what skills are available and find community skills to extend the assistant's capabilities.
9
9
 
10
- ## Listing available skills
10
+ ## Bundled skills (first-party)
11
11
 
12
- ```bash
13
- vellum skills list --json
12
+ First-party skills are **bundled** with the assistant — they are compiled in and always available. They do not need to be installed or downloaded. To activate a bundled skill, use the `skill_load` tool:
13
+
14
+ ```
15
+ skill_load skill=<skill-id>
14
16
  ```
15
17
 
16
- Returns a JSON object with `ok: true` and a `skills` array. Each skill has:
17
- - `id` — the skill identifier (used for install)
18
- - `name` — human-readable name
19
- - `description` — what the skill does
20
- - `emoji` — optional emoji
21
- - `includes` — optional list of dependency skill IDs
22
- - `version` — optional version string
18
+ The skill catalog shown in the system prompt lists all bundled skills with their IDs. When a user asks about capabilities, refer to this list to find relevant bundled skills and load them as needed.
23
19
 
24
- ## Installing a skill
20
+ ## Community skills (Clawhub)
25
21
 
26
- ```bash
27
- vellum skills install <skill-id> --json
28
- ```
22
+ Community skills are published on [Clawhub](https://clawhub.com) and can be searched and installed on demand.
23
+
24
+ ### Searching for community skills
25
+
26
+ Use the `skill_load` tool to search the catalog, or check the system prompt's available skills list. The IPC `skills_search` message searches both bundled and community skills.
27
+
28
+ ### Installing a community skill
29
+
30
+ Community skills are installed via the IPC `skills_install` message with a `slug` parameter. Once installed, they appear in `~/.vellum/workspace/skills/<slug>/` and can be loaded with `skill_load` like any other skill.
29
31
 
30
- Installs the skill to the managed skills directory. If the skill is already installed, pass `--overwrite` to replace it.
32
+ ### Inspecting a community skill
31
33
 
32
- Returns `{ "ok": true, "skillId": "<id>" }` on success.
34
+ Before installing, you can inspect a community skill via the IPC `skills_inspect` message with a `slug` parameter. This returns metadata (author, stats, version) and optionally the skill's SKILL.md content so the user can review it.
33
35
 
34
36
  ## Typical flow
35
37
 
36
38
  1. **User asks about capabilities** — "Can you order food?" or "What can you do?"
37
- - Run `vellum skills list --json` to see what's available
39
+ - Check the bundled skills list in the system prompt
38
40
  - Present relevant skills to the user
41
+ - Load any that match with `skill_load`
39
42
 
40
- 2. **User wants a new skill** "I want to use Slack" or "Set up Telegram"
41
- - Run `vellum skills list --json` to find matching skills
42
- - Run `vellum skills install <skill-id> --json` to install it
43
- - The skill will be available on the next conversation turn
43
+ 2. **User wants a capability not covered by bundled skills** "Can you do X?"
44
+ - Search for community skills that provide the capability
45
+ - Present matching results with descriptions and install counts
46
+ - Install the chosen skill, then load it with `skill_load`
44
47
 
45
- 3. **Skill has dependencies** — if `includes` lists other skill IDs, install those first
48
+ 3. **Skill has dependencies** — if `includes` lists other skill IDs, load those first with `skill_load`
46
49
 
47
50
  ## Notes
48
51
 
49
- - Skills are fetched from the Vellum platform API
50
- - Installed skills are stored in `~/.vellum/workspace/skills/<skill-id>/`
51
- - After installing, the skill may need to be enabled in settings
52
- - Use `--json` on all commands for reliable parsing
52
+ - Bundled skills are always available and do not need installation
53
+ - Community skills are installed to `~/.vellum/workspace/skills/<slug>/`
54
+ - After installing a community skill, it may need to be enabled in settings
55
+ - Skills can be enabled or disabled via feature flags without uninstalling them