@cadraos/sdk 0.3.5 → 0.3.7

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.
@@ -307,7 +307,8 @@ var HttpClient = class {
307
307
  const controller = new AbortController();
308
308
  const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
309
309
  try {
310
- const response = await fetch(url, {
310
+ const doFetch = this.config.fetch ?? fetch;
311
+ const response = await doFetch(url, {
311
312
  method: options.method,
312
313
  headers,
313
314
  body: options.body !== void 0 ? JSON.stringify(options.body) : void 0,
@@ -439,7 +440,8 @@ var SSEClient = class {
439
440
  console.log("[SDK:SSE] Auth header:", this.config.authHeader ? `${this.config.authHeader.substring(0, 30)}...` : "MISSING");
440
441
  console.log("[SDK:SSE] Org ID:", this.config.orgId);
441
442
  try {
442
- const response = await fetch(this.config.url, {
443
+ const doFetch = this.config.fetch ?? fetch;
444
+ const response = await doFetch(this.config.url, {
443
445
  method: "GET",
444
446
  headers: {
445
447
  "Authorization": this.config.authHeader,
@@ -687,6 +689,15 @@ var ExecutionStreamControllerImpl = class {
687
689
  sseClient = null;
688
690
  status = "connecting";
689
691
  reconnectAttempts = 0;
692
+ // CAD-39 / webchat dual-plane create-connect race. `hasConnected` flips true on
693
+ // the first successful SSE open; `notFoundRetries` bounds retries of a 404
694
+ // encountered BEFORE we ever connect (the run row is persisted slightly AFTER
695
+ // the client opens the stream — the norm on the webchat path where msg-api owns
696
+ // the executionId and cadra persists the agent_executions row via an async
697
+ // worker callback). See handleConnectionError.
698
+ hasConnected = false;
699
+ notFoundRetries = 0;
700
+ maxConnectRaceRetries = 3;
690
701
  seenEventIds = /* @__PURE__ */ new Set();
691
702
  _lastEventId = null;
692
703
  activityTimeoutId = null;
@@ -815,6 +826,7 @@ var ExecutionStreamControllerImpl = class {
815
826
  url,
816
827
  authHeader: `Bearer ${authToken}`,
817
828
  orgId: this.options.orgId,
829
+ fetch: this.options.fetch,
818
830
  onEvent: (event) => this.handleEvent(event),
819
831
  onError: (error) => {
820
832
  console.error("[SDK:StreamController] SSE error:", error);
@@ -825,6 +837,8 @@ var ExecutionStreamControllerImpl = class {
825
837
  if (connected) {
826
838
  this.status = "connected";
827
839
  this.reconnectAttempts = 0;
840
+ this.hasConnected = true;
841
+ this.notFoundRetries = 0;
828
842
  this.resetActivityTimeout();
829
843
  }
830
844
  this.emit("connectionChange", { connected, usingFallback: false });
@@ -1114,6 +1128,38 @@ var ExecutionStreamControllerImpl = class {
1114
1128
  return;
1115
1129
  }
1116
1130
  const msg = error instanceof Error ? error.message : String(error);
1131
+ const isNotFound = /\b404\b/.test(msg);
1132
+ const isAuthFailure = /\b40[13]\b/.test(msg) || /INVALID_API_KEY|INVALID_REQUEST/.test(msg);
1133
+ if (isNotFound && !isAuthFailure && !this.hasConnected) {
1134
+ if (this.notFoundRetries < this.maxConnectRaceRetries) {
1135
+ this.notFoundRetries++;
1136
+ this.status = "reconnecting";
1137
+ const delay = Math.min(
1138
+ this.config.reconnectBaseDelayMs * this.notFoundRetries,
1139
+ this.config.reconnectMaxDelayMs
1140
+ );
1141
+ await new Promise((resolve) => setTimeout(resolve, delay));
1142
+ if (this.status === "closed") {
1143
+ return;
1144
+ }
1145
+ try {
1146
+ await this.connectSSE();
1147
+ } catch (retryError) {
1148
+ await this.handleConnectionError(retryError);
1149
+ }
1150
+ return;
1151
+ }
1152
+ if (this.pollingEnabled) {
1153
+ if (this.sseClient) {
1154
+ this.sseClient.disconnect();
1155
+ this.sseClient = null;
1156
+ }
1157
+ this.status = "fallback_polling";
1158
+ this.emit("connectionChange", { connected: false, usingFallback: true });
1159
+ this.startPolling();
1160
+ return;
1161
+ }
1162
+ }
1117
1163
  if (/\b4\d\d\b/.test(msg) || /INVALID_API_KEY|INVALID_REQUEST/.test(msg)) {
1118
1164
  if (this.sseClient) {
1119
1165
  this.sseClient.disconnect();
@@ -1492,6 +1538,7 @@ var AgentsAPI = class extends BaseResourceAPI {
1492
1538
  apiKey: config.apiKey,
1493
1539
  tokenProvider: config.tokenProvider,
1494
1540
  orgId: config.orgId,
1541
+ fetch: config.fetch,
1495
1542
  getExecution: (id) => this.getExecution(id)
1496
1543
  });
1497
1544
  console.log("[SDK:Agents] Stream controller created - caller must call connect() after registering listeners");
@@ -1538,6 +1585,7 @@ var AgentsAPI = class extends BaseResourceAPI {
1538
1585
  apiKey: config.apiKey,
1539
1586
  tokenProvider: config.tokenProvider,
1540
1587
  orgId: config.orgId,
1588
+ fetch: config.fetch,
1541
1589
  getExecution: (id) => this.getExecution(id)
1542
1590
  });
1543
1591
  console.log("[SDK:Agents] Stream controller created for existing execution - caller must call connect() after registering listeners");
@@ -2386,6 +2434,7 @@ var SessionsAPI = class extends BaseResourceAPI {
2386
2434
  baseUrl: config.baseUrl,
2387
2435
  apiKey: config.apiKey,
2388
2436
  orgId: config.orgId,
2437
+ fetch: config.fetch,
2389
2438
  getExecution: (id) => this.getExecution(id)
2390
2439
  });
2391
2440
  await controller.connect();
@@ -3040,7 +3089,8 @@ var CadraClient = class {
3040
3089
  baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
3041
3090
  orgId: options.orgId,
3042
3091
  timeout: options.timeout ?? DEFAULT_TIMEOUT,
3043
- headers: options.headers
3092
+ headers: options.headers,
3093
+ fetch: options.fetch
3044
3094
  };
3045
3095
  if ("apiKey" in options) {
3046
3096
  this.config.apiKey = options.apiKey;
@@ -3061,7 +3111,8 @@ var CadraClient = class {
3061
3111
  orgId: this.config.orgId,
3062
3112
  timeout: this.config.timeout,
3063
3113
  retry: retryConfig,
3064
- headers: this.config.headers
3114
+ headers: this.config.headers,
3115
+ fetch: this.config.fetch
3065
3116
  };
3066
3117
  this.httpClient = new HttpClient(httpConfig);
3067
3118
  const getStreamConfig = () => ({
@@ -3069,7 +3120,8 @@ var CadraClient = class {
3069
3120
  apiKey: this.config.apiKey,
3070
3121
  token: this.config.token,
3071
3122
  tokenProvider: this.config.tokenProvider,
3072
- orgId: this.config.orgId
3123
+ orgId: this.config.orgId,
3124
+ fetch: this.config.fetch
3073
3125
  });
3074
3126
  this.agents = new AgentsAPI(this.httpClient, getStreamConfig);
3075
3127
  this.skills = new SkillsAPI(this.httpClient);