@bman654/clodex 2.1.5 → 2.1.6

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/cli.js CHANGED
@@ -217,7 +217,7 @@ import { join } from "path";
217
217
  // package.json
218
218
  var package_default = {
219
219
  name: "@bman654/clodex",
220
- version: "2.1.5",
220
+ version: "2.1.6",
221
221
  publishConfig: {
222
222
  access: "public"
223
223
  },
@@ -4007,6 +4007,11 @@ function clampRetryAfterSeconds(value) {
4007
4007
  }
4008
4008
  return Math.min(Math.round(value), MAX_RETRY_AFTER_SECONDS);
4009
4009
  }
4010
+ function retryAfterFromText(message) {
4011
+ if (typeof message !== "string") return void 0;
4012
+ const match = /retry after (\d+)s\b/i.exec(message);
4013
+ return match ? Number(match[1]) : void 0;
4014
+ }
4010
4015
  function numericRetryAfterSeconds(inner) {
4011
4016
  const data = inner.data;
4012
4017
  const fromBody = data?.error?.retry_after_seconds;
@@ -4014,12 +4019,84 @@ function numericRetryAfterSeconds(inner) {
4014
4019
  const fromHeader = inner.responseHeaders?.["retry-after"];
4015
4020
  if (typeof fromHeader === "string" && /^\d+$/.test(fromHeader.trim())) return Number(fromHeader.trim());
4016
4021
  for (const message of [data?.error?.message, inner.message]) {
4017
- if (typeof message !== "string") continue;
4018
- const match = /retry after (\d+)s\b/i.exec(message);
4019
- if (match) return Number(match[1]);
4022
+ const fromText = retryAfterFromText(message);
4023
+ if (fromText !== void 0) return fromText;
4020
4024
  }
4021
4025
  return void 0;
4022
4026
  }
4027
+ var MAX_CLIENT_MESSAGE_CHARS = 240;
4028
+ var CHUNK_DISCRIMINATOR_TYPES = /* @__PURE__ */ new Set(["error", "response.failed"]);
4029
+ function asRecord(value) {
4030
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
4031
+ }
4032
+ function nonEmptyString(record, key) {
4033
+ const value = record[key];
4034
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
4035
+ }
4036
+ function errorCodeValue(record) {
4037
+ const value = record.code;
4038
+ if (typeof value === "number" && Number.isFinite(value)) return String(value);
4039
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
4040
+ }
4041
+ function frameStatusCode(code, discriminator) {
4042
+ if (code !== void 0 && /^\d{3}$/.test(code)) {
4043
+ const numeric = Number(code);
4044
+ if (numeric >= 400 && numeric <= 599) return numeric;
4045
+ }
4046
+ if (/insufficient_quota|rate_limit/.test(discriminator)) return 429;
4047
+ if (discriminator.includes("authentication")) return 401;
4048
+ if (discriminator.includes("permission")) return 403;
4049
+ if (discriminator.includes("not_found")) return 404;
4050
+ if (/invalid|bad_request|context_length/.test(discriminator)) return 400;
4051
+ if (discriminator.includes("overload")) return 503;
4052
+ if (discriminator.includes("timeout")) return 504;
4053
+ return 500;
4054
+ }
4055
+ function frameIsContextLengthExceeded(discriminator, message) {
4056
+ if (/context_length|context_window/.test(discriminator)) return true;
4057
+ return /context_length_exceeded|maximum context length|prompt is too long/i.test(message);
4058
+ }
4059
+ function frameIsRetryable(frame) {
4060
+ if (frame.transportCode !== void 0) return true;
4061
+ const { statusCode } = frame;
4062
+ return statusCode === 408 || statusCode === 409 || statusCode === 429 || statusCode >= 500;
4063
+ }
4064
+ function providerErrorFrame(err) {
4065
+ const outer = asRecord(err);
4066
+ if (!outer) return void 0;
4067
+ const nested = asRecord(outer.error) ?? asRecord(asRecord(outer.response)?.error);
4068
+ const unwrapped = !(err instanceof Error) && (typeof outer.type === "string" || Object.hasOwn(outer, "code") || Object.hasOwn(outer, "param")) ? outer : void 0;
4069
+ const payload = nested ?? unwrapped;
4070
+ if (!payload) return void 0;
4071
+ const rawMessage = payload.message;
4072
+ if (typeof rawMessage !== "string") return void 0;
4073
+ const message = rawMessage.trim() !== "" ? rawMessage : "Provider returned an error";
4074
+ const code = errorCodeValue(payload);
4075
+ const rawType = nonEmptyString(payload, "type");
4076
+ const type = rawType !== void 0 && CHUNK_DISCRIMINATOR_TYPES.has(rawType) ? void 0 : rawType;
4077
+ const discriminator = [code, type].filter((value) => value !== void 0).join(" ").toLowerCase();
4078
+ const statusCode = frameStatusCode(code, discriminator);
4079
+ const rawRetryAfter = statusCode === 429 ? typeof payload.retry_after_seconds === "number" && Number.isFinite(payload.retry_after_seconds) && payload.retry_after_seconds >= 0 ? payload.retry_after_seconds : retryAfterFromText(message) : void 0;
4080
+ let serialized;
4081
+ try {
4082
+ serialized = JSON.stringify(payload) ?? message;
4083
+ } catch {
4084
+ serialized = message;
4085
+ }
4086
+ return {
4087
+ message,
4088
+ statusCode,
4089
+ contextLengthExceeded: frameIsContextLengthExceeded(discriminator, message),
4090
+ ...rawRetryAfter !== void 0 ? { retryAfterSeconds: clampRetryAfterSeconds(rawRetryAfter) } : {},
4091
+ ...code === "websocket_transport_error" ? { transportCode: "websocket_transport_error" } : {},
4092
+ serialized
4093
+ };
4094
+ }
4095
+ function frameFromError(err) {
4096
+ const retry = RetryError.isInstance(err) ? err : void 0;
4097
+ const frame = providerErrorFrame(retry?.lastError ?? err);
4098
+ return frame ? { frame, attemptCount: retry?.errors.length ?? 1 } : void 0;
4099
+ }
4023
4100
  function boundedTransportCode(data) {
4024
4101
  if (!data || typeof data !== "object") return void 0;
4025
4102
  const error = data.error;
@@ -4029,7 +4106,19 @@ function boundedTransportCode(data) {
4029
4106
  function sdkUpstreamErrorDetails(err) {
4030
4107
  const retry = RetryError.isInstance(err) ? err : void 0;
4031
4108
  const inner = retry?.lastError ?? err;
4032
- if (!APICallError.isInstance(inner)) return void 0;
4109
+ if (!APICallError.isInstance(inner)) {
4110
+ const recovered = frameFromError(err);
4111
+ if (!recovered) return void 0;
4112
+ const { frame, attemptCount } = recovered;
4113
+ return {
4114
+ statusCode: frame.statusCode,
4115
+ errorContent: frame.serialized,
4116
+ isRetryable: frameIsRetryable(frame),
4117
+ attemptCount,
4118
+ ...frame.retryAfterSeconds !== void 0 ? { retryAfterSeconds: frame.retryAfterSeconds } : {},
4119
+ ...frame.transportCode !== void 0 ? { transportCode: frame.transportCode } : {}
4120
+ };
4121
+ }
4033
4122
  let errorContent = inner.responseBody;
4034
4123
  if (!errorContent && inner.data !== void 0) {
4035
4124
  try {
@@ -4050,6 +4139,8 @@ function sdkUpstreamErrorDetails(err) {
4050
4139
  };
4051
4140
  }
4052
4141
  function isContextLengthExceededError(err, formattedMessage = "") {
4142
+ const frame = frameFromError(err)?.frame;
4143
+ if (frame) return frame.contextLengthExceeded;
4053
4144
  const details = sdkUpstreamErrorDetails(err);
4054
4145
  const rec = err && typeof err === "object" ? err : void 0;
4055
4146
  const candidates = [
@@ -4068,6 +4159,11 @@ function isContextLengthExceededError(err, formattedMessage = "") {
4068
4159
  function formatUpstreamError(err) {
4069
4160
  if (!err || typeof err !== "object") return "Upstream model request failed.";
4070
4161
  const rec = err;
4162
+ const frame = frameFromError(err)?.frame;
4163
+ if (frame) {
4164
+ const short = truncateForClient(sanitizeMessage(frame.message)) || "Upstream model request failed.";
4165
+ return `${short} (HTTP ${frame.statusCode})`;
4166
+ }
4071
4167
  if (rec.data?.error?.message) {
4072
4168
  const short = sanitizeMessage(rec.data.error.message);
4073
4169
  return rec.statusCode ? `${short} (HTTP ${rec.statusCode})` : short;
@@ -4106,6 +4202,8 @@ function upstreamHttpStatus(err, message) {
4106
4202
  const code = err.statusCode;
4107
4203
  if (typeof code === "number" && code >= 400 && code <= 599) return code;
4108
4204
  }
4205
+ const frameStatus = frameFromError(err)?.frame.statusCode;
4206
+ if (frameStatus !== void 0) return frameStatus;
4109
4207
  if (message.includes("HTTP 429") || message.includes("429")) return 429;
4110
4208
  if (message.includes("HTTP 400")) return 400;
4111
4209
  return 500;
@@ -4126,6 +4224,10 @@ function anthropicErrorType(status) {
4126
4224
  return "api_error";
4127
4225
  }
4128
4226
  }
4227
+ function truncateForClient(message) {
4228
+ if (message.length <= MAX_CLIENT_MESSAGE_CHARS) return message;
4229
+ return `${[...message].slice(0, MAX_CLIENT_MESSAGE_CHARS - 1).join("")}\u2026`;
4230
+ }
4129
4231
  function sanitizeMessage(message) {
4130
4232
  const line = message.split("\n")[0]?.trim() ?? message;
4131
4233
  if (line.startsWith("RetryError") || line.includes("AI_RetryError")) {
@@ -4374,6 +4476,15 @@ function responseErrorCode(event) {
4374
4476
  const responseError = response?.error && typeof response.error === "object" ? response.error : void 0;
4375
4477
  return typeof responseError?.code === "string" ? responseError.code : void 0;
4376
4478
  }
4479
+ function responseErrorType(event) {
4480
+ if (!event || typeof event !== "object") return void 0;
4481
+ const record = event;
4482
+ const error = record.error && typeof record.error === "object" ? record.error : void 0;
4483
+ if (typeof error?.type === "string") return error.type;
4484
+ const response = record.response && typeof record.response === "object" ? record.response : void 0;
4485
+ const responseError = response?.error && typeof response.error === "object" ? response.error : void 0;
4486
+ return typeof responseError?.type === "string" ? responseError.type : void 0;
4487
+ }
4377
4488
  function responseRetryAfterSeconds(event) {
4378
4489
  if (!event || typeof event !== "object") return void 0;
4379
4490
  const record = event;
@@ -4388,6 +4499,27 @@ function responseRetryAfterSeconds(event) {
4388
4499
  }
4389
4500
  return void 0;
4390
4501
  }
4502
+ function responseErrorStatus(event) {
4503
+ if (!event || typeof event !== "object") return void 0;
4504
+ const record = event;
4505
+ for (const candidate of [record.status, record.error?.status]) {
4506
+ if (typeof candidate === "number" && Number.isInteger(candidate) && candidate >= 400 && candidate <= 599) {
4507
+ return candidate;
4508
+ }
4509
+ }
4510
+ return void 0;
4511
+ }
4512
+ function responseErrorMessage(event) {
4513
+ if (!event || typeof event !== "object") return void 0;
4514
+ const record = event;
4515
+ const response = record.response && typeof record.response === "object" ? record.response : void 0;
4516
+ for (const candidate of [record.error, response?.error, record]) {
4517
+ if (!candidate || typeof candidate !== "object") continue;
4518
+ const message = candidate.message;
4519
+ if (typeof message === "string" && message.trim()) return message.trim();
4520
+ }
4521
+ return void 0;
4522
+ }
4391
4523
  function boundedDiagnosticIdentifier(value) {
4392
4524
  if (typeof value !== "string") return void 0;
4393
4525
  const normalized = value.trim();
@@ -4894,7 +5026,8 @@ function handleSocketMessage(entry, data) {
4894
5026
  );
4895
5027
  return;
4896
5028
  }
4897
- if (FAILURE_EVENT_TYPES.has(type ?? "")) {
5029
+ const errorStatus = type === "error" && !ctx.emittedModelData ? responseErrorStatus(event) : void 0;
5030
+ if (FAILURE_EVENT_TYPES.has(type ?? "") && (errorStatus === void 0 || willRetry)) {
4898
5031
  emitResponseErrorDiagnostic(entry, ctx, {
4899
5032
  source: "response_event",
4900
5033
  upstreamEventType: type,
@@ -4911,6 +5044,32 @@ function handleSocketMessage(entry, data) {
4911
5044
  dispatchContext(replacement, ctx);
4912
5045
  return;
4913
5046
  }
5047
+ if (errorStatus !== void 0) {
5048
+ const statedRetryAfter = errorStatus === 429 ? responseRetryAfterSeconds(event) : void 0;
5049
+ const retryAfterSeconds = statedRetryAfter === void 0 ? void 0 : clampRetryAfterSeconds(statedRetryAfter);
5050
+ const reason = responseErrorMessage(event) ?? `OpenAI rejected the request (HTTP ${errorStatus})`;
5051
+ failContext(
5052
+ entry,
5053
+ ctx,
5054
+ retryAfterSeconds === void 0 ? reason : `${reason}; retry after ${retryAfterSeconds}s`,
5055
+ {
5056
+ source: "error_frame",
5057
+ // Names the failure. Without it this record — now the ONLY one for a
5058
+ // rejection — can carry no indication of what failed, since a bare
5059
+ // error frame often has no `code` at all.
5060
+ errorType: boundedDiagnosticIdentifier(responseErrorType(event)),
5061
+ // Upstream-controlled, so bounded like every other identifier in this
5062
+ // file's diagnostics. The connection-limit branch can pass its code raw
5063
+ // only because it has just been compared `===` to a known constant.
5064
+ errorCode: boundedDiagnosticIdentifier(errorCode),
5065
+ mappedStatusCode: errorStatus,
5066
+ ...retryAfterSeconds !== void 0 ? { retryAfterSeconds } : {}
5067
+ },
5068
+ errorStatus,
5069
+ retryAfterSeconds
5070
+ );
5071
+ return;
5072
+ }
4914
5073
  ctx.pendingEvents.push(event);
4915
5074
  if (isModelDataEvent(type)) flushPending(ctx);
4916
5075
  if (TERMINAL_EVENT_TYPES.has(type ?? "") || type === "error") {
@@ -5706,6 +5865,9 @@ function mapCodexEffortToAnthropic(effort) {
5706
5865
  function isGpt56Model(modelId) {
5707
5866
  return /^gpt-5\.6(?:-|$)/i.test(modelId);
5708
5867
  }
5868
+ function isReasoningSummaryUnsupportedModel(modelId) {
5869
+ return /codex-spark(?:-|$)/i.test(modelId);
5870
+ }
5709
5871
  function mapCodexEffortToOpenAI(effort, modelId) {
5710
5872
  if (modelId && isGpt56Model(modelId) && GPT_56_EFFORT_LEVELS.includes(effort)) {
5711
5873
  return effort;
@@ -5942,7 +6104,8 @@ function effortProviderOptions(npm, effort, modelId, metadata) {
5942
6104
  if (npm === "@ai-sdk/openai" || npm === "@ai-sdk/azure") {
5943
6105
  if (!modelId || !modelPrefersResponsesApi(modelId)) return void 0;
5944
6106
  const reasoningEffort = mapCodexEffortToOpenAI(effort, modelId);
5945
- return reasoningEffort ? { openai: { reasoningEffort } } : void 0;
6107
+ if (!reasoningEffort) return void 0;
6108
+ return isReasoningSummaryUnsupportedModel(modelId) ? { openai: { reasoningEffort, reasoningSummary: null } } : { openai: { reasoningEffort } };
5946
6109
  }
5947
6110
  if (npm === "@ai-sdk/xai") {
5948
6111
  if (!modelId || !isXaiReasoningEffortModel(modelId)) return void 0;