@getsupervisor/agents-studio-sdk 1.41.2-patch.14 → 1.41.2-patch.15

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
@@ -397,6 +397,45 @@ npx tsx examples/custom-tool-connection.ts
397
397
 
398
398
  El script envía la metadata de conexión (URL, método, headers) y, sobre todo, almacena un `configSchema` específico del workspace dentro de `tool_agent_connections.metadata`. Ese esquema describe los campos que el agente debe solicitar (en el ejemplo `agentId` y `customerName`) y coincide con la acción `triggerWorkflow` que expone el seed `custom.http.workflow`. Después de conectar la tool ejecuta `client.tools.execute('custom.http.workflow', { action: 'triggerWorkflow', args: { ... } })` respetando el schema definido en tu metadata.
399
399
 
400
+ ## SIP Trunks
401
+
402
+ Namespace: `client.sip`
403
+
404
+ Gestiona trunks SIP para conectar agentes de voz a carriers PSTN (Twilio, ccc2.uno, etc.).
405
+
406
+ Operaciones disponibles:
407
+
408
+ - `sip.list()` — lista todos los SIP trunks del workspace.
409
+ - `sip.get(trunkId)` — obtiene un trunk por ID.
410
+ - `sip.create(payload)` — crea un trunk (devuelve `password` solo en la creación).
411
+ - `sip.update(trunkId, payload)` — actualiza un trunk (campos parciales).
412
+ - `sip.delete(trunkId)` — elimina un trunk y su subscriber asociado.
413
+
414
+ Ejemplo:
415
+
416
+ ```ts
417
+ // crear un trunk SIP
418
+ const trunk = await client.sip.create({
419
+ name: 'Twilio Production',
420
+ carrierAddress: 'my-trunk.pstn.twilio.com',
421
+ // opcionales: carrierPort (default 5060), carrierTransport (default 'udp'), phoneNumbers
422
+ });
423
+
424
+ console.log(trunk.username); // auto-generado para SIP digest auth
425
+ console.log(trunk.password); // solo visible en la creación
426
+
427
+ // listar trunks del workspace
428
+ const trunks = await client.sip.list();
429
+
430
+ // actualizar
431
+ await client.sip.update(trunk.id, { name: 'Twilio Staging' });
432
+
433
+ // eliminar
434
+ await client.sip.delete(trunk.id);
435
+ ```
436
+
437
+ Scopes requeridos: `sip:read` para lectura, `sip:write` para escritura.
438
+
400
439
  ## Configuración
401
440
 
402
441
  ```ts
package/dist/index.cjs CHANGED
@@ -50,6 +50,7 @@ __export(index_exports, {
50
50
  createCatalogsApi: () => createCatalogsApi,
51
51
  createClient: () => createClient,
52
52
  createHttp: () => createHttp,
53
+ createSipTrunksApi: () => createSipTrunksApi,
53
54
  createToolsApi: () => createToolsApi,
54
55
  createUsageApi: () => createUsageApi,
55
56
  createVoicesApi: () => createVoicesApi,
@@ -952,6 +953,102 @@ function createAgentVersionsApi(cfg) {
952
953
  };
953
954
  }
954
955
 
956
+ // src/utils/sse-stream.ts
957
+ function extractField(line, prefix) {
958
+ if (!line.startsWith(prefix)) {
959
+ return null;
960
+ }
961
+ return line.slice(prefix.length);
962
+ }
963
+ function parseSseMessage(raw) {
964
+ let type = "";
965
+ let data = "";
966
+ for (const line of raw.split("\n")) {
967
+ type = extractField(line, "event: ") ?? type;
968
+ data = extractField(line, "data: ") ?? data;
969
+ }
970
+ if (!type || !data) {
971
+ return null;
972
+ }
973
+ return { type, data };
974
+ }
975
+ function dispatchSseEvent(event, handlers) {
976
+ const handler = handlers[event.type];
977
+ if (!handler) {
978
+ return void 0;
979
+ }
980
+ try {
981
+ const parsed = JSON.parse(event.data);
982
+ handler(parsed);
983
+ return parsed;
984
+ } catch {
985
+ return void 0;
986
+ }
987
+ }
988
+ function processRawPart(raw, handlers, resolveEvent) {
989
+ const trimmed = raw.trim();
990
+ if (!trimmed) {
991
+ return void 0;
992
+ }
993
+ const event = parseSseMessage(trimmed);
994
+ if (!event) {
995
+ return void 0;
996
+ }
997
+ const result = dispatchSseEvent(event, handlers);
998
+ if (event.type !== resolveEvent) {
999
+ return void 0;
1000
+ }
1001
+ return result;
1002
+ }
1003
+ function flushRemainingBuffer(buffer) {
1004
+ if (!buffer.trim()) {
1005
+ return "";
1006
+ }
1007
+ return buffer + "\n\n";
1008
+ }
1009
+ function consumeSseStream(response, handlers, resolveEvent) {
1010
+ if (!response.body) {
1011
+ throw new Error("No response body for SSE stream");
1012
+ }
1013
+ return new Promise((resolve, reject) => {
1014
+ let resolved;
1015
+ let buffer = "";
1016
+ const reader = response.body.getReader();
1017
+ const decoder = new TextDecoder();
1018
+ const processBuffer = () => {
1019
+ const parts = buffer.split("\n\n");
1020
+ buffer = parts.pop() ?? "";
1021
+ for (const part of parts) {
1022
+ const result = processRawPart(part, handlers, resolveEvent);
1023
+ if (result) {
1024
+ resolved = result;
1025
+ }
1026
+ }
1027
+ };
1028
+ const finalize = () => {
1029
+ buffer = flushRemainingBuffer(buffer);
1030
+ processBuffer();
1031
+ if (resolved) {
1032
+ resolve(resolved);
1033
+ return;
1034
+ }
1035
+ reject(new Error(`SSE stream ended without '${resolveEvent}' event`));
1036
+ };
1037
+ const read = () => {
1038
+ reader.read().then(({ done, value }) => {
1039
+ if (done) {
1040
+ finalize();
1041
+ return;
1042
+ }
1043
+ buffer += decoder.decode(value, { stream: true });
1044
+ processBuffer();
1045
+ read();
1046
+ }).catch(reject);
1047
+ };
1048
+ read();
1049
+ });
1050
+ }
1051
+
955
1052
  // src/entities/agent.ts
956
1053
  var bindAgentStageTriggers = (api, agentId, blueprintId, stageId) => ({
957
1054
  list(opts) {
@@ -1172,8 +1269,36 @@ var createAgentEntity = (dto, options) => {
1172
1269
  };
1173
1270
 
1174
1271
  // src/api/agents.ts
1272
+ function normalizeCloneSelection(selection) {
1273
+ if (!selection) {
1274
+ return [];
1275
+ }
1276
+ if (Array.isArray(selection)) {
1277
+ return selection;
1278
+ }
1279
+ return Object.entries(selection).filter(([, enabled]) => enabled).map(([component]) => component);
1280
+ }
1281
+ function buildCloneRequest(payload) {
1282
+ const { clone, ...rest } = payload;
1283
+ return { ...rest, clone: normalizeCloneSelection(clone) };
1284
+ }
1285
+ function buildSseHandlers(callbacks) {
1286
+ return {
1287
+ "agent-created": (data) => callbacks.onAgentCreated?.(data),
1288
+ "runtime-progress": (data) => callbacks.onProgress?.(data),
1289
+ "runtime-complete": (data) => callbacks.onComplete?.(data),
1290
+ "runtime-error": (data) => callbacks.onError?.(data)
1291
+ };
1292
+ }
1293
+ function resolveAgentId(agent) {
1294
+ if (typeof agent === "string") {
1295
+ return agent;
1296
+ }
1297
+ return agent.agentId;
1298
+ }
1175
1299
  function createAgentsApi(cfg, relatedApis) {
1176
- const { base, doFetch, resolveWorkspaceId, resolveApiKey } = createHttp(cfg);
1300
+ const { base, doFetch, buildHeaders, resolveWorkspaceId, resolveApiKey } = createHttp(cfg);
1301
+ const jsonHeaders = { "content-type": "application/json" };
1177
1302
  const requireWorkspace = () => {
1178
1303
  const workspaceId = resolveWorkspaceId();
1179
1304
  if (typeof workspaceId === "string" && workspaceId.trim().length > 0) {
@@ -1185,167 +1310,144 @@ function createAgentsApi(cfg, relatedApis) {
1185
1310
  }
1186
1311
  throw new WorkspaceNotSelectedError();
1187
1312
  };
1188
- const jsonHeaders = { "content-type": "application/json" };
1189
- const normalizeCloneSelection = (selection) => {
1190
- if (!selection) {
1191
- return [];
1192
- }
1193
- if (Array.isArray(selection)) {
1194
- return selection;
1195
- }
1196
- return Object.entries(selection).filter(([, enabled]) => enabled).map(([component]) => component);
1197
- };
1198
- const buildCloneAgentRequest = (payload) => {
1199
- const { clone, ...rest } = payload;
1200
- return {
1201
- ...rest,
1202
- clone: normalizeCloneSelection(clone)
1203
- };
1204
- };
1205
- const fetchAgentsPage = async (options = {}) => {
1206
- requireWorkspace();
1207
- const sanitizedOptions = {
1208
- page: options.page,
1209
- limit: options.limit,
1210
- filter: options.filter
1211
- };
1212
- const query = serializeListOptions(sanitizedOptions);
1213
- const res = await doFetch(`${base}/agents`, {
1214
- method: "GET",
1215
- query
1216
- });
1217
- return res.json();
1218
- };
1219
- const listAgents = async (options = {}) => {
1220
- const normalizedOptions = { ...options ?? {} };
1221
- const response = await fetchAgentsPage(normalizedOptions);
1222
- return attachPaginator(response, fetchAgentsPage, normalizedOptions);
1223
- };
1224
- const getAgentDetail = async (agentId) => {
1313
+ const postJson = async (url, payload) => {
1225
1314
  requireWorkspace();
1226
- const res = await doFetch(`${base}/agents/${agentId}`, {
1227
- method: "GET"
1228
- });
1229
- return res.json();
1230
- };
1231
- const createAgent = async (payload) => {
1232
- requireWorkspace();
1233
- const res = await doFetch(`${base}/agents`, {
1315
+ const res = await doFetch(url, {
1234
1316
  method: "POST",
1235
1317
  body: JSON.stringify(payload),
1236
1318
  headers: jsonHeaders
1237
1319
  });
1238
1320
  return res.json();
1239
1321
  };
1240
- const forkAgentFromTemplate = async (payload) => {
1322
+ const postWithSse = async (url, payload, callbacks) => {
1241
1323
  requireWorkspace();
1242
- const res = await doFetch(`${base}/agents/from-template`, {
1324
+ const headers = buildHeaders({ "content-type": "application/json" });
1325
+ const fx = cfg.fetchImpl ?? fetch;
1326
+ const res = await fx(url, {
1243
1327
  method: "POST",
1244
1328
  body: JSON.stringify(payload),
1245
- headers: jsonHeaders
1246
- });
1247
- return res.json();
1248
- };
1249
- const cloneAgent = async (agentId, payload) => {
1250
- requireWorkspace();
1251
- const requestPayload = buildCloneAgentRequest(payload);
1252
- const res = await doFetch(`${base}/agents/${agentId}/clone`, {
1253
- method: "POST",
1254
- body: JSON.stringify(requestPayload),
1255
- headers: jsonHeaders
1329
+ headers
1256
1330
  });
1257
- return res.json();
1331
+ const contentType = res.headers.get("content-type") ?? "";
1332
+ if (contentType.includes("application/json")) {
1333
+ const agent = await res.json();
1334
+ callbacks.onAgentCreated?.(agent);
1335
+ return agent;
1336
+ }
1337
+ return consumeSseStream(
1338
+ res,
1339
+ buildSseHandlers(callbacks),
1340
+ "agent-created"
1341
+ );
1258
1342
  };
1259
- const updateAgent = async (agentId, payload) => {
1343
+ const fetchPage = async (options = {}) => {
1260
1344
  requireWorkspace();
1261
- const res = await doFetch(`${base}/agents/${agentId}`, {
1262
- method: "PATCH",
1263
- body: JSON.stringify(payload),
1264
- headers: jsonHeaders
1345
+ const query = serializeListOptions({
1346
+ page: options.page,
1347
+ limit: options.limit,
1348
+ filter: options.filter
1265
1349
  });
1350
+ const res = await doFetch(`${base}/agents`, { method: "GET", query });
1266
1351
  return res.json();
1267
1352
  };
1268
- const resolveAgentId = (agent) => {
1269
- return typeof agent === "string" ? agent : agent.agentId;
1270
- };
1271
- const deleteAgent = async (agent) => {
1272
- requireWorkspace();
1273
- const agentId = resolveAgentId(agent);
1274
- await doFetch(`${base}/agents/${agentId}`, {
1275
- method: "DELETE"
1276
- });
1277
- };
1278
1353
  const baseApi = {
1279
- list: listAgents,
1280
- get: getAgentDetail,
1281
- create: createAgent,
1282
- clone: cloneAgent,
1283
- forkFromTemplate: forkAgentFromTemplate,
1284
- update: updateAgent,
1285
- delete: deleteAgent
1354
+ async list(options = {}) {
1355
+ const opts = { ...options ?? {} };
1356
+ const response = await fetchPage(opts);
1357
+ return attachPaginator(response, fetchPage, opts);
1358
+ },
1359
+ async get(agentId) {
1360
+ requireWorkspace();
1361
+ const res = await doFetch(`${base}/agents/${agentId}`, { method: "GET" });
1362
+ return res.json();
1363
+ },
1364
+ async create(payload, callbacks) {
1365
+ if (callbacks) {
1366
+ return postWithSse(`${base}/agents`, payload, callbacks);
1367
+ }
1368
+ return postJson(`${base}/agents`, payload);
1369
+ },
1370
+ async clone(agentId, payload) {
1371
+ return postJson(
1372
+ `${base}/agents/${agentId}/clone`,
1373
+ buildCloneRequest(payload)
1374
+ );
1375
+ },
1376
+ async forkFromTemplate(payload, callbacks) {
1377
+ if (callbacks) {
1378
+ return postWithSse(`${base}/agents/from-template`, payload, callbacks);
1379
+ }
1380
+ return postJson(`${base}/agents/from-template`, payload);
1381
+ },
1382
+ async update(agentId, payload) {
1383
+ requireWorkspace();
1384
+ const res = await doFetch(`${base}/agents/${agentId}`, {
1385
+ method: "PATCH",
1386
+ body: JSON.stringify(payload),
1387
+ headers: jsonHeaders
1388
+ });
1389
+ return res.json();
1390
+ },
1391
+ async presignDocuments(files) {
1392
+ return postJson(`${base}/documents`, { files });
1393
+ },
1394
+ async delete(agent) {
1395
+ requireWorkspace();
1396
+ await doFetch(`${base}/agents/${resolveAgentId(agent)}`, {
1397
+ method: "DELETE"
1398
+ });
1399
+ }
1286
1400
  };
1287
1401
  if (!relatedApis) {
1288
1402
  return baseApi;
1289
1403
  }
1404
+ return withEntityWrapping(baseApi, fetchPage, relatedApis);
1405
+ }
1406
+ function withEntityWrapping(api, fetchPage, deps) {
1290
1407
  const wrapAgent = (detail) => createAgentEntity(detail, {
1291
- tagsApi: relatedApis.tagsApi,
1292
- phonesApi: relatedApis.phonesApi,
1293
- scheduleApi: relatedApis.scheduleApi,
1294
- scheduleExceptionsApi: relatedApis.scheduleExceptionsApi,
1295
- versionsApi: relatedApis.versionsApi,
1296
- blueprintsApi: relatedApis.blueprintsApi,
1297
- stagesApi: relatedApis.stagesApi,
1298
- stageTriggersApi: relatedApis.stageTriggersApi,
1408
+ ...deps,
1299
1409
  reload: async (agentId) => {
1300
- const latest = await getAgentDetail(agentId);
1410
+ const latest = await api.get(agentId);
1301
1411
  return wrapAgent(latest);
1302
1412
  },
1303
1413
  updateAgent: async (agentId, payload) => {
1304
- const updated = await updateAgent(agentId, payload);
1414
+ const updated = await api.update(agentId, payload);
1305
1415
  return wrapAgent(updated);
1306
1416
  },
1307
1417
  deleteAgent: async (agentId) => {
1308
- await deleteAgent(agentId);
1418
+ await api.delete(agentId);
1309
1419
  },
1310
1420
  cloneAgent: async (agentId, payload) => {
1311
- const cloned = await cloneAgent(agentId, payload);
1421
+ const cloned = await api.clone(agentId, payload);
1312
1422
  return wrapAgent(cloned);
1313
1423
  }
1314
1424
  });
1425
+ const wrapList = async (opts) => {
1426
+ const result = await fetchPage(opts);
1427
+ const items = Array.isArray(result.data) ? result.data : [];
1428
+ return { ...result, data: items.map(wrapAgent) };
1429
+ };
1315
1430
  return {
1316
- ...baseApi,
1431
+ ...api,
1317
1432
  async list(options = {}) {
1318
- const normalizedOptions = { ...options ?? {} };
1319
- const applyWrap = async (opts) => {
1320
- const result = await fetchAgentsPage(opts);
1321
- const items = Array.isArray(result.data) ? result.data : [];
1322
- return {
1323
- ...result,
1324
- data: items.map((summary) => wrapAgent(summary))
1325
- };
1326
- };
1327
- const initial = await applyWrap(normalizedOptions);
1328
- return attachPaginator(initial, applyWrap, normalizedOptions);
1433
+ const opts = { ...options ?? {} };
1434
+ const initial = await wrapList(opts);
1435
+ return attachPaginator(initial, wrapList, opts);
1329
1436
  },
1330
1437
  async get(agentId) {
1331
- const detail = await getAgentDetail(agentId);
1332
- return wrapAgent(detail);
1438
+ return wrapAgent(await api.get(agentId));
1333
1439
  },
1334
- async create(payload) {
1335
- const detail = await createAgent(payload);
1336
- return wrapAgent(detail);
1440
+ async create(payload, callbacks) {
1441
+ return wrapAgent(await api.create(payload, callbacks));
1337
1442
  },
1338
1443
  async clone(agentId, payload) {
1339
- const detail = await cloneAgent(agentId, payload);
1340
- return wrapAgent(detail);
1444
+ return wrapAgent(await api.clone(agentId, payload));
1341
1445
  },
1342
- async forkFromTemplate(payload) {
1343
- const detail = await forkAgentFromTemplate(payload);
1344
- return wrapAgent(detail);
1446
+ async forkFromTemplate(payload, callbacks) {
1447
+ return wrapAgent(await api.forkFromTemplate(payload, callbacks));
1345
1448
  },
1346
1449
  async update(agentId, payload) {
1347
- const detail = await updateAgent(agentId, payload);
1348
- return wrapAgent(detail);
1450
+ return wrapAgent(await api.update(agentId, payload));
1349
1451
  }
1350
1452
  };
1351
1453
  }
@@ -1609,6 +1711,42 @@ function createCatalogsApi(cfg) {
1609
1711
  };
1610
1712
  }
1611
1713
 
1714
+ // src/api/sip-trunks.ts
1715
+ function createSipTrunksApi(cfg) {
1716
+ const { base, doFetch } = createHttp(cfg);
1717
+ return {
1718
+ async list() {
1719
+ const res = await doFetch(`${base}/sip/trunks`, { method: "GET" });
1720
+ return res.json();
1721
+ },
1722
+ async get(trunkId) {
1723
+ const res = await doFetch(`${base}/sip/trunks/${trunkId}`, {
1724
+ method: "GET"
1725
+ });
1726
+ return res.json();
1727
+ },
1728
+ async create(body) {
1729
+ const res = await doFetch(`${base}/sip/trunks`, {
1730
+ method: "POST",
1731
+ headers: { "Content-Type": "application/json" },
1732
+ body: JSON.stringify(body)
1733
+ });
1734
+ return res.json();
1735
+ },
1736
+ async update(trunkId, body) {
1737
+ const res = await doFetch(`${base}/sip/trunks/${trunkId}`, {
1738
+ method: "PATCH",
1739
+ headers: { "Content-Type": "application/json" },
1740
+ body: JSON.stringify(body)
1741
+ });
1742
+ return res.json();
1743
+ },
1744
+ async delete(trunkId) {
1745
+ await doFetch(`${base}/sip/trunks/${trunkId}`, { method: "DELETE" });
1746
+ }
1747
+ };
1748
+ }
1749
+
1612
1750
  // src/api/tools.ts
1613
1751
  var IDEMPOTENCY_HEADER = "Idempotency-Key";
1614
1752
  var generateIdempotencyKey = (explicit) => {
@@ -2376,6 +2514,7 @@ function createClient(initialCfg) {
2376
2514
  billing: createBillingApi(runtimeCfg),
2377
2515
  calls: callsApi,
2378
2516
  usage: createUsageApi(runtimeCfg),
2517
+ sip: createSipTrunksApi(runtimeCfg),
2379
2518
  webhooks: webhooksApi
2380
2519
  };
2381
2520
  return {
@@ -2466,6 +2605,7 @@ function createClient(initialCfg) {
2466
2605
  createCatalogsApi,
2467
2606
  createClient,
2468
2607
  createHttp,
2608
+ createSipTrunksApi,
2469
2609
  createToolsApi,
2470
2610
  createUsageApi,
2471
2611
  createVoicesApi,