@diegopetrucci/pi-oracle 0.1.12 → 0.1.14

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 (2) hide show
  1. package/index.ts +92 -6
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -114,6 +114,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
114
114
  "claude-sonnet-4",
115
115
  "claude-3-7-sonnet",
116
116
  ],
117
+ "ant-ling": ["Ling-2.6-1T", "Ling-2.6-flash"],
117
118
  "azure-openai-responses": [
118
119
  "gpt-5.5-pro",
119
120
  "gpt-5.5",
@@ -146,6 +147,8 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
146
147
  "workers-ai/@cf/zai-org/glm-4.7-flash",
147
148
  ],
148
149
  "cloudflare-workers-ai": [
150
+ "@cf/moonshotai/kimi-k2.7-code",
151
+ "@cf/zai-org/glm-5.2",
149
152
  "@cf/moonshotai/kimi-k2.6",
150
153
  "@cf/nvidia/nemotron-3-120b-a12b",
151
154
  "@cf/moonshotai/kimi-k2.5",
@@ -155,9 +158,14 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
155
158
  deepseek: ["deepseek-v4-pro", "deepseek-v4-flash"],
156
159
  fireworks: [
157
160
  "accounts/fireworks/models/deepseek-v4-pro",
158
- "accounts/fireworks/models/kimi-k2p6",
161
+ "accounts/fireworks/models/kimi-k2p7-code",
162
+ "accounts/fireworks/routers/kimi-k2p7-code-fast",
163
+ "accounts/fireworks/models/glm-5p2",
164
+ "accounts/fireworks/models/minimax-m3",
159
165
  "accounts/fireworks/models/glm-5p1",
166
+ "accounts/fireworks/models/kimi-k2p6",
160
167
  "accounts/fireworks/models/minimax-m2p7",
168
+ "accounts/fireworks/models/qwen3p7-plus",
161
169
  "accounts/fireworks/models/qwen3p6-plus",
162
170
  "accounts/fireworks/models/gpt-oss-120b",
163
171
  ],
@@ -217,9 +225,9 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
217
225
  "MiniMaxAI/MiniMax-M2.5",
218
226
  "Qwen/Qwen3-Coder-Next",
219
227
  ],
220
- "kimi-coding": ["k2p6", "kimi-k2-thinking", "kimi-for-coding"],
221
- minimax: ["MiniMax-M2.7-highspeed", "MiniMax-M2.7"],
222
- "minimax-cn": ["MiniMax-M2.7-highspeed", "MiniMax-M2.7"],
228
+ "kimi-coding": ["k2p7", "kimi-k2-thinking", "kimi-for-coding"],
229
+ minimax: ["MiniMax-M3", "MiniMax-M2.7-highspeed", "MiniMax-M2.7"],
230
+ "minimax-cn": ["MiniMax-M3", "MiniMax-M2.7-highspeed", "MiniMax-M2.7"],
223
231
  mistral: [
224
232
  "mistral-medium-2604",
225
233
  "mistral-medium-3.5",
@@ -285,11 +293,16 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
285
293
  ],
286
294
  "opencode-go": [
287
295
  "deepseek-v4-pro",
296
+ "glm-5.2",
288
297
  "glm-5.1",
298
+ "qwen3.7-max",
299
+ "qwen3.7-plus",
289
300
  "qwen3.6-plus",
290
301
  "mimo-v2.5-pro",
291
302
  "mimo-v2-pro",
303
+ "minimax-m3",
292
304
  "minimax-m2.7",
305
+ "kimi-k2.7-code",
293
306
  "kimi-k2.6",
294
307
  "kimi-k2.5",
295
308
  ],
@@ -310,20 +323,26 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
310
323
  "google/gemini-3.1-pro-preview-customtools",
311
324
  "google/gemini-3.1-pro-preview",
312
325
  "google/gemini-2.5-pro",
326
+ "moonshotai/kimi-k2.7-code",
313
327
  "moonshotai/kimi-k2.6",
314
328
  "moonshotai/kimi-k2-thinking",
315
329
  "deepseek/deepseek-v4-pro",
316
330
  "deepseek/deepseek-r1",
317
331
  "deepseek/deepseek-v3.2",
332
+ "minimax/minimax-m3",
318
333
  "minimax/minimax-m2.7",
319
334
  "minimax/minimax-m2.1",
335
+ "z-ai/glm-5.2",
320
336
  "z-ai/glm-5.1",
321
337
  ],
322
338
  together: [
323
339
  "deepseek-ai/DeepSeek-V4-Pro",
324
340
  "zai-org/GLM-5.1",
341
+ "moonshotai/Kimi-K2.7-Code",
325
342
  "moonshotai/Kimi-K2.6",
343
+ "Qwen/Qwen3.7-Max",
326
344
  "Qwen/Qwen3.6-Plus",
345
+ "MiniMaxAI/MiniMax-M3",
327
346
  "MiniMaxAI/MiniMax-M2.7",
328
347
  "Qwen/Qwen3.5-397B-A17B",
329
348
  "Qwen/Qwen3-Coder-Next-FP8",
@@ -347,15 +366,21 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
347
366
  "openai/gpt-5.4",
348
367
  "openai/gpt-5.1-codex",
349
368
  "openai/gpt-5-codex",
369
+ "moonshotai/kimi-k2.7-code",
370
+ "moonshotai/kimi-k2.7-code-highspeed",
350
371
  "moonshotai/kimi-k2.6",
351
372
  "moonshotai/kimi-k2-thinking",
352
373
  "deepseek/deepseek-v4-pro",
353
374
  "deepseek/deepseek-v3.2-thinking",
375
+ "alibaba/qwen3.7-max",
376
+ "alibaba/qwen3.7-plus",
354
377
  "alibaba/qwen3.5-plus",
355
378
  "alibaba/qwen3-max-thinking",
356
379
  "google/gemini-3.1-pro-preview",
357
380
  "google/gemini-3-flash",
358
381
  "xai/grok-4.3",
382
+ "minimax/minimax-m3",
383
+ "zai/glm-5.2",
359
384
  "zai/glm-5.1",
360
385
  ],
361
386
  xai: [
@@ -390,7 +415,18 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
390
415
  "mimo-v2-omni",
391
416
  "mimo-v2-flash",
392
417
  ],
418
+ nvidia: [
419
+ "nvidia/nemotron-3-ultra-550b-a55b",
420
+ "nvidia/nemotron-3-super-120b-a12b",
421
+ "moonshotai/kimi-k2.6",
422
+ "z-ai/glm-5.1",
423
+ "qwen/qwen3.5-122b-a10b",
424
+ "openai/gpt-oss-120b",
425
+ "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning",
426
+ "nvidia/nemotron-3-nano-30b-a3b",
427
+ ],
393
428
  zai: [
429
+ "glm-5.2",
394
430
  "glm-5.1",
395
431
  "glm-5-turbo",
396
432
  "glm-5v-turbo",
@@ -401,8 +437,17 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
401
437
  "glm-4.5v",
402
438
  "glm-4.5-air",
403
439
  ],
404
- moonshotai: ["kimi-k2.6", "kimi-k2-thinking-turbo", "kimi-k2-thinking", "kimi-k2.5"],
405
- "moonshotai-cn": ["kimi-k2.6", "kimi-k2-thinking-turbo", "kimi-k2-thinking", "kimi-k2.5"],
440
+ "zai-coding-cn": [
441
+ "glm-5.2",
442
+ "glm-5.1",
443
+ "glm-5-turbo",
444
+ "glm-5v-turbo",
445
+ "glm-5",
446
+ "glm-4.7",
447
+ "glm-4.5-air",
448
+ ],
449
+ moonshotai: ["kimi-k2.7-code", "kimi-k2.7-code-highspeed", "kimi-k2.6", "kimi-k2-thinking-turbo", "kimi-k2-thinking", "kimi-k2.5"],
450
+ "moonshotai-cn": ["kimi-k2.7-code", "kimi-k2.7-code-highspeed", "kimi-k2.6", "kimi-k2-thinking-turbo", "kimi-k2-thinking", "kimi-k2.5"],
406
451
  };
407
452
 
408
453
  const ORACLE_SYSTEM_PROMPT = [
@@ -557,6 +602,26 @@ function extractTextFromContent(content: unknown): string {
557
602
  return parts.join("\n\n").trim();
558
603
  }
559
604
 
605
+ // Errors that typically resolve on retry: provider overload, rate limiting,
606
+ // transient 5xx, gateway/network failures, and request timeouts. Keep this list
607
+ // pattern-based so we recognize variants across providers without enumerating them.
608
+ const TRANSIENT_ERROR_PATTERN =
609
+ /\b(overload(?:ed)?|rate[ _-]?limit(?:ed)?|too many requests|429|500|502|503|504|bad gateway|service unavailable|gateway timeout|temporarily unavailable|timed?[ _-]?out|timeout|econnreset|econnrefused|etimedout|enetunreach|socket hang up|fetch failed)\b/i;
610
+
611
+ function isTransientErrorMessage(message: string): boolean {
612
+ return TRANSIENT_ERROR_PATTERN.test(message);
613
+ }
614
+
615
+ function formatOracleModelError(stopReason: "error" | "aborted", errorMessage: string | undefined): string {
616
+ const trimmed = errorMessage?.trim();
617
+ if (stopReason === "aborted") {
618
+ return trimmed ? `Oracle model turn aborted: ${trimmed}` : "Oracle model turn aborted.";
619
+ }
620
+ if (!trimmed) return "Oracle model error (no detail provided by provider).";
621
+ const base = `Oracle model error: ${trimmed}`;
622
+ return isTransientErrorMessage(trimmed) ? `${base} (transient; retry may succeed)` : base;
623
+ }
624
+
560
625
  function parseVersionScore(text: string): number {
561
626
  const matches = text.match(/\d+(?:\.\d+){0,2}/g) ?? [];
562
627
  let best = 0;
@@ -817,6 +882,9 @@ async function runOracle(
817
882
  let finalOutput = "";
818
883
  let stderr = "";
819
884
 
885
+ let lastStopReason: string | undefined;
886
+ let lastErrorMessage: string | undefined;
887
+
820
888
  const details: OracleDetails = {
821
889
  ...selection,
822
890
  includeBash,
@@ -888,6 +956,11 @@ async function runOracle(
888
956
  if (text) finalOutput = text;
889
957
  currentText = "";
890
958
 
959
+ const stopReason = event.message.stopReason;
960
+ lastStopReason = typeof stopReason === "string" ? stopReason : undefined;
961
+ const errorMessageField = event.message.errorMessage;
962
+ lastErrorMessage = typeof errorMessageField === "string" ? errorMessageField : undefined;
963
+
891
964
  const messageUsage = event.message.usage;
892
965
  if (messageUsage) {
893
966
  usage.turns += 1;
@@ -946,6 +1019,19 @@ async function runOracle(
946
1019
  return { ok: false, error: "Oracle was aborted.", details };
947
1020
  }
948
1021
 
1022
+ // The pi subprocess in `--mode json` does not promote an errored assistant
1023
+ // turn to a non-zero exit code or stderr; the error is only carried on the
1024
+ // streamed assistant message via stopReason/errorMessage. Surface that here
1025
+ // so callers can distinguish transient provider errors from a genuinely
1026
+ // empty response.
1027
+ if (lastStopReason === "error" || lastStopReason === "aborted") {
1028
+ return {
1029
+ ok: false,
1030
+ error: formatOracleModelError(lastStopReason, lastErrorMessage),
1031
+ details,
1032
+ };
1033
+ }
1034
+
949
1035
  if (exitCode !== 0) {
950
1036
  return {
951
1037
  ok: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diegopetrucci/pi-oracle",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "An Amp-style oracle extension for pi that consults the strongest reasoning model on your current provider.",
5
5
  "keywords": [
6
6
  "pi-package",