@vellumai/assistant 0.4.37 → 0.4.41

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 (169) hide show
  1. package/ARCHITECTURE.md +3 -3
  2. package/README.md +13 -13
  3. package/bun.lock +80 -24
  4. package/docs/architecture/integrations.md +126 -128
  5. package/docs/runbook-trusted-contacts.md +1 -1
  6. package/docs/trusted-contact-access.md +12 -12
  7. package/package.json +3 -1
  8. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +0 -14
  9. package/src/__tests__/app-bundler.test.ts +209 -0
  10. package/src/__tests__/app-compiler.test.ts +279 -0
  11. package/src/__tests__/app-executors.test.ts +293 -483
  12. package/src/__tests__/app-migration.test.ts +148 -0
  13. package/src/__tests__/app-routes-csp.test.ts +202 -0
  14. package/src/__tests__/avatar-e2e.test.ts +452 -0
  15. package/src/__tests__/avatar-generator.test.ts +193 -0
  16. package/src/__tests__/avatar-router.test.ts +186 -0
  17. package/src/__tests__/browser-download-timeout.test.ts +28 -0
  18. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +9 -9
  19. package/src/__tests__/call-domain.test.ts +3 -7
  20. package/src/__tests__/credential-security-e2e.test.ts +19 -12
  21. package/src/__tests__/credentials-cli.test.ts +30 -4
  22. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +1 -1
  23. package/src/__tests__/handlers-slack-config.test.ts +0 -72
  24. package/src/__tests__/handlers-telegram-config.test.ts +19 -12
  25. package/src/__tests__/handlers-twitter-config.test.ts +105 -48
  26. package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
  27. package/src/__tests__/integration-status.test.ts +15 -5
  28. package/src/__tests__/integrations-cli.test.ts +1 -1
  29. package/src/__tests__/invite-redemption-service.test.ts +62 -7
  30. package/src/__tests__/ipc-snapshot.test.ts +0 -8
  31. package/src/__tests__/managed-avatar-client.test.ts +280 -0
  32. package/src/__tests__/mcp-cli.test.ts +3 -3
  33. package/src/__tests__/oauth-cli.test.ts +203 -0
  34. package/src/__tests__/relay-server.test.ts +3 -3
  35. package/src/__tests__/secret-onetime-send.test.ts +19 -12
  36. package/src/__tests__/secure-keys.test.ts +78 -0
  37. package/src/__tests__/session-messaging-secret-redirect.test.ts +3 -0
  38. package/src/__tests__/slack-channel-config.test.ts +23 -16
  39. package/src/__tests__/slack-share-routes.test.ts +263 -0
  40. package/src/__tests__/sms-messaging-provider.test.ts +3 -1
  41. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +7 -7
  42. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
  43. package/src/__tests__/trusted-contact-verification.test.ts +10 -10
  44. package/src/__tests__/twilio-config.test.ts +15 -36
  45. package/src/__tests__/twilio-provider.test.ts +4 -0
  46. package/src/__tests__/twitter-auth-handler.test.ts +27 -14
  47. package/src/__tests__/twitter-cli-error-shaping.test.ts +1 -1
  48. package/src/__tests__/twitter-cli-routing.test.ts +38 -53
  49. package/src/__tests__/twitter-oauth-client.test.ts +18 -47
  50. package/src/__tests__/voice-invite-redemption.test.ts +27 -3
  51. package/src/amazon/cart.ts +1 -1
  52. package/src/amazon/client.ts +89 -7
  53. package/src/approvals/guardian-request-resolvers.ts +2 -2
  54. package/src/bundler/app-bundler.ts +77 -32
  55. package/src/bundler/app-compiler.ts +195 -0
  56. package/src/bundler/manifest.ts +1 -1
  57. package/src/bundler/package-resolver.ts +185 -0
  58. package/src/calls/call-domain.ts +4 -14
  59. package/src/calls/relay-server.ts +2 -2
  60. package/src/calls/twilio-config.ts +5 -24
  61. package/src/calls/twilio-rest.ts +19 -5
  62. package/src/cli/amazon.ts +74 -249
  63. package/src/cli/audit.ts +2 -2
  64. package/src/cli/autonomy.ts +9 -9
  65. package/src/cli/channels.ts +5 -5
  66. package/src/cli/completions.ts +27 -27
  67. package/src/cli/config.ts +14 -14
  68. package/src/cli/contacts.ts +27 -27
  69. package/src/cli/credentials.ts +28 -28
  70. package/src/cli/dev.ts +2 -2
  71. package/src/cli/doctor.ts +2 -2
  72. package/src/cli/email.ts +82 -82
  73. package/src/cli/influencer.ts +13 -13
  74. package/src/cli/integrations.ts +19 -144
  75. package/src/cli/keys.ts +10 -10
  76. package/src/cli/map.ts +4 -4
  77. package/src/cli/mcp.ts +17 -17
  78. package/src/cli/memory.ts +18 -18
  79. package/src/cli/notifications.ts +13 -13
  80. package/src/cli/oauth.ts +77 -0
  81. package/src/cli/program.ts +2 -0
  82. package/src/cli/sequence.ts +27 -27
  83. package/src/cli/sessions.ts +12 -12
  84. package/src/cli/trust.ts +8 -8
  85. package/src/cli/twitter.ts +124 -70
  86. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
  87. package/src/config/bundled-skills/agentmail/SKILL.md +34 -34
  88. package/src/config/bundled-skills/amazon/SKILL.md +54 -54
  89. package/src/config/bundled-skills/app-builder/SKILL.md +137 -3
  90. package/src/config/bundled-skills/app-builder/tools/app-create.ts +10 -4
  91. package/src/config/bundled-skills/configure-settings/SKILL.md +18 -18
  92. package/src/config/bundled-skills/contacts/SKILL.md +12 -12
  93. package/src/config/bundled-skills/doordash/lib/client.ts +7 -9
  94. package/src/config/bundled-skills/email-setup/SKILL.md +4 -4
  95. package/src/config/bundled-skills/frontend-design/icon.svg +16 -0
  96. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +143 -162
  97. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +4 -4
  98. package/src/config/bundled-skills/influencer/SKILL.md +13 -13
  99. package/src/config/bundled-skills/mcp-setup/SKILL.md +11 -11
  100. package/src/config/bundled-skills/phone-calls/SKILL.md +48 -54
  101. package/src/config/bundled-skills/public-ingress/SKILL.md +6 -6
  102. package/src/config/bundled-skills/slack-app-setup/SKILL.md +1 -1
  103. package/src/config/bundled-skills/sms-setup/SKILL.md +3 -3
  104. package/src/config/bundled-skills/telegram-setup/SKILL.md +2 -2
  105. package/src/config/bundled-skills/twilio-setup/SKILL.md +136 -225
  106. package/src/config/bundled-skills/twitter/SKILL.md +68 -44
  107. package/src/config/bundled-skills/voice-setup/SKILL.md +2 -2
  108. package/src/config/core-schema.ts +26 -0
  109. package/src/config/env.ts +4 -0
  110. package/src/config/feature-flag-registry.json +9 -1
  111. package/src/config/schema.ts +8 -0
  112. package/src/config/system-prompt.ts +6 -3
  113. package/src/config/templates/BOOTSTRAP.md +7 -5
  114. package/src/contacts/contacts-write.ts +5 -1
  115. package/src/daemon/handlers/apps.ts +31 -4
  116. package/src/daemon/handlers/config-ingress.ts +3 -3
  117. package/src/daemon/handlers/config-integrations.ts +120 -49
  118. package/src/daemon/handlers/config-slack-channel.ts +26 -7
  119. package/src/daemon/handlers/config-slack.ts +1 -54
  120. package/src/daemon/handlers/config-telegram.ts +28 -10
  121. package/src/daemon/handlers/config.ts +1 -4
  122. package/src/daemon/handlers/twitter-auth.ts +11 -4
  123. package/src/daemon/ipc-contract/apps.ts +0 -13
  124. package/src/daemon/ipc-contract-inventory.json +0 -2
  125. package/src/daemon/lifecycle.ts +8 -1
  126. package/src/daemon/session-messaging.ts +2 -2
  127. package/src/daemon/tool-side-effects.ts +30 -0
  128. package/src/email/providers/agentmail.ts +1 -1
  129. package/src/email/providers/index.ts +1 -1
  130. package/src/email/service.ts +1 -1
  131. package/src/gallery/default-gallery.ts +538 -0
  132. package/src/gallery/gallery-manifest.ts +5 -1
  133. package/src/influencer/client.ts +8 -6
  134. package/src/mcp/client.ts +1 -1
  135. package/src/media/avatar-router.ts +99 -0
  136. package/src/media/avatar-types.ts +60 -0
  137. package/src/media/managed-avatar-client.ts +189 -0
  138. package/src/memory/app-migration.ts +114 -0
  139. package/src/memory/app-store.ts +11 -0
  140. package/src/memory/qdrant-client.ts +1 -1
  141. package/src/messaging/providers/slack/client.ts +12 -2
  142. package/src/messaging/providers/sms/adapter.ts +6 -10
  143. package/src/migrations/data-layout.ts +8 -1
  144. package/src/oauth/token-persistence.ts +9 -6
  145. package/src/runtime/assistant-scope.ts +5 -0
  146. package/src/runtime/auth/route-policy.ts +4 -0
  147. package/src/runtime/channel-readiness-service.ts +9 -4
  148. package/src/runtime/gateway-internal-client.ts +11 -3
  149. package/src/runtime/http-server.ts +2 -0
  150. package/src/runtime/invite-redemption-service.ts +23 -13
  151. package/src/runtime/middleware/twilio-validation.ts +2 -2
  152. package/src/runtime/routes/app-routes.ts +131 -3
  153. package/src/runtime/routes/inbound-stages/verification-intercept.ts +3 -3
  154. package/src/runtime/routes/integration-routes.ts +2 -2
  155. package/src/runtime/routes/slack-share-routes.ts +235 -0
  156. package/src/runtime/routes/twilio-routes.ts +47 -34
  157. package/src/schedule/integration-status.ts +2 -3
  158. package/src/security/token-manager.ts +11 -3
  159. package/src/tools/apps/executors.ts +116 -8
  160. package/src/tools/browser/browser-manager.ts +30 -2
  161. package/src/tools/browser/chrome-cdp.ts +31 -3
  162. package/src/tools/credentials/vault.ts +9 -7
  163. package/src/tools/executor.ts +4 -0
  164. package/src/tools/system/avatar-generator.ts +55 -34
  165. package/src/twitter/client.ts +1 -1
  166. package/src/twitter/oauth-client.ts +31 -43
  167. package/src/twitter/router.ts +25 -23
  168. package/src/util/platform.ts +5 -0
  169. package/src/slack/slack-webhook.ts +0 -66
@@ -1,348 +1,259 @@
1
1
  ---
2
2
  name: "Twilio Setup"
3
- description: "Configure Twilio credentials and phone numbers for voice calls and SMS messaging"
3
+ description: "Configure Twilio credentials and phone numbers for voice calls"
4
4
  user-invocable: true
5
5
  includes: ["public-ingress"]
6
6
  metadata: { "vellum": { "emoji": "\ud83d\udcf1" } }
7
7
  ---
8
8
 
9
- You are helping your user configure Twilio for voice calls and SMS messaging. Twilio is the shared telephony provider for both the **phone-calls** and **SMS messaging** capabilities. When this skill is invoked, walk through each step below using the Twilio HTTP control-plane endpoints and existing tools.
9
+ You are helping your user configure Twilio for voice calls. Walk through each step below.
10
10
 
11
- ## Quick Start
11
+ ## Value Classification
12
12
 
13
- ```bash
14
- # 1. Check current status
15
- vellum integrations twilio config --json
16
- # 2. Store credentials (after collecting via credential_store prompt)
17
- curl -s -X POST "$INTERNAL_GATEWAY_BASE_URL/v1/integrations/twilio/credentials" \
18
- -H "Authorization: Bearer $GATEWAY_AUTH_TOKEN" -H "Content-Type: application/json" \
19
- -d '{"accountSid":"ACxxx","authToken":"xxx"}'
20
- # 3. Get credential ID and Account SID for proxied calls
21
- credential_store action=list # → note credential_id for twilio/account_sid
22
- vellum integrations twilio config --json | jq -r '.accountSid'
23
- # 4. Search and provision via Twilio API (proxy injects auth automatically)
24
- # bash network_mode=proxied credential_ids=["<cred_id>"]
25
- curl -s "https://api.twilio.com/2010-04-01/Accounts/<SID>/AvailablePhoneNumbers/US/Local.json?SmsEnabled=true&VoiceEnabled=true"
26
- curl -s -X POST "https://api.twilio.com/2010-04-01/Accounts/<SID>/IncomingPhoneNumbers.json" -d "PhoneNumber=+1xxx"
27
- # 5. Assign locally (saves to config + sets up webhooks)
28
- curl -s -X POST "$INTERNAL_GATEWAY_BASE_URL/v1/integrations/twilio/numbers/assign" \
29
- -H "Authorization: Bearer $GATEWAY_AUTH_TOKEN" -H "Content-Type: application/json" \
30
- -d '{"phoneNumber":"+1xxx"}'
31
- ```
32
-
33
- For voice call setup after Twilio is configured, use `phone-calls` + `call_start`.
34
-
35
- ## Overview
36
-
37
- This skill manages the full Twilio lifecycle:
38
-
39
- - **Credential storage** — Account SID and Auth Token
40
- - **Direct Twilio API access** — Search and purchase numbers via proxied calls to the Twilio REST API (the proxy injects authentication automatically)
41
- - **Phone number assignment** — Assign an existing Twilio number to the assistant
42
- - **Status checking** — Verify credentials and assigned number
43
-
44
- Number search and purchase use proxied calls to the Twilio REST API (`bash` with `network_mode: "proxied"`). Local bookkeeping (assign, webhook sync) uses gateway control-plane endpoints. Status/list retrieval uses `vellum integrations ...` CLI reads.
45
-
46
- ### Multi-Assistant Setups
47
-
48
- In a multi-assistant environment (multiple assistants sharing the same runtime), some actions are **assistant-scoped** while others are **global** (shared across all assistants):
13
+ Before you begin, understand how each Twilio value is stored:
49
14
 
50
- **Global actions** (ignore `assistantId` credentials are shared across all assistants):
15
+ | Value | Type | Storage method | Secret? |
16
+ | ------------ | ---------- | --------------------------------------------- | ------- |
17
+ | Account SID | Config | `assistant config set twilio.accountSid` | No |
18
+ | Auth Token | Credential | `assistant credentials set twilio:auth_token` | **Yes** |
19
+ | Phone Number | Config | `assistant config set twilio.phoneNumber` | No |
51
20
 
52
- - `POST /v1/integrations/twilio/credentials` — Stores Account SID and Auth Token in global secure storage (`credential:twilio:*` keys). All assistants share the same Twilio account credentials.
53
- - `DELETE /v1/integrations/twilio/credentials` Removes the globally stored Account SID and Auth Token. This affects all assistants.
21
+ - **Config values** (Account SID, Phone Number) are non-sensitive identifiers. Collect them via normal conversation -- the user can paste them in chat or you can use `AskUserQuestion`.
22
+ - **Credential values** (Auth Token) are secrets. Collect them securely via `credential_store` -- never accept them pasted in plaintext chat.
54
23
 
55
- **Assistant-scoped actions** (use `assistantId` query parameter to scope phone number configuration per assistant):
24
+ ## Retrieving Twilio Credentials
56
25
 
57
- - `GET /v1/integrations/twilio/config` Returns the phone number assigned to the specified assistant.
58
- - `POST /v1/integrations/twilio/numbers/assign` — Assigns a phone number to a specific assistant via the per-assistant mapping.
59
- - `POST /v1/integrations/twilio/numbers/provision` — Legacy convenience endpoint that provisions a new number and assigns it to the specified assistant. The main flow now uses proxied Twilio API calls (search + purchase) followed by the assign endpoint.
60
- - `GET /v1/integrations/twilio/numbers` — Lists all phone numbers on the shared Twilio account (uses global credentials).
26
+ Many steps below require the Account SID and Auth Token. Retrieve them with:
61
27
 
62
- Include `assistantId` as a query parameter in assistant-scoped requests whenever:
63
-
64
- - Multiple assistants share the same Twilio account but use different phone numbers
65
- - You want to ensure configuration changes only affect a specific assistant
66
- - The user has explicitly selected or referenced a particular assistant
67
-
68
- All HTTP examples below include the optional `assistantId` query parameter in assistant-scoped requests. Omit it in single-assistant setups. For global actions (credentials), the `assistantId` parameter is accepted but ignored.
28
+ ```bash
29
+ TWILIO_SID=$(assistant config get twilio.accountSid)
30
+ TWILIO_TOKEN=$(assistant credentials reveal twilio:auth_token)
31
+ ```
69
32
 
70
33
  ## Step 1: Check Current Configuration
71
34
 
72
- First, check whether Twilio is already configured:
73
-
74
35
  ```bash
75
- vellum integrations twilio config --json
36
+ assistant config get twilio.accountSid
37
+ assistant credentials inspect twilio:auth_token --json # check "hasSecret" field
38
+ assistant config get twilio.phoneNumber
76
39
  ```
77
40
 
78
- The response includes:
79
-
80
- - `hasCredentials` — whether Account SID and Auth Token are stored
81
- - `phoneNumber` — the currently assigned phone number (if any)
82
-
83
- If both are present, tell the user Twilio is already configured and offer to show the current status or reconfigure.
41
+ - If `twilio.accountSid` has a value, `hasSecret` is `true`, and `twilio.phoneNumber` is set -- Twilio is fully configured. Offer to show status or reconfigure.
42
+ - Otherwise, continue to the missing steps.
84
43
 
85
44
  ## Step 2: Collect and Store Credentials
86
45
 
87
- If credentials are not yet stored, guide the user through Twilio account setup:
46
+ Tell the user: **"You'll need a Twilio account. Sign up at https://www.twilio.com/try-twilio -- it's free to start and includes trial credit."**
88
47
 
89
- 1. Tell the user: **"You'll need a Twilio account. Sign up at https://www.twilio.com/try-twilio — it's free to start and includes trial credit."**
90
- 2. Once they have an account, they need two pieces of information:
91
- - **Account SID** — found on the Twilio Console dashboard at https://console.twilio.com
92
- - **Auth Token** — found on the same dashboard (click "Show" to reveal it)
48
+ They need two values from the Twilio Console dashboard (https://console.twilio.com):
93
49
 
94
- **IMPORTANT Secure credential collection only:** Never use credentials pasted in plaintext chat. Always collect credentials through the secure credential prompt flow:
50
+ - **Account SID** -- visible on the dashboard, starts with `AC`
51
+ - **Auth Token** -- click "Show" to reveal (this is the only secret)
95
52
 
96
- - 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"`.
97
- - 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"`.
53
+ ### Collect Account SID
98
54
 
99
- After both credentials are collected, retrieve them from secure storage and send them to the gateway:
55
+ Ask the user for their Account SID. They can paste it directly in chat since it is not a secret. Then store it:
100
56
 
101
57
  ```bash
102
- curl -s -X POST "$INTERNAL_GATEWAY_BASE_URL/v1/integrations/twilio/credentials" \
103
- -H "Authorization: Bearer $GATEWAY_AUTH_TOKEN" \
104
- -H "Content-Type: application/json" \
105
- -d '{"accountSid":"<value from credential_store for twilio/account_sid>","authToken":"<value from credential_store for twilio/auth_token>"}'
58
+ assistant config set twilio.accountSid "<Account SID from user>"
106
59
  ```
107
60
 
108
- Both `accountSid` and `authToken` are required — the endpoint validates the credentials against the Twilio API before storing them. If credentials are invalid, the response returns an error. Tell the user and ask them to re-enter via the secure prompt.
109
-
110
- **Note:** Setting credentials is a global operation — credentials are stored once and shared across all assistants. The `assistantId` parameter is accepted but ignored.
61
+ ### Collect Auth Token
111
62
 
112
- ## Step 3: Get a Phone Number
113
-
114
- The assistant needs a phone number to make calls and send SMS. There are two paths:
115
-
116
- ### Option A: Provision a New Number
63
+ Collect the Twilio auth token securely:
117
64
 
118
- If the user wants to buy a new number through Twilio:
65
+ - 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 (click 'Show' to reveal it)"`, `placeholder: "your_auth_token"`.
119
66
 
120
- **3a. Get the credential ID and Account SID:**
121
-
122
- ```
123
- credential_store action=list
124
- ```
125
-
126
- Find the entry with `service: "twilio"` and `field: "account_sid"`. Note its `credential_id`.
127
-
128
- Then retrieve the Account SID (needed for Twilio URL paths):
67
+ Confirm it has been stored successfully:
129
68
 
130
69
  ```bash
131
- vellum integrations twilio config --json | jq -r '.accountSid'
70
+ assistant credentials inspect "twilio:auth_token"
132
71
  ```
133
72
 
134
- **3b. Search for available numbers (proxied Twilio API):**
73
+ If credentials are invalid, Twilio API calls in Step 3 will fail -- ask the user to re-enter.
135
74
 
136
- ```
137
- bash:
138
- network_mode: proxied
139
- credential_ids: ["<credential_id from 3a>"]
140
- command: |
141
- curl -s "https://api.twilio.com/2010-04-01/Accounts/<ACCOUNT_SID>/AvailablePhoneNumbers/US/Local.json?SmsEnabled=true&VoiceEnabled=true&AreaCode=415"
142
- ```
143
-
144
- - `AreaCode` is optional — ask the user if they have a preferred area code
145
- - Replace `US` with a different ISO 3166-1 alpha-2 country code if the user wants a non-US number
146
- - The proxy automatically injects `Authorization: Basic <credentials>` — do not include an Authorization header
147
-
148
- The response contains an `available_phone_numbers` array. Present the first few options to the user with their `phone_number` and `friendly_name`.
75
+ ## Step 3: Get a Phone Number
149
76
 
150
- **3c. Purchase the chosen number (proxied Twilio API):**
77
+ The assistant needs a phone number for voice calls. Three options:
151
78
 
152
- ```
153
- bash:
154
- network_mode: proxied
155
- credential_ids: ["<credential_id from 3a>"]
156
- command: |
157
- curl -s -X POST "https://api.twilio.com/2010-04-01/Accounts/<ACCOUNT_SID>/IncomingPhoneNumbers.json" \
158
- -d "PhoneNumber=+14155551234"
159
- ```
79
+ ### Option A: Use an Existing Number
160
80
 
161
- The response includes the purchased number's `phone_number` and `sid`.
81
+ You should assume this option if the user had just created their Twilio account. Trial accounts come with one free number.
162
82
 
163
- **3d. Assign locally (saves to config + sets up webhooks):**
83
+ Retrieve credentials, then list numbers on the account:
164
84
 
165
85
  ```bash
166
- curl -s -X POST "$INTERNAL_GATEWAY_BASE_URL/v1/integrations/twilio/numbers/assign" \
167
- -H "Authorization: Bearer $GATEWAY_AUTH_TOKEN" \
168
- -H "Content-Type: application/json" \
169
- -d '{"phoneNumber":"+14155551234"}'
86
+ curl -s -u "$TWILIO_SID:$TWILIO_TOKEN" \
87
+ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_SID/IncomingPhoneNumbers.json"
170
88
  ```
171
89
 
172
- This persists the number to secure storage and config, and configures Twilio webhooks (voice, status callback, SMS) if a public ingress URL is available. The response includes the new `phoneNumber`. No separate assign call is needed.
173
-
174
- **Webhook auto-configuration:** When `ingress.publicBaseUrl` is configured, the assign endpoint automatically sets the following webhooks on the Twilio phone number:
175
-
176
- - Voice webhook: `{publicBaseUrl}/webhooks/twilio/voice`
177
- - Voice status callback: `{publicBaseUrl}/webhooks/twilio/status`
178
- - SMS webhook: `{publicBaseUrl}/webhooks/twilio/sms`
90
+ Present the `incoming_phone_numbers` array. Let the user choose.
179
91
 
180
- If ingress is not yet configured, webhook setup is skipped gracefully — the number is still assigned and usable once ingress is set up later.
92
+ ### Option B: Provision a New Number
181
93
 
182
- **Trial account note:** Twilio trial accounts come with one free phone number. Check "Active Numbers" in the Twilio Console first before provisioning.
94
+ Retrieve credentials (see "Retrieving Twilio Credentials" above), then:
183
95
 
184
- ### Option B: Assign an Existing Number
96
+ **Search for available numbers:**
185
97
 
186
- If the user already has a Twilio phone number, first get the credential ID and Account SID (same as Option A, step 3a), then list available numbers:
187
-
188
- ```
189
- bash:
190
- network_mode: proxied
191
- credential_ids: ["<credential_id>"]
192
- command: |
193
- curl -s "https://api.twilio.com/2010-04-01/Accounts/<ACCOUNT_SID>/IncomingPhoneNumbers.json"
98
+ ```bash
99
+ curl -s -u "$TWILIO_SID:$TWILIO_TOKEN" \
100
+ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_SID/AvailablePhoneNumbers/US/Local.json?VoiceEnabled=true&AreaCode=415"
194
101
  ```
195
102
 
196
- The response includes an `incoming_phone_numbers` array with each number's `phone_number`, `friendly_name`, and `capabilities`. Present these to the user and let them choose.
103
+ - `AreaCode` is optional -- ask the user if they have a preference
104
+ - Replace `US` with another country code if needed
197
105
 
198
- Then assign the chosen number:
106
+ Present the first few results from the `available_phone_numbers` array (show `phone_number` and `friendly_name`).
107
+
108
+ **Purchase the chosen number:**
199
109
 
200
110
  ```bash
201
- curl -s -X POST "$INTERNAL_GATEWAY_BASE_URL/v1/integrations/twilio/numbers/assign" \
202
- -H "Authorization: Bearer $GATEWAY_AUTH_TOKEN" \
203
- -H "Content-Type: application/json" \
204
- -d '{"phoneNumber":"+14155551234"}'
111
+ curl -s -u "$TWILIO_SID:$TWILIO_TOKEN" -X POST \
112
+ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_SID/IncomingPhoneNumbers.json" \
113
+ -d "PhoneNumber=+14155551234"
205
114
  ```
206
115
 
207
- The phone number must be in E.164 format. Like provisioning, assigning also auto-configures Twilio webhooks when a public ingress URL is available.
116
+ Note the `sid` field (starts with `PN`) from the response -- needed for webhook setup in Step 4.
208
117
 
209
118
  ### Option C: Manual Entry
210
119
 
211
- If the user wants to enter a number directly (e.g., they know it already), store it via credential store:
120
+ If the user already has a number and knows it, skip the API calls. They can paste it directly in chat.
212
121
 
213
- ```
214
- credential_store action=store service=twilio field=phone_number value=+14155551234
215
- ```
122
+ ### Save the phone number
216
123
 
217
- Then assign it through the gateway:
124
+ After choosing a number via any option, store it as a config value:
218
125
 
219
126
  ```bash
220
- curl -s -X POST "$INTERNAL_GATEWAY_BASE_URL/v1/integrations/twilio/numbers/assign" \
221
- -H "Authorization: Bearer $GATEWAY_AUTH_TOKEN" \
222
- -H "Content-Type: application/json" \
223
- -d '{"phoneNumber":"+14155551234"}'
127
+ assistant config set twilio.phoneNumber "+14155551234"
224
128
  ```
225
129
 
226
- ## Step 4: Set Up Public Ingress
227
-
228
- Twilio needs a publicly reachable URL for voice webhooks, ConversationRelay WebSocket, and SMS delivery reports. The **public-ingress** skill handles this via ngrok.
130
+ ## Step 4: Set Up Public Ingress and Webhooks
229
131
 
230
- Check if ingress is already configured:
132
+ Twilio needs a publicly reachable URL for voice webhooks. Check if ingress is configured:
231
133
 
232
134
  ```bash
233
- vellum config get ingress.publicBaseUrl
234
- vellum config get ingress.enabled
135
+ assistant config get ingress.publicBaseUrl
136
+ assistant config get ingress.enabled
235
137
  ```
236
138
 
237
- If not configured, load and run the public-ingress skill:
139
+ If not configured, load the public-ingress skill:
238
140
 
239
141
  ```
240
142
  skill_load skill=public-ingress
241
143
  ```
242
144
 
243
- **Twilio webhook endpoints (auto-configured on provision/assign):**
244
-
245
- - Voice webhook: `{publicBaseUrl}/webhooks/twilio/voice`
246
- - Voice status callback: `{publicBaseUrl}/webhooks/twilio/status`
247
- - ConversationRelay WebSocket: `{publicBaseUrl}/webhooks/twilio/relay` (wss://)
248
- - SMS webhook: `{publicBaseUrl}/webhooks/twilio/sms`
249
-
250
- Webhook URLs are automatically configured on the Twilio phone number when provisioning or assigning a number with a valid ingress URL. No manual Twilio Console webhook configuration is needed.
145
+ ### Configure Twilio Webhooks
251
146
 
252
- ## Step 5: Verify Setup
147
+ Set webhook URLs on the phone number so Twilio routes traffic to the assistant.
253
148
 
254
- After configuration, verify by checking the config endpoint again.
149
+ Retrieve credentials and config values:
255
150
 
256
151
  ```bash
257
- vellum integrations twilio config --json
152
+ TWILIO_SID=$(assistant config get twilio.accountSid)
153
+ TWILIO_TOKEN=$(assistant credentials reveal twilio:auth_token)
154
+ PUBLIC_URL=$(assistant config get ingress.publicBaseUrl)
155
+ PHONE_NUMBER=$(assistant config get twilio.phoneNumber)
258
156
  ```
259
157
 
260
- Confirm:
158
+ Look up the phone number's SID:
261
159
 
262
- - `hasCredentials` is `true`
263
- - `phoneNumber` is set to the expected number
264
-
265
- Tell the user: **"Twilio is configured. Your assistant's phone number is {phoneNumber}. This number is used for both voice calls and SMS messaging."**
160
+ ```bash
161
+ curl -s -u "$TWILIO_SID:$TWILIO_TOKEN" \
162
+ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_SID/IncomingPhoneNumbers.json?PhoneNumber=$PHONE_NUMBER"
163
+ ```
266
164
 
267
- ## Step 5.5: Guardian Verification (Voice)
165
+ Note the `sid` field (starts with `PN`) from the matching entry, then update webhooks:
268
166
 
269
- Now link the user's phone number as the trusted voice guardian. Tell the user: "Now let's verify your guardian identity for voice. This links your phone number so the assistant can verify inbound callers."
167
+ ```bash
168
+ curl -s -u "$TWILIO_SID:$TWILIO_TOKEN" -X POST \
169
+ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_SID/IncomingPhoneNumbers/$PHONE_SID.json" \
170
+ -d "VoiceUrl=$PUBLIC_URL/webhooks/twilio/voice" \
171
+ -d "StatusCallback=$PUBLIC_URL/webhooks/twilio/status"
172
+ ```
270
173
 
271
- Load the **guardian-verify-setup** skill to handle the verification flow:
174
+ ## Step 5: Verify and Enable
272
175
 
273
- - Call `skill_load` with `skill: "guardian-verify-setup"` to load the dependency skill.
176
+ Re-run the checks from Step 1 to confirm everything is set. Then enable voice calls:
274
177
 
275
- When invoking the skill, indicate the channel is `voice`. The guardian-verify-setup skill manages the full outbound verification flow, including:
178
+ ```bash
179
+ assistant config set calls.enabled true
180
+ ```
276
181
 
277
- - Collecting the user's phone number as the destination (accepts any common format -- the API normalizes to E.164)
278
- - Starting the outbound verification session via the gateway endpoint `POST /v1/integrations/guardian/outbound/start` with `channel: "voice"`
279
- - Calling the phone number and providing a code for the user to enter via their phone's keypad
280
- - Proactively polling for completion (voice auto-check) so the user gets instant confirmation
281
- - Checking guardian status to confirm the binding was created
282
- - Handling resend, cancel, and error cases
182
+ Tell the user: **"Twilio is configured. Your assistant's phone number is {phoneNumber}."**
283
183
 
284
- Tell the user: _"I've loaded the guardian verification guide. It will walk you through linking your phone number as the trusted voice guardian."_
184
+ ## Step 6: Guardian Verification (Optional)
285
185
 
286
- After the guardian-verify-setup skill completes (or the user skips), continue to Step 6.
186
+ Link the user's phone number as the trusted voice guardian so the assistant can verify inbound callers.
287
187
 
288
- **Note:** Guardian verification is optional but recommended. If the user declines or wants to skip, proceed to Step 6 without blocking.
188
+ Load the guardian-verify-setup skill with `channel: "voice"`:
289
189
 
290
- To re-check guardian status later:
291
-
292
- ```bash
293
- vellum integrations guardian status --channel voice --json
190
+ ```
191
+ skill_load skill=guardian-verify-setup
294
192
  ```
295
193
 
296
- ## Step 6: Enable Features
297
-
298
- Now that Twilio is configured, the user can enable the features that depend on it:
194
+ The skill handles the full verification flow (outbound call, code entry, confirmation). If the user declines, skip this step.
299
195
 
300
- **For voice calls:**
196
+ To re-check guardian status later:
301
197
 
302
198
  ```bash
303
- vellum config set calls.enabled true
199
+ assistant integrations guardian status --channel voice --json
304
200
  ```
305
201
 
306
- **For SMS messaging:**
307
- SMS is available automatically once Twilio is configured — no additional feature flag is needed.
308
-
309
202
  ## Clearing Credentials
310
203
 
311
- If the user wants to disconnect Twilio:
204
+ To disconnect Twilio:
312
205
 
313
206
  ```bash
314
- curl -s -X DELETE "$INTERNAL_GATEWAY_BASE_URL/v1/integrations/twilio/credentials" \
315
- -H "Authorization: Bearer $GATEWAY_AUTH_TOKEN"
207
+ assistant credentials delete twilio:auth_token
208
+ assistant config set twilio.accountSid ""
316
209
  ```
317
210
 
318
- This removes the stored Account SID and Auth Token. Phone number assignments are preserved. Voice calls and SMS will stop working until credentials are reconfigured.
319
-
320
- **Note:** Clearing credentials is a global operation — it removes credentials for all assistants, not just the current one. The `assistantId` parameter is accepted but ignored. In multi-assistant setups, warn the user that clearing credentials will affect all assistants sharing this Twilio account.
211
+ Phone number assignments are preserved. Voice calls will stop until credentials are reconfigured.
321
212
 
322
213
  ## Troubleshooting
323
214
 
324
215
  ### "Twilio credentials not configured"
325
216
 
326
- Run Steps 2 and 3 to store credentials and assign a phone number.
217
+ Run Steps 2 and 3.
327
218
 
328
219
  ### "No phone number assigned"
329
220
 
330
- Run Step 3 to provision or assign a phone number.
221
+ Run Step 3.
331
222
 
332
223
  ### Phone number provisioning fails
333
224
 
334
- - Verify Twilio credentials are correct
335
- - On trial accounts, you may already have a free number check "Active Numbers" in the Console
336
- - Ensure the Twilio account has sufficient balance for paid accounts
225
+ - Verify credentials are correct
226
+ - Trial accounts may already have a free number -- check "Active Numbers" in the Console
227
+ - Ensure the account has sufficient balance
337
228
 
338
- ### Calls/SMS fail after setup
229
+ ### Calls fail after setup
339
230
 
340
- - Verify public ingress is running (`ingress.publicBaseUrl` must be set)
231
+ - Verify ingress is running: `assistant config get ingress.publicBaseUrl`
341
232
  - For calls, ensure `calls.enabled` is `true`
342
- - On trial accounts, outbound calls and SMS can only reach verified numbers
233
+ - Trial accounts can only reach verified numbers
234
+
235
+ ### Incoming calls not reaching the assistant
343
236
 
344
- ### "Number not found" when assigning
237
+ Webhooks on the Twilio phone number may not match the current ingress URL. This happens when ngrok restarts with a new URL or webhooks were never configured.
345
238
 
346
- - The number must be owned by the same Twilio account
347
- - Use the list numbers endpoint to see available numbers
348
- - Ensure the number is in E.164 format (`+` followed by country code and number)
239
+ **Diagnose** -- fetch the number's current webhooks and compare to the expected URL:
240
+
241
+ ```bash
242
+ TWILIO_SID=$(assistant config get twilio.accountSid)
243
+ TWILIO_TOKEN=$(assistant credentials reveal twilio:auth_token)
244
+ PUBLIC_URL=$(assistant config get ingress.publicBaseUrl)
245
+ PHONE_NUMBER=$(assistant config get twilio.phoneNumber)
246
+
247
+ curl -s -u "$TWILIO_SID:$TWILIO_TOKEN" \
248
+ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_SID/IncomingPhoneNumbers.json?PhoneNumber=$PHONE_NUMBER"
249
+ ```
250
+
251
+ Check that `voice_url` and `status_callback` start with the current `ingress.publicBaseUrl`. If they don't match, update them:
252
+
253
+ ```bash
254
+ PHONE_SID=<PN sid from the response above>
255
+ curl -s -u "$TWILIO_SID:$TWILIO_TOKEN" -X POST \
256
+ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_SID/IncomingPhoneNumbers/$PHONE_SID.json" \
257
+ -d "VoiceUrl=$PUBLIC_URL/webhooks/twilio/voice" \
258
+ -d "StatusCallback=$PUBLIC_URL/webhooks/twilio/status"
259
+ ```