phonic 0.20.0 → 0.21.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
@@ -4,17 +4,24 @@ Node.js library for the Phonic API.
4
4
 
5
5
  - [Installation](#installation)
6
6
  - [Setup](#setup)
7
- - [Usage](#usage)
8
- - [Get voices](#get-voices)
9
- - [Get voice by id](#get-voice-by-id)
7
+ - [Agents](#agents)
8
+ - [List agents](#list-agents)
9
+ - [Get agent](#get-agent)
10
+ - [Create agent](#create-agent)
11
+ - [Update agent](#update-agent)
12
+ - [Delete agent](#delete-agent)
13
+ - [Voices](#voices)
14
+ - [List voices](#list-voices)
15
+ - [Get voice](#get-voice)
16
+ - [Conversations](#conversations)
17
+ - [List conversations](#list-conversations)
10
18
  - [Get conversation by id](#get-conversation-by-id)
11
19
  - [Get conversation by external id](#get-conversation-by-external-id)
12
- - [List conversations](#list-conversations)
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)
16
- - [Messages that Phonic sends back to you](#messages-that-phonic-sends-back-to-you)
17
-
20
+ - [STS outbound call](#sts-outbound-call)
21
+ - [STS outbound call using own Twilio account](#sts-outbound-call-using-own-twilio-account)
22
+ - [STS via WebSocket](#sts-via-websocket)
23
+ - [Messages that Phonic sends back to you](#messages-that-phonic-sends-back-to-you)
24
+ - [License](#license)
18
25
 
19
26
  ## Installation
20
27
 
@@ -32,69 +39,150 @@ import { Phonic } from "phonic";
32
39
  const phonic = new Phonic("ph_...");
33
40
  ```
34
41
 
35
- ## Usage
42
+ ## Agents
36
43
 
37
- ### Get voices
44
+ ### List agents
38
45
 
39
46
  ```ts
40
- const { data, error } = await phonic.voices.list({ model: "merritt" });
41
-
42
- if (error === null) {
43
- console.log(data.voices);
44
- }
47
+ const agentsResult = await phonic.agents.list({ project: "my-project" });
45
48
  ```
46
49
 
50
+ ### Get agent
47
51
 
48
- ### Get voice by id
52
+ ```ts
53
+ const agentResult = await phonic.agents.get("my-agent", { project: "my-project" });
54
+ ```
55
+
56
+ ### Create agent
49
57
 
50
58
  ```ts
51
- const { data, error } = await phonic.voices.get("grant");
59
+ const createAgentResult = await phonic.agents.create({
60
+ name: "my-agent",
61
+
62
+ // Optional fields
63
+ project: "my-project", // Defaults to "main"
64
+ phoneNumber: "assign-automatically", // Defaults to null
65
+ audioFormat: "mulaw_8000", // Defaults to "pcm_44100". Must be "mulaw_8000" when `phoneNumber` is "assign-automatically"
66
+ voiceId: "sarah", // Defaults to "grant"
67
+ welcomeMessage: "Hello, how can I help you?", // Defaults to ""
68
+ systemPrompt: "You are an expert in {{subject}}. Be kind to {{user_name}}.", // Defaults to "Respond in 1-2 sentences."
69
+ templateVariables: {
70
+ subject: {
71
+ defaultValue: "Maths"
72
+ },
73
+ user_name: {
74
+ defaultValue: null
75
+ }
76
+ },
77
+ tools: ["keypad_input", "natural_conversation_ending", "my-custom-tool"], // Defaults to []
78
+ noInputPokeSec: 30, // Defaults to null
79
+ noInputPokeText: "Hey, are you with me?", // Defaults to "Are you still there?"
80
+ noInputEndConversationSec: 150, // Defaults to 180
81
+ boostedKeywords: ["Salamanca Market", "Bonorong Wildlife Sanctuary"], // Defaults to []
82
+ configurationEndpoint: {
83
+ url: "https://myapp.com/webhooks/phonic-config",
84
+ headers: {
85
+ Authorization: "Bearer 123"
86
+ },
87
+ timeoutMs: 10000 // Defaults to 3000
88
+ } // Defaults to null
89
+ });
90
+ ```
52
91
 
53
- if (error === null) {
54
- console.log(data.voice);
55
- }
92
+ ### Update agent
93
+
94
+ ```ts
95
+ const updateAgentResult = await phonic.agents.update("my-agent", {
96
+ name: "my-updated-agent",
97
+
98
+ // Optional fields
99
+ project: "my-project",
100
+ phoneNumber: "assign-automatically", // or null
101
+ voiceId: "sarah",
102
+ audioFormat: "mulaw_8000", // Must be "mulaw_8000" when `phoneNumber` is "assign-automatically"
103
+ welcomeMessage: "Hello, how can I help you?",
104
+ systemPrompt: "You are an expert in {{subject}}. Be kind to {{user_name}}.",
105
+ templateVariables: {
106
+ subject: {
107
+ defaultValue: "Maths"
108
+ },
109
+ user_name: {
110
+ defaultValue: null
111
+ }
112
+ },
113
+ tools: ["keypad_input", "natural_conversation_ending", "my-custom-tool"],
114
+ noInputPokeSec: 30,
115
+ noInputPokeText: "Hey, are you with me?",
116
+ noInputEndConversationSec: 150,
117
+ boostedKeywords: ["Salamanca Market", "Bonorong Wildlife Sanctuary"],
118
+ configurationEndpoint: {
119
+ url: "https://myapp.com/webhooks/phonic-config",
120
+ headers: {
121
+ Authorization: "Bearer 123"
122
+ },
123
+ timeoutMs: 7000
124
+ }
125
+ });
56
126
  ```
57
127
 
58
- ### Get conversation by id
128
+ ### Delete agent
59
129
 
60
130
  ```ts
61
- const { data, error } = await phonic.conversations.get("conv_b1804883-5be4-42fe-b1cf-aa84450d5c84");
131
+ const deleteAgentResult = await phonic.agents.delete({
132
+ name: "my-agent",
62
133
 
63
- if (error === null) {
64
- console.log(data.conversation);
65
- }
134
+ // Optional fields
135
+ project: "my-project",
136
+ });
66
137
  ```
67
138
 
68
- ### Get conversation by external id
139
+ ## Voices
140
+
141
+ ### List voices
69
142
 
70
143
  ```ts
71
- const { data, error } = await phonic.conversations.getByExternalId({
72
- project: "main",
73
- externalId: "CAdb9c032c809fec7feb932ea4c96d71e1"
74
- });
144
+ const voicesResult = await phonic.voices.list({ model: "merritt" });
145
+ ```
75
146
 
76
- if (error === null) {
77
- console.log(data.conversation);
78
- }
147
+
148
+ ### Get voice
149
+
150
+ ```ts
151
+ const voiceResult = await phonic.voices.get("grant");
79
152
  ```
80
153
 
154
+ ## Conversations
155
+
81
156
  ### List conversations
82
157
 
83
158
  ```ts
84
- const { data, error } = await phonic.conversations.list({
159
+ const conversationsResult = await phonic.conversations.list({
85
160
  project: "main",
86
161
  durationMin: 10, // sec
87
162
  durationMax: 20, // sec
88
163
  startedAtMin: "2025-04-17", // 00:00:00 UTC time is assumed
89
164
  startedAtMax: "2025-09-05T10:30:00.000Z",
90
165
  });
166
+ ```
91
167
 
92
- if (error === null) {
93
- console.log(data.conversations);
94
- }
168
+
169
+ ### Get conversation by id
170
+
171
+ ```ts
172
+ const conversationResult = await phonic.conversations.get("conv_b1804883-5be4-42fe-b1cf-aa84450d5c84");
173
+ ```
174
+
175
+ ### Get conversation by external id
176
+
177
+ ```ts
178
+ const conversationResult = await phonic.conversations.getByExternalId({
179
+ project: "main",
180
+ externalId: "CAdb9c032c809fec7feb932ea4c96d71e1"
181
+ });
95
182
  ```
96
183
 
97
- ### STS outbound call
184
+
185
+ ## STS outbound call
98
186
 
99
187
  ```ts
100
188
  const { data, error } = await phonic.sts.outboundCall("+19189396241", {
@@ -112,7 +200,7 @@ const { data, error } = await phonic.sts.outboundCall("+19189396241", {
112
200
  });
113
201
  ```
114
202
 
115
- ### STS outbound call using own Twilio account
203
+ ## STS outbound call using own Twilio account
116
204
 
117
205
  In Twilio, create a restricted API key with the following permissions: `voice -> calls -> read` and `voice -> calls -> create`.
118
206
 
@@ -141,7 +229,7 @@ const { data, error } = await phonic.sts.twilio.outboundCall(
141
229
  );
142
230
  ```
143
231
 
144
- ### STS via WebSocket
232
+ ## STS via WebSocket
145
233
 
146
234
  To start a conversation, open a WebSocket connection:
147
235
 
@@ -235,9 +323,9 @@ phonicWebSocket.onError((event) => {
235
323
  });
236
324
  ```
237
325
 
238
- #### Messages that Phonic sends back to you
326
+ ### Messages that Phonic sends back to you
239
327
 
240
- ##### `input_text`
328
+ #### `input_text`
241
329
 
242
330
  ```ts
243
331
  {
@@ -248,7 +336,7 @@ phonicWebSocket.onError((event) => {
248
336
 
249
337
  Phonic sends this message once user's audio is transcribed.
250
338
 
251
- ##### `audio_chunk`
339
+ #### `audio_chunk`
252
340
 
253
341
  ```ts
254
342
  {
@@ -260,7 +348,7 @@ Phonic sends this message once user's audio is transcribed.
260
348
 
261
349
  These are the assistant response audio chunks.
262
350
 
263
- ##### `audio_finished`
351
+ #### `audio_finished`
264
352
 
265
353
  ```ts
266
354
  {
@@ -270,7 +358,7 @@ These are the assistant response audio chunks.
270
358
 
271
359
  Sent after the last "audio_chunk" is sent.
272
360
 
273
- ##### `interrupted_response`
361
+ #### `interrupted_response`
274
362
 
275
363
  ```ts
276
364
  {
@@ -281,7 +369,7 @@ Sent after the last "audio_chunk" is sent.
281
369
 
282
370
  Sent when the user interrupts the assistant, after the user has finished speaking.
283
371
 
284
- #### `assistant_ended_conversation`
372
+ ### `assistant_ended_conversation`
285
373
 
286
374
  ```ts
287
375
  {
package/dist/index.d.mts CHANGED
@@ -12,6 +12,13 @@ type FetchOptions = {
12
12
  method: "POST";
13
13
  headers?: Record<string, string>;
14
14
  body: string;
15
+ } | {
16
+ method: "PATCH";
17
+ headers?: Record<string, string>;
18
+ body: string;
19
+ } | {
20
+ method: "DELETE";
21
+ headers?: Record<string, string>;
15
22
  };
16
23
  type DataOrError<T> = Promise<{
17
24
  data: T;
@@ -21,65 +28,12 @@ type DataOrError<T> = Promise<{
21
28
  error: {
22
29
  message: string;
23
30
  code?: string;
31
+ param_errors?: Record<string, string>;
24
32
  };
25
33
  }>;
26
34
  type ISODate = `${string}-${string}-${string}`;
27
35
  type ISODateTime$1 = `${string}Z`;
28
36
 
29
- type ISODateTime = `${string}Z`;
30
- type ConversationItem = {
31
- role: "user";
32
- item_idx: number;
33
- text: string;
34
- duration_ms: number;
35
- started_at: string;
36
- } | {
37
- role: "assistant";
38
- item_idx: number;
39
- text: string;
40
- voice_id: string;
41
- system_prompt: string;
42
- output_audio_speed: number;
43
- duration_ms: number;
44
- started_at: string;
45
- };
46
- type Conversation = {
47
- id: string;
48
- external_id: string | null;
49
- model: string;
50
- welcome_message: string | null;
51
- input_format: "pcm_44100" | "mulaw_8000";
52
- output_format: "pcm_44100" | "mulaw_8000";
53
- text: string;
54
- duration_ms: number;
55
- started_at: ISODateTime;
56
- ended_at: ISODateTime;
57
- items: Array<ConversationItem>;
58
- };
59
- type ConversationSuccessResponse = {
60
- conversation: Conversation;
61
- };
62
- type ConversationsSuccessResponse = {
63
- conversations: Array<Conversation>;
64
- };
65
-
66
- declare class Conversations {
67
- private readonly phonic;
68
- constructor(phonic: Phonic);
69
- get(id: string): DataOrError<ConversationSuccessResponse>;
70
- getByExternalId({ project, externalId, }: {
71
- project?: string;
72
- externalId: string;
73
- }): DataOrError<ConversationSuccessResponse>;
74
- list({ project, durationMin, durationMax, startedAtMin, startedAtMax, }: {
75
- project?: string;
76
- durationMin?: number;
77
- durationMax?: number;
78
- startedAtMin?: ISODate | ISODateTime$1;
79
- startedAtMax?: ISODate | ISODateTime$1;
80
- }): DataOrError<ConversationsSuccessResponse>;
81
- }
82
-
83
37
  type PhonicSTSTool = "keypad_input" | "natural_conversation_ending" | (string & {});
84
38
  interface PhonicSTSConfigBase {
85
39
  input_format: "pcm_44100" | "mulaw_8000";
@@ -162,6 +116,169 @@ type PhonicConfigurationEndpointResponsePayload = {
162
116
  boosted_keywords?: string[];
163
117
  };
164
118
 
119
+ type Agent = {
120
+ id: string;
121
+ name: string;
122
+ org_id: string;
123
+ project: {
124
+ id: string;
125
+ name: string;
126
+ };
127
+ phone_number: string | null;
128
+ voice_id: string;
129
+ audio_format: "pcm_44100" | "mulaw_8000";
130
+ welcome_message: string | null;
131
+ system_prompt: string;
132
+ template_variables: Record<string, {
133
+ default_value: string | null;
134
+ }>;
135
+ tools: Array<PhonicSTSTool>;
136
+ no_input_poke_sec: number | null;
137
+ no_input_poke_text: string;
138
+ no_input_end_conversation_sec: number;
139
+ boosted_keywords: string[];
140
+ configuration_endpoint: {
141
+ url: string;
142
+ headers: Record<string, string>;
143
+ timeout_ms: number;
144
+ } | null;
145
+ };
146
+ type ListAgentParams = {
147
+ project?: string;
148
+ };
149
+ type ListAgentSuccessResponse = DataOrError<{
150
+ agents: Array<Agent>;
151
+ }>;
152
+ type GetAgentParams = {
153
+ project?: string;
154
+ };
155
+ type GetAgentSuccessResponse = DataOrError<{
156
+ agent: Agent;
157
+ }>;
158
+ interface AgentOptionalParams {
159
+ project?: string;
160
+ voiceId?: string;
161
+ welcomeMessage?: string;
162
+ systemPrompt?: string;
163
+ templateVariables?: Record<string, {
164
+ defaultValue: string | null;
165
+ }>;
166
+ tools?: Array<PhonicSTSTool>;
167
+ noInputPokeSec?: number | null;
168
+ noInputPokeText?: string;
169
+ noInputEndConversationSec?: number;
170
+ boostedKeywords?: string[];
171
+ configurationEndpoint?: {
172
+ url: string;
173
+ headers?: Record<string, string>;
174
+ timeoutMs?: number;
175
+ } | null;
176
+ }
177
+ interface CreateAgentBaseParams extends AgentOptionalParams {
178
+ name: string;
179
+ }
180
+ interface AgentPhoneNumberParams {
181
+ phoneNumber: "assign-automatically";
182
+ audioFormat?: "mulaw_8000";
183
+ }
184
+ interface AgentNoPhoneNumberParams {
185
+ phoneNumber?: null;
186
+ audioFormat?: "pcm_44100" | "mulaw_8000";
187
+ }
188
+ interface CreateAgentWithPhoneNumberParams extends CreateAgentBaseParams, AgentPhoneNumberParams {
189
+ }
190
+ interface CreateAgentWithoutPhoneNumberParams extends CreateAgentBaseParams, AgentNoPhoneNumberParams {
191
+ }
192
+ type CreateAgentParams = CreateAgentWithPhoneNumberParams | CreateAgentWithoutPhoneNumberParams;
193
+ type CreateAgentSuccessResponse = {
194
+ id: string;
195
+ name: string;
196
+ };
197
+ interface UpdateAgentBaseParams extends AgentOptionalParams {
198
+ name?: string;
199
+ }
200
+ interface UpdateAgentWithPhoneNumberParams extends UpdateAgentBaseParams, AgentPhoneNumberParams {
201
+ }
202
+ interface UpdateAgentWithoutPhoneNumberParams extends UpdateAgentBaseParams, AgentNoPhoneNumberParams {
203
+ }
204
+ type UpdateAgentParams = UpdateAgentWithPhoneNumberParams | UpdateAgentWithoutPhoneNumberParams;
205
+ type UpdateAgentSuccessResponse = {
206
+ success: true;
207
+ };
208
+ type DeleteAgentParams = {
209
+ project?: string;
210
+ };
211
+ type DeleteAgentSuccessResponse = {
212
+ success: true;
213
+ };
214
+
215
+ declare class Agents {
216
+ private readonly phonic;
217
+ constructor(phonic: Phonic);
218
+ private getQueryString;
219
+ private getTemplateVariablesForBody;
220
+ private getConfigurationEndpointForBody;
221
+ list(params?: ListAgentParams): DataOrError<ListAgentSuccessResponse>;
222
+ get(name: string, params?: GetAgentParams): DataOrError<GetAgentSuccessResponse>;
223
+ create(params: CreateAgentParams): DataOrError<CreateAgentSuccessResponse>;
224
+ update(name: string, params: UpdateAgentParams): DataOrError<UpdateAgentSuccessResponse>;
225
+ delete(name: string, params?: DeleteAgentParams): DataOrError<DeleteAgentSuccessResponse>;
226
+ }
227
+
228
+ type ISODateTime = `${string}Z`;
229
+ type ConversationItem = {
230
+ role: "user";
231
+ item_idx: number;
232
+ text: string;
233
+ duration_ms: number;
234
+ started_at: string;
235
+ } | {
236
+ role: "assistant";
237
+ item_idx: number;
238
+ text: string;
239
+ voice_id: string;
240
+ system_prompt: string;
241
+ output_audio_speed: number;
242
+ duration_ms: number;
243
+ started_at: string;
244
+ };
245
+ type Conversation = {
246
+ id: string;
247
+ external_id: string | null;
248
+ model: string;
249
+ welcome_message: string | null;
250
+ input_format: "pcm_44100" | "mulaw_8000";
251
+ output_format: "pcm_44100" | "mulaw_8000";
252
+ text: string;
253
+ duration_ms: number;
254
+ started_at: ISODateTime;
255
+ ended_at: ISODateTime;
256
+ items: Array<ConversationItem>;
257
+ };
258
+ type ConversationSuccessResponse = {
259
+ conversation: Conversation;
260
+ };
261
+ type ConversationsSuccessResponse = {
262
+ conversations: Array<Conversation>;
263
+ };
264
+
265
+ declare class Conversations {
266
+ private readonly phonic;
267
+ constructor(phonic: Phonic);
268
+ get(id: string): DataOrError<ConversationSuccessResponse>;
269
+ getByExternalId({ project, externalId, }: {
270
+ project?: string;
271
+ externalId: string;
272
+ }): DataOrError<ConversationSuccessResponse>;
273
+ list({ project, durationMin, durationMax, startedAtMin, startedAtMax, }: {
274
+ project?: string;
275
+ durationMin?: number;
276
+ durationMax?: number;
277
+ startedAtMin?: ISODate | ISODateTime$1;
278
+ startedAtMax?: ISODate | ISODateTime$1;
279
+ }): DataOrError<ConversationsSuccessResponse>;
280
+ }
281
+
165
282
  type PhonicSTSTwilioOutboundCallParams = {
166
283
  account_sid: string;
167
284
  api_key_sid: string;
@@ -238,6 +355,7 @@ declare class Phonic {
238
355
  readonly baseUrl: string;
239
356
  readonly __downstreamWebSocketUrl: string | null;
240
357
  readonly headers: Record<string, string>;
358
+ readonly agents: Agents;
241
359
  readonly conversations: Conversations;
242
360
  readonly voices: Voices;
243
361
  readonly sts: SpeechToSpeech;
@@ -248,6 +366,7 @@ declare class Phonic {
248
366
  error: {
249
367
  message: string;
250
368
  code?: string;
369
+ param_errors?: Record<string, string>;
251
370
  };
252
371
  } | {
253
372
  data: T;
@@ -258,6 +377,29 @@ declare class Phonic {
258
377
  error: {
259
378
  message: string;
260
379
  code?: string;
380
+ param_errors?: Record<string, string>;
381
+ };
382
+ } | {
383
+ data: T;
384
+ error: null;
385
+ }>;
386
+ patch<T>(path: string, body: Record<string, unknown>, headers?: Record<string, string>): Promise<{
387
+ data: null;
388
+ error: {
389
+ message: string;
390
+ code?: string;
391
+ param_errors?: Record<string, string>;
392
+ };
393
+ } | {
394
+ data: T;
395
+ error: null;
396
+ }>;
397
+ delete<T>(path: string, headers?: Record<string, string>): Promise<{
398
+ data: null;
399
+ error: {
400
+ message: string;
401
+ code?: string;
402
+ param_errors?: Record<string, string>;
261
403
  };
262
404
  } | {
263
405
  data: T;
package/dist/index.d.ts CHANGED
@@ -12,6 +12,13 @@ type FetchOptions = {
12
12
  method: "POST";
13
13
  headers?: Record<string, string>;
14
14
  body: string;
15
+ } | {
16
+ method: "PATCH";
17
+ headers?: Record<string, string>;
18
+ body: string;
19
+ } | {
20
+ method: "DELETE";
21
+ headers?: Record<string, string>;
15
22
  };
16
23
  type DataOrError<T> = Promise<{
17
24
  data: T;
@@ -21,65 +28,12 @@ type DataOrError<T> = Promise<{
21
28
  error: {
22
29
  message: string;
23
30
  code?: string;
31
+ param_errors?: Record<string, string>;
24
32
  };
25
33
  }>;
26
34
  type ISODate = `${string}-${string}-${string}`;
27
35
  type ISODateTime$1 = `${string}Z`;
28
36
 
29
- type ISODateTime = `${string}Z`;
30
- type ConversationItem = {
31
- role: "user";
32
- item_idx: number;
33
- text: string;
34
- duration_ms: number;
35
- started_at: string;
36
- } | {
37
- role: "assistant";
38
- item_idx: number;
39
- text: string;
40
- voice_id: string;
41
- system_prompt: string;
42
- output_audio_speed: number;
43
- duration_ms: number;
44
- started_at: string;
45
- };
46
- type Conversation = {
47
- id: string;
48
- external_id: string | null;
49
- model: string;
50
- welcome_message: string | null;
51
- input_format: "pcm_44100" | "mulaw_8000";
52
- output_format: "pcm_44100" | "mulaw_8000";
53
- text: string;
54
- duration_ms: number;
55
- started_at: ISODateTime;
56
- ended_at: ISODateTime;
57
- items: Array<ConversationItem>;
58
- };
59
- type ConversationSuccessResponse = {
60
- conversation: Conversation;
61
- };
62
- type ConversationsSuccessResponse = {
63
- conversations: Array<Conversation>;
64
- };
65
-
66
- declare class Conversations {
67
- private readonly phonic;
68
- constructor(phonic: Phonic);
69
- get(id: string): DataOrError<ConversationSuccessResponse>;
70
- getByExternalId({ project, externalId, }: {
71
- project?: string;
72
- externalId: string;
73
- }): DataOrError<ConversationSuccessResponse>;
74
- list({ project, durationMin, durationMax, startedAtMin, startedAtMax, }: {
75
- project?: string;
76
- durationMin?: number;
77
- durationMax?: number;
78
- startedAtMin?: ISODate | ISODateTime$1;
79
- startedAtMax?: ISODate | ISODateTime$1;
80
- }): DataOrError<ConversationsSuccessResponse>;
81
- }
82
-
83
37
  type PhonicSTSTool = "keypad_input" | "natural_conversation_ending" | (string & {});
84
38
  interface PhonicSTSConfigBase {
85
39
  input_format: "pcm_44100" | "mulaw_8000";
@@ -162,6 +116,169 @@ type PhonicConfigurationEndpointResponsePayload = {
162
116
  boosted_keywords?: string[];
163
117
  };
164
118
 
119
+ type Agent = {
120
+ id: string;
121
+ name: string;
122
+ org_id: string;
123
+ project: {
124
+ id: string;
125
+ name: string;
126
+ };
127
+ phone_number: string | null;
128
+ voice_id: string;
129
+ audio_format: "pcm_44100" | "mulaw_8000";
130
+ welcome_message: string | null;
131
+ system_prompt: string;
132
+ template_variables: Record<string, {
133
+ default_value: string | null;
134
+ }>;
135
+ tools: Array<PhonicSTSTool>;
136
+ no_input_poke_sec: number | null;
137
+ no_input_poke_text: string;
138
+ no_input_end_conversation_sec: number;
139
+ boosted_keywords: string[];
140
+ configuration_endpoint: {
141
+ url: string;
142
+ headers: Record<string, string>;
143
+ timeout_ms: number;
144
+ } | null;
145
+ };
146
+ type ListAgentParams = {
147
+ project?: string;
148
+ };
149
+ type ListAgentSuccessResponse = DataOrError<{
150
+ agents: Array<Agent>;
151
+ }>;
152
+ type GetAgentParams = {
153
+ project?: string;
154
+ };
155
+ type GetAgentSuccessResponse = DataOrError<{
156
+ agent: Agent;
157
+ }>;
158
+ interface AgentOptionalParams {
159
+ project?: string;
160
+ voiceId?: string;
161
+ welcomeMessage?: string;
162
+ systemPrompt?: string;
163
+ templateVariables?: Record<string, {
164
+ defaultValue: string | null;
165
+ }>;
166
+ tools?: Array<PhonicSTSTool>;
167
+ noInputPokeSec?: number | null;
168
+ noInputPokeText?: string;
169
+ noInputEndConversationSec?: number;
170
+ boostedKeywords?: string[];
171
+ configurationEndpoint?: {
172
+ url: string;
173
+ headers?: Record<string, string>;
174
+ timeoutMs?: number;
175
+ } | null;
176
+ }
177
+ interface CreateAgentBaseParams extends AgentOptionalParams {
178
+ name: string;
179
+ }
180
+ interface AgentPhoneNumberParams {
181
+ phoneNumber: "assign-automatically";
182
+ audioFormat?: "mulaw_8000";
183
+ }
184
+ interface AgentNoPhoneNumberParams {
185
+ phoneNumber?: null;
186
+ audioFormat?: "pcm_44100" | "mulaw_8000";
187
+ }
188
+ interface CreateAgentWithPhoneNumberParams extends CreateAgentBaseParams, AgentPhoneNumberParams {
189
+ }
190
+ interface CreateAgentWithoutPhoneNumberParams extends CreateAgentBaseParams, AgentNoPhoneNumberParams {
191
+ }
192
+ type CreateAgentParams = CreateAgentWithPhoneNumberParams | CreateAgentWithoutPhoneNumberParams;
193
+ type CreateAgentSuccessResponse = {
194
+ id: string;
195
+ name: string;
196
+ };
197
+ interface UpdateAgentBaseParams extends AgentOptionalParams {
198
+ name?: string;
199
+ }
200
+ interface UpdateAgentWithPhoneNumberParams extends UpdateAgentBaseParams, AgentPhoneNumberParams {
201
+ }
202
+ interface UpdateAgentWithoutPhoneNumberParams extends UpdateAgentBaseParams, AgentNoPhoneNumberParams {
203
+ }
204
+ type UpdateAgentParams = UpdateAgentWithPhoneNumberParams | UpdateAgentWithoutPhoneNumberParams;
205
+ type UpdateAgentSuccessResponse = {
206
+ success: true;
207
+ };
208
+ type DeleteAgentParams = {
209
+ project?: string;
210
+ };
211
+ type DeleteAgentSuccessResponse = {
212
+ success: true;
213
+ };
214
+
215
+ declare class Agents {
216
+ private readonly phonic;
217
+ constructor(phonic: Phonic);
218
+ private getQueryString;
219
+ private getTemplateVariablesForBody;
220
+ private getConfigurationEndpointForBody;
221
+ list(params?: ListAgentParams): DataOrError<ListAgentSuccessResponse>;
222
+ get(name: string, params?: GetAgentParams): DataOrError<GetAgentSuccessResponse>;
223
+ create(params: CreateAgentParams): DataOrError<CreateAgentSuccessResponse>;
224
+ update(name: string, params: UpdateAgentParams): DataOrError<UpdateAgentSuccessResponse>;
225
+ delete(name: string, params?: DeleteAgentParams): DataOrError<DeleteAgentSuccessResponse>;
226
+ }
227
+
228
+ type ISODateTime = `${string}Z`;
229
+ type ConversationItem = {
230
+ role: "user";
231
+ item_idx: number;
232
+ text: string;
233
+ duration_ms: number;
234
+ started_at: string;
235
+ } | {
236
+ role: "assistant";
237
+ item_idx: number;
238
+ text: string;
239
+ voice_id: string;
240
+ system_prompt: string;
241
+ output_audio_speed: number;
242
+ duration_ms: number;
243
+ started_at: string;
244
+ };
245
+ type Conversation = {
246
+ id: string;
247
+ external_id: string | null;
248
+ model: string;
249
+ welcome_message: string | null;
250
+ input_format: "pcm_44100" | "mulaw_8000";
251
+ output_format: "pcm_44100" | "mulaw_8000";
252
+ text: string;
253
+ duration_ms: number;
254
+ started_at: ISODateTime;
255
+ ended_at: ISODateTime;
256
+ items: Array<ConversationItem>;
257
+ };
258
+ type ConversationSuccessResponse = {
259
+ conversation: Conversation;
260
+ };
261
+ type ConversationsSuccessResponse = {
262
+ conversations: Array<Conversation>;
263
+ };
264
+
265
+ declare class Conversations {
266
+ private readonly phonic;
267
+ constructor(phonic: Phonic);
268
+ get(id: string): DataOrError<ConversationSuccessResponse>;
269
+ getByExternalId({ project, externalId, }: {
270
+ project?: string;
271
+ externalId: string;
272
+ }): DataOrError<ConversationSuccessResponse>;
273
+ list({ project, durationMin, durationMax, startedAtMin, startedAtMax, }: {
274
+ project?: string;
275
+ durationMin?: number;
276
+ durationMax?: number;
277
+ startedAtMin?: ISODate | ISODateTime$1;
278
+ startedAtMax?: ISODate | ISODateTime$1;
279
+ }): DataOrError<ConversationsSuccessResponse>;
280
+ }
281
+
165
282
  type PhonicSTSTwilioOutboundCallParams = {
166
283
  account_sid: string;
167
284
  api_key_sid: string;
@@ -238,6 +355,7 @@ declare class Phonic {
238
355
  readonly baseUrl: string;
239
356
  readonly __downstreamWebSocketUrl: string | null;
240
357
  readonly headers: Record<string, string>;
358
+ readonly agents: Agents;
241
359
  readonly conversations: Conversations;
242
360
  readonly voices: Voices;
243
361
  readonly sts: SpeechToSpeech;
@@ -248,6 +366,7 @@ declare class Phonic {
248
366
  error: {
249
367
  message: string;
250
368
  code?: string;
369
+ param_errors?: Record<string, string>;
251
370
  };
252
371
  } | {
253
372
  data: T;
@@ -258,6 +377,29 @@ declare class Phonic {
258
377
  error: {
259
378
  message: string;
260
379
  code?: string;
380
+ param_errors?: Record<string, string>;
381
+ };
382
+ } | {
383
+ data: T;
384
+ error: null;
385
+ }>;
386
+ patch<T>(path: string, body: Record<string, unknown>, headers?: Record<string, string>): Promise<{
387
+ data: null;
388
+ error: {
389
+ message: string;
390
+ code?: string;
391
+ param_errors?: Record<string, string>;
392
+ };
393
+ } | {
394
+ data: T;
395
+ error: null;
396
+ }>;
397
+ delete<T>(path: string, headers?: Record<string, string>): Promise<{
398
+ data: null;
399
+ error: {
400
+ message: string;
401
+ code?: string;
402
+ param_errors?: Record<string, string>;
261
403
  };
262
404
  } | {
263
405
  data: T;
package/dist/index.js CHANGED
@@ -35,7 +35,112 @@ __export(index_exports, {
35
35
  module.exports = __toCommonJS(index_exports);
36
36
 
37
37
  // package.json
38
- var version = "0.20.0";
38
+ var version = "0.21.0";
39
+
40
+ // src/agents/index.ts
41
+ var Agents = class {
42
+ constructor(phonic) {
43
+ this.phonic = phonic;
44
+ }
45
+ getQueryString(params) {
46
+ const project = params?.project;
47
+ const queryString = new URLSearchParams({
48
+ ...project !== void 0 && { project }
49
+ }).toString();
50
+ return queryString;
51
+ }
52
+ getTemplateVariablesForBody(templateVariables) {
53
+ if (templateVariables === void 0) {
54
+ return void 0;
55
+ }
56
+ return Object.fromEntries(
57
+ Object.entries(templateVariables).map(([key, value]) => [
58
+ key,
59
+ {
60
+ default_value: value.defaultValue
61
+ }
62
+ ])
63
+ );
64
+ }
65
+ getConfigurationEndpointForBody(configurationEndpoint) {
66
+ if (configurationEndpoint === void 0 || configurationEndpoint === null) {
67
+ return configurationEndpoint;
68
+ }
69
+ return {
70
+ url: configurationEndpoint.url,
71
+ headers: configurationEndpoint.headers,
72
+ timeout_ms: configurationEndpoint.timeoutMs
73
+ };
74
+ }
75
+ async list(params) {
76
+ const response = await this.phonic.get(
77
+ `/agents?${this.getQueryString(params)}`
78
+ );
79
+ return response;
80
+ }
81
+ async get(name, params) {
82
+ const response = await this.phonic.get(
83
+ `/agents/${name}?${this.getQueryString(params)}`
84
+ );
85
+ return response;
86
+ }
87
+ async create(params) {
88
+ const response = await this.phonic.post(
89
+ `/agents?${this.getQueryString(params)}`,
90
+ {
91
+ name: params.name,
92
+ phone_number: params.phoneNumber,
93
+ audio_format: params.phoneNumber === "assign-automatically" ? "mulaw_8000" : params.audioFormat,
94
+ voice_id: params.voiceId,
95
+ welcome_message: params.welcomeMessage,
96
+ system_prompt: params.systemPrompt,
97
+ template_variables: this.getTemplateVariablesForBody(
98
+ params.templateVariables
99
+ ),
100
+ tools: params.tools,
101
+ no_input_poke_sec: params.noInputPokeSec,
102
+ no_input_poke_text: params.noInputPokeText,
103
+ no_input_end_conversation_sec: params.noInputEndConversationSec,
104
+ boosted_keywords: params.boostedKeywords,
105
+ configuration_endpoint: this.getConfigurationEndpointForBody(
106
+ params.configurationEndpoint
107
+ )
108
+ }
109
+ );
110
+ return response;
111
+ }
112
+ async update(name, params) {
113
+ const response = await this.phonic.patch(
114
+ `/agents/${name}?${this.getQueryString(params)}`,
115
+ {
116
+ name: params.name,
117
+ phone_number: params.phoneNumber,
118
+ audio_format: params.phoneNumber === "assign-automatically" ? "mulaw_8000" : params.audioFormat,
119
+ voice_id: params.voiceId,
120
+ welcome_message: params.welcomeMessage,
121
+ system_prompt: params.systemPrompt,
122
+ template_variables: this.getTemplateVariablesForBody(
123
+ params.templateVariables
124
+ ),
125
+ tools: params.tools,
126
+ no_input_poke_sec: params.noInputPokeSec,
127
+ no_input_poke_text: params.noInputPokeText,
128
+ no_input_end_conversation_sec: params.noInputEndConversationSec,
129
+ boosted_keywords: params.boostedKeywords,
130
+ configuration_endpoint: this.getConfigurationEndpointForBody(
131
+ params.configurationEndpoint
132
+ )
133
+ }
134
+ );
135
+ return response;
136
+ }
137
+ async delete(name, params) {
138
+ const response = await this.phonic.delete(
139
+ `/agents/${name}?${this.getQueryString(params)}`
140
+ );
141
+ return response;
142
+ }
143
+ };
39
144
 
40
145
  // src/conversations/index.ts
41
146
  var Conversations = class {
@@ -286,6 +391,7 @@ var Phonic = class {
286
391
  baseUrl;
287
392
  __downstreamWebSocketUrl;
288
393
  headers;
394
+ agents = new Agents(this);
289
395
  conversations = new Conversations(this);
290
396
  voices = new Voices(this);
291
397
  sts = new SpeechToSpeech(this);
@@ -305,11 +411,11 @@ var Phonic = class {
305
411
  }
306
412
  try {
307
413
  const data = await response.json();
308
- const errorMessage = data.error.message || response.statusText;
309
414
  return {
310
415
  data: null,
311
416
  error: {
312
- message: errorMessage
417
+ message: data.error.message || response.statusText,
418
+ param_errors: data.param_errors
313
419
  }
314
420
  };
315
421
  } catch (error) {
@@ -340,6 +446,19 @@ var Phonic = class {
340
446
  headers
341
447
  });
342
448
  }
449
+ async patch(path, body, headers) {
450
+ return this.fetchRequest(path, {
451
+ method: "PATCH",
452
+ body: JSON.stringify(body),
453
+ headers
454
+ });
455
+ }
456
+ async delete(path, headers) {
457
+ return this.fetchRequest(path, {
458
+ method: "DELETE",
459
+ headers
460
+ });
461
+ }
343
462
  };
344
463
  // Annotate the CommonJS export names for ESM import in node:
345
464
  0 && (module.exports = {
package/dist/index.mjs CHANGED
@@ -1,5 +1,110 @@
1
1
  // package.json
2
- var version = "0.20.0";
2
+ var version = "0.21.0";
3
+
4
+ // src/agents/index.ts
5
+ var Agents = class {
6
+ constructor(phonic) {
7
+ this.phonic = phonic;
8
+ }
9
+ getQueryString(params) {
10
+ const project = params?.project;
11
+ const queryString = new URLSearchParams({
12
+ ...project !== void 0 && { project }
13
+ }).toString();
14
+ return queryString;
15
+ }
16
+ getTemplateVariablesForBody(templateVariables) {
17
+ if (templateVariables === void 0) {
18
+ return void 0;
19
+ }
20
+ return Object.fromEntries(
21
+ Object.entries(templateVariables).map(([key, value]) => [
22
+ key,
23
+ {
24
+ default_value: value.defaultValue
25
+ }
26
+ ])
27
+ );
28
+ }
29
+ getConfigurationEndpointForBody(configurationEndpoint) {
30
+ if (configurationEndpoint === void 0 || configurationEndpoint === null) {
31
+ return configurationEndpoint;
32
+ }
33
+ return {
34
+ url: configurationEndpoint.url,
35
+ headers: configurationEndpoint.headers,
36
+ timeout_ms: configurationEndpoint.timeoutMs
37
+ };
38
+ }
39
+ async list(params) {
40
+ const response = await this.phonic.get(
41
+ `/agents?${this.getQueryString(params)}`
42
+ );
43
+ return response;
44
+ }
45
+ async get(name, params) {
46
+ const response = await this.phonic.get(
47
+ `/agents/${name}?${this.getQueryString(params)}`
48
+ );
49
+ return response;
50
+ }
51
+ async create(params) {
52
+ const response = await this.phonic.post(
53
+ `/agents?${this.getQueryString(params)}`,
54
+ {
55
+ name: params.name,
56
+ phone_number: params.phoneNumber,
57
+ audio_format: params.phoneNumber === "assign-automatically" ? "mulaw_8000" : params.audioFormat,
58
+ voice_id: params.voiceId,
59
+ welcome_message: params.welcomeMessage,
60
+ system_prompt: params.systemPrompt,
61
+ template_variables: this.getTemplateVariablesForBody(
62
+ params.templateVariables
63
+ ),
64
+ tools: params.tools,
65
+ no_input_poke_sec: params.noInputPokeSec,
66
+ no_input_poke_text: params.noInputPokeText,
67
+ no_input_end_conversation_sec: params.noInputEndConversationSec,
68
+ boosted_keywords: params.boostedKeywords,
69
+ configuration_endpoint: this.getConfigurationEndpointForBody(
70
+ params.configurationEndpoint
71
+ )
72
+ }
73
+ );
74
+ return response;
75
+ }
76
+ async update(name, params) {
77
+ const response = await this.phonic.patch(
78
+ `/agents/${name}?${this.getQueryString(params)}`,
79
+ {
80
+ name: params.name,
81
+ phone_number: params.phoneNumber,
82
+ audio_format: params.phoneNumber === "assign-automatically" ? "mulaw_8000" : params.audioFormat,
83
+ voice_id: params.voiceId,
84
+ welcome_message: params.welcomeMessage,
85
+ system_prompt: params.systemPrompt,
86
+ template_variables: this.getTemplateVariablesForBody(
87
+ params.templateVariables
88
+ ),
89
+ tools: params.tools,
90
+ no_input_poke_sec: params.noInputPokeSec,
91
+ no_input_poke_text: params.noInputPokeText,
92
+ no_input_end_conversation_sec: params.noInputEndConversationSec,
93
+ boosted_keywords: params.boostedKeywords,
94
+ configuration_endpoint: this.getConfigurationEndpointForBody(
95
+ params.configurationEndpoint
96
+ )
97
+ }
98
+ );
99
+ return response;
100
+ }
101
+ async delete(name, params) {
102
+ const response = await this.phonic.delete(
103
+ `/agents/${name}?${this.getQueryString(params)}`
104
+ );
105
+ return response;
106
+ }
107
+ };
3
108
 
4
109
  // src/conversations/index.ts
5
110
  var Conversations = class {
@@ -250,6 +355,7 @@ var Phonic = class {
250
355
  baseUrl;
251
356
  __downstreamWebSocketUrl;
252
357
  headers;
358
+ agents = new Agents(this);
253
359
  conversations = new Conversations(this);
254
360
  voices = new Voices(this);
255
361
  sts = new SpeechToSpeech(this);
@@ -269,11 +375,11 @@ var Phonic = class {
269
375
  }
270
376
  try {
271
377
  const data = await response.json();
272
- const errorMessage = data.error.message || response.statusText;
273
378
  return {
274
379
  data: null,
275
380
  error: {
276
- message: errorMessage
381
+ message: data.error.message || response.statusText,
382
+ param_errors: data.param_errors
277
383
  }
278
384
  };
279
385
  } catch (error) {
@@ -304,6 +410,19 @@ var Phonic = class {
304
410
  headers
305
411
  });
306
412
  }
413
+ async patch(path, body, headers) {
414
+ return this.fetchRequest(path, {
415
+ method: "PATCH",
416
+ body: JSON.stringify(body),
417
+ headers
418
+ });
419
+ }
420
+ async delete(path, headers) {
421
+ return this.fetchRequest(path, {
422
+ method: "DELETE",
423
+ headers
424
+ });
425
+ }
307
426
  };
308
427
  export {
309
428
  Phonic
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phonic",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "Phonic Node.js SDK",
5
5
  "scripts": {
6
6
  "build": "tsup",