@cadraos/sdk 0.1.10 → 0.1.12

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
@@ -54,7 +54,7 @@ var BaseResourceAPI = class {
54
54
  };
55
55
 
56
56
  // src/errors/sdk-errors.ts
57
- var AISaaSError = class extends Error {
57
+ var CadraError = class extends Error {
58
58
  /** Error code */
59
59
  code;
60
60
  /** HTTP status code */
@@ -65,7 +65,7 @@ var AISaaSError = class extends Error {
65
65
  requestId;
66
66
  constructor(message, code, status, details, requestId) {
67
67
  super(message);
68
- this.name = "AISaaSError";
68
+ this.name = "CadraError";
69
69
  this.code = code;
70
70
  this.status = status;
71
71
  this.details = details;
@@ -75,25 +75,25 @@ var AISaaSError = class extends Error {
75
75
  }
76
76
  }
77
77
  };
78
- var AuthenticationError = class extends AISaaSError {
78
+ var AuthenticationError = class extends CadraError {
79
79
  constructor(message = "Authentication failed", code = "authentication_error", details, requestId) {
80
80
  super(message, code, 401, details, requestId);
81
81
  this.name = "AuthenticationError";
82
82
  }
83
83
  };
84
- var AuthorizationError = class extends AISaaSError {
84
+ var AuthorizationError = class extends CadraError {
85
85
  constructor(message = "Access denied", code = "authorization_error", details, requestId) {
86
86
  super(message, code, 403, details, requestId);
87
87
  this.name = "AuthorizationError";
88
88
  }
89
89
  };
90
- var NotFoundError = class extends AISaaSError {
90
+ var NotFoundError = class extends CadraError {
91
91
  constructor(message = "Resource not found", code = "not_found", details, requestId) {
92
92
  super(message, code, 404, details, requestId);
93
93
  this.name = "NotFoundError";
94
94
  }
95
95
  };
96
- var ValidationError = class extends AISaaSError {
96
+ var ValidationError = class extends CadraError {
97
97
  /** Field-level validation errors */
98
98
  errors;
99
99
  constructor(message = "Validation failed", errors = [], details, requestId) {
@@ -102,7 +102,7 @@ var ValidationError = class extends AISaaSError {
102
102
  this.errors = errors;
103
103
  }
104
104
  };
105
- var RateLimitError = class extends AISaaSError {
105
+ var RateLimitError = class extends CadraError {
106
106
  /** Seconds until rate limit resets */
107
107
  retryAfter;
108
108
  constructor(message = "Rate limit exceeded", retryAfter, details, requestId) {
@@ -111,25 +111,25 @@ var RateLimitError = class extends AISaaSError {
111
111
  this.retryAfter = retryAfter;
112
112
  }
113
113
  };
114
- var ServerError = class extends AISaaSError {
114
+ var ServerError = class extends CadraError {
115
115
  constructor(message = "Server error", status = 500, details, requestId) {
116
116
  super(message, "server_error", status, details, requestId);
117
117
  this.name = "ServerError";
118
118
  }
119
119
  };
120
- var ConflictError = class extends AISaaSError {
120
+ var ConflictError = class extends CadraError {
121
121
  constructor(message = "Resource conflict", details, requestId) {
122
122
  super(message, "conflict", 409, details, requestId);
123
123
  this.name = "ConflictError";
124
124
  }
125
125
  };
126
- var TimeoutError = class extends AISaaSError {
126
+ var TimeoutError = class extends CadraError {
127
127
  constructor(message = "Request timed out", details, requestId) {
128
128
  super(message, "timeout", 408, details, requestId);
129
129
  this.name = "TimeoutError";
130
130
  }
131
131
  };
132
- var NetworkError = class extends AISaaSError {
132
+ var NetworkError = class extends CadraError {
133
133
  constructor(message = "Network error", details) {
134
134
  super(message, "network_error", 0, details);
135
135
  this.name = "NetworkError";
@@ -171,7 +171,7 @@ function parseApiError(status, body, requestId) {
171
171
  if (status >= 500) {
172
172
  return new ServerError(message, status, details, requestId);
173
173
  }
174
- return new AISaaSError(message, code, status, details, requestId);
174
+ return new CadraError(message, code, status, details, requestId);
175
175
  }
176
176
  }
177
177
 
@@ -259,15 +259,21 @@ var HttpClient = class {
259
259
  * Build full URL with query parameters
260
260
  */
261
261
  buildUrl(path, query) {
262
- const url = new URL(path, this.config.baseUrl);
262
+ const base = this.config.baseUrl.replace(/\/+$/, "");
263
+ let url = `${base}${path}`;
263
264
  if (query) {
265
+ const params = new URLSearchParams();
264
266
  for (const [key, value] of Object.entries(query)) {
265
267
  if (value !== void 0) {
266
- url.searchParams.set(key, String(value));
268
+ params.set(key, String(value));
267
269
  }
268
270
  }
271
+ const qs = params.toString();
272
+ if (qs) {
273
+ url += `?${qs}`;
274
+ }
269
275
  }
270
- return url.toString();
276
+ return url;
271
277
  }
272
278
  /**
273
279
  * Make an HTTP request
@@ -571,9 +577,11 @@ var DEFAULT_STREAMING_CONFIG = {
571
577
  activityTimeoutMs: 3e4,
572
578
  pollingIntervalMs: 2e3
573
579
  };
580
+ var DEFAULT_POLLING_ENABLED = true;
574
581
  var ExecutionStreamControllerImpl = class {
575
582
  options;
576
583
  config;
584
+ pollingEnabled;
577
585
  sseClient = null;
578
586
  status = "connecting";
579
587
  reconnectAttempts = 0;
@@ -607,6 +615,7 @@ var ExecutionStreamControllerImpl = class {
607
615
  constructor(options) {
608
616
  this.options = options;
609
617
  this.config = { ...DEFAULT_STREAMING_CONFIG, ...options.config };
618
+ this.pollingEnabled = options.pollingEnabled ?? DEFAULT_POLLING_ENABLED;
610
619
  }
611
620
  /**
612
621
  * Get the last event ID (for resume support)
@@ -667,7 +676,7 @@ var ExecutionStreamControllerImpl = class {
667
676
  return Promise.resolve(this.finalExecution);
668
677
  }
669
678
  if (this.finalError) {
670
- return Promise.reject(new AISaaSError(
679
+ return Promise.reject(new CadraError(
671
680
  this.finalError.error,
672
681
  this.finalError.errorCode ?? "execution_error",
673
682
  500
@@ -686,7 +695,8 @@ var ExecutionStreamControllerImpl = class {
686
695
  * Connect to SSE endpoint
687
696
  */
688
697
  async connectSSE() {
689
- const url = `${this.options.baseUrl}/agents/runs/${this.options.executionId}/stream`;
698
+ const base = this.options.baseUrl.replace(/\/+$/, "");
699
+ const url = `${base}/api/v1/agents/runs/${this.options.executionId}/stream`;
690
700
  let authToken = this.options.apiKey;
691
701
  if (!authToken && this.options.tokenProvider) {
692
702
  authToken = await this.options.tokenProvider();
@@ -921,7 +931,7 @@ var ExecutionStreamControllerImpl = class {
921
931
  this.finalError = error;
922
932
  this.emit("error", error);
923
933
  if (this.waitReject) {
924
- this.waitReject(new AISaaSError(
934
+ this.waitReject(new CadraError(
925
935
  error.error,
926
936
  error.errorCode ?? "execution_error",
927
937
  500
@@ -946,15 +956,61 @@ var ExecutionStreamControllerImpl = class {
946
956
  if (this.status === "closed") {
947
957
  return;
948
958
  }
959
+ await this.recoverState();
960
+ if (this.status === "closed") {
961
+ return;
962
+ }
949
963
  try {
950
964
  await this.connectSSE();
951
965
  } catch {
952
966
  await this.handleConnectionError(error);
953
967
  }
954
968
  } else {
955
- this.status = "fallback_polling";
956
- this.emit("connectionChange", { connected: false, usingFallback: true });
957
- this.startPolling();
969
+ if (this.pollingEnabled) {
970
+ this.status = "fallback_polling";
971
+ this.emit("connectionChange", { connected: false, usingFallback: true });
972
+ this.startPolling();
973
+ } else {
974
+ this.handleError({
975
+ error: "SSE connection failed and polling is disabled",
976
+ errorCode: "connection_failed"
977
+ });
978
+ }
979
+ }
980
+ }
981
+ /**
982
+ * Recover state by checking execution status.
983
+ *
984
+ * Called during reconnection to catch any events missed while SSE was down.
985
+ * If the execution completed while disconnected, emits completion immediately.
986
+ * Otherwise, emits any new logs that weren't seen via SSE.
987
+ */
988
+ async recoverState() {
989
+ try {
990
+ const execution = await this.options.getExecution(this.options.executionId);
991
+ if (execution.logs) {
992
+ for (const log of execution.logs) {
993
+ if (!this.seenEventIds.has(log.uuid)) {
994
+ this.seenEventIds.add(log.uuid);
995
+ this.emit("log", log);
996
+ }
997
+ }
998
+ }
999
+ if (execution.status === "completed") {
1000
+ this.stopPolling();
1001
+ this.handleComplete(execution);
1002
+ return;
1003
+ }
1004
+ if (execution.status === "failed" || execution.status === "cancelled") {
1005
+ this.stopPolling();
1006
+ this.handleError({
1007
+ error: execution.error ?? `Execution ${execution.status}`,
1008
+ errorCode: execution.status
1009
+ });
1010
+ return;
1011
+ }
1012
+ } catch (err) {
1013
+ console.warn("[SDK:StreamController] State recovery failed (non-fatal):", err);
958
1014
  }
959
1015
  }
960
1016
  /**
@@ -1039,7 +1095,7 @@ function createExecutionStreamController(options) {
1039
1095
  // src/resources/agents.ts
1040
1096
  var AgentsAPI = class extends BaseResourceAPI {
1041
1097
  constructor(http, getStreamConfig) {
1042
- super(http, "/agents");
1098
+ super(http, "/api/v1/agents");
1043
1099
  this.getStreamConfig = getStreamConfig;
1044
1100
  }
1045
1101
  // ===== LIST Operations =====
@@ -1315,7 +1371,7 @@ var AgentsAPI = class extends BaseResourceAPI {
1315
1371
  // src/resources/skills.ts
1316
1372
  var SkillsAPI = class extends BaseResourceAPI {
1317
1373
  constructor(http) {
1318
- super(http, "/skills");
1374
+ super(http, "/api/v1/skills");
1319
1375
  }
1320
1376
  // ===== LIST Operations =====
1321
1377
  /**
@@ -1459,7 +1515,7 @@ var SkillsAPI = class extends BaseResourceAPI {
1459
1515
  // src/resources/tools.ts
1460
1516
  var ToolsAPI = class extends BaseResourceAPI {
1461
1517
  constructor(http) {
1462
- super(http, "/tools");
1518
+ super(http, "/api/v1/tools");
1463
1519
  }
1464
1520
  // ===== LIST Operations =====
1465
1521
  /**
@@ -1622,7 +1678,7 @@ var ToolsAPI = class extends BaseResourceAPI {
1622
1678
  // src/resources/artifacts.ts
1623
1679
  var ArtifactsAPI = class extends BaseResourceAPI {
1624
1680
  constructor(http) {
1625
- super(http, "/artifacts");
1681
+ super(http, "/api/v1/artifacts");
1626
1682
  }
1627
1683
  // ===== LIST Operations =====
1628
1684
  /**
@@ -1818,7 +1874,7 @@ var ArtifactsAPI = class extends BaseResourceAPI {
1818
1874
  // src/resources/sessions.ts
1819
1875
  var SessionsAPI = class extends BaseResourceAPI {
1820
1876
  constructor(http, getStreamConfig) {
1821
- super(http, "/sessions");
1877
+ super(http, "/api/v1/sessions");
1822
1878
  this.getStreamConfig = getStreamConfig;
1823
1879
  }
1824
1880
  // ===== LIST Operations =====
@@ -2049,9 +2105,9 @@ var SessionsAPI = class extends BaseResourceAPI {
2049
2105
  };
2050
2106
 
2051
2107
  // src/client.ts
2052
- var DEFAULT_BASE_URL = "https://api.aisaas.com/v1";
2108
+ var DEFAULT_BASE_URL = "https://api.cadraos.com";
2053
2109
  var DEFAULT_TIMEOUT = 3e4;
2054
- var AISaaSClient = class {
2110
+ var CadraClient = class {
2055
2111
  httpClient;
2056
2112
  config;
2057
2113
  /**
@@ -2082,19 +2138,19 @@ var AISaaSClient = class {
2082
2138
  * @example
2083
2139
  * ```typescript
2084
2140
  * // API key authentication
2085
- * const client = new AISaaSClient({
2141
+ * const client = new CadraClient({
2086
2142
  * apiKey: 'sk_...',
2087
2143
  * orgId: 123,
2088
2144
  * });
2089
2145
  *
2090
2146
  * // OAuth token authentication
2091
- * const client = new AISaaSClient({
2147
+ * const client = new CadraClient({
2092
2148
  * token: 'eyJ...',
2093
2149
  * orgId: 123,
2094
2150
  * });
2095
2151
  *
2096
2152
  * // Token provider (for automatic refresh)
2097
- * const client = new AISaaSClient({
2153
+ * const client = new CadraClient({
2098
2154
  * tokenProvider: async () => myAuth.getAccessToken(),
2099
2155
  * orgId: 123,
2100
2156
  * });
@@ -2102,6 +2158,19 @@ var AISaaSClient = class {
2102
2158
  */
2103
2159
  constructor(options) {
2104
2160
  this.validateOptions(options);
2161
+ if (options.baseUrl) {
2162
+ try {
2163
+ const parsed = new URL(options.baseUrl);
2164
+ if (/\/(api|v\d)/.test(parsed.pathname)) {
2165
+ if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
2166
+ console.warn(
2167
+ `[CadraOS SDK] baseUrl should be the origin only (e.g., "https://api.cadraos.com" or "http://localhost:3000"). The SDK automatically prepends "/api/v1/" to all requests. Received: "${options.baseUrl}"`
2168
+ );
2169
+ }
2170
+ }
2171
+ } catch {
2172
+ }
2173
+ }
2105
2174
  this.config = {
2106
2175
  baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
2107
2176
  orgId: options.orgId,
@@ -2164,10 +2233,12 @@ var AISaaSClient = class {
2164
2233
  }
2165
2234
  };
2166
2235
 
2167
- exports.AISaaSClient = AISaaSClient;
2168
- exports.AISaaSError = AISaaSError;
2236
+ exports.AISaaSClient = CadraClient;
2237
+ exports.AISaaSError = CadraError;
2169
2238
  exports.AuthenticationError = AuthenticationError;
2170
2239
  exports.AuthorizationError = AuthorizationError;
2240
+ exports.CadraClient = CadraClient;
2241
+ exports.CadraError = CadraError;
2171
2242
  exports.ConflictError = ConflictError;
2172
2243
  exports.NetworkError = NetworkError;
2173
2244
  exports.NotFoundError = NotFoundError;