@axonflow/sdk 6.1.0 → 7.0.0

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 (48) hide show
  1. package/README.md +15 -6
  2. package/dist/cjs/client.d.ts +78 -1
  3. package/dist/cjs/client.d.ts.map +1 -1
  4. package/dist/cjs/client.js +228 -55
  5. package/dist/cjs/client.js.map +1 -1
  6. package/dist/cjs/heartbeat.d.ts +115 -0
  7. package/dist/cjs/heartbeat.d.ts.map +1 -0
  8. package/dist/cjs/heartbeat.js +280 -0
  9. package/dist/cjs/heartbeat.js.map +1 -0
  10. package/dist/cjs/telemetry.d.ts +22 -3
  11. package/dist/cjs/telemetry.d.ts.map +1 -1
  12. package/dist/cjs/telemetry.js +73 -19
  13. package/dist/cjs/telemetry.js.map +1 -1
  14. package/dist/cjs/types/config.d.ts +2 -2
  15. package/dist/cjs/types/index.d.ts +1 -0
  16. package/dist/cjs/types/index.d.ts.map +1 -1
  17. package/dist/cjs/types/index.js +1 -0
  18. package/dist/cjs/types/index.js.map +1 -1
  19. package/dist/cjs/types/llm-providers.d.ts +63 -0
  20. package/dist/cjs/types/llm-providers.d.ts.map +1 -0
  21. package/dist/cjs/types/llm-providers.js +9 -0
  22. package/dist/cjs/types/llm-providers.js.map +1 -0
  23. package/dist/cjs/version.d.ts +1 -1
  24. package/dist/cjs/version.js +1 -1
  25. package/dist/esm/client.d.ts +78 -1
  26. package/dist/esm/client.d.ts.map +1 -1
  27. package/dist/esm/client.js +229 -56
  28. package/dist/esm/client.js.map +1 -1
  29. package/dist/esm/heartbeat.d.ts +115 -0
  30. package/dist/esm/heartbeat.d.ts.map +1 -0
  31. package/dist/esm/heartbeat.js +237 -0
  32. package/dist/esm/heartbeat.js.map +1 -0
  33. package/dist/esm/telemetry.d.ts +22 -3
  34. package/dist/esm/telemetry.d.ts.map +1 -1
  35. package/dist/esm/telemetry.js +72 -19
  36. package/dist/esm/telemetry.js.map +1 -1
  37. package/dist/esm/types/config.d.ts +2 -2
  38. package/dist/esm/types/index.d.ts +1 -0
  39. package/dist/esm/types/index.d.ts.map +1 -1
  40. package/dist/esm/types/index.js +1 -0
  41. package/dist/esm/types/index.js.map +1 -1
  42. package/dist/esm/types/llm-providers.d.ts +63 -0
  43. package/dist/esm/types/llm-providers.d.ts.map +1 -0
  44. package/dist/esm/types/llm-providers.js +8 -0
  45. package/dist/esm/types/llm-providers.js.map +1 -0
  46. package/dist/esm/version.d.ts +1 -1
  47. package/dist/esm/version.js +1 -1
  48. package/package.json +5 -2
@@ -1,5 +1,6 @@
1
1
  import { VERSION } from './version.js';
2
- import { sendTelemetryPing } from './telemetry.js';
2
+ import { maybeSendHeartbeat, flushHeartbeat } from './heartbeat.js';
3
+ import { sendTelemetryPingNow } from './telemetry.js';
3
4
  import { AuthenticationError, APIError, PolicyViolationError, ConfigurationError, ConnectorError, PlanExecutionError, VersionConflictError, IdempotencyKeyMismatchError, } from './errors.js';
4
5
  import { generateRequestId, debugLog } from './utils/helpers.js';
5
6
  /**
@@ -63,8 +64,11 @@ export class AxonFlow {
63
64
  endpoint: 'https://try.getaxonflow.com',
64
65
  };
65
66
  }
66
- // Set defaults first to determine endpoint
67
- const endpoint = config.endpoint ?? 'https://staging-eu.getaxonflow.com';
67
+ // Set defaults first to determine endpoint. Default is localhost so
68
+ // local docker-compose flows work zero-config; production callers
69
+ // always pass an explicit endpoint. The previous default
70
+ // (staging-eu.getaxonflow.com) was decommissioned 2026-04-09.
71
+ const endpoint = config.endpoint ?? 'http://localhost:8080';
68
72
  // Credentials check: OAuth2-style (clientId/clientSecret)
69
73
  const hasCredentials = !!(config.clientId && config.clientSecret);
70
74
  // Set configuration
@@ -89,6 +93,9 @@ export class AxonFlow {
89
93
  };
90
94
  // Interceptors removed in v3.0.0 (deprecated wrapOpenAIClient/wrapAnthropicClient)
91
95
  this.interceptors = [];
96
+ // Capture for the heartbeat gate (see _preRequestHook).
97
+ this.telemetryEnabled = config.telemetry;
98
+ this.explicitMode = config.mode;
92
99
  if (this.config.debug) {
93
100
  // Determine auth method for logging
94
101
  const authMethod = hasCredentials ? 'client-credentials' : 'community (no auth)';
@@ -98,14 +105,66 @@ export class AxonFlow {
98
105
  authMethod,
99
106
  });
100
107
  }
101
- // Send telemetry ping (fire-and-forget).
102
- sendTelemetryPing({
108
+ // Heartbeat gate: at most one anonymous ping per environment per
109
+ // 7 days, gated by SDK activity. Constructor kicks off the gate AND
110
+ // chains the in-flight delivery Promise so `heartbeatReady` resolves
111
+ // only once the POST has settled — callers in short-lived processes
112
+ // (CLI, Lambda boot) can `await client.heartbeatReady` to guarantee
113
+ // delivery before exit. Subsequent gate runs happen async via
114
+ // _preRequestHook on every public HTTP request site. See
115
+ // src/heartbeat.ts.
116
+ this.heartbeatReady = (async () => {
117
+ await this._preRequestHook();
118
+ const inFlight = flushHeartbeat();
119
+ if (inFlight) {
120
+ await inFlight;
121
+ }
122
+ })();
123
+ }
124
+ /**
125
+ * Single hook invoked at the start of every public HTTP request path
126
+ * (via the `_fetch` wrapper). Schedules a heartbeat-gate evaluation;
127
+ * the gate's in-memory 1-hour cache plus the in-flight Promise gate
128
+ * mean the typical hot-path cost is a single comparison and an env
129
+ * read.
130
+ *
131
+ * Returns a Promise that the caller may discard — the gate runs
132
+ * asynchronously so user API calls are never delayed by telemetry.
133
+ */
134
+ async _preRequestHook() {
135
+ // Replicate the legacy sendTelemetryPing gating decision precisely:
136
+ // - explicit telemetry === false → off
137
+ // - explicit telemetry === true → on
138
+ // - explicit explicitMode === 'sandbox' (user-provided) → off
139
+ // - undefined explicitMode (auto-detected) → on regardless of mode
140
+ let enabled;
141
+ if (this.telemetryEnabled === false) {
142
+ enabled = false;
143
+ }
144
+ else if (this.telemetryEnabled === true) {
145
+ enabled = true;
146
+ }
147
+ else {
148
+ enabled = this.explicitMode !== 'sandbox';
149
+ }
150
+ await maybeSendHeartbeat(enabled, () => sendTelemetryPingNow({
103
151
  mode: this.config.mode,
104
- explicitMode: config.mode,
105
152
  endpoint: this.config.endpoint,
106
- telemetryEnabled: config.telemetry,
107
153
  debug: this.config.debug,
108
- });
154
+ }));
155
+ }
156
+ /**
157
+ * Single HTTP wrapper used by every public-API request path. Schedules
158
+ * a heartbeat-gate evaluation as a side effect (non-blocking — the gate
159
+ * runs asynchronously) and returns the underlying `fetch` response.
160
+ *
161
+ * IMPORTANT: This wrapper must NOT be called from the telemetry path
162
+ * itself (sendTelemetryPingNow / detectPlatformVersion). Those use raw
163
+ * `fetch` to avoid recursive heartbeat triggering.
164
+ */
165
+ async _fetch(input, init) {
166
+ void this._preRequestHook();
167
+ return fetch(input, init);
109
168
  }
110
169
  /**
111
170
  * Get authentication headers based on configured credentials.
@@ -279,7 +338,7 @@ export class AxonFlow {
279
338
  'Content-Type': 'application/json',
280
339
  ...this.getAuthHeaders(),
281
340
  };
282
- const response = await fetch(url, {
341
+ const response = await this._fetch(url, {
283
342
  method: 'POST',
284
343
  headers,
285
344
  body: JSON.stringify(agentRequest),
@@ -343,11 +402,15 @@ export class AxonFlow {
343
402
  * Create a sandbox client for testing
344
403
  */
345
404
  static sandbox(clientId = 'demo-client', clientSecret = 'demo-secret') {
405
+ // Sandbox mode targets the local docker-compose default. The previous
406
+ // staging-eu.getaxonflow.com endpoint was decommissioned 2026-04-09.
407
+ // Override with a custom endpoint via AxonFlow constructor if you
408
+ // need to point sandbox at a hosted environment.
346
409
  return new AxonFlow({
347
410
  clientId,
348
411
  clientSecret,
349
412
  mode: 'sandbox',
350
- endpoint: 'https://staging-eu.getaxonflow.com',
413
+ endpoint: 'http://localhost:8080',
351
414
  debug: true,
352
415
  });
353
416
  }
@@ -388,7 +451,7 @@ export class AxonFlow {
388
451
  async healthCheck() {
389
452
  const url = `${this.config.endpoint}/health`;
390
453
  try {
391
- const response = await fetch(url, {
454
+ const response = await this._fetch(url, {
392
455
  method: 'GET',
393
456
  headers: this.getAuthHeaders(),
394
457
  signal: AbortSignal.timeout(this.config.timeout),
@@ -453,7 +516,7 @@ export class AxonFlow {
453
516
  async orchestratorHealthCheck() {
454
517
  const url = `${this.config.endpoint}/health`;
455
518
  try {
456
- const response = await fetch(url, {
519
+ const response = await this._fetch(url, {
457
520
  method: 'GET',
458
521
  headers: this.getAuthHeaders(),
459
522
  signal: AbortSignal.timeout(this.config.timeout),
@@ -563,7 +626,7 @@ export class AxonFlow {
563
626
  query: options.query.substring(0, 50),
564
627
  });
565
628
  }
566
- const response = await fetch(url, {
629
+ const response = await this._fetch(url, {
567
630
  method: 'POST',
568
631
  headers,
569
632
  body: JSON.stringify(agentRequest),
@@ -695,6 +758,116 @@ export class AxonFlow {
695
758
  }
696
759
  return connectors;
697
760
  }
761
+ /**
762
+ * List configured LLM providers from a SINGLE page of results.
763
+ *
764
+ * Calls `GET /api/v1/llm-providers`. Mirrors the Java SDK's
765
+ * `listLLMProviders()`, the Python SDK's `list_providers()`, and the Go
766
+ * SDK's `ListProviders()`.
767
+ *
768
+ * For multi-page traversal use {@link listAllProviders}; for pagination
769
+ * metadata use {@link listProvidersPaged}.
770
+ *
771
+ * @param options - Optional filters and pagination: `type`, `enabled`,
772
+ * `page`, `page_size`. Server defaults are page 1, page_size 20.
773
+ * @returns Array of LLMProvider records, each with optional health snapshot.
774
+ *
775
+ * @example
776
+ * ```typescript
777
+ * const providers = await client.listProviders();
778
+ * providers.forEach(p =>
779
+ * console.log(`${p.name} (${p.type}) — ${p.health?.status ?? "?"}`)
780
+ * );
781
+ * ```
782
+ */
783
+ async listProviders(options) {
784
+ const result = await this.listProvidersPaged(options);
785
+ return result.providers;
786
+ }
787
+ /**
788
+ * List one page of LLM providers along with the pagination metadata
789
+ * (page / page_size / total_items / total_pages) so callers can
790
+ * paginate manually.
791
+ *
792
+ * @param options - Optional filters and pagination controls.
793
+ * @returns LLMProviderListResponse with `providers` and `pagination`.
794
+ */
795
+ async listProvidersPaged(options) {
796
+ const params = new URLSearchParams();
797
+ if (options?.type !== undefined) {
798
+ params.set('type', options.type);
799
+ }
800
+ if (options?.enabled !== undefined) {
801
+ params.set('enabled', options.enabled ? 'true' : 'false');
802
+ }
803
+ if (options?.page !== undefined) {
804
+ params.set('page', String(options.page));
805
+ }
806
+ if (options?.page_size !== undefined) {
807
+ params.set('page_size', String(options.page_size));
808
+ }
809
+ const queryString = params.toString();
810
+ const path = queryString ? `/api/v1/llm-providers?${queryString}` : '/api/v1/llm-providers';
811
+ const response = await this.orchestratorRequest('GET', path);
812
+ if (Array.isArray(response)) {
813
+ // Defensive fallback — older platforms may not have wrapped the
814
+ // response in {providers: [...], pagination: {...}}.
815
+ return {
816
+ providers: response,
817
+ pagination: {
818
+ page: 1,
819
+ page_size: response.length,
820
+ total_items: response.length,
821
+ total_pages: 1,
822
+ },
823
+ };
824
+ }
825
+ const providers = response.providers ?? [];
826
+ const pagination = response.pagination ?? {
827
+ page: 1,
828
+ page_size: providers.length,
829
+ total_items: providers.length,
830
+ total_pages: 1,
831
+ };
832
+ if (this.config.debug) {
833
+ debugLog('Listed LLM providers', {
834
+ count: providers.length,
835
+ page: pagination.page,
836
+ total_pages: pagination.total_pages,
837
+ });
838
+ }
839
+ return { providers, pagination };
840
+ }
841
+ /**
842
+ * Walk every page of LLM providers and return the combined list.
843
+ *
844
+ * Defaults to `page_size=100` (the server-side max) to minimise round
845
+ * trips. Per-page filters from `options.type` / `options.enabled` are
846
+ * honoured on every page; `options.page` / `options.page_size` are
847
+ * overridden by the walker.
848
+ *
849
+ * @param options - Optional `type` / `enabled` filters and `page_size`.
850
+ * @returns The full provider list across all pages.
851
+ */
852
+ async listAllProviders(options) {
853
+ const pageSize = options?.page_size ?? 100;
854
+ const all = [];
855
+ let page = 1;
856
+ while (true) {
857
+ const result = await this.listProvidersPaged({
858
+ type: options?.type,
859
+ enabled: options?.enabled,
860
+ page,
861
+ page_size: pageSize,
862
+ });
863
+ all.push(...result.providers);
864
+ if (result.pagination.total_pages <= page || result.providers.length === 0) {
865
+ break;
866
+ }
867
+ page += 1;
868
+ }
869
+ return all;
870
+ }
698
871
  /**
699
872
  * Install an MCP connector from the marketplace
700
873
  */
@@ -757,7 +930,7 @@ export class AxonFlow {
757
930
  'Content-Type': 'application/json',
758
931
  ...this.getAuthHeaders(),
759
932
  };
760
- const response = await fetch(url, {
933
+ const response = await this._fetch(url, {
761
934
  method: 'POST',
762
935
  headers,
763
936
  body: JSON.stringify(agentRequest),
@@ -826,7 +999,7 @@ export class AxonFlow {
826
999
  statement: options.statement.substring(0, 50),
827
1000
  });
828
1001
  }
829
- const response = await fetch(url, {
1002
+ const response = await this._fetch(url, {
830
1003
  method: 'POST',
831
1004
  headers,
832
1005
  body: JSON.stringify(body),
@@ -908,7 +1081,7 @@ export class AxonFlow {
908
1081
  statement: options.statement.substring(0, 50),
909
1082
  });
910
1083
  }
911
- const response = await fetch(url, {
1084
+ const response = await this._fetch(url, {
912
1085
  method: 'POST',
913
1086
  headers,
914
1087
  body: JSON.stringify(body),
@@ -980,7 +1153,7 @@ export class AxonFlow {
980
1153
  rowCount: options.rowCount,
981
1154
  });
982
1155
  }
983
- const response = await fetch(url, {
1156
+ const response = await this._fetch(url, {
984
1157
  method: 'POST',
985
1158
  headers,
986
1159
  body: JSON.stringify(body),
@@ -1052,7 +1225,7 @@ export class AxonFlow {
1052
1225
  ...this.getAuthHeaders(),
1053
1226
  };
1054
1227
  // Use mapTimeout for MAP operations (default 2 minutes)
1055
- const response = await fetch(url, {
1228
+ const response = await this._fetch(url, {
1056
1229
  method: 'POST',
1057
1230
  headers,
1058
1231
  body: JSON.stringify(agentRequest),
@@ -1112,7 +1285,7 @@ export class AxonFlow {
1112
1285
  ...this.getAuthHeaders(),
1113
1286
  };
1114
1287
  // Use mapTimeout for MAP operations (default 2 minutes)
1115
- const response = await fetch(url, {
1288
+ const response = await this._fetch(url, {
1116
1289
  method: 'POST',
1117
1290
  headers,
1118
1291
  body: JSON.stringify(agentRequest),
@@ -1167,7 +1340,7 @@ export class AxonFlow {
1167
1340
  */
1168
1341
  async getPlanStatus(planId) {
1169
1342
  const url = `${this.config.endpoint}/api/v1/plan/${planId}`;
1170
- const response = await fetch(url, {
1343
+ const response = await this._fetch(url, {
1171
1344
  method: 'GET',
1172
1345
  signal: AbortSignal.timeout(this.config.timeout),
1173
1346
  });
@@ -1200,7 +1373,7 @@ export class AxonFlow {
1200
1373
  if (reason) {
1201
1374
  body.reason = reason;
1202
1375
  }
1203
- const response = await fetch(url, {
1376
+ const response = await this._fetch(url, {
1204
1377
  method: 'POST',
1205
1378
  headers,
1206
1379
  body: JSON.stringify(body),
@@ -1249,7 +1422,7 @@ export class AxonFlow {
1249
1422
  if (request.metadata !== undefined) {
1250
1423
  body.metadata = request.metadata;
1251
1424
  }
1252
- const response = await fetch(url, {
1425
+ const response = await this._fetch(url, {
1253
1426
  method: 'PUT',
1254
1427
  headers,
1255
1428
  body: JSON.stringify(body),
@@ -1283,7 +1456,7 @@ export class AxonFlow {
1283
1456
  const headers = {
1284
1457
  ...this.getAuthHeaders(),
1285
1458
  };
1286
- const response = await fetch(url, {
1459
+ const response = await this._fetch(url, {
1287
1460
  method: 'GET',
1288
1461
  headers,
1289
1462
  signal: AbortSignal.timeout(this.config.timeout),
@@ -1316,7 +1489,7 @@ export class AxonFlow {
1316
1489
  'Content-Type': 'application/json',
1317
1490
  ...this.getAuthHeaders(),
1318
1491
  };
1319
- const response = await fetch(url, {
1492
+ const response = await this._fetch(url, {
1320
1493
  method: 'POST',
1321
1494
  headers,
1322
1495
  body: JSON.stringify({ approved: approved ?? true }),
@@ -1410,7 +1583,7 @@ export class AxonFlow {
1410
1583
  if (this.config.debug) {
1411
1584
  debugLog('Gateway Mode: Pre-check', { query: options.query.substring(0, 50) });
1412
1585
  }
1413
- const response = await fetch(url, {
1586
+ const response = await this._fetch(url, {
1414
1587
  method: 'POST',
1415
1588
  headers,
1416
1589
  body: JSON.stringify(requestBody),
@@ -1506,7 +1679,7 @@ export class AxonFlow {
1506
1679
  model: options.model,
1507
1680
  });
1508
1681
  }
1509
- const response = await fetch(url, {
1682
+ const response = await this._fetch(url, {
1510
1683
  method: 'POST',
1511
1684
  headers,
1512
1685
  body: JSON.stringify(requestBody),
@@ -2099,7 +2272,7 @@ export class AxonFlow {
2099
2272
  if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
2100
2273
  options.body = JSON.stringify(body);
2101
2274
  }
2102
- const response = await fetch(url, options);
2275
+ const response = await this._fetch(url, options);
2103
2276
  if (!response.ok) {
2104
2277
  const errorText = await response.text();
2105
2278
  if (response.status === 401 || response.status === 403) {
@@ -2655,7 +2828,7 @@ export class AxonFlow {
2655
2828
  */
2656
2829
  async loginToPortal(orgId, password) {
2657
2830
  const url = `${this.config.endpoint}/api/v1/auth/login`;
2658
- const response = await fetch(url, {
2831
+ const response = await this._fetch(url, {
2659
2832
  method: 'POST',
2660
2833
  headers: { 'Content-Type': 'application/json' },
2661
2834
  body: JSON.stringify({ org_id: orgId, password }),
@@ -2697,7 +2870,7 @@ export class AxonFlow {
2697
2870
  return;
2698
2871
  }
2699
2872
  try {
2700
- await fetch(`${this.config.endpoint}/api/v1/auth/logout`, {
2873
+ await this._fetch(`${this.config.endpoint}/api/v1/auth/logout`, {
2701
2874
  method: 'POST',
2702
2875
  headers: { Cookie: `axonflow_session=${this.sessionCookie}` },
2703
2876
  signal: AbortSignal.timeout(this.config.timeout),
@@ -3241,7 +3414,7 @@ export class AxonFlow {
3241
3414
  if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
3242
3415
  options.body = JSON.stringify(body);
3243
3416
  }
3244
- const response = await fetch(url, options);
3417
+ const response = await this._fetch(url, options);
3245
3418
  if (!response.ok) {
3246
3419
  const errorText = await response.text();
3247
3420
  if (response.status === 401 || response.status === 403) {
@@ -3285,7 +3458,7 @@ export class AxonFlow {
3285
3458
  if (this.config.debug) {
3286
3459
  debugLog('Portal request', { method, path });
3287
3460
  }
3288
- const response = await fetch(url, options);
3461
+ const response = await this._fetch(url, options);
3289
3462
  if (!response.ok) {
3290
3463
  const errorText = await response.text();
3291
3464
  if (response.status === 401 || response.status === 403) {
@@ -3897,7 +4070,7 @@ export class AxonFlow {
3897
4070
  if (this.config.debug) {
3898
4071
  debugLog('Portal request (text)', { method, path });
3899
4072
  }
3900
- const response = await fetch(url, options);
4073
+ const response = await this._fetch(url, options);
3901
4074
  if (!response.ok) {
3902
4075
  const errorText = await response.text();
3903
4076
  if (response.status === 401 || response.status === 403) {
@@ -4340,7 +4513,7 @@ export class AxonFlow {
4340
4513
  'Content-Type': 'application/json',
4341
4514
  ...this.getAuthHeaders(),
4342
4515
  };
4343
- const response = await fetch(url, {
4516
+ const response = await this._fetch(url, {
4344
4517
  method: 'POST',
4345
4518
  headers,
4346
4519
  body: JSON.stringify({}),
@@ -4529,7 +4702,7 @@ export class AxonFlow {
4529
4702
  risk_rating_reliance: request.humanReliance,
4530
4703
  metadata: request.metadata,
4531
4704
  };
4532
- const response = await fetch(url, {
4705
+ const response = await this._fetch(url, {
4533
4706
  method: 'POST',
4534
4707
  headers: {
4535
4708
  'Content-Type': 'application/json',
@@ -4546,7 +4719,7 @@ export class AxonFlow {
4546
4719
  }
4547
4720
  async masfeatGetSystem(systemId) {
4548
4721
  const url = `${this.config.endpoint}/api/v1/masfeat/registry/${systemId}`;
4549
- const response = await fetch(url, {
4722
+ const response = await this._fetch(url, {
4550
4723
  method: 'GET',
4551
4724
  headers: {
4552
4725
  ...this.getAuthHeaders(),
@@ -4580,7 +4753,7 @@ export class AxonFlow {
4580
4753
  body.human_reliance = request.humanReliance;
4581
4754
  if (request.metadata !== undefined)
4582
4755
  body.metadata = request.metadata;
4583
- const response = await fetch(url, {
4756
+ const response = await this._fetch(url, {
4584
4757
  method: 'PUT',
4585
4758
  headers: {
4586
4759
  'Content-Type': 'application/json',
@@ -4609,7 +4782,7 @@ export class AxonFlow {
4609
4782
  params.append('offset', options.offset.toString());
4610
4783
  const queryString = params.toString();
4611
4784
  const url = `${this.config.endpoint}/api/v1/masfeat/registry${queryString ? `?${queryString}` : ''}`;
4612
- const response = await fetch(url, {
4785
+ const response = await this._fetch(url, {
4613
4786
  method: 'GET',
4614
4787
  headers: {
4615
4788
  ...this.getAuthHeaders(),
@@ -4626,7 +4799,7 @@ export class AxonFlow {
4626
4799
  async masfeatActivateSystem(systemId) {
4627
4800
  // Use PUT to update status - the /activate endpoint doesn't exist
4628
4801
  const url = `${this.config.endpoint}/api/v1/masfeat/registry/${systemId}`;
4629
- const response = await fetch(url, {
4802
+ const response = await this._fetch(url, {
4630
4803
  method: 'PUT',
4631
4804
  headers: {
4632
4805
  'Content-Type': 'application/json',
@@ -4643,7 +4816,7 @@ export class AxonFlow {
4643
4816
  }
4644
4817
  async masfeatRetireSystem(systemId) {
4645
4818
  const url = `${this.config.endpoint}/api/v1/masfeat/registry/${systemId}`;
4646
- const response = await fetch(url, {
4819
+ const response = await this._fetch(url, {
4647
4820
  method: 'DELETE',
4648
4821
  headers: {
4649
4822
  ...this.getAuthHeaders(),
@@ -4658,7 +4831,7 @@ export class AxonFlow {
4658
4831
  }
4659
4832
  async masfeatGetRegistrySummary() {
4660
4833
  const url = `${this.config.endpoint}/api/v1/masfeat/registry/summary`;
4661
- const response = await fetch(url, {
4834
+ const response = await this._fetch(url, {
4662
4835
  method: 'GET',
4663
4836
  headers: {
4664
4837
  ...this.getAuthHeaders(),
@@ -4720,7 +4893,7 @@ export class AxonFlow {
4720
4893
  due_date: f.dueDate?.toISOString(),
4721
4894
  }));
4722
4895
  }
4723
- const response = await fetch(url, {
4896
+ const response = await this._fetch(url, {
4724
4897
  method: 'POST',
4725
4898
  headers: {
4726
4899
  'Content-Type': 'application/json',
@@ -4737,7 +4910,7 @@ export class AxonFlow {
4737
4910
  }
4738
4911
  async masfeatGetAssessment(assessmentId) {
4739
4912
  const url = `${this.config.endpoint}/api/v1/masfeat/assessments/${assessmentId}`;
4740
- const response = await fetch(url, {
4913
+ const response = await this._fetch(url, {
4741
4914
  method: 'GET',
4742
4915
  headers: {
4743
4916
  ...this.getAuthHeaders(),
@@ -4785,7 +4958,7 @@ export class AxonFlow {
4785
4958
  body.recommendations = request.recommendations;
4786
4959
  if (request.assessors !== undefined)
4787
4960
  body.assessors = request.assessors;
4788
- const response = await fetch(url, {
4961
+ const response = await this._fetch(url, {
4789
4962
  method: 'PUT',
4790
4963
  headers: {
4791
4964
  'Content-Type': 'application/json',
@@ -4812,7 +4985,7 @@ export class AxonFlow {
4812
4985
  params.append('offset', options.offset.toString());
4813
4986
  const queryString = params.toString();
4814
4987
  const url = `${this.config.endpoint}/api/v1/masfeat/assessments${queryString ? `?${queryString}` : ''}`;
4815
- const response = await fetch(url, {
4988
+ const response = await this._fetch(url, {
4816
4989
  method: 'GET',
4817
4990
  headers: {
4818
4991
  ...this.getAuthHeaders(),
@@ -4828,7 +5001,7 @@ export class AxonFlow {
4828
5001
  }
4829
5002
  async masfeatSubmitAssessment(assessmentId) {
4830
5003
  const url = `${this.config.endpoint}/api/v1/masfeat/assessments/${assessmentId}/submit`;
4831
- const response = await fetch(url, {
5004
+ const response = await this._fetch(url, {
4832
5005
  method: 'POST',
4833
5006
  headers: {
4834
5007
  'Content-Type': 'application/json',
@@ -4844,7 +5017,7 @@ export class AxonFlow {
4844
5017
  }
4845
5018
  async masfeatApproveAssessment(assessmentId, request) {
4846
5019
  const url = `${this.config.endpoint}/api/v1/masfeat/assessments/${assessmentId}/approve`;
4847
- const response = await fetch(url, {
5020
+ const response = await this._fetch(url, {
4848
5021
  method: 'POST',
4849
5022
  headers: {
4850
5023
  'Content-Type': 'application/json',
@@ -4864,7 +5037,7 @@ export class AxonFlow {
4864
5037
  }
4865
5038
  async masfeatRejectAssessment(assessmentId, request) {
4866
5039
  const url = `${this.config.endpoint}/api/v1/masfeat/assessments/${assessmentId}/reject`;
4867
- const response = await fetch(url, {
5040
+ const response = await this._fetch(url, {
4868
5041
  method: 'POST',
4869
5042
  headers: {
4870
5043
  'Content-Type': 'application/json',
@@ -4885,7 +5058,7 @@ export class AxonFlow {
4885
5058
  // Kill Switch Methods
4886
5059
  async masfeatGetKillSwitch(systemId) {
4887
5060
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}`;
4888
- const response = await fetch(url, {
5061
+ const response = await this._fetch(url, {
4889
5062
  method: 'GET',
4890
5063
  headers: {
4891
5064
  ...this.getAuthHeaders(),
@@ -4909,7 +5082,7 @@ export class AxonFlow {
4909
5082
  body.error_rate_threshold = request.errorRateThreshold;
4910
5083
  if (request.autoTriggerEnabled !== undefined)
4911
5084
  body.auto_trigger_enabled = request.autoTriggerEnabled;
4912
- const response = await fetch(url, {
5085
+ const response = await this._fetch(url, {
4913
5086
  method: 'POST',
4914
5087
  headers: {
4915
5088
  'Content-Type': 'application/json',
@@ -4926,7 +5099,7 @@ export class AxonFlow {
4926
5099
  }
4927
5100
  async masfeatCheckKillSwitch(systemId, request) {
4928
5101
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/check`;
4929
- const response = await fetch(url, {
5102
+ const response = await this._fetch(url, {
4930
5103
  method: 'POST',
4931
5104
  headers: {
4932
5105
  'Content-Type': 'application/json',
@@ -4947,7 +5120,7 @@ export class AxonFlow {
4947
5120
  }
4948
5121
  async masfeatTriggerKillSwitch(systemId, request) {
4949
5122
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/trigger`;
4950
- const response = await fetch(url, {
5123
+ const response = await this._fetch(url, {
4951
5124
  method: 'POST',
4952
5125
  headers: {
4953
5126
  'Content-Type': 'application/json',
@@ -4967,7 +5140,7 @@ export class AxonFlow {
4967
5140
  }
4968
5141
  async masfeatRestoreKillSwitch(systemId, request) {
4969
5142
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/restore`;
4970
- const response = await fetch(url, {
5143
+ const response = await this._fetch(url, {
4971
5144
  method: 'POST',
4972
5145
  headers: {
4973
5146
  'Content-Type': 'application/json',
@@ -4987,7 +5160,7 @@ export class AxonFlow {
4987
5160
  }
4988
5161
  async masfeatEnableKillSwitch(systemId) {
4989
5162
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/enable`;
4990
- const response = await fetch(url, {
5163
+ const response = await this._fetch(url, {
4991
5164
  method: 'POST',
4992
5165
  headers: {
4993
5166
  'Content-Type': 'application/json',
@@ -5003,7 +5176,7 @@ export class AxonFlow {
5003
5176
  }
5004
5177
  async masfeatDisableKillSwitch(systemId, request) {
5005
5178
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/disable`;
5006
- const response = await fetch(url, {
5179
+ const response = await this._fetch(url, {
5007
5180
  method: 'POST',
5008
5181
  headers: {
5009
5182
  'Content-Type': 'application/json',
@@ -5024,7 +5197,7 @@ export class AxonFlow {
5024
5197
  params.append('limit', limit.toString());
5025
5198
  const queryString = params.toString();
5026
5199
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/history${queryString ? `?${queryString}` : ''}`;
5027
- const response = await fetch(url, {
5200
+ const response = await this._fetch(url, {
5028
5201
  method: 'GET',
5029
5202
  headers: {
5030
5203
  ...this.getAuthHeaders(),
@@ -5580,7 +5753,7 @@ export class AxonFlow {
5580
5753
  }
5581
5754
  let response;
5582
5755
  try {
5583
- response = await fetch(url, fetchOptions);
5756
+ response = await this._fetch(url, fetchOptions);
5584
5757
  }
5585
5758
  catch (error) {
5586
5759
  if (error instanceof Error && error.name === 'AbortError') {