@diegopetrucci/pi-oracle 0.1.15 → 0.1.19
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/.pi-fleet-tested-version +1 -1
- package/index.ts +239 -120
- package/package.json +1 -1
package/.pi-fleet-tested-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.80.6
|
package/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { getAgentDir, getMarkdownTheme, type ExtensionAPI, type ExtensionContext
|
|
|
7
7
|
import { Container, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
|
|
8
8
|
import { Type } from "typebox";
|
|
9
9
|
|
|
10
|
-
type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
10
|
+
type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
11
11
|
type ThinkingLevelMap = Partial<Record<ThinkingLevel, unknown | null>>;
|
|
12
12
|
|
|
13
13
|
type PiModel = {
|
|
@@ -67,7 +67,7 @@ interface OraclePreferences {
|
|
|
67
67
|
const READ_ONLY_TOOLS = ["read", "grep", "find", "ls"];
|
|
68
68
|
const READ_ONLY_PLUS_BASH_TOOLS = [...READ_ONLY_TOOLS, "bash"];
|
|
69
69
|
const DEFAULT_THINKING_LEVEL: ThinkingLevel = "xhigh";
|
|
70
|
-
const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"] as const;
|
|
70
|
+
const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"] as const;
|
|
71
71
|
const COLLAPSED_LINE_LIMIT = 8;
|
|
72
72
|
const ORACLE_STATUS_ID = "oracle";
|
|
73
73
|
const ORACLE_WIDGET_ID = "oracle";
|
|
@@ -82,6 +82,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
82
82
|
"claude-opus-4-5",
|
|
83
83
|
"claude-opus-4-1",
|
|
84
84
|
"claude-opus-4",
|
|
85
|
+
"claude-sonnet-5",
|
|
85
86
|
"claude-sonnet-4-6",
|
|
86
87
|
"claude-sonnet-4-5",
|
|
87
88
|
"claude-sonnet-4",
|
|
@@ -95,37 +96,32 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
95
96
|
anthropic: [
|
|
96
97
|
"claude-fable-5",
|
|
97
98
|
"claude-opus-4-8",
|
|
98
|
-
"claude-opus-4.8",
|
|
99
99
|
"claude-opus-4-7",
|
|
100
|
-
"claude-opus-4.7",
|
|
101
100
|
"claude-opus-4-6",
|
|
102
|
-
"claude-opus-4.6",
|
|
103
101
|
"claude-opus-4-5",
|
|
104
|
-
"claude-opus-4.5",
|
|
105
102
|
"claude-opus-4-1",
|
|
106
|
-
"claude-
|
|
107
|
-
"claude-opus-4-0",
|
|
108
|
-
"claude-opus-4",
|
|
103
|
+
"claude-sonnet-5",
|
|
109
104
|
"claude-sonnet-4-6",
|
|
110
|
-
"claude-sonnet-4.6",
|
|
111
105
|
"claude-sonnet-4-5",
|
|
112
|
-
"claude-sonnet-4.5",
|
|
113
|
-
"claude-sonnet-4-0",
|
|
114
|
-
"claude-sonnet-4",
|
|
115
|
-
"claude-3-7-sonnet",
|
|
116
106
|
],
|
|
117
107
|
"ant-ling": ["Ling-2.6-1T", "Ling-2.6-flash"],
|
|
118
108
|
"azure-openai-responses": [
|
|
109
|
+
"gpt-5.6-sol",
|
|
110
|
+
"gpt-5.6-terra",
|
|
111
|
+
"gpt-5.6-luna",
|
|
119
112
|
"gpt-5.5-pro",
|
|
120
113
|
"gpt-5.5",
|
|
121
114
|
"gpt-5.4-pro",
|
|
122
115
|
"gpt-5.4",
|
|
123
116
|
"gpt-5.3-codex",
|
|
124
117
|
"gpt-5-pro",
|
|
118
|
+
"gpt-5-chat-latest",
|
|
125
119
|
"gpt-5.2-pro",
|
|
126
120
|
"gpt-5.2",
|
|
127
121
|
"gpt-5.2-codex",
|
|
128
122
|
"gpt-5.1-codex-max",
|
|
123
|
+
"gpt-5.1-codex",
|
|
124
|
+
"gpt-5.1",
|
|
129
125
|
"gpt-5.1-chat-latest",
|
|
130
126
|
"o3-pro",
|
|
131
127
|
"o3-deep-research",
|
|
@@ -133,7 +129,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
133
129
|
"gpt-5.4-mini",
|
|
134
130
|
"gpt-5-mini",
|
|
135
131
|
],
|
|
136
|
-
cerebras: ["gpt-oss-120b", "zai-glm-4.7", "
|
|
132
|
+
cerebras: ["gpt-oss-120b", "zai-glm-4.7", "gemma-4-31b"],
|
|
137
133
|
"cloudflare-ai-gateway": [
|
|
138
134
|
"claude-fable-5",
|
|
139
135
|
"claude-opus-4-7",
|
|
@@ -151,8 +147,8 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
151
147
|
"@cf/zai-org/glm-5.2",
|
|
152
148
|
"@cf/moonshotai/kimi-k2.6",
|
|
153
149
|
"@cf/nvidia/nemotron-3-120b-a12b",
|
|
154
|
-
"@cf/moonshotai/kimi-k2.5",
|
|
155
150
|
"@cf/openai/gpt-oss-120b",
|
|
151
|
+
"@cf/qwen/qwen3-30b-a3b-fp8",
|
|
156
152
|
"@cf/zai-org/glm-4.7-flash",
|
|
157
153
|
],
|
|
158
154
|
deepseek: ["deepseek-v4-pro", "deepseek-v4-flash"],
|
|
@@ -161,13 +157,17 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
161
157
|
"accounts/fireworks/models/kimi-k2p7-code",
|
|
162
158
|
"accounts/fireworks/routers/kimi-k2p7-code-fast",
|
|
163
159
|
"accounts/fireworks/models/glm-5p2",
|
|
160
|
+
"accounts/fireworks/routers/glm-5p2-fast",
|
|
164
161
|
"accounts/fireworks/models/minimax-m3",
|
|
165
162
|
"accounts/fireworks/models/glm-5p1",
|
|
163
|
+
"accounts/fireworks/routers/glm-5p1-fast",
|
|
166
164
|
"accounts/fireworks/models/kimi-k2p6",
|
|
165
|
+
"accounts/fireworks/routers/kimi-k2p6-turbo",
|
|
166
|
+
"accounts/fireworks/routers/kimi-k2p6-fast",
|
|
167
167
|
"accounts/fireworks/models/minimax-m2p7",
|
|
168
168
|
"accounts/fireworks/models/qwen3p7-plus",
|
|
169
|
-
"accounts/fireworks/models/qwen3p6-plus",
|
|
170
169
|
"accounts/fireworks/models/gpt-oss-120b",
|
|
170
|
+
"accounts/fireworks/models/gpt-oss-20b",
|
|
171
171
|
],
|
|
172
172
|
"github-copilot": [
|
|
173
173
|
"claude-fable-5",
|
|
@@ -178,40 +178,46 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
178
178
|
"gpt-5.5",
|
|
179
179
|
"gpt-5.4",
|
|
180
180
|
"gpt-5.3-codex",
|
|
181
|
+
"gpt-5.2-codex",
|
|
181
182
|
"gpt-5.2",
|
|
182
|
-
"gpt-5.1-codex-max",
|
|
183
|
-
"gpt-5.1",
|
|
184
|
-
"gpt-5",
|
|
185
183
|
"gemini-3.1-pro-preview",
|
|
186
|
-
"gemini-3-
|
|
184
|
+
"gemini-3.5-flash",
|
|
185
|
+
"gemini-3-flash-preview",
|
|
186
|
+
"claude-sonnet-5",
|
|
187
187
|
"claude-sonnet-4.6",
|
|
188
188
|
"claude-sonnet-4.5",
|
|
189
189
|
"gemini-2.5-pro",
|
|
190
|
+
"gpt-5-mini",
|
|
191
|
+
"kimi-k2.7-code",
|
|
190
192
|
],
|
|
191
193
|
google: [
|
|
192
194
|
"gemini-3.1-pro-preview-customtools",
|
|
193
195
|
"gemini-3.1-pro-preview",
|
|
194
196
|
"gemini-3-pro-preview",
|
|
195
|
-
"gemini-
|
|
197
|
+
"gemini-3.5-flash",
|
|
196
198
|
"gemini-2.5-pro",
|
|
197
|
-
"gemini-2.5-flash
|
|
198
|
-
"gemini-
|
|
199
|
+
"gemini-2.5-flash",
|
|
200
|
+
"gemini-3.1-flash-lite-preview",
|
|
201
|
+
"gemini-3.1-flash-lite",
|
|
199
202
|
"gemini-2.5-flash-lite",
|
|
203
|
+
"gemini-2.0-flash",
|
|
200
204
|
],
|
|
201
205
|
"google-vertex": [
|
|
202
206
|
"gemini-3.1-pro-preview-customtools",
|
|
203
207
|
"gemini-3.1-pro-preview",
|
|
204
|
-
"gemini-3-
|
|
208
|
+
"gemini-3.5-flash",
|
|
209
|
+
"gemini-3-flash-preview",
|
|
205
210
|
"gemini-2.5-pro",
|
|
211
|
+
"gemini-2.5-flash",
|
|
212
|
+
"gemini-3.1-flash-lite",
|
|
206
213
|
"gemini-2.5-flash-lite",
|
|
207
|
-
"gemini-2.0-flash-lite",
|
|
208
214
|
],
|
|
209
215
|
groq: [
|
|
210
216
|
"openai/gpt-oss-120b",
|
|
211
|
-
"groq/compound-mini",
|
|
212
217
|
"qwen/qwen3-32b",
|
|
213
|
-
"
|
|
214
|
-
"
|
|
218
|
+
"meta-llama/llama-4-scout-17b-16e-instruct",
|
|
219
|
+
"llama-3.3-70b-versatile",
|
|
220
|
+
"openai/gpt-oss-20b",
|
|
215
221
|
],
|
|
216
222
|
huggingface: [
|
|
217
223
|
"zai-org/GLM-5.1",
|
|
@@ -241,16 +247,22 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
241
247
|
"devstral-2512",
|
|
242
248
|
],
|
|
243
249
|
openai: [
|
|
250
|
+
"gpt-5.6-sol",
|
|
251
|
+
"gpt-5.6-terra",
|
|
252
|
+
"gpt-5.6-luna",
|
|
244
253
|
"gpt-5.5-pro",
|
|
245
254
|
"gpt-5.5",
|
|
246
255
|
"gpt-5.4-pro",
|
|
247
256
|
"gpt-5.4",
|
|
248
257
|
"gpt-5.3-codex",
|
|
249
258
|
"gpt-5-pro",
|
|
259
|
+
"gpt-5-chat-latest",
|
|
250
260
|
"gpt-5.2-pro",
|
|
251
261
|
"gpt-5.2",
|
|
252
262
|
"gpt-5.2-codex",
|
|
253
263
|
"gpt-5.1-codex-max",
|
|
264
|
+
"gpt-5.1-codex",
|
|
265
|
+
"gpt-5.1",
|
|
254
266
|
"gpt-5.1-chat-latest",
|
|
255
267
|
"o3-pro",
|
|
256
268
|
"o3-deep-research",
|
|
@@ -259,14 +271,13 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
259
271
|
"gpt-5-mini",
|
|
260
272
|
],
|
|
261
273
|
"openai-codex": [
|
|
274
|
+
"gpt-5.6-sol",
|
|
275
|
+
"gpt-5.6-terra",
|
|
276
|
+
"gpt-5.6-luna",
|
|
262
277
|
"gpt-5.5",
|
|
263
278
|
"gpt-5.4",
|
|
264
|
-
"gpt-5.3-codex",
|
|
265
|
-
"gpt-5.2",
|
|
266
|
-
"gpt-5.1-codex-max",
|
|
267
279
|
"gpt-5.4-mini",
|
|
268
|
-
"gpt-5.
|
|
269
|
-
"big-pickle",
|
|
280
|
+
"gpt-5.3-codex-spark",
|
|
270
281
|
],
|
|
271
282
|
opencode: [
|
|
272
283
|
"claude-fable-5",
|
|
@@ -281,15 +292,19 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
281
292
|
"gpt-5.3-codex",
|
|
282
293
|
"gpt-5.2-codex",
|
|
283
294
|
"gpt-5.1-codex",
|
|
295
|
+
"grok-4.5",
|
|
296
|
+
"gemini-3.5-flash",
|
|
284
297
|
"gemini-3.1-pro",
|
|
298
|
+
"glm-5.2",
|
|
285
299
|
"glm-5.1",
|
|
286
300
|
"glm-5",
|
|
301
|
+
"kimi-k2.7-code",
|
|
287
302
|
"kimi-k2.6",
|
|
288
303
|
"kimi-k2.5",
|
|
289
304
|
"qwen3.6-plus",
|
|
290
305
|
"qwen3.5-plus",
|
|
306
|
+
"minimax-m3",
|
|
291
307
|
"minimax-m2.7",
|
|
292
|
-
"minimax-m2.5-free",
|
|
293
308
|
],
|
|
294
309
|
"opencode-go": [
|
|
295
310
|
"deepseek-v4-pro",
|
|
@@ -299,12 +314,11 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
299
314
|
"qwen3.7-plus",
|
|
300
315
|
"qwen3.6-plus",
|
|
301
316
|
"mimo-v2.5-pro",
|
|
302
|
-
"mimo-v2
|
|
317
|
+
"mimo-v2.5",
|
|
303
318
|
"minimax-m3",
|
|
304
319
|
"minimax-m2.7",
|
|
305
320
|
"kimi-k2.7-code",
|
|
306
321
|
"kimi-k2.6",
|
|
307
|
-
"kimi-k2.5",
|
|
308
322
|
],
|
|
309
323
|
openrouter: [
|
|
310
324
|
"anthropic/claude-fable-5",
|
|
@@ -312,20 +326,30 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
312
326
|
"anthropic/claude-opus-4.8",
|
|
313
327
|
"anthropic/claude-opus-4.8-fast",
|
|
314
328
|
"anthropic/claude-opus-4.7",
|
|
315
|
-
"anthropic/claude-opus-4.
|
|
329
|
+
"anthropic/claude-opus-4.7-fast",
|
|
316
330
|
"anthropic/claude-opus-4.6",
|
|
317
331
|
"anthropic/claude-opus-4.5",
|
|
318
|
-
"anthropic/claude-opus-4",
|
|
332
|
+
"anthropic/claude-opus-4.1",
|
|
333
|
+
"openai/gpt-5.6-sol-pro",
|
|
334
|
+
"openai/gpt-5.6-sol",
|
|
335
|
+
"openai/gpt-5.6-terra-pro",
|
|
336
|
+
"openai/gpt-5.6-terra",
|
|
337
|
+
"openai/gpt-5.6-luna-pro",
|
|
338
|
+
"openai/gpt-5.6-luna",
|
|
319
339
|
"openai/gpt-5.5-pro",
|
|
320
340
|
"openai/gpt-5.5",
|
|
321
|
-
"openai/gpt-
|
|
322
|
-
"openai/gpt-5.4",
|
|
341
|
+
"~openai/gpt-latest",
|
|
323
342
|
"google/gemini-3.1-pro-preview-customtools",
|
|
324
343
|
"google/gemini-3.1-pro-preview",
|
|
344
|
+
"~google/gemini-pro-latest",
|
|
345
|
+
"google/gemini-3.5-flash",
|
|
325
346
|
"google/gemini-2.5-pro",
|
|
326
347
|
"moonshotai/kimi-k2.7-code",
|
|
348
|
+
"~moonshotai/kimi-latest",
|
|
327
349
|
"moonshotai/kimi-k2.6",
|
|
328
350
|
"moonshotai/kimi-k2-thinking",
|
|
351
|
+
"x-ai/grok-4.5",
|
|
352
|
+
"~x-ai/grok-latest",
|
|
329
353
|
"deepseek/deepseek-v4-pro",
|
|
330
354
|
"deepseek/deepseek-r1",
|
|
331
355
|
"deepseek/deepseek-v3.2",
|
|
@@ -337,6 +361,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
337
361
|
],
|
|
338
362
|
together: [
|
|
339
363
|
"deepseek-ai/DeepSeek-V4-Pro",
|
|
364
|
+
"zai-org/GLM-5.2",
|
|
340
365
|
"zai-org/GLM-5.1",
|
|
341
366
|
"moonshotai/Kimi-K2.7-Code",
|
|
342
367
|
"moonshotai/Kimi-K2.6",
|
|
@@ -345,12 +370,10 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
345
370
|
"MiniMaxAI/MiniMax-M3",
|
|
346
371
|
"MiniMaxAI/MiniMax-M2.7",
|
|
347
372
|
"Qwen/Qwen3.5-397B-A17B",
|
|
348
|
-
"Qwen/Qwen3-Coder-Next-FP8",
|
|
349
|
-
"Qwen/Qwen3-235B-A22B-Instruct-2507-tput",
|
|
350
373
|
"openai/gpt-oss-120b",
|
|
351
|
-
"
|
|
352
|
-
"
|
|
353
|
-
"
|
|
374
|
+
"openai/gpt-oss-20b",
|
|
375
|
+
"nvidia/nemotron-3-ultra-550b-a55b",
|
|
376
|
+
"google/gemma-4-31B-it",
|
|
354
377
|
],
|
|
355
378
|
"vercel-ai-gateway": [
|
|
356
379
|
"anthropic/claude-fable-5",
|
|
@@ -359,11 +382,17 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
359
382
|
"anthropic/claude-opus-4.6",
|
|
360
383
|
"anthropic/claude-opus-4.5",
|
|
361
384
|
"anthropic/claude-opus-4.1",
|
|
385
|
+
"anthropic/claude-sonnet-5",
|
|
362
386
|
"anthropic/claude-sonnet-4.6",
|
|
387
|
+
"openai/gpt-5.6-sol",
|
|
388
|
+
"openai/gpt-5.6-terra",
|
|
389
|
+
"openai/gpt-5.6-luna",
|
|
363
390
|
"openai/gpt-5.5-pro",
|
|
364
391
|
"openai/gpt-5.5",
|
|
365
392
|
"openai/gpt-5.4-pro",
|
|
366
393
|
"openai/gpt-5.4",
|
|
394
|
+
"openai/gpt-5.3-codex",
|
|
395
|
+
"openai/gpt-5.2-codex",
|
|
367
396
|
"openai/gpt-5.1-codex",
|
|
368
397
|
"openai/gpt-5-codex",
|
|
369
398
|
"moonshotai/kimi-k2.7-code",
|
|
@@ -374,52 +403,37 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
374
403
|
"deepseek/deepseek-v3.2-thinking",
|
|
375
404
|
"alibaba/qwen3.7-max",
|
|
376
405
|
"alibaba/qwen3.7-plus",
|
|
406
|
+
"alibaba/qwen3.6-plus",
|
|
377
407
|
"alibaba/qwen3.5-plus",
|
|
378
408
|
"alibaba/qwen3-max-thinking",
|
|
379
409
|
"google/gemini-3.1-pro-preview",
|
|
410
|
+
"google/gemini-3.5-flash",
|
|
380
411
|
"google/gemini-3-flash",
|
|
381
|
-
"xai/grok-4.
|
|
412
|
+
"xai/grok-4.5",
|
|
413
|
+
"xai/grok-4.20-reasoning",
|
|
382
414
|
"minimax/minimax-m3",
|
|
383
415
|
"zai/glm-5.2",
|
|
384
416
|
"zai/glm-5.1",
|
|
385
417
|
],
|
|
386
418
|
xai: [
|
|
387
|
-
"grok-4.
|
|
419
|
+
"grok-4.5",
|
|
388
420
|
"grok-4.20-0309-reasoning",
|
|
389
|
-
"grok-4-
|
|
390
|
-
"grok-4
|
|
391
|
-
"grok-
|
|
392
|
-
"grok-
|
|
393
|
-
"grok-3-
|
|
394
|
-
"grok-3
|
|
421
|
+
"grok-4.20-0309-non-reasoning",
|
|
422
|
+
"grok-4.3",
|
|
423
|
+
"grok-build-0.1",
|
|
424
|
+
"grok-code-fast-1",
|
|
425
|
+
"grok-3-fast",
|
|
426
|
+
"grok-3",
|
|
395
427
|
],
|
|
396
428
|
xiaomi: ["mimo-v2.5-pro", "mimo-v2.5", "mimo-v2-pro", "mimo-v2-omni", "mimo-v2-flash"],
|
|
397
|
-
"xiaomi-token-plan-ams": [
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
"mimo-v2-pro",
|
|
401
|
-
"mimo-v2-omni",
|
|
402
|
-
"mimo-v2-flash",
|
|
403
|
-
],
|
|
404
|
-
"xiaomi-token-plan-cn": [
|
|
405
|
-
"mimo-v2.5-pro",
|
|
406
|
-
"mimo-v2.5",
|
|
407
|
-
"mimo-v2-pro",
|
|
408
|
-
"mimo-v2-omni",
|
|
409
|
-
"mimo-v2-flash",
|
|
410
|
-
],
|
|
411
|
-
"xiaomi-token-plan-sgp": [
|
|
412
|
-
"mimo-v2.5-pro",
|
|
413
|
-
"mimo-v2.5",
|
|
414
|
-
"mimo-v2-pro",
|
|
415
|
-
"mimo-v2-omni",
|
|
416
|
-
"mimo-v2-flash",
|
|
417
|
-
],
|
|
429
|
+
"xiaomi-token-plan-ams": ["mimo-v2.5-pro", "mimo-v2.5", "mimo-v2-pro"],
|
|
430
|
+
"xiaomi-token-plan-cn": ["mimo-v2.5-pro", "mimo-v2.5", "mimo-v2-pro"],
|
|
431
|
+
"xiaomi-token-plan-sgp": ["mimo-v2.5-pro", "mimo-v2.5", "mimo-v2-pro"],
|
|
418
432
|
nvidia: [
|
|
419
433
|
"nvidia/nemotron-3-ultra-550b-a55b",
|
|
420
434
|
"nvidia/nemotron-3-super-120b-a12b",
|
|
421
435
|
"moonshotai/kimi-k2.6",
|
|
422
|
-
"z-ai/glm-5.
|
|
436
|
+
"z-ai/glm-5.2",
|
|
423
437
|
"qwen/qwen3.5-122b-a10b",
|
|
424
438
|
"openai/gpt-oss-120b",
|
|
425
439
|
"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
@@ -430,11 +444,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
430
444
|
"glm-5.1",
|
|
431
445
|
"glm-5-turbo",
|
|
432
446
|
"glm-5v-turbo",
|
|
433
|
-
"glm-5",
|
|
434
447
|
"glm-4.7",
|
|
435
|
-
"glm-4.7-flash",
|
|
436
|
-
"glm-4.6v",
|
|
437
|
-
"glm-4.5v",
|
|
438
448
|
"glm-4.5-air",
|
|
439
449
|
],
|
|
440
450
|
"zai-coding-cn": [
|
|
@@ -516,7 +526,7 @@ function normalizeModelPreference(value: unknown): string | undefined {
|
|
|
516
526
|
function parseModelPreference(value: unknown): { model?: string; thinkingLevel?: ThinkingLevel } {
|
|
517
527
|
const model = normalizeModelPreference(value);
|
|
518
528
|
if (!model) return {};
|
|
519
|
-
const match = model.match(/^(.*):(off|minimal|low|medium|high|xhigh)$/i);
|
|
529
|
+
const match = model.match(/^(.*):(off|minimal|low|medium|high|xhigh|max)$/i);
|
|
520
530
|
if (!match?.[1]) return { model };
|
|
521
531
|
return { model: match[1], thinkingLevel: parseThinkingLevel(match[2]) };
|
|
522
532
|
}
|
|
@@ -612,6 +622,19 @@ function isTransientErrorMessage(message: string): boolean {
|
|
|
612
622
|
return TRANSIENT_ERROR_PATTERN.test(message);
|
|
613
623
|
}
|
|
614
624
|
|
|
625
|
+
// A model the catalog advertises but the active provider/subscription cannot
|
|
626
|
+
// serve surfaces as a not-found/404-style error (legacy snapshots or
|
|
627
|
+
// access-gated tiers). These are NOT transient: the same model keeps failing,
|
|
628
|
+
// so callers should fall back to a different model instead of retrying it.
|
|
629
|
+
const MODEL_AVAILABILITY_ERROR_PATTERN =
|
|
630
|
+
/\b(?:404|403|not[_ ]?found(?:[_ ]?error)?|model[_ ]?not[_ ]?found(?:[_ ]?error)?|no such model|unknown model|does not exist|is not available|not available|model[_ ]?not[_ ]?available|unsupported model|invalid model|forbidden|access[ _-]?denied|permission[ _-]?denied|not[ _-]?entitled|do(?:es)? not have access)\b/i;
|
|
631
|
+
|
|
632
|
+
function isModelAvailabilityError(message: string | undefined): boolean {
|
|
633
|
+
if (!message) return false;
|
|
634
|
+
if (isTransientErrorMessage(message)) return false;
|
|
635
|
+
return MODEL_AVAILABILITY_ERROR_PATTERN.test(message);
|
|
636
|
+
}
|
|
637
|
+
|
|
615
638
|
function formatOracleModelError(stopReason: "error" | "aborted", errorMessage: string | undefined): string {
|
|
616
639
|
const trimmed = errorMessage?.trim();
|
|
617
640
|
if (stopReason === "aborted") {
|
|
@@ -700,7 +723,7 @@ function getPiInvocation(args: string[]): { command: string; args: string[] } {
|
|
|
700
723
|
}
|
|
701
724
|
|
|
702
725
|
function withThinking(modelRef: string, thinkingLevel: ThinkingLevel): string {
|
|
703
|
-
if (/(?:^|\/)[^:]+:(off|minimal|low|medium|high|xhigh)$/i.test(modelRef)) return modelRef;
|
|
726
|
+
if (/(?:^|\/)[^:]+:(off|minimal|low|medium|high|xhigh|max)$/i.test(modelRef)) return modelRef;
|
|
704
727
|
return `${modelRef}:${thinkingLevel}`;
|
|
705
728
|
}
|
|
706
729
|
|
|
@@ -709,8 +732,8 @@ function isThinkingLevelSupported(model: PiModel, level: ThinkingLevel): boolean
|
|
|
709
732
|
if (!model.reasoning) return level === "off";
|
|
710
733
|
|
|
711
734
|
const map = model.thinkingLevelMap;
|
|
712
|
-
if (level === "xhigh") {
|
|
713
|
-
return !!map && Object.prototype.hasOwnProperty.call(map,
|
|
735
|
+
if (level === "xhigh" || level === "max") {
|
|
736
|
+
return !!map && Object.prototype.hasOwnProperty.call(map, level) && map[level] != null;
|
|
714
737
|
}
|
|
715
738
|
return map?.[level] !== null;
|
|
716
739
|
}
|
|
@@ -731,11 +754,16 @@ function clampThinkingLevel(model: PiModel, requested: ThinkingLevel): ThinkingL
|
|
|
731
754
|
return "off";
|
|
732
755
|
}
|
|
733
756
|
|
|
757
|
+
function isGpt56SolModel(model: PiModel | undefined): boolean {
|
|
758
|
+
if (!model) return false;
|
|
759
|
+
return /\bgpt-5\.6-sol\b/i.test(`${model.id} ${model.name ?? ""}`);
|
|
760
|
+
}
|
|
761
|
+
|
|
734
762
|
function resolveThinkingLevel(
|
|
735
763
|
model: PiModel | undefined,
|
|
736
764
|
override: ThinkingLevel | undefined,
|
|
737
765
|
): { requested: ThinkingLevel; effective: ThinkingLevel; clamped: boolean } {
|
|
738
|
-
const requested = override ?? (model?.reasoning ? DEFAULT_THINKING_LEVEL : "off");
|
|
766
|
+
const requested = override ?? (model?.reasoning ? (isGpt56SolModel(model) ? "high" : DEFAULT_THINKING_LEVEL) : "off");
|
|
739
767
|
const effective = model ? clampThinkingLevel(model, requested) : requested;
|
|
740
768
|
return { requested, effective, clamped: effective !== requested };
|
|
741
769
|
}
|
|
@@ -776,10 +804,48 @@ async function findAvailableModel(
|
|
|
776
804
|
return undefined;
|
|
777
805
|
}
|
|
778
806
|
|
|
807
|
+
function toOracleSelection(
|
|
808
|
+
model: PiModel,
|
|
809
|
+
thinkingLevelOverride: ThinkingLevel | undefined,
|
|
810
|
+
reason: string,
|
|
811
|
+
): OracleSelection {
|
|
812
|
+
const thinking = resolveThinkingLevel(model, thinkingLevelOverride);
|
|
813
|
+
return {
|
|
814
|
+
modelRef: `${model.provider}/${model.id}`,
|
|
815
|
+
provider: model.provider,
|
|
816
|
+
modelId: model.id,
|
|
817
|
+
modelName: model.name,
|
|
818
|
+
thinkingLevel: thinking.effective,
|
|
819
|
+
...(thinking.clamped ? { requestedThinkingLevel: thinking.requested, thinkingLevelClamped: true } : {}),
|
|
820
|
+
autoSelected: true,
|
|
821
|
+
selectionReason: appendThinkingLevelClampReason(reason, thinking),
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
function buildSessionFallbackSelection(
|
|
826
|
+
ctx: { model?: PiModel },
|
|
827
|
+
thinkingLevelOverride: ThinkingLevel | undefined,
|
|
828
|
+
): OracleSelection | undefined {
|
|
829
|
+
const model = ctx.model;
|
|
830
|
+
if (!model) return undefined;
|
|
831
|
+
return toOracleSelection(
|
|
832
|
+
model,
|
|
833
|
+
thinkingLevelOverride,
|
|
834
|
+
`Used the current session model ${model.provider}/${model.id} as a final fallback.`,
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
function withFallbackReason(selection: OracleSelection, previous: OracleSelection): OracleSelection {
|
|
839
|
+
return {
|
|
840
|
+
...selection,
|
|
841
|
+
selectionReason: `${selection.selectionReason} (Fell back from ${previous.modelRef} after a model-availability error.)`,
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
|
|
779
845
|
async function selectOracleModel(
|
|
780
846
|
ctx: { model?: PiModel; modelRegistry: { getAvailable(): PiModel[] | Promise<PiModel[]> } },
|
|
781
847
|
thinkingLevelOverride?: ThinkingLevel,
|
|
782
|
-
): Promise<{ ok: true; selection: OracleSelection } | { ok: false; error: string }> {
|
|
848
|
+
): Promise<{ ok: true; selection: OracleSelection; ordered: OracleSelection[] } | { ok: false; error: string }> {
|
|
783
849
|
const available = await ctx.modelRegistry.getAvailable();
|
|
784
850
|
if (available.length === 0) {
|
|
785
851
|
return {
|
|
@@ -810,27 +876,23 @@ async function selectOracleModel(
|
|
|
810
876
|
reason = "No reasoning models were available, so the top-ranked model across all available providers was used.";
|
|
811
877
|
}
|
|
812
878
|
|
|
879
|
+
const sorted = [...candidates].sort((a, b) => rankModel(b) - rankModel(a));
|
|
813
880
|
const preferred = selectPreferredModel(candidates, providerForPreferences);
|
|
814
|
-
const
|
|
815
|
-
|
|
816
|
-
const
|
|
817
|
-
|
|
818
|
-
|
|
881
|
+
const orderedModels = preferred ? [preferred, ...sorted.filter((model) => model !== preferred)] : sorted;
|
|
882
|
+
|
|
883
|
+
const ordered = orderedModels.map((model, index) =>
|
|
884
|
+
toOracleSelection(
|
|
885
|
+
model,
|
|
886
|
+
thinkingLevelOverride,
|
|
887
|
+
index === 0
|
|
888
|
+
? preferred
|
|
889
|
+
? `Selected ${model.id} via the hardcoded preference list for ${model.provider}.`
|
|
890
|
+
: reason
|
|
891
|
+
: `Auto-selected ${model.provider}/${model.id} as a lower-ranked fallback.`,
|
|
892
|
+
),
|
|
819
893
|
);
|
|
820
894
|
|
|
821
|
-
return {
|
|
822
|
-
ok: true,
|
|
823
|
-
selection: {
|
|
824
|
-
modelRef: `${winner.provider}/${winner.id}`,
|
|
825
|
-
provider: winner.provider,
|
|
826
|
-
modelId: winner.id,
|
|
827
|
-
modelName: winner.name,
|
|
828
|
-
thinkingLevel: thinking.effective,
|
|
829
|
-
...(thinking.clamped ? { requestedThinkingLevel: thinking.requested, thinkingLevelClamped: true } : {}),
|
|
830
|
-
autoSelected: true,
|
|
831
|
-
selectionReason,
|
|
832
|
-
},
|
|
833
|
-
};
|
|
895
|
+
return { ok: true, selection: ordered[0], ordered };
|
|
834
896
|
}
|
|
835
897
|
|
|
836
898
|
function updateOracleUi(ctx: ExtensionContext, activeRuns: Map<string, OracleUiRun>): void {
|
|
@@ -1061,6 +1123,13 @@ function renderCollapsedText(text: string, lineLimit = COLLAPSED_LINE_LIMIT): st
|
|
|
1061
1123
|
return [...lines.slice(0, lineLimit), `... (${lines.length - lineLimit} more lines)`].join("\n");
|
|
1062
1124
|
}
|
|
1063
1125
|
|
|
1126
|
+
export const __test__ = {
|
|
1127
|
+
findAvailableModel,
|
|
1128
|
+
parseModelPreference,
|
|
1129
|
+
resolveThinkingLevel,
|
|
1130
|
+
selectOracleModel,
|
|
1131
|
+
};
|
|
1132
|
+
|
|
1064
1133
|
export default function oracleExtension(pi: ExtensionAPI) {
|
|
1065
1134
|
const activeRuns = new Map<string, OracleUiRun>();
|
|
1066
1135
|
let preferences: OraclePreferences = {};
|
|
@@ -1177,7 +1246,7 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1177
1246
|
return;
|
|
1178
1247
|
}
|
|
1179
1248
|
|
|
1180
|
-
notifyCommand(ctx, "Usage: /oracle status | model <provider/model|auto> | thinking <off|minimal|low|medium|high|xhigh|auto> | clear [all|model|thinking]", "warning");
|
|
1249
|
+
notifyCommand(ctx, "Usage: /oracle status | model <provider/model|auto> | thinking <off|minimal|low|medium|high|xhigh|max|auto> | clear [all|model|thinking]", "warning");
|
|
1181
1250
|
},
|
|
1182
1251
|
});
|
|
1183
1252
|
|
|
@@ -1223,13 +1292,17 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1223
1292
|
parameters: OracleParams,
|
|
1224
1293
|
|
|
1225
1294
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
1295
|
+
const rawTask = (params as { task?: unknown }).task;
|
|
1296
|
+
const task = typeof rawTask === "string" ? rawTask.trim() : "";
|
|
1297
|
+
if (!task) throw new Error("Invalid parameters: expected task to be a non-empty string.");
|
|
1298
|
+
|
|
1226
1299
|
const explicitModel = parseModelPreference(params.model);
|
|
1227
1300
|
const defaultModel = parseModelPreference(preferences.model);
|
|
1228
1301
|
const configuredModel = explicitModel.model ?? defaultModel.model;
|
|
1229
1302
|
const configuredThinkingLevel =
|
|
1230
1303
|
params.thinkingLevel ?? explicitModel.thinkingLevel ?? preferences.thinkingLevel ?? defaultModel.thinkingLevel;
|
|
1231
1304
|
const uiRun: OracleUiRun = {
|
|
1232
|
-
task
|
|
1305
|
+
task,
|
|
1233
1306
|
includeBash: params.includeBash ?? false,
|
|
1234
1307
|
startedAt: Date.now(),
|
|
1235
1308
|
};
|
|
@@ -1237,7 +1310,16 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1237
1310
|
updateOracleUi(ctx, activeRuns);
|
|
1238
1311
|
|
|
1239
1312
|
try {
|
|
1240
|
-
|
|
1313
|
+
const attempts: OracleSelection[] = [];
|
|
1314
|
+
const seen = new Set<string>();
|
|
1315
|
+
const pushAttempt = (candidate: OracleSelection | undefined) => {
|
|
1316
|
+
if (!candidate) return;
|
|
1317
|
+
const key = `${candidate.provider}/${candidate.modelId}`.toLowerCase();
|
|
1318
|
+
if (seen.has(key)) return;
|
|
1319
|
+
seen.add(key);
|
|
1320
|
+
attempts.push(candidate);
|
|
1321
|
+
};
|
|
1322
|
+
|
|
1241
1323
|
if (configuredModel) {
|
|
1242
1324
|
const modelRef = configuredModel;
|
|
1243
1325
|
const matched = await findAvailableModel(ctx, modelRef);
|
|
@@ -1256,7 +1338,7 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1256
1338
|
: usedToolOverride
|
|
1257
1339
|
? "Used the explicit model override provided in the tool call. The model was not matched against the authenticated model list, so the reasoning level fallback was applied."
|
|
1258
1340
|
: "Used the configured default oracle model. The model was not matched against the authenticated model list, so the reasoning level fallback was applied.";
|
|
1259
|
-
|
|
1341
|
+
pushAttempt({
|
|
1260
1342
|
modelRef: matched ? `${matched.provider}/${matched.id}` : modelRef,
|
|
1261
1343
|
provider,
|
|
1262
1344
|
modelId,
|
|
@@ -1267,7 +1349,7 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1267
1349
|
: {}),
|
|
1268
1350
|
autoSelected: false,
|
|
1269
1351
|
selectionReason,
|
|
1270
|
-
};
|
|
1352
|
+
});
|
|
1271
1353
|
} else {
|
|
1272
1354
|
const selectionResult = await selectOracleModel(ctx, configuredThinkingLevel);
|
|
1273
1355
|
if (!selectionResult.ok) {
|
|
@@ -1290,11 +1372,14 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1290
1372
|
},
|
|
1291
1373
|
};
|
|
1292
1374
|
}
|
|
1293
|
-
|
|
1375
|
+
for (const candidate of selectionResult.ordered) pushAttempt(candidate);
|
|
1294
1376
|
}
|
|
1295
1377
|
|
|
1296
|
-
|
|
1297
|
-
|
|
1378
|
+
// Keep the known-good session model as a final fallback: the catalog can
|
|
1379
|
+
// advertise models the active provider/subscription cannot actually serve
|
|
1380
|
+
// (legacy snapshots, access-gated tiers), which fail with a not-found/404
|
|
1381
|
+
// error. Falling back lets the run degrade gracefully instead of hard-failing.
|
|
1382
|
+
pushAttempt(buildSessionFallbackSelection(ctx, configuredThinkingLevel));
|
|
1298
1383
|
|
|
1299
1384
|
const handleUpdate = (partial: { content: Array<{ type: "text"; text: string }>; details: OracleDetails }) => {
|
|
1300
1385
|
uiRun.preview = partial.content[0]?.text ?? uiRun.preview;
|
|
@@ -1302,17 +1387,51 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1302
1387
|
onUpdate?.(partial);
|
|
1303
1388
|
};
|
|
1304
1389
|
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1390
|
+
let lastErrorResult: { ok: false; error: string; details: OracleDetails } | undefined;
|
|
1391
|
+
for (let index = 0; index < attempts.length; index++) {
|
|
1392
|
+
const previous = index > 0 ? attempts[index - 1] : undefined;
|
|
1393
|
+
const attempt = previous ? withFallbackReason(attempts[index], previous) : attempts[index];
|
|
1394
|
+
uiRun.selection = attempt;
|
|
1395
|
+
updateOracleUi(ctx, activeRuns);
|
|
1396
|
+
|
|
1397
|
+
const result = await runOracle(attempt, { ...params, task }, signal, handleUpdate, ctx.cwd);
|
|
1398
|
+
if (result.ok) {
|
|
1399
|
+
return {
|
|
1400
|
+
content: [{ type: "text", text: result.output }],
|
|
1401
|
+
details: result.details,
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
lastErrorResult = result;
|
|
1406
|
+
const canFallBack = index < attempts.length - 1 && isModelAvailabilityError(result.error);
|
|
1407
|
+
if (!canFallBack) {
|
|
1408
|
+
return {
|
|
1409
|
+
content: [{ type: "text", text: result.error }],
|
|
1410
|
+
details: result.details,
|
|
1411
|
+
};
|
|
1412
|
+
}
|
|
1311
1413
|
}
|
|
1312
1414
|
|
|
1313
1415
|
return {
|
|
1314
|
-
content: [
|
|
1315
|
-
|
|
1416
|
+
content: [
|
|
1417
|
+
{ type: "text", text: lastErrorResult?.error ?? "Oracle could not select an available model." },
|
|
1418
|
+
],
|
|
1419
|
+
details:
|
|
1420
|
+
lastErrorResult?.details ?? {
|
|
1421
|
+
modelRef: "",
|
|
1422
|
+
provider: ctx.model?.provider ?? "unknown",
|
|
1423
|
+
modelId: "",
|
|
1424
|
+
modelName: undefined,
|
|
1425
|
+
thinkingLevel: configuredThinkingLevel ?? DEFAULT_THINKING_LEVEL,
|
|
1426
|
+
autoSelected: true,
|
|
1427
|
+
selectionReason: "No authenticated models were available to run the oracle.",
|
|
1428
|
+
includeBash: params.includeBash ?? false,
|
|
1429
|
+
usage: createEmptyUsage(),
|
|
1430
|
+
stderr: "",
|
|
1431
|
+
exitCode: 1,
|
|
1432
|
+
durationMs: 0,
|
|
1433
|
+
cwd: params.cwd ?? ctx.cwd,
|
|
1434
|
+
},
|
|
1316
1435
|
};
|
|
1317
1436
|
} finally {
|
|
1318
1437
|
activeRuns.delete(toolCallId);
|
package/package.json
CHANGED