reasonix 0.5.21 → 0.5.23

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.d.ts CHANGED
@@ -1084,12 +1084,21 @@ declare function healLoadedMessagesByTokens(messages: ChatMessage[], maxTokens:
1084
1084
  charsSaved: number;
1085
1085
  };
1086
1086
  /**
1087
- * Annotate the `DeepSeek 400: maximum context length …` error the API
1088
- * returns when a session's history has grown past 131,072 tokens. The
1089
- * raw message is a JSON blob; we surface a short actionable hint on top
1090
- * so the user knows to `/forget` or `/clear` rather than parsing the
1091
- * JSON themselves. Other errors pass through unchanged — the loop's
1092
- * error channel already formats them well enough.
1087
+ * Turn raw `DeepSeek NNN: {json}` errors into short actionable hints.
1088
+ * Client code throws these verbatim from the HTTP layer (see client.ts);
1089
+ * this is the one place the UI text layer reads to decide what the user
1090
+ * actually needs to do about it.
1091
+ *
1092
+ * Covered codes (per DeepSeek's error-code doc):
1093
+ * - 400 + "maximum context length" → context-overflow, point at /forget
1094
+ * - 400 generic → strip the JSON, show inner message
1095
+ * - 401 → API key rejected, point at `reasonix setup`
1096
+ * - 402 → balance depleted, link to top-up page
1097
+ * - 422 → param error, show inner message (usually explains which field)
1098
+ *
1099
+ * 429/500/502/503/504 are swallowed by retry.ts before they reach here;
1100
+ * if they DO reach here (all retries exhausted), the raw string already
1101
+ * says "DeepSeek 503: server busy" etc. which is informative enough.
1093
1102
  */
1094
1103
  declare function formatLoopError(err: Error): string;
1095
1104
 
package/dist/index.js CHANGED
@@ -117,7 +117,7 @@ var DeepSeekClient = class {
117
117
  }
118
118
  this.apiKey = apiKey;
119
119
  this.baseUrl = (opts.baseUrl ?? process.env.DEEPSEEK_BASE_URL ?? "https://api.deepseek.com").replace(/\/+$/, "");
120
- this.timeoutMs = opts.timeoutMs ?? 12e4;
120
+ this.timeoutMs = opts.timeoutMs ?? 66e4;
121
121
  this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);
122
122
  this.retry = opts.retry ?? {};
123
123
  }
@@ -2566,10 +2566,41 @@ function formatLoopError(err) {
2566
2566
  if (msg.includes("maximum context length")) {
2567
2567
  const reqMatch = msg.match(/requested\s+(\d+)\s+tokens/);
2568
2568
  const requested = reqMatch ? `${Number(reqMatch[1]).toLocaleString()} tokens` : "too many tokens";
2569
- return `Context overflow (DeepSeek 400): session history is ${requested}, past the 131,072-token limit. Usually this means a single tool call returned a huge payload. v0.3.0-alpha.6+ caps new tool results at 32k chars, AND auto-heals oversized history on session load \u2014 restart Reasonix and this session should come back trimmed. If it still overflows, run /forget (delete the session) or /clear (drop the displayed history) to start fresh.`;
2569
+ return `Context overflow (DeepSeek 400): session history is ${requested}, past the model's prompt limit (V4: 1M tokens; legacy chat/reasoner: 131k). Usually a single tool result grew too big. Reasonix caps new tool results at 8k tokens and auto-heals oversized history on session load \u2014 a restart often clears it. If it still overflows, run /forget (delete the session) or /clear (drop the displayed history) to start fresh.`;
2570
+ }
2571
+ const m = /^DeepSeek (\d{3}):\s*([\s\S]*)$/.exec(msg);
2572
+ if (!m) return msg;
2573
+ const status = m[1] ?? "";
2574
+ const body = m[2] ?? "";
2575
+ const inner = extractDeepSeekErrorMessage(body);
2576
+ if (status === "401") {
2577
+ return `Authentication failed (DeepSeek 401): ${inner}. Your API key is rejected. Fix with \`reasonix setup\` or \`export DEEPSEEK_API_KEY=sk-...\`. Get one at https://platform.deepseek.com/api_keys.`;
2578
+ }
2579
+ if (status === "402") {
2580
+ return `Out of balance (DeepSeek 402): ${inner}. Top up at https://platform.deepseek.com/top_up \u2014 the panel header shows your balance once it's non-zero.`;
2581
+ }
2582
+ if (status === "422") {
2583
+ return `Invalid parameter (DeepSeek 422): ${inner}`;
2584
+ }
2585
+ if (status === "400") {
2586
+ return `Bad request (DeepSeek 400): ${inner}`;
2570
2587
  }
2571
2588
  return msg;
2572
2589
  }
2590
+ function extractDeepSeekErrorMessage(body) {
2591
+ const trimmed = body.trim();
2592
+ if (!trimmed) return "(no message)";
2593
+ try {
2594
+ const parsed = JSON.parse(trimmed);
2595
+ if (parsed && typeof parsed === "object") {
2596
+ const obj = parsed;
2597
+ if (obj.error && typeof obj.error.message === "string") return obj.error.message;
2598
+ if (typeof obj.message === "string") return obj.message;
2599
+ }
2600
+ } catch {
2601
+ }
2602
+ return trimmed;
2603
+ }
2573
2604
 
2574
2605
  // src/at-mentions.ts
2575
2606
  import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync as statSync2 } from "fs";