@amigo-ai/platform-sdk 0.4.1 → 0.4.3

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 (65) hide show
  1. package/README.md +111 -0
  2. package/api.md +347 -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 +164 -28
  6. package/dist/core/openapi-client.js.map +1 -1
  7. package/dist/core/request-options.js +80 -0
  8. package/dist/core/request-options.js.map +1 -0
  9. package/dist/core/retry.js +5 -2
  10. package/dist/core/retry.js.map +1 -1
  11. package/dist/core/utils.js +48 -2
  12. package/dist/core/utils.js.map +1 -1
  13. package/dist/core/webhooks.js +9 -0
  14. package/dist/core/webhooks.js.map +1 -1
  15. package/dist/index.cjs +538 -84
  16. package/dist/index.cjs.map +4 -4
  17. package/dist/index.js +113 -30
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +538 -84
  20. package/dist/index.mjs.map +4 -4
  21. package/dist/resources/base.js +33 -0
  22. package/dist/resources/base.js.map +1 -1
  23. package/dist/types/core/errors.d.ts +6 -0
  24. package/dist/types/core/errors.d.ts.map +1 -1
  25. package/dist/types/core/openapi-client.d.ts +26 -1
  26. package/dist/types/core/openapi-client.d.ts.map +1 -1
  27. package/dist/types/core/request-options.d.ts +66 -0
  28. package/dist/types/core/request-options.d.ts.map +1 -0
  29. package/dist/types/core/retry.d.ts +1 -1
  30. package/dist/types/core/retry.d.ts.map +1 -1
  31. package/dist/types/core/utils.d.ts +27 -1
  32. package/dist/types/core/utils.d.ts.map +1 -1
  33. package/dist/types/core/webhooks.d.ts.map +1 -1
  34. package/dist/types/index.d.ts +31 -2
  35. package/dist/types/index.d.ts.map +1 -1
  36. package/dist/types/resources/actions.d.ts +5 -5
  37. package/dist/types/resources/agents.d.ts +7 -7
  38. package/dist/types/resources/analytics.d.ts +11 -11
  39. package/dist/types/resources/api-keys.d.ts +4 -4
  40. package/dist/types/resources/audit.d.ts +6 -6
  41. package/dist/types/resources/base.d.ts +8 -3
  42. package/dist/types/resources/base.d.ts.map +1 -1
  43. package/dist/types/resources/billing.d.ts +6 -6
  44. package/dist/types/resources/calls.d.ts +6 -6
  45. package/dist/types/resources/compliance.d.ts +3 -3
  46. package/dist/types/resources/context-graphs.d.ts +7 -7
  47. package/dist/types/resources/data-sources.d.ts +6 -6
  48. package/dist/types/resources/functions.d.ts +6 -6
  49. package/dist/types/resources/integrations.d.ts +6 -6
  50. package/dist/types/resources/memory.d.ts +3 -3
  51. package/dist/types/resources/operators.d.ts +18 -18
  52. package/dist/types/resources/personas.d.ts +4 -4
  53. package/dist/types/resources/phone-numbers.d.ts +5 -5
  54. package/dist/types/resources/recordings.d.ts +2 -2
  55. package/dist/types/resources/review-queue.d.ts +17 -17
  56. package/dist/types/resources/safety.d.ts +5 -5
  57. package/dist/types/resources/services.d.ts +4 -4
  58. package/dist/types/resources/settings.d.ts +14 -14
  59. package/dist/types/resources/simulations.d.ts +6 -6
  60. package/dist/types/resources/skills.d.ts +5 -5
  61. package/dist/types/resources/triggers.d.ts +8 -8
  62. package/dist/types/resources/webhook-destinations.d.ts +6 -6
  63. package/dist/types/resources/workspaces.d.ts +5 -5
  64. package/dist/types/resources/world.d.ts +18 -18
  65. package/package.json +6 -2
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,104 @@ 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
+
317
+ // src/core/request-options.ts
318
+ function stripRequestControls(options) {
319
+ if (!options) {
320
+ return void 0;
321
+ }
322
+ const rest = { ...options };
323
+ delete rest.timeout;
324
+ delete rest.maxRetries;
325
+ delete rest.retry;
326
+ return rest;
327
+ }
328
+ function mergeRequestOptions(base, override) {
329
+ if (!base) {
330
+ return override;
331
+ }
332
+ if (!override) {
333
+ return base;
334
+ }
335
+ const mergeableOverride = override;
336
+ return {
337
+ ...base,
338
+ ...override,
339
+ headers: mergeHeaders(base.headers, mergeableOverride.headers),
340
+ signal: mergeableOverride.signal ?? base.signal,
341
+ timeout: mergeableOverride.timeout ?? base.timeout,
342
+ maxRetries: mergeableOverride.maxRetries ?? base.maxRetries,
343
+ retry: mergeableOverride.retry ?? base.retry
344
+ };
345
+ }
346
+ function mergeScopedRequestOptions(base, override) {
347
+ return mergeRequestOptions(base, override) ?? override;
348
+ }
349
+ function mergeHeaders(base, override) {
350
+ if (!base && !override) {
351
+ return void 0;
352
+ }
353
+ const headers = new Headers();
354
+ let hasEntries = false;
355
+ applyHeaders(headers, base, () => {
356
+ hasEntries = true;
357
+ });
358
+ applyHeaders(headers, override, () => {
359
+ hasEntries = true;
360
+ });
361
+ return hasEntries ? headers : void 0;
362
+ }
363
+ function applyHeaders(target, source, onSet) {
364
+ if (!source) {
365
+ return;
366
+ }
367
+ if (source instanceof Headers) {
368
+ source.forEach((value, key) => {
369
+ target.set(key, value);
370
+ onSet();
371
+ });
372
+ return;
373
+ }
374
+ if (Array.isArray(source)) {
375
+ for (const [key, value] of source) {
376
+ if (!key) {
377
+ continue;
378
+ }
379
+ if (value === null || value === void 0) {
380
+ target.delete(key);
381
+ continue;
382
+ }
383
+ target.set(key, String(value));
384
+ onSet();
385
+ }
386
+ return;
387
+ }
388
+ for (const [key, value] of Object.entries(source)) {
389
+ if (value === null || value === void 0) {
390
+ target.delete(key);
391
+ continue;
392
+ }
393
+ target.set(
394
+ key,
395
+ Array.isArray(value) ? value.map((item) => String(item)).join(", ") : String(value)
396
+ );
397
+ onSet();
398
+ }
399
+ }
400
+
289
401
  // src/core/retry.ts
290
402
  var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
291
403
  var POST_RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429]);
@@ -319,28 +431,177 @@ function parseRetryAfterHeader(header) {
319
431
  }
320
432
  return void 0;
321
433
  }
322
- function resolveRetryOptions(opts) {
434
+ function resolveRetryOptions(opts, maxRetries) {
435
+ const maxAttempts = typeof maxRetries === "number" && Number.isFinite(maxRetries) ? Math.max(1, Math.floor(maxRetries) + 1) : opts?.maxAttempts ?? 3;
323
436
  return {
324
- maxAttempts: opts?.maxAttempts ?? 3,
437
+ maxAttempts,
325
438
  baseDelayMs: opts?.baseDelayMs ?? 250,
326
439
  maxDelayMs: opts?.maxDelayMs ?? 3e4
327
440
  };
328
441
  }
329
442
 
443
+ // src/core/utils.ts
444
+ function extractRequestId(response) {
445
+ return response.headers.get("x-request-id");
446
+ }
447
+ function buildLastResponse(response) {
448
+ return {
449
+ requestId: extractRequestId(response),
450
+ statusCode: response.status,
451
+ headers: response.headers,
452
+ rateLimit: parseRateLimitHeaders(response.headers)
453
+ };
454
+ }
455
+ function extractData(result) {
456
+ if (result.data !== void 0) {
457
+ return attachResponseMetadata(result.data, result.response);
458
+ }
459
+ throw new ParseError(
460
+ "Unexpected empty response from API",
461
+ result.error !== void 0 ? JSON.stringify(result.error) : void 0
462
+ );
463
+ }
464
+ function withResponse(result) {
465
+ const data = extractData(result);
466
+ const lastResponse = buildLastResponse(result.response);
467
+ return {
468
+ data,
469
+ response: result.response,
470
+ requestId: lastResponse.requestId,
471
+ rateLimit: lastResponse.rateLimit
472
+ };
473
+ }
474
+ async function* paginate(fetcher) {
475
+ let token = void 0;
476
+ while (true) {
477
+ const page = await fetcher(token);
478
+ for (const item of page.items) {
479
+ yield item;
480
+ }
481
+ if (!page.has_more || page.continuation_token === null) break;
482
+ token = page.continuation_token;
483
+ }
484
+ }
485
+ function attachResponseMetadata(data, response) {
486
+ if (!response || typeof data !== "object" || data === null) {
487
+ return data;
488
+ }
489
+ const target = data;
490
+ const lastResponse = buildLastResponse(response);
491
+ defineHiddenMetadata(target, "_request_id", lastResponse.requestId);
492
+ defineHiddenMetadata(target, "lastResponse", lastResponse);
493
+ return target;
494
+ }
495
+ function defineHiddenMetadata(target, key, value) {
496
+ try {
497
+ Object.defineProperty(target, key, {
498
+ value,
499
+ enumerable: false,
500
+ configurable: true,
501
+ writable: false
502
+ });
503
+ } catch {
504
+ }
505
+ }
506
+
330
507
  // src/core/openapi-client.ts
331
508
  var createClient = typeof import_openapi_fetch.default === "function" ? import_openapi_fetch.default : import_openapi_fetch.default.default;
509
+ var platformClientContext = /* @__PURE__ */ new WeakMap();
332
510
  function createPlatformClient(config) {
333
- const retryOpts = resolveRetryOptions(config.retry);
334
- const baseFetch = config.fetch ?? globalThis.fetch;
335
- const retryingFetch = async (input, init) => {
336
- const method = (init?.method ?? "GET").toUpperCase();
337
- const signal = init?.signal;
511
+ const transport = toRequestTransport(config.fetch ?? globalThis.fetch);
512
+ const defaults = {
513
+ retry: config.retry,
514
+ maxRetries: config.maxRetries,
515
+ timeout: config.timeout
516
+ };
517
+ const client = createClient({
518
+ baseUrl: config.baseUrl,
519
+ fetch: createRetryingFetch(transport, defaults),
520
+ headers: config.headers
521
+ });
522
+ platformClientContext.set(client, { transport, defaults });
523
+ const errorMiddleware = {
524
+ async onResponse({ response }) {
525
+ if (!response.ok) {
526
+ throw await createApiError(response);
527
+ }
528
+ return response;
529
+ }
530
+ };
531
+ const authMiddleware = createAuthMiddleware({ apiKey: config.apiKey });
532
+ const hookMiddleware = config.hooks ? {
533
+ async onRequest({ request, schemaPath, id }) {
534
+ await config.hooks?.onRequest?.({ request, schemaPath, id });
535
+ return request;
536
+ },
537
+ async onResponse({ request, response, schemaPath, id }) {
538
+ await config.hooks?.onResponse?.({
539
+ id,
540
+ request,
541
+ response,
542
+ schemaPath,
543
+ requestId: extractRequestId(response),
544
+ rateLimit: parseRateLimitHeaders(response.headers)
545
+ });
546
+ return response;
547
+ },
548
+ async onError({ request, error, schemaPath, id }) {
549
+ await config.hooks?.onError?.({ id, request, error, schemaPath });
550
+ }
551
+ } : void 0;
552
+ client.use(authMiddleware);
553
+ client.use(errorMiddleware);
554
+ if (hookMiddleware) {
555
+ client.use(hookMiddleware);
556
+ }
557
+ return client;
558
+ }
559
+ function applyPlatformRequestOptions(client, init) {
560
+ if (!init) {
561
+ return void 0;
562
+ }
563
+ const context = platformClientContext.get(client);
564
+ const stripped = stripRequestControls(init);
565
+ if (!context) {
566
+ return stripped;
567
+ }
568
+ const overrideFetch = stripped?.fetch;
569
+ const hasControlOverride = overrideFetch !== void 0 || init.timeout !== void 0 || init.maxRetries !== void 0 || init.retry !== void 0;
570
+ if (!hasControlOverride) {
571
+ return stripped;
572
+ }
573
+ const transport = toRequestTransport(
574
+ overrideFetch ?? context.transport
575
+ );
576
+ const fetch = createRetryingFetch(transport, {
577
+ timeout: init.timeout ?? context.defaults.timeout,
578
+ maxRetries: init.maxRetries ?? context.defaults.maxRetries,
579
+ retry: init.retry ?? context.defaults.retry
580
+ });
581
+ return {
582
+ ...stripped,
583
+ fetch
584
+ };
585
+ }
586
+ function createRetryingFetch(transport, defaults) {
587
+ return async (input, init) => {
588
+ const baseRequest = input instanceof Request ? input : new Request(input, init);
589
+ const method = baseRequest.method.toUpperCase();
590
+ const retryOpts = resolveRetryOptions(defaults.retry, defaults.maxRetries);
591
+ const timeoutMs = defaults.timeout;
338
592
  const isIdempotent = method === "GET" || method === "HEAD" || method === "OPTIONS";
339
593
  for (let attempt = 0; attempt < retryOpts.maxAttempts; attempt++) {
340
594
  let response;
341
595
  let error;
596
+ let timedOut = false;
342
597
  try {
343
- response = await baseFetch(input, init);
598
+ const prepared = prepareRequestForAttempt(baseRequest, timeoutMs);
599
+ try {
600
+ response = await transport(prepared.request);
601
+ } finally {
602
+ timedOut = prepared.timedOut;
603
+ prepared.cleanup();
604
+ }
344
605
  } catch (err) {
345
606
  error = err;
346
607
  }
@@ -348,6 +609,9 @@ function createPlatformClient(config) {
348
609
  const ctx = { method, attempt, response, options: retryOpts };
349
610
  const attemptsRemain = attempt + 1 < retryOpts.maxAttempts;
350
611
  if (error) {
612
+ if (timedOut) {
613
+ throw new RequestTimeoutError(`Request timed out after ${timeoutMs}ms`, timeoutMs, error);
614
+ }
351
615
  if (isIdempotent && attemptsRemain) {
352
616
  await sleep(computeDelay(attempt, new Response(), retryOpts));
353
617
  continue;
@@ -359,7 +623,7 @@ function createPlatformClient(config) {
359
623
  }
360
624
  if (response && attemptsRemain && shouldRetry(ctx)) {
361
625
  const delay = computeDelay(attempt, response, retryOpts);
362
- if (signal?.aborted) return response;
626
+ if (baseRequest.signal.aborted) return response;
363
627
  await sleep(delay);
364
628
  continue;
365
629
  }
@@ -367,54 +631,163 @@ function createPlatformClient(config) {
367
631
  }
368
632
  throw new NetworkError("Retry loop exhausted");
369
633
  };
370
- const client = createClient({
371
- baseUrl: config.baseUrl,
372
- fetch: retryingFetch
373
- });
374
- const errorMiddleware = {
375
- async onResponse({ response }) {
376
- if (!response.ok) {
377
- throw await createApiError(response);
378
- }
379
- return response;
380
- }
381
- };
382
- const authMiddleware = createAuthMiddleware({ apiKey: config.apiKey });
383
- client.use(authMiddleware);
384
- client.use(errorMiddleware);
385
- return client;
386
634
  }
387
635
  function sleep(ms) {
388
636
  return new Promise((resolve) => setTimeout(resolve, ms));
389
637
  }
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
- );
638
+ function toRequestTransport(fetcher) {
639
+ return async (input) => fetcher(input);
398
640
  }
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;
641
+ function prepareRequestForAttempt(request, timeoutMs) {
642
+ const attemptRequest = request.clone();
643
+ const timeout = createTimeoutSignal(attemptRequest.signal, timeoutMs);
644
+ if (!timeout.signal) {
645
+ return {
646
+ request: attemptRequest,
647
+ timedOut: false,
648
+ cleanup: timeout.cleanup
649
+ };
650
+ }
651
+ return {
652
+ request: new Request(attemptRequest, { signal: timeout.signal }),
653
+ get timedOut() {
654
+ return timeout.didTimeout;
655
+ },
656
+ cleanup: timeout.cleanup
657
+ };
658
+ }
659
+ function createTimeoutSignal(upstream, timeoutMs) {
660
+ if (!timeoutMs || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
661
+ return {
662
+ signal: upstream ?? void 0,
663
+ didTimeout: false,
664
+ cleanup: () => {
665
+ }
666
+ };
667
+ }
668
+ const controller = new AbortController();
669
+ let didTimeout = false;
670
+ const cleanups = [];
671
+ const onAbort = () => controller.abort(upstream?.reason);
672
+ if (upstream) {
673
+ if (upstream.aborted) {
674
+ controller.abort(upstream.reason);
675
+ } else {
676
+ upstream.addEventListener("abort", onAbort, { once: true });
677
+ cleanups.push(() => upstream.removeEventListener("abort", onAbort));
405
678
  }
406
- if (!page.has_more || page.continuation_token === null) break;
407
- token = page.continuation_token;
408
679
  }
680
+ const timer = setTimeout(() => {
681
+ didTimeout = true;
682
+ controller.abort();
683
+ }, timeoutMs);
684
+ cleanups.push(() => clearTimeout(timer));
685
+ return {
686
+ signal: controller.signal,
687
+ get didTimeout() {
688
+ return didTimeout;
689
+ },
690
+ cleanup: () => {
691
+ for (const cleanup of cleanups) {
692
+ cleanup();
693
+ }
694
+ }
695
+ };
409
696
  }
410
697
 
411
698
  // src/resources/base.ts
699
+ var scopedClientState = /* @__PURE__ */ new WeakMap();
412
700
  var WorkspaceScopedResource = class {
413
701
  constructor(client, workspaceId2) {
414
702
  this.client = client;
415
703
  this.workspaceId = workspaceId2;
416
704
  }
705
+ withOptions(options) {
706
+ const ResourceCtor = this.constructor;
707
+ return new ResourceCtor(scopePlatformClient(this.client, options), this.workspaceId);
708
+ }
417
709
  };
710
+ function scopePlatformClient(client, options) {
711
+ const { baseClient, options: existingOptions } = resolveScopedPlatformClient(client);
712
+ const mergedOptions = mergeScopedRequestOptions(existingOptions, options);
713
+ const scopedClient = {
714
+ request: (method, path, init) => baseClient.request(
715
+ method,
716
+ path,
717
+ applyPlatformRequestOptions(
718
+ baseClient,
719
+ mergeRequestOptions(mergedOptions, init)
720
+ )
721
+ ),
722
+ GET: (path, init) => baseClient.GET(
723
+ path,
724
+ applyPlatformRequestOptions(
725
+ baseClient,
726
+ mergeRequestOptions(mergedOptions, init)
727
+ )
728
+ ),
729
+ PUT: (path, init) => baseClient.PUT(
730
+ path,
731
+ applyPlatformRequestOptions(
732
+ baseClient,
733
+ mergeRequestOptions(mergedOptions, init)
734
+ )
735
+ ),
736
+ POST: (path, init) => baseClient.POST(
737
+ path,
738
+ applyPlatformRequestOptions(
739
+ baseClient,
740
+ mergeRequestOptions(mergedOptions, init)
741
+ )
742
+ ),
743
+ DELETE: (path, init) => baseClient.DELETE(
744
+ path,
745
+ applyPlatformRequestOptions(
746
+ baseClient,
747
+ mergeRequestOptions(mergedOptions, init)
748
+ )
749
+ ),
750
+ OPTIONS: (path, init) => baseClient.OPTIONS(
751
+ path,
752
+ applyPlatformRequestOptions(
753
+ baseClient,
754
+ mergeRequestOptions(mergedOptions, init)
755
+ )
756
+ ),
757
+ HEAD: (path, init) => baseClient.HEAD(
758
+ path,
759
+ applyPlatformRequestOptions(
760
+ baseClient,
761
+ mergeRequestOptions(mergedOptions, init)
762
+ )
763
+ ),
764
+ PATCH: (path, init) => baseClient.PATCH(
765
+ path,
766
+ applyPlatformRequestOptions(
767
+ baseClient,
768
+ mergeRequestOptions(mergedOptions, init)
769
+ )
770
+ ),
771
+ TRACE: (path, init) => baseClient.TRACE(
772
+ path,
773
+ applyPlatformRequestOptions(
774
+ baseClient,
775
+ mergeRequestOptions(mergedOptions, init)
776
+ )
777
+ ),
778
+ use: (...middleware) => baseClient.use(...middleware),
779
+ eject: (...middleware) => baseClient.eject(...middleware)
780
+ };
781
+ scopedClientState.set(scopedClient, { baseClient, options: mergedOptions });
782
+ return scopedClient;
783
+ }
784
+ function resolveScopedPlatformClient(client) {
785
+ const existing = scopedClientState.get(client);
786
+ return {
787
+ baseClient: existing?.baseClient ?? client,
788
+ options: existing?.options
789
+ };
790
+ }
418
791
 
419
792
  // src/resources/workspaces.ts
420
793
  var WorkspacesResource = class extends WorkspaceScopedResource {
@@ -2184,23 +2557,10 @@ var simulationSessionId = (id) => id;
2184
2557
  var functionId = (id) => id;
2185
2558
  var dataSourceId = (id) => id;
2186
2559
 
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
2560
  // src/core/webhooks.ts
2202
2561
  var textEncoder = new TextEncoder();
2203
2562
  var MAX_TIMESTAMP_SKEW_MS = 5 * 60 * 1e3;
2563
+ var webCryptoPromise;
2204
2564
  var WebhookVerificationError = class extends Error {
2205
2565
  constructor(message) {
2206
2566
  super(message);
@@ -2288,6 +2648,7 @@ function toUint8Array(payload) {
2288
2648
  return new Uint8Array(payload);
2289
2649
  }
2290
2650
  async function signWebhookPayload(payload, secret, timestamp) {
2651
+ const crypto = await resolveWebCrypto();
2291
2652
  const key = await crypto.subtle.importKey(
2292
2653
  "raw",
2293
2654
  textEncoder.encode(secret),
@@ -2299,6 +2660,13 @@ async function signWebhookPayload(payload, secret, timestamp) {
2299
2660
  const mac = await crypto.subtle.sign("HMAC", key, toCryptoBuffer(message));
2300
2661
  return new Uint8Array(mac);
2301
2662
  }
2663
+ async function resolveWebCrypto() {
2664
+ if (globalThis.crypto?.subtle) {
2665
+ return globalThis.crypto;
2666
+ }
2667
+ webCryptoPromise ??= import("node:crypto").then(({ webcrypto }) => webcrypto);
2668
+ return await webCryptoPromise;
2669
+ }
2302
2670
  function normalizeSignature(signature) {
2303
2671
  const normalized = signature.startsWith("sha256=") ? signature.slice(7) : signature;
2304
2672
  if (!/^[a-fA-F0-9]+$/.test(normalized) || normalized.length % 2 !== 0) {
@@ -2339,7 +2707,9 @@ function toCryptoBuffer(bytes) {
2339
2707
 
2340
2708
  // src/index.ts
2341
2709
  var DEFAULT_BASE_URL = "https://api.platform.amigo.ai";
2342
- var AmigoClient = class {
2710
+ var AmigoClient = class _AmigoClient {
2711
+ workspaceId;
2712
+ baseUrl;
2343
2713
  workspaces;
2344
2714
  apiKeys;
2345
2715
  agents;
@@ -2368,6 +2738,7 @@ var AmigoClient = class {
2368
2738
  safety;
2369
2739
  compliance;
2370
2740
  functions;
2741
+ api;
2371
2742
  constructor(config) {
2372
2743
  if (!config.apiKey || typeof config.apiKey !== "string") {
2373
2744
  throw new ConfigurationError("apiKey is required and must be a non-empty string");
@@ -2380,36 +2751,119 @@ var AmigoClient = class {
2380
2751
  apiKey: config.apiKey,
2381
2752
  baseUrl,
2382
2753
  retry: config.retry,
2754
+ maxRetries: config.maxRetries,
2755
+ timeout: config.timeout,
2756
+ headers: config.headers,
2757
+ hooks: config.hooks,
2383
2758
  fetch: config.fetch
2384
2759
  });
2385
- const ws = config.workspaceId;
2386
- this.workspaces = new WorkspacesResource(client, ws);
2387
- this.apiKeys = new ApiKeysResource(client, ws);
2388
- this.agents = new AgentsResource(client, ws);
2389
- this.skills = new SkillsResource(client, ws);
2390
- this.actions = new ActionsResource(client, ws);
2391
- this.operators = new OperatorsResource(client, ws);
2392
- this.triggers = new TriggersResource(client, ws);
2393
- this.services = new ServicesResource(client, ws);
2394
- this.contextGraphs = new ContextGraphsResource(client, ws);
2395
- this.dataSources = new DataSourcesResource(client, ws);
2396
- this.world = new WorldResource(client, ws);
2397
- this.calls = new CallsResource(client, ws);
2398
- this.phoneNumbers = new PhoneNumbersResource(client, ws);
2399
- this.integrations = new IntegrationsResource(client, ws);
2400
- this.analytics = new AnalyticsResource(client, ws);
2401
- this.simulations = new SimulationsResource(client, ws);
2402
- this.settings = new SettingsResource(client, ws);
2403
- this.billing = new BillingResource(client, ws);
2404
- this.memory = new MemoryResource(client, ws);
2405
- this.personas = new PersonasResource(client, ws);
2406
- this.reviewQueue = new ReviewQueueResource(client, ws);
2407
- this.recordings = new RecordingsResource(client, ws);
2408
- this.audit = new AuditResource(client, ws);
2409
- this.webhookDestinations = new WebhookDestinationsResource(client, ws);
2410
- this.safety = new SafetyResource(client, ws);
2411
- this.compliance = new ComplianceResource(client, ws);
2412
- this.functions = new FunctionsResource(client, ws);
2760
+ _AmigoClient.hydrate(this, client, config.workspaceId, baseUrl);
2761
+ }
2762
+ withOptions(options) {
2763
+ return _AmigoClient.fromPlatformClient(
2764
+ scopePlatformClient(this.api, options),
2765
+ this.workspaceId,
2766
+ this.baseUrl
2767
+ );
2768
+ }
2769
+ async GET(path, ...[init]) {
2770
+ return withResponse(await this.resolveApiRequest(path, "GET", init));
2771
+ }
2772
+ async POST(path, ...[init]) {
2773
+ return withResponse(await this.resolveApiRequest(path, "POST", init));
2774
+ }
2775
+ async PUT(path, ...[init]) {
2776
+ return withResponse(await this.resolveApiRequest(path, "PUT", init));
2777
+ }
2778
+ async PATCH(path, ...[init]) {
2779
+ return withResponse(await this.resolveApiRequest(path, "PATCH", init));
2780
+ }
2781
+ async DELETE(path, ...[init]) {
2782
+ return withResponse(await this.resolveApiRequest(path, "DELETE", init));
2783
+ }
2784
+ async HEAD(path, ...[init]) {
2785
+ return withResponse(await this.resolveApiRequest(path, "HEAD", init));
2786
+ }
2787
+ async OPTIONS(path, ...[init]) {
2788
+ return withResponse(await this.resolveApiRequest(path, "OPTIONS", init));
2789
+ }
2790
+ static fromPlatformClient(client, workspaceId2, baseUrl) {
2791
+ const instance = Object.create(_AmigoClient.prototype);
2792
+ _AmigoClient.hydrate(instance, client, workspaceId2, baseUrl);
2793
+ return instance;
2794
+ }
2795
+ static hydrate(target, client, workspaceId2, baseUrl) {
2796
+ const mutable = target;
2797
+ mutable.workspaceId = workspaceId2;
2798
+ mutable.baseUrl = baseUrl;
2799
+ target.api = client;
2800
+ mutable.workspaces = new WorkspacesResource(client, workspaceId2);
2801
+ mutable.apiKeys = new ApiKeysResource(client, workspaceId2);
2802
+ mutable.agents = new AgentsResource(client, workspaceId2);
2803
+ mutable.skills = new SkillsResource(client, workspaceId2);
2804
+ mutable.actions = new ActionsResource(client, workspaceId2);
2805
+ mutable.operators = new OperatorsResource(client, workspaceId2);
2806
+ mutable.triggers = new TriggersResource(client, workspaceId2);
2807
+ mutable.services = new ServicesResource(client, workspaceId2);
2808
+ mutable.contextGraphs = new ContextGraphsResource(client, workspaceId2);
2809
+ mutable.dataSources = new DataSourcesResource(client, workspaceId2);
2810
+ mutable.world = new WorldResource(client, workspaceId2);
2811
+ mutable.calls = new CallsResource(client, workspaceId2);
2812
+ mutable.phoneNumbers = new PhoneNumbersResource(client, workspaceId2);
2813
+ mutable.integrations = new IntegrationsResource(client, workspaceId2);
2814
+ mutable.analytics = new AnalyticsResource(client, workspaceId2);
2815
+ mutable.simulations = new SimulationsResource(client, workspaceId2);
2816
+ mutable.settings = new SettingsResource(client, workspaceId2);
2817
+ mutable.billing = new BillingResource(client, workspaceId2);
2818
+ mutable.memory = new MemoryResource(client, workspaceId2);
2819
+ mutable.personas = new PersonasResource(client, workspaceId2);
2820
+ mutable.reviewQueue = new ReviewQueueResource(client, workspaceId2);
2821
+ mutable.recordings = new RecordingsResource(client, workspaceId2);
2822
+ mutable.audit = new AuditResource(client, workspaceId2);
2823
+ mutable.webhookDestinations = new WebhookDestinationsResource(client, workspaceId2);
2824
+ mutable.safety = new SafetyResource(client, workspaceId2);
2825
+ mutable.compliance = new ComplianceResource(client, workspaceId2);
2826
+ mutable.functions = new FunctionsResource(client, workspaceId2);
2827
+ }
2828
+ async resolveApiRequest(path, method, init) {
2829
+ const { baseClient, options } = resolveScopedPlatformClient(this.api);
2830
+ const mergedInit = mergeRequestOptions(options, withWorkspaceId(path, init, this.workspaceId));
2831
+ const requestInit = applyPlatformRequestOptions(
2832
+ baseClient,
2833
+ mergedInit
2834
+ );
2835
+ switch (method) {
2836
+ case "GET":
2837
+ return await baseClient.GET(path, requestInit);
2838
+ case "POST":
2839
+ return await baseClient.POST(path, requestInit);
2840
+ case "PUT":
2841
+ return await baseClient.PUT(path, requestInit);
2842
+ case "PATCH":
2843
+ return await baseClient.PATCH(path, requestInit);
2844
+ case "DELETE":
2845
+ return await baseClient.DELETE(path, requestInit);
2846
+ case "HEAD":
2847
+ return await baseClient.HEAD(path, requestInit);
2848
+ case "OPTIONS":
2849
+ return await baseClient.OPTIONS(path, requestInit);
2850
+ }
2413
2851
  }
2414
2852
  };
2853
+ function withWorkspaceId(path, init, workspaceId2) {
2854
+ if (!path.includes("{workspace_id}")) {
2855
+ return init ?? {};
2856
+ }
2857
+ const current = init ?? {};
2858
+ return {
2859
+ ...current,
2860
+ params: {
2861
+ ...current.params ?? {},
2862
+ path: {
2863
+ ...current.params?.path ?? {},
2864
+ workspace_id: workspaceId2
2865
+ }
2866
+ }
2867
+ };
2868
+ }
2415
2869
  //# sourceMappingURL=index.cjs.map