phonic 0.16.3 → 0.18.0

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/README.md CHANGED
@@ -10,8 +10,11 @@ Node.js library for the Phonic API.
10
10
  - [Get conversation by id](#get-conversation-by-id)
11
11
  - [Get conversation by external id](#get-conversation-by-external-id)
12
12
  - [List conversations](#list-conversations)
13
- - [Speech-to-speech via WebSocket](#speech-to-speech-via-websocket)
13
+ - [STS outbound call](#sts-outbound-call)
14
+ - [STS outbound call using own Twilio account](#sts-outbound-call-using-own-twilio-account)
15
+ - [STS via WebSocket](#sts-via-websocket)
14
16
  - [Messages that Phonic sends back to you](#messages-that-phonic-sends-back-to-you)
17
+
15
18
 
16
19
  ## Installation
17
20
 
@@ -45,7 +48,7 @@ if (error === null) {
45
48
  ### Get voice by id
46
49
 
47
50
  ```ts
48
- const { data, error } = await phonic.voices.get("meredith");
51
+ const { data, error } = await phonic.voices.get("greta");
49
52
 
50
53
  if (error === null) {
51
54
  console.log(data.voice);
@@ -91,7 +94,52 @@ if (error === null) {
91
94
  }
92
95
  ```
93
96
 
94
- ### Speech-to-speech via WebSocket
97
+ ### STS outbound call
98
+
99
+ ```ts
100
+ const { data, error } = await phonic.sts.outboundCall("+19189396241", {
101
+ welcome_message: "Hello, how can I help you?",
102
+
103
+ // Optional fields
104
+ project: "main",
105
+ system_prompt: "You are a helpful assistant.",
106
+ voice_id: "greta",
107
+ enable_silent_audio_fallback: true,
108
+ vad_prebuffer_duration_ms: 1800,
109
+ vad_min_speech_duration_ms: 40,
110
+ vad_min_silence_duration_ms: 550,
111
+ vad_threshold: 0.6,
112
+ });
113
+ ```
114
+
115
+ ### STS outbound call using own Twilio account
116
+
117
+ ```ts
118
+ const { data, error } = await phonic.sts.twilio.outboundCall(
119
+ {
120
+ account_sid: "AC...",
121
+ api_key_sid: "SK...",
122
+ api_key_secret: "...",
123
+ from_phone_number: "+19189372905",
124
+ to_phone_number: "+19189396241",
125
+ },
126
+ {
127
+ welcome_message: "Hello, how can I help you?",
128
+
129
+ // Optional fields
130
+ project: "main",
131
+ system_prompt: "You are a helpful assistant.",
132
+ voice_id: "greta",
133
+ enable_silent_audio_fallback: true,
134
+ vad_prebuffer_duration_ms: 1800,
135
+ vad_min_speech_duration_ms: 40,
136
+ vad_min_silence_duration_ms: 550,
137
+ vad_threshold: 0.6,
138
+ }
139
+ );
140
+ ```
141
+
142
+ ### STS via WebSocket
95
143
 
96
144
  To start a conversation, open a WebSocket connection:
97
145
 
@@ -103,8 +151,13 @@ const phonicWebSocket = phonic.sts.websocket({
103
151
  project: "main",
104
152
  system_prompt: "You are a helpful assistant.",
105
153
  welcome_message: "Hello, how can I help you?",
106
- voice_id: "meredith",
107
- output_format: "mulaw_8000"
154
+ voice_id: "greta",
155
+ output_format: "mulaw_8000",
156
+ enable_silent_audio_fallback: true,
157
+ vad_prebuffer_duration_ms: 1800,
158
+ vad_min_speech_duration_ms: 40,
159
+ vad_min_silence_duration_ms: 550,
160
+ vad_threshold: 0.6,
108
161
  });
109
162
  ```
110
163
 
package/dist/index.d.mts CHANGED
@@ -7,17 +7,21 @@ type PhonicConfig = {
7
7
  };
8
8
  type FetchOptions = {
9
9
  method: "GET";
10
- };
11
- type ErrorResponse = {
12
- message: string;
13
- code?: string;
10
+ headers?: Record<string, string>;
11
+ } | {
12
+ method: "POST";
13
+ headers?: Record<string, string>;
14
+ body: string;
14
15
  };
15
16
  type DataOrError<T> = Promise<{
16
17
  data: T;
17
18
  error: null;
18
19
  } | {
19
20
  data: null;
20
- error: ErrorResponse;
21
+ error: {
22
+ message: string;
23
+ code?: string;
24
+ };
21
25
  }>;
22
26
  type ISODate = `${string}-${string}-${string}`;
23
27
  type ISODateTime$1 = `${string}Z`;
@@ -121,6 +125,31 @@ type PhonicSTSWebSocketResponseMessage = {
121
125
  type OnMessageCallback = (message: PhonicSTSWebSocketResponseMessage) => void;
122
126
  type OnCloseCallback = (event: WebSocket.CloseEvent) => void;
123
127
  type OnErrorCallback = (event: WebSocket.ErrorEvent) => void;
128
+ type PhonicSTSOutboundCallConfig = Omit<PhonicSTSConfig, "input_format" | "output_format"> & {
129
+ welcome_message: string;
130
+ };
131
+ type OutboundCallSuccessResponse = {
132
+ success: true;
133
+ };
134
+
135
+ type PhonicSTSTwilioOutboundCallParams = {
136
+ account_sid: string;
137
+ api_key_sid: string;
138
+ api_key_secret: string;
139
+ from_phone_number: string;
140
+ to_phone_number: string;
141
+ };
142
+ type PhonicSTSTwilioOutboundCallConfig = PhonicSTSOutboundCallConfig;
143
+ type TwilioOutboundCallSuccessResponse = {
144
+ success: true;
145
+ callSid: string;
146
+ };
147
+
148
+ declare class Twilio {
149
+ private readonly phonic;
150
+ constructor(phonic: Phonic);
151
+ outboundCall(params: PhonicSTSTwilioOutboundCallParams, config: PhonicSTSTwilioOutboundCallConfig): DataOrError<TwilioOutboundCallSuccessResponse>;
152
+ }
124
153
 
125
154
  declare class PhonicSTSWebSocket {
126
155
  private readonly ws;
@@ -148,8 +177,10 @@ declare class PhonicSTSWebSocket {
148
177
 
149
178
  declare class SpeechToSpeech {
150
179
  private readonly phonic;
180
+ readonly twilio: Twilio;
151
181
  constructor(phonic: Phonic);
152
182
  websocket(config: PhonicSTSConfig): PhonicSTSWebSocket;
183
+ outboundCall(toPhoneNumber: string, config: PhonicSTSOutboundCallConfig): DataOrError<OutboundCallSuccessResponse>;
153
184
  }
154
185
 
155
186
  type Voice = {
@@ -184,7 +215,20 @@ declare class Phonic {
184
215
  fetchRequest<T>(path: string, options: FetchOptions): DataOrError<T>;
185
216
  get<T>(path: string): Promise<{
186
217
  data: null;
187
- error: ErrorResponse;
218
+ error: {
219
+ message: string;
220
+ code?: string;
221
+ };
222
+ } | {
223
+ data: T;
224
+ error: null;
225
+ }>;
226
+ post<T>(path: string, body: Record<string, unknown>, headers?: Record<string, string>): Promise<{
227
+ data: null;
228
+ error: {
229
+ message: string;
230
+ code?: string;
231
+ };
188
232
  } | {
189
233
  data: T;
190
234
  error: null;
package/dist/index.d.ts CHANGED
@@ -7,17 +7,21 @@ type PhonicConfig = {
7
7
  };
8
8
  type FetchOptions = {
9
9
  method: "GET";
10
- };
11
- type ErrorResponse = {
12
- message: string;
13
- code?: string;
10
+ headers?: Record<string, string>;
11
+ } | {
12
+ method: "POST";
13
+ headers?: Record<string, string>;
14
+ body: string;
14
15
  };
15
16
  type DataOrError<T> = Promise<{
16
17
  data: T;
17
18
  error: null;
18
19
  } | {
19
20
  data: null;
20
- error: ErrorResponse;
21
+ error: {
22
+ message: string;
23
+ code?: string;
24
+ };
21
25
  }>;
22
26
  type ISODate = `${string}-${string}-${string}`;
23
27
  type ISODateTime$1 = `${string}Z`;
@@ -121,6 +125,31 @@ type PhonicSTSWebSocketResponseMessage = {
121
125
  type OnMessageCallback = (message: PhonicSTSWebSocketResponseMessage) => void;
122
126
  type OnCloseCallback = (event: WebSocket.CloseEvent) => void;
123
127
  type OnErrorCallback = (event: WebSocket.ErrorEvent) => void;
128
+ type PhonicSTSOutboundCallConfig = Omit<PhonicSTSConfig, "input_format" | "output_format"> & {
129
+ welcome_message: string;
130
+ };
131
+ type OutboundCallSuccessResponse = {
132
+ success: true;
133
+ };
134
+
135
+ type PhonicSTSTwilioOutboundCallParams = {
136
+ account_sid: string;
137
+ api_key_sid: string;
138
+ api_key_secret: string;
139
+ from_phone_number: string;
140
+ to_phone_number: string;
141
+ };
142
+ type PhonicSTSTwilioOutboundCallConfig = PhonicSTSOutboundCallConfig;
143
+ type TwilioOutboundCallSuccessResponse = {
144
+ success: true;
145
+ callSid: string;
146
+ };
147
+
148
+ declare class Twilio {
149
+ private readonly phonic;
150
+ constructor(phonic: Phonic);
151
+ outboundCall(params: PhonicSTSTwilioOutboundCallParams, config: PhonicSTSTwilioOutboundCallConfig): DataOrError<TwilioOutboundCallSuccessResponse>;
152
+ }
124
153
 
125
154
  declare class PhonicSTSWebSocket {
126
155
  private readonly ws;
@@ -148,8 +177,10 @@ declare class PhonicSTSWebSocket {
148
177
 
149
178
  declare class SpeechToSpeech {
150
179
  private readonly phonic;
180
+ readonly twilio: Twilio;
151
181
  constructor(phonic: Phonic);
152
182
  websocket(config: PhonicSTSConfig): PhonicSTSWebSocket;
183
+ outboundCall(toPhoneNumber: string, config: PhonicSTSOutboundCallConfig): DataOrError<OutboundCallSuccessResponse>;
153
184
  }
154
185
 
155
186
  type Voice = {
@@ -184,7 +215,20 @@ declare class Phonic {
184
215
  fetchRequest<T>(path: string, options: FetchOptions): DataOrError<T>;
185
216
  get<T>(path: string): Promise<{
186
217
  data: null;
187
- error: ErrorResponse;
218
+ error: {
219
+ message: string;
220
+ code?: string;
221
+ };
222
+ } | {
223
+ data: T;
224
+ error: null;
225
+ }>;
226
+ post<T>(path: string, body: Record<string, unknown>, headers?: Record<string, string>): Promise<{
227
+ data: null;
228
+ error: {
229
+ message: string;
230
+ code?: string;
231
+ };
188
232
  } | {
189
233
  data: T;
190
234
  error: null;
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ __export(index_exports, {
35
35
  module.exports = __toCommonJS(index_exports);
36
36
 
37
37
  // package.json
38
- var version = "0.16.3";
38
+ var version = "0.18.0";
39
39
 
40
40
  // src/conversations/index.ts
41
41
  var Conversations = class {
@@ -85,6 +85,29 @@ var Conversations = class {
85
85
  // src/sts/index.ts
86
86
  var import_ws = __toESM(require("ws"));
87
87
 
88
+ // src/sts/twilio/index.ts
89
+ var Twilio = class {
90
+ constructor(phonic) {
91
+ this.phonic = phonic;
92
+ }
93
+ async outboundCall(params, config) {
94
+ const response = await this.phonic.post(
95
+ "/sts/twilio/outbound_call",
96
+ {
97
+ from_phone_number: params.from_phone_number,
98
+ to_phone_number: params.to_phone_number,
99
+ config
100
+ },
101
+ {
102
+ "X-Twilio-Account-Sid": params.account_sid,
103
+ "X-Twilio-Api-Key-Sid": params.api_key_sid,
104
+ "X-Twilio-Api-Key-Secret": params.api_key_secret
105
+ }
106
+ );
107
+ return response;
108
+ }
109
+ };
110
+
88
111
  // src/sts/websocket.ts
89
112
  var PhonicSTSWebSocket = class {
90
113
  constructor(ws, config) {
@@ -188,7 +211,9 @@ var PhonicSTSWebSocket = class {
188
211
  var SpeechToSpeech = class {
189
212
  constructor(phonic) {
190
213
  this.phonic = phonic;
214
+ this.twilio = new Twilio(phonic);
191
215
  }
216
+ twilio;
192
217
  websocket(config) {
193
218
  const wsBaseUrl = this.phonic.baseUrl.replace(/^http/, "ws");
194
219
  const queryString = new URLSearchParams({
@@ -202,6 +227,16 @@ var SpeechToSpeech = class {
202
227
  });
203
228
  return new PhonicSTSWebSocket(ws, config);
204
229
  }
230
+ async outboundCall(toPhoneNumber, config) {
231
+ const response = await this.phonic.post(
232
+ "/sts/outbound_call",
233
+ {
234
+ to_phone_number: toPhoneNumber,
235
+ config
236
+ }
237
+ );
238
+ return response;
239
+ }
205
240
  };
206
241
 
207
242
  // src/voices/index.ts
@@ -256,9 +291,13 @@ var Phonic = class {
256
291
  sts = new SpeechToSpeech(this);
257
292
  async fetchRequest(path, options) {
258
293
  try {
294
+ const { headers, ...restOptions } = options;
259
295
  const response = await fetch(`${this.baseUrl}/v1${path}`, {
260
- headers: this.headers,
261
- ...options
296
+ headers: {
297
+ ...this.headers,
298
+ ...headers
299
+ },
300
+ ...restOptions
262
301
  });
263
302
  if (response.ok) {
264
303
  const data = await response.json();
@@ -294,6 +333,13 @@ var Phonic = class {
294
333
  async get(path) {
295
334
  return this.fetchRequest(path, { method: "GET" });
296
335
  }
336
+ async post(path, body, headers) {
337
+ return this.fetchRequest(path, {
338
+ method: "POST",
339
+ body: JSON.stringify(body),
340
+ headers
341
+ });
342
+ }
297
343
  };
298
344
  // Annotate the CommonJS export names for ESM import in node:
299
345
  0 && (module.exports = {
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "0.16.3";
2
+ var version = "0.18.0";
3
3
 
4
4
  // src/conversations/index.ts
5
5
  var Conversations = class {
@@ -49,6 +49,29 @@ var Conversations = class {
49
49
  // src/sts/index.ts
50
50
  import WebSocket from "ws";
51
51
 
52
+ // src/sts/twilio/index.ts
53
+ var Twilio = class {
54
+ constructor(phonic) {
55
+ this.phonic = phonic;
56
+ }
57
+ async outboundCall(params, config) {
58
+ const response = await this.phonic.post(
59
+ "/sts/twilio/outbound_call",
60
+ {
61
+ from_phone_number: params.from_phone_number,
62
+ to_phone_number: params.to_phone_number,
63
+ config
64
+ },
65
+ {
66
+ "X-Twilio-Account-Sid": params.account_sid,
67
+ "X-Twilio-Api-Key-Sid": params.api_key_sid,
68
+ "X-Twilio-Api-Key-Secret": params.api_key_secret
69
+ }
70
+ );
71
+ return response;
72
+ }
73
+ };
74
+
52
75
  // src/sts/websocket.ts
53
76
  var PhonicSTSWebSocket = class {
54
77
  constructor(ws, config) {
@@ -152,7 +175,9 @@ var PhonicSTSWebSocket = class {
152
175
  var SpeechToSpeech = class {
153
176
  constructor(phonic) {
154
177
  this.phonic = phonic;
178
+ this.twilio = new Twilio(phonic);
155
179
  }
180
+ twilio;
156
181
  websocket(config) {
157
182
  const wsBaseUrl = this.phonic.baseUrl.replace(/^http/, "ws");
158
183
  const queryString = new URLSearchParams({
@@ -166,6 +191,16 @@ var SpeechToSpeech = class {
166
191
  });
167
192
  return new PhonicSTSWebSocket(ws, config);
168
193
  }
194
+ async outboundCall(toPhoneNumber, config) {
195
+ const response = await this.phonic.post(
196
+ "/sts/outbound_call",
197
+ {
198
+ to_phone_number: toPhoneNumber,
199
+ config
200
+ }
201
+ );
202
+ return response;
203
+ }
169
204
  };
170
205
 
171
206
  // src/voices/index.ts
@@ -220,9 +255,13 @@ var Phonic = class {
220
255
  sts = new SpeechToSpeech(this);
221
256
  async fetchRequest(path, options) {
222
257
  try {
258
+ const { headers, ...restOptions } = options;
223
259
  const response = await fetch(`${this.baseUrl}/v1${path}`, {
224
- headers: this.headers,
225
- ...options
260
+ headers: {
261
+ ...this.headers,
262
+ ...headers
263
+ },
264
+ ...restOptions
226
265
  });
227
266
  if (response.ok) {
228
267
  const data = await response.json();
@@ -258,6 +297,13 @@ var Phonic = class {
258
297
  async get(path) {
259
298
  return this.fetchRequest(path, { method: "GET" });
260
299
  }
300
+ async post(path, body, headers) {
301
+ return this.fetchRequest(path, {
302
+ method: "POST",
303
+ body: JSON.stringify(body),
304
+ headers
305
+ });
306
+ }
261
307
  };
262
308
  export {
263
309
  Phonic
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phonic",
3
- "version": "0.16.3",
3
+ "version": "0.18.0",
4
4
  "description": "Phonic Node.js SDK",
5
5
  "scripts": {
6
6
  "build": "tsup",
@@ -33,16 +33,17 @@
33
33
  "url": "https://github.com/Phonic-Co/phonic-node/issues"
34
34
  },
35
35
  "dependencies": {
36
- "ws": "8.18.1"
36
+ "ws": "8.18.2"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@biomejs/biome": "1.9.4",
40
40
  "@changesets/changelog-github": "0.5.1",
41
- "@changesets/cli": "2.28.1",
42
- "@types/bun": "1.2.8",
41
+ "@changesets/cli": "2.29.2",
42
+ "@types/bun": "1.2.12",
43
+ "@types/ws": "8.18.1",
43
44
  "tsup": "8.4.0",
44
45
  "typescript": "5.8.3",
45
- "zod": "3.24.2"
46
+ "zod": "3.24.4"
46
47
  },
47
48
  "files": ["dist/**"],
48
49
  "author": {