voicecc 1.2.12 → 1.2.13

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.
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Claude Voice</title>
7
- <script type="module" crossorigin src="/assets/index-DCeOdulF.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-DbjqXBdo.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-DeN1WDo9.css">
9
9
  </head>
10
10
  <body>
@@ -192,18 +192,18 @@ export function agentsRoutes(): Hono {
192
192
  }
193
193
 
194
194
  // Place the actual Twilio call
195
- const client = twilioSdk(accountSid, authToken);
196
- const numbers = await client.incomingPhoneNumbers.list({ limit: 1 });
197
- if (numbers.length === 0) {
198
- return c.json({ error: "No Twilio phone numbers found on this account" }, 400);
195
+ const fromNumber = envVars.TWILIO_PHONE_NUMBER;
196
+ if (!fromNumber) {
197
+ return c.json({ error: "No Twilio phone number selected. Select one in Twilio settings." }, 400);
199
198
  }
200
199
 
200
+ const client = twilioSdk(accountSid, authToken);
201
201
  const tunnelHost = tunnelUrl.replace(/^https?:\/\//, "");
202
202
  const twiml = `<Response><Connect><Stream url="wss://${tunnelHost}/media/${token}?agentId=${id}" /></Connect></Response>`;
203
203
 
204
204
  const call = await client.calls.create({
205
205
  to: userPhone,
206
- from: numbers[0].phoneNumber,
206
+ from: fromNumber,
207
207
  twiml,
208
208
  });
209
209
 
@@ -134,17 +134,15 @@ export function twilioRoutes(): Hono {
134
134
  }
135
135
 
136
136
  try {
137
- const client = twilioSdk(accountSid, authToken);
138
-
139
- // Get the first Twilio phone number to use as caller ID
140
- const numbers = await client.incomingPhoneNumbers.list({ limit: 1 });
141
- if (numbers.length === 0) {
142
- return c.json({ error: "No Twilio phone numbers found on this account" }, 400);
137
+ const fromNumber = envVars.TWILIO_PHONE_NUMBER;
138
+ if (!fromNumber) {
139
+ return c.json({ error: "No Twilio phone number selected. Select one in step 2." }, 400);
143
140
  }
144
141
 
142
+ const client = twilioSdk(accountSid, authToken);
145
143
  const call = await client.calls.create({
146
144
  to,
147
- from: numbers[0].phoneNumber,
145
+ from: fromNumber,
148
146
  twiml: '<Response><Say>This is a test call from your voice assistant. If you can hear this, your Twilio setup is working correctly. Goodbye!</Say></Response>',
149
147
  });
150
148
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "voicecc",
3
- "version": "1.2.12",
3
+ "version": "1.2.13",
4
4
  "description": "Voice Agent Platform running on Claude Code -- create and deploy conversational voice agents with ElevenLabs STT/TTS and VAD",
5
5
  "repository": {
6
6
  "type": "git",
@@ -70,26 +70,36 @@ export async function startTwilioServer(_dashboardPort: number, tunnelUrl?: stri
70
70
  throw new Error("TWILIO_AUTH_TOKEN is not set in .env");
71
71
  }
72
72
 
73
+ if (!envVars.TWILIO_PHONE_NUMBER) {
74
+ throw new Error("TWILIO_PHONE_NUMBER is not set in .env");
75
+ }
76
+
73
77
  const accountSid = envVars.TWILIO_ACCOUNT_SID;
74
78
  const webhookUrl = tunnelUrl ? `${tunnelUrl}/api/twilio/incoming-call` : null;
75
79
 
76
80
  if (tunnelUrl && accountSid && envVars.TWILIO_AUTH_TOKEN) {
77
81
  const client = twilioSdk(accountSid, envVars.TWILIO_AUTH_TOKEN);
78
82
 
79
- // Update all phone numbers on the account to point to the new webhook URL
83
+ // Update the selected phone number's webhook URL
84
+ const selectedNumber = envVars.TWILIO_PHONE_NUMBER;
80
85
  try {
81
- const numbers = await client.incomingPhoneNumbers.list();
82
- for (const num of numbers) {
83
- await client.incomingPhoneNumbers(num.sid).update({
84
- voiceUrl: webhookUrl!,
85
- voiceMethod: "POST",
86
- });
87
- }
88
- if (numbers.length > 0) {
89
- console.log(`Updated ${numbers.length} phone number(s) webhook to ${webhookUrl}`);
86
+ if (selectedNumber) {
87
+ // Find the SID for the selected number and update only that one
88
+ const numbers = await client.incomingPhoneNumbers.list({ phoneNumber: selectedNumber });
89
+ if (numbers.length > 0) {
90
+ await client.incomingPhoneNumbers(numbers[0].sid).update({
91
+ voiceUrl: webhookUrl!,
92
+ voiceMethod: "POST",
93
+ });
94
+ console.log(`Updated webhook for ${selectedNumber} to ${webhookUrl}`);
95
+ } else {
96
+ console.error(`Selected phone number ${selectedNumber} not found on Twilio account`);
97
+ }
98
+ } else {
99
+ console.warn("No TWILIO_PHONE_NUMBER configured, skipping webhook setup");
90
100
  }
91
101
  } catch (err) {
92
- console.error(`Failed to update phone number webhooks: ${err}`);
102
+ console.error(`Failed to update phone number webhook: ${err}`);
93
103
  }
94
104
  }
95
105
 
@@ -89,6 +89,7 @@ class VoiceServerConfig:
89
89
  project_root: str
90
90
  twilio_account_sid: str
91
91
  twilio_auth_token: str
92
+ twilio_phone_number: str
92
93
  user_phone_number: str
93
94
  max_concurrent_sessions: int
94
95
 
@@ -127,6 +128,7 @@ def load_config() -> VoiceServerConfig:
127
128
  project_root=PROJECT_ROOT,
128
129
  twilio_account_sid=os.environ.get("TWILIO_ACCOUNT_SID", ""),
129
130
  twilio_auth_token=os.environ.get("TWILIO_AUTH_TOKEN", ""),
131
+ twilio_phone_number=os.environ.get("TWILIO_PHONE_NUMBER", ""),
130
132
  user_phone_number=os.environ.get("USER_PHONE_NUMBER", ""),
131
133
  max_concurrent_sessions=int(
132
134
  os.environ.get("MAX_CONCURRENT_SESSIONS") or DEFAULT_MAX_CONCURRENT_SESSIONS
@@ -414,14 +414,14 @@ async def initiate_agent_call(agent: Agent, client: ClaudeSDKClient) -> str:
414
414
  # Schedule cleanup for unanswered calls
415
415
  asyncio.create_task(_cleanup_pending_call(token))
416
416
 
417
- # Get from number via Twilio API
417
+ # Get the configured Twilio phone number
418
418
  from twilio.rest import Client as TwilioClient
419
419
 
420
+ from_number: str = _config.twilio_phone_number
421
+ if not from_number:
422
+ raise RuntimeError("No TWILIO_PHONE_NUMBER configured")
423
+
420
424
  twilio_client = TwilioClient(_config.twilio_account_sid, _config.twilio_auth_token)
421
- numbers = twilio_client.incoming_phone_numbers.list(limit=1)
422
- if not numbers:
423
- raise RuntimeError("No Twilio phone numbers found on the account")
424
- from_number: str = numbers[0].phone_number or ""
425
425
 
426
426
  # Build TwiML with WebSocket stream URL
427
427
  tunnel_host = tunnel_url.replace("https://", "").replace("http://", "")