@qadanm/opencode-smart-router 0.0.0-stage → 0.4.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 (65) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/CONTRIBUTING.md +96 -0
  3. package/LICENSE +21 -0
  4. package/README.md +341 -2
  5. package/SECURITY.md +174 -0
  6. package/config.example.json +108 -0
  7. package/dist/allowance.js +487 -0
  8. package/dist/gui-experimental.cjs +1 -0
  9. package/dist/index.js +11111 -0
  10. package/dist/npm/index.js +40 -0
  11. package/dist/tui.js +587 -0
  12. package/docs/ARCHITECTURE.md +104 -0
  13. package/docs/DEBUGGING-GUI.md +70 -0
  14. package/docs/INSTALL.md +120 -0
  15. package/docs/LIMITATIONS.md +213 -0
  16. package/docs/MODELS.md +124 -0
  17. package/docs/OPENDESIGN-INTEGRATION.md +635 -0
  18. package/docs/QA.md +142 -0
  19. package/docs/SHARED-CORE.md +72 -0
  20. package/install +75 -0
  21. package/package.json +92 -4
  22. package/scripts/install.sh +324 -0
  23. package/scripts/uninstall.sh +91 -0
  24. package/src/allowance.ts +135 -0
  25. package/src/core/classify/classifier.ts +305 -0
  26. package/src/core/config-writer.ts +167 -0
  27. package/src/core/config.ts +1030 -0
  28. package/src/core/context/strategy.ts +188 -0
  29. package/src/core/context-health.ts +39 -0
  30. package/src/core/failures.ts +398 -0
  31. package/src/core/history/opencode.ts +173 -0
  32. package/src/core/models/protocol.ts +22 -0
  33. package/src/core/models/registry.ts +203 -0
  34. package/src/core/models/seed.ts +771 -0
  35. package/src/core/offline/mode.ts +321 -0
  36. package/src/core/plan-page.ts +390 -0
  37. package/src/core/plans/catalog.ts +481 -0
  38. package/src/core/policy/calibration.ts +259 -0
  39. package/src/core/policy/eligibility.ts +578 -0
  40. package/src/core/providers/enablement.ts +143 -0
  41. package/src/core/providers/opendesign-credits.ts +206 -0
  42. package/src/core/providers/opendesign-models.ts +628 -0
  43. package/src/core/providers/opendesign.ts +474 -0
  44. package/src/core/quota/calibration.ts +166 -0
  45. package/src/core/quota/commandcode.ts +471 -0
  46. package/src/core/quota/credentials.ts +490 -0
  47. package/src/core/quota/ledger.ts +1273 -0
  48. package/src/core/quota/opencode-go.ts +148 -0
  49. package/src/core/quota/opendesign.ts +1043 -0
  50. package/src/core/quota/reconcile.ts +155 -0
  51. package/src/core/quota/report.ts +261 -0
  52. package/src/core/quota/service.ts +273 -0
  53. package/src/core/reprompt.ts +48 -0
  54. package/src/core/routing/engine.ts +919 -0
  55. package/src/core/types.ts +825 -0
  56. package/src/core/ui.ts +236 -0
  57. package/src/core/util.ts +114 -0
  58. package/src/gui/index.tsx +1670 -0
  59. package/src/gui/viewmodel.ts +456 -0
  60. package/src/index.ts +48 -0
  61. package/src/rpc.ts +204 -0
  62. package/src/server/controller.ts +3281 -0
  63. package/src/server/route-tracker.ts +60 -0
  64. package/src/server/shared-core.ts +671 -0
  65. package/src/tui/index.tsx +168 -0
@@ -0,0 +1,628 @@
1
+ import type { CostTier } from "../types.js"
2
+ import { OPENDESIGN_CREDIT_MULTIPLIERS, OPENDESIGN_UNPUBLISHED_MULTIPLIER_MODELS } from "./opendesign-credits.js"
3
+ import { OPENDESIGN_DESIGN_PLAN_MODELS } from "../plans/catalog.js"
4
+
5
+ /**
6
+ * OpenDesign model catalog.
7
+ *
8
+ * The gateway is authoritative for entitlement, context, output budget and
9
+ * image support. Everything below was read from the live gateway's
10
+ * `GET /v1/models` response on 2026-10-29, which is refreshed by the discovery
11
+ * adapter at runtime.
12
+ *
13
+ * Two funding groups exist on the paid plans:
14
+ *
15
+ * - **Design Plan models** draw from the shared Design Plan credit pool and
16
+ * are charged at their published multiplier.
17
+ * - **Plan models** draw from the separate plan model pool, which has no
18
+ * usage windows. Design Plan multipliers do not apply to them.
19
+ *
20
+ * Which group a model belongs to is decided by the plan catalog, not by this
21
+ * file; `fundingPoolFor` is the single source of truth.
22
+ *
23
+ * Intelligence and design scores are reused from the router's existing seed
24
+ * for the same underlying model, because the same model has the same quality
25
+ * regardless of which subscription serves it. Models the router has never
26
+ * scored stay unapproved until the owner approves them explicitly.
27
+ *
28
+ * Underlying token prices are the vendor list prices already curated in the
29
+ * router seed. OpenDesign does not publish per-token prices for plan models;
30
+ * for Design Plan models it publishes a credit multiplier that converts usage
31
+ * value into credits. See docs/OPENDESIGN-INTEGRATION.md for the accuracy
32
+ * limits of this proxy.
33
+ */
34
+
35
+ export interface OpenDesignModelSpec {
36
+ readonly modelID: string
37
+ readonly name: string
38
+ /**
39
+ * Design Plan credit multiplier. Meaningful only for a model funded from
40
+ * the Design Plan pool; plan models are billed at plain usage value.
41
+ */
42
+ readonly creditMultiplier: number
43
+ readonly multiplierEvidence: "published" | "unverified" | "not-applicable"
44
+ /** Usable input window the gateway reports for this model. */
45
+ readonly context: number
46
+ /** Maximum output tokens the gateway reports. */
47
+ readonly maxOutput: number
48
+ readonly input: readonly string[]
49
+ readonly cost: readonly CostTier[]
50
+ readonly intelligence: number
51
+ readonly design: number
52
+ readonly designEvidence: "benchmark" | "curated" | "observed" | "unverified"
53
+ readonly tier: 1 | 2 | 3
54
+ readonly approved: boolean
55
+ readonly notes: string
56
+ }
57
+
58
+ const cost = (input: number, output: number, read: number, write = 0): CostTier[] => [
59
+ { input, output, cache: { read, write } },
60
+ ]
61
+
62
+ const tieredCost = (
63
+ base: CostTier,
64
+ size: number,
65
+ high: { input: number; output: number; read: number; write: number },
66
+ ): CostTier[] => [
67
+ base,
68
+ {
69
+ input: high.input,
70
+ output: high.output,
71
+ cache: { read: high.read, write: high.write },
72
+ tier: { type: "context" as const, size },
73
+ },
74
+ ]
75
+
76
+ /**
77
+ * Conservative fallbacks used when the gateway does not report a context or
78
+ * output budget. A model with missing metadata is never treated as if it
79
+ * could accept an unbounded request.
80
+ */
81
+ export const OPENDESIGN_FALLBACK_CONTEXT = 232_000
82
+ export const OPENDESIGN_FALLBACK_OUTPUT = 32_000
83
+
84
+ const spec = (
85
+ modelID: string,
86
+ name: string,
87
+ extra: Omit<OpenDesignModelSpec, "modelID" | "name" | "creditMultiplier" | "multiplierEvidence"> &
88
+ Partial<Pick<OpenDesignModelSpec, "creditMultiplier" | "multiplierEvidence">>,
89
+ ): OpenDesignModelSpec => {
90
+ const inDesignPlan = OPENDESIGN_DESIGN_PLAN_MODELS.has(modelID)
91
+ const published = OPENDESIGN_CREDIT_MULTIPLIERS[modelID]
92
+ const hasPublished = typeof published === "number"
93
+ return {
94
+ modelID,
95
+ name,
96
+ creditMultiplier: extra.creditMultiplier ?? published ?? 1,
97
+ multiplierEvidence:
98
+ extra.multiplierEvidence ??
99
+ (inDesignPlan ? (hasPublished ? "published" : "unverified") : "not-applicable"),
100
+ context: extra.context,
101
+ maxOutput: extra.maxOutput,
102
+ input: extra.input,
103
+ cost: extra.cost,
104
+ intelligence: extra.intelligence,
105
+ design: extra.design,
106
+ designEvidence: extra.designEvidence,
107
+ tier: extra.tier,
108
+ approved: extra.approved,
109
+ notes: extra.notes,
110
+ }
111
+ }
112
+
113
+ /**
114
+ * The models the gateway serves for this account.
115
+ *
116
+ * Entitlement is confirmed at runtime from `GET /v1/models`; a model missing
117
+ * from that response is not plan-eligible even if it appears here.
118
+ */
119
+ export const OPENDESIGN_MODELS: ReadonlyArray<OpenDesignModelSpec> = [
120
+ // ---------------------------------------------------------------------------
121
+ // Design Plan models. Charged at their published multiplier.
122
+ // ---------------------------------------------------------------------------
123
+ spec("deepseek-v4.1-flash", "DeepSeek V4.1 Flash", {
124
+ context: 1_048_000,
125
+ maxOutput: 128_000,
126
+ input: ["text", "image"],
127
+ cost: cost(0.3, 1.2, 0.006),
128
+ intelligence: 39.5,
129
+ design: 65,
130
+ designEvidence: "observed",
131
+ tier: 2,
132
+ approved: true,
133
+ notes:
134
+ "0.5x Design Plan credits. Gateway default. Served as DeepSeek-V4.1-Flash-1017 (2026-10-17 checkpoint). Native image input. The gateway advertises context_budget 328,000 but does not enforce it: measured on 2026-10-30 at 1,043,337 input tokens with HTTP 200, and rejected only above the 1,048,000 vendor limit. The seed carries the measured window.",
135
+ }),
136
+ spec("claude-haiku-5.5", "Claude Haiku 5.5", {
137
+ context: 228_000,
138
+ maxOutput: 128_000,
139
+ input: ["text", "image", "pdf"],
140
+ cost: tieredCost(cost(0.1, 0.5, 0.01, 0.125)[0]!, 100_000, {
141
+ input: 0.5,
142
+ output: 2.5,
143
+ read: 0.05,
144
+ write: 0.625,
145
+ }),
146
+ intelligence: 43.4,
147
+ design: 70,
148
+ designEvidence: "curated",
149
+ tier: 2,
150
+ approved: true,
151
+ notes: "2x Design Plan credits. Highest design score inside the Design Plan group.",
152
+ }),
153
+ spec("glm-5.3-flash", "GLM-5.3-Flash", {
154
+ context: 232_000,
155
+ maxOutput: 32_000,
156
+ input: ["text", "image", "video"],
157
+ cost: cost(0.075, 0.25, 0.015),
158
+ intelligence: 41.8,
159
+ design: 65,
160
+ designEvidence: "curated",
161
+ tier: 2,
162
+ approved: true,
163
+ notes: "1x Design Plan credits. Native image and video input.",
164
+ }),
165
+ spec("minimax-m3.1-flash", "MiniMax M3.1 Flash", {
166
+ context: 1_000_000,
167
+ maxOutput: OPENDESIGN_FALLBACK_OUTPUT,
168
+ input: ["text", "image", "video"],
169
+ cost: cost(0.15, 0.6, 0.015),
170
+ intelligence: 42.7,
171
+ design: 60,
172
+ designEvidence: "curated",
173
+ tier: 2,
174
+ approved: true,
175
+ notes:
176
+ "The gateway reports a 1M vendor limit but no context_budget for this model, so the vendor limit is used. Confirmed against models.dev (1,000,000) and by 475 successful calls with no context-length error. The gateway also serves this model outside the Design Plan group; OpenDesign has not published which group or multiplier applies, so the neutral 1x rate is used and the uncertainty is reported.",
177
+ }),
178
+ spec("mimo-v2.6-pro", "MiMo-V2.6-Pro", {
179
+ context: 232_000,
180
+ maxOutput: 32_000,
181
+ input: ["text", "image", "audio", "video"],
182
+ cost: cost(0.435, 0.87, 0.0036),
183
+ intelligence: 46.3,
184
+ design: 62,
185
+ designEvidence: "curated",
186
+ tier: 2,
187
+ approved: true,
188
+ notes: "1x Design Plan credits. Highest intelligence score inside the Design Plan group.",
189
+ }),
190
+ spec("mimo-v2.6-flash", "MiMo-V2.6-Flash", {
191
+ context: 232_000,
192
+ maxOutput: 32_000,
193
+ input: ["text", "image", "audio", "video"],
194
+ cost: cost(0.14, 0.28, 0.0028),
195
+ intelligence: 37.9,
196
+ design: 50,
197
+ designEvidence: "curated",
198
+ tier: 1,
199
+ approved: true,
200
+ notes: "1x Design Plan credits. Economy tier; below the standard intelligence floor.",
201
+ }),
202
+ spec("gpt-6-luna", "GPT-6 Luna", {
203
+ context: 400_000,
204
+ maxOutput: 128_000,
205
+ input: ["text", "image", "pdf"],
206
+ cost: tieredCost(cost(0.1, 0.5, 0.01, 0.125)[0]!, 272_000, {
207
+ input: 0.2,
208
+ output: 0.75,
209
+ read: 0.02,
210
+ write: 0.25,
211
+ }),
212
+ intelligence: 38.1,
213
+ design: 55,
214
+ designEvidence: "curated",
215
+ tier: 1,
216
+ approved: true,
217
+ notes: "4x Design Plan credits, the most expensive Design Plan route. 400k usable input window.",
218
+ }),
219
+ spec("deepseek-v4-pro", "DeepSeek V4 Pro", {
220
+ context: 328_000,
221
+ maxOutput: 128_000,
222
+ input: ["text"],
223
+ cost: cost(1.32, 3.96, 0.044),
224
+ intelligence: 36,
225
+ design: 55,
226
+ designEvidence: "curated",
227
+ tier: 2,
228
+ approved: false,
229
+ notes: "Text only and below the standard intelligence floor. Requires explicit approval.",
230
+ }),
231
+ spec("deepseek-v4-flash", "DeepSeek V4 Flash", {
232
+ context: 232_000,
233
+ maxOutput: 32_000,
234
+ input: ["text"],
235
+ cost: cost(0.44, 1.32, 0.014),
236
+ intelligence: 0,
237
+ design: 0,
238
+ designEvidence: "unverified",
239
+ tier: 2,
240
+ approved: false,
241
+ notes:
242
+ "Served upstream by DeepSeek-V4.1-Flash-1017 (DeepSeek retired the legacy name but still accepts and bills it). Unscored under this id; the price is a conservative upper bound borrowed from V4 Pro. Set an explicit price in models.definitions before approving.",
243
+ }),
244
+ spec("deepseek-v4-flash-vision-exp", "DeepSeek V4 Flash Vision Exp", {
245
+ context: 232_000,
246
+ maxOutput: 32_000,
247
+ input: ["text", "image"],
248
+ cost: cost(0.44, 1.32, 0.014),
249
+ intelligence: 0,
250
+ design: 0,
251
+ designEvidence: "unverified",
252
+ tier: 2,
253
+ approved: false,
254
+ notes:
255
+ "Unscored. Conservative upper-bound price; set an explicit price in models.definitions before approving.",
256
+ }),
257
+ spec("glm-5.3-flashx", "GLM-5.3-Flash-X", {
258
+ context: 232_000,
259
+ maxOutput: 32_000,
260
+ input: ["text", "image", "pdf", "video"],
261
+ cost: cost(0.37, 1.25, 0.075),
262
+ intelligence: 0,
263
+ design: 0,
264
+ designEvidence: "unverified",
265
+ tier: 2,
266
+ approved: false,
267
+ notes:
268
+ "2x Design Plan credits. Unscored; conservative upper-bound price borrowed from GLM-5.3. Set an explicit price in models.definitions before approving.",
269
+ }),
270
+ spec("hy4-preview", "Hunyuan H4 Preview", {
271
+ context: 232_000,
272
+ maxOutput: 32_000,
273
+ input: ["text"],
274
+ cost: cost(0.834, 2.501, 0.042),
275
+ intelligence: 0,
276
+ design: 0,
277
+ designEvidence: "unverified",
278
+ tier: 1,
279
+ approved: false,
280
+ notes: "Unscored and text only. Requires explicit approval.",
281
+ }),
282
+ spec("kimi-k2.7-code", "Kimi K2.7 Code", {
283
+ context: 262_000,
284
+ maxOutput: 32_000,
285
+ input: ["text", "image"],
286
+ cost: cost(0.95, 4, 0.19),
287
+ intelligence: 0,
288
+ design: 0,
289
+ designEvidence: "unverified",
290
+ tier: 2,
291
+ approved: false,
292
+ notes:
293
+ "Unscored. Conservative upper-bound price borrowed from Kimi K3; set an explicit price in models.definitions before approving.",
294
+ }),
295
+
296
+ // ---------------------------------------------------------------------------
297
+ // Plan models. Funded from the separate plan model pool, which has no usage
298
+ // windows. Only available on Plus, Pro and Max.
299
+ // ---------------------------------------------------------------------------
300
+ spec("claude-sonnet-5.5", "Claude Sonnet 5.5", {
301
+ context: 328_000,
302
+ maxOutput: 128_000,
303
+ input: ["text", "image", "pdf"],
304
+ cost: cost(2, 10, 0.2, 2.5),
305
+ intelligence: 56,
306
+ design: 90,
307
+ designEvidence: "curated",
308
+ tier: 3,
309
+ approved: false,
310
+ notes:
311
+ "Plan model. Premier design and architecture quality. Funded from plan model credits, so routing here consumes escalation capacity rather than routine allowance.",
312
+ }),
313
+ spec("gpt-6-sol", "GPT-6 Sol", {
314
+ context: 304_000,
315
+ maxOutput: 32_000,
316
+ input: ["text", "image", "pdf"],
317
+ cost: tieredCost(cost(2, 10, 0.2, 2.5)[0]!, 272_000, { input: 4, output: 15, read: 0.4, write: 5 }),
318
+ intelligence: 0,
319
+ design: 88,
320
+ designEvidence: "unverified",
321
+ tier: 3,
322
+ approved: false,
323
+ notes: "Plan model. Unscored in the router's curated set. Explicit approval required.",
324
+ }),
325
+ spec("gpt-6.1-sol", "GPT-6.1 Sol", {
326
+ context: 400_000,
327
+ maxOutput: 128_000,
328
+ input: ["text", "image", "pdf"],
329
+ cost: tieredCost(cost(2, 10, 0.1, 2.5)[0]!, 272_000, { input: 4, output: 15, read: 0.2, write: 5 }),
330
+ intelligence: 0,
331
+ design: 88,
332
+ designEvidence: "unverified",
333
+ tier: 3,
334
+ approved: false,
335
+ notes: "Plan model. Unscored. Explicit approval required.",
336
+ }),
337
+ spec("gpt-6-astra", "GPT-6 Astra", {
338
+ context: 400_000,
339
+ maxOutput: 128_000,
340
+ input: ["text", "image", "pdf"],
341
+ cost: tieredCost(cost(10, 50, 1, 12.5)[0]!, 272_000, { input: 20, output: 75, read: 2, write: 25 }),
342
+ intelligence: 0,
343
+ design: 88,
344
+ designEvidence: "unverified",
345
+ tier: 3,
346
+ approved: false,
347
+ notes: "Plan model, frontier-priced. Never selected automatically without explicit approval.",
348
+ }),
349
+ spec("claude-opus-5.5", "Claude Opus 5.5", {
350
+ context: 328_000,
351
+ maxOutput: 128_000,
352
+ input: ["text", "image", "pdf"],
353
+ cost: cost(4, 20, 0.2, 5),
354
+ intelligence: 0,
355
+ design: 92,
356
+ designEvidence: "unverified",
357
+ tier: 3,
358
+ approved: false,
359
+ notes: "Plan model. Unscored. Explicit approval required.",
360
+ }),
361
+ spec("claude-opus-5", "Claude Opus 5", {
362
+ context: 232_000,
363
+ maxOutput: 32_000,
364
+ input: ["text", "image", "pdf"],
365
+ cost: cost(5, 25, 0.5, 6.25),
366
+ intelligence: 0,
367
+ design: 91,
368
+ designEvidence: "unverified",
369
+ tier: 3,
370
+ approved: false,
371
+ notes: "Plan model. Unscored. Explicit approval required.",
372
+ }),
373
+ spec("claude-opus-4.8", "Claude Opus 4.8", {
374
+ context: 232_000,
375
+ maxOutput: 32_000,
376
+ input: ["text", "image", "pdf"],
377
+ cost: cost(5, 25, 0.5, 6.25),
378
+ intelligence: 0,
379
+ design: 90,
380
+ designEvidence: "unverified",
381
+ tier: 3,
382
+ approved: false,
383
+ notes: "Plan model. Unscored. Explicit approval required.",
384
+ }),
385
+ spec("claude-sonnet-5", "Claude Sonnet 5", {
386
+ context: 232_000,
387
+ maxOutput: 32_000,
388
+ input: ["text", "image", "pdf"],
389
+ cost: cost(2, 10, 0.2, 2.5),
390
+ intelligence: 0,
391
+ design: 88,
392
+ designEvidence: "unverified",
393
+ tier: 3,
394
+ approved: false,
395
+ notes: "Plan model. Unscored. Explicit approval required.",
396
+ }),
397
+ spec("claude-fable-5.1", "Claude Fable 5.1", {
398
+ context: 328_000,
399
+ maxOutput: 128_000,
400
+ input: ["text", "image", "pdf"],
401
+ cost: cost(10, 50, 0.25, 12.5),
402
+ intelligence: 0,
403
+ design: 90,
404
+ designEvidence: "unverified",
405
+ tier: 3,
406
+ approved: false,
407
+ notes: "Plan model, frontier-priced. Never selected automatically without explicit approval.",
408
+ }),
409
+ spec("claude-fable-5", "Claude Fable 5", {
410
+ context: 232_000,
411
+ maxOutput: 32_000,
412
+ input: ["text", "image", "pdf"],
413
+ cost: cost(10, 50, 1, 12.5),
414
+ intelligence: 0,
415
+ design: 89,
416
+ designEvidence: "unverified",
417
+ tier: 3,
418
+ approved: false,
419
+ notes: "Plan model, frontier-priced. Never selected automatically without explicit approval.",
420
+ }),
421
+ spec("muse-spark-1.3", "Muse Spark 1.3", {
422
+ context: 1_048_000,
423
+ maxOutput: 32_000,
424
+ input: ["text", "image", "video", "pdf", "audio"],
425
+ cost: cost(1.25, 4.25, 0.15),
426
+ intelligence: 48.1,
427
+ design: 82,
428
+ designEvidence: "curated",
429
+ tier: 3,
430
+ approved: false,
431
+ notes:
432
+ "Plan model. Strong design quality and a 1,048,000-token window. Funded from plan model credits; escalate here deliberately, not by default.",
433
+ }),
434
+ spec("muse-wonder", "Muse Wonder", {
435
+ context: 232_000,
436
+ maxOutput: 32_000,
437
+ input: ["text", "image", "video", "pdf", "audio"],
438
+ cost: cost(4, 20, 0.2),
439
+ intelligence: 0,
440
+ design: 86,
441
+ designEvidence: "unverified",
442
+ tier: 3,
443
+ approved: false,
444
+ notes: "Plan model. Unscored. Explicit approval required.",
445
+ }),
446
+ spec("gemini-4-argon", "Gemini 4 Argon", {
447
+ context: 264_000,
448
+ maxOutput: 64_000,
449
+ input: ["text", "image", "video", "audio", "pdf"],
450
+ cost: cost(2, 10, 0.1),
451
+ intelligence: 0,
452
+ design: 85,
453
+ designEvidence: "unverified",
454
+ tier: 3,
455
+ approved: false,
456
+ notes: "Plan model. Unscored. Explicit approval required.",
457
+ }),
458
+ spec("gemini-3.8-flash", "Gemini 3.8 Flash", {
459
+ context: 264_000,
460
+ maxOutput: 64_000,
461
+ input: ["text", "image", "video", "audio", "pdf"],
462
+ cost: cost(0.75, 3.75, 0.075),
463
+ intelligence: 0,
464
+ design: 78,
465
+ designEvidence: "unverified",
466
+ tier: 3,
467
+ approved: false,
468
+ notes: "Plan model. Unscored. Explicit approval required.",
469
+ }),
470
+ spec("gemini-3.7-flash", "Gemini 3.7 Flash", {
471
+ context: 232_000,
472
+ maxOutput: 32_000,
473
+ input: ["text", "image", "video", "audio", "pdf"],
474
+ cost: cost(0.75, 3.75, 0.075),
475
+ intelligence: 0,
476
+ design: 76,
477
+ designEvidence: "unverified",
478
+ tier: 3,
479
+ approved: false,
480
+ notes: "Plan model. Unscored. Explicit approval required.",
481
+ }),
482
+ spec("kimi-k3", "Kimi K3", {
483
+ context: 232_000,
484
+ maxOutput: 32_000,
485
+ input: ["text", "image", "video"],
486
+ cost: cost(3, 15, 0.3, 3),
487
+ intelligence: 43.6,
488
+ design: 72,
489
+ designEvidence: "curated",
490
+ tier: 3,
491
+ approved: false,
492
+ notes: "Plan model. Strong design quality; funded from plan model credits.",
493
+ }),
494
+ spec("kimi-k3.1-pro", "Kimi K3.1 Pro", {
495
+ context: 232_000,
496
+ maxOutput: 32_000,
497
+ input: ["text", "image", "video"],
498
+ cost: cost(2, 10, 0.2, 2),
499
+ intelligence: 0,
500
+ design: 75,
501
+ designEvidence: "unverified",
502
+ tier: 3,
503
+ approved: false,
504
+ notes: "Plan model. Unscored. Explicit approval required.",
505
+ }),
506
+ spec("grok-4.7", "Grok 4.7", {
507
+ context: 328_000,
508
+ maxOutput: 128_000,
509
+ input: ["text", "image", "pdf"],
510
+ cost: tieredCost(cost(2, 6, 0.5)[0]!, 200_000, { input: 4, output: 12, read: 1, write: 0 }),
511
+ intelligence: 46.4,
512
+ design: 75,
513
+ designEvidence: "curated",
514
+ tier: 3,
515
+ approved: false,
516
+ notes: "Plan model. Funded from plan model credits.",
517
+ }),
518
+ spec("grok-4.6", "Grok 4.6", {
519
+ context: 232_000,
520
+ maxOutput: 32_000,
521
+ input: ["text", "image", "pdf"],
522
+ cost: tieredCost(cost(2, 6, 0.5)[0]!, 200_000, { input: 4, output: 12, read: 1, write: 0 }),
523
+ intelligence: 0,
524
+ design: 74,
525
+ designEvidence: "unverified",
526
+ tier: 3,
527
+ approved: false,
528
+ notes: "Plan model. Unscored. Explicit approval required.",
529
+ }),
530
+ spec("grok-4.5", "Grok 4.5", {
531
+ context: 232_000,
532
+ maxOutput: 32_000,
533
+ input: ["text", "image", "pdf"],
534
+ cost: tieredCost(cost(2, 6, 0.5)[0]!, 200_000, { input: 4, output: 12, read: 0.6, write: 0 }),
535
+ intelligence: 0,
536
+ design: 72,
537
+ designEvidence: "unverified",
538
+ tier: 3,
539
+ approved: false,
540
+ notes: "Plan model. Unscored. Explicit approval required.",
541
+ }),
542
+ spec("gpt-5.6-sol", "GPT-5.6 Sol", {
543
+ context: 304_000,
544
+ maxOutput: 32_000,
545
+ input: ["text", "image", "pdf"],
546
+ cost: tieredCost(cost(4, 20, 0.4, 5)[0]!, 272_000, { input: 8, output: 30, read: 0.8, write: 10 }),
547
+ intelligence: 0,
548
+ design: 85,
549
+ designEvidence: "unverified",
550
+ tier: 3,
551
+ approved: false,
552
+ notes: "Plan model. Unscored. Explicit approval required.",
553
+ }),
554
+ spec("gpt-5.6-terra", "GPT-5.6 Terra", {
555
+ context: 304_000,
556
+ maxOutput: 32_000,
557
+ input: ["text", "image", "pdf"],
558
+ cost: tieredCost(cost(2, 12, 0.2, 2.5)[0]!, 272_000, { input: 4, output: 18, read: 0.4, write: 5 }),
559
+ intelligence: 0,
560
+ design: 84,
561
+ designEvidence: "unverified",
562
+ tier: 3,
563
+ approved: false,
564
+ notes: "Plan model. Unscored. Explicit approval required.",
565
+ }),
566
+ spec("gpt-5.6-luna", "GPT-5.6 Luna", {
567
+ context: 304_000,
568
+ maxOutput: 32_000,
569
+ input: ["text", "image", "pdf"],
570
+ cost: tieredCost(cost(0.2, 1.2, 0.02, 0.25)[0]!, 272_000, { input: 0.4, output: 1.8, read: 0.04, write: 0.5 }),
571
+ intelligence: 0,
572
+ design: 60,
573
+ designEvidence: "unverified",
574
+ tier: 3,
575
+ approved: false,
576
+ notes: "Plan model. Unscored. Explicit approval required.",
577
+ }),
578
+ spec("gpt-6.1-terra", "GPT-6.1 Terra", {
579
+ context: 304_000,
580
+ maxOutput: 32_000,
581
+ input: ["text", "image", "pdf"],
582
+ cost: tieredCost(cost(2, 12, 0.2, 2.5)[0]!, 272_000, { input: 4, output: 18, read: 0.4, write: 5 }),
583
+ intelligence: 0,
584
+ design: 87,
585
+ designEvidence: "unverified",
586
+ tier: 3,
587
+ approved: false,
588
+ notes: "Plan model. Unscored. Explicit approval required.",
589
+ }),
590
+ spec("qwen3.7-max", "Qwen3.7 Max", {
591
+ context: 232_000,
592
+ maxOutput: 32_000,
593
+ input: ["text", "image", "video"],
594
+ cost: cost(2.5, 7.5, 0.5, 3.125),
595
+ intelligence: 0,
596
+ design: 70,
597
+ designEvidence: "unverified",
598
+ tier: 3,
599
+ approved: false,
600
+ notes: "Plan model. Unscored. Explicit approval required.",
601
+ }),
602
+ spec("glm-5.2", "GLM-5.2", {
603
+ context: 232_000,
604
+ maxOutput: 32_000,
605
+ input: ["text"],
606
+ cost: cost(1.4, 4.4, 0.26),
607
+ intelligence: 0,
608
+ design: 78,
609
+ designEvidence: "unverified",
610
+ tier: 3,
611
+ approved: false,
612
+ notes: "Plan model. Unscored and text only. Explicit approval required.",
613
+ }),
614
+ ]
615
+
616
+ export const OPEN_DESIGN_MODEL_BY_ID: ReadonlyMap<string, OpenDesignModelSpec> = new Map(
617
+ OPENDESIGN_MODELS.map((model) => [model.modelID, model]),
618
+ )
619
+
620
+ /** Models whose multiplier is not published, exposed for status reporting. */
621
+ export const OPENDESIGN_MODELS_WITHOUT_PUBLISHED_MULTIPLIER: readonly string[] = [
622
+ ...OPENDESIGN_UNPUBLISHED_MULTIPLIER_MODELS,
623
+ ]
624
+
625
+ /** Models funded from the separate plan model pool. */
626
+ export const OPENDESIGN_PLAN_MODEL_IDS: readonly string[] = OPENDESIGN_MODELS
627
+ .filter((model) => !OPENDESIGN_DESIGN_PLAN_MODELS.has(model.modelID))
628
+ .map((model) => model.modelID)