@prestyj/ai 5.1.0 → 5.2.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.
package/README.md CHANGED
@@ -40,7 +40,7 @@ Tool parameters are Zod schemas. Converted to JSON Schema at the provider bounda
40
40
 
41
41
  | Provider | Models | Notes |
42
42
  |---|---|---|
43
- | `anthropic` | Claude Fable 5, Opus 4.8, Sonnet 4.6, Haiku 4.5 | Extended thinking, prompt caching, server-side compaction |
43
+ | `anthropic` | Claude Opus 4.8, Sonnet 5, Haiku 4.5 | Extended thinking, prompt caching, server-side compaction |
44
44
  | `openai` | GPT-4.1, o3, o4-mini | Supports OAuth (codex endpoint) and API keys |
45
45
  | `glm` | GLM-5.1, GLM-4.7 | Z.AI platform, OpenAI-compatible |
46
46
  | `moonshot` | Kimi K2.7 | Moonshot platform, OpenAI-compatible |
package/dist/index.cjs CHANGED
@@ -144,6 +144,22 @@ function isMythosAccessError(message) {
144
144
  const lower = message.toLowerCase();
145
145
  return lower.includes("mythos") && (lower.includes("not_found") || lower.includes("not found") || lower.includes("no access"));
146
146
  }
147
+ function isRawJsonErrorEcho(message) {
148
+ const trimmed = message.trim();
149
+ const jsonStart = trimmed.indexOf("{");
150
+ if (jsonStart === -1) return false;
151
+ const prefix = trimmed.slice(0, jsonStart).trim();
152
+ if (prefix && !/^\d+$/.test(prefix)) return false;
153
+ try {
154
+ const parsed = JSON.parse(trimmed.slice(jsonStart));
155
+ return typeof parsed === "object" && parsed !== null;
156
+ } catch {
157
+ return false;
158
+ }
159
+ }
160
+ function emptyProviderErrorMessage(statusCode) {
161
+ return statusCode ? `The provider returned an empty error response (HTTP ${statusCode}), with no further detail.` : "The provider returned an empty error response, with no further detail.";
162
+ }
147
163
  function formatError(err) {
148
164
  if (err instanceof ProviderError) {
149
165
  const name = providerDisplayName(err.provider);
@@ -839,7 +855,7 @@ function toAnthropicToolChoice(choice) {
839
855
  return { type: "tool", name: choice.name };
840
856
  }
841
857
  function isAdaptiveThinkingModel(model) {
842
- return /opus-4[-.]8|opus-4[-.]7|opus-4[-.]6|sonnet-4[-.]6|fable-5|mythos-5/.test(model);
858
+ return /opus-4[-.]8|opus-4[-.]7|opus-4[-.]6|sonnet-5|fable-5|mythos-5/.test(model);
843
859
  }
844
860
  function toAnthropicThinking(level, maxTokens, model) {
845
861
  if (isAdaptiveThinkingModel(model)) {
@@ -1596,9 +1612,10 @@ function toError(err) {
1596
1612
  const errorBody = err.error;
1597
1613
  const nestedError = errorBody?.error;
1598
1614
  const requestId = err.requestID ?? err.request_id ?? (typeof errorBody?.request_id === "string" ? errorBody.request_id : void 0) ?? (typeof nestedError?.request_id === "string" ? nestedError.request_id : void 0) ?? void 0;
1599
- const bodyMessage = typeof nestedError?.message === "string" ? nestedError.message : typeof errorBody?.message === "string" ? errorBody.message : void 0;
1615
+ const bodyMessage = typeof nestedError?.message === "string" && nestedError.message.trim() ? nestedError.message.trim() : typeof errorBody?.message === "string" && errorBody.message.trim() ? errorBody.message.trim() : void 0;
1600
1616
  const bodyType = typeof nestedError?.type === "string" ? nestedError.type : typeof errorBody?.type === "string" ? errorBody.type : typeof err.type === "string" ? err.type : void 0;
1601
- const message = bodyType && bodyMessage ? `${bodyType}: ${bodyMessage}` : bodyMessage ?? err.message;
1617
+ const fallbackMessage = isRawJsonErrorEcho(err.message) ? emptyProviderErrorMessage(err.status) : err.message;
1618
+ const message = bodyType && bodyMessage ? `${bodyType}: ${bodyMessage}` : bodyMessage ?? fallbackMessage;
1602
1619
  if (err.status === 429) {
1603
1620
  const limit = readUnifiedRateLimit(err.headers);
1604
1621
  const farOff = limit.resetsAt != null && limit.resetsAt * 1e3 - Date.now() > 6e4;
@@ -2047,7 +2064,7 @@ function toError2(err, provider = "openai") {
2047
2064
  const body = err.error;
2048
2065
  const bodyMessage = typeof body?.message === "string" && body.message.trim() ? body.message.trim() : void 0;
2049
2066
  const modelName = typeof body?.model === "string" ? body.model : "";
2050
- const cleanMessage = bodyMessage ?? err.message;
2067
+ const cleanMessage = bodyMessage ?? (isRawJsonErrorEcho(err.message) ? emptyProviderErrorMessage(err.status) : err.message);
2051
2068
  let hint;
2052
2069
  if (modelName === "codex-mini-latest" || cleanMessage.includes("codex-mini-latest")) {
2053
2070
  hint = "codex-mini-latest requires an OpenAI Pro or Max subscription. Your account currently has access to GPT-5.4 and GPT-5.4 Mini.";