phonic 0.26.1 → 0.27.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
@@ -190,16 +190,25 @@ const toolsResult = await phonic.tools.list();
190
190
 
191
191
  ### Get tool
192
192
 
193
+ Gets a tool by its ID or name.
194
+
193
195
  ```ts
194
196
  const toolResult = await phonic.tools.get("next_invoice");
197
+ const toolByIdResult = await phonic.tools.get("tool_12cf6e88-c254-4d3e-a149-ddf1bdd2254c");
195
198
  ```
196
199
 
197
200
  ### Create tool
198
201
 
202
+ Tools can be either webhook-based (HTTP endpoints) or WebSocket-based.
203
+
204
+ #### Create webhook tool
205
+
199
206
  ```ts
200
- const createToolResult = await phonic.tools.create({
207
+ const createWebhookToolResult = await phonic.tools.create({
201
208
  name: "next_invoice",
202
209
  description: "Returns the next invoice of the given user",
210
+ type: "custom_webhook",
211
+ executionMode: "sync",
203
212
  endpointMethod: "POST",
204
213
  endpointUrl: "https://myapp.com/webhooks/next-invoice",
205
214
  endpointHeaders: {
@@ -230,12 +239,75 @@ const createToolResult = await phonic.tools.create({
230
239
  });
231
240
  ```
232
241
 
242
+ #### Create WebSocket tool
243
+
244
+ WebSocket tools allow you to handle tool execution through the WebSocket connection. When the agent calls a WebSocket tool, you'll receive a `tool_call` message and must respond with a `tool_call_output` message that contains the tool result.
245
+
246
+ ```ts
247
+ const createWebSocketToolResult = await phonic.tools.create({
248
+ name: "get_product_recommendations",
249
+ description: "Gets personalized product recommendations",
250
+ type: "custom_websocket",
251
+ executionMode: "async",
252
+ toolCallOutputTimeoutMs: 5000, // Optional, defaults to 15000
253
+ parameters: [
254
+ {
255
+ type: "string",
256
+ name: "category",
257
+ description: "Product category (e.g., 'handbags', 'shoes', 'electronics')",
258
+ isRequired: true
259
+ }
260
+ ]
261
+ });
262
+ ```
263
+
264
+ To use this tool in a conversation, add it to your agent or config:
265
+
266
+ ```ts
267
+ // When creating an agent
268
+ const agent = await phonic.agents.create({
269
+ name: "shopping-assistant",
270
+ tools: ["get_product_recommendations"],
271
+ // ... other config
272
+ });
273
+
274
+ // Or, override agent settings when starting a WebSocket conversation
275
+ const phonicWebSocket = phonic.sts.websocket({
276
+ name: "shopping-assistant",
277
+ tools: ["get_product_recommendations"],
278
+ // ... other config
279
+ });
280
+
281
+ // Handle the tool call when it's invoked
282
+ phonicWebSocket.onMessage(async (message) => {
283
+ if (message.type === "tool_call" && message.name === "get_product_recommendations") {
284
+ const category = message.parameters.category;
285
+
286
+ // Execute your business logic
287
+ const recommendations = fetchRecommendations(category);
288
+
289
+ // Send the result back
290
+ phonicWebSocket.[sendToolCallOutput](#send-tool-output-to-phonic)({
291
+ toolCallId: message.tool_call_id,
292
+ output: {
293
+ products: recommendations,
294
+ total: recommendations.length
295
+ }
296
+ });
297
+ }
298
+ });
299
+ ```
300
+
233
301
  ### Update tool
234
302
 
303
+ Updates a tool by ID or name. All fields are optional - only provided fields will be updated.
304
+
235
305
  ```ts
236
- const updateToolResult = await phonic.tools.update("next_invoice", {
306
+ const updateWebhookToolResult = await phonic.tools.update("next_invoice", {
237
307
  name: "next_invoice_updated",
238
308
  description: "Updated description.",
309
+ type: "custom_webhook",
310
+ executionMode: "sync",
239
311
  endpointMethod: "POST",
240
312
  endpointUrl: "https://myapp.com/webhooks/next-invoice-updated",
241
313
  endpointHeaders: {
@@ -266,8 +338,19 @@ const updateToolResult = await phonic.tools.update("next_invoice", {
266
338
  });
267
339
  ```
268
340
 
341
+ For WebSocket tools, you would use `toolCallOutputTimeoutMs` instead of the endpoint fields:
342
+
343
+ ```ts
344
+ const updateWebSocketToolResult = await phonic.tools.update("get_product_recommendations", {
345
+ description: "Updated product recommendation tool",
346
+ toolCallOutputTimeoutMs: 7000
347
+ });
348
+ ```
349
+
269
350
  ### Delete tool
270
351
 
352
+ Deletes a tool by ID or name.
353
+
271
354
  ```ts
272
355
  const deleteToolResult = await phonic.tools.delete("next_invoice");
273
356
  ```
@@ -412,6 +495,26 @@ phonicWebSocket.onMessage((message) => {
412
495
  );
413
496
  break;
414
497
  }
498
+
499
+ case "tool_call": {
500
+ // Handle WebSocket tool calls
501
+ console.log(`Tool ${message.tool_name} called with parameters:`, message.parameters);
502
+
503
+ // Example: Process a product recommendations tool call
504
+ if (message.tool_name === "get_product_recommendations") {
505
+ const category = message.parameters.category;
506
+ const recommendations = fetchRecommendations(category);
507
+
508
+ phonicWebSocket.[sendToolCallOutput](#send-tool-output-to-phonic)({
509
+ toolCallId: message.tool_call_id,
510
+ output: {
511
+ products: recommendations,
512
+ total: recommendations.length
513
+ }
514
+ });
515
+ }
516
+ break;
517
+ }
415
518
  }
416
519
  });
417
520
  ```
@@ -432,6 +535,34 @@ phonicWebSocket.setExternalId({
432
535
  })
433
536
  ```
434
537
 
538
+ ### Send tool output to Phonic
539
+
540
+ When you receive a `tool_call` message for a WebSocket tool, you must respond with the tool's output using `sendToolCallOutput()`. This method sends the execution result back to Phonic so the conversation can continue.
541
+
542
+ ```ts
543
+ phonicWebSocket.sendToolCallOutput({
544
+ toolCallId: "tool_call_123...", // The tool_call_id from the tool_call message
545
+ output: "Success! Found 2 items" // Can be any JSON-serializable value (string, number, object, array, etc.)
546
+ });
547
+
548
+ // Or with an object:
549
+ phonicWebSocket.sendToolCallOutput({
550
+ toolCallId: message.tool_call_id,
551
+ output: {
552
+ result: "success",
553
+ data: {
554
+ items: ["item1", "item2"],
555
+ total: 2
556
+ }
557
+ }
558
+ });
559
+ ```
560
+
561
+ **Important notes:**
562
+ - You must use the exact `tool_call_id` received in the `tool_call` message
563
+ - The `output` can be any JSON-serializable value (string, number, boolean, object, array, etc.)
564
+ - If you don't send a response within `toolCallOutputTimeoutMs`, the tool call will be marked as failed.
565
+
435
566
  To end the conversation, close the WebSocket:
436
567
 
437
568
  ```ts
@@ -564,7 +695,24 @@ Sent when the assistant decides to end the conversation.
564
695
  ```ts
565
696
  {
566
697
  type: "tool_call";
567
- id: string;
698
+ tool_call_id: string;
699
+ tool_name: string;
700
+ parameters: Record<string, unknown>;
701
+ }
702
+ ```
703
+
704
+ Sent when a WebSocket tool is called during the conversation. When you receive this message, you should:
705
+ 1. Process the tool call using the provided `tool_name` and `parameters`
706
+ 2. Send back the result using [`phonicWebSocket.sendToolCallOutput`](#send-tool-output-to-phonic)
707
+
708
+ This is only sent for tools created with `type: "custom_websocket"`. Webhook tools are executed server-side and only send `tool_call_output_processed` messages.
709
+
710
+ #### `tool_call_output_processed`
711
+
712
+ ```ts
713
+ {
714
+ type: "tool_call_output_processed";
715
+ tool_call_id: string;
568
716
  tool: {
569
717
  id: string;
570
718
  name: string;
package/dist/index.d.mts CHANGED
@@ -93,8 +93,8 @@ type PhonicSTSWebSocketResponseMessage = {
93
93
  type: "dtmf";
94
94
  digits: string;
95
95
  } | {
96
- type: "tool_call";
97
- id: string;
96
+ type: "tool_call_output_processed";
97
+ tool_call_id: string;
98
98
  tool: {
99
99
  id: string;
100
100
  name: string;
@@ -109,10 +109,17 @@ type PhonicSTSWebSocketResponseMessage = {
109
109
  } | null;
110
110
  [key: string]: unknown;
111
111
  } | null;
112
- response_body: Record<string, unknown> | null;
112
+ parameters: Record<string, unknown> | null;
113
+ output: unknown | null;
114
+ response_body: unknown | null;
113
115
  response_status_code: number | null;
114
116
  timed_out: boolean | null;
115
117
  error_message: string | null;
118
+ } | {
119
+ type: "tool_call";
120
+ tool_call_id: string;
121
+ tool_name: string;
122
+ parameters: Record<string, unknown>;
116
123
  } | {
117
124
  type: "error";
118
125
  error: {
@@ -371,12 +378,17 @@ declare class PhonicSTSWebSocket {
371
378
  private buffer;
372
379
  private isOpen;
373
380
  constructor(ws: WebSocket, config: PhonicSTSConfig);
381
+ private processUserMessage;
374
382
  onMessage(callback: OnMessageCallback): void;
375
383
  onClose(callback: OnCloseCallback): void;
376
384
  onError(callback: OnErrorCallback): void;
377
385
  audioChunk({ audio }: {
378
386
  audio: string;
379
387
  }): void;
388
+ sendToolCallOutput({ toolCallId, output, }: {
389
+ toolCallId: string;
390
+ output: unknown;
391
+ }): void;
380
392
  updateSystemPrompt({ systemPrompt }: {
381
393
  systemPrompt: string;
382
394
  }): void;
@@ -405,31 +417,50 @@ interface ArrayParameter extends ParameterBase {
405
417
  itemType: "string" | "integer" | "number" | "boolean";
406
418
  }
407
419
  type ToolParameters = Array<PrimitiveParameter | ArrayParameter>;
408
- type Tool = {
420
+ type ExecutionMode = "sync" | "async";
421
+ interface ToolBase {
409
422
  id: string;
410
423
  name: string;
411
424
  description: string;
425
+ execution_mode: ExecutionMode;
426
+ parameters: ToolParameters;
427
+ }
428
+ interface WebhookTool extends ToolBase {
429
+ type: "custom_webhook";
412
430
  endpoint_method: "POST";
413
431
  endpoint_url: string;
414
432
  endpoint_headers: Record<string, string>;
415
433
  endpoint_timeout_ms: number;
416
- parameters: ToolParameters;
417
- };
434
+ }
435
+ interface WebSocketTool extends ToolBase {
436
+ type: "custom_websocket";
437
+ tool_call_output_timeout_ms: number;
438
+ }
439
+ type Tool = WebhookTool | WebSocketTool;
418
440
  type ListToolsSuccessResponse = DataOrError<{
419
441
  tools: Array<Tool>;
420
442
  }>;
421
443
  type GetToolSuccessResponse = DataOrError<{
422
444
  tool: Tool;
423
445
  }>;
424
- type CreateToolParams = {
446
+ interface CreateToolParamsBase {
425
447
  name: string;
426
448
  description: string;
449
+ executionMode: ExecutionMode;
450
+ parameters?: ToolParameters;
451
+ }
452
+ interface CreateWebhookToolParams extends CreateToolParamsBase {
453
+ type: "custom_webhook";
427
454
  endpointMethod: "POST";
428
455
  endpointUrl: string;
429
456
  endpointHeaders?: Record<string, string>;
430
457
  endpointTimeoutMs?: number;
431
- parameters?: ToolParameters;
432
- };
458
+ }
459
+ interface CreateWebSocketToolParams extends CreateToolParamsBase {
460
+ type: "custom_websocket";
461
+ toolCallOutputTimeoutMs?: number;
462
+ }
463
+ type CreateToolParams = CreateWebhookToolParams | CreateWebSocketToolParams;
433
464
  type CreateToolSuccessResponse = {
434
465
  id: string;
435
466
  name: string;
@@ -437,11 +468,14 @@ type CreateToolSuccessResponse = {
437
468
  type UpdateToolParams = {
438
469
  name?: string;
439
470
  description?: string;
471
+ type?: "custom_webhook" | "custom_websocket";
472
+ executionMode?: ExecutionMode;
440
473
  endpointMethod?: "POST";
441
474
  endpointUrl?: string;
442
475
  endpointHeaders?: Record<string, string>;
443
476
  endpointTimeoutMs?: number;
444
- parameters?: Array<PrimitiveParameter | ArrayParameter>;
477
+ toolCallOutputTimeoutMs?: number;
478
+ parameters?: ToolParameters;
445
479
  };
446
480
  type UpdateToolSuccessResponse = {
447
481
  success: true;
@@ -550,4 +584,4 @@ declare class Phonic {
550
584
  }>;
551
585
  }
552
586
 
553
- export { Phonic, type PhonicConfigurationEndpointRequestPayload, type PhonicConfigurationEndpointResponsePayload, type PhonicSTSConfig, PhonicSTSWebSocket };
587
+ export { Phonic, type PhonicConfigurationEndpointRequestPayload, type PhonicConfigurationEndpointResponsePayload, type PhonicSTSConfig, PhonicSTSWebSocket, type PhonicSTSWebSocketResponseMessage };
package/dist/index.d.ts CHANGED
@@ -93,8 +93,8 @@ type PhonicSTSWebSocketResponseMessage = {
93
93
  type: "dtmf";
94
94
  digits: string;
95
95
  } | {
96
- type: "tool_call";
97
- id: string;
96
+ type: "tool_call_output_processed";
97
+ tool_call_id: string;
98
98
  tool: {
99
99
  id: string;
100
100
  name: string;
@@ -109,10 +109,17 @@ type PhonicSTSWebSocketResponseMessage = {
109
109
  } | null;
110
110
  [key: string]: unknown;
111
111
  } | null;
112
- response_body: Record<string, unknown> | null;
112
+ parameters: Record<string, unknown> | null;
113
+ output: unknown | null;
114
+ response_body: unknown | null;
113
115
  response_status_code: number | null;
114
116
  timed_out: boolean | null;
115
117
  error_message: string | null;
118
+ } | {
119
+ type: "tool_call";
120
+ tool_call_id: string;
121
+ tool_name: string;
122
+ parameters: Record<string, unknown>;
116
123
  } | {
117
124
  type: "error";
118
125
  error: {
@@ -371,12 +378,17 @@ declare class PhonicSTSWebSocket {
371
378
  private buffer;
372
379
  private isOpen;
373
380
  constructor(ws: WebSocket, config: PhonicSTSConfig);
381
+ private processUserMessage;
374
382
  onMessage(callback: OnMessageCallback): void;
375
383
  onClose(callback: OnCloseCallback): void;
376
384
  onError(callback: OnErrorCallback): void;
377
385
  audioChunk({ audio }: {
378
386
  audio: string;
379
387
  }): void;
388
+ sendToolCallOutput({ toolCallId, output, }: {
389
+ toolCallId: string;
390
+ output: unknown;
391
+ }): void;
380
392
  updateSystemPrompt({ systemPrompt }: {
381
393
  systemPrompt: string;
382
394
  }): void;
@@ -405,31 +417,50 @@ interface ArrayParameter extends ParameterBase {
405
417
  itemType: "string" | "integer" | "number" | "boolean";
406
418
  }
407
419
  type ToolParameters = Array<PrimitiveParameter | ArrayParameter>;
408
- type Tool = {
420
+ type ExecutionMode = "sync" | "async";
421
+ interface ToolBase {
409
422
  id: string;
410
423
  name: string;
411
424
  description: string;
425
+ execution_mode: ExecutionMode;
426
+ parameters: ToolParameters;
427
+ }
428
+ interface WebhookTool extends ToolBase {
429
+ type: "custom_webhook";
412
430
  endpoint_method: "POST";
413
431
  endpoint_url: string;
414
432
  endpoint_headers: Record<string, string>;
415
433
  endpoint_timeout_ms: number;
416
- parameters: ToolParameters;
417
- };
434
+ }
435
+ interface WebSocketTool extends ToolBase {
436
+ type: "custom_websocket";
437
+ tool_call_output_timeout_ms: number;
438
+ }
439
+ type Tool = WebhookTool | WebSocketTool;
418
440
  type ListToolsSuccessResponse = DataOrError<{
419
441
  tools: Array<Tool>;
420
442
  }>;
421
443
  type GetToolSuccessResponse = DataOrError<{
422
444
  tool: Tool;
423
445
  }>;
424
- type CreateToolParams = {
446
+ interface CreateToolParamsBase {
425
447
  name: string;
426
448
  description: string;
449
+ executionMode: ExecutionMode;
450
+ parameters?: ToolParameters;
451
+ }
452
+ interface CreateWebhookToolParams extends CreateToolParamsBase {
453
+ type: "custom_webhook";
427
454
  endpointMethod: "POST";
428
455
  endpointUrl: string;
429
456
  endpointHeaders?: Record<string, string>;
430
457
  endpointTimeoutMs?: number;
431
- parameters?: ToolParameters;
432
- };
458
+ }
459
+ interface CreateWebSocketToolParams extends CreateToolParamsBase {
460
+ type: "custom_websocket";
461
+ toolCallOutputTimeoutMs?: number;
462
+ }
463
+ type CreateToolParams = CreateWebhookToolParams | CreateWebSocketToolParams;
433
464
  type CreateToolSuccessResponse = {
434
465
  id: string;
435
466
  name: string;
@@ -437,11 +468,14 @@ type CreateToolSuccessResponse = {
437
468
  type UpdateToolParams = {
438
469
  name?: string;
439
470
  description?: string;
471
+ type?: "custom_webhook" | "custom_websocket";
472
+ executionMode?: ExecutionMode;
440
473
  endpointMethod?: "POST";
441
474
  endpointUrl?: string;
442
475
  endpointHeaders?: Record<string, string>;
443
476
  endpointTimeoutMs?: number;
444
- parameters?: Array<PrimitiveParameter | ArrayParameter>;
477
+ toolCallOutputTimeoutMs?: number;
478
+ parameters?: ToolParameters;
445
479
  };
446
480
  type UpdateToolSuccessResponse = {
447
481
  success: true;
@@ -550,4 +584,4 @@ declare class Phonic {
550
584
  }>;
551
585
  }
552
586
 
553
- export { Phonic, type PhonicConfigurationEndpointRequestPayload, type PhonicConfigurationEndpointResponsePayload, type PhonicSTSConfig, PhonicSTSWebSocket };
587
+ export { Phonic, type PhonicConfigurationEndpointRequestPayload, type PhonicConfigurationEndpointResponsePayload, type PhonicSTSConfig, PhonicSTSWebSocket, type PhonicSTSWebSocketResponseMessage };
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.26.1";
38
+ var version = "0.27.0";
39
39
 
40
40
  // src/agents/index.ts
41
41
  var Agents = class {
@@ -298,6 +298,9 @@ var PhonicSTSWebSocket = class {
298
298
  this.onClose = this.onClose.bind(this);
299
299
  this.onError = this.onError.bind(this);
300
300
  this.audioChunk = this.audioChunk.bind(this);
301
+ this.sendToolCallOutput = this.sendToolCallOutput.bind(this);
302
+ this.updateSystemPrompt = this.updateSystemPrompt.bind(this);
303
+ this.setExternalId = this.setExternalId.bind(this);
301
304
  this.close = this.close.bind(this);
302
305
  }
303
306
  onMessageCallback = null;
@@ -305,6 +308,14 @@ var PhonicSTSWebSocket = class {
305
308
  onErrorCallback = null;
306
309
  buffer = [];
307
310
  isOpen = false;
311
+ processUserMessage(message) {
312
+ const messageStr = JSON.stringify(message);
313
+ if (this.isOpen) {
314
+ this.ws.send(messageStr);
315
+ } else {
316
+ this.buffer.push(messageStr);
317
+ }
318
+ }
308
319
  onMessage(callback) {
309
320
  this.onMessageCallback = callback;
310
321
  }
@@ -315,37 +326,32 @@ var PhonicSTSWebSocket = class {
315
326
  this.onErrorCallback = callback;
316
327
  }
317
328
  audioChunk({ audio }) {
318
- const audiochunkMessage = JSON.stringify({
329
+ this.processUserMessage({
319
330
  type: "audio_chunk",
320
331
  audio
321
332
  });
322
- if (this.isOpen) {
323
- this.ws.send(audiochunkMessage);
324
- } else {
325
- this.buffer.push(audiochunkMessage);
326
- }
333
+ }
334
+ sendToolCallOutput({
335
+ toolCallId,
336
+ output
337
+ }) {
338
+ this.processUserMessage({
339
+ type: "tool_call_output",
340
+ tool_call_id: toolCallId,
341
+ output
342
+ });
327
343
  }
328
344
  updateSystemPrompt({ systemPrompt }) {
329
- const updateSystemPromptMessage = JSON.stringify({
345
+ this.processUserMessage({
330
346
  type: "update_system_prompt",
331
347
  system_prompt: systemPrompt
332
348
  });
333
- if (this.isOpen) {
334
- this.ws.send(updateSystemPromptMessage);
335
- } else {
336
- this.buffer.push(updateSystemPromptMessage);
337
- }
338
349
  }
339
350
  setExternalId({ externalId }) {
340
- const setExternalIdMessage = JSON.stringify({
351
+ this.processUserMessage({
341
352
  type: "set_external_id",
342
353
  external_id: externalId
343
354
  });
344
- if (this.isOpen) {
345
- this.ws.send(setExternalIdMessage);
346
- } else {
347
- this.buffer.push(setExternalIdMessage);
348
- }
349
355
  }
350
356
  close(code) {
351
357
  this.ws.close(code ?? 1e3);
@@ -404,17 +410,25 @@ var Tools = class {
404
410
  return response;
405
411
  }
406
412
  async create(params) {
413
+ const body = {
414
+ name: params.name,
415
+ description: params.description,
416
+ type: params.type,
417
+ execution_mode: params.executionMode,
418
+ parameters: this.getParametersForBody(params.parameters)
419
+ };
420
+ if (params.type === "custom_webhook") {
421
+ body.endpoint_method = params.endpointMethod;
422
+ body.endpoint_url = params.endpointUrl;
423
+ body.endpoint_headers = params.endpointHeaders;
424
+ body.endpoint_timeout_ms = params.endpointTimeoutMs;
425
+ }
426
+ if (params.type === "custom_websocket") {
427
+ body.tool_call_output_timeout_ms = params.toolCallOutputTimeoutMs;
428
+ }
407
429
  const response = await this.phonic.post(
408
430
  "/tools",
409
- {
410
- name: params.name,
411
- description: params.description,
412
- endpoint_method: params.endpointMethod,
413
- endpoint_url: params.endpointUrl,
414
- endpoint_headers: params.endpointHeaders,
415
- endpoint_timeout_ms: params.endpointTimeoutMs,
416
- parameters: this.getParametersForBody(params.parameters)
417
- }
431
+ body
418
432
  );
419
433
  return response;
420
434
  }
@@ -424,11 +438,14 @@ var Tools = class {
424
438
  {
425
439
  name: params.name,
426
440
  description: params.description,
441
+ type: params.type,
442
+ execution_mode: params.executionMode,
427
443
  endpoint_method: params.endpointMethod,
428
444
  endpoint_url: params.endpointUrl,
429
445
  endpoint_headers: params.endpointHeaders,
430
446
  endpoint_timeout_ms: params.endpointTimeoutMs,
431
- parameters: this.getParametersForBody(params.parameters)
447
+ parameters: this.getParametersForBody(params.parameters),
448
+ tool_call_output_timeout_ms: params.toolCallOutputTimeoutMs
432
449
  }
433
450
  );
434
451
  return response;
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "0.26.1";
2
+ var version = "0.27.0";
3
3
 
4
4
  // src/agents/index.ts
5
5
  var Agents = class {
@@ -262,6 +262,9 @@ var PhonicSTSWebSocket = class {
262
262
  this.onClose = this.onClose.bind(this);
263
263
  this.onError = this.onError.bind(this);
264
264
  this.audioChunk = this.audioChunk.bind(this);
265
+ this.sendToolCallOutput = this.sendToolCallOutput.bind(this);
266
+ this.updateSystemPrompt = this.updateSystemPrompt.bind(this);
267
+ this.setExternalId = this.setExternalId.bind(this);
265
268
  this.close = this.close.bind(this);
266
269
  }
267
270
  onMessageCallback = null;
@@ -269,6 +272,14 @@ var PhonicSTSWebSocket = class {
269
272
  onErrorCallback = null;
270
273
  buffer = [];
271
274
  isOpen = false;
275
+ processUserMessage(message) {
276
+ const messageStr = JSON.stringify(message);
277
+ if (this.isOpen) {
278
+ this.ws.send(messageStr);
279
+ } else {
280
+ this.buffer.push(messageStr);
281
+ }
282
+ }
272
283
  onMessage(callback) {
273
284
  this.onMessageCallback = callback;
274
285
  }
@@ -279,37 +290,32 @@ var PhonicSTSWebSocket = class {
279
290
  this.onErrorCallback = callback;
280
291
  }
281
292
  audioChunk({ audio }) {
282
- const audiochunkMessage = JSON.stringify({
293
+ this.processUserMessage({
283
294
  type: "audio_chunk",
284
295
  audio
285
296
  });
286
- if (this.isOpen) {
287
- this.ws.send(audiochunkMessage);
288
- } else {
289
- this.buffer.push(audiochunkMessage);
290
- }
297
+ }
298
+ sendToolCallOutput({
299
+ toolCallId,
300
+ output
301
+ }) {
302
+ this.processUserMessage({
303
+ type: "tool_call_output",
304
+ tool_call_id: toolCallId,
305
+ output
306
+ });
291
307
  }
292
308
  updateSystemPrompt({ systemPrompt }) {
293
- const updateSystemPromptMessage = JSON.stringify({
309
+ this.processUserMessage({
294
310
  type: "update_system_prompt",
295
311
  system_prompt: systemPrompt
296
312
  });
297
- if (this.isOpen) {
298
- this.ws.send(updateSystemPromptMessage);
299
- } else {
300
- this.buffer.push(updateSystemPromptMessage);
301
- }
302
313
  }
303
314
  setExternalId({ externalId }) {
304
- const setExternalIdMessage = JSON.stringify({
315
+ this.processUserMessage({
305
316
  type: "set_external_id",
306
317
  external_id: externalId
307
318
  });
308
- if (this.isOpen) {
309
- this.ws.send(setExternalIdMessage);
310
- } else {
311
- this.buffer.push(setExternalIdMessage);
312
- }
313
319
  }
314
320
  close(code) {
315
321
  this.ws.close(code ?? 1e3);
@@ -368,17 +374,25 @@ var Tools = class {
368
374
  return response;
369
375
  }
370
376
  async create(params) {
377
+ const body = {
378
+ name: params.name,
379
+ description: params.description,
380
+ type: params.type,
381
+ execution_mode: params.executionMode,
382
+ parameters: this.getParametersForBody(params.parameters)
383
+ };
384
+ if (params.type === "custom_webhook") {
385
+ body.endpoint_method = params.endpointMethod;
386
+ body.endpoint_url = params.endpointUrl;
387
+ body.endpoint_headers = params.endpointHeaders;
388
+ body.endpoint_timeout_ms = params.endpointTimeoutMs;
389
+ }
390
+ if (params.type === "custom_websocket") {
391
+ body.tool_call_output_timeout_ms = params.toolCallOutputTimeoutMs;
392
+ }
371
393
  const response = await this.phonic.post(
372
394
  "/tools",
373
- {
374
- name: params.name,
375
- description: params.description,
376
- endpoint_method: params.endpointMethod,
377
- endpoint_url: params.endpointUrl,
378
- endpoint_headers: params.endpointHeaders,
379
- endpoint_timeout_ms: params.endpointTimeoutMs,
380
- parameters: this.getParametersForBody(params.parameters)
381
- }
395
+ body
382
396
  );
383
397
  return response;
384
398
  }
@@ -388,11 +402,14 @@ var Tools = class {
388
402
  {
389
403
  name: params.name,
390
404
  description: params.description,
405
+ type: params.type,
406
+ execution_mode: params.executionMode,
391
407
  endpoint_method: params.endpointMethod,
392
408
  endpoint_url: params.endpointUrl,
393
409
  endpoint_headers: params.endpointHeaders,
394
410
  endpoint_timeout_ms: params.endpointTimeoutMs,
395
- parameters: this.getParametersForBody(params.parameters)
411
+ parameters: this.getParametersForBody(params.parameters),
412
+ tool_call_output_timeout_ms: params.toolCallOutputTimeoutMs
396
413
  }
397
414
  );
398
415
  return response;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phonic",
3
- "version": "0.26.1",
3
+ "version": "0.27.0",
4
4
  "description": "Phonic Node.js SDK",
5
5
  "scripts": {
6
6
  "build": "tsup",