@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
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AxonFlow = void 0;
4
4
  const version_1 = require("./version");
5
+ const heartbeat_1 = require("./heartbeat");
5
6
  const telemetry_1 = require("./telemetry");
6
7
  const errors_1 = require("./errors");
7
8
  const helpers_1 = require("./utils/helpers");
@@ -66,8 +67,11 @@ class AxonFlow {
66
67
  endpoint: 'https://try.getaxonflow.com',
67
68
  };
68
69
  }
69
- // Set defaults first to determine endpoint
70
- const endpoint = config.endpoint ?? 'https://staging-eu.getaxonflow.com';
70
+ // Set defaults first to determine endpoint. Default is localhost so
71
+ // local docker-compose flows work zero-config; production callers
72
+ // always pass an explicit endpoint. The previous default
73
+ // (staging-eu.getaxonflow.com) was decommissioned 2026-04-09.
74
+ const endpoint = config.endpoint ?? 'http://localhost:8080';
71
75
  // Credentials check: OAuth2-style (clientId/clientSecret)
72
76
  const hasCredentials = !!(config.clientId && config.clientSecret);
73
77
  // Set configuration
@@ -92,6 +96,9 @@ class AxonFlow {
92
96
  };
93
97
  // Interceptors removed in v3.0.0 (deprecated wrapOpenAIClient/wrapAnthropicClient)
94
98
  this.interceptors = [];
99
+ // Capture for the heartbeat gate (see _preRequestHook).
100
+ this.telemetryEnabled = config.telemetry;
101
+ this.explicitMode = config.mode;
95
102
  if (this.config.debug) {
96
103
  // Determine auth method for logging
97
104
  const authMethod = hasCredentials ? 'client-credentials' : 'community (no auth)';
@@ -101,14 +108,66 @@ class AxonFlow {
101
108
  authMethod,
102
109
  });
103
110
  }
104
- // Send telemetry ping (fire-and-forget).
105
- (0, telemetry_1.sendTelemetryPing)({
111
+ // Heartbeat gate: at most one anonymous ping per environment per
112
+ // 7 days, gated by SDK activity. Constructor kicks off the gate AND
113
+ // chains the in-flight delivery Promise so `heartbeatReady` resolves
114
+ // only once the POST has settled — callers in short-lived processes
115
+ // (CLI, Lambda boot) can `await client.heartbeatReady` to guarantee
116
+ // delivery before exit. Subsequent gate runs happen async via
117
+ // _preRequestHook on every public HTTP request site. See
118
+ // src/heartbeat.ts.
119
+ this.heartbeatReady = (async () => {
120
+ await this._preRequestHook();
121
+ const inFlight = (0, heartbeat_1.flushHeartbeat)();
122
+ if (inFlight) {
123
+ await inFlight;
124
+ }
125
+ })();
126
+ }
127
+ /**
128
+ * Single hook invoked at the start of every public HTTP request path
129
+ * (via the `_fetch` wrapper). Schedules a heartbeat-gate evaluation;
130
+ * the gate's in-memory 1-hour cache plus the in-flight Promise gate
131
+ * mean the typical hot-path cost is a single comparison and an env
132
+ * read.
133
+ *
134
+ * Returns a Promise that the caller may discard — the gate runs
135
+ * asynchronously so user API calls are never delayed by telemetry.
136
+ */
137
+ async _preRequestHook() {
138
+ // Replicate the legacy sendTelemetryPing gating decision precisely:
139
+ // - explicit telemetry === false → off
140
+ // - explicit telemetry === true → on
141
+ // - explicit explicitMode === 'sandbox' (user-provided) → off
142
+ // - undefined explicitMode (auto-detected) → on regardless of mode
143
+ let enabled;
144
+ if (this.telemetryEnabled === false) {
145
+ enabled = false;
146
+ }
147
+ else if (this.telemetryEnabled === true) {
148
+ enabled = true;
149
+ }
150
+ else {
151
+ enabled = this.explicitMode !== 'sandbox';
152
+ }
153
+ await (0, heartbeat_1.maybeSendHeartbeat)(enabled, () => (0, telemetry_1.sendTelemetryPingNow)({
106
154
  mode: this.config.mode,
107
- explicitMode: config.mode,
108
155
  endpoint: this.config.endpoint,
109
- telemetryEnabled: config.telemetry,
110
156
  debug: this.config.debug,
111
- });
157
+ }));
158
+ }
159
+ /**
160
+ * Single HTTP wrapper used by every public-API request path. Schedules
161
+ * a heartbeat-gate evaluation as a side effect (non-blocking — the gate
162
+ * runs asynchronously) and returns the underlying `fetch` response.
163
+ *
164
+ * IMPORTANT: This wrapper must NOT be called from the telemetry path
165
+ * itself (sendTelemetryPingNow / detectPlatformVersion). Those use raw
166
+ * `fetch` to avoid recursive heartbeat triggering.
167
+ */
168
+ async _fetch(input, init) {
169
+ void this._preRequestHook();
170
+ return fetch(input, init);
112
171
  }
113
172
  /**
114
173
  * Get authentication headers based on configured credentials.
@@ -282,7 +341,7 @@ class AxonFlow {
282
341
  'Content-Type': 'application/json',
283
342
  ...this.getAuthHeaders(),
284
343
  };
285
- const response = await fetch(url, {
344
+ const response = await this._fetch(url, {
286
345
  method: 'POST',
287
346
  headers,
288
347
  body: JSON.stringify(agentRequest),
@@ -346,11 +405,15 @@ class AxonFlow {
346
405
  * Create a sandbox client for testing
347
406
  */
348
407
  static sandbox(clientId = 'demo-client', clientSecret = 'demo-secret') {
408
+ // Sandbox mode targets the local docker-compose default. The previous
409
+ // staging-eu.getaxonflow.com endpoint was decommissioned 2026-04-09.
410
+ // Override with a custom endpoint via AxonFlow constructor if you
411
+ // need to point sandbox at a hosted environment.
349
412
  return new AxonFlow({
350
413
  clientId,
351
414
  clientSecret,
352
415
  mode: 'sandbox',
353
- endpoint: 'https://staging-eu.getaxonflow.com',
416
+ endpoint: 'http://localhost:8080',
354
417
  debug: true,
355
418
  });
356
419
  }
@@ -391,7 +454,7 @@ class AxonFlow {
391
454
  async healthCheck() {
392
455
  const url = `${this.config.endpoint}/health`;
393
456
  try {
394
- const response = await fetch(url, {
457
+ const response = await this._fetch(url, {
395
458
  method: 'GET',
396
459
  headers: this.getAuthHeaders(),
397
460
  signal: AbortSignal.timeout(this.config.timeout),
@@ -456,7 +519,7 @@ class AxonFlow {
456
519
  async orchestratorHealthCheck() {
457
520
  const url = `${this.config.endpoint}/health`;
458
521
  try {
459
- const response = await fetch(url, {
522
+ const response = await this._fetch(url, {
460
523
  method: 'GET',
461
524
  headers: this.getAuthHeaders(),
462
525
  signal: AbortSignal.timeout(this.config.timeout),
@@ -566,7 +629,7 @@ class AxonFlow {
566
629
  query: options.query.substring(0, 50),
567
630
  });
568
631
  }
569
- const response = await fetch(url, {
632
+ const response = await this._fetch(url, {
570
633
  method: 'POST',
571
634
  headers,
572
635
  body: JSON.stringify(agentRequest),
@@ -698,6 +761,116 @@ class AxonFlow {
698
761
  }
699
762
  return connectors;
700
763
  }
764
+ /**
765
+ * List configured LLM providers from a SINGLE page of results.
766
+ *
767
+ * Calls `GET /api/v1/llm-providers`. Mirrors the Java SDK's
768
+ * `listLLMProviders()`, the Python SDK's `list_providers()`, and the Go
769
+ * SDK's `ListProviders()`.
770
+ *
771
+ * For multi-page traversal use {@link listAllProviders}; for pagination
772
+ * metadata use {@link listProvidersPaged}.
773
+ *
774
+ * @param options - Optional filters and pagination: `type`, `enabled`,
775
+ * `page`, `page_size`. Server defaults are page 1, page_size 20.
776
+ * @returns Array of LLMProvider records, each with optional health snapshot.
777
+ *
778
+ * @example
779
+ * ```typescript
780
+ * const providers = await client.listProviders();
781
+ * providers.forEach(p =>
782
+ * console.log(`${p.name} (${p.type}) — ${p.health?.status ?? "?"}`)
783
+ * );
784
+ * ```
785
+ */
786
+ async listProviders(options) {
787
+ const result = await this.listProvidersPaged(options);
788
+ return result.providers;
789
+ }
790
+ /**
791
+ * List one page of LLM providers along with the pagination metadata
792
+ * (page / page_size / total_items / total_pages) so callers can
793
+ * paginate manually.
794
+ *
795
+ * @param options - Optional filters and pagination controls.
796
+ * @returns LLMProviderListResponse with `providers` and `pagination`.
797
+ */
798
+ async listProvidersPaged(options) {
799
+ const params = new URLSearchParams();
800
+ if (options?.type !== undefined) {
801
+ params.set('type', options.type);
802
+ }
803
+ if (options?.enabled !== undefined) {
804
+ params.set('enabled', options.enabled ? 'true' : 'false');
805
+ }
806
+ if (options?.page !== undefined) {
807
+ params.set('page', String(options.page));
808
+ }
809
+ if (options?.page_size !== undefined) {
810
+ params.set('page_size', String(options.page_size));
811
+ }
812
+ const queryString = params.toString();
813
+ const path = queryString ? `/api/v1/llm-providers?${queryString}` : '/api/v1/llm-providers';
814
+ const response = await this.orchestratorRequest('GET', path);
815
+ if (Array.isArray(response)) {
816
+ // Defensive fallback — older platforms may not have wrapped the
817
+ // response in {providers: [...], pagination: {...}}.
818
+ return {
819
+ providers: response,
820
+ pagination: {
821
+ page: 1,
822
+ page_size: response.length,
823
+ total_items: response.length,
824
+ total_pages: 1,
825
+ },
826
+ };
827
+ }
828
+ const providers = response.providers ?? [];
829
+ const pagination = response.pagination ?? {
830
+ page: 1,
831
+ page_size: providers.length,
832
+ total_items: providers.length,
833
+ total_pages: 1,
834
+ };
835
+ if (this.config.debug) {
836
+ (0, helpers_1.debugLog)('Listed LLM providers', {
837
+ count: providers.length,
838
+ page: pagination.page,
839
+ total_pages: pagination.total_pages,
840
+ });
841
+ }
842
+ return { providers, pagination };
843
+ }
844
+ /**
845
+ * Walk every page of LLM providers and return the combined list.
846
+ *
847
+ * Defaults to `page_size=100` (the server-side max) to minimise round
848
+ * trips. Per-page filters from `options.type` / `options.enabled` are
849
+ * honoured on every page; `options.page` / `options.page_size` are
850
+ * overridden by the walker.
851
+ *
852
+ * @param options - Optional `type` / `enabled` filters and `page_size`.
853
+ * @returns The full provider list across all pages.
854
+ */
855
+ async listAllProviders(options) {
856
+ const pageSize = options?.page_size ?? 100;
857
+ const all = [];
858
+ let page = 1;
859
+ while (true) {
860
+ const result = await this.listProvidersPaged({
861
+ type: options?.type,
862
+ enabled: options?.enabled,
863
+ page,
864
+ page_size: pageSize,
865
+ });
866
+ all.push(...result.providers);
867
+ if (result.pagination.total_pages <= page || result.providers.length === 0) {
868
+ break;
869
+ }
870
+ page += 1;
871
+ }
872
+ return all;
873
+ }
701
874
  /**
702
875
  * Install an MCP connector from the marketplace
703
876
  */
@@ -760,7 +933,7 @@ class AxonFlow {
760
933
  'Content-Type': 'application/json',
761
934
  ...this.getAuthHeaders(),
762
935
  };
763
- const response = await fetch(url, {
936
+ const response = await this._fetch(url, {
764
937
  method: 'POST',
765
938
  headers,
766
939
  body: JSON.stringify(agentRequest),
@@ -829,7 +1002,7 @@ class AxonFlow {
829
1002
  statement: options.statement.substring(0, 50),
830
1003
  });
831
1004
  }
832
- const response = await fetch(url, {
1005
+ const response = await this._fetch(url, {
833
1006
  method: 'POST',
834
1007
  headers,
835
1008
  body: JSON.stringify(body),
@@ -911,7 +1084,7 @@ class AxonFlow {
911
1084
  statement: options.statement.substring(0, 50),
912
1085
  });
913
1086
  }
914
- const response = await fetch(url, {
1087
+ const response = await this._fetch(url, {
915
1088
  method: 'POST',
916
1089
  headers,
917
1090
  body: JSON.stringify(body),
@@ -983,7 +1156,7 @@ class AxonFlow {
983
1156
  rowCount: options.rowCount,
984
1157
  });
985
1158
  }
986
- const response = await fetch(url, {
1159
+ const response = await this._fetch(url, {
987
1160
  method: 'POST',
988
1161
  headers,
989
1162
  body: JSON.stringify(body),
@@ -1055,7 +1228,7 @@ class AxonFlow {
1055
1228
  ...this.getAuthHeaders(),
1056
1229
  };
1057
1230
  // Use mapTimeout for MAP operations (default 2 minutes)
1058
- const response = await fetch(url, {
1231
+ const response = await this._fetch(url, {
1059
1232
  method: 'POST',
1060
1233
  headers,
1061
1234
  body: JSON.stringify(agentRequest),
@@ -1115,7 +1288,7 @@ class AxonFlow {
1115
1288
  ...this.getAuthHeaders(),
1116
1289
  };
1117
1290
  // Use mapTimeout for MAP operations (default 2 minutes)
1118
- const response = await fetch(url, {
1291
+ const response = await this._fetch(url, {
1119
1292
  method: 'POST',
1120
1293
  headers,
1121
1294
  body: JSON.stringify(agentRequest),
@@ -1170,7 +1343,7 @@ class AxonFlow {
1170
1343
  */
1171
1344
  async getPlanStatus(planId) {
1172
1345
  const url = `${this.config.endpoint}/api/v1/plan/${planId}`;
1173
- const response = await fetch(url, {
1346
+ const response = await this._fetch(url, {
1174
1347
  method: 'GET',
1175
1348
  signal: AbortSignal.timeout(this.config.timeout),
1176
1349
  });
@@ -1203,7 +1376,7 @@ class AxonFlow {
1203
1376
  if (reason) {
1204
1377
  body.reason = reason;
1205
1378
  }
1206
- const response = await fetch(url, {
1379
+ const response = await this._fetch(url, {
1207
1380
  method: 'POST',
1208
1381
  headers,
1209
1382
  body: JSON.stringify(body),
@@ -1252,7 +1425,7 @@ class AxonFlow {
1252
1425
  if (request.metadata !== undefined) {
1253
1426
  body.metadata = request.metadata;
1254
1427
  }
1255
- const response = await fetch(url, {
1428
+ const response = await this._fetch(url, {
1256
1429
  method: 'PUT',
1257
1430
  headers,
1258
1431
  body: JSON.stringify(body),
@@ -1286,7 +1459,7 @@ class AxonFlow {
1286
1459
  const headers = {
1287
1460
  ...this.getAuthHeaders(),
1288
1461
  };
1289
- const response = await fetch(url, {
1462
+ const response = await this._fetch(url, {
1290
1463
  method: 'GET',
1291
1464
  headers,
1292
1465
  signal: AbortSignal.timeout(this.config.timeout),
@@ -1319,7 +1492,7 @@ class AxonFlow {
1319
1492
  'Content-Type': 'application/json',
1320
1493
  ...this.getAuthHeaders(),
1321
1494
  };
1322
- const response = await fetch(url, {
1495
+ const response = await this._fetch(url, {
1323
1496
  method: 'POST',
1324
1497
  headers,
1325
1498
  body: JSON.stringify({ approved: approved ?? true }),
@@ -1413,7 +1586,7 @@ class AxonFlow {
1413
1586
  if (this.config.debug) {
1414
1587
  (0, helpers_1.debugLog)('Gateway Mode: Pre-check', { query: options.query.substring(0, 50) });
1415
1588
  }
1416
- const response = await fetch(url, {
1589
+ const response = await this._fetch(url, {
1417
1590
  method: 'POST',
1418
1591
  headers,
1419
1592
  body: JSON.stringify(requestBody),
@@ -1509,7 +1682,7 @@ class AxonFlow {
1509
1682
  model: options.model,
1510
1683
  });
1511
1684
  }
1512
- const response = await fetch(url, {
1685
+ const response = await this._fetch(url, {
1513
1686
  method: 'POST',
1514
1687
  headers,
1515
1688
  body: JSON.stringify(requestBody),
@@ -2102,7 +2275,7 @@ class AxonFlow {
2102
2275
  if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
2103
2276
  options.body = JSON.stringify(body);
2104
2277
  }
2105
- const response = await fetch(url, options);
2278
+ const response = await this._fetch(url, options);
2106
2279
  if (!response.ok) {
2107
2280
  const errorText = await response.text();
2108
2281
  if (response.status === 401 || response.status === 403) {
@@ -2658,7 +2831,7 @@ class AxonFlow {
2658
2831
  */
2659
2832
  async loginToPortal(orgId, password) {
2660
2833
  const url = `${this.config.endpoint}/api/v1/auth/login`;
2661
- const response = await fetch(url, {
2834
+ const response = await this._fetch(url, {
2662
2835
  method: 'POST',
2663
2836
  headers: { 'Content-Type': 'application/json' },
2664
2837
  body: JSON.stringify({ org_id: orgId, password }),
@@ -2700,7 +2873,7 @@ class AxonFlow {
2700
2873
  return;
2701
2874
  }
2702
2875
  try {
2703
- await fetch(`${this.config.endpoint}/api/v1/auth/logout`, {
2876
+ await this._fetch(`${this.config.endpoint}/api/v1/auth/logout`, {
2704
2877
  method: 'POST',
2705
2878
  headers: { Cookie: `axonflow_session=${this.sessionCookie}` },
2706
2879
  signal: AbortSignal.timeout(this.config.timeout),
@@ -3244,7 +3417,7 @@ class AxonFlow {
3244
3417
  if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
3245
3418
  options.body = JSON.stringify(body);
3246
3419
  }
3247
- const response = await fetch(url, options);
3420
+ const response = await this._fetch(url, options);
3248
3421
  if (!response.ok) {
3249
3422
  const errorText = await response.text();
3250
3423
  if (response.status === 401 || response.status === 403) {
@@ -3288,7 +3461,7 @@ class AxonFlow {
3288
3461
  if (this.config.debug) {
3289
3462
  (0, helpers_1.debugLog)('Portal request', { method, path });
3290
3463
  }
3291
- const response = await fetch(url, options);
3464
+ const response = await this._fetch(url, options);
3292
3465
  if (!response.ok) {
3293
3466
  const errorText = await response.text();
3294
3467
  if (response.status === 401 || response.status === 403) {
@@ -3900,7 +4073,7 @@ class AxonFlow {
3900
4073
  if (this.config.debug) {
3901
4074
  (0, helpers_1.debugLog)('Portal request (text)', { method, path });
3902
4075
  }
3903
- const response = await fetch(url, options);
4076
+ const response = await this._fetch(url, options);
3904
4077
  if (!response.ok) {
3905
4078
  const errorText = await response.text();
3906
4079
  if (response.status === 401 || response.status === 403) {
@@ -4343,7 +4516,7 @@ class AxonFlow {
4343
4516
  'Content-Type': 'application/json',
4344
4517
  ...this.getAuthHeaders(),
4345
4518
  };
4346
- const response = await fetch(url, {
4519
+ const response = await this._fetch(url, {
4347
4520
  method: 'POST',
4348
4521
  headers,
4349
4522
  body: JSON.stringify({}),
@@ -4532,7 +4705,7 @@ class AxonFlow {
4532
4705
  risk_rating_reliance: request.humanReliance,
4533
4706
  metadata: request.metadata,
4534
4707
  };
4535
- const response = await fetch(url, {
4708
+ const response = await this._fetch(url, {
4536
4709
  method: 'POST',
4537
4710
  headers: {
4538
4711
  'Content-Type': 'application/json',
@@ -4549,7 +4722,7 @@ class AxonFlow {
4549
4722
  }
4550
4723
  async masfeatGetSystem(systemId) {
4551
4724
  const url = `${this.config.endpoint}/api/v1/masfeat/registry/${systemId}`;
4552
- const response = await fetch(url, {
4725
+ const response = await this._fetch(url, {
4553
4726
  method: 'GET',
4554
4727
  headers: {
4555
4728
  ...this.getAuthHeaders(),
@@ -4583,7 +4756,7 @@ class AxonFlow {
4583
4756
  body.human_reliance = request.humanReliance;
4584
4757
  if (request.metadata !== undefined)
4585
4758
  body.metadata = request.metadata;
4586
- const response = await fetch(url, {
4759
+ const response = await this._fetch(url, {
4587
4760
  method: 'PUT',
4588
4761
  headers: {
4589
4762
  'Content-Type': 'application/json',
@@ -4612,7 +4785,7 @@ class AxonFlow {
4612
4785
  params.append('offset', options.offset.toString());
4613
4786
  const queryString = params.toString();
4614
4787
  const url = `${this.config.endpoint}/api/v1/masfeat/registry${queryString ? `?${queryString}` : ''}`;
4615
- const response = await fetch(url, {
4788
+ const response = await this._fetch(url, {
4616
4789
  method: 'GET',
4617
4790
  headers: {
4618
4791
  ...this.getAuthHeaders(),
@@ -4629,7 +4802,7 @@ class AxonFlow {
4629
4802
  async masfeatActivateSystem(systemId) {
4630
4803
  // Use PUT to update status - the /activate endpoint doesn't exist
4631
4804
  const url = `${this.config.endpoint}/api/v1/masfeat/registry/${systemId}`;
4632
- const response = await fetch(url, {
4805
+ const response = await this._fetch(url, {
4633
4806
  method: 'PUT',
4634
4807
  headers: {
4635
4808
  'Content-Type': 'application/json',
@@ -4646,7 +4819,7 @@ class AxonFlow {
4646
4819
  }
4647
4820
  async masfeatRetireSystem(systemId) {
4648
4821
  const url = `${this.config.endpoint}/api/v1/masfeat/registry/${systemId}`;
4649
- const response = await fetch(url, {
4822
+ const response = await this._fetch(url, {
4650
4823
  method: 'DELETE',
4651
4824
  headers: {
4652
4825
  ...this.getAuthHeaders(),
@@ -4661,7 +4834,7 @@ class AxonFlow {
4661
4834
  }
4662
4835
  async masfeatGetRegistrySummary() {
4663
4836
  const url = `${this.config.endpoint}/api/v1/masfeat/registry/summary`;
4664
- const response = await fetch(url, {
4837
+ const response = await this._fetch(url, {
4665
4838
  method: 'GET',
4666
4839
  headers: {
4667
4840
  ...this.getAuthHeaders(),
@@ -4723,7 +4896,7 @@ class AxonFlow {
4723
4896
  due_date: f.dueDate?.toISOString(),
4724
4897
  }));
4725
4898
  }
4726
- const response = await fetch(url, {
4899
+ const response = await this._fetch(url, {
4727
4900
  method: 'POST',
4728
4901
  headers: {
4729
4902
  'Content-Type': 'application/json',
@@ -4740,7 +4913,7 @@ class AxonFlow {
4740
4913
  }
4741
4914
  async masfeatGetAssessment(assessmentId) {
4742
4915
  const url = `${this.config.endpoint}/api/v1/masfeat/assessments/${assessmentId}`;
4743
- const response = await fetch(url, {
4916
+ const response = await this._fetch(url, {
4744
4917
  method: 'GET',
4745
4918
  headers: {
4746
4919
  ...this.getAuthHeaders(),
@@ -4788,7 +4961,7 @@ class AxonFlow {
4788
4961
  body.recommendations = request.recommendations;
4789
4962
  if (request.assessors !== undefined)
4790
4963
  body.assessors = request.assessors;
4791
- const response = await fetch(url, {
4964
+ const response = await this._fetch(url, {
4792
4965
  method: 'PUT',
4793
4966
  headers: {
4794
4967
  'Content-Type': 'application/json',
@@ -4815,7 +4988,7 @@ class AxonFlow {
4815
4988
  params.append('offset', options.offset.toString());
4816
4989
  const queryString = params.toString();
4817
4990
  const url = `${this.config.endpoint}/api/v1/masfeat/assessments${queryString ? `?${queryString}` : ''}`;
4818
- const response = await fetch(url, {
4991
+ const response = await this._fetch(url, {
4819
4992
  method: 'GET',
4820
4993
  headers: {
4821
4994
  ...this.getAuthHeaders(),
@@ -4831,7 +5004,7 @@ class AxonFlow {
4831
5004
  }
4832
5005
  async masfeatSubmitAssessment(assessmentId) {
4833
5006
  const url = `${this.config.endpoint}/api/v1/masfeat/assessments/${assessmentId}/submit`;
4834
- const response = await fetch(url, {
5007
+ const response = await this._fetch(url, {
4835
5008
  method: 'POST',
4836
5009
  headers: {
4837
5010
  'Content-Type': 'application/json',
@@ -4847,7 +5020,7 @@ class AxonFlow {
4847
5020
  }
4848
5021
  async masfeatApproveAssessment(assessmentId, request) {
4849
5022
  const url = `${this.config.endpoint}/api/v1/masfeat/assessments/${assessmentId}/approve`;
4850
- const response = await fetch(url, {
5023
+ const response = await this._fetch(url, {
4851
5024
  method: 'POST',
4852
5025
  headers: {
4853
5026
  'Content-Type': 'application/json',
@@ -4867,7 +5040,7 @@ class AxonFlow {
4867
5040
  }
4868
5041
  async masfeatRejectAssessment(assessmentId, request) {
4869
5042
  const url = `${this.config.endpoint}/api/v1/masfeat/assessments/${assessmentId}/reject`;
4870
- const response = await fetch(url, {
5043
+ const response = await this._fetch(url, {
4871
5044
  method: 'POST',
4872
5045
  headers: {
4873
5046
  'Content-Type': 'application/json',
@@ -4888,7 +5061,7 @@ class AxonFlow {
4888
5061
  // Kill Switch Methods
4889
5062
  async masfeatGetKillSwitch(systemId) {
4890
5063
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}`;
4891
- const response = await fetch(url, {
5064
+ const response = await this._fetch(url, {
4892
5065
  method: 'GET',
4893
5066
  headers: {
4894
5067
  ...this.getAuthHeaders(),
@@ -4912,7 +5085,7 @@ class AxonFlow {
4912
5085
  body.error_rate_threshold = request.errorRateThreshold;
4913
5086
  if (request.autoTriggerEnabled !== undefined)
4914
5087
  body.auto_trigger_enabled = request.autoTriggerEnabled;
4915
- const response = await fetch(url, {
5088
+ const response = await this._fetch(url, {
4916
5089
  method: 'POST',
4917
5090
  headers: {
4918
5091
  'Content-Type': 'application/json',
@@ -4929,7 +5102,7 @@ class AxonFlow {
4929
5102
  }
4930
5103
  async masfeatCheckKillSwitch(systemId, request) {
4931
5104
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/check`;
4932
- const response = await fetch(url, {
5105
+ const response = await this._fetch(url, {
4933
5106
  method: 'POST',
4934
5107
  headers: {
4935
5108
  'Content-Type': 'application/json',
@@ -4950,7 +5123,7 @@ class AxonFlow {
4950
5123
  }
4951
5124
  async masfeatTriggerKillSwitch(systemId, request) {
4952
5125
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/trigger`;
4953
- const response = await fetch(url, {
5126
+ const response = await this._fetch(url, {
4954
5127
  method: 'POST',
4955
5128
  headers: {
4956
5129
  'Content-Type': 'application/json',
@@ -4970,7 +5143,7 @@ class AxonFlow {
4970
5143
  }
4971
5144
  async masfeatRestoreKillSwitch(systemId, request) {
4972
5145
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/restore`;
4973
- const response = await fetch(url, {
5146
+ const response = await this._fetch(url, {
4974
5147
  method: 'POST',
4975
5148
  headers: {
4976
5149
  'Content-Type': 'application/json',
@@ -4990,7 +5163,7 @@ class AxonFlow {
4990
5163
  }
4991
5164
  async masfeatEnableKillSwitch(systemId) {
4992
5165
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/enable`;
4993
- const response = await fetch(url, {
5166
+ const response = await this._fetch(url, {
4994
5167
  method: 'POST',
4995
5168
  headers: {
4996
5169
  'Content-Type': 'application/json',
@@ -5006,7 +5179,7 @@ class AxonFlow {
5006
5179
  }
5007
5180
  async masfeatDisableKillSwitch(systemId, request) {
5008
5181
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/disable`;
5009
- const response = await fetch(url, {
5182
+ const response = await this._fetch(url, {
5010
5183
  method: 'POST',
5011
5184
  headers: {
5012
5185
  'Content-Type': 'application/json',
@@ -5027,7 +5200,7 @@ class AxonFlow {
5027
5200
  params.append('limit', limit.toString());
5028
5201
  const queryString = params.toString();
5029
5202
  const url = `${this.config.endpoint}/api/v1/masfeat/killswitch/${systemId}/history${queryString ? `?${queryString}` : ''}`;
5030
- const response = await fetch(url, {
5203
+ const response = await this._fetch(url, {
5031
5204
  method: 'GET',
5032
5205
  headers: {
5033
5206
  ...this.getAuthHeaders(),
@@ -5583,7 +5756,7 @@ class AxonFlow {
5583
5756
  }
5584
5757
  let response;
5585
5758
  try {
5586
- response = await fetch(url, fetchOptions);
5759
+ response = await this._fetch(url, fetchOptions);
5587
5760
  }
5588
5761
  catch (error) {
5589
5762
  if (error instanceof Error && error.name === 'AbortError') {