@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.
- package/ARCHITECTURE.md +3 -3
- package/README.md +13 -13
- package/bun.lock +80 -24
- package/docs/architecture/integrations.md +126 -128
- package/docs/runbook-trusted-contacts.md +1 -1
- package/docs/trusted-contact-access.md +12 -12
- package/package.json +3 -1
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +0 -14
- package/src/__tests__/app-bundler.test.ts +209 -0
- package/src/__tests__/app-compiler.test.ts +279 -0
- package/src/__tests__/app-executors.test.ts +293 -483
- package/src/__tests__/app-migration.test.ts +148 -0
- package/src/__tests__/app-routes-csp.test.ts +202 -0
- package/src/__tests__/avatar-e2e.test.ts +452 -0
- package/src/__tests__/avatar-generator.test.ts +193 -0
- package/src/__tests__/avatar-router.test.ts +186 -0
- package/src/__tests__/browser-download-timeout.test.ts +28 -0
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +9 -9
- package/src/__tests__/call-domain.test.ts +3 -7
- package/src/__tests__/credential-security-e2e.test.ts +19 -12
- package/src/__tests__/credentials-cli.test.ts +30 -4
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +1 -1
- package/src/__tests__/handlers-slack-config.test.ts +0 -72
- package/src/__tests__/handlers-telegram-config.test.ts +19 -12
- package/src/__tests__/handlers-twitter-config.test.ts +105 -48
- package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
- package/src/__tests__/integration-status.test.ts +15 -5
- package/src/__tests__/integrations-cli.test.ts +1 -1
- package/src/__tests__/invite-redemption-service.test.ts +62 -7
- package/src/__tests__/ipc-snapshot.test.ts +0 -8
- package/src/__tests__/managed-avatar-client.test.ts +280 -0
- package/src/__tests__/mcp-cli.test.ts +3 -3
- package/src/__tests__/oauth-cli.test.ts +203 -0
- package/src/__tests__/relay-server.test.ts +3 -3
- package/src/__tests__/secret-onetime-send.test.ts +19 -12
- package/src/__tests__/secure-keys.test.ts +78 -0
- package/src/__tests__/session-messaging-secret-redirect.test.ts +3 -0
- package/src/__tests__/slack-channel-config.test.ts +23 -16
- package/src/__tests__/slack-share-routes.test.ts +263 -0
- package/src/__tests__/sms-messaging-provider.test.ts +3 -1
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +7 -7
- package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
- package/src/__tests__/trusted-contact-verification.test.ts +10 -10
- package/src/__tests__/twilio-config.test.ts +15 -36
- package/src/__tests__/twilio-provider.test.ts +4 -0
- package/src/__tests__/twitter-auth-handler.test.ts +27 -14
- package/src/__tests__/twitter-cli-error-shaping.test.ts +1 -1
- package/src/__tests__/twitter-cli-routing.test.ts +38 -53
- package/src/__tests__/twitter-oauth-client.test.ts +18 -47
- package/src/__tests__/voice-invite-redemption.test.ts +27 -3
- package/src/amazon/cart.ts +1 -1
- package/src/amazon/client.ts +89 -7
- package/src/approvals/guardian-request-resolvers.ts +2 -2
- package/src/bundler/app-bundler.ts +77 -32
- package/src/bundler/app-compiler.ts +195 -0
- package/src/bundler/manifest.ts +1 -1
- package/src/bundler/package-resolver.ts +185 -0
- package/src/calls/call-domain.ts +4 -14
- package/src/calls/relay-server.ts +2 -2
- package/src/calls/twilio-config.ts +5 -24
- package/src/calls/twilio-rest.ts +19 -5
- package/src/cli/amazon.ts +74 -249
- package/src/cli/audit.ts +2 -2
- package/src/cli/autonomy.ts +9 -9
- package/src/cli/channels.ts +5 -5
- package/src/cli/completions.ts +27 -27
- package/src/cli/config.ts +14 -14
- package/src/cli/contacts.ts +27 -27
- package/src/cli/credentials.ts +28 -28
- package/src/cli/dev.ts +2 -2
- package/src/cli/doctor.ts +2 -2
- package/src/cli/email.ts +82 -82
- package/src/cli/influencer.ts +13 -13
- package/src/cli/integrations.ts +19 -144
- package/src/cli/keys.ts +10 -10
- package/src/cli/map.ts +4 -4
- package/src/cli/mcp.ts +17 -17
- package/src/cli/memory.ts +18 -18
- package/src/cli/notifications.ts +13 -13
- package/src/cli/oauth.ts +77 -0
- package/src/cli/program.ts +2 -0
- package/src/cli/sequence.ts +27 -27
- package/src/cli/sessions.ts +12 -12
- package/src/cli/trust.ts +8 -8
- package/src/cli/twitter.ts +124 -70
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/agentmail/SKILL.md +34 -34
- package/src/config/bundled-skills/amazon/SKILL.md +54 -54
- package/src/config/bundled-skills/app-builder/SKILL.md +137 -3
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +10 -4
- package/src/config/bundled-skills/configure-settings/SKILL.md +18 -18
- package/src/config/bundled-skills/contacts/SKILL.md +12 -12
- package/src/config/bundled-skills/doordash/lib/client.ts +7 -9
- package/src/config/bundled-skills/email-setup/SKILL.md +4 -4
- package/src/config/bundled-skills/frontend-design/icon.svg +16 -0
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +143 -162
- package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +4 -4
- package/src/config/bundled-skills/influencer/SKILL.md +13 -13
- package/src/config/bundled-skills/mcp-setup/SKILL.md +11 -11
- package/src/config/bundled-skills/phone-calls/SKILL.md +48 -54
- package/src/config/bundled-skills/public-ingress/SKILL.md +6 -6
- package/src/config/bundled-skills/slack-app-setup/SKILL.md +1 -1
- package/src/config/bundled-skills/sms-setup/SKILL.md +3 -3
- package/src/config/bundled-skills/telegram-setup/SKILL.md +2 -2
- package/src/config/bundled-skills/twilio-setup/SKILL.md +136 -225
- package/src/config/bundled-skills/twitter/SKILL.md +68 -44
- package/src/config/bundled-skills/voice-setup/SKILL.md +2 -2
- package/src/config/core-schema.ts +26 -0
- package/src/config/env.ts +4 -0
- package/src/config/feature-flag-registry.json +9 -1
- package/src/config/schema.ts +8 -0
- package/src/config/system-prompt.ts +6 -3
- package/src/config/templates/BOOTSTRAP.md +7 -5
- package/src/contacts/contacts-write.ts +5 -1
- package/src/daemon/handlers/apps.ts +31 -4
- package/src/daemon/handlers/config-ingress.ts +3 -3
- package/src/daemon/handlers/config-integrations.ts +120 -49
- package/src/daemon/handlers/config-slack-channel.ts +26 -7
- package/src/daemon/handlers/config-slack.ts +1 -54
- package/src/daemon/handlers/config-telegram.ts +28 -10
- package/src/daemon/handlers/config.ts +1 -4
- package/src/daemon/handlers/twitter-auth.ts +11 -4
- package/src/daemon/ipc-contract/apps.ts +0 -13
- package/src/daemon/ipc-contract-inventory.json +0 -2
- package/src/daemon/lifecycle.ts +8 -1
- package/src/daemon/session-messaging.ts +2 -2
- package/src/daemon/tool-side-effects.ts +30 -0
- package/src/email/providers/agentmail.ts +1 -1
- package/src/email/providers/index.ts +1 -1
- package/src/email/service.ts +1 -1
- package/src/gallery/default-gallery.ts +538 -0
- package/src/gallery/gallery-manifest.ts +5 -1
- package/src/influencer/client.ts +8 -6
- package/src/mcp/client.ts +1 -1
- package/src/media/avatar-router.ts +99 -0
- package/src/media/avatar-types.ts +60 -0
- package/src/media/managed-avatar-client.ts +189 -0
- package/src/memory/app-migration.ts +114 -0
- package/src/memory/app-store.ts +11 -0
- package/src/memory/qdrant-client.ts +1 -1
- package/src/messaging/providers/slack/client.ts +12 -2
- package/src/messaging/providers/sms/adapter.ts +6 -10
- package/src/migrations/data-layout.ts +8 -1
- package/src/oauth/token-persistence.ts +9 -6
- package/src/runtime/assistant-scope.ts +5 -0
- package/src/runtime/auth/route-policy.ts +4 -0
- package/src/runtime/channel-readiness-service.ts +9 -4
- package/src/runtime/gateway-internal-client.ts +11 -3
- package/src/runtime/http-server.ts +2 -0
- package/src/runtime/invite-redemption-service.ts +23 -13
- package/src/runtime/middleware/twilio-validation.ts +2 -2
- package/src/runtime/routes/app-routes.ts +131 -3
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +3 -3
- package/src/runtime/routes/integration-routes.ts +2 -2
- package/src/runtime/routes/slack-share-routes.ts +235 -0
- package/src/runtime/routes/twilio-routes.ts +47 -34
- package/src/schedule/integration-status.ts +2 -3
- package/src/security/token-manager.ts +11 -3
- package/src/tools/apps/executors.ts +116 -8
- package/src/tools/browser/browser-manager.ts +30 -2
- package/src/tools/browser/chrome-cdp.ts +31 -3
- package/src/tools/credentials/vault.ts +9 -7
- package/src/tools/executor.ts +4 -0
- package/src/tools/system/avatar-generator.ts +55 -34
- package/src/twitter/client.ts +1 -1
- package/src/twitter/oauth-client.ts +31 -43
- package/src/twitter/router.ts +25 -23
- package/src/util/platform.ts +5 -0
- 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
|
|
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
|
|
9
|
+
You are helping your user configure Twilio for voice calls. Walk through each step below.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Value Classification
|
|
12
12
|
|
|
13
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
53
|
-
-
|
|
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
|
-
|
|
24
|
+
## Retrieving Twilio Credentials
|
|
56
25
|
|
|
57
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
70
|
+
assistant credentials inspect "twilio:auth_token"
|
|
132
71
|
```
|
|
133
72
|
|
|
134
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
83
|
+
Retrieve credentials, then list numbers on the account:
|
|
164
84
|
|
|
165
85
|
```bash
|
|
166
|
-
curl -s -
|
|
167
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
92
|
+
### Option B: Provision a New Number
|
|
181
93
|
|
|
182
|
-
|
|
94
|
+
Retrieve credentials (see "Retrieving Twilio Credentials" above), then:
|
|
183
95
|
|
|
184
|
-
|
|
96
|
+
**Search for available numbers:**
|
|
185
97
|
|
|
186
|
-
|
|
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
|
-
|
|
103
|
+
- `AreaCode` is optional -- ask the user if they have a preference
|
|
104
|
+
- Replace `US` with another country code if needed
|
|
197
105
|
|
|
198
|
-
|
|
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 -
|
|
202
|
-
-
|
|
203
|
-
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
124
|
+
After choosing a number via any option, store it as a config value:
|
|
218
125
|
|
|
219
126
|
```bash
|
|
220
|
-
|
|
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
|
|
132
|
+
Twilio needs a publicly reachable URL for voice webhooks. Check if ingress is configured:
|
|
231
133
|
|
|
232
134
|
```bash
|
|
233
|
-
|
|
234
|
-
|
|
135
|
+
assistant config get ingress.publicBaseUrl
|
|
136
|
+
assistant config get ingress.enabled
|
|
235
137
|
```
|
|
236
138
|
|
|
237
|
-
If not configured, load
|
|
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
|
-
|
|
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
|
-
|
|
147
|
+
Set webhook URLs on the phone number so Twilio routes traffic to the assistant.
|
|
253
148
|
|
|
254
|
-
|
|
149
|
+
Retrieve credentials and config values:
|
|
255
150
|
|
|
256
151
|
```bash
|
|
257
|
-
|
|
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
|
-
|
|
158
|
+
Look up the phone number's SID:
|
|
261
159
|
|
|
262
|
-
|
|
263
|
-
-
|
|
264
|
-
|
|
265
|
-
|
|
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
|
-
|
|
165
|
+
Note the `sid` field (starts with `PN`) from the matching entry, then update webhooks:
|
|
268
166
|
|
|
269
|
-
|
|
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
|
-
|
|
174
|
+
## Step 5: Verify and Enable
|
|
272
175
|
|
|
273
|
-
-
|
|
176
|
+
Re-run the checks from Step 1 to confirm everything is set. Then enable voice calls:
|
|
274
177
|
|
|
275
|
-
|
|
178
|
+
```bash
|
|
179
|
+
assistant config set calls.enabled true
|
|
180
|
+
```
|
|
276
181
|
|
|
277
|
-
|
|
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
|
-
|
|
184
|
+
## Step 6: Guardian Verification (Optional)
|
|
285
185
|
|
|
286
|
-
|
|
186
|
+
Link the user's phone number as the trusted voice guardian so the assistant can verify inbound callers.
|
|
287
187
|
|
|
288
|
-
|
|
188
|
+
Load the guardian-verify-setup skill with `channel: "voice"`:
|
|
289
189
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
```bash
|
|
293
|
-
vellum integrations guardian status --channel voice --json
|
|
190
|
+
```
|
|
191
|
+
skill_load skill=guardian-verify-setup
|
|
294
192
|
```
|
|
295
193
|
|
|
296
|
-
|
|
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
|
-
|
|
196
|
+
To re-check guardian status later:
|
|
301
197
|
|
|
302
198
|
```bash
|
|
303
|
-
|
|
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
|
-
|
|
204
|
+
To disconnect Twilio:
|
|
312
205
|
|
|
313
206
|
```bash
|
|
314
|
-
|
|
315
|
-
|
|
207
|
+
assistant credentials delete twilio:auth_token
|
|
208
|
+
assistant config set twilio.accountSid ""
|
|
316
209
|
```
|
|
317
210
|
|
|
318
|
-
|
|
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
|
|
217
|
+
Run Steps 2 and 3.
|
|
327
218
|
|
|
328
219
|
### "No phone number assigned"
|
|
329
220
|
|
|
330
|
-
Run Step 3
|
|
221
|
+
Run Step 3.
|
|
331
222
|
|
|
332
223
|
### Phone number provisioning fails
|
|
333
224
|
|
|
334
|
-
- Verify
|
|
335
|
-
-
|
|
336
|
-
- Ensure the
|
|
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
|
|
229
|
+
### Calls fail after setup
|
|
339
230
|
|
|
340
|
-
- Verify
|
|
231
|
+
- Verify ingress is running: `assistant config get ingress.publicBaseUrl`
|
|
341
232
|
- For calls, ensure `calls.enabled` is `true`
|
|
342
|
-
-
|
|
233
|
+
- Trial accounts can only reach verified numbers
|
|
234
|
+
|
|
235
|
+
### Incoming calls not reaching the assistant
|
|
343
236
|
|
|
344
|
-
|
|
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
|
-
|
|
347
|
-
|
|
348
|
-
|
|
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
|
+
```
|