@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.mjs CHANGED
@@ -234,6 +234,90 @@ function parseRateLimitHeaders(headers) {
234
234
  };
235
235
  }
236
236
 
237
+ // src/core/request-options.ts
238
+ function stripRequestControls(options) {
239
+ if (!options) {
240
+ return void 0;
241
+ }
242
+ const rest = { ...options };
243
+ delete rest.timeout;
244
+ delete rest.maxRetries;
245
+ delete rest.retry;
246
+ return rest;
247
+ }
248
+ function mergeRequestOptions(base, override) {
249
+ if (!base) {
250
+ return override;
251
+ }
252
+ if (!override) {
253
+ return base;
254
+ }
255
+ const mergeableOverride = override;
256
+ return {
257
+ ...base,
258
+ ...override,
259
+ headers: mergeHeaders(base.headers, mergeableOverride.headers),
260
+ signal: mergeableOverride.signal ?? base.signal,
261
+ timeout: mergeableOverride.timeout ?? base.timeout,
262
+ maxRetries: mergeableOverride.maxRetries ?? base.maxRetries,
263
+ retry: mergeableOverride.retry ?? base.retry
264
+ };
265
+ }
266
+ function mergeScopedRequestOptions(base, override) {
267
+ return mergeRequestOptions(base, override) ?? override;
268
+ }
269
+ function mergeHeaders(base, override) {
270
+ if (!base && !override) {
271
+ return void 0;
272
+ }
273
+ const headers = new Headers();
274
+ let hasEntries = false;
275
+ applyHeaders(headers, base, () => {
276
+ hasEntries = true;
277
+ });
278
+ applyHeaders(headers, override, () => {
279
+ hasEntries = true;
280
+ });
281
+ return hasEntries ? headers : void 0;
282
+ }
283
+ function applyHeaders(target, source, onSet) {
284
+ if (!source) {
285
+ return;
286
+ }
287
+ if (source instanceof Headers) {
288
+ source.forEach((value, key) => {
289
+ target.set(key, value);
290
+ onSet();
291
+ });
292
+ return;
293
+ }
294
+ if (Array.isArray(source)) {
295
+ for (const [key, value] of source) {
296
+ if (!key) {
297
+ continue;
298
+ }
299
+ if (value === null || value === void 0) {
300
+ target.delete(key);
301
+ continue;
302
+ }
303
+ target.set(key, String(value));
304
+ onSet();
305
+ }
306
+ return;
307
+ }
308
+ for (const [key, value] of Object.entries(source)) {
309
+ if (value === null || value === void 0) {
310
+ target.delete(key);
311
+ continue;
312
+ }
313
+ target.set(
314
+ key,
315
+ Array.isArray(value) ? value.map((item) => String(item)).join(", ") : String(value)
316
+ );
317
+ onSet();
318
+ }
319
+ }
320
+
237
321
  // src/core/retry.ts
238
322
  var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
239
323
  var POST_RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429]);
@@ -342,18 +426,89 @@ function defineHiddenMetadata(target, key, value) {
342
426
 
343
427
  // src/core/openapi-client.ts
344
428
  var createClient = typeof createClientImport === "function" ? createClientImport : createClientImport.default;
429
+ var platformClientContext = /* @__PURE__ */ new WeakMap();
345
430
  function createPlatformClient(config) {
346
- const baseFetch = config.fetch ?? globalThis.fetch;
347
- const retryingFetch = async (input, init) => {
431
+ const transport = toRequestTransport(config.fetch ?? globalThis.fetch);
432
+ const defaults = {
433
+ retry: config.retry,
434
+ maxRetries: config.maxRetries,
435
+ timeout: config.timeout
436
+ };
437
+ const client = createClient({
438
+ baseUrl: config.baseUrl,
439
+ fetch: createRetryingFetch(transport, defaults),
440
+ headers: config.headers
441
+ });
442
+ platformClientContext.set(client, { transport, defaults });
443
+ const errorMiddleware = {
444
+ async onResponse({ response }) {
445
+ if (!response.ok) {
446
+ throw await createApiError(response);
447
+ }
448
+ return response;
449
+ }
450
+ };
451
+ const authMiddleware = createAuthMiddleware({ apiKey: config.apiKey });
452
+ const hookMiddleware = config.hooks ? {
453
+ async onRequest({ request, schemaPath, id }) {
454
+ await config.hooks?.onRequest?.({ request, schemaPath, id });
455
+ return request;
456
+ },
457
+ async onResponse({ request, response, schemaPath, id }) {
458
+ await config.hooks?.onResponse?.({
459
+ id,
460
+ request,
461
+ response,
462
+ schemaPath,
463
+ requestId: extractRequestId(response),
464
+ rateLimit: parseRateLimitHeaders(response.headers)
465
+ });
466
+ return response;
467
+ },
468
+ async onError({ request, error, schemaPath, id }) {
469
+ await config.hooks?.onError?.({ id, request, error, schemaPath });
470
+ }
471
+ } : void 0;
472
+ client.use(authMiddleware);
473
+ client.use(errorMiddleware);
474
+ if (hookMiddleware) {
475
+ client.use(hookMiddleware);
476
+ }
477
+ return client;
478
+ }
479
+ function applyPlatformRequestOptions(client, init) {
480
+ if (!init) {
481
+ return void 0;
482
+ }
483
+ const context = platformClientContext.get(client);
484
+ const stripped = stripRequestControls(init);
485
+ if (!context) {
486
+ return stripped;
487
+ }
488
+ const overrideFetch = stripped?.fetch;
489
+ const hasControlOverride = overrideFetch !== void 0 || init.timeout !== void 0 || init.maxRetries !== void 0 || init.retry !== void 0;
490
+ if (!hasControlOverride) {
491
+ return stripped;
492
+ }
493
+ const transport = toRequestTransport(
494
+ overrideFetch ?? context.transport
495
+ );
496
+ const fetch = createRetryingFetch(transport, {
497
+ timeout: init.timeout ?? context.defaults.timeout,
498
+ maxRetries: init.maxRetries ?? context.defaults.maxRetries,
499
+ retry: init.retry ?? context.defaults.retry
500
+ });
501
+ return {
502
+ ...stripped,
503
+ fetch
504
+ };
505
+ }
506
+ function createRetryingFetch(transport, defaults) {
507
+ return async (input, init) => {
348
508
  const baseRequest = input instanceof Request ? input : new Request(input, init);
349
509
  const method = baseRequest.method.toUpperCase();
350
- const requestRetry = getRequestOption(baseRequest, "retry");
351
- const requestMaxRetries = getRequestOption(baseRequest, "maxRetries");
352
- const retryOpts = resolveRetryOptions(
353
- requestRetry ?? config.retry,
354
- requestMaxRetries ?? config.maxRetries
355
- );
356
- const timeoutMs = getRequestOption(baseRequest, "timeout") ?? config.timeout;
510
+ const retryOpts = resolveRetryOptions(defaults.retry, defaults.maxRetries);
511
+ const timeoutMs = defaults.timeout;
357
512
  const isIdempotent = method === "GET" || method === "HEAD" || method === "OPTIONS";
358
513
  for (let attempt = 0; attempt < retryOpts.maxAttempts; attempt++) {
359
514
  let response;
@@ -362,7 +517,7 @@ function createPlatformClient(config) {
362
517
  try {
363
518
  const prepared = prepareRequestForAttempt(baseRequest, timeoutMs);
364
519
  try {
365
- response = await baseFetch(prepared.request, init);
520
+ response = await transport(prepared.request);
366
521
  } finally {
367
522
  timedOut = prepared.timedOut;
368
523
  prepared.cleanup();
@@ -396,53 +551,12 @@ function createPlatformClient(config) {
396
551
  }
397
552
  throw new NetworkError("Retry loop exhausted");
398
553
  };
399
- const client = createClient({
400
- baseUrl: config.baseUrl,
401
- fetch: retryingFetch,
402
- headers: config.headers
403
- });
404
- const errorMiddleware = {
405
- async onResponse({ response }) {
406
- if (!response.ok) {
407
- throw await createApiError(response);
408
- }
409
- return response;
410
- }
411
- };
412
- const authMiddleware = createAuthMiddleware({ apiKey: config.apiKey });
413
- const hookMiddleware = config.hooks ? {
414
- async onRequest({ request, schemaPath, id }) {
415
- await config.hooks?.onRequest?.({ request, schemaPath, id });
416
- return request;
417
- },
418
- async onResponse({ request, response, schemaPath, id }) {
419
- await config.hooks?.onResponse?.({
420
- id,
421
- request,
422
- response,
423
- schemaPath,
424
- requestId: extractRequestId(response),
425
- rateLimit: parseRateLimitHeaders(response.headers)
426
- });
427
- return response;
428
- },
429
- async onError({ request, error, schemaPath, id }) {
430
- await config.hooks?.onError?.({ id, request, error, schemaPath });
431
- }
432
- } : void 0;
433
- client.use(authMiddleware);
434
- client.use(errorMiddleware);
435
- if (hookMiddleware) {
436
- client.use(hookMiddleware);
437
- }
438
- return client;
439
554
  }
440
555
  function sleep(ms) {
441
556
  return new Promise((resolve) => setTimeout(resolve, ms));
442
557
  }
443
- function getRequestOption(request, key) {
444
- const value = request[key];
445
- return value;
558
+ function toRequestTransport(fetcher) {
559
+ return async (input) => fetcher(input);
446
560
  }
447
561
  function prepareRequestForAttempt(request, timeoutMs) {
448
562
  const attemptRequest = request.clone();
@@ -502,12 +616,98 @@ function createTimeoutSignal(upstream, timeoutMs) {
502
616
  }
503
617
 
504
618
  // src/resources/base.ts
619
+ var scopedClientState = /* @__PURE__ */ new WeakMap();
505
620
  var WorkspaceScopedResource = class {
506
621
  constructor(client, workspaceId2) {
507
622
  this.client = client;
508
623
  this.workspaceId = workspaceId2;
509
624
  }
625
+ withOptions(options) {
626
+ const ResourceCtor = this.constructor;
627
+ return new ResourceCtor(scopePlatformClient(this.client, options), this.workspaceId);
628
+ }
510
629
  };
630
+ function scopePlatformClient(client, options) {
631
+ const { baseClient, options: existingOptions } = resolveScopedPlatformClient(client);
632
+ const mergedOptions = mergeScopedRequestOptions(existingOptions, options);
633
+ const scopedClient = {
634
+ request: (method, path, init) => baseClient.request(
635
+ method,
636
+ path,
637
+ applyPlatformRequestOptions(
638
+ baseClient,
639
+ mergeRequestOptions(mergedOptions, init)
640
+ )
641
+ ),
642
+ GET: (path, init) => baseClient.GET(
643
+ path,
644
+ applyPlatformRequestOptions(
645
+ baseClient,
646
+ mergeRequestOptions(mergedOptions, init)
647
+ )
648
+ ),
649
+ PUT: (path, init) => baseClient.PUT(
650
+ path,
651
+ applyPlatformRequestOptions(
652
+ baseClient,
653
+ mergeRequestOptions(mergedOptions, init)
654
+ )
655
+ ),
656
+ POST: (path, init) => baseClient.POST(
657
+ path,
658
+ applyPlatformRequestOptions(
659
+ baseClient,
660
+ mergeRequestOptions(mergedOptions, init)
661
+ )
662
+ ),
663
+ DELETE: (path, init) => baseClient.DELETE(
664
+ path,
665
+ applyPlatformRequestOptions(
666
+ baseClient,
667
+ mergeRequestOptions(mergedOptions, init)
668
+ )
669
+ ),
670
+ OPTIONS: (path, init) => baseClient.OPTIONS(
671
+ path,
672
+ applyPlatformRequestOptions(
673
+ baseClient,
674
+ mergeRequestOptions(mergedOptions, init)
675
+ )
676
+ ),
677
+ HEAD: (path, init) => baseClient.HEAD(
678
+ path,
679
+ applyPlatformRequestOptions(
680
+ baseClient,
681
+ mergeRequestOptions(mergedOptions, init)
682
+ )
683
+ ),
684
+ PATCH: (path, init) => baseClient.PATCH(
685
+ path,
686
+ applyPlatformRequestOptions(
687
+ baseClient,
688
+ mergeRequestOptions(mergedOptions, init)
689
+ )
690
+ ),
691
+ TRACE: (path, init) => baseClient.TRACE(
692
+ path,
693
+ applyPlatformRequestOptions(
694
+ baseClient,
695
+ mergeRequestOptions(mergedOptions, init)
696
+ )
697
+ ),
698
+ use: (...middleware) => baseClient.use(...middleware),
699
+ eject: (...middleware) => baseClient.eject(...middleware)
700
+ };
701
+ scopedClientState.set(scopedClient, { baseClient, options: mergedOptions });
702
+ return scopedClient;
703
+ }
704
+ function resolveScopedPlatformClient(client) {
705
+ const existing = scopedClientState.get(client);
706
+ return {
707
+ baseClient: existing?.baseClient ?? client,
708
+ options: existing?.options
709
+ };
710
+ }
511
711
 
512
712
  // src/resources/workspaces.ts
513
713
  var WorkspacesResource = class extends WorkspaceScopedResource {
@@ -2280,6 +2480,7 @@ var dataSourceId = (id) => id;
2280
2480
  // src/core/webhooks.ts
2281
2481
  var textEncoder = new TextEncoder();
2282
2482
  var MAX_TIMESTAMP_SKEW_MS = 5 * 60 * 1e3;
2483
+ var webCryptoPromise;
2283
2484
  var WebhookVerificationError = class extends Error {
2284
2485
  constructor(message) {
2285
2486
  super(message);
@@ -2367,6 +2568,7 @@ function toUint8Array(payload) {
2367
2568
  return new Uint8Array(payload);
2368
2569
  }
2369
2570
  async function signWebhookPayload(payload, secret, timestamp) {
2571
+ const crypto = await resolveWebCrypto();
2370
2572
  const key = await crypto.subtle.importKey(
2371
2573
  "raw",
2372
2574
  textEncoder.encode(secret),
@@ -2378,6 +2580,13 @@ async function signWebhookPayload(payload, secret, timestamp) {
2378
2580
  const mac = await crypto.subtle.sign("HMAC", key, toCryptoBuffer(message));
2379
2581
  return new Uint8Array(mac);
2380
2582
  }
2583
+ async function resolveWebCrypto() {
2584
+ if (globalThis.crypto?.subtle) {
2585
+ return globalThis.crypto;
2586
+ }
2587
+ webCryptoPromise ??= import("node:crypto").then(({ webcrypto }) => webcrypto);
2588
+ return await webCryptoPromise;
2589
+ }
2381
2590
  function normalizeSignature(signature) {
2382
2591
  const normalized = signature.startsWith("sha256=") ? signature.slice(7) : signature;
2383
2592
  if (!/^[a-fA-F0-9]+$/.test(normalized) || normalized.length % 2 !== 0) {
@@ -2418,7 +2627,7 @@ function toCryptoBuffer(bytes) {
2418
2627
 
2419
2628
  // src/index.ts
2420
2629
  var DEFAULT_BASE_URL = "https://api.platform.amigo.ai";
2421
- var AmigoClient = class {
2630
+ var AmigoClient = class _AmigoClient {
2422
2631
  workspaceId;
2423
2632
  baseUrl;
2424
2633
  workspaces;
@@ -2468,72 +2677,97 @@ var AmigoClient = class {
2468
2677
  hooks: config.hooks,
2469
2678
  fetch: config.fetch
2470
2679
  });
2471
- const ws = config.workspaceId;
2472
- this.workspaceId = ws;
2473
- this.baseUrl = baseUrl;
2474
- this.api = client;
2475
- this.workspaces = new WorkspacesResource(client, ws);
2476
- this.apiKeys = new ApiKeysResource(client, ws);
2477
- this.agents = new AgentsResource(client, ws);
2478
- this.skills = new SkillsResource(client, ws);
2479
- this.actions = new ActionsResource(client, ws);
2480
- this.operators = new OperatorsResource(client, ws);
2481
- this.triggers = new TriggersResource(client, ws);
2482
- this.services = new ServicesResource(client, ws);
2483
- this.contextGraphs = new ContextGraphsResource(client, ws);
2484
- this.dataSources = new DataSourcesResource(client, ws);
2485
- this.world = new WorldResource(client, ws);
2486
- this.calls = new CallsResource(client, ws);
2487
- this.phoneNumbers = new PhoneNumbersResource(client, ws);
2488
- this.integrations = new IntegrationsResource(client, ws);
2489
- this.analytics = new AnalyticsResource(client, ws);
2490
- this.simulations = new SimulationsResource(client, ws);
2491
- this.settings = new SettingsResource(client, ws);
2492
- this.billing = new BillingResource(client, ws);
2493
- this.memory = new MemoryResource(client, ws);
2494
- this.personas = new PersonasResource(client, ws);
2495
- this.reviewQueue = new ReviewQueueResource(client, ws);
2496
- this.recordings = new RecordingsResource(client, ws);
2497
- this.audit = new AuditResource(client, ws);
2498
- this.webhookDestinations = new WebhookDestinationsResource(client, ws);
2499
- this.safety = new SafetyResource(client, ws);
2500
- this.compliance = new ComplianceResource(client, ws);
2501
- this.functions = new FunctionsResource(client, ws);
2502
- }
2503
- async GET(path, init) {
2504
- return withResponse(
2505
- await this.api.GET(path, withWorkspaceId(path, init, this.workspaceId))
2506
- );
2507
- }
2508
- async POST(path, init) {
2509
- return withResponse(
2510
- await this.api.POST(path, withWorkspaceId(path, init, this.workspaceId))
2511
- );
2512
- }
2513
- async PUT(path, init) {
2514
- return withResponse(
2515
- await this.api.PUT(path, withWorkspaceId(path, init, this.workspaceId))
2516
- );
2517
- }
2518
- async PATCH(path, init) {
2519
- return withResponse(
2520
- await this.api.PATCH(path, withWorkspaceId(path, init, this.workspaceId))
2521
- );
2522
- }
2523
- async DELETE(path, init) {
2524
- return withResponse(
2525
- await this.api.DELETE(path, withWorkspaceId(path, init, this.workspaceId))
2526
- );
2527
- }
2528
- async HEAD(path, init) {
2529
- return withResponse(
2530
- await this.api.HEAD(path, withWorkspaceId(path, init, this.workspaceId))
2531
- );
2532
- }
2533
- async OPTIONS(path, init) {
2534
- return withResponse(
2535
- await this.api.OPTIONS(path, withWorkspaceId(path, init, this.workspaceId))
2536
- );
2680
+ _AmigoClient.hydrate(this, client, config.workspaceId, baseUrl);
2681
+ }
2682
+ withOptions(options) {
2683
+ return _AmigoClient.fromPlatformClient(
2684
+ scopePlatformClient(this.api, options),
2685
+ this.workspaceId,
2686
+ this.baseUrl
2687
+ );
2688
+ }
2689
+ async GET(path, ...[init]) {
2690
+ return withResponse(await this.resolveApiRequest(path, "GET", init));
2691
+ }
2692
+ async POST(path, ...[init]) {
2693
+ return withResponse(await this.resolveApiRequest(path, "POST", init));
2694
+ }
2695
+ async PUT(path, ...[init]) {
2696
+ return withResponse(await this.resolveApiRequest(path, "PUT", init));
2697
+ }
2698
+ async PATCH(path, ...[init]) {
2699
+ return withResponse(await this.resolveApiRequest(path, "PATCH", init));
2700
+ }
2701
+ async DELETE(path, ...[init]) {
2702
+ return withResponse(await this.resolveApiRequest(path, "DELETE", init));
2703
+ }
2704
+ async HEAD(path, ...[init]) {
2705
+ return withResponse(await this.resolveApiRequest(path, "HEAD", init));
2706
+ }
2707
+ async OPTIONS(path, ...[init]) {
2708
+ return withResponse(await this.resolveApiRequest(path, "OPTIONS", init));
2709
+ }
2710
+ static fromPlatformClient(client, workspaceId2, baseUrl) {
2711
+ const instance = Object.create(_AmigoClient.prototype);
2712
+ _AmigoClient.hydrate(instance, client, workspaceId2, baseUrl);
2713
+ return instance;
2714
+ }
2715
+ static hydrate(target, client, workspaceId2, baseUrl) {
2716
+ const mutable = target;
2717
+ mutable.workspaceId = workspaceId2;
2718
+ mutable.baseUrl = baseUrl;
2719
+ target.api = client;
2720
+ mutable.workspaces = new WorkspacesResource(client, workspaceId2);
2721
+ mutable.apiKeys = new ApiKeysResource(client, workspaceId2);
2722
+ mutable.agents = new AgentsResource(client, workspaceId2);
2723
+ mutable.skills = new SkillsResource(client, workspaceId2);
2724
+ mutable.actions = new ActionsResource(client, workspaceId2);
2725
+ mutable.operators = new OperatorsResource(client, workspaceId2);
2726
+ mutable.triggers = new TriggersResource(client, workspaceId2);
2727
+ mutable.services = new ServicesResource(client, workspaceId2);
2728
+ mutable.contextGraphs = new ContextGraphsResource(client, workspaceId2);
2729
+ mutable.dataSources = new DataSourcesResource(client, workspaceId2);
2730
+ mutable.world = new WorldResource(client, workspaceId2);
2731
+ mutable.calls = new CallsResource(client, workspaceId2);
2732
+ mutable.phoneNumbers = new PhoneNumbersResource(client, workspaceId2);
2733
+ mutable.integrations = new IntegrationsResource(client, workspaceId2);
2734
+ mutable.analytics = new AnalyticsResource(client, workspaceId2);
2735
+ mutable.simulations = new SimulationsResource(client, workspaceId2);
2736
+ mutable.settings = new SettingsResource(client, workspaceId2);
2737
+ mutable.billing = new BillingResource(client, workspaceId2);
2738
+ mutable.memory = new MemoryResource(client, workspaceId2);
2739
+ mutable.personas = new PersonasResource(client, workspaceId2);
2740
+ mutable.reviewQueue = new ReviewQueueResource(client, workspaceId2);
2741
+ mutable.recordings = new RecordingsResource(client, workspaceId2);
2742
+ mutable.audit = new AuditResource(client, workspaceId2);
2743
+ mutable.webhookDestinations = new WebhookDestinationsResource(client, workspaceId2);
2744
+ mutable.safety = new SafetyResource(client, workspaceId2);
2745
+ mutable.compliance = new ComplianceResource(client, workspaceId2);
2746
+ mutable.functions = new FunctionsResource(client, workspaceId2);
2747
+ }
2748
+ async resolveApiRequest(path, method, init) {
2749
+ const { baseClient, options } = resolveScopedPlatformClient(this.api);
2750
+ const mergedInit = mergeRequestOptions(options, withWorkspaceId(path, init, this.workspaceId));
2751
+ const requestInit = applyPlatformRequestOptions(
2752
+ baseClient,
2753
+ mergedInit
2754
+ );
2755
+ switch (method) {
2756
+ case "GET":
2757
+ return await baseClient.GET(path, requestInit);
2758
+ case "POST":
2759
+ return await baseClient.POST(path, requestInit);
2760
+ case "PUT":
2761
+ return await baseClient.PUT(path, requestInit);
2762
+ case "PATCH":
2763
+ return await baseClient.PATCH(path, requestInit);
2764
+ case "DELETE":
2765
+ return await baseClient.DELETE(path, requestInit);
2766
+ case "HEAD":
2767
+ return await baseClient.HEAD(path, requestInit);
2768
+ case "OPTIONS":
2769
+ return await baseClient.OPTIONS(path, requestInit);
2770
+ }
2537
2771
  }
2538
2772
  };
2539
2773
  function withWorkspaceId(path, init, workspaceId2) {
@@ -2546,8 +2780,8 @@ function withWorkspaceId(path, init, workspaceId2) {
2546
2780
  params: {
2547
2781
  ...current.params ?? {},
2548
2782
  path: {
2549
- workspace_id: workspaceId2,
2550
- ...current.params?.path ?? {}
2783
+ ...current.params?.path ?? {},
2784
+ workspace_id: workspaceId2
2551
2785
  }
2552
2786
  }
2553
2787
  };