@amigo-ai/platform-sdk 0.4.2 → 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.
package/dist/index.cjs CHANGED
@@ -314,6 +314,90 @@ function parseRateLimitHeaders(headers) {
314
314
  };
315
315
  }
316
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
+
317
401
  // src/core/retry.ts
318
402
  var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
319
403
  var POST_RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429]);
@@ -422,18 +506,89 @@ function defineHiddenMetadata(target, key, value) {
422
506
 
423
507
  // src/core/openapi-client.ts
424
508
  var createClient = typeof import_openapi_fetch.default === "function" ? import_openapi_fetch.default : import_openapi_fetch.default.default;
509
+ var platformClientContext = /* @__PURE__ */ new WeakMap();
425
510
  function createPlatformClient(config) {
426
- const baseFetch = config.fetch ?? globalThis.fetch;
427
- const retryingFetch = async (input, init) => {
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) => {
428
588
  const baseRequest = input instanceof Request ? input : new Request(input, init);
429
589
  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;
590
+ const retryOpts = resolveRetryOptions(defaults.retry, defaults.maxRetries);
591
+ const timeoutMs = defaults.timeout;
437
592
  const isIdempotent = method === "GET" || method === "HEAD" || method === "OPTIONS";
438
593
  for (let attempt = 0; attempt < retryOpts.maxAttempts; attempt++) {
439
594
  let response;
@@ -442,7 +597,7 @@ function createPlatformClient(config) {
442
597
  try {
443
598
  const prepared = prepareRequestForAttempt(baseRequest, timeoutMs);
444
599
  try {
445
- response = await baseFetch(prepared.request, init);
600
+ response = await transport(prepared.request);
446
601
  } finally {
447
602
  timedOut = prepared.timedOut;
448
603
  prepared.cleanup();
@@ -476,53 +631,12 @@ function createPlatformClient(config) {
476
631
  }
477
632
  throw new NetworkError("Retry loop exhausted");
478
633
  };
479
- const client = createClient({
480
- baseUrl: config.baseUrl,
481
- fetch: retryingFetch,
482
- headers: config.headers
483
- });
484
- const errorMiddleware = {
485
- async onResponse({ response }) {
486
- if (!response.ok) {
487
- throw await createApiError(response);
488
- }
489
- return response;
490
- }
491
- };
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;
513
- client.use(authMiddleware);
514
- client.use(errorMiddleware);
515
- if (hookMiddleware) {
516
- client.use(hookMiddleware);
517
- }
518
- return client;
519
634
  }
520
635
  function sleep(ms) {
521
636
  return new Promise((resolve) => setTimeout(resolve, ms));
522
637
  }
523
- function getRequestOption(request, key) {
524
- const value = request[key];
525
- return value;
638
+ function toRequestTransport(fetcher) {
639
+ return async (input) => fetcher(input);
526
640
  }
527
641
  function prepareRequestForAttempt(request, timeoutMs) {
528
642
  const attemptRequest = request.clone();
@@ -582,12 +696,98 @@ function createTimeoutSignal(upstream, timeoutMs) {
582
696
  }
583
697
 
584
698
  // src/resources/base.ts
699
+ var scopedClientState = /* @__PURE__ */ new WeakMap();
585
700
  var WorkspaceScopedResource = class {
586
701
  constructor(client, workspaceId2) {
587
702
  this.client = client;
588
703
  this.workspaceId = workspaceId2;
589
704
  }
705
+ withOptions(options) {
706
+ const ResourceCtor = this.constructor;
707
+ return new ResourceCtor(scopePlatformClient(this.client, options), this.workspaceId);
708
+ }
590
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
+ }
591
791
 
592
792
  // src/resources/workspaces.ts
593
793
  var WorkspacesResource = class extends WorkspaceScopedResource {
@@ -2360,6 +2560,7 @@ var dataSourceId = (id) => id;
2360
2560
  // src/core/webhooks.ts
2361
2561
  var textEncoder = new TextEncoder();
2362
2562
  var MAX_TIMESTAMP_SKEW_MS = 5 * 60 * 1e3;
2563
+ var webCryptoPromise;
2363
2564
  var WebhookVerificationError = class extends Error {
2364
2565
  constructor(message) {
2365
2566
  super(message);
@@ -2447,6 +2648,7 @@ function toUint8Array(payload) {
2447
2648
  return new Uint8Array(payload);
2448
2649
  }
2449
2650
  async function signWebhookPayload(payload, secret, timestamp) {
2651
+ const crypto = await resolveWebCrypto();
2450
2652
  const key = await crypto.subtle.importKey(
2451
2653
  "raw",
2452
2654
  textEncoder.encode(secret),
@@ -2458,6 +2660,13 @@ async function signWebhookPayload(payload, secret, timestamp) {
2458
2660
  const mac = await crypto.subtle.sign("HMAC", key, toCryptoBuffer(message));
2459
2661
  return new Uint8Array(mac);
2460
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
+ }
2461
2670
  function normalizeSignature(signature) {
2462
2671
  const normalized = signature.startsWith("sha256=") ? signature.slice(7) : signature;
2463
2672
  if (!/^[a-fA-F0-9]+$/.test(normalized) || normalized.length % 2 !== 0) {
@@ -2498,7 +2707,7 @@ function toCryptoBuffer(bytes) {
2498
2707
 
2499
2708
  // src/index.ts
2500
2709
  var DEFAULT_BASE_URL = "https://api.platform.amigo.ai";
2501
- var AmigoClient = class {
2710
+ var AmigoClient = class _AmigoClient {
2502
2711
  workspaceId;
2503
2712
  baseUrl;
2504
2713
  workspaces;
@@ -2548,72 +2757,97 @@ var AmigoClient = class {
2548
2757
  hooks: config.hooks,
2549
2758
  fetch: config.fetch
2550
2759
  });
2551
- const ws = config.workspaceId;
2552
- this.workspaceId = ws;
2553
- this.baseUrl = baseUrl;
2554
- this.api = client;
2555
- this.workspaces = new WorkspacesResource(client, ws);
2556
- this.apiKeys = new ApiKeysResource(client, ws);
2557
- this.agents = new AgentsResource(client, ws);
2558
- this.skills = new SkillsResource(client, ws);
2559
- this.actions = new ActionsResource(client, ws);
2560
- this.operators = new OperatorsResource(client, ws);
2561
- this.triggers = new TriggersResource(client, ws);
2562
- this.services = new ServicesResource(client, ws);
2563
- this.contextGraphs = new ContextGraphsResource(client, ws);
2564
- this.dataSources = new DataSourcesResource(client, ws);
2565
- this.world = new WorldResource(client, ws);
2566
- this.calls = new CallsResource(client, ws);
2567
- this.phoneNumbers = new PhoneNumbersResource(client, ws);
2568
- this.integrations = new IntegrationsResource(client, ws);
2569
- this.analytics = new AnalyticsResource(client, ws);
2570
- this.simulations = new SimulationsResource(client, ws);
2571
- this.settings = new SettingsResource(client, ws);
2572
- this.billing = new BillingResource(client, ws);
2573
- this.memory = new MemoryResource(client, ws);
2574
- this.personas = new PersonasResource(client, ws);
2575
- this.reviewQueue = new ReviewQueueResource(client, ws);
2576
- this.recordings = new RecordingsResource(client, ws);
2577
- this.audit = new AuditResource(client, ws);
2578
- this.webhookDestinations = new WebhookDestinationsResource(client, ws);
2579
- this.safety = new SafetyResource(client, ws);
2580
- this.compliance = new ComplianceResource(client, ws);
2581
- this.functions = new FunctionsResource(client, ws);
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
- );
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
+ }
2617
2851
  }
2618
2852
  };
2619
2853
  function withWorkspaceId(path, init, workspaceId2) {
@@ -2626,8 +2860,8 @@ function withWorkspaceId(path, init, workspaceId2) {
2626
2860
  params: {
2627
2861
  ...current.params ?? {},
2628
2862
  path: {
2629
- workspace_id: workspaceId2,
2630
- ...current.params?.path ?? {}
2863
+ ...current.params?.path ?? {},
2864
+ workspace_id: workspaceId2
2631
2865
  }
2632
2866
  }
2633
2867
  };