pi-io-provider 1.1.2 → 1.1.4

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
@@ -16,37 +16,37 @@ A [pi](https://github.com/badlogic/pi-mono) extension that adds [IO Intelligence
16
16
 
17
17
  | Model | ID | Context | Max Output | Vision | Reasoning | Cache | Input $/M | Output $/M |
18
18
  |-------|----|---------|------------|--------|-----------|-------|-----------|------------|
19
+ | Kimi K2.5 | `moonshotai/Kimi-K2.5` | 262K | 262K | ✅ | ✅ | ✅ | $0.56 | $2.94 |
20
+ | Kimi K2.6 | `moonshotai/Kimi-K2.6` | 262K | 262K | ✅ | ✅ | ✅ | $0.86 | $3.64 |
21
+ | Kimi K2.7 Code | `moonshotai/Kimi-K2.7-Code` | 262K | 262K | ✅ | ✅ | ✅ | $1.01 | $4.53 |
22
+ | Kimi K3 | `moonshotai/Kimi-K3` | 1.0M | 1.0M | ✅ | ✅ | ✅ | $3.90 | $18.00 |
23
+ | Qwen3.6 27B | `Qwen/Qwen3.6-27B` | 33K | 33K | ✅ | ✅ | ✅ | $0.37 | $3.03 |
24
+ | Qwen3.6 35B A3B | `Qwen/Qwen3.6-35B-A3B` | 262K | 262K | ✅ | ✅ | ✅ | $0.18 | $1.12 |
19
25
  | DeepSeek R1 0528 | `deepseek-ai/DeepSeek-R1-0528` | 128K | 128K | ❌ | ✅ | ✅ | $0.57 | $2.28 |
26
+ | DeepSeek V3.2 | `deepseek-ai/DeepSeek-V3.2` | 164K | 164K | ❌ | ✅ | ✅ | $0.39 | $1.09 |
27
+ | DeepSeek V4 Flash | `deepseek-ai/DeepSeek-V4-Flash` | 33K | 33K | ❌ | ✅ | ✅ | $0.14 | $0.28 |
28
+ | DeepSeek V4 Flash 0731 | `deepseek-ai/DeepSeek-V4-Flash-0731` | 262K | 66K | ❌ | ✅ | ✅ | $0.16 | $0.33 |
29
+ | DeepSeek V4 Pro | `deepseek-ai/DeepSeek-V4-Pro` | 1.0M | 600K | ❌ | ✅ | ✅ | $1.51 | $3.05 |
30
+ | Gemma 4 26B A4B | `google/gemma-4-26b-a4b-it` | 262K | 262K | ❌ | ✅ | ✅ | $0.12 | $0.42 |
31
+ | MiniMax M2.5 | `MiniMaxAI/MiniMax-M2.5` | 197K | 197K | ❌ | ✅ | ✅ | $0.27 | $1.07 |
32
+ | MiniMax M2.7 | `MiniMaxAI/MiniMax-M2.7` | 262K | 66K | ❌ | ✅ | ✅ | $0.43 | $1.62 |
20
33
  | Kimi K2 Thinking | `moonshotai/Kimi-K2-Thinking` | 262K | 262K | ❌ | ✅ | ✅ | $0.60 | $2.50 |
21
- | Llama 3.2 90B Vision Instruct | `meta-llama/Llama-3.2-90B-Vision-Instruct` | 16K | 16K | | | ✅ | $0.34 | $0.34 |
22
- | Llama 4 Maverick 17B 128E Instruct FP8 | `meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8` | 430K | 430K | | | ✅ | $0.28 | $0.93 |
23
- | Kimi K2.5 | `moonshotai/Kimi-K2.5` | 262K | 262K | | | ✅ | $0.53 | $2.79 |
24
- | Kimi K2.6 | `moonshotai/Kimi-K2.6` | 262K | 262K | | | ✅ | $0.84 | $3.76 |
25
- | DeepSeek V3.2 | `deepseek-ai/DeepSeek-V3.2` | 164K | 164K | ❌ | | ✅ | $0.90 | $1.76 |
26
- | DeepSeek V4 Flash | `deepseek-ai/DeepSeek-V4-Flash` | 33K | 33K | ❌ | | ✅ | $0.20 | $0.37 |
27
- | DeepSeek V4 Pro | `deepseek-ai/DeepSeek-V4-Pro` | 1.0M | 600K | ❌ | | ✅ | $1.62 | $3.25 |
28
- | Gemma 4 26B A4B | `google/gemma-4-26b-a4b-it` | 262K | 262K | ❌ | | ✅ | $0.12 | $0.39 |
29
- | Qwen3 Coder 480B A35B Instruct INT4 Mixed AR | `Intel/Qwen3-Coder-480B-A35B-Instruct-int4-mixed-ar` | 106K | 106K | ❌ | | ✅ | $0.58 | $2.25 |
30
- | Llama 3.3 70B Instruct | `meta-llama/Llama-3.3-70B-Instruct` | 128K | 128K | ❌ | | ✅ | $0.51 | $1.04 |
31
- | MiniMax M2.5 | `MiniMaxAI/MiniMax-M2.5` | 197K | 197K | | ❌ | ✅ | $0.28 | $1.13 |
32
- | MiniMax M2.7 | `MiniMaxAI/MiniMax-M2.7` | 205K | 205K | ❌ | ❌ | ✅ | $0.42 | $1.62 |
33
- | Mistral Nemo Instruct 2407 | `mistralai/Mistral-Nemo-Instruct-2407` | 128K | 128K | ❌ | ❌ | ✅ | $0.07 | $0.12 |
34
+ | gpt-oss-120b | `openai/gpt-oss-120b` | 131K | 131K | | | ✅ | $0.18 | $0.71 |
35
+ | gpt-oss-20b | `openai/gpt-oss-20b` | 64K | 64K | | | ✅ | $0.06 | $0.22 |
36
+ | MiMo-V2.5 | `XiaomiMiMo/MiMo-V2.5` | 262K | 262K | | | ✅ | $0.20 | $0.64 |
37
+ | GLM-4.5-Air | `zai-org/GLM-4.5-Air` | 131K | 131K | | | ✅ | $0.16 | $0.94 |
38
+ | GLM 4.6 | `zai-org/GLM-4.6` | 131K | 131K | ❌ | | ✅ | $0.54 | $2.07 |
39
+ | GLM 4.7 | `zai-org/GLM-4.7` | 203K | 203K | ❌ | | ✅ | $0.88 | $2.37 |
40
+ | GLM 4.7 Flash | `zai-org/GLM-4.7-Flash` | 200K | 200K | ❌ | | ✅ | $0.06 | $0.40 |
41
+ | GLM 5 | `zai-org/GLM-5` | 203K | 203K | ❌ | | ✅ | $0.76 | $2.36 |
42
+ | GLM 5.1 | `zai-org/GLM-5.1` | 203K | 33K | ❌ | | ✅ | $1.21 | $3.98 |
43
+ | GLM 5.2 | `zai-org/GLM-5.2` | 262K | 66K | ❌ | | ✅ | $1.28 | $4.14 |
44
+ | Llama 4 Maverick 17B 128E Instruct FP8 | `meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8` | 430K | 430K | | ❌ | ✅ | $0.27 | $0.90 |
45
+ | Qwen3 Coder 480B A35B Instruct INT4 Mixed AR | `Intel/Qwen3-Coder-480B-A35B-Instruct-int4-mixed-ar` | 106K | 106K | ❌ | ❌ | ✅ | $0.45 | $2.15 |
46
+ | Llama 3.3 70B Instruct | `meta-llama/Llama-3.3-70B-Instruct` | 128K | 128K | ❌ | ❌ | ✅ | $0.61 | $0.84 |
47
+ | Mistral Nemo Instruct 2407 | `mistralai/Mistral-Nemo-Instruct-2407` | 128K | 128K | ❌ | ❌ | ✅ | $0.03 | $0.08 |
34
48
  | Kimi K2 Instruct 0905 | `moonshotai/Kimi-K2-Instruct-0905` | 262K | 262K | ❌ | ❌ | ✅ | $0.57 | $2.30 |
35
- | Kimi K2.7 Code | `moonshotai/Kimi-K2.7-Code` | 262K | 262K | ❌ | ❌ | ✅ | $1.10 | $4.70 |
36
- | Kimi K3 | `moonshotai/Kimi-K3` | 1.0M | 1.0M | ❌ | ❌ | ✅ | $3.28 | $16.30 |
37
- | gpt-oss-120b | `openai/gpt-oss-120b` | 131K | 131K | ❌ | ❌ | ✅ | $0.19 | $0.70 |
38
- | gpt-oss-20b | `openai/gpt-oss-20b` | 64K | 64K | ❌ | ❌ | ✅ | $0.06 | $0.22 |
39
49
  | Qwen3 Next 80B A3B Instruct | `Qwen/Qwen3-Next-80B-A3B-Instruct` | 262K | 262K | ❌ | ❌ | ✅ | $0.12 | $1.14 |
40
- | Qwen3.6 27B | `Qwen/Qwen3.6-27B` | 33K | 33K | ❌ | ❌ | ✅ | $0.40 | $3.09 |
41
- | Qwen3.6 35B A3B | `Qwen/Qwen3.6-35B-A3B` | 262K | 262K | ❌ | ❌ | ✅ | $0.18 | $1.19 |
42
- | MiMo-V2.5 | `XiaomiMiMo/MiMo-V2.5` | 262K | 262K | ❌ | ❌ | ✅ | $0.20 | $0.64 |
43
- | GLM-4.5-Air | `zai-org/GLM-4.5-Air` | 131K | 131K | ❌ | ❌ | ✅ | $0.16 | $0.94 |
44
- | GLM 4.6 | `zai-org/GLM-4.6` | 131K | 131K | ❌ | ❌ | ✅ | $0.54 | $2.07 |
45
- | GLM 4.7 | `zai-org/GLM-4.7` | 203K | 203K | ❌ | ❌ | ✅ | $0.86 | $2.24 |
46
- | GLM 4.7 Flash | `zai-org/GLM-4.7-Flash` | 200K | 200K | ❌ | ❌ | ✅ | $0.08 | $0.42 |
47
- | GLM 5 | `zai-org/GLM-5` | 203K | 203K | ❌ | ❌ | ✅ | $0.86 | $2.78 |
48
- | GLM 5.1 | `zai-org/GLM-5.1` | 203K | 33K | ❌ | ❌ | ✅ | $1.29 | $4.22 |
49
- | GLM 5.2 | `zai-org/GLM-5.2` | 262K | 66K | ❌ | ❌ | ✅ | $1.96 | $6.16 |
50
50
 
51
51
  *Costs are per million tokens. Cache read/write pricing available on most models.*
52
52
 
@@ -1 +1,25 @@
1
- {}
1
+ {
2
+ "meta-llama/Llama-3.2-90B-Vision-Instruct": {
3
+ "id": "meta-llama/Llama-3.2-90B-Vision-Instruct",
4
+ "name": "Llama 3.2 90B Vision Instruct",
5
+ "reasoning": false,
6
+ "input": [
7
+ "text",
8
+ "image"
9
+ ],
10
+ "cost": {
11
+ "input": 0.345,
12
+ "output": 0.345,
13
+ "cacheRead": 0.1725,
14
+ "cacheWrite": 0.7
15
+ },
16
+ "contextWindow": 16000,
17
+ "maxTokens": 16000,
18
+ "compat": {
19
+ "supportsStore": false,
20
+ "supportsDeveloperRole": false,
21
+ "maxTokensField": "max_tokens"
22
+ },
23
+ "deprecatedAt": "2026-08-11T02:00:10.112Z"
24
+ }
25
+ }
package/index.ts CHANGED
@@ -59,12 +59,14 @@ interface JsonModel {
59
59
  };
60
60
  contextWindow: number;
61
61
  maxTokens: number;
62
+ thinkingLevelMap?: Record<string, string | null>;
62
63
  compat?: {
63
64
  supportsDeveloperRole?: boolean;
64
65
  supportsStore?: boolean;
65
66
  maxTokensField?: "max_completion_tokens" | "max_tokens";
66
67
  thinkingFormat?: "openai" | "zai" | "qwen" | "qwen-chat-template";
67
68
  supportsReasoningEffort?: boolean;
69
+ requiresReasoningContentOnAssistantMessages?: boolean;
68
70
  };
69
71
  }
70
72
 
@@ -80,6 +82,7 @@ interface PatchEntry {
80
82
  };
81
83
  contextWindow?: number;
82
84
  maxTokens?: number;
85
+ thinkingLevelMap?: Record<string, string | null>;
83
86
  compat?: Record<string, unknown>;
84
87
  }
85
88
 
@@ -95,6 +98,7 @@ function applyPatch(model: JsonModel, patch: PatchEntry): JsonModel {
95
98
  if (patch.input !== undefined) result.input = patch.input;
96
99
  if (patch.contextWindow !== undefined) result.contextWindow = patch.contextWindow;
97
100
  if (patch.maxTokens !== undefined) result.maxTokens = patch.maxTokens;
101
+ if (patch.thinkingLevelMap !== undefined) result.thinkingLevelMap = { ...patch.thinkingLevelMap };
98
102
 
99
103
  if (patch.cost) {
100
104
  result.cost = {
@@ -111,6 +115,9 @@ function applyPatch(model: JsonModel, patch: PatchEntry): JsonModel {
111
115
  if (!result.reasoning && result.compat?.thinkingFormat) {
112
116
  delete result.compat.thinkingFormat;
113
117
  }
118
+ if (!result.reasoning && result.thinkingLevelMap) {
119
+ delete result.thinkingLevelMap;
120
+ }
114
121
  if (result.compat && Object.keys(result.compat).length === 0) {
115
122
  delete result.compat;
116
123
  }
@@ -164,7 +171,7 @@ const LIVE_FETCH_TIMEOUT_MS = 8000;
164
171
 
165
172
  /** Transform a model from the IO Intelligence /v1/models API to JsonModel format. */
166
173
  function transformApiModel(apiModel: any): JsonModel | null {
167
- const hasVision = apiModel.supports_images_input === true;
174
+ const hasVision = apiModel.supports_images_input === true || (apiModel.input_modalities || []).includes("image");
168
175
  // IO returns per-token pricing, convert to per-million. Round to 6 decimals to
169
176
  // normalize float noise from the ×1e6 multiply and preserve sub-cent cache prices.
170
177
  const toPerM = (v: any) => Math.round((typeof v === "number" ? v * 1_000_000 : 0) * 1e6) / 1e6;
@@ -181,13 +188,14 @@ function transformApiModel(apiModel: any): JsonModel | null {
181
188
  cacheWrite: toPerM(apiModel.cache_write_token_price),
182
189
  },
183
190
  contextWindow: apiModel.context_window || 131072,
184
- maxTokens: apiModel.max_tokens || 0,
191
+ maxTokens: apiModel.max_tokens || apiModel.context_window || 131072,
192
+ compat: {
193
+ supportsStore: false,
194
+ supportsDeveloperRole: false,
195
+ maxTokensField: "max_tokens",
196
+ ...(hasReasoning ? { supportsReasoningEffort: true } : {}),
197
+ },
185
198
  };
186
- if (hasReasoning) {
187
- model.compat = {
188
- supportsReasoningEffort: true,
189
- };
190
- }
191
199
  return model;
192
200
  }
193
201
 
package/models.json CHANGED
@@ -1,24 +1,53 @@
1
1
  [
2
+ {
3
+ "id": "deepseek-ai/DeepSeek-V4-Flash-0731",
4
+ "name": "DeepSeek V4 Flash 0731",
5
+ "reasoning": true,
6
+ "input": [
7
+ "text"
8
+ ],
9
+ "cost": {
10
+ "input": 0.164,
11
+ "output": 0.332,
12
+ "cacheRead": 0.082,
13
+ "cacheWrite": 0
14
+ },
15
+ "contextWindow": 262100,
16
+ "maxTokens": 65536,
17
+ "compat": {
18
+ "supportsStore": false,
19
+ "supportsDeveloperRole": false,
20
+ "maxTokensField": "max_tokens",
21
+ "supportsReasoningEffort": true
22
+ }
23
+ },
2
24
  {
3
25
  "id": "moonshotai/Kimi-K3",
4
26
  "name": "Kimi K3",
5
- "reasoning": false,
27
+ "reasoning": true,
6
28
  "input": [
7
- "text"
29
+ "text",
30
+ "image"
8
31
  ],
9
32
  "cost": {
10
- "input": 3.28,
11
- "output": 16.3,
12
- "cacheRead": 1.64,
33
+ "input": 3.9,
34
+ "output": 18,
35
+ "cacheRead": 1.95,
13
36
  "cacheWrite": 0
14
37
  },
15
38
  "contextWindow": 1048576,
16
- "maxTokens": 1048576
39
+ "maxTokens": 1048576,
40
+ "compat": {
41
+ "supportsStore": false,
42
+ "supportsDeveloperRole": false,
43
+ "maxTokensField": "max_tokens",
44
+ "supportsReasoningEffort": true
45
+ }
17
46
  },
18
47
  {
19
48
  "id": "XiaomiMiMo/MiMo-V2.5",
20
49
  "name": "MiMo-V2.5",
21
- "reasoning": false,
50
+ "reasoning": true,
22
51
  "input": [
23
52
  "text"
24
53
  ],
@@ -29,217 +58,304 @@
29
58
  "cacheWrite": 0
30
59
  },
31
60
  "contextWindow": 262144,
32
- "maxTokens": 262144
61
+ "maxTokens": 262144,
62
+ "compat": {
63
+ "supportsStore": false,
64
+ "supportsDeveloperRole": false,
65
+ "maxTokensField": "max_tokens",
66
+ "supportsReasoningEffort": true
67
+ }
33
68
  },
34
69
  {
35
70
  "id": "zai-org/GLM-5.2",
36
71
  "name": "GLM 5.2",
37
- "reasoning": false,
72
+ "reasoning": true,
38
73
  "input": [
39
74
  "text"
40
75
  ],
41
76
  "cost": {
42
- "input": 1.96,
43
- "output": 6.16,
44
- "cacheRead": 0.98,
77
+ "input": 1.282,
78
+ "output": 4.144,
79
+ "cacheRead": 0.641,
45
80
  "cacheWrite": 0
46
81
  },
47
82
  "contextWindow": 262144,
48
- "maxTokens": 65536
83
+ "maxTokens": 65536,
84
+ "compat": {
85
+ "supportsStore": false,
86
+ "supportsDeveloperRole": false,
87
+ "maxTokensField": "max_tokens",
88
+ "supportsReasoningEffort": true
89
+ }
49
90
  },
50
91
  {
51
92
  "id": "moonshotai/Kimi-K2.7-Code",
52
93
  "name": "Kimi K2.7 Code",
53
- "reasoning": false,
94
+ "reasoning": true,
54
95
  "input": [
55
- "text"
96
+ "text",
97
+ "image"
56
98
  ],
57
99
  "cost": {
58
- "input": 1.098,
59
- "output": 4.7,
60
- "cacheRead": 0.549,
100
+ "input": 1.014,
101
+ "output": 4.528,
102
+ "cacheRead": 0.507,
61
103
  "cacheWrite": 0
62
104
  },
63
105
  "contextWindow": 262144,
64
- "maxTokens": 262144
106
+ "maxTokens": 262144,
107
+ "compat": {
108
+ "supportsStore": false,
109
+ "supportsDeveloperRole": false,
110
+ "maxTokensField": "max_tokens",
111
+ "supportsReasoningEffort": true
112
+ }
65
113
  },
66
114
  {
67
115
  "id": "Qwen/Qwen3.6-35B-A3B",
68
116
  "name": "Qwen3.6 35B A3B",
69
- "reasoning": false,
117
+ "reasoning": true,
70
118
  "input": [
71
- "text"
119
+ "text",
120
+ "image"
72
121
  ],
73
122
  "cost": {
74
- "input": 0.1752,
75
- "output": 1.19275,
76
- "cacheRead": 0.0876,
123
+ "input": 0.1768,
124
+ "output": 1.11675,
125
+ "cacheRead": 0.0884,
77
126
  "cacheWrite": 0
78
127
  },
79
128
  "contextWindow": 262140,
80
- "maxTokens": 262140
129
+ "maxTokens": 262140,
130
+ "compat": {
131
+ "supportsStore": false,
132
+ "supportsDeveloperRole": false,
133
+ "maxTokensField": "max_tokens",
134
+ "supportsReasoningEffort": true
135
+ }
81
136
  },
82
137
  {
83
138
  "id": "Qwen/Qwen3.6-27B",
84
139
  "name": "Qwen3.6 27B",
85
- "reasoning": false,
140
+ "reasoning": true,
86
141
  "input": [
87
- "text"
142
+ "text",
143
+ "image"
88
144
  ],
89
145
  "cost": {
90
- "input": 0.403,
91
- "output": 3.09,
92
- "cacheRead": 0.2015,
146
+ "input": 0.3708,
147
+ "output": 3.03,
148
+ "cacheRead": 0.1854,
93
149
  "cacheWrite": 0
94
150
  },
95
151
  "contextWindow": 32768,
96
- "maxTokens": 32768
152
+ "maxTokens": 32768,
153
+ "compat": {
154
+ "supportsStore": false,
155
+ "supportsDeveloperRole": false,
156
+ "maxTokensField": "max_tokens",
157
+ "supportsReasoningEffort": true
158
+ }
97
159
  },
98
160
  {
99
161
  "id": "MiniMaxAI/MiniMax-M2.7",
100
162
  "name": "MiniMax M2.7",
101
- "reasoning": false,
163
+ "reasoning": true,
102
164
  "input": [
103
165
  "text"
104
166
  ],
105
167
  "cost": {
106
- "input": 0.42,
168
+ "input": 0.426,
107
169
  "output": 1.62,
108
- "cacheRead": 0.21,
170
+ "cacheRead": 0.213,
109
171
  "cacheWrite": 0
110
172
  },
111
- "contextWindow": 204800,
112
- "maxTokens": 204800
173
+ "contextWindow": 262100,
174
+ "maxTokens": 65536,
175
+ "compat": {
176
+ "supportsStore": false,
177
+ "supportsDeveloperRole": false,
178
+ "maxTokensField": "max_tokens",
179
+ "supportsReasoningEffort": true
180
+ }
113
181
  },
114
182
  {
115
183
  "id": "deepseek-ai/DeepSeek-V4-Flash",
116
184
  "name": "DeepSeek V4 Flash",
117
- "reasoning": false,
185
+ "reasoning": true,
118
186
  "input": [
119
187
  "text"
120
188
  ],
121
189
  "cost": {
122
- "input": 0.20346,
123
- "output": 0.36692,
124
- "cacheRead": 0.10173,
190
+ "input": 0.1388,
191
+ "output": 0.2776,
192
+ "cacheRead": 0.0694,
125
193
  "cacheWrite": 0
126
194
  },
127
195
  "contextWindow": 32768,
128
- "maxTokens": 32768
196
+ "maxTokens": 32768,
197
+ "compat": {
198
+ "supportsStore": false,
199
+ "supportsDeveloperRole": false,
200
+ "maxTokensField": "max_tokens",
201
+ "supportsReasoningEffort": true
202
+ }
129
203
  },
130
204
  {
131
205
  "id": "deepseek-ai/DeepSeek-V4-Pro",
132
206
  "name": "DeepSeek V4 Pro",
133
- "reasoning": false,
207
+ "reasoning": true,
134
208
  "input": [
135
209
  "text"
136
210
  ],
137
211
  "cost": {
138
- "input": 1.624,
139
- "output": 3.2482,
140
- "cacheRead": 0.812,
212
+ "input": 1.513124,
213
+ "output": 3.0526,
214
+ "cacheRead": 0.756562,
141
215
  "cacheWrite": 0
142
216
  },
143
217
  "contextWindow": 1048576,
144
- "maxTokens": 600000
218
+ "maxTokens": 600000,
219
+ "compat": {
220
+ "supportsStore": false,
221
+ "supportsDeveloperRole": false,
222
+ "maxTokensField": "max_tokens",
223
+ "supportsReasoningEffort": true
224
+ }
145
225
  },
146
226
  {
147
227
  "id": "moonshotai/Kimi-K2.6",
148
228
  "name": "Kimi K2.6",
149
- "reasoning": false,
229
+ "reasoning": true,
150
230
  "input": [
151
231
  "text",
152
232
  "image"
153
233
  ],
154
234
  "cost": {
155
- "input": 0.84,
156
- "output": 3.762,
157
- "cacheRead": 0.42,
235
+ "input": 0.85986,
236
+ "output": 3.64456,
237
+ "cacheRead": 0.42993,
158
238
  "cacheWrite": 0
159
239
  },
160
240
  "contextWindow": 262142,
161
- "maxTokens": 262142
241
+ "maxTokens": 262142,
242
+ "compat": {
243
+ "supportsStore": false,
244
+ "supportsDeveloperRole": false,
245
+ "maxTokensField": "max_tokens",
246
+ "supportsReasoningEffort": true
247
+ }
162
248
  },
163
249
  {
164
250
  "id": "zai-org/GLM-5.1",
165
251
  "name": "GLM 5.1",
166
- "reasoning": false,
252
+ "reasoning": true,
167
253
  "input": [
168
254
  "text"
169
255
  ],
170
256
  "cost": {
171
- "input": 1.29,
172
- "output": 4.22,
173
- "cacheRead": 0.645,
257
+ "input": 1.21,
258
+ "output": 3.98,
259
+ "cacheRead": 0.605,
174
260
  "cacheWrite": 0
175
261
  },
176
262
  "contextWindow": 202750,
177
- "maxTokens": 32768
263
+ "maxTokens": 32768,
264
+ "compat": {
265
+ "supportsStore": false,
266
+ "supportsDeveloperRole": false,
267
+ "maxTokensField": "max_tokens",
268
+ "supportsReasoningEffort": true
269
+ }
178
270
  },
179
271
  {
180
272
  "id": "MiniMaxAI/MiniMax-M2.5",
181
273
  "name": "MiniMax M2.5",
182
- "reasoning": false,
274
+ "reasoning": true,
183
275
  "input": [
184
276
  "text"
185
277
  ],
186
278
  "cost": {
187
- "input": 0.282,
188
- "output": 1.128,
189
- "cacheRead": 0.141,
279
+ "input": 0.273,
280
+ "output": 1.066,
281
+ "cacheRead": 0.1365,
190
282
  "cacheWrite": 0
191
283
  },
192
284
  "contextWindow": 196600,
193
- "maxTokens": 196600
285
+ "maxTokens": 196600,
286
+ "compat": {
287
+ "supportsStore": false,
288
+ "supportsDeveloperRole": false,
289
+ "maxTokensField": "max_tokens",
290
+ "supportsReasoningEffort": true
291
+ }
194
292
  },
195
293
  {
196
294
  "id": "moonshotai/Kimi-K2.5",
197
295
  "name": "Kimi K2.5",
198
- "reasoning": false,
296
+ "reasoning": true,
199
297
  "input": [
200
298
  "text",
201
299
  "image"
202
300
  ],
203
301
  "cost": {
204
- "input": 0.528,
205
- "output": 2.79,
206
- "cacheRead": 0.264,
302
+ "input": 0.558,
303
+ "output": 2.94,
304
+ "cacheRead": 0.279,
207
305
  "cacheWrite": 1.1
208
306
  },
209
307
  "contextWindow": 262144,
210
- "maxTokens": 262144
308
+ "maxTokens": 262144,
309
+ "compat": {
310
+ "supportsStore": false,
311
+ "supportsDeveloperRole": false,
312
+ "maxTokensField": "max_tokens",
313
+ "supportsReasoningEffort": true
314
+ }
211
315
  },
212
316
  {
213
317
  "id": "zai-org/GLM-5",
214
318
  "name": "GLM 5",
215
- "reasoning": false,
319
+ "reasoning": true,
216
320
  "input": [
217
321
  "text"
218
322
  ],
219
323
  "cost": {
220
- "input": 0.86,
221
- "output": 2.784,
222
- "cacheRead": 0.43,
324
+ "input": 0.76,
325
+ "output": 2.356,
326
+ "cacheRead": 0.38,
223
327
  "cacheWrite": 0
224
328
  },
225
329
  "contextWindow": 202752,
226
- "maxTokens": 202752
330
+ "maxTokens": 202752,
331
+ "compat": {
332
+ "supportsStore": false,
333
+ "supportsDeveloperRole": false,
334
+ "maxTokensField": "max_tokens",
335
+ "supportsReasoningEffort": true
336
+ }
227
337
  },
228
338
  {
229
339
  "id": "deepseek-ai/DeepSeek-V3.2",
230
340
  "name": "DeepSeek V3.2",
231
- "reasoning": false,
341
+ "reasoning": true,
232
342
  "input": [
233
343
  "text"
234
344
  ],
235
345
  "cost": {
236
- "input": 0.90054,
237
- "output": 1.75646,
238
- "cacheRead": 0.45027,
346
+ "input": 0.3881,
347
+ "output": 1.0943,
348
+ "cacheRead": 0.19405,
239
349
  "cacheWrite": 0.5
240
350
  },
241
351
  "contextWindow": 163840,
242
- "maxTokens": 163840
352
+ "maxTokens": 163840,
353
+ "compat": {
354
+ "supportsStore": false,
355
+ "supportsDeveloperRole": false,
356
+ "maxTokensField": "max_tokens",
357
+ "supportsReasoningEffort": true
358
+ }
243
359
  },
244
360
  {
245
361
  "id": "moonshotai/Kimi-K2-Thinking",
@@ -255,12 +371,18 @@
255
371
  "cacheWrite": 0.64
256
372
  },
257
373
  "contextWindow": 262144,
258
- "maxTokens": 262144
374
+ "maxTokens": 262144,
375
+ "compat": {
376
+ "supportsStore": false,
377
+ "supportsDeveloperRole": false,
378
+ "maxTokensField": "max_tokens",
379
+ "supportsReasoningEffort": true
380
+ }
259
381
  },
260
382
  {
261
383
  "id": "zai-org/GLM-4.5-Air",
262
384
  "name": "GLM-4.5-Air",
263
- "reasoning": false,
385
+ "reasoning": true,
264
386
  "input": [
265
387
  "text"
266
388
  ],
@@ -271,55 +393,79 @@
271
393
  "cacheWrite": 0
272
394
  },
273
395
  "contextWindow": 131070,
274
- "maxTokens": 131070
396
+ "maxTokens": 131070,
397
+ "compat": {
398
+ "supportsStore": false,
399
+ "supportsDeveloperRole": false,
400
+ "maxTokensField": "max_tokens",
401
+ "supportsReasoningEffort": true
402
+ }
275
403
  },
276
404
  {
277
405
  "id": "google/gemma-4-26b-a4b-it",
278
406
  "name": "Gemma 4 26B A4B",
279
- "reasoning": false,
407
+ "reasoning": true,
280
408
  "input": [
281
409
  "text"
282
410
  ],
283
411
  "cost": {
284
- "input": 0.122,
285
- "output": 0.388,
286
- "cacheRead": 0.061,
412
+ "input": 0.124,
413
+ "output": 0.42,
414
+ "cacheRead": 0.062,
287
415
  "cacheWrite": 0
288
416
  },
289
417
  "contextWindow": 262142,
290
- "maxTokens": 262142
418
+ "maxTokens": 262142,
419
+ "compat": {
420
+ "supportsStore": false,
421
+ "supportsDeveloperRole": false,
422
+ "maxTokensField": "max_tokens",
423
+ "supportsReasoningEffort": true
424
+ }
291
425
  },
292
426
  {
293
427
  "id": "zai-org/GLM-4.7-Flash",
294
428
  "name": "GLM 4.7 Flash",
295
- "reasoning": false,
429
+ "reasoning": true,
296
430
  "input": [
297
431
  "text"
298
432
  ],
299
433
  "cost": {
300
- "input": 0.078875,
301
- "output": 0.425,
302
- "cacheRead": 0.039438,
434
+ "input": 0.062625,
435
+ "output": 0.4,
436
+ "cacheRead": 0.031313,
303
437
  "cacheWrite": 0.14
304
438
  },
305
439
  "contextWindow": 200000,
306
- "maxTokens": 200000
440
+ "maxTokens": 200000,
441
+ "compat": {
442
+ "supportsStore": false,
443
+ "supportsDeveloperRole": false,
444
+ "maxTokensField": "max_tokens",
445
+ "supportsReasoningEffort": true
446
+ }
307
447
  },
308
448
  {
309
449
  "id": "zai-org/GLM-4.7",
310
450
  "name": "GLM 4.7",
311
- "reasoning": false,
451
+ "reasoning": true,
312
452
  "input": [
313
453
  "text"
314
454
  ],
315
455
  "cost": {
316
- "input": 0.864,
317
- "output": 2.24,
318
- "cacheRead": 0.432,
456
+ "input": 0.88,
457
+ "output": 2.37,
458
+ "cacheRead": 0.44,
319
459
  "cacheWrite": 0.6
320
460
  },
321
461
  "contextWindow": 202752,
322
- "maxTokens": 202752
462
+ "maxTokens": 202752,
463
+ "compat": {
464
+ "supportsStore": false,
465
+ "supportsDeveloperRole": false,
466
+ "maxTokensField": "max_tokens",
467
+ "supportsReasoningEffort": true
468
+ }
323
469
  },
324
470
  {
325
471
  "id": "moonshotai/Kimi-K2-Instruct-0905",
@@ -335,40 +481,34 @@
335
481
  "cacheWrite": 0.78
336
482
  },
337
483
  "contextWindow": 262144,
338
- "maxTokens": 262144
339
- },
340
- {
341
- "id": "meta-llama/Llama-3.2-90B-Vision-Instruct",
342
- "name": "Llama 3.2 90B Vision Instruct",
343
- "reasoning": false,
344
- "input": [
345
- "text",
346
- "image"
347
- ],
348
- "cost": {
349
- "input": 0.345,
350
- "output": 0.345,
351
- "cacheRead": 0.1725,
352
- "cacheWrite": 0.7
353
- },
354
- "contextWindow": 16000,
355
- "maxTokens": 16000
484
+ "maxTokens": 262144,
485
+ "compat": {
486
+ "supportsStore": false,
487
+ "supportsDeveloperRole": false,
488
+ "maxTokensField": "max_tokens"
489
+ }
356
490
  },
357
491
  {
358
492
  "id": "openai/gpt-oss-120b",
359
493
  "name": "gpt-oss-120b",
360
- "reasoning": false,
494
+ "reasoning": true,
361
495
  "input": [
362
496
  "text"
363
497
  ],
364
498
  "cost": {
365
- "input": 0.188,
366
- "output": 0.7,
367
- "cacheRead": 0.094,
499
+ "input": 0.178,
500
+ "output": 0.71,
501
+ "cacheRead": 0.089,
368
502
  "cacheWrite": 0.04
369
503
  },
370
504
  "contextWindow": 131072,
371
- "maxTokens": 131072
505
+ "maxTokens": 131072,
506
+ "compat": {
507
+ "supportsStore": false,
508
+ "supportsDeveloperRole": false,
509
+ "maxTokensField": "max_tokens",
510
+ "supportsReasoningEffort": true
511
+ }
372
512
  },
373
513
  {
374
514
  "id": "deepseek-ai/DeepSeek-R1-0528",
@@ -384,12 +524,18 @@
384
524
  "cacheWrite": 0.8
385
525
  },
386
526
  "contextWindow": 128000,
387
- "maxTokens": 128000
527
+ "maxTokens": 128000,
528
+ "compat": {
529
+ "supportsStore": false,
530
+ "supportsDeveloperRole": false,
531
+ "maxTokensField": "max_tokens",
532
+ "supportsReasoningEffort": true
533
+ }
388
534
  },
389
535
  {
390
536
  "id": "zai-org/GLM-4.6",
391
537
  "name": "GLM 4.6",
392
- "reasoning": false,
538
+ "reasoning": true,
393
539
  "input": [
394
540
  "text"
395
541
  ],
@@ -400,7 +546,13 @@
400
546
  "cacheWrite": 0.7
401
547
  },
402
548
  "contextWindow": 131072,
403
- "maxTokens": 131072
549
+ "maxTokens": 131072,
550
+ "compat": {
551
+ "supportsStore": false,
552
+ "supportsDeveloperRole": false,
553
+ "maxTokensField": "max_tokens",
554
+ "supportsReasoningEffort": true
555
+ }
404
556
  },
405
557
  {
406
558
  "id": "Qwen/Qwen3-Next-80B-A3B-Instruct",
@@ -416,7 +568,12 @@
416
568
  "cacheWrite": 0.12
417
569
  },
418
570
  "contextWindow": 262144,
419
- "maxTokens": 262144
571
+ "maxTokens": 262144,
572
+ "compat": {
573
+ "supportsStore": false,
574
+ "supportsDeveloperRole": false,
575
+ "maxTokensField": "max_tokens"
576
+ }
420
577
  },
421
578
  {
422
579
  "id": "Intel/Qwen3-Coder-480B-A35B-Instruct-int4-mixed-ar",
@@ -426,13 +583,18 @@
426
583
  "text"
427
584
  ],
428
585
  "cost": {
429
- "input": 0.585,
430
- "output": 2.245,
431
- "cacheRead": 0.2925,
586
+ "input": 0.445,
587
+ "output": 2.145,
588
+ "cacheRead": 0.2225,
432
589
  "cacheWrite": 0.44
433
590
  },
434
591
  "contextWindow": 106000,
435
- "maxTokens": 106000
592
+ "maxTokens": 106000,
593
+ "compat": {
594
+ "supportsStore": false,
595
+ "supportsDeveloperRole": false,
596
+ "maxTokensField": "max_tokens"
597
+ }
436
598
  },
437
599
  {
438
600
  "id": "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8",
@@ -443,13 +605,18 @@
443
605
  "image"
444
606
  ],
445
607
  "cost": {
446
- "input": 0.284,
447
- "output": 0.934,
448
- "cacheRead": 0.142,
608
+ "input": 0.274,
609
+ "output": 0.8992,
610
+ "cacheRead": 0.137,
449
611
  "cacheWrite": 0.3
450
612
  },
451
613
  "contextWindow": 430000,
452
- "maxTokens": 430000
614
+ "maxTokens": 430000,
615
+ "compat": {
616
+ "supportsStore": false,
617
+ "supportsDeveloperRole": false,
618
+ "maxTokensField": "max_tokens"
619
+ }
453
620
  },
454
621
  {
455
622
  "id": "mistralai/Mistral-Nemo-Instruct-2407",
@@ -459,29 +626,40 @@
459
626
  "text"
460
627
  ],
461
628
  "cost": {
462
- "input": 0.069667,
463
- "output": 0.116667,
464
- "cacheRead": 0.034834,
629
+ "input": 0.029667,
630
+ "output": 0.076667,
631
+ "cacheRead": 0.014834,
465
632
  "cacheWrite": 0.04
466
633
  },
467
634
  "contextWindow": 128000,
468
- "maxTokens": 128000
635
+ "maxTokens": 128000,
636
+ "compat": {
637
+ "supportsStore": false,
638
+ "supportsDeveloperRole": false,
639
+ "maxTokensField": "max_tokens"
640
+ }
469
641
  },
470
642
  {
471
643
  "id": "openai/gpt-oss-20b",
472
644
  "name": "gpt-oss-20b",
473
- "reasoning": false,
645
+ "reasoning": true,
474
646
  "input": [
475
647
  "text"
476
648
  ],
477
649
  "cost": {
478
650
  "input": 0.059,
479
- "output": 0.216,
651
+ "output": 0.218,
480
652
  "cacheRead": 0.0295,
481
653
  "cacheWrite": 0.03
482
654
  },
483
655
  "contextWindow": 64000,
484
- "maxTokens": 64000
656
+ "maxTokens": 64000,
657
+ "compat": {
658
+ "supportsStore": false,
659
+ "supportsDeveloperRole": false,
660
+ "maxTokensField": "max_tokens",
661
+ "supportsReasoningEffort": true
662
+ }
485
663
  },
486
664
  {
487
665
  "id": "meta-llama/Llama-3.3-70B-Instruct",
@@ -491,12 +669,17 @@
491
669
  "text"
492
670
  ],
493
671
  "cost": {
494
- "input": 0.5126,
495
- "output": 1.0446,
496
- "cacheRead": 0.2563,
672
+ "input": 0.608,
673
+ "output": 0.838,
674
+ "cacheRead": 0.304,
497
675
  "cacheWrite": 0.2
498
676
  },
499
677
  "contextWindow": 128000,
500
- "maxTokens": 128000
678
+ "maxTokens": 128000,
679
+ "compat": {
680
+ "supportsStore": false,
681
+ "supportsDeveloperRole": false,
682
+ "maxTokensField": "max_tokens"
683
+ }
501
684
  }
502
685
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-io-provider",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "IO Intelligence provider extension for pi - Access DeepSeek, Kimi, GLM, Llama, Qwen, Mistral, and more through the IO Intelligence API",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -6,18 +6,122 @@
6
6
  * Fetches the model list from https://api.intelligence.io.solutions/api/v1/models
7
7
  * and regenerates models.json and the README model table.
8
8
  *
9
- * Requires IOINTELLIGENCE_API_KEY environment variable.
9
+ * API key: the stored `io-intelligence` credential in ~/.pi/agent/auth.json wins, then
10
+ * the IOINTELLIGENCE_API_KEY environment variable. The script refuses to run without one.
10
11
  * Usage: IOINTELLIGENCE_API_KEY=your-key node scripts/update-models.js
11
12
  */
12
13
 
13
14
  import https from 'https';
14
15
  import fs from 'fs';
16
+ import os from 'os';
17
+ import { execSync } from 'child_process';
15
18
  import path from 'path';
16
19
  import { fileURLToPath } from 'url';
17
20
 
18
21
  const __filename = fileURLToPath(import.meta.url);
19
22
  const __dirname = path.dirname(__filename);
20
23
 
24
+ // pi's agent directory: PI_CODING_AGENT_DIR (with ~ expansion) or ~/.pi/agent.
25
+ function piAgentDir() {
26
+ const envDir = process.env.PI_CODING_AGENT_DIR;
27
+ if (envDir) {
28
+ return envDir.startsWith('~/') || envDir === '~'
29
+ ? path.join(os.homedir(), envDir.slice(1))
30
+ : envDir;
31
+ }
32
+ return path.join(os.homedir(), '.pi', 'agent');
33
+ }
34
+
35
+ const AUTH_JSON_PATH = path.join(piAgentDir(), 'auth.json');
36
+
37
+ /**
38
+ * Resolve a configured value using pi's semantics (resolve-config-value.ts in
39
+ * pi-mono): "!command" runs via the shell (10s timeout) and uses trimmed
40
+ * stdout; "$VAR" / "${VAR}" interpolate environment variables ("$$" escapes a
41
+ * literal "$", "$!" a literal "!"); anything else is a literal. Returns
42
+ * undefined when a referenced env var is unset or a command fails.
43
+ */
44
+ function resolveConfigValue(config, env) {
45
+ if (typeof config !== 'string' || config.length === 0) return undefined;
46
+ if (config.startsWith('!')) {
47
+ try {
48
+ const out = execSync(config.slice(1), {
49
+ encoding: 'utf8',
50
+ timeout: 10000,
51
+ stdio: ['ignore', 'pipe', 'ignore'],
52
+ });
53
+ return out.trim() || undefined;
54
+ } catch {
55
+ return undefined;
56
+ }
57
+ }
58
+ const ENV_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
59
+ let resolved = '';
60
+ let index = 0;
61
+ while (index < config.length) {
62
+ const dollar = config.indexOf('$', index);
63
+ if (dollar < 0) {
64
+ resolved += config.slice(index);
65
+ break;
66
+ }
67
+ resolved += config.slice(index, dollar);
68
+ const next = config[dollar + 1];
69
+ let name;
70
+ if (next === '$' || next === '!') {
71
+ resolved += next;
72
+ index = dollar + 2;
73
+ continue;
74
+ } else if (next === '{') {
75
+ const end = config.indexOf('}', dollar + 2);
76
+ if (end < 0) {
77
+ resolved += '$';
78
+ index = dollar + 1;
79
+ continue;
80
+ }
81
+ const inner = config.slice(dollar + 2, end);
82
+ if (!ENV_NAME_RE.test(inner)) {
83
+ resolved += config.slice(dollar, end + 1);
84
+ index = end + 1;
85
+ continue;
86
+ }
87
+ name = inner;
88
+ index = end + 1;
89
+ } else {
90
+ const match = config.slice(dollar + 1).match(/^[A-Za-z_][A-Za-z0-9_]*/);
91
+ if (!match) {
92
+ resolved += '$';
93
+ index = dollar + 1;
94
+ continue;
95
+ }
96
+ name = match[0];
97
+ index = dollar + 1 + name.length;
98
+ }
99
+ const value = (env && env[name]) || process.env[name] || undefined;
100
+ if (value === undefined) return undefined;
101
+ resolved += value;
102
+ }
103
+ return resolved;
104
+ }
105
+
106
+ /**
107
+ * The API key, resolved the way pi itself resolves it for this provider: the
108
+ * stored `io-intelligence` credential in ~/.pi/agent/auth.json wins, then
109
+ * the IOINTELLIGENCE_API_KEY environment variable.
110
+ */
111
+ function resolveApiKey() {
112
+ try {
113
+ const auth = JSON.parse(fs.readFileSync(AUTH_JSON_PATH, 'utf8'));
114
+ const credential = auth?.['io-intelligence'];
115
+ if (credential && credential.type === 'api_key' && typeof credential.key === 'string') {
116
+ const key = resolveConfigValue(credential.key, credential.env);
117
+ if (key) return key;
118
+ }
119
+ } catch {
120
+ // Missing or unparseable auth.json: fall through to the env var.
121
+ }
122
+ return process.env.IOINTELLIGENCE_API_KEY || undefined;
123
+ }
124
+
21
125
  const API_BASE = 'https://api.intelligence.io.solutions/api/v1';
22
126
  const MODELS_PATH = path.join(process.cwd(), 'models.json');
23
127
  const PATCH_PATH = path.join(process.cwd(), 'patch.json');
@@ -81,9 +185,17 @@ function convertModel(apiModel, existingModelsMap) {
81
185
  if (priceOut > 0) existing.cost.output = Math.round(priceOut * 1e6) / 1e6;
82
186
  if (cacheRead > 0) existing.cost.cacheRead = Math.round(cacheRead * 1e6) / 1e6;
83
187
  if (cacheWrite > 0) existing.cost.cacheWrite = Math.round(cacheWrite * 1e6) / 1e6;
84
- if (apiModel.supports_images_input && !existing.input.includes('image')) {
85
- existing.input = ['text', 'image'];
86
- }
188
+ const hasVision = apiModel.supports_images_input === true || (apiModel.input_modalities || []).includes('image');
189
+ const hasReasoning = apiModel.capabilities?.reasoning === true || apiModel.supports_reasoning === true;
190
+ existing.input = hasVision ? ['text', 'image'] : ['text'];
191
+ existing.reasoning = hasReasoning;
192
+ existing.compat = {
193
+ ...(existing.compat || {}),
194
+ supportsStore: false,
195
+ supportsDeveloperRole: false,
196
+ maxTokensField: 'max_tokens',
197
+ ...(hasReasoning ? { supportsReasoningEffort: true } : {}),
198
+ };
87
199
  return existing;
88
200
  }
89
201
 
@@ -91,7 +203,7 @@ function convertModel(apiModel, existingModelsMap) {
91
203
  const ctx = apiModel.context_window || 0;
92
204
  const maxTok = apiModel.max_tokens || ctx;
93
205
  const input = ['text'];
94
- if (apiModel.supports_images_input) input.push('image');
206
+ if (apiModel.supports_images_input === true || (apiModel.input_modalities || []).includes('image')) input.push('image');
95
207
 
96
208
  const priceIn = (apiModel.input_token_price || 0) * 1_000_000;
97
209
  const priceOut = (apiModel.output_token_price || 0) * 1_000_000;
@@ -101,7 +213,7 @@ function convertModel(apiModel, existingModelsMap) {
101
213
  return {
102
214
  id,
103
215
  name: cleanName(apiModel.name, id),
104
- reasoning: false,
216
+ reasoning: apiModel.capabilities?.reasoning === true || apiModel.supports_reasoning === true,
105
217
  input,
106
218
  cost: {
107
219
  input: Math.round(priceIn * 1e6) / 1e6,
@@ -111,6 +223,14 @@ function convertModel(apiModel, existingModelsMap) {
111
223
  },
112
224
  contextWindow: ctx,
113
225
  maxTokens: maxTok,
226
+ compat: {
227
+ supportsStore: false,
228
+ supportsDeveloperRole: false,
229
+ maxTokensField: 'max_tokens',
230
+ ...((apiModel.capabilities?.reasoning === true || apiModel.supports_reasoning === true)
231
+ ? { supportsReasoningEffort: true }
232
+ : {}),
233
+ },
114
234
  };
115
235
  }
116
236
 
@@ -123,6 +243,7 @@ function applyPatch(model, patch) {
123
243
  if (patch.input !== undefined) result.input = patch.input;
124
244
  if (patch.contextWindow !== undefined) result.contextWindow = patch.contextWindow;
125
245
  if (patch.maxTokens !== undefined) result.maxTokens = patch.maxTokens;
246
+ if (patch.thinkingLevelMap !== undefined) result.thinkingLevelMap = { ...patch.thinkingLevelMap };
126
247
  if (patch.cost) {
127
248
  result.cost = {
128
249
  input: patch.cost.input ?? result.cost.input,
@@ -137,6 +258,9 @@ function applyPatch(model, patch) {
137
258
  if (!result.reasoning && result.compat?.thinkingFormat) {
138
259
  delete result.compat.thinkingFormat;
139
260
  }
261
+ if (!result.reasoning && result.thinkingLevelMap) {
262
+ delete result.thinkingLevelMap;
263
+ }
140
264
  if (result.compat && Object.keys(result.compat).length === 0) {
141
265
  delete result.compat;
142
266
  }
@@ -390,9 +514,9 @@ function updateDeprecatedModels(modelsJsonPath, newModels) {
390
514
  }
391
515
 
392
516
  async function main() {
393
- const apiKey = process.env.IOINTELLIGENCE_API_KEY;
517
+ const apiKey = resolveApiKey();
394
518
  if (!apiKey) {
395
- console.error('Error: IOINTELLIGENCE_API_KEY environment variable is required');
519
+ console.error('Error: No API key found: no `io-intelligence` credential resolved from ' + AUTH_JSON_PATH + ' and IOINTELLIGENCE_API_KEY is not set');
396
520
  console.error('Usage: IOINTELLIGENCE_API_KEY=your-key node scripts/update-models.js');
397
521
  process.exit(1);
398
522
  }