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

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
@@ -49,7 +49,9 @@ __export(index_exports, {
49
49
  createCatalogTemplatesApi: () => createCatalogTemplatesApi,
50
50
  createCatalogsApi: () => createCatalogsApi,
51
51
  createClient: () => createClient,
52
+ createDocumentsApi: () => createDocumentsApi,
52
53
  createHttp: () => createHttp,
54
+ createSipTrunksApi: () => createSipTrunksApi,
53
55
  createToolsApi: () => createToolsApi,
54
56
  createUsageApi: () => createUsageApi,
55
57
  createVoicesApi: () => createVoicesApi,
@@ -952,6 +954,102 @@ function createAgentVersionsApi(cfg) {
952
954
  };
953
955
  }
954
956
 
957
+ // src/utils/sse-stream.ts
958
+ function extractField(line, prefix) {
959
+ if (!line.startsWith(prefix)) {
960
+ return null;
961
+ }
962
+ return line.slice(prefix.length);
963
+ }
964
+ function parseSseMessage(raw) {
965
+ let type = "";
966
+ let data = "";
967
+ for (const line of raw.split("\n")) {
968
+ type = extractField(line, "event: ") ?? type;
969
+ data = extractField(line, "data: ") ?? data;
970
+ }
971
+ if (!type || !data) {
972
+ return null;
973
+ }
974
+ return { type, data };
975
+ }
976
+ function dispatchSseEvent(event, handlers) {
977
+ const handler = handlers[event.type];
978
+ if (!handler) {
979
+ return void 0;
980
+ }
981
+ try {
982
+ const parsed = JSON.parse(event.data);
983
+ handler(parsed);
984
+ return parsed;
985
+ } catch {
986
+ return void 0;
987
+ }
988
+ }
989
+ function processRawPart(raw, handlers, resolveEvent) {
990
+ const trimmed = raw.trim();
991
+ if (!trimmed) {
992
+ return void 0;
993
+ }
994
+ const event = parseSseMessage(trimmed);
995
+ if (!event) {
996
+ return void 0;
997
+ }
998
+ const result = dispatchSseEvent(event, handlers);
999
+ if (event.type !== resolveEvent) {
1000
+ return void 0;
1001
+ }
1002
+ return result;
1003
+ }
1004
+ function flushRemainingBuffer(buffer) {
1005
+ if (!buffer.trim()) {
1006
+ return "";
1007
+ }
1008
+ return buffer + "\n\n";
1009
+ }
1010
+ function consumeSseStream(response, handlers, resolveEvent) {
1011
+ if (!response.body) {
1012
+ throw new Error("No response body for SSE stream");
1013
+ }
1014
+ return new Promise((resolve, reject) => {
1015
+ let resolved;
1016
+ let buffer = "";
1017
+ const reader = response.body.getReader();
1018
+ const decoder = new TextDecoder();
1019
+ const processBuffer = () => {
1020
+ const parts = buffer.split("\n\n");
1021
+ buffer = parts.pop() ?? "";
1022
+ for (const part of parts) {
1023
+ const result = processRawPart(part, handlers, resolveEvent);
1024
+ if (result) {
1025
+ resolved = result;
1026
+ }
1027
+ }
1028
+ };
1029
+ const finalize = () => {
1030
+ buffer = flushRemainingBuffer(buffer);
1031
+ processBuffer();
1032
+ if (resolved) {
1033
+ resolve(resolved);
1034
+ return;
1035
+ }
1036
+ reject(new Error(`SSE stream ended without '${resolveEvent}' event`));
1037
+ };
1038
+ const read = () => {
1039
+ reader.read().then(({ done, value }) => {
1040
+ if (done) {
1041
+ finalize();
1042
+ return;
1043
+ }
1044
+ buffer += decoder.decode(value, { stream: true });
1045
+ processBuffer();
1046
+ read();
1047
+ }).catch(reject);
1048
+ };
1049
+ read();
1050
+ });
1051
+ }
1052
+
955
1053
  // src/entities/agent.ts
956
1054
  var bindAgentStageTriggers = (api, agentId, blueprintId, stageId) => ({
957
1055
  list(opts) {
@@ -1172,8 +1270,36 @@ var createAgentEntity = (dto, options) => {
1172
1270
  };
1173
1271
 
1174
1272
  // src/api/agents.ts
1273
+ function normalizeCloneSelection(selection) {
1274
+ if (!selection) {
1275
+ return [];
1276
+ }
1277
+ if (Array.isArray(selection)) {
1278
+ return selection;
1279
+ }
1280
+ return Object.entries(selection).filter(([, enabled]) => enabled).map(([component]) => component);
1281
+ }
1282
+ function buildCloneRequest(payload) {
1283
+ const { clone, ...rest } = payload;
1284
+ return { ...rest, clone: normalizeCloneSelection(clone) };
1285
+ }
1286
+ function buildSseHandlers(callbacks) {
1287
+ return {
1288
+ "agent-created": (data) => callbacks.onAgentCreated?.(data),
1289
+ "runtime-progress": (data) => callbacks.onProgress?.(data),
1290
+ "runtime-complete": (data) => callbacks.onComplete?.(data),
1291
+ "runtime-error": (data) => callbacks.onError?.(data)
1292
+ };
1293
+ }
1294
+ function resolveAgentId(agent) {
1295
+ if (typeof agent === "string") {
1296
+ return agent;
1297
+ }
1298
+ return agent.agentId;
1299
+ }
1175
1300
  function createAgentsApi(cfg, relatedApis) {
1176
- const { base, doFetch, resolveWorkspaceId, resolveApiKey } = createHttp(cfg);
1301
+ const { base, doFetch, buildHeaders, resolveWorkspaceId, resolveApiKey } = createHttp(cfg);
1302
+ const jsonHeaders = { "content-type": "application/json" };
1177
1303
  const requireWorkspace = () => {
1178
1304
  const workspaceId = resolveWorkspaceId();
1179
1305
  if (typeof workspaceId === "string" && workspaceId.trim().length > 0) {
@@ -1185,167 +1311,169 @@ function createAgentsApi(cfg, relatedApis) {
1185
1311
  }
1186
1312
  throw new WorkspaceNotSelectedError();
1187
1313
  };
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) => {
1225
- requireWorkspace();
1226
- const res = await doFetch(`${base}/agents/${agentId}`, {
1227
- method: "GET"
1228
- });
1229
- return res.json();
1230
- };
1231
- const createAgent = async (payload) => {
1314
+ const postJson = async (url, payload) => {
1232
1315
  requireWorkspace();
1233
- const res = await doFetch(`${base}/agents`, {
1316
+ const res = await doFetch(url, {
1234
1317
  method: "POST",
1235
1318
  body: JSON.stringify(payload),
1236
1319
  headers: jsonHeaders
1237
1320
  });
1238
1321
  return res.json();
1239
1322
  };
1240
- const forkAgentFromTemplate = async (payload) => {
1323
+ const postWithSse = async (url, payload, callbacks) => {
1241
1324
  requireWorkspace();
1242
- const res = await doFetch(`${base}/agents/from-template`, {
1325
+ const headers = buildHeaders({ "content-type": "application/json" });
1326
+ const fx = cfg.fetchImpl ?? fetch;
1327
+ const res = await fx(url, {
1243
1328
  method: "POST",
1244
1329
  body: JSON.stringify(payload),
1245
- headers: jsonHeaders
1330
+ headers
1246
1331
  });
1247
- return res.json();
1332
+ if (!res.ok) {
1333
+ const body = await res.text();
1334
+ throw new Error(`POST ${url} failed with status ${res.status}: ${body}`);
1335
+ }
1336
+ const contentType = res.headers.get("content-type") ?? "";
1337
+ if (contentType.includes("application/json")) {
1338
+ const agent = await res.json();
1339
+ callbacks.onAgentCreated?.(agent);
1340
+ return agent;
1341
+ }
1342
+ return consumeSseStream(
1343
+ res,
1344
+ buildSseHandlers(callbacks),
1345
+ "agent-created"
1346
+ );
1248
1347
  };
1249
- const cloneAgent = async (agentId, payload) => {
1348
+ const getWithSse = async (url, callbacks) => {
1250
1349
  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
1256
- });
1257
- return res.json();
1350
+ const headers = buildHeaders({});
1351
+ const fx = cfg.fetchImpl ?? fetch;
1352
+ const res = await fx(url, { method: "GET", headers });
1353
+ if (!res.ok) {
1354
+ const body = await res.text();
1355
+ throw new Error(`GET ${url} failed with status ${res.status}: ${body}`);
1356
+ }
1357
+ const contentType = res.headers.get("content-type") ?? "";
1358
+ if (contentType.includes("application/json")) {
1359
+ const agent = await res.json();
1360
+ callbacks.onAgentCreated?.(agent);
1361
+ return agent;
1362
+ }
1363
+ return consumeSseStream(
1364
+ res,
1365
+ buildSseHandlers(callbacks),
1366
+ "agent-created"
1367
+ );
1258
1368
  };
1259
- const updateAgent = async (agentId, payload) => {
1369
+ const fetchPage = async (options = {}) => {
1260
1370
  requireWorkspace();
1261
- const res = await doFetch(`${base}/agents/${agentId}`, {
1262
- method: "PATCH",
1263
- body: JSON.stringify(payload),
1264
- headers: jsonHeaders
1371
+ const query = serializeListOptions({
1372
+ page: options.page,
1373
+ limit: options.limit,
1374
+ filter: options.filter
1265
1375
  });
1376
+ const res = await doFetch(`${base}/agents`, { method: "GET", query });
1266
1377
  return res.json();
1267
1378
  };
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
1379
  const baseApi = {
1279
- list: listAgents,
1280
- get: getAgentDetail,
1281
- create: createAgent,
1282
- clone: cloneAgent,
1283
- forkFromTemplate: forkAgentFromTemplate,
1284
- update: updateAgent,
1285
- delete: deleteAgent
1380
+ async list(options = {}) {
1381
+ const opts = { ...options ?? {} };
1382
+ const response = await fetchPage(opts);
1383
+ return attachPaginator(response, fetchPage, opts);
1384
+ },
1385
+ async get(agentId, callbacks) {
1386
+ if (callbacks) {
1387
+ return getWithSse(`${base}/agents/${agentId}`, callbacks);
1388
+ }
1389
+ requireWorkspace();
1390
+ const res = await doFetch(`${base}/agents/${agentId}`, { method: "GET" });
1391
+ return res.json();
1392
+ },
1393
+ async create(payload, callbacks) {
1394
+ if (callbacks) {
1395
+ return postWithSse(`${base}/agents`, payload, callbacks);
1396
+ }
1397
+ return postJson(`${base}/agents`, payload);
1398
+ },
1399
+ async clone(agentId, payload) {
1400
+ return postJson(
1401
+ `${base}/agents/${agentId}/clone`,
1402
+ buildCloneRequest(payload)
1403
+ );
1404
+ },
1405
+ async forkFromTemplate(payload, callbacks) {
1406
+ if (callbacks) {
1407
+ return postWithSse(`${base}/agents/from-template`, payload, callbacks);
1408
+ }
1409
+ return postJson(`${base}/agents/from-template`, payload);
1410
+ },
1411
+ async update(agentId, payload) {
1412
+ requireWorkspace();
1413
+ const res = await doFetch(`${base}/agents/${agentId}`, {
1414
+ method: "PATCH",
1415
+ body: JSON.stringify(payload),
1416
+ headers: jsonHeaders
1417
+ });
1418
+ return res.json();
1419
+ },
1420
+ async delete(agent) {
1421
+ requireWorkspace();
1422
+ await doFetch(`${base}/agents/${resolveAgentId(agent)}`, {
1423
+ method: "DELETE"
1424
+ });
1425
+ }
1286
1426
  };
1287
1427
  if (!relatedApis) {
1288
1428
  return baseApi;
1289
1429
  }
1430
+ return withEntityWrapping(baseApi, fetchPage, relatedApis);
1431
+ }
1432
+ function withEntityWrapping(api, fetchPage, deps) {
1290
1433
  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,
1434
+ ...deps,
1299
1435
  reload: async (agentId) => {
1300
- const latest = await getAgentDetail(agentId);
1436
+ const latest = await api.get(agentId);
1301
1437
  return wrapAgent(latest);
1302
1438
  },
1303
1439
  updateAgent: async (agentId, payload) => {
1304
- const updated = await updateAgent(agentId, payload);
1440
+ const updated = await api.update(agentId, payload);
1305
1441
  return wrapAgent(updated);
1306
1442
  },
1307
1443
  deleteAgent: async (agentId) => {
1308
- await deleteAgent(agentId);
1444
+ await api.delete(agentId);
1309
1445
  },
1310
1446
  cloneAgent: async (agentId, payload) => {
1311
- const cloned = await cloneAgent(agentId, payload);
1447
+ const cloned = await api.clone(agentId, payload);
1312
1448
  return wrapAgent(cloned);
1313
1449
  }
1314
1450
  });
1451
+ const wrapList = async (opts) => {
1452
+ const result = await fetchPage(opts);
1453
+ const items = Array.isArray(result.data) ? result.data : [];
1454
+ return { ...result, data: items.map(wrapAgent) };
1455
+ };
1315
1456
  return {
1316
- ...baseApi,
1457
+ ...api,
1317
1458
  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);
1459
+ const opts = { ...options ?? {} };
1460
+ const initial = await wrapList(opts);
1461
+ return attachPaginator(initial, wrapList, opts);
1329
1462
  },
1330
- async get(agentId) {
1331
- const detail = await getAgentDetail(agentId);
1332
- return wrapAgent(detail);
1463
+ async get(agentId, callbacks) {
1464
+ return wrapAgent(await api.get(agentId, callbacks));
1333
1465
  },
1334
- async create(payload) {
1335
- const detail = await createAgent(payload);
1336
- return wrapAgent(detail);
1466
+ async create(payload, callbacks) {
1467
+ return wrapAgent(await api.create(payload, callbacks));
1337
1468
  },
1338
1469
  async clone(agentId, payload) {
1339
- const detail = await cloneAgent(agentId, payload);
1340
- return wrapAgent(detail);
1470
+ return wrapAgent(await api.clone(agentId, payload));
1341
1471
  },
1342
- async forkFromTemplate(payload) {
1343
- const detail = await forkAgentFromTemplate(payload);
1344
- return wrapAgent(detail);
1472
+ async forkFromTemplate(payload, callbacks) {
1473
+ return wrapAgent(await api.forkFromTemplate(payload, callbacks));
1345
1474
  },
1346
1475
  async update(agentId, payload) {
1347
- const detail = await updateAgent(agentId, payload);
1348
- return wrapAgent(detail);
1476
+ return wrapAgent(await api.update(agentId, payload));
1349
1477
  }
1350
1478
  };
1351
1479
  }
@@ -1609,6 +1737,70 @@ function createCatalogsApi(cfg) {
1609
1737
  };
1610
1738
  }
1611
1739
 
1740
+ // src/api/documents.ts
1741
+ function createDocumentsApi(cfg) {
1742
+ const { base, doFetch, resolveWorkspaceId, resolveApiKey } = createHttp(cfg);
1743
+ const jsonHeaders = { "content-type": "application/json" };
1744
+ const requireWorkspace = () => {
1745
+ const workspaceId = resolveWorkspaceId();
1746
+ if (typeof workspaceId === "string" && workspaceId.trim().length > 0) {
1747
+ return;
1748
+ }
1749
+ const apiKey = resolveApiKey();
1750
+ if (typeof apiKey === "string" && apiKey.trim().length > 0) {
1751
+ return;
1752
+ }
1753
+ throw new WorkspaceNotSelectedError();
1754
+ };
1755
+ return {
1756
+ async create(files) {
1757
+ requireWorkspace();
1758
+ const res = await doFetch(`${base}/documents`, {
1759
+ method: "POST",
1760
+ body: JSON.stringify({ files }),
1761
+ headers: jsonHeaders
1762
+ });
1763
+ return res.json();
1764
+ }
1765
+ };
1766
+ }
1767
+
1768
+ // src/api/sip-trunks.ts
1769
+ function createSipTrunksApi(cfg) {
1770
+ const { base, doFetch } = createHttp(cfg);
1771
+ return {
1772
+ async list() {
1773
+ const res = await doFetch(`${base}/sip/trunks`, { method: "GET" });
1774
+ return res.json();
1775
+ },
1776
+ async get(trunkId) {
1777
+ const res = await doFetch(`${base}/sip/trunks/${trunkId}`, {
1778
+ method: "GET"
1779
+ });
1780
+ return res.json();
1781
+ },
1782
+ async create(body) {
1783
+ const res = await doFetch(`${base}/sip/trunks`, {
1784
+ method: "POST",
1785
+ headers: { "Content-Type": "application/json" },
1786
+ body: JSON.stringify(body)
1787
+ });
1788
+ return res.json();
1789
+ },
1790
+ async update(trunkId, body) {
1791
+ const res = await doFetch(`${base}/sip/trunks/${trunkId}`, {
1792
+ method: "PATCH",
1793
+ headers: { "Content-Type": "application/json" },
1794
+ body: JSON.stringify(body)
1795
+ });
1796
+ return res.json();
1797
+ },
1798
+ async delete(trunkId) {
1799
+ await doFetch(`${base}/sip/trunks/${trunkId}`, { method: "DELETE" });
1800
+ }
1801
+ };
1802
+ }
1803
+
1612
1804
  // src/api/tools.ts
1613
1805
  var IDEMPOTENCY_HEADER = "Idempotency-Key";
1614
1806
  var generateIdempotencyKey = (explicit) => {
@@ -2370,12 +2562,14 @@ function createClient(initialCfg) {
2370
2562
  ...catalogsApi,
2371
2563
  templates: catalogTemplatesApi
2372
2564
  },
2565
+ documents: createDocumentsApi(runtimeCfg),
2373
2566
  campaigns: createCampaignsApi(runtimeCfg),
2374
2567
  voices: voicesApi,
2375
2568
  apiKeys: apiKeysApi,
2376
2569
  billing: createBillingApi(runtimeCfg),
2377
2570
  calls: callsApi,
2378
2571
  usage: createUsageApi(runtimeCfg),
2572
+ sip: createSipTrunksApi(runtimeCfg),
2379
2573
  webhooks: webhooksApi
2380
2574
  };
2381
2575
  return {
@@ -2465,7 +2659,9 @@ function createClient(initialCfg) {
2465
2659
  createCatalogTemplatesApi,
2466
2660
  createCatalogsApi,
2467
2661
  createClient,
2662
+ createDocumentsApi,
2468
2663
  createHttp,
2664
+ createSipTrunksApi,
2469
2665
  createToolsApi,
2470
2666
  createUsageApi,
2471
2667
  createVoicesApi,