@cadraos/sdk 0.3.14-p46.4 → 0.3.15

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 (38) hide show
  1. package/README.md +104 -53
  2. package/dist/ai-functions/react/index.cjs +176 -0
  3. package/dist/ai-functions/react/index.cjs.map +1 -0
  4. package/dist/ai-functions/react/index.d.cts +129 -0
  5. package/dist/ai-functions/react/index.d.ts +129 -0
  6. package/dist/ai-functions/react/index.js +153 -0
  7. package/dist/ai-functions/react/index.js.map +1 -0
  8. package/dist/ai-functions/server/index.cjs +296 -0
  9. package/dist/ai-functions/server/index.cjs.map +1 -0
  10. package/dist/ai-functions/server/index.d.cts +334 -0
  11. package/dist/ai-functions/server/index.d.ts +334 -0
  12. package/dist/ai-functions/server/index.js +284 -0
  13. package/dist/ai-functions/server/index.js.map +1 -0
  14. package/dist/chat/index.cjs +303 -17
  15. package/dist/chat/index.cjs.map +1 -1
  16. package/dist/chat/index.d.cts +211 -0
  17. package/dist/chat/index.d.ts +211 -0
  18. package/dist/chat/index.js +303 -17
  19. package/dist/chat/index.js.map +1 -1
  20. package/dist/index.cjs +225 -3
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +279 -1
  23. package/dist/index.d.ts +279 -1
  24. package/dist/index.js +219 -4
  25. package/dist/index.js.map +1 -1
  26. package/dist/kanban/index.cjs +218 -3
  27. package/dist/kanban/index.cjs.map +1 -1
  28. package/dist/kanban/index.d.cts +211 -0
  29. package/dist/kanban/index.d.ts +211 -0
  30. package/dist/kanban/index.js +218 -3
  31. package/dist/kanban/index.js.map +1 -1
  32. package/dist/teams/index.cjs +218 -3
  33. package/dist/teams/index.cjs.map +1 -1
  34. package/dist/teams/index.d.cts +211 -0
  35. package/dist/teams/index.d.ts +211 -0
  36. package/dist/teams/index.js +218 -3
  37. package/dist/teams/index.js.map +1 -1
  38. package/package.json +21 -1
@@ -3665,6 +3665,14 @@ var CadraError = class extends Error {
3665
3665
  details;
3666
3666
  /** Request ID from server (for debugging) */
3667
3667
  requestId;
3668
+ /**
3669
+ * The server's own `error.code` exactly as sent on the wire (e.g.
3670
+ * `FUNCTION_NOT_PUBLISHED`, `DUPLICATE_REQUEST`, `VARIABLE_TYPE`).
3671
+ * Populated by `parseApiError` for EVERY status. `code` keeps its historic
3672
+ * per-class values (`conflict`, `server_error`, `validation_error`, …) for
3673
+ * compatibility; branch on `serverCode` when you need the precise reason.
3674
+ */
3675
+ serverCode;
3668
3676
  constructor(message, code, status, details, requestId) {
3669
3677
  super(message);
3670
3678
  this.name = "CadraError";
@@ -3742,6 +3750,12 @@ function parseApiError(status, body, requestId) {
3742
3750
  const message = errorBody?.error?.message ?? "An error occurred";
3743
3751
  const code = errorBody?.error?.code ?? "unknown_error";
3744
3752
  const details = errorBody?.error?.details;
3753
+ const serverCode = typeof errorBody?.error?.code === "string" ? errorBody.error.code : void 0;
3754
+ const error = buildApiError(status, message, code, details, requestId);
3755
+ if (serverCode !== void 0) error.serverCode = serverCode;
3756
+ return error;
3757
+ }
3758
+ function buildApiError(status, message, code, details, requestId) {
3745
3759
  switch (status) {
3746
3760
  case 400:
3747
3761
  case 422: {
@@ -3777,6 +3791,42 @@ function parseApiError(status, body, requestId) {
3777
3791
  }
3778
3792
  }
3779
3793
 
3794
+ // src/errors/ai-function-errors.ts
3795
+ var AiFunctionDuplicateError = class extends ConflictError {
3796
+ /** The existing run's execution id. */
3797
+ executionId;
3798
+ /** The existing run's status (`running`, a terminal status, or `abandoned`). */
3799
+ runStatus;
3800
+ constructor(message, details, requestId) {
3801
+ super(message, details, requestId);
3802
+ this.name = "AiFunctionDuplicateError";
3803
+ this.serverCode = "DUPLICATE_REQUEST";
3804
+ this.executionId = typeof details?.executionId === "string" ? details.executionId : void 0;
3805
+ this.runStatus = typeof details?.status === "string" ? details.status : void 0;
3806
+ }
3807
+ };
3808
+ var AiFunctionChargedError = class extends CadraError {
3809
+ constructor(source) {
3810
+ super(source.message, source.code, source.status, source.details, source.requestId);
3811
+ this.name = "AiFunctionChargedError";
3812
+ this.serverCode = source.serverCode;
3813
+ }
3814
+ };
3815
+ var AiFunctionParameterError = class extends ValidationError {
3816
+ functionKey;
3817
+ issues;
3818
+ constructor(functionKey, issues) {
3819
+ super(
3820
+ `Invalid parameters for AI function "${functionKey}": ` + issues.map((i) => `${i.name} (${i.code})`).join(", "),
3821
+ issues.map((i) => ({ field: i.name, message: i.code })),
3822
+ { functionKey, issues }
3823
+ );
3824
+ this.name = "AiFunctionParameterError";
3825
+ this.functionKey = functionKey;
3826
+ this.issues = issues;
3827
+ }
3828
+ };
3829
+
3780
3830
  // src/utils/retry.ts
3781
3831
  var DEFAULT_RETRY_CONFIG = {
3782
3832
  maxRetries: 3,
@@ -3841,6 +3891,10 @@ var HttpClient = class {
3841
3891
  constructor(config) {
3842
3892
  this.config = config;
3843
3893
  }
3894
+ /** The client-wide request timeout (ms) this client was configured with. */
3895
+ get timeoutMs() {
3896
+ return this.config.timeout;
3897
+ }
3844
3898
  /**
3845
3899
  * Get authorization header value
3846
3900
  */
@@ -3895,7 +3949,8 @@ var HttpClient = class {
3895
3949
  headers["Idempotency-Key"] = options.idempotencyKey;
3896
3950
  }
3897
3951
  const controller = new AbortController();
3898
- const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
3952
+ const timeoutMs = options.timeoutMs ?? this.config.timeout;
3953
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
3899
3954
  try {
3900
3955
  const doFetch = this.config.fetch ?? fetch;
3901
3956
  const response = await doFetch(url, {
@@ -3931,7 +3986,7 @@ var HttpClient = class {
3931
3986
  } catch (error) {
3932
3987
  clearTimeout(timeoutId);
3933
3988
  if (error instanceof Error && error.name === "AbortError") {
3934
- throw new TimeoutError(`Request timed out after ${this.config.timeout}ms`);
3989
+ throw new TimeoutError(`Request timed out after ${options.timeoutMs ?? this.config.timeout}ms`);
3935
3990
  }
3936
3991
  if (error instanceof TypeError && error.message.includes("fetch")) {
3937
3992
  throw new NetworkError(`Network error: ${error.message}`);
@@ -3963,7 +4018,8 @@ var HttpClient = class {
3963
4018
  path,
3964
4019
  body,
3965
4020
  idempotencyKey: options?.idempotencyKey,
3966
- skipRetry: options?.skipRetry
4021
+ skipRetry: options?.skipRetry,
4022
+ timeoutMs: options?.timeoutMs
3967
4023
  });
3968
4024
  }
3969
4025
  /**
@@ -4712,6 +4768,10 @@ var ExecutionStreamControllerImpl = class {
4712
4768
  toolName,
4713
4769
  result: data.result,
4714
4770
  durationMs: data.durationMs ?? 0,
4771
+ // CAD-243: pass the producer's failure verdict through.
4772
+ ...data.isError === true ? { isError: true } : {},
4773
+ ...typeof data.status === "string" ? { status: data.status } : {},
4774
+ ...typeof data.error === "string" ? { error: data.error } : {},
4715
4775
  forwardedFrom: event.data._forwardedFrom,
4716
4776
  // CAD-87 S1-001 EventIdentity → (execId, seq) reducer dedup (S1-003).
4717
4777
  sourceExecutionId: data.sourceExecutionId ?? data.executionId,
@@ -6950,6 +7010,156 @@ var RemoteRunnersAPI = class extends BaseResourceAPI {
6950
7010
  }
6951
7011
  };
6952
7012
 
7013
+ // src/resources/ai-functions.ts
7014
+ var AI_FUNCTION_RUN_TIMEOUT_MS = 31e4;
7015
+ var AI_FUNCTION_DESCRIPTOR_TTL_MS = 6e4;
7016
+ function checkAiFunctionParameters(parameters, variables) {
7017
+ const issues = [];
7018
+ const declared = /* @__PURE__ */ new Set();
7019
+ for (const p of parameters) {
7020
+ declared.add(p.name);
7021
+ const has = Object.prototype.hasOwnProperty.call(variables, p.name);
7022
+ const value = has ? variables[p.name] : void 0;
7023
+ if (value === void 0 || value === null) {
7024
+ if (p.required) issues.push({ name: p.name, code: "missing" });
7025
+ continue;
7026
+ }
7027
+ switch (p.type) {
7028
+ case "number":
7029
+ if (typeof value !== "number" || !Number.isFinite(value)) {
7030
+ issues.push({ name: p.name, code: "type" });
7031
+ }
7032
+ break;
7033
+ case "boolean":
7034
+ if (typeof value !== "boolean") issues.push({ name: p.name, code: "type" });
7035
+ break;
7036
+ case "enum":
7037
+ if (typeof value !== "string") issues.push({ name: p.name, code: "type" });
7038
+ else if (p.options && !p.options.includes(value)) {
7039
+ issues.push({ name: p.name, code: "option" });
7040
+ }
7041
+ break;
7042
+ case "string":
7043
+ case "text":
7044
+ if (typeof value !== "string") issues.push({ name: p.name, code: "type" });
7045
+ else if (typeof p.maxLength === "number" && value.length > p.maxLength) {
7046
+ issues.push({ name: p.name, code: "too_long" });
7047
+ }
7048
+ break;
7049
+ case "image":
7050
+ if (typeof value !== "string") issues.push({ name: p.name, code: "type" });
7051
+ break;
7052
+ }
7053
+ }
7054
+ for (const name of Object.keys(variables)) {
7055
+ if (!declared.has(name)) issues.push({ name, code: "unknown" });
7056
+ }
7057
+ return issues;
7058
+ }
7059
+ var AiFunctionsAPI = class extends BaseResourceAPI {
7060
+ descriptorCache = /* @__PURE__ */ new Map();
7061
+ constructor(http) {
7062
+ super(http, "/api/v1/ai-functions");
7063
+ }
7064
+ /**
7065
+ * List the functions this org can call — the index (D27a). Each entry carries
7066
+ * the live version's typed parameters; never prompt text.
7067
+ */
7068
+ async list() {
7069
+ const data = await this.httpGet("");
7070
+ const functions = Array.isArray(data) ? data : data?.functions ?? [];
7071
+ for (const d of functions) this.cacheDescriptor(d);
7072
+ return functions;
7073
+ }
7074
+ /**
7075
+ * Get one function's descriptor by key (D27a).
7076
+ * `NotFoundError` (`FUNCTION_NOT_FOUND`) / `ConflictError` (`FUNCTION_NOT_PUBLISHED`).
7077
+ */
7078
+ async get(functionKey) {
7079
+ const data = await this.httpGet(
7080
+ `/${encodeURIComponent(functionKey)}`
7081
+ );
7082
+ const descriptor = data && typeof data === "object" && "function" in data && !("functionKey" in data) ? data.function : data;
7083
+ this.cacheDescriptor(descriptor, functionKey);
7084
+ return descriptor;
7085
+ }
7086
+ /**
7087
+ * Read one of this org's own runs (safe projection, §6.5).
7088
+ */
7089
+ async getRun(executionId) {
7090
+ return this.httpGet(`/runs/${encodeURIComponent(executionId)}`);
7091
+ }
7092
+ /** Forget cached descriptors (one key, or all). */
7093
+ clearDescriptorCache(functionKey) {
7094
+ if (functionKey) this.descriptorCache.delete(functionKey);
7095
+ else this.descriptorCache.clear();
7096
+ }
7097
+ async run(refOrKey, parametersOrOptions, shorthandOpts) {
7098
+ let ref;
7099
+ let options;
7100
+ if (typeof refOrKey === "string") {
7101
+ ref = { functionKey: refOrKey };
7102
+ options = { ...shorthandOpts ?? {}, variables: parametersOrOptions };
7103
+ } else {
7104
+ ref = refOrKey;
7105
+ options = parametersOrOptions;
7106
+ }
7107
+ const variables = options.variables ?? {};
7108
+ const functionKey = "functionKey" in ref ? ref.functionKey : void 0;
7109
+ const shouldCheck = functionKey !== void 0 && options.version === void 0 && options.validate !== false;
7110
+ if (shouldCheck) {
7111
+ const descriptor = await this.getCachedDescriptor(functionKey);
7112
+ const issues = checkAiFunctionParameters(descriptor.parameters, variables);
7113
+ if (issues.length > 0) {
7114
+ throw new AiFunctionParameterError(functionKey, issues);
7115
+ }
7116
+ }
7117
+ const body = {
7118
+ ref,
7119
+ variables,
7120
+ version: options.version,
7121
+ idempotencyKey: options.idempotencyKey ?? generateExecutionId(),
7122
+ params: options.params
7123
+ };
7124
+ try {
7125
+ return await this.httpPost("/run", body, {
7126
+ skipRetry: true,
7127
+ timeoutMs: Math.max(AI_FUNCTION_RUN_TIMEOUT_MS, this.http.timeoutMs ?? 0)
7128
+ });
7129
+ } catch (error) {
7130
+ throw this.mapRunError(error, functionKey);
7131
+ }
7132
+ }
7133
+ // ── internals ──────────────────────────────────────────────────────────────
7134
+ cacheDescriptor(descriptor, key) {
7135
+ if (!descriptor || typeof descriptor !== "object") return;
7136
+ const cacheKey = key ?? descriptor.functionKey;
7137
+ if (!cacheKey) return;
7138
+ this.descriptorCache.set(cacheKey, {
7139
+ descriptor,
7140
+ expiresAt: Date.now() + AI_FUNCTION_DESCRIPTOR_TTL_MS
7141
+ });
7142
+ }
7143
+ async getCachedDescriptor(functionKey) {
7144
+ const hit = this.descriptorCache.get(functionKey);
7145
+ if (hit && hit.expiresAt > Date.now()) return hit.descriptor;
7146
+ return this.get(functionKey);
7147
+ }
7148
+ mapRunError(error, functionKey) {
7149
+ if (!(error instanceof CadraError)) return error;
7150
+ if (error.serverCode === "DUPLICATE_REQUEST") {
7151
+ return new AiFunctionDuplicateError(error.message, error.details, error.requestId);
7152
+ }
7153
+ if (error.details?.charged === true) {
7154
+ return new AiFunctionChargedError(error);
7155
+ }
7156
+ if (functionKey && error.serverCode?.startsWith("VARIABLE_")) {
7157
+ this.descriptorCache.delete(functionKey);
7158
+ }
7159
+ return error;
7160
+ }
7161
+ };
7162
+
6953
7163
  // src/client.ts
6954
7164
  var DEFAULT_BASE_URL = "https://api.cadraos.com";
6955
7165
  var DEFAULT_TIMEOUT = 3e4;
@@ -6996,6 +7206,10 @@ var CadraClient = class {
6996
7206
  * Remote runner operations (list)
6997
7207
  */
6998
7208
  remoteRunners;
7209
+ /**
7210
+ * AI function operations (list, get, run, getRun) — p93
7211
+ */
7212
+ aiFunctions;
6999
7213
  /**
7000
7214
  * Create a new AI SaaS client
7001
7215
  *
@@ -7085,6 +7299,7 @@ var CadraClient = class {
7085
7299
  this.kanban = new KanbanAPI(this.httpClient, getStreamConfig);
7086
7300
  this.remoteAgents = new RemoteAgentsAPI(this.httpClient, getStreamConfig);
7087
7301
  this.remoteRunners = new RemoteRunnersAPI(this.httpClient);
7302
+ this.aiFunctions = new AiFunctionsAPI(this.httpClient);
7088
7303
  }
7089
7304
  /**
7090
7305
  * Validate client options