@amigo-ai/platform-sdk 0.4.1 → 0.4.2

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.
Files changed (54) hide show
  1. package/README.md +87 -0
  2. package/api.md +354 -0
  3. package/dist/core/errors.js +26 -4
  4. package/dist/core/errors.js.map +1 -1
  5. package/dist/core/openapi-client.js +108 -6
  6. package/dist/core/openapi-client.js.map +1 -1
  7. package/dist/core/retry.js +5 -2
  8. package/dist/core/retry.js.map +1 -1
  9. package/dist/core/utils.js +48 -2
  10. package/dist/core/utils.js.map +1 -1
  11. package/dist/index.cjs +258 -38
  12. package/dist/index.cjs.map +4 -4
  13. package/dist/index.js +50 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.mjs +258 -38
  16. package/dist/index.mjs.map +4 -4
  17. package/dist/types/core/errors.d.ts +6 -0
  18. package/dist/types/core/errors.d.ts.map +1 -1
  19. package/dist/types/core/openapi-client.d.ts +24 -1
  20. package/dist/types/core/openapi-client.d.ts.map +1 -1
  21. package/dist/types/core/retry.d.ts +1 -1
  22. package/dist/types/core/retry.d.ts.map +1 -1
  23. package/dist/types/core/utils.d.ts +27 -1
  24. package/dist/types/core/utils.d.ts.map +1 -1
  25. package/dist/types/index.d.ts +40 -2
  26. package/dist/types/index.d.ts.map +1 -1
  27. package/dist/types/resources/actions.d.ts +5 -5
  28. package/dist/types/resources/agents.d.ts +7 -7
  29. package/dist/types/resources/analytics.d.ts +11 -11
  30. package/dist/types/resources/api-keys.d.ts +4 -4
  31. package/dist/types/resources/audit.d.ts +6 -6
  32. package/dist/types/resources/billing.d.ts +6 -6
  33. package/dist/types/resources/calls.d.ts +6 -6
  34. package/dist/types/resources/compliance.d.ts +3 -3
  35. package/dist/types/resources/context-graphs.d.ts +7 -7
  36. package/dist/types/resources/data-sources.d.ts +6 -6
  37. package/dist/types/resources/functions.d.ts +6 -6
  38. package/dist/types/resources/integrations.d.ts +6 -6
  39. package/dist/types/resources/memory.d.ts +3 -3
  40. package/dist/types/resources/operators.d.ts +18 -18
  41. package/dist/types/resources/personas.d.ts +4 -4
  42. package/dist/types/resources/phone-numbers.d.ts +5 -5
  43. package/dist/types/resources/recordings.d.ts +2 -2
  44. package/dist/types/resources/review-queue.d.ts +17 -17
  45. package/dist/types/resources/safety.d.ts +5 -5
  46. package/dist/types/resources/services.d.ts +4 -4
  47. package/dist/types/resources/settings.d.ts +14 -14
  48. package/dist/types/resources/simulations.d.ts +6 -6
  49. package/dist/types/resources/skills.d.ts +5 -5
  50. package/dist/types/resources/triggers.d.ts +8 -8
  51. package/dist/types/resources/webhook-destinations.d.ts +6 -6
  52. package/dist/types/resources/workspaces.d.ts +5 -5
  53. package/dist/types/resources/world.d.ts +18 -18
  54. package/package.json +2 -1
package/dist/index.cjs CHANGED
@@ -42,6 +42,7 @@ __export(index_exports, {
42
42
  ParseError: () => ParseError,
43
43
  PermissionError: () => PermissionError,
44
44
  RateLimitError: () => RateLimitError,
45
+ RequestTimeoutError: () => RequestTimeoutError,
45
46
  ServerError: () => ServerError,
46
47
  ServiceUnavailableError: () => ServiceUnavailableError,
47
48
  ValidationError: () => ValidationError,
@@ -49,17 +50,20 @@ __export(index_exports, {
49
50
  actionId: () => actionId,
50
51
  agentId: () => agentId,
51
52
  apiKeyId: () => apiKeyId,
53
+ buildLastResponse: () => buildLastResponse,
52
54
  callId: () => callId,
53
55
  contextGraphId: () => contextGraphId,
54
56
  dataSourceId: () => dataSourceId,
55
57
  entityId: () => entityId,
56
58
  eventId: () => eventId,
59
+ extractRequestId: () => extractRequestId,
57
60
  functionId: () => functionId,
58
61
  integrationId: () => integrationId,
59
62
  isAmigoError: () => isAmigoError,
60
63
  isAuthenticationError: () => isAuthenticationError,
61
64
  isNotFoundError: () => isNotFoundError,
62
65
  isRateLimitError: () => isRateLimitError,
66
+ isRequestTimeoutError: () => isRequestTimeoutError,
63
67
  paginate: () => paginate,
64
68
  parseRateLimitHeaders: () => parseRateLimitHeaders,
65
69
  parseWebhookEvent: () => parseWebhookEvent,
@@ -191,6 +195,13 @@ var NetworkError = class extends AmigoError {
191
195
  }
192
196
  }
193
197
  };
198
+ var RequestTimeoutError = class extends NetworkError {
199
+ timeoutMs;
200
+ constructor(message, timeoutMs, cause) {
201
+ super(message, cause);
202
+ this.timeoutMs = timeoutMs;
203
+ }
204
+ };
194
205
  var ParseError = class extends AmigoError {
195
206
  body;
196
207
  constructor(message, body) {
@@ -264,6 +275,9 @@ function isRateLimitError(err) {
264
275
  function isAuthenticationError(err) {
265
276
  return err instanceof AuthenticationError;
266
277
  }
278
+ function isRequestTimeoutError(err) {
279
+ return err instanceof RequestTimeoutError;
280
+ }
267
281
 
268
282
  // src/core/openapi-client.ts
269
283
  var import_openapi_fetch = __toESM(require("openapi-fetch"), 1);
@@ -286,6 +300,20 @@ function createAuthMiddleware(config) {
286
300
  };
287
301
  }
288
302
 
303
+ // src/core/rate-limit.ts
304
+ function parseRateLimitHeaders(headers) {
305
+ const limit = headers.get("x-ratelimit-limit");
306
+ const remaining = headers.get("x-ratelimit-remaining");
307
+ const reset = headers.get("x-ratelimit-reset");
308
+ const retryAfter = headers.get("retry-after");
309
+ return {
310
+ limit: limit ? parseInt(limit, 10) : null,
311
+ remaining: remaining ? parseInt(remaining, 10) : null,
312
+ reset: reset ? new Date(parseInt(reset, 10) * 1e3) : null,
313
+ retryAfter: retryAfter ? parseInt(retryAfter, 10) : null
314
+ };
315
+ }
316
+
289
317
  // src/core/retry.ts
290
318
  var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
291
319
  var POST_RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429]);
@@ -319,28 +347,106 @@ function parseRetryAfterHeader(header) {
319
347
  }
320
348
  return void 0;
321
349
  }
322
- function resolveRetryOptions(opts) {
350
+ function resolveRetryOptions(opts, maxRetries) {
351
+ const maxAttempts = typeof maxRetries === "number" && Number.isFinite(maxRetries) ? Math.max(1, Math.floor(maxRetries) + 1) : opts?.maxAttempts ?? 3;
323
352
  return {
324
- maxAttempts: opts?.maxAttempts ?? 3,
353
+ maxAttempts,
325
354
  baseDelayMs: opts?.baseDelayMs ?? 250,
326
355
  maxDelayMs: opts?.maxDelayMs ?? 3e4
327
356
  };
328
357
  }
329
358
 
359
+ // src/core/utils.ts
360
+ function extractRequestId(response) {
361
+ return response.headers.get("x-request-id");
362
+ }
363
+ function buildLastResponse(response) {
364
+ return {
365
+ requestId: extractRequestId(response),
366
+ statusCode: response.status,
367
+ headers: response.headers,
368
+ rateLimit: parseRateLimitHeaders(response.headers)
369
+ };
370
+ }
371
+ function extractData(result) {
372
+ if (result.data !== void 0) {
373
+ return attachResponseMetadata(result.data, result.response);
374
+ }
375
+ throw new ParseError(
376
+ "Unexpected empty response from API",
377
+ result.error !== void 0 ? JSON.stringify(result.error) : void 0
378
+ );
379
+ }
380
+ function withResponse(result) {
381
+ const data = extractData(result);
382
+ const lastResponse = buildLastResponse(result.response);
383
+ return {
384
+ data,
385
+ response: result.response,
386
+ requestId: lastResponse.requestId,
387
+ rateLimit: lastResponse.rateLimit
388
+ };
389
+ }
390
+ async function* paginate(fetcher) {
391
+ let token = void 0;
392
+ while (true) {
393
+ const page = await fetcher(token);
394
+ for (const item of page.items) {
395
+ yield item;
396
+ }
397
+ if (!page.has_more || page.continuation_token === null) break;
398
+ token = page.continuation_token;
399
+ }
400
+ }
401
+ function attachResponseMetadata(data, response) {
402
+ if (!response || typeof data !== "object" || data === null) {
403
+ return data;
404
+ }
405
+ const target = data;
406
+ const lastResponse = buildLastResponse(response);
407
+ defineHiddenMetadata(target, "_request_id", lastResponse.requestId);
408
+ defineHiddenMetadata(target, "lastResponse", lastResponse);
409
+ return target;
410
+ }
411
+ function defineHiddenMetadata(target, key, value) {
412
+ try {
413
+ Object.defineProperty(target, key, {
414
+ value,
415
+ enumerable: false,
416
+ configurable: true,
417
+ writable: false
418
+ });
419
+ } catch {
420
+ }
421
+ }
422
+
330
423
  // src/core/openapi-client.ts
331
424
  var createClient = typeof import_openapi_fetch.default === "function" ? import_openapi_fetch.default : import_openapi_fetch.default.default;
332
425
  function createPlatformClient(config) {
333
- const retryOpts = resolveRetryOptions(config.retry);
334
426
  const baseFetch = config.fetch ?? globalThis.fetch;
335
427
  const retryingFetch = async (input, init) => {
336
- const method = (init?.method ?? "GET").toUpperCase();
337
- const signal = init?.signal;
428
+ const baseRequest = input instanceof Request ? input : new Request(input, init);
429
+ const method = baseRequest.method.toUpperCase();
430
+ const requestRetry = getRequestOption(baseRequest, "retry");
431
+ const requestMaxRetries = getRequestOption(baseRequest, "maxRetries");
432
+ const retryOpts = resolveRetryOptions(
433
+ requestRetry ?? config.retry,
434
+ requestMaxRetries ?? config.maxRetries
435
+ );
436
+ const timeoutMs = getRequestOption(baseRequest, "timeout") ?? config.timeout;
338
437
  const isIdempotent = method === "GET" || method === "HEAD" || method === "OPTIONS";
339
438
  for (let attempt = 0; attempt < retryOpts.maxAttempts; attempt++) {
340
439
  let response;
341
440
  let error;
441
+ let timedOut = false;
342
442
  try {
343
- response = await baseFetch(input, init);
443
+ const prepared = prepareRequestForAttempt(baseRequest, timeoutMs);
444
+ try {
445
+ response = await baseFetch(prepared.request, init);
446
+ } finally {
447
+ timedOut = prepared.timedOut;
448
+ prepared.cleanup();
449
+ }
344
450
  } catch (err) {
345
451
  error = err;
346
452
  }
@@ -348,6 +454,9 @@ function createPlatformClient(config) {
348
454
  const ctx = { method, attempt, response, options: retryOpts };
349
455
  const attemptsRemain = attempt + 1 < retryOpts.maxAttempts;
350
456
  if (error) {
457
+ if (timedOut) {
458
+ throw new RequestTimeoutError(`Request timed out after ${timeoutMs}ms`, timeoutMs, error);
459
+ }
351
460
  if (isIdempotent && attemptsRemain) {
352
461
  await sleep(computeDelay(attempt, new Response(), retryOpts));
353
462
  continue;
@@ -359,7 +468,7 @@ function createPlatformClient(config) {
359
468
  }
360
469
  if (response && attemptsRemain && shouldRetry(ctx)) {
361
470
  const delay = computeDelay(attempt, response, retryOpts);
362
- if (signal?.aborted) return response;
471
+ if (baseRequest.signal.aborted) return response;
363
472
  await sleep(delay);
364
473
  continue;
365
474
  }
@@ -369,7 +478,8 @@ function createPlatformClient(config) {
369
478
  };
370
479
  const client = createClient({
371
480
  baseUrl: config.baseUrl,
372
- fetch: retryingFetch
481
+ fetch: retryingFetch,
482
+ headers: config.headers
373
483
  });
374
484
  const errorMiddleware = {
375
485
  async onResponse({ response }) {
@@ -380,32 +490,95 @@ function createPlatformClient(config) {
380
490
  }
381
491
  };
382
492
  const authMiddleware = createAuthMiddleware({ apiKey: config.apiKey });
493
+ const hookMiddleware = config.hooks ? {
494
+ async onRequest({ request, schemaPath, id }) {
495
+ await config.hooks?.onRequest?.({ request, schemaPath, id });
496
+ return request;
497
+ },
498
+ async onResponse({ request, response, schemaPath, id }) {
499
+ await config.hooks?.onResponse?.({
500
+ id,
501
+ request,
502
+ response,
503
+ schemaPath,
504
+ requestId: extractRequestId(response),
505
+ rateLimit: parseRateLimitHeaders(response.headers)
506
+ });
507
+ return response;
508
+ },
509
+ async onError({ request, error, schemaPath, id }) {
510
+ await config.hooks?.onError?.({ id, request, error, schemaPath });
511
+ }
512
+ } : void 0;
383
513
  client.use(authMiddleware);
384
514
  client.use(errorMiddleware);
515
+ if (hookMiddleware) {
516
+ client.use(hookMiddleware);
517
+ }
385
518
  return client;
386
519
  }
387
520
  function sleep(ms) {
388
521
  return new Promise((resolve) => setTimeout(resolve, ms));
389
522
  }
390
-
391
- // src/core/utils.ts
392
- function extractData(result) {
393
- if (result.data !== void 0) return result.data;
394
- throw new ParseError(
395
- "Unexpected empty response from API",
396
- result.error !== void 0 ? JSON.stringify(result.error) : void 0
397
- );
523
+ function getRequestOption(request, key) {
524
+ const value = request[key];
525
+ return value;
398
526
  }
399
- async function* paginate(fetcher) {
400
- let token = void 0;
401
- while (true) {
402
- const page = await fetcher(token);
403
- for (const item of page.items) {
404
- yield item;
527
+ function prepareRequestForAttempt(request, timeoutMs) {
528
+ const attemptRequest = request.clone();
529
+ const timeout = createTimeoutSignal(attemptRequest.signal, timeoutMs);
530
+ if (!timeout.signal) {
531
+ return {
532
+ request: attemptRequest,
533
+ timedOut: false,
534
+ cleanup: timeout.cleanup
535
+ };
536
+ }
537
+ return {
538
+ request: new Request(attemptRequest, { signal: timeout.signal }),
539
+ get timedOut() {
540
+ return timeout.didTimeout;
541
+ },
542
+ cleanup: timeout.cleanup
543
+ };
544
+ }
545
+ function createTimeoutSignal(upstream, timeoutMs) {
546
+ if (!timeoutMs || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
547
+ return {
548
+ signal: upstream ?? void 0,
549
+ didTimeout: false,
550
+ cleanup: () => {
551
+ }
552
+ };
553
+ }
554
+ const controller = new AbortController();
555
+ let didTimeout = false;
556
+ const cleanups = [];
557
+ const onAbort = () => controller.abort(upstream?.reason);
558
+ if (upstream) {
559
+ if (upstream.aborted) {
560
+ controller.abort(upstream.reason);
561
+ } else {
562
+ upstream.addEventListener("abort", onAbort, { once: true });
563
+ cleanups.push(() => upstream.removeEventListener("abort", onAbort));
405
564
  }
406
- if (!page.has_more || page.continuation_token === null) break;
407
- token = page.continuation_token;
408
565
  }
566
+ const timer = setTimeout(() => {
567
+ didTimeout = true;
568
+ controller.abort();
569
+ }, timeoutMs);
570
+ cleanups.push(() => clearTimeout(timer));
571
+ return {
572
+ signal: controller.signal,
573
+ get didTimeout() {
574
+ return didTimeout;
575
+ },
576
+ cleanup: () => {
577
+ for (const cleanup of cleanups) {
578
+ cleanup();
579
+ }
580
+ }
581
+ };
409
582
  }
410
583
 
411
584
  // src/resources/base.ts
@@ -2184,20 +2357,6 @@ var simulationSessionId = (id) => id;
2184
2357
  var functionId = (id) => id;
2185
2358
  var dataSourceId = (id) => id;
2186
2359
 
2187
- // src/core/rate-limit.ts
2188
- function parseRateLimitHeaders(headers) {
2189
- const limit = headers.get("x-ratelimit-limit");
2190
- const remaining = headers.get("x-ratelimit-remaining");
2191
- const reset = headers.get("x-ratelimit-reset");
2192
- const retryAfter = headers.get("retry-after");
2193
- return {
2194
- limit: limit ? parseInt(limit, 10) : null,
2195
- remaining: remaining ? parseInt(remaining, 10) : null,
2196
- reset: reset ? new Date(parseInt(reset, 10) * 1e3) : null,
2197
- retryAfter: retryAfter ? parseInt(retryAfter, 10) : null
2198
- };
2199
- }
2200
-
2201
2360
  // src/core/webhooks.ts
2202
2361
  var textEncoder = new TextEncoder();
2203
2362
  var MAX_TIMESTAMP_SKEW_MS = 5 * 60 * 1e3;
@@ -2340,6 +2499,8 @@ function toCryptoBuffer(bytes) {
2340
2499
  // src/index.ts
2341
2500
  var DEFAULT_BASE_URL = "https://api.platform.amigo.ai";
2342
2501
  var AmigoClient = class {
2502
+ workspaceId;
2503
+ baseUrl;
2343
2504
  workspaces;
2344
2505
  apiKeys;
2345
2506
  agents;
@@ -2368,6 +2529,7 @@ var AmigoClient = class {
2368
2529
  safety;
2369
2530
  compliance;
2370
2531
  functions;
2532
+ api;
2371
2533
  constructor(config) {
2372
2534
  if (!config.apiKey || typeof config.apiKey !== "string") {
2373
2535
  throw new ConfigurationError("apiKey is required and must be a non-empty string");
@@ -2380,9 +2542,16 @@ var AmigoClient = class {
2380
2542
  apiKey: config.apiKey,
2381
2543
  baseUrl,
2382
2544
  retry: config.retry,
2545
+ maxRetries: config.maxRetries,
2546
+ timeout: config.timeout,
2547
+ headers: config.headers,
2548
+ hooks: config.hooks,
2383
2549
  fetch: config.fetch
2384
2550
  });
2385
2551
  const ws = config.workspaceId;
2552
+ this.workspaceId = ws;
2553
+ this.baseUrl = baseUrl;
2554
+ this.api = client;
2386
2555
  this.workspaces = new WorkspacesResource(client, ws);
2387
2556
  this.apiKeys = new ApiKeysResource(client, ws);
2388
2557
  this.agents = new AgentsResource(client, ws);
@@ -2411,5 +2580,56 @@ var AmigoClient = class {
2411
2580
  this.compliance = new ComplianceResource(client, ws);
2412
2581
  this.functions = new FunctionsResource(client, ws);
2413
2582
  }
2583
+ async GET(path, init) {
2584
+ return withResponse(
2585
+ await this.api.GET(path, withWorkspaceId(path, init, this.workspaceId))
2586
+ );
2587
+ }
2588
+ async POST(path, init) {
2589
+ return withResponse(
2590
+ await this.api.POST(path, withWorkspaceId(path, init, this.workspaceId))
2591
+ );
2592
+ }
2593
+ async PUT(path, init) {
2594
+ return withResponse(
2595
+ await this.api.PUT(path, withWorkspaceId(path, init, this.workspaceId))
2596
+ );
2597
+ }
2598
+ async PATCH(path, init) {
2599
+ return withResponse(
2600
+ await this.api.PATCH(path, withWorkspaceId(path, init, this.workspaceId))
2601
+ );
2602
+ }
2603
+ async DELETE(path, init) {
2604
+ return withResponse(
2605
+ await this.api.DELETE(path, withWorkspaceId(path, init, this.workspaceId))
2606
+ );
2607
+ }
2608
+ async HEAD(path, init) {
2609
+ return withResponse(
2610
+ await this.api.HEAD(path, withWorkspaceId(path, init, this.workspaceId))
2611
+ );
2612
+ }
2613
+ async OPTIONS(path, init) {
2614
+ return withResponse(
2615
+ await this.api.OPTIONS(path, withWorkspaceId(path, init, this.workspaceId))
2616
+ );
2617
+ }
2414
2618
  };
2619
+ function withWorkspaceId(path, init, workspaceId2) {
2620
+ if (!path.includes("{workspace_id}")) {
2621
+ return init ?? {};
2622
+ }
2623
+ const current = init ?? {};
2624
+ return {
2625
+ ...current,
2626
+ params: {
2627
+ ...current.params ?? {},
2628
+ path: {
2629
+ workspace_id: workspaceId2,
2630
+ ...current.params?.path ?? {}
2631
+ }
2632
+ }
2633
+ };
2634
+ }
2415
2635
  //# sourceMappingURL=index.cjs.map