@juspay/neurolink 12.9.6 → 12.11.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +3 -3
  2. package/dist/artifacts/artifactBanking.d.ts +6 -2
  3. package/dist/artifacts/artifactBanking.js +9 -14
  4. package/dist/artifacts/artifactReader.d.ts +69 -0
  5. package/dist/artifacts/artifactReader.js +157 -0
  6. package/dist/artifacts/artifactStore.d.ts +7 -3
  7. package/dist/artifacts/artifactStore.js +10 -21
  8. package/dist/artifacts/artifactStoreFactory.d.ts +39 -0
  9. package/dist/artifacts/artifactStoreFactory.js +101 -0
  10. package/dist/artifacts/redisArtifactStore.d.ts +84 -0
  11. package/dist/artifacts/redisArtifactStore.js +270 -0
  12. package/dist/browser/neurolink.min.js +381 -383
  13. package/dist/constants/enums.d.ts +77 -0
  14. package/dist/constants/enums.js +82 -0
  15. package/dist/core/modules/GenerationHandler.d.ts +15 -3
  16. package/dist/core/modules/GenerationHandler.js +172 -14
  17. package/dist/index.d.ts +3 -0
  18. package/dist/index.js +7 -0
  19. package/dist/memory/memoryRetrievalTools.js +104 -35
  20. package/dist/neurolink.d.ts +45 -1
  21. package/dist/neurolink.js +128 -18
  22. package/dist/providers/catalog/baseten.json +263 -0
  23. package/dist/providers/catalog/gmicloud.json +64 -0
  24. package/dist/providers/catalog/inception-labs.json +75 -0
  25. package/dist/providers/catalog/index.generated.d.ts +1 -1
  26. package/dist/providers/catalog/index.generated.js +15 -0
  27. package/dist/providers/catalog/io-intelligence.json +463 -0
  28. package/dist/providers/catalog/schema.d.ts +1 -1
  29. package/dist/providers/catalog/upstage.json +165 -0
  30. package/dist/providers/openaiChatCompletionsClient.js +18 -1
  31. package/dist/types/artifact.d.ts +124 -3
  32. package/dist/types/config.d.ts +7 -0
  33. package/dist/types/generate.d.ts +17 -0
  34. package/dist/types/openaiCompatible.d.ts +5 -1
  35. package/dist/types/providerCatalog.generated.d.ts +2 -2
  36. package/dist/types/providers.d.ts +20 -0
  37. package/dist/utils/redis.d.ts +15 -0
  38. package/dist/utils/redis.js +64 -6
  39. package/package.json +10 -6
@@ -0,0 +1,463 @@
1
+ {
2
+ "$schema": "./provider-catalog.schema.json",
3
+ "id": "io-intelligence",
4
+ "displayName": "io.net Intelligence",
5
+ "aliases": ["io-net"],
6
+ "tier": 2,
7
+ "wire": {
8
+ "baseURL": "https://api.intelligence.io.solutions/api/v1"
9
+ },
10
+ "models": {
11
+ "default": "meta-llama/Llama-3.3-70B-Instruct",
12
+ "fallbacks": [
13
+ "meta-llama/Llama-3.3-70B-Instruct",
14
+ "openai/gpt-oss-20b",
15
+ "zai-org/GLM-4.5-Air"
16
+ ],
17
+ "defaultContextWindow": 128000,
18
+ "defaultMaxOutputTokens": 8192,
19
+ "catalog": {
20
+ "zai-org/GLM-5.3-Flash": {
21
+ "contextWindow": 262144,
22
+ "maxOutputTokens": 131072,
23
+ "pricingPerMTok": {
24
+ "input": 0.147997,
25
+ "output": 0.49399,
26
+ "cachedInput": 0.073999
27
+ },
28
+ "vision": true,
29
+ "status": "production",
30
+ "description": "Z.ai: GLM 5.3 Flash"
31
+ },
32
+ "zai-org/GLM-5.3": {
33
+ "contextWindow": 262144,
34
+ "maxOutputTokens": 131072,
35
+ "pricingPerMTok": {
36
+ "input": 1.39,
37
+ "output": 4.4,
38
+ "cachedInput": 0.695
39
+ },
40
+ "vision": false,
41
+ "status": "production",
42
+ "description": "Z.ai: GLM 5.3"
43
+ },
44
+ "Qwen/Qwen3.8-27B": {
45
+ "contextWindow": 65536,
46
+ "maxOutputTokens": 65536,
47
+ "pricingPerMTok": {
48
+ "input": 0.39,
49
+ "output": 2.99,
50
+ "cachedInput": 0.195
51
+ },
52
+ "vision": true,
53
+ "status": "production",
54
+ "description": "Qwen: Qwen3.8 27B"
55
+ },
56
+ "deepseek-ai/DeepSeek-V4-Flash-0731": {
57
+ "contextWindow": 262100,
58
+ "maxOutputTokens": 65536,
59
+ "pricingPerMTok": {
60
+ "input": 0.196,
61
+ "output": 0.534,
62
+ "cachedInput": 0.098
63
+ },
64
+ "vision": false,
65
+ "status": "production",
66
+ "description": "DeepSeek: DeepSeek V4 Flash 0731"
67
+ },
68
+ "moonshotai/Kimi-K3": {
69
+ "contextWindow": 1048576,
70
+ "pricingPerMTok": {
71
+ "input": 3.18,
72
+ "output": 15.9,
73
+ "cachedInput": 1.59
74
+ },
75
+ "vision": true,
76
+ "status": "production",
77
+ "description": "MoonshotAI: Kimi K3"
78
+ },
79
+ "XiaomiMiMo/MiMo-V2.5": {
80
+ "contextWindow": 1048576,
81
+ "pricingPerMTok": {
82
+ "input": 0.1934,
83
+ "output": 0.6268,
84
+ "cachedInput": 0.0967
85
+ },
86
+ "vision": false,
87
+ "status": "production",
88
+ "description": "Xiaomi: MiMo-V2.5"
89
+ },
90
+ "zai-org/GLM-5.2": {
91
+ "contextWindow": 262144,
92
+ "maxOutputTokens": 131072,
93
+ "pricingPerMTok": {
94
+ "input": 1.552,
95
+ "output": 4.884,
96
+ "cachedInput": 0.776
97
+ },
98
+ "vision": false,
99
+ "status": "production",
100
+ "description": "Z.ai: GLM 5.2"
101
+ },
102
+ "moonshotai/Kimi-K2.7-Code": {
103
+ "contextWindow": 262144,
104
+ "pricingPerMTok": {
105
+ "input": 1.026,
106
+ "output": 4.53,
107
+ "cachedInput": 0.513
108
+ },
109
+ "vision": true,
110
+ "status": "production",
111
+ "description": "MoonshotAI: Kimi K2.7 Code"
112
+ },
113
+ "Qwen/Qwen3.6-35B-A3B": {
114
+ "contextWindow": 262144,
115
+ "pricingPerMTok": {
116
+ "input": 0.1872,
117
+ "output": 1.24675,
118
+ "cachedInput": 0.0936
119
+ },
120
+ "vision": true,
121
+ "status": "production",
122
+ "description": "Qwen: Qwen3.6 35B A3B"
123
+ },
124
+ "Qwen/Qwen3.6-27B": {
125
+ "contextWindow": 32768,
126
+ "pricingPerMTok": {
127
+ "input": 0.399,
128
+ "output": 3.19,
129
+ "cachedInput": 0.1995
130
+ },
131
+ "vision": true,
132
+ "status": "production",
133
+ "description": "Qwen: Qwen3.6 27B"
134
+ },
135
+ "MiniMaxAI/MiniMax-M2.7": {
136
+ "contextWindow": 262100,
137
+ "maxOutputTokens": 65536,
138
+ "pricingPerMTok": {
139
+ "input": 0.426,
140
+ "output": 1.62,
141
+ "cachedInput": 0.213
142
+ },
143
+ "vision": false,
144
+ "status": "production",
145
+ "description": "MiniMaxAI: MiniMax M2.7"
146
+ },
147
+ "deepseek-ai/DeepSeek-V4-Flash": {
148
+ "contextWindow": 32768,
149
+ "maxOutputTokens": 32768,
150
+ "pricingPerMTok": {
151
+ "input": 0.199,
152
+ "output": 0.512,
153
+ "cachedInput": 0.0995
154
+ },
155
+ "vision": false,
156
+ "status": "production",
157
+ "description": "DeepSeek: DeepSeek V4 Flash"
158
+ },
159
+ "deepseek-ai/DeepSeek-V4-Pro": {
160
+ "contextWindow": 1048576,
161
+ "maxOutputTokens": 600000,
162
+ "pricingPerMTok": {
163
+ "input": 1.618,
164
+ "output": 3.288,
165
+ "cachedInput": 0.809
166
+ },
167
+ "vision": false,
168
+ "status": "production",
169
+ "description": "DeepSeek: DeepSeek V4 Pro"
170
+ },
171
+ "moonshotai/Kimi-K2.6": {
172
+ "contextWindow": 262142,
173
+ "pricingPerMTok": {
174
+ "input": 0.76744,
175
+ "output": 3.43436,
176
+ "cachedInput": 0.38372
177
+ },
178
+ "vision": true,
179
+ "status": "production",
180
+ "description": "MoonshotAI: Kimi K2.6"
181
+ },
182
+ "zai-org/GLM-5.1": {
183
+ "contextWindow": 202750,
184
+ "maxOutputTokens": 32768,
185
+ "pricingPerMTok": {
186
+ "input": 1.29,
187
+ "output": 4.22,
188
+ "cachedInput": 0.645
189
+ },
190
+ "vision": false,
191
+ "status": "production",
192
+ "description": "Z.ai: GLM 5.1"
193
+ },
194
+ "MiniMaxAI/MiniMax-M2.5": {
195
+ "contextWindow": 196600,
196
+ "pricingPerMTok": {
197
+ "input": 0.294,
198
+ "output": 1.176,
199
+ "cachedInput": 0.147
200
+ },
201
+ "vision": false,
202
+ "status": "production",
203
+ "description": "MiniMaxAI/MiniMax-M2.5"
204
+ },
205
+ "moonshotai/Kimi-K2.5": {
206
+ "contextWindow": 262144,
207
+ "pricingPerMTok": {
208
+ "input": 0.5284,
209
+ "output": 2.785,
210
+ "cachedInput": 0.2642
211
+ },
212
+ "vision": true,
213
+ "status": "production",
214
+ "description": "MoonshotAI: Kimi K2.5"
215
+ },
216
+ "zai-org/GLM-5": {
217
+ "contextWindow": 202752,
218
+ "pricingPerMTok": {
219
+ "input": 0.85,
220
+ "output": 2.774,
221
+ "cachedInput": 0.425
222
+ },
223
+ "vision": false,
224
+ "status": "production",
225
+ "description": "Z.ai: GLM 5"
226
+ },
227
+ "deepseek-ai/DeepSeek-V3.2": {
228
+ "contextWindow": 163840,
229
+ "pricingPerMTok": {
230
+ "input": 1.4301,
231
+ "output": 2.4063,
232
+ "cachedInput": 0.71505
233
+ },
234
+ "vision": false,
235
+ "status": "production",
236
+ "description": "DeepSeek: DeepSeek V3.2"
237
+ },
238
+ "moonshotai/Kimi-K2-Thinking": {
239
+ "contextWindow": 262144,
240
+ "pricingPerMTok": {
241
+ "input": 0.6,
242
+ "output": 2.5,
243
+ "cachedInput": 0.3
244
+ },
245
+ "vision": false,
246
+ "status": "production",
247
+ "description": "MoonshotAI: Kimi K2 Thinking"
248
+ },
249
+ "zai-org/GLM-4.5-Air": {
250
+ "contextWindow": 131070,
251
+ "pricingPerMTok": {
252
+ "input": 0.165,
253
+ "output": 0.975,
254
+ "cachedInput": 0.0825
255
+ },
256
+ "vision": false,
257
+ "status": "production",
258
+ "description": "Z.ai: GLM-4.5-Air"
259
+ },
260
+ "google/gemma-4-26b-a4b-it": {
261
+ "contextWindow": 262142,
262
+ "pricingPerMTok": {
263
+ "input": 0.116,
264
+ "output": 0.38,
265
+ "cachedInput": 0.058
266
+ },
267
+ "vision": false,
268
+ "status": "production",
269
+ "description": "Google: Gemma 4 26B A4B"
270
+ },
271
+ "zai-org/GLM-4.7-Flash": {
272
+ "contextWindow": 200000,
273
+ "pricingPerMTok": {
274
+ "input": 0.062625,
275
+ "output": 0.4,
276
+ "cachedInput": 0.031313
277
+ },
278
+ "vision": false,
279
+ "status": "production",
280
+ "description": "Z.ai: GLM 4.7 Flash"
281
+ },
282
+ "zai-org/GLM-4.7": {
283
+ "contextWindow": 202752,
284
+ "pricingPerMTok": {
285
+ "input": 0.88,
286
+ "output": 2.37,
287
+ "cachedInput": 0.44
288
+ },
289
+ "vision": false,
290
+ "status": "production",
291
+ "description": "Z.ai: GLM 4.7"
292
+ },
293
+ "moonshotai/Kimi-K2-Instruct-0905": {
294
+ "contextWindow": 262144,
295
+ "pricingPerMTok": {
296
+ "input": 0.57,
297
+ "output": 2.3,
298
+ "cachedInput": 0.285
299
+ },
300
+ "vision": false,
301
+ "status": "production",
302
+ "description": "MoonshotAI: Kimi K2 Instruct 0905"
303
+ },
304
+ "openai/gpt-oss-120b": {
305
+ "contextWindow": 131072,
306
+ "pricingPerMTok": {
307
+ "input": 0.188,
308
+ "output": 0.7,
309
+ "cachedInput": 0.094
310
+ },
311
+ "vision": false,
312
+ "status": "production",
313
+ "description": "OpenAI: gpt-oss-120b"
314
+ },
315
+ "deepseek-ai/DeepSeek-R1-0528": {
316
+ "contextWindow": 128000,
317
+ "pricingPerMTok": {
318
+ "input": 0.56775,
319
+ "output": 2.279,
320
+ "cachedInput": 0.283875
321
+ },
322
+ "vision": false,
323
+ "status": "production",
324
+ "description": "DeepSeek: R1 0528"
325
+ },
326
+ "zai-org/GLM-4.6": {
327
+ "contextWindow": 131072,
328
+ "pricingPerMTok": {
329
+ "input": 0.536,
330
+ "output": 2.07,
331
+ "cachedInput": 0.268
332
+ },
333
+ "vision": false,
334
+ "status": "production",
335
+ "description": "Z.ai: GLM 4.6"
336
+ },
337
+ "Qwen/Qwen3-Next-80B-A3B-Instruct": {
338
+ "contextWindow": 262144,
339
+ "pricingPerMTok": {
340
+ "input": 0.1175,
341
+ "output": 1.136,
342
+ "cachedInput": 0.05875
343
+ },
344
+ "vision": false,
345
+ "status": "production",
346
+ "description": "Qwen: Qwen3 Next 80B A3B Instruct"
347
+ },
348
+ "Intel/Qwen3-Coder-480B-A35B-Instruct-int4-mixed-ar": {
349
+ "contextWindow": 106000,
350
+ "pricingPerMTok": {
351
+ "input": 0.445,
352
+ "output": 2.145,
353
+ "cachedInput": 0.2225
354
+ },
355
+ "vision": false,
356
+ "status": "production",
357
+ "description": "Intel: Qwen3 Coder 480B A35B Instruct INT4 Mixed AR"
358
+ },
359
+ "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": {
360
+ "contextWindow": 430000,
361
+ "pricingPerMTok": {
362
+ "input": 0.274,
363
+ "output": 0.8992,
364
+ "cachedInput": 0.137
365
+ },
366
+ "vision": true,
367
+ "status": "production",
368
+ "description": "Meta-Llama: Llama 4 Maverick 17B 128E Instruct FP8"
369
+ },
370
+ "mistralai/Mistral-Nemo-Instruct-2407": {
371
+ "contextWindow": 128000,
372
+ "pricingPerMTok": {
373
+ "input": 0.0635,
374
+ "output": 0.09875,
375
+ "cachedInput": 0.03175
376
+ },
377
+ "vision": false,
378
+ "status": "production",
379
+ "description": "Mistral: Mistral Nemo Instruct 2407"
380
+ },
381
+ "openai/gpt-oss-20b": {
382
+ "contextWindow": 64000,
383
+ "pricingPerMTok": {
384
+ "input": 0.067,
385
+ "output": 0.24,
386
+ "cachedInput": 0.0335
387
+ },
388
+ "vision": false,
389
+ "status": "production",
390
+ "description": "OpenAI: gpt-oss-20b"
391
+ },
392
+ "meta-llama/Llama-3.3-70B-Instruct": {
393
+ "contextWindow": 128000,
394
+ "pricingPerMTok": {
395
+ "input": 0.6066,
396
+ "output": 1.0386,
397
+ "cachedInput": 0.3033
398
+ },
399
+ "vision": false,
400
+ "status": "production",
401
+ "description": "Recommended - Meta: Llama 3.3 70B Instruct"
402
+ }
403
+ },
404
+ "topModels": [
405
+ "meta-llama/Llama-3.3-70B-Instruct",
406
+ "openai/gpt-oss-20b",
407
+ "zai-org/GLM-4.5-Air",
408
+ "google/gemma-4-26b-a4b-it",
409
+ "zai-org/GLM-5.3-Flash",
410
+ "Qwen/Qwen3.8-27B",
411
+ "deepseek-ai/DeepSeek-V4-Pro"
412
+ ]
413
+ },
414
+ "capabilities": {
415
+ "text": true,
416
+ "streaming": true,
417
+ "tools": true,
418
+ "toolsWithStreaming": true,
419
+ "structuredOutput": true,
420
+ "structuredOutputWithTools": true,
421
+ "embeddings": false,
422
+ "thinking": false
423
+ },
424
+ "errorRules": [
425
+ {
426
+ "pattern": "requested model is not available for Chat Completions API",
427
+ "class": "invalid-model",
428
+ "message": "io.net Intelligence model '{model}' is not available for the Chat Completions API. Choose a current model from https://ai.io.net/."
429
+ }
430
+ ],
431
+ "setup": {
432
+ "url": "https://ai.io.net/",
433
+ "apiKeyFormat": null,
434
+ "billingPolicy": "free-tier",
435
+ "instructions": [
436
+ "1. Visit: https://ai.io.net/",
437
+ "2. Sign in or create an io.net account",
438
+ "3. Create an API key for your project in the console",
439
+ "4. Set {apiKeyEnvVar} in your .env file"
440
+ ]
441
+ },
442
+ "evidence": {
443
+ "rosterVerified": {
444
+ "date": "2026-09-03",
445
+ "method": "authenticated GET /v1/models",
446
+ "status": 200
447
+ },
448
+ "authProbe": {
449
+ "date": "2026-09-03",
450
+ "status": 401
451
+ },
452
+ "liveMatrix": {
453
+ "date": "2026-09-03",
454
+ "result": "SDK end-to-end via dist: generate, stream, tool call (nonce round-trip) and json_schema structured output all pass. Tools + schema: after a tool result the vendor answers finish_reason=tool_calls with no tool_calls and null content when JSON is requested (4/4 raw replays); the SDK now re-asks that step once with tool_choice none and recovers the JSON — passed 1/1 in the final live proof through dist/index.js, tool nonce present in structuredData. structuredOutputWithTools is declared true on that basis."
455
+ },
456
+ "addedInPR": "pending",
457
+ "billingProbe": {
458
+ "date": "2026-09-03",
459
+ "status": 200,
460
+ "method": "official io.net Intelligence web app plan configuration: Standard default with daily_limit fallback of 2; Professional and Developer are paid upgrade plans"
461
+ }
462
+ }
463
+ }
@@ -88,8 +88,8 @@ export declare const providerCatalogJsonSchema: z.ZodObject<{
88
88
  url: z.ZodString;
89
89
  apiKeyFormat: z.ZodNullable<z.ZodString>;
90
90
  billingPolicy: z.ZodEnum<{
91
- "free-with-card": "free-with-card";
92
91
  "free-tier": "free-tier";
92
+ "free-with-card": "free-with-card";
93
93
  "no-free-tier": "no-free-tier";
94
94
  }>;
95
95
  instructions: z.ZodArray<z.ZodString>;
@@ -0,0 +1,165 @@
1
+ {
2
+ "$schema": "./provider-catalog.schema.json",
3
+ "id": "upstage",
4
+ "displayName": "Upstage",
5
+ "aliases": ["solar"],
6
+ "tier": 2,
7
+ "wire": {
8
+ "baseURL": "https://api.upstage.ai/v1"
9
+ },
10
+ "models": {
11
+ "default": "solar-pro4",
12
+ "fallbacks": ["solar-pro3", "solar-mini"],
13
+ "defaultContextWindow": 524288,
14
+ "defaultMaxOutputTokens": 131072,
15
+ "catalog": {
16
+ "solar-pro4": {
17
+ "contextWindow": 524288,
18
+ "maxOutputTokens": 131072,
19
+ "pricingPerMTok": {
20
+ "input": 0.3,
21
+ "output": 1.2,
22
+ "cachedInput": 0.06
23
+ },
24
+ "vision": false,
25
+ "status": "production",
26
+ "description": "Recommended - Solar Pro 4; 512K context, up to 128K output tokens; agentic flagship for tool calling, terminal tasks and long-document reasoning"
27
+ },
28
+ "solar-pro4-260806": {
29
+ "contextWindow": 524288,
30
+ "maxOutputTokens": 131072,
31
+ "pricingPerMTok": {
32
+ "input": 0.3,
33
+ "output": 1.2,
34
+ "cachedInput": 0.06
35
+ },
36
+ "vision": false,
37
+ "status": "production",
38
+ "description": "Pinned dated snapshot of Solar Pro 4 (2026-08-06 build) — the id the solar-pro4 alias currently resolves to"
39
+ },
40
+ "solar-pro3": {
41
+ "pricingPerMTok": {
42
+ "input": 0.15,
43
+ "output": 0.6,
44
+ "cachedInput": 0.015
45
+ },
46
+ "vision": false,
47
+ "status": "production",
48
+ "description": "Solar Pro 3; drop-in replacement for Solar Pro 2 with the same API interface, throughput and latency"
49
+ },
50
+ "solar-pro3-260323": {
51
+ "pricingPerMTok": {
52
+ "input": 0.15,
53
+ "output": 0.6,
54
+ "cachedInput": 0.015
55
+ },
56
+ "vision": false,
57
+ "status": "production",
58
+ "description": "Pinned dated snapshot of Solar Pro 3 (2026-03-23 build)"
59
+ },
60
+ "solar-pro2": {
61
+ "pricingPerMTok": {
62
+ "input": 0.15,
63
+ "output": 0.6,
64
+ "cachedInput": 0.015
65
+ },
66
+ "vision": false,
67
+ "status": "production",
68
+ "description": "Solar Pro 2; 31B-parameter model with an optional Reasoning Mode"
69
+ },
70
+ "solar-pro2-251215": {
71
+ "pricingPerMTok": {
72
+ "input": 0.15,
73
+ "output": 0.6,
74
+ "cachedInput": 0.015
75
+ },
76
+ "vision": false,
77
+ "status": "production",
78
+ "description": "Pinned dated snapshot of Solar Pro 2 (2025-12-15 build)"
79
+ },
80
+ "solar-mini": {
81
+ "pricingPerMTok": {
82
+ "input": 0.15,
83
+ "output": 0.15
84
+ },
85
+ "vision": false,
86
+ "status": "production",
87
+ "description": "Solar Mini; small, fast model for lightweight reasoning and cost-efficient tasks"
88
+ },
89
+ "solar-mini-250422": {
90
+ "pricingPerMTok": {
91
+ "input": 0.15,
92
+ "output": 0.15
93
+ },
94
+ "vision": false,
95
+ "status": "production",
96
+ "description": "Pinned dated snapshot of Solar Mini (2025-04-22 build)"
97
+ },
98
+ "syn-pro": {
99
+ "vision": false,
100
+ "status": "production",
101
+ "description": "Syn Pro; Upstage's Japan-focused LLM"
102
+ },
103
+ "syn-pro-251021": {
104
+ "vision": false,
105
+ "status": "production",
106
+ "description": "Pinned dated snapshot of Syn Pro (2025-10-21 build)"
107
+ }
108
+ },
109
+ "topModels": [
110
+ "solar-pro4",
111
+ "solar-pro3",
112
+ "solar-pro2",
113
+ "solar-mini",
114
+ "syn-pro"
115
+ ]
116
+ },
117
+ "capabilities": {
118
+ "text": true,
119
+ "streaming": true,
120
+ "tools": true,
121
+ "toolsWithStreaming": true,
122
+ "structuredOutput": true,
123
+ "structuredOutputWithTools": true,
124
+ "embeddings": false,
125
+ "thinking": false
126
+ },
127
+ "errorRules": [
128
+ {
129
+ "status": 401,
130
+ "pattern": "invalid_api_key|API key is invalid",
131
+ "class": "authentication",
132
+ "message": "Invalid Upstage API key. Check {apiKeyEnvVar}. Get one at https://console.upstage.ai/api-keys"
133
+ },
134
+ {
135
+ "pattern": "requested model is invalid or no longer supported",
136
+ "class": "invalid-model",
137
+ "message": "Upstage model '{model}' is invalid or no longer supported. Pick a current model from https://console.upstage.ai/docs/models."
138
+ }
139
+ ],
140
+ "setup": {
141
+ "url": "https://console.upstage.ai/api-keys",
142
+ "apiKeyFormat": "^up_[A-Za-z0-9]+$",
143
+ "billingPolicy": "free-tier",
144
+ "instructions": [
145
+ "1. Visit: https://console.upstage.ai (Google OAuth works)",
146
+ "2. New accounts get a $10 sign-up credit — no payment method required",
147
+ "3. Create an API key under API Keys",
148
+ "4. Set {apiKeyEnvVar} in your .env file"
149
+ ]
150
+ },
151
+ "evidence": {
152
+ "rosterVerified": {
153
+ "date": "2026-09-03",
154
+ "method": "authenticated GET /v1/models",
155
+ "status": 200
156
+ },
157
+ "authProbe": {
158
+ "date": "2026-09-03",
159
+ "status": 401,
160
+ "code": "invalid_api_key"
161
+ },
162
+ "liveMatrix": null,
163
+ "addedInPR": "pending"
164
+ }
165
+ }
@@ -624,6 +624,23 @@ export const parseSSEStream = async (body, onTextDelta, onReasoningDelta) => {
624
624
  }
625
625
  return result;
626
626
  };
627
+ function extractOpenAICompatErrorMessage(parsed) {
628
+ const message = parsed?.error?.message;
629
+ if (typeof message === "string" && message.trim().length > 0) {
630
+ return message;
631
+ }
632
+ if (Array.isArray(message)) {
633
+ const pydanticMessages = message
634
+ .map((item) => item.msg?.trim())
635
+ .filter((item) => item !== undefined && item.length > 0);
636
+ if (pydanticMessages.length > 0) {
637
+ return pydanticMessages.join("; ");
638
+ }
639
+ }
640
+ return typeof parsed?.detail === "string" && parsed.detail.trim().length > 0
641
+ ? parsed.detail
642
+ : undefined;
643
+ }
627
644
  export const buildAPIError = async (url, body, res) => {
628
645
  let bodyText;
629
646
  let parsed;
@@ -636,7 +653,7 @@ export const buildAPIError = async (url, body, res) => {
636
653
  catch {
637
654
  parsed = undefined;
638
655
  }
639
- const msg = parsed?.error?.message ??
656
+ const msg = extractOpenAICompatErrorMessage(parsed) ??
640
657
  `OpenAI-compatible request failed with status ${res.status}`;
641
658
  const err = new Error(msg);
642
659
  err.statusCode = res.status;