@prismshadow/penguin-server 0.2.16 → 0.2.17

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 (108) hide show
  1. package/README.md +1 -1
  2. package/dist/api/types.d.ts +233 -47
  3. package/dist/api/types.js +9 -3
  4. package/dist/auth-token.js +1 -1
  5. package/dist/{chunk-HMTT2PX4.js → chunk-2LZDP26O.js} +8 -5
  6. package/dist/chunk-2LZDP26O.js.map +1 -0
  7. package/dist/{chunk-LPPVGHYD.js → chunk-BL4U7GYY.js} +2 -2
  8. package/dist/chunk-BL4U7GYY.js.map +1 -0
  9. package/dist/chunk-GGIINEEK.js +3401 -0
  10. package/dist/chunk-GGIINEEK.js.map +1 -0
  11. package/dist/chunk-HDBZRVA5.js +29 -0
  12. package/dist/chunk-HDBZRVA5.js.map +1 -0
  13. package/dist/{chunk-3SFJKLQU.js → chunk-HPOHMZCH.js} +679 -559
  14. package/dist/chunk-HPOHMZCH.js.map +1 -0
  15. package/dist/{chunk-QFV3ERQO.js → chunk-OQZDL3TR.js} +2 -2
  16. package/dist/hmr/manifest.js +1 -1
  17. package/dist/index.js +7701 -4814
  18. package/dist/index.js.map +1 -1
  19. package/dist/machine-status.js +2 -2
  20. package/dist/model-catalog.d.ts +610 -0
  21. package/dist/model-catalog.js +108 -0
  22. package/dist/model-catalog.js.map +1 -0
  23. package/dist/plugin/index.d.ts +113 -58
  24. package/dist/reset-admin-password.js +1 -1
  25. package/dist/version-report.js +2 -2
  26. package/package.json +14 -9
  27. package/web-dist/assets/{abnfDiagram-VCTEODGH-0AKFiyig.js → abnfDiagram-VCTEODGH-DMzkb4l4.js} +1 -1
  28. package/web-dist/assets/{addon-clipboard-BovFnNVg.js → addon-clipboard-BtD2BVSi.js} +1 -1
  29. package/web-dist/assets/{addon-fit-B1npgxQk.js → addon-fit-Dr6HWsi_.js} +1 -1
  30. package/web-dist/assets/{addon-web-links-D88QHj7A.js → addon-web-links-VEE3YLzQ.js} +1 -1
  31. package/web-dist/assets/{arc-Beox1Cgf.js → arc-CvMPOU_B.js} +1 -1
  32. package/web-dist/assets/{architectureDiagram-5GKGNRK7-CC1sLMY1.js → architectureDiagram-5GKGNRK7-Bk65mIBz.js} +1 -1
  33. package/web-dist/assets/{blockDiagram-I7D4REHJ-B8BY1PkZ.js → blockDiagram-I7D4REHJ-D54-XSNs.js} +1 -1
  34. package/web-dist/assets/{c4Diagram-7LVT6UL2-yjY0BkxQ.js → c4Diagram-7LVT6UL2-Dm954LSt.js} +1 -1
  35. package/web-dist/assets/channel-CVHI75kz.js +1 -0
  36. package/web-dist/assets/{chunk-2Q5K7J3B-DdgIvETg.js → chunk-2Q5K7J3B-D_LJ_7Cn.js} +1 -1
  37. package/web-dist/assets/{chunk-5VM5RSS4-BE38k1Rs.js → chunk-5VM5RSS4-B8RI4tl3.js} +1 -1
  38. package/web-dist/assets/{chunk-F27PBJKO-D4YXmaqQ.js → chunk-F27PBJKO-aVSYH9JV.js} +1 -1
  39. package/web-dist/assets/{chunk-IMKFNOWR-CyJFdThc.js → chunk-IMKFNOWR-DnkdWeq2.js} +1 -1
  40. package/web-dist/assets/{chunk-JWPE2WC7-BAM_oEUU.js → chunk-JWPE2WC7-C2pJzKuW.js} +1 -1
  41. package/web-dist/assets/{chunk-POPQ4Y6H-BP3D0FVi.js → chunk-POPQ4Y6H-Bx7Iikzx.js} +1 -1
  42. package/web-dist/assets/{chunk-SVP7TREG-Clk8PdKZ.js → chunk-SVP7TREG-qJC2SMqr.js} +1 -1
  43. package/web-dist/assets/{chunk-TICWLB2K-EvWPnEGg.js → chunk-TICWLB2K-Crl_BgKI.js} +1 -1
  44. package/web-dist/assets/{chunk-XXDRQBXY-6p5D0UB1.js → chunk-XXDRQBXY-BFFemuGm.js} +1 -1
  45. package/web-dist/assets/classDiagram-ZZMXUADV-CBdzAPFu.js +1 -0
  46. package/web-dist/assets/classDiagram-v2-VYDZK3BY-CBdzAPFu.js +1 -0
  47. package/web-dist/assets/{cose-bilkent-JH36ORCC-bpkI-tLJ.js → cose-bilkent-JH36ORCC-Bmh2Kx7h.js} +1 -1
  48. package/web-dist/assets/{cynefin-OW5HDTMX-srLaqJ4e.js → cynefin-OW5HDTMX-BveNWnUV.js} +1 -1
  49. package/web-dist/assets/{cynefinDiagram-5FMLGOSQ-BPfpHSPc.js → cynefinDiagram-5FMLGOSQ-85itazbJ.js} +1 -1
  50. package/web-dist/assets/{dagre-GXQ25YYZ-C4fF5-j7.js → dagre-GXQ25YYZ-DIZT-KY_.js} +1 -1
  51. package/web-dist/assets/{diagram-S7CK7UJ4-BzBLb_9-.js → diagram-S7CK7UJ4-Dum-g63f.js} +1 -1
  52. package/web-dist/assets/{diagram-UQ7AKVKN-BJuJ1o_T.js → diagram-UQ7AKVKN-DallMKJl.js} +1 -1
  53. package/web-dist/assets/{diagram-VSXAHHWV-DFelN9i9.js → diagram-VSXAHHWV-DWELqxfN.js} +1 -1
  54. package/web-dist/assets/{diagram-VX7I27RA-BgrEoPyp.js → diagram-VX7I27RA-BNs0gB9E.js} +1 -1
  55. package/web-dist/assets/{diagram-Z3DM3KII-C71KiMiX.js → diagram-Z3DM3KII-C9mF9xAd.js} +1 -1
  56. package/web-dist/assets/{ebnfDiagram-PWID7BFC-EYteyp1b.js → ebnfDiagram-PWID7BFC-D_Diy9HH.js} +1 -1
  57. package/web-dist/assets/{erDiagram-RLTQ6QDP-B6n6-sz6.js → erDiagram-RLTQ6QDP-4QTS5VIh.js} +1 -1
  58. package/web-dist/assets/{flowDiagram-HODETNUW-BtoMTdyT.js → flowDiagram-HODETNUW-CliTRrtV.js} +1 -1
  59. package/web-dist/assets/{ganttDiagram-EL5Y4UJY-CbOAa3vS.js → ganttDiagram-EL5Y4UJY-DCRd-Ss4.js} +1 -1
  60. package/web-dist/assets/{gitGraphDiagram-WWUBYQGX-B7-8sszH.js → gitGraphDiagram-WWUBYQGX-CTz13GjS.js} +1 -1
  61. package/web-dist/assets/highlighter-BScH1Ud3.js +2 -0
  62. package/web-dist/assets/{highlighter-core-CMXoD8ze.js → highlighter-core-DKz8Z6-I.js} +1 -1
  63. package/web-dist/assets/{highlighter.worker-D6D9fPma.js → highlighter.worker-CKF6ok1g.js} +1 -1
  64. package/web-dist/assets/index-BUvJ5Ctt.js +1299 -0
  65. package/web-dist/assets/index-DRj7nvPY.css +1 -0
  66. package/web-dist/assets/{infoDiagram-27XIBGKW-BBjf6pkP.js → infoDiagram-27XIBGKW-DNfTEPAV.js} +1 -1
  67. package/web-dist/assets/{ishikawaDiagram-5VMMS53U-BBSvCv45.js → ishikawaDiagram-5VMMS53U-B7aCjjG1.js} +1 -1
  68. package/web-dist/assets/{journeyDiagram-3NMN7TZE-CuHHl5zk.js → journeyDiagram-3NMN7TZE-COmDALVr.js} +1 -1
  69. package/web-dist/assets/{kanban-definition-UXKFOSKX-DJyP4Myw.js → kanban-definition-UXKFOSKX-BzUfPINh.js} +1 -1
  70. package/web-dist/assets/{layout-Bqqhdwtt.js → layout-BwzuPU4M.js} +1 -1
  71. package/web-dist/assets/{linear-BZfUSIf8.js → linear-WPZTYjz3.js} +1 -1
  72. package/web-dist/assets/mermaid.core-zKzlwpkw.js +310 -0
  73. package/web-dist/assets/{mindmap-definition-YA3MSWOX-BtyMD4wz.js → mindmap-definition-YA3MSWOX-DCRg7eAx.js} +1 -1
  74. package/web-dist/assets/{pegDiagram-XKGWAZYB-BUF_GJ0B.js → pegDiagram-XKGWAZYB-DyphzDLU.js} +1 -1
  75. package/web-dist/assets/{pieDiagram-E7YTZNPT-nweubbsU.js → pieDiagram-E7YTZNPT-BI5DueGA.js} +1 -1
  76. package/web-dist/assets/powershell-DXrKVo3G.js +1 -0
  77. package/web-dist/assets/powershell-Dpen1YoG.js +1 -0
  78. package/web-dist/assets/{quadrantDiagram-AXDQQJYC-B_r4Wkxy.js → quadrantDiagram-AXDQQJYC-GZxSMY2Z.js} +1 -1
  79. package/web-dist/assets/{railroadDiagram-O6MQD6OU-Dn7nm0MX.js → railroadDiagram-O6MQD6OU-DEFCigBf.js} +1 -1
  80. package/web-dist/assets/{requirementDiagram-BXWQKSXE-DaagYJ49.js → requirementDiagram-BXWQKSXE-Br0thc4j.js} +1 -1
  81. package/web-dist/assets/{sankeyDiagram-P5KCCOFB-CqEX6H-B.js → sankeyDiagram-P5KCCOFB-DYf0pY67.js} +1 -1
  82. package/web-dist/assets/{sequenceDiagram-WJ2MYXX4-BzLfQO55.js → sequenceDiagram-WJ2MYXX4-1EFMboX4.js} +1 -1
  83. package/web-dist/assets/{sizeCapture-INFHLROL-BcUuVH2L.js → sizeCapture-INFHLROL-BuOFv-5q.js} +1 -1
  84. package/web-dist/assets/{stateDiagram-D77RDMKH-BO3LWLvT.js → stateDiagram-D77RDMKH-Bg3H1tjX.js} +1 -1
  85. package/web-dist/assets/stateDiagram-v2-MP3YSRHH-DfaDaPAd.js +1 -0
  86. package/web-dist/assets/{swimlanes-42K2YHIH-etP_hkIB.js → swimlanes-42K2YHIH-BuOa6Osb.js} +1 -1
  87. package/web-dist/assets/swimlanesDiagram-VR7AAH4N-BopAC7b8.js +8 -0
  88. package/web-dist/assets/{timeline-definition-24CTP7MA-CTLt2XCT.js → timeline-definition-24CTP7MA-BDekfdDT.js} +1 -1
  89. package/web-dist/assets/{vennDiagram-4TSXK5OY-DPO6ZSvH.js → vennDiagram-4TSXK5OY-DnC09UI4.js} +1 -1
  90. package/web-dist/assets/{wardleyDiagram-VM6X3IG4-DFofGg8b.js → wardleyDiagram-VM6X3IG4-BXKvxuZQ.js} +1 -1
  91. package/web-dist/assets/{xterm-RdyTuaAH.js → xterm-oY4DYg5s.js} +1 -1
  92. package/web-dist/assets/{xychartDiagram-S5SC5T6Z-Bgtb34Gu.js → xychartDiagram-S5SC5T6Z-DdDC1VLb.js} +1 -1
  93. package/web-dist/index.html +6 -5
  94. package/dist/chunk-3SFJKLQU.js.map +0 -1
  95. package/dist/chunk-HMTT2PX4.js.map +0 -1
  96. package/dist/chunk-LPPVGHYD.js.map +0 -1
  97. package/dist/chunk-W7JNIJ25.js +0 -19
  98. package/dist/chunk-W7JNIJ25.js.map +0 -1
  99. package/web-dist/assets/channel-mfsAVJLE.js +0 -1
  100. package/web-dist/assets/classDiagram-ZZMXUADV-BPVO1m8i.js +0 -1
  101. package/web-dist/assets/classDiagram-v2-VYDZK3BY-BPVO1m8i.js +0 -1
  102. package/web-dist/assets/highlighter-Bj5l2XH_.js +0 -2
  103. package/web-dist/assets/index-BOCqRT4e.css +0 -1
  104. package/web-dist/assets/index-BrMpjp2s.js +0 -1286
  105. package/web-dist/assets/mermaid.core-BlUspEsI.js +0 -310
  106. package/web-dist/assets/stateDiagram-v2-MP3YSRHH-B-EuucjM.js +0 -1
  107. package/web-dist/assets/swimlanesDiagram-VR7AAH4N-0JbFdDbQ.js +0 -8
  108. /package/dist/{chunk-QFV3ERQO.js.map → chunk-OQZDL3TR.js.map} +0 -0
@@ -0,0 +1,3401 @@
1
+ // src/model-catalog/catalog.ts
2
+ import {
3
+ CLIENT_CREDENTIALS,
4
+ OFFICIAL_CLIENT_TYPES,
5
+ routedClientType
6
+ } from "@prismshadow/mmsp/credentials";
7
+ import { sameClientType } from "@prismshadow/penguin-core/model-connection";
8
+ var VLLM_CLIENT_TYPE = "openai-chat-vllm-adapter";
9
+ var VLLM_LOCAL_BASE_URL = "http://127.0.0.1:8000/v1";
10
+ var OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1";
11
+ var SILICONFLOW_BASE_URL = "https://api.siliconflow.cn/v1";
12
+ var QWEN_TOKEN_PLAN_BASE_URL = "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1";
13
+ var QWEN_PAYG_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
14
+ var FIREWORKS_BASE_URL = "https://api.fireworks.ai/inference/v1";
15
+ var TOKENDANCE_BASE_URL = "https://tokendance.space/gateway/v1";
16
+ var TOKENDANCE_MESSAGES_BASE_URL = "https://tokendance.space/gateway";
17
+ var DEEPSEEK_BASE_URL = "https://api.deepseek.com";
18
+ var MODELSCOPE_BASE_URL = "https://api-inference.modelscope.cn/v1";
19
+ var ATLASCLOUD_BASE_URL = "https://api.atlascloud.ai/v1";
20
+ var PENGUIN_GO_BASE_URL = "https://go.penguin.ooo/api/v1";
21
+ var OPENCODE_GO_BASE_URL = "https://opencode.ai/zen/go/v1";
22
+ var OPENCODE_GO_MESSAGES_BASE_URL = "https://opencode.ai/zen/go";
23
+ var OPENCODE_GO_GOOGLE_BASE_URL = "https://opencode.ai/inference/go/google";
24
+ var PENGUIN_GO_PROVIDER_ID = "penguin-go";
25
+ function fixedClientType(providerId) {
26
+ return providerId === PENGUIN_GO_PROVIDER_ID ? "mmsp" : void 0;
27
+ }
28
+ function fixedClientTypeRefuses(providerId, target, next, stored) {
29
+ const fixed = fixedClientType(providerId);
30
+ if (fixed === void 0) return false;
31
+ const value = next?.trim() ?? "";
32
+ if (value === "") return target === "group" && (stored?.trim() ?? "") !== "";
33
+ if (sameClientType(value, fixed)) return false;
34
+ return stored === void 0 || !sameClientType(value, stored);
35
+ }
36
+ var MODELSCOPE_PROVIDER_ID = "modelscope";
37
+ var MODEL_PROVIDERS = [
38
+ {
39
+ id: "tokendance",
40
+ label: "TokenDance",
41
+ envKey: "OPENAI_API_KEY",
42
+ envBaseUrlKey: "OPENAI_BASE_URL",
43
+ apiKeyUrl: "https://tokendance.space/keys",
44
+ modelsUrl: "https://tokendance.space/models",
45
+ gatewayBaseUrl: TOKENDANCE_BASE_URL,
46
+ // Every preset speaks Chat Completions, and the group takes models added by hand
47
+ // (`addable`), which follow the group: a new Project's `[providers.tokendance]` carries
48
+ // this pin, so such a row resolves to it.
49
+ clientType: "openai-chat",
50
+ addable: true,
51
+ recommended: true,
52
+ // https://tokendance.space/docs/api-key-oauth
53
+ oauth: {
54
+ authorizeUrl: "https://tokendance.space/auth",
55
+ exchangeUrl: "https://tokendance.space/portal/api/v1/auth/keys",
56
+ keyName: "PenguinHarness"
57
+ },
58
+ // https://tokendance.space/docs/open-api (the account's wallet, in micro-yuan)
59
+ balance: {
60
+ url: "https://tokendance.space/portal/api/v1/user/balance",
61
+ format: "tokendance"
62
+ }
63
+ },
64
+ {
65
+ id: PENGUIN_GO_PROVIDER_ID,
66
+ label: "Penguin Go",
67
+ // The authorization flow writes the relay key once, on the group's `[providers.penguin-go]`
68
+ // table, and that key is the only one the group's rows use: a third-party adapter takes
69
+ // keys from the config alone, and every row names the relay, so none is handed the
70
+ // environment's. The env pair records what the mmsp client reads, as a fact. Every row names the relay and speaks MMSP, so a new
71
+ // Project writes both on the group; the protocol is fixed (fixedClientType).
72
+ envKey: "MMSP_API_KEY",
73
+ envBaseUrlKey: "MMSP_BASE_URL",
74
+ apiKeyUrl: "https://go.penguin.ooo/",
75
+ modelsUrl: "https://go.penguin.ooo/",
76
+ bridgeAuth: { flow: "penguin-go" },
77
+ balance: {
78
+ url: "https://go.penguin.ooo/api/me/by-key",
79
+ format: "penguin-go"
80
+ }
81
+ },
82
+ {
83
+ // One key serves the whole group, but its models sit on four protocols (see the group's
84
+ // block comment in MODEL_CATALOG), so no group-level pin: a new Project writes each row's
85
+ // protocol on the row, and the Messages or Google base on the rows that use it. The env pair
86
+ // records what its Chat Completions majority's client reads. Like every gateway's, its rows
87
+ // carry a base URL, so a keyless row is refused: the key goes on the group or the row.
88
+ id: "opencode-go",
89
+ label: "OpenCode Go",
90
+ envKey: "OPENAI_API_KEY",
91
+ envBaseUrlKey: "OPENAI_BASE_URL",
92
+ apiKeyUrl: "https://opencode.ai/v2/docs/console/api/inference/#authentication",
93
+ modelsUrl: "https://opencode.ai/v2/docs/console/go/",
94
+ gatewayBaseUrl: OPENCODE_GO_BASE_URL
95
+ },
96
+ {
97
+ id: "deepseek",
98
+ label: "DeepSeek",
99
+ envKey: "DEEPSEEK_API_KEY",
100
+ envBaseUrlKey: "DEEPSEEK_BASE_URL",
101
+ apiKeyUrl: "https://platform.deepseek.com/api_keys",
102
+ modelsUrl: "https://api-docs.deepseek.com/quick_start/pricing",
103
+ // https://api-docs.deepseek.com/api/get-user-balance
104
+ balance: { url: `${DEEPSEEK_BASE_URL}/user/balance`, format: "deepseek" }
105
+ },
106
+ {
107
+ id: "openrouter",
108
+ label: "OpenRouter",
109
+ envKey: "OPENAI_API_KEY",
110
+ envBaseUrlKey: "OPENAI_BASE_URL",
111
+ apiKeyUrl: "https://openrouter.ai/workspaces/default/keys",
112
+ modelsUrl: "https://openrouter.ai/models",
113
+ gatewayBaseUrl: OPENROUTER_BASE_URL,
114
+ // The whole group speaks the Responses API, which OpenRouter serves at the preset base
115
+ // URL below for every upstream — presets and user-added entries alike.
116
+ clientType: "openai-responses",
117
+ // The catalog lists a fraction of what OpenRouter serves, so the group takes more.
118
+ addable: true
119
+ },
120
+ {
121
+ id: "fireworks",
122
+ label: "Fireworks AI",
123
+ envKey: "OPENAI_API_KEY",
124
+ envBaseUrlKey: "OPENAI_BASE_URL",
125
+ apiKeyUrl: "https://app.fireworks.ai/settings/users/api-keys",
126
+ modelsUrl: "https://app.fireworks.ai/models",
127
+ gatewayBaseUrl: FIREWORKS_BASE_URL
128
+ },
129
+ {
130
+ id: "google",
131
+ label: "Google Gemini",
132
+ envKey: "GEMINI_API_KEY",
133
+ envBaseUrlKey: "GEMINI_BASE_URL",
134
+ apiKeyUrl: "https://aistudio.google.com/api-keys",
135
+ modelsUrl: "https://ai.google.dev/gemini-api/docs/models"
136
+ },
137
+ {
138
+ id: "openai",
139
+ label: "OpenAI",
140
+ envKey: "OPENAI_API_KEY",
141
+ envBaseUrlKey: "OPENAI_BASE_URL",
142
+ apiKeyUrl: "https://platform.openai.com/api-keys",
143
+ modelsUrl: "https://platform.openai.com/docs/models"
144
+ },
145
+ {
146
+ id: "anthropic",
147
+ label: "Anthropic",
148
+ envKey: "ANTHROPIC_API_KEY",
149
+ envBaseUrlKey: "ANTHROPIC_BASE_URL",
150
+ apiKeyUrl: "https://platform.claude.com/settings/keys",
151
+ modelsUrl: "https://docs.claude.com/en/docs/about-claude/models/overview"
152
+ },
153
+ {
154
+ id: "siliconflow",
155
+ label: "SiliconFlow",
156
+ envKey: "OPENAI_API_KEY",
157
+ envBaseUrlKey: "OPENAI_BASE_URL",
158
+ apiKeyUrl: "https://cloud.siliconflow.cn/me/account/ak",
159
+ modelsUrl: "https://cloud.siliconflow.cn/models",
160
+ gatewayBaseUrl: SILICONFLOW_BASE_URL,
161
+ // As TokenDance: Chat Completions throughout, and models added by hand follow the group.
162
+ clientType: "openai-chat",
163
+ addable: true
164
+ },
165
+ {
166
+ id: "atlascloud",
167
+ label: "Atlas Cloud",
168
+ envKey: "OPENAI_API_KEY",
169
+ envBaseUrlKey: "OPENAI_BASE_URL",
170
+ apiKeyUrl: "https://atlascloud.ai/docs/api-keys",
171
+ modelsUrl: "https://atlascloud.ai/models",
172
+ gatewayBaseUrl: ATLASCLOUD_BASE_URL,
173
+ // As SiliconFlow: Chat Completions throughout, and the catalog lists a fraction of what
174
+ // the gateway serves, so the group takes models added by hand, which follow the group.
175
+ clientType: "openai-chat",
176
+ addable: true
177
+ },
178
+ {
179
+ id: "zhipu",
180
+ label: "Z.AI (GLM)",
181
+ envKey: "ZAI_API_KEY",
182
+ envBaseUrlKey: "ZAI_BASE_URL",
183
+ apiKeyUrl: "https://open.bigmodel.cn/apikey/platform",
184
+ modelsUrl: "https://docs.z.ai/guides/overview/pricing"
185
+ },
186
+ {
187
+ id: "moonshot",
188
+ label: "Moonshot (Kimi)",
189
+ envKey: "MOONSHOT_API_KEY",
190
+ envBaseUrlKey: "MOONSHOT_BASE_URL",
191
+ apiKeyUrl: "https://platform.kimi.com/console/api-keys",
192
+ modelsUrl: "https://platform.kimi.com/docs/pricing"
193
+ },
194
+ {
195
+ id: "minimax",
196
+ label: "MiniMax",
197
+ envKey: "MINIMAX_API_KEY",
198
+ envBaseUrlKey: "MINIMAX_BASE_URL",
199
+ // The pay-as-you-go key page; a Token Plan Subscription Key (Billing > Token Plan) works
200
+ // against the same endpoint, so the group is not tied to either billing mode.
201
+ apiKeyUrl: "https://platform.minimax.io/user-center/basic-information/interface-key",
202
+ modelsUrl: "https://platform.minimax.io/docs/guides/models-intro"
203
+ },
204
+ {
205
+ id: "qwen-pay-as-you-go",
206
+ label: "Qwen Pay-As-You-Go",
207
+ envKey: "OPENAI_API_KEY",
208
+ envBaseUrlKey: "OPENAI_BASE_URL",
209
+ apiKeyUrl: "https://platform.qianwenai.com/docs/api-reference/preparation/api-key",
210
+ modelsUrl: "https://www.qianwenai.com/models",
211
+ gatewayBaseUrl: QWEN_PAYG_BASE_URL
212
+ },
213
+ {
214
+ id: "qwen-token-plan",
215
+ label: "Qwen Token Plan",
216
+ envKey: "OPENAI_API_KEY",
217
+ envBaseUrlKey: "OPENAI_BASE_URL",
218
+ apiKeyUrl: "https://platform.qianwenai.com/pricing/token-plan",
219
+ modelsUrl: "https://platform.qianwenai.com/docs/token-plan/personal/token-plan-personal-overview",
220
+ gatewayBaseUrl: QWEN_TOKEN_PLAN_BASE_URL
221
+ },
222
+ {
223
+ // ModelScope's own inference service: OpenAI-compatible, reselling other vendors' models
224
+ // under `org/Model-Name` ids. Two things set it apart from the gateways above.
225
+ //
226
+ // Its credential is the account's access token rather than a minted API key, and the
227
+ // group obtains one through the authorization bridge instead of sending the user to copy
228
+ // it out of the console (bridgeAuth below; the console link stays for anyone who already
229
+ // has a token). ModelScope is the vendor here as well as the gateway — the bridge exists
230
+ // because its OAuth requires a client secret the desktop App cannot keep locally, not
231
+ // because inference requests are routed through that bridge.
232
+ //
233
+ // Every preset row names the endpoint and one protocol in the catalog, so a new Project
234
+ // writes both on the group's `[providers.modelscope]` table and the rows follow it.
235
+ id: MODELSCOPE_PROVIDER_ID,
236
+ label: "ModelScope",
237
+ envKey: "OPENAI_API_KEY",
238
+ envBaseUrlKey: "OPENAI_BASE_URL",
239
+ apiKeyUrl: "https://www.modelscope.cn/my/myaccesstoken",
240
+ modelsUrl: "https://www.modelscope.cn/models",
241
+ gatewayBaseUrl: MODELSCOPE_BASE_URL,
242
+ bridgeAuth: { flow: "modelscope" }
243
+ },
244
+ {
245
+ // Self-hosted: the user runs the server, so there is no console to mint a key at
246
+ // (apiKeyUrl) and no endpoint every user shares (gatewayBaseUrl). The group's rows name the
247
+ // address a server started on this machine answers on, which a new Project stores as the
248
+ // group's base URL. modelsUrl points at the recipe index, which is where the served ids in
249
+ // this group are documented.
250
+ id: "vllm",
251
+ label: "vLLM",
252
+ // vLLM's own pair, which MMSP's vLLM client reads, and never OpenAI's.
253
+ envKey: "VLLM_API_KEY",
254
+ envBaseUrlKey: "VLLM_BASE_URL",
255
+ modelsUrl: "https://recipes.vllm.ai/",
256
+ clientType: VLLM_CLIENT_TYPE,
257
+ // The served ids are the user's own, so this group keeps taking models added by hand.
258
+ addable: true
259
+ },
260
+ {
261
+ id: "custom",
262
+ label: "Custom",
263
+ envKey: "OPENAI_API_KEY",
264
+ envBaseUrlKey: "OPENAI_BASE_URL",
265
+ addable: true
266
+ }
267
+ ];
268
+ function cny(cacheRead, cacheWrite, output) {
269
+ const r = (v) => Math.round(v / 7 * 1e6) / 1e6;
270
+ return usd(r(cacheRead), r(cacheWrite), r(output));
271
+ }
272
+ function usd(cacheRead, cacheWrite, output) {
273
+ return { unit: "usd_per_mtok", cache_read: cacheRead, cache_write: cacheWrite, output };
274
+ }
275
+ function offPeakAt(schedule, now) {
276
+ const local = new Date(now.getTime() + schedule.utcOffsetMinutes * 6e4);
277
+ const isoDay = local.getUTCDay() === 0 ? 7 : local.getUTCDay();
278
+ if (!schedule.peakDays.includes(isoDay)) return true;
279
+ const hour = local.getUTCHours() + local.getUTCMinutes() / 60;
280
+ return !schedule.peakHours.some(([from, to]) => hour >= from && hour < to);
281
+ }
282
+ var DEEPSEEK_OFF_PEAK = {
283
+ rate: 0.5,
284
+ utcOffsetMinutes: 480,
285
+ peakDays: [1, 2, 3, 4, 5],
286
+ peakHours: [
287
+ [9, 12],
288
+ [14, 18]
289
+ ]
290
+ };
291
+ var QWEN_OFF_PEAK = {
292
+ rate: 0.5,
293
+ utcOffsetMinutes: 480,
294
+ peakDays: [1, 2, 3, 4, 5, 6, 7],
295
+ peakHours: [[8, 22]]
296
+ };
297
+ function offPeakScheduledRefs() {
298
+ const bySchedule = /* @__PURE__ */ new Map();
299
+ for (const entry of MODEL_CATALOG) {
300
+ const schedule = entry.offPeakDiscount;
301
+ if (schedule === void 0) continue;
302
+ const group = bySchedule.get(schedule) ?? { schedule, refs: [] };
303
+ group.refs.push({ provider: entry.provider, modelId: entry.modelId });
304
+ bySchedule.set(schedule, group);
305
+ }
306
+ return [...bySchedule.values()];
307
+ }
308
+ function effectivePricing(entry, now = /* @__PURE__ */ new Date()) {
309
+ const { pricing } = entry;
310
+ if (pricing === void 0) return pricing;
311
+ const tier = entry.offPeakDiscount !== void 0 && offPeakAt(entry.offPeakDiscount, now) ? entry.offPeakDiscount.rate : 0;
312
+ const kept = (1 - tier) * (1 - (entry.discount ?? 0));
313
+ if (kept === 1) return pricing;
314
+ const off = (v) => Math.round(v * kept * 1e6) / 1e6;
315
+ return {
316
+ unit: pricing.unit,
317
+ cache_read: off(pricing.cache_read),
318
+ cache_write: off(pricing.cache_write),
319
+ output: off(pricing.output)
320
+ };
321
+ }
322
+ var MODEL_CATALOG = [
323
+ // -- DeepSeek (official CNY pricing: cache hit / cache miss / output). Prices and model
324
+ // names re-read 2026-09-16 from api-docs.deepseek.com/zh-cn/quick_start/pricing, which now
325
+ // lists exactly two names, both with a 1M context window and a 384K output cap:
326
+ // `deepseek-flash` (DeepSeek-V4.1-Flash, image input) on the peak tier CNY 0.04 / 2 / 8, and
327
+ // `deepseek-v4-pro` (DeepSeek-V4-Pro-0813, text only) at 0.30 / 9 / 27. The rows store the
328
+ // PEAK tier and declare DEEPSEEK_OFF_PEAK, which halves every bucket outside Beijing weekday
329
+ // 09:00-12:00 and 14:00-18:00 — so both tiers are billed at the rate actually in force,
330
+ // rather than one of them being approximated by the other.
331
+ // The retired V4 Flash names, `deepseek-v4-flash` and `deepseek-v4-flash-vision-exp`, are
332
+ // still accepted and served by V4.1 Flash at the Flash price and on the same schedule, but
333
+ // the page no longer lists them: they stay below as retired rows, which are not presets. --
334
+ {
335
+ // DeepSeek's pricing page names this model `deepseek-flash` (model version
336
+ // DeepSeek-V4.1-Flash, released as of the 2026-09-10 read): 1M context, image input, and
337
+ // the Flash series peak price and off-peak schedule.
338
+ modelId: "deepseek-flash",
339
+ displayName: "DeepSeek V4.1 Flash",
340
+ provider: "deepseek",
341
+ contextWindow: 1e6,
342
+ pricing: cny(0.04, 2, 8),
343
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
344
+ supportsVision: true,
345
+ wasDefault: true
346
+ },
347
+ {
348
+ // Retired 2026-09-16 (see ModelCatalogEntry.retired): the default model of new Projects
349
+ // from 0.2.0 to 0.2.8. DeepSeek still accepts the id and serves it from V4.1 Flash at the
350
+ // Flash price, off-peak schedule included. Text only: MMSP's DeepSeek client refuses
351
+ // image parts for this id.
352
+ modelId: "deepseek-v4-flash",
353
+ displayName: "DeepSeek V4 Flash",
354
+ provider: "deepseek",
355
+ contextWindow: 1e6,
356
+ pricing: cny(0.04, 2, 8),
357
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
358
+ supportsVision: false,
359
+ retired: true,
360
+ wasDefault: true
361
+ },
362
+ {
363
+ // Retired 2026-09-16 (see ModelCatalogEntry.retired): the default model of new Projects in
364
+ // 0.2.9, served from V4.1 Flash at the Flash price like deepseek-v4-flash above.
365
+ modelId: "deepseek-v4-flash-vision-exp",
366
+ displayName: "DeepSeek V4 Flash Vision Exp",
367
+ provider: "deepseek",
368
+ contextWindow: 1e6,
369
+ pricing: cny(0.04, 2, 8),
370
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
371
+ supportsVision: true,
372
+ retired: true,
373
+ wasDefault: true
374
+ },
375
+ {
376
+ // DeepSeek's pricing page names the model behind this id DeepSeek-V4-Pro-0813 (read
377
+ // 2026-09-16), which is what the display name says — the same 0813 release the gateway
378
+ // groups sell under dated ids. Text only. DeepSeek states that V4 Pro stays available
379
+ // after 2026-09-14 with its billing unchanged, so the row keeps the V4 Pro peak price on
380
+ // the shared off-peak schedule. MMSP's DeepSeek client also matches this bare id against
381
+ // its text-only deny-list /^deepseek-v4-(flash|pro)(-\d{4})?$/, so image parts never
382
+ // leave the harness for it.
383
+ modelId: "deepseek-v4-pro",
384
+ displayName: "DeepSeek V4 Pro 0813",
385
+ provider: "deepseek",
386
+ contextWindow: 1e6,
387
+ pricing: cny(0.3, 9, 27),
388
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
389
+ supportsVision: false,
390
+ wasDefault: true
391
+ },
392
+ // -- OpenRouter (gateway: OpenAI-compatible protocol, preset base URL). Prices re-read in
393
+ // one pass on 2026-08-07 from the models API (/api/v1/models; the API is authoritative
394
+ // where a model's web page disagrees); the DeepSeek rows, the rows added on 2026-08-18
395
+ // (grok-4.6, deepseek-v4-pro-0813, glm-5.3, the openai/* additions) and every
396
+ // pre-existing openai/* and google/* row were re-read on 2026-08-18 from the model
397
+ // pages and the per-model endpoints API. The rows added on 2026-10-10 — the four Claude 5.x
398
+ // rows, openai/gpt-6.1-sol, stepfun/step-5-preview, x-ai/grok-4.7,
399
+ // xiaomi/mimo-v2.6-flash and xiaomi/mimo-v2.6-pro — were read that day from the models API and the per-model
400
+ // endpoints API, whose default endpoint runs no promotion (`discount: 0`) on any of them;
401
+ // their context windows are the listing's `top_provider.context_length`, as on the
402
+ // mimo-v2.5 and step-3.7-flash rows.
403
+ //
404
+ // Protocol: every row pins `openai-responses`. OpenRouter serves the Responses API at
405
+ // {base}/responses for every upstream, at the same https://openrouter.ai/api/v1 base URL
406
+ // the rows already carry, and the group pins the same protocol, which a new Project writes on
407
+ // `[providers.openrouter]`, so an entry added to it by hand follows it. The generic Responses client sends a text-only tool result as a plain
408
+ // string and replays reasoning items only where the upstream returned them.
409
+ //
410
+ // Price buckets: cache_read stores the published input_cache_read
411
+ // (falling back to the input price for the rows without one — the :free rows and the
412
+ // GPT Pro tiers, which publish no cache discount); cache_write stores
413
+ // input_cache_write only when it is a genuine per-token write premium (the Anthropic, GPT
414
+ // and qwen3.8-max rows, 1.25x input) —
415
+ // Gemini's field is an hourly cache-STORAGE rate, not a per-token price, so those rows
416
+ // keep the input price — and otherwise also carries the input price. The :free tier and
417
+ // the openrouter/free Free Models Router store a genuine $0 price (not "unknown"), so
418
+ // costs correctly compute to 0. GPT models are uniformly vision-capable (OpenAI
419
+ // product-line policy) even where the gateway page omits the modality.
420
+ //
421
+ // Discounts: what these rows record is what OpenRouter actually BILLS, so a gateway
422
+ // promotion is stored at its discounted rate (unlike the direct-vendor rows, which keep the
423
+ // list price). The Gemini 3.x Flash rows are the exception: the promotion they sit on is
424
+ // Google's own dated launch discount rather than the gateway's, so they keep the list price
425
+ // and declare it in `discount`, exactly as their direct-vendor twins do. The endpoints API
426
+ // exposes the running promotion as `pricing.discount` on the default endpoint; rows sitting
427
+ // on one say so and name the rate to restore, because a lapsed promotion silently doubles
428
+ // the real cost — that is exactly how the gpt-5.6-terra and gpt-5.6-luna rows drifted 2x
429
+ // low before the 2026-08-18 re-read. --
430
+ {
431
+ // $10 input / $12.50 cache write / $0.25 cache read / $50 output, the cache read at 2.5% of
432
+ // input as on Anthropic's own list; 1M window, image input.
433
+ modelId: "anthropic/claude-fable-5.1",
434
+ displayName: "Claude Fable 5.1",
435
+ provider: "openrouter",
436
+ contextWindow: 1e6,
437
+ pricing: usd(0.25, 12.5, 50),
438
+ supportsVision: true,
439
+ clientType: "openai-responses",
440
+ baseUrl: OPENROUTER_BASE_URL
441
+ },
442
+ {
443
+ modelId: "anthropic/claude-fable-5",
444
+ displayName: "Claude Fable 5",
445
+ provider: "openrouter",
446
+ contextWindow: 1e6,
447
+ pricing: usd(1, 12.5, 50),
448
+ supportsVision: true,
449
+ clientType: "openai-responses",
450
+ baseUrl: OPENROUTER_BASE_URL
451
+ },
452
+ {
453
+ // $0.10 input / $0.125 cache write / $0.01 cache read / $0.50 output for prompts up to
454
+ // 100,000 tokens; the listing's `overrides` bill every rate 5x from 100,000 prompt tokens,
455
+ // Anthropic's own tiering. The base tier is recorded, as for the other tiered rows.
456
+ modelId: "anthropic/claude-haiku-5.5",
457
+ displayName: "Claude Haiku 5.5",
458
+ provider: "openrouter",
459
+ contextWindow: 1e6,
460
+ pricing: usd(0.01, 0.125, 0.5),
461
+ supportsVision: true,
462
+ clientType: "openai-responses",
463
+ baseUrl: OPENROUTER_BASE_URL
464
+ },
465
+ {
466
+ // $4 input / $5 cache write / $0.20 cache read / $20 output.
467
+ modelId: "anthropic/claude-opus-5.5",
468
+ displayName: "Claude Opus 5.5",
469
+ provider: "openrouter",
470
+ contextWindow: 1e6,
471
+ pricing: usd(0.2, 5, 20),
472
+ supportsVision: true,
473
+ clientType: "openai-responses",
474
+ baseUrl: OPENROUTER_BASE_URL
475
+ },
476
+ {
477
+ modelId: "anthropic/claude-opus-5",
478
+ displayName: "Claude Opus 5",
479
+ provider: "openrouter",
480
+ contextWindow: 1e6,
481
+ pricing: usd(0.5, 6.25, 25),
482
+ supportsVision: true,
483
+ clientType: "openai-responses",
484
+ baseUrl: OPENROUTER_BASE_URL
485
+ },
486
+ {
487
+ modelId: "anthropic/claude-opus-4.8",
488
+ displayName: "Claude Opus 4.8",
489
+ provider: "openrouter",
490
+ contextWindow: 1e6,
491
+ pricing: usd(0.5, 6.25, 25),
492
+ supportsVision: true,
493
+ clientType: "openai-responses",
494
+ baseUrl: OPENROUTER_BASE_URL
495
+ },
496
+ {
497
+ modelId: "anthropic/claude-opus-4.7",
498
+ displayName: "Claude Opus 4.7",
499
+ provider: "openrouter",
500
+ contextWindow: 1e6,
501
+ pricing: usd(0.5, 6.25, 25),
502
+ supportsVision: true,
503
+ clientType: "openai-responses",
504
+ baseUrl: OPENROUTER_BASE_URL
505
+ },
506
+ {
507
+ // $2 input / $2.50 cache write / $0.10 cache read / $10 output. The cache read is half
508
+ // Sonnet 5's $0.20: Anthropic prices it at 5% of input on this generation (MMSP 0.5.2
509
+ // moved its registry row from $0.20), and OpenRouter bills the same.
510
+ modelId: "anthropic/claude-sonnet-5.5",
511
+ displayName: "Claude Sonnet 5.5",
512
+ provider: "openrouter",
513
+ contextWindow: 1e6,
514
+ pricing: usd(0.1, 2.5, 10),
515
+ supportsVision: true,
516
+ clientType: "openai-responses",
517
+ baseUrl: OPENROUTER_BASE_URL
518
+ },
519
+ {
520
+ modelId: "anthropic/claude-sonnet-5",
521
+ displayName: "Claude Sonnet 5",
522
+ provider: "openrouter",
523
+ contextWindow: 1e6,
524
+ pricing: usd(0.2, 2.5, 10),
525
+ supportsVision: true,
526
+ clientType: "openai-responses",
527
+ baseUrl: OPENROUTER_BASE_URL
528
+ },
529
+ {
530
+ // Listed 2026-09-10 from the models API: the base price is the PEAK tier and
531
+ // `pricing.overrides` bill exactly half on weekends and outside weekday UTC 01:00-04:00 /
532
+ // 06:00-10:00 — DeepSeek's own Beijing windows — so the row stores the peak price and
533
+ // declares DEEPSEEK_OFF_PEAK, exactly as the direct row does. Context window and image
534
+ // input from the same listing.
535
+ modelId: "deepseek/deepseek-v4.1-flash",
536
+ displayName: "DeepSeek V4.1 Flash",
537
+ provider: "openrouter",
538
+ contextWindow: 1048576,
539
+ pricing: usd(6e-3, 0.3, 1.2),
540
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
541
+ supportsVision: true,
542
+ clientType: "openai-responses",
543
+ baseUrl: OPENROUTER_BASE_URL
544
+ },
545
+ {
546
+ // The 1017 snapshot, served by DeepSeek's own endpoint (MMSP 0.5.5's registry, models API
547
+ // read 2026-10-19): $0.15 / $0.60 / $0.003 off-peak, double in DeepSeek's weekday windows,
548
+ // so the row stores that peak and declares DEEPSEEK_OFF_PEAK like the row above.
549
+ modelId: "deepseek/deepseek-v4.1-flash-1017",
550
+ displayName: "DeepSeek V4.1 Flash 1017",
551
+ provider: "openrouter",
552
+ contextWindow: 1048576,
553
+ pricing: usd(6e-3, 0.3, 1.2),
554
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
555
+ supportsVision: true,
556
+ clientType: "openai-responses",
557
+ baseUrl: OPENROUTER_BASE_URL
558
+ },
559
+ {
560
+ modelId: "deepseek/deepseek-v4-flash-0731",
561
+ displayName: "DeepSeek V4 Flash 0731",
562
+ provider: "openrouter",
563
+ contextWindow: 1e6,
564
+ pricing: usd(0.0157192, 0.078596, 0.157192),
565
+ supportsVision: false,
566
+ clientType: "openai-responses",
567
+ baseUrl: OPENROUTER_BASE_URL
568
+ },
569
+ {
570
+ modelId: "deepseek/deepseek-v4-flash",
571
+ displayName: "DeepSeek V4 Flash",
572
+ provider: "openrouter",
573
+ contextWindow: 1e6,
574
+ pricing: usd(0.0168, 0.0679, 0.168),
575
+ supportsVision: false,
576
+ clientType: "openai-responses",
577
+ baseUrl: OPENROUTER_BASE_URL
578
+ },
579
+ {
580
+ // DeepSeek serves this one alone on OpenRouter, so the stored rates are its own published
581
+ // USD list ($0.22 / $0.66 / $0.007 cache read), and the context window is that endpoint's
582
+ // 1,048,576. The row keeps that flat price as the API lists it: as of the 2026-09-10 read
583
+ // the listing carries no `pricing.overrides`, so unlike the deepseek-v4.1-flash row above
584
+ // there is no peak/off-peak split to record here.
585
+ modelId: "deepseek/deepseek-v4-flash-vision-exp",
586
+ displayName: "DeepSeek V4 Flash Vision Exp",
587
+ provider: "openrouter",
588
+ contextWindow: 1048576,
589
+ pricing: usd(7e-3, 0.22, 0.66),
590
+ supportsVision: true,
591
+ clientType: "openai-responses",
592
+ baseUrl: OPENROUTER_BASE_URL
593
+ },
594
+ {
595
+ // The 0813 general-availability release of DeepSeek V4 Pro (OpenRouter listing dated
596
+ // 2026-08-12); the default routed endpoint is DeepSeek's own API, so the price matches
597
+ // the official USD list, and the context window is the default endpoint's 1,048,576.
598
+ modelId: "deepseek/deepseek-v4-pro-0813",
599
+ displayName: "DeepSeek V4 Pro 0813",
600
+ provider: "openrouter",
601
+ contextWindow: 1048576,
602
+ pricing: usd(0.022, 0.66, 1.98),
603
+ supportsVision: false,
604
+ clientType: "openai-responses",
605
+ baseUrl: OPENROUTER_BASE_URL
606
+ },
607
+ {
608
+ modelId: "deepseek/deepseek-v4-pro",
609
+ displayName: "DeepSeek V4 Pro",
610
+ provider: "openrouter",
611
+ contextWindow: 1e6,
612
+ pricing: usd(0.022, 0.66, 1.98),
613
+ supportsVision: false,
614
+ clientType: "openai-responses",
615
+ baseUrl: OPENROUTER_BASE_URL
616
+ },
617
+ {
618
+ // Standard tier from openrouter.ai/google/gemini-4-argon (2026-10-14): Google's
619
+ // $4 input / $20 output / $0.20 cache hit, 50% off through 2026-11-30. Argon supports
620
+ // implicit caching only, so cache_write records input rather than cache storage.
621
+ modelId: "google/gemini-4-argon",
622
+ displayName: "Gemini 4 Argon",
623
+ provider: "openrouter",
624
+ contextWindow: 1048576,
625
+ pricing: usd(0.2, 4, 20),
626
+ discount: 0.5,
627
+ supportsVision: true,
628
+ clientType: "openai-responses",
629
+ baseUrl: OPENROUTER_BASE_URL
630
+ },
631
+ {
632
+ // Same Gemini cache conventions as the gemini-3.6-flash row below. OpenRouter passes
633
+ // Google's launch discount through, so it bills $0.075/$0.75/$3.75 — the list price less
634
+ // 50%, declared in `discount` so the $0.15/$1.50/$7.50 list survives the promotion (same
635
+ // treatment as the 3.6 row below). Gemini 3.7 Flash is no longer listed beside it: Google
636
+ // retires that id and reroutes it to 3.8 Flash.
637
+ modelId: "google/gemini-3.8-flash",
638
+ displayName: "Gemini 3.8 Flash",
639
+ provider: "openrouter",
640
+ contextWindow: 1048576,
641
+ pricing: usd(0.15, 1.5, 7.5),
642
+ discount: 0.5,
643
+ supportsVision: true,
644
+ clientType: "openai-responses",
645
+ baseUrl: OPENROUTER_BASE_URL
646
+ },
647
+ {
648
+ // cache_read is billed as its own bucket in the cost center, and an input-priced
649
+ // cache_read would overstate cache-heavy Gemini spend 10x; cache_write repeats the input
650
+ // price (see the block comment — Gemini publishes storage-per-hour, not per-token write),
651
+ // matching the direct-vendor Gemini rows below. OpenRouter bills $0.075/$0.75/$3.75
652
+ // today (endpoints API, read 2026-09-09): it reports that halved rate as its plain price
653
+ // with `discount: 0`, but it is Google's launch discount passed through and ends with it
654
+ // on 2026-12-31, so this row records the list price and the promotion the way its
655
+ // siblings do.
656
+ modelId: "google/gemini-3.6-flash",
657
+ displayName: "Gemini 3.6 Flash",
658
+ provider: "openrouter",
659
+ contextWindow: 1048576,
660
+ pricing: usd(0.15, 1.5, 7.5),
661
+ discount: 0.5,
662
+ supportsVision: true,
663
+ clientType: "openai-responses",
664
+ baseUrl: OPENROUTER_BASE_URL
665
+ },
666
+ {
667
+ // The 3.5 tier's own list price — $1.50 input / $9.00 output / $0.15 cache hit on Google's
668
+ // page, with no launch discount — and OpenRouter's default endpoint bills exactly that
669
+ // (`discount: 0`, read 2026-09-09). The $9 output is the tier, not a promotion to declare.
670
+ modelId: "google/gemini-3.5-flash",
671
+ displayName: "Gemini 3.5 Flash",
672
+ provider: "openrouter",
673
+ contextWindow: 1048576,
674
+ pricing: usd(0.15, 1.5, 9),
675
+ supportsVision: true,
676
+ clientType: "openai-responses",
677
+ baseUrl: OPENROUTER_BASE_URL
678
+ },
679
+ {
680
+ // Same published-cache-price convention as gemini-3.6-flash above (2026-07-22: $0.03/mtok
681
+ // cache hit, $0.30 input, $2.50 output; re-read 2026-09-09, unchanged and `discount: 0`).
682
+ modelId: "google/gemini-3.5-flash-lite",
683
+ displayName: "Gemini 3.5 Flash-Lite",
684
+ provider: "openrouter",
685
+ contextWindow: 1048576,
686
+ pricing: usd(0.03, 0.3, 2.5),
687
+ supportsVision: true,
688
+ clientType: "openai-responses",
689
+ baseUrl: OPENROUTER_BASE_URL
690
+ },
691
+ {
692
+ // The paid listing, which replaced the free variant when its free period ended (models API
693
+ // read 2026-10-23): $0.15 input / $0.60 output / $0.015 cache read, 1,048,576 tokens, image
694
+ // input, MiniMax's own list price.
695
+ modelId: "minimax/minimax-m3.1-flash",
696
+ displayName: "MiniMax M3.1 Flash",
697
+ provider: "openrouter",
698
+ contextWindow: 1048576,
699
+ pricing: usd(0.015, 0.15, 0.6),
700
+ supportsVision: true,
701
+ clientType: "openai-responses",
702
+ baseUrl: OPENROUTER_BASE_URL
703
+ },
704
+ {
705
+ // No official separate cache price published: cache_read uses the standard input price (no discount assumed).
706
+ modelId: "minimax/minimax-m3",
707
+ displayName: "MiniMax M3",
708
+ provider: "openrouter",
709
+ contextWindow: 1048576,
710
+ pricing: usd(0.06, 0.3, 1.2),
711
+ supportsVision: true,
712
+ clientType: "openai-responses",
713
+ baseUrl: OPENROUTER_BASE_URL
714
+ },
715
+ {
716
+ // Read 2026-10-24 from the models API and the per-model endpoints API: $2 input / $10
717
+ // output / $0.20 cache read over 1,048,576 tokens, image input, served by Moonshot AI alone
718
+ // and with no promotion on the default endpoint (`discount: 0`). The listing's
719
+ // `moonshotai/highspeed` endpoint ($4 / $20 / $0.20) is a provider route under this same id,
720
+ // not a model of its own.
721
+ modelId: "moonshotai/kimi-k3.1-pro",
722
+ displayName: "Kimi K3.1 Pro",
723
+ provider: "openrouter",
724
+ contextWindow: 1048576,
725
+ pricing: usd(0.2, 2, 10),
726
+ supportsVision: true,
727
+ clientType: "openai-responses",
728
+ baseUrl: OPENROUTER_BASE_URL
729
+ },
730
+ {
731
+ modelId: "moonshotai/kimi-k3",
732
+ displayName: "Kimi K3",
733
+ provider: "openrouter",
734
+ contextWindow: 1e6,
735
+ pricing: usd(0.3, 3, 15),
736
+ supportsVision: true,
737
+ clientType: "openai-responses",
738
+ baseUrl: OPENROUTER_BASE_URL
739
+ },
740
+ {
741
+ modelId: "moonshotai/kimi-k2.6",
742
+ displayName: "Kimi K2.6",
743
+ provider: "openrouter",
744
+ contextWindow: 262144,
745
+ pricing: usd(0.0992, 0.589, 2.48),
746
+ supportsVision: true,
747
+ clientType: "openai-responses",
748
+ baseUrl: OPENROUTER_BASE_URL
749
+ },
750
+ {
751
+ modelId: "nvidia/nemotron-3-ultra-550b-a55b:free",
752
+ displayName: "Nemotron 3 Ultra (free)",
753
+ provider: "openrouter",
754
+ contextWindow: 1e6,
755
+ pricing: usd(0, 0, 0),
756
+ supportsVision: false,
757
+ clientType: "openai-responses",
758
+ baseUrl: OPENROUTER_BASE_URL
759
+ },
760
+ // The openai/* rows below mirror the direct OpenAI group one-for-one. Their context
761
+ // windows are OpenRouter's published 1,050,000 / 400,000, matching the direct rows.
762
+ {
763
+ // Read 2026-10-10: the default endpoint is OpenAI's own, at $2 input / $0.10 cached input
764
+ // / $2.50 cache write / $10 output with `discount: 0`, OpenAI's list. The listing's
765
+ // `overrides` from 272,000 prompt tokens (2x prompt and cache, 1.5x completion) are the
766
+ // long-context tier, which is not recorded, as on the direct row.
767
+ modelId: "openai/gpt-6.1-sol",
768
+ displayName: "GPT-6.1 Sol",
769
+ provider: "openrouter",
770
+ contextWindow: 105e4,
771
+ pricing: usd(0.1, 2.5, 10),
772
+ supportsVision: true,
773
+ clientType: "openai-responses",
774
+ baseUrl: OPENROUTER_BASE_URL
775
+ },
776
+ {
777
+ // Read 2026-09-09 from the models API and the per-model endpoints API: the default
778
+ // endpoint is OpenAI's own, listed at $10 input / $1 cached input / $12.5 cache write /
779
+ // $50 output with `discount: 0`, so the list price is what OpenRouter bills. The
780
+ // endpoints API also publishes `overrides` above 272,000 prompt tokens (2x prompt and
781
+ // cache, 1.5x completion); as on the direct row, only the base tier is recorded.
782
+ modelId: "openai/gpt-6-astra",
783
+ displayName: "GPT-6 Astra",
784
+ provider: "openrouter",
785
+ contextWindow: 105e4,
786
+ pricing: usd(1, 12.5, 50),
787
+ supportsVision: true,
788
+ clientType: "openai-responses",
789
+ baseUrl: OPENROUTER_BASE_URL
790
+ },
791
+ {
792
+ // https://developers.openai.com/api/docs/models/gpt-6-luna (2026-10-14).
793
+ // Base tier: above 272K input, input/cache rates double and output is 1.5x.
794
+ modelId: "openai/gpt-6-luna",
795
+ displayName: "GPT-6 Luna",
796
+ provider: "openrouter",
797
+ contextWindow: 105e4,
798
+ pricing: usd(0.01, 0.125, 0.5),
799
+ supportsVision: true,
800
+ clientType: "openai-responses",
801
+ baseUrl: OPENROUTER_BASE_URL
802
+ },
803
+ {
804
+ // The 50% promotion this row used to store has ended: OpenRouter now bills the full
805
+ // $0.20/$1.20 rate (endpoints API `discount: 0`), so the stored rates doubled on the
806
+ // 2026-08-18 re-read.
807
+ modelId: "openai/gpt-5.6-luna",
808
+ displayName: "GPT-5.6 Luna",
809
+ provider: "openrouter",
810
+ contextWindow: 105e4,
811
+ pricing: usd(0.02, 0.25, 1.2),
812
+ supportsVision: true,
813
+ clientType: "openai-responses",
814
+ baseUrl: OPENROUTER_BASE_URL
815
+ },
816
+ {
817
+ // Running a `discount: 0.5` promotion as of 2026-08-18, so OpenRouter bills half the
818
+ // $0.50/$6.25/$30 list price — restore the list rates when the promotion ends.
819
+ modelId: "openai/gpt-5.6-sol",
820
+ displayName: "GPT-5.6 Sol",
821
+ provider: "openrouter",
822
+ contextWindow: 105e4,
823
+ pricing: usd(0.25, 3.125, 15),
824
+ supportsVision: true,
825
+ clientType: "openai-responses",
826
+ baseUrl: OPENROUTER_BASE_URL
827
+ },
828
+ {
829
+ // Same lapsed promotion as the luna row: now billed at the full $2/$12 rate.
830
+ modelId: "openai/gpt-5.6-terra",
831
+ displayName: "GPT-5.6 Terra",
832
+ provider: "openrouter",
833
+ contextWindow: 105e4,
834
+ pricing: usd(0.2, 2.5, 12),
835
+ supportsVision: true,
836
+ clientType: "openai-responses",
837
+ baseUrl: OPENROUTER_BASE_URL
838
+ },
839
+ {
840
+ modelId: "openai/gpt-5.5",
841
+ displayName: "GPT-5.5",
842
+ provider: "openrouter",
843
+ contextWindow: 105e4,
844
+ pricing: usd(0.5, 5, 30),
845
+ supportsVision: true,
846
+ clientType: "openai-responses",
847
+ baseUrl: OPENROUTER_BASE_URL
848
+ },
849
+ {
850
+ // No published cache discount (the Pro tiers bill cached input at the standard rate), so
851
+ // cache_read carries the input price — same convention as the direct gpt-5.5-pro row.
852
+ modelId: "openai/gpt-5.5-pro",
853
+ displayName: "GPT-5.5 Pro",
854
+ provider: "openrouter",
855
+ contextWindow: 105e4,
856
+ pricing: usd(30, 30, 180),
857
+ supportsVision: true,
858
+ clientType: "openai-responses",
859
+ baseUrl: OPENROUTER_BASE_URL
860
+ },
861
+ {
862
+ modelId: "openai/gpt-5.4",
863
+ displayName: "GPT-5.4",
864
+ provider: "openrouter",
865
+ contextWindow: 105e4,
866
+ pricing: usd(0.25, 2.5, 15),
867
+ supportsVision: true,
868
+ clientType: "openai-responses",
869
+ baseUrl: OPENROUTER_BASE_URL
870
+ },
871
+ {
872
+ modelId: "openai/gpt-5.4-mini",
873
+ displayName: "GPT-5.4 mini",
874
+ provider: "openrouter",
875
+ contextWindow: 4e5,
876
+ pricing: usd(0.075, 0.75, 4.5),
877
+ supportsVision: true,
878
+ clientType: "openai-responses",
879
+ baseUrl: OPENROUTER_BASE_URL
880
+ },
881
+ {
882
+ modelId: "openai/gpt-5.4-nano",
883
+ displayName: "GPT-5.4 nano",
884
+ provider: "openrouter",
885
+ contextWindow: 4e5,
886
+ pricing: usd(0.02, 0.2, 1.25),
887
+ supportsVision: true,
888
+ clientType: "openai-responses",
889
+ baseUrl: OPENROUTER_BASE_URL
890
+ },
891
+ {
892
+ // No published cache discount, as with gpt-5.5-pro above.
893
+ modelId: "openai/gpt-5.4-pro",
894
+ displayName: "GPT-5.4 Pro",
895
+ provider: "openrouter",
896
+ contextWindow: 105e4,
897
+ pricing: usd(30, 30, 180),
898
+ supportsVision: true,
899
+ clientType: "openai-responses",
900
+ baseUrl: OPENROUTER_BASE_URL
901
+ },
902
+ {
903
+ // OpenRouter's unified Free Models Router: each request is routed to a random free model
904
+ // currently on OpenRouter, filtered by the features the request needs (tool calling,
905
+ // structured outputs, ...). Routed targets vary, so the context window is a deliberately
906
+ // conservative figure rather than any single target's real window: it keeps the 75%
907
+ // compaction clamp meaningful (compaction fires at 96000) and reduces hard context-length
908
+ // 400s on small-window targets. supportsVision stays false deliberately: the harness must
909
+ // not send images to a router whose target may be text-only.
910
+ modelId: "openrouter/free",
911
+ displayName: "Free Models Router",
912
+ provider: "openrouter",
913
+ contextWindow: 128e3,
914
+ pricing: usd(0, 0, 0),
915
+ supportsVision: false,
916
+ clientType: "openai-responses",
917
+ baseUrl: OPENROUTER_BASE_URL
918
+ },
919
+ {
920
+ // Read 2026-09-16 from the models API: $0.214 input / $2.55 output with a published $0.15
921
+ // input_cache_read, a 1,000,000-token context window, and text, image and video input.
922
+ modelId: "qwen/qwen3.8-27b",
923
+ displayName: "Qwen 3.8 27B",
924
+ provider: "openrouter",
925
+ contextWindow: 1e6,
926
+ pricing: usd(0.15, 0.214, 2.55),
927
+ supportsVision: true,
928
+ clientType: "openai-responses",
929
+ baseUrl: OPENROUTER_BASE_URL
930
+ },
931
+ {
932
+ modelId: "qwen/qwen3.8-max",
933
+ displayName: "Qwen 3.8 Max",
934
+ provider: "openrouter",
935
+ contextWindow: 1e6,
936
+ pricing: usd(0.25, 2.5, 6),
937
+ supportsVision: true,
938
+ clientType: "openai-responses",
939
+ baseUrl: OPENROUTER_BASE_URL
940
+ },
941
+ {
942
+ modelId: "qwen/qwen3.6-35b-a3b",
943
+ displayName: "Qwen 3.6 35B A3B",
944
+ provider: "openrouter",
945
+ contextWindow: 262144,
946
+ pricing: usd(0.05, 0.14, 1),
947
+ supportsVision: true,
948
+ clientType: "openai-responses",
949
+ baseUrl: OPENROUTER_BASE_URL
950
+ },
951
+ {
952
+ // Recursive's Flint, listed 2026-10-21 (models API read 2026-10-23): free, 262,144 tokens,
953
+ // up to 235,929 output tokens, text input only, with reasoning and tool calls.
954
+ modelId: "recursive/flint-v1.0:free",
955
+ displayName: "Flint (free)",
956
+ provider: "openrouter",
957
+ contextWindow: 262144,
958
+ pricing: usd(0, 0, 0),
959
+ supportsVision: false,
960
+ clientType: "openai-responses",
961
+ baseUrl: OPENROUTER_BASE_URL
962
+ },
963
+ {
964
+ // StepFun's own endpoint is the only one: $1 input / $2.70 output with a published $0.05
965
+ // input_cache_read and no write premium, so cache_write carries the input price. 1,000,000
966
+ // window; text, image and video input.
967
+ modelId: "stepfun/step-5-preview",
968
+ displayName: "Step 5 Preview",
969
+ provider: "openrouter",
970
+ contextWindow: 1e6,
971
+ pricing: usd(0.05, 1, 2.7),
972
+ supportsVision: true,
973
+ clientType: "openai-responses",
974
+ baseUrl: OPENROUTER_BASE_URL
975
+ },
976
+ {
977
+ // No official separate cache price published: cache_read uses the standard input price.
978
+ modelId: "stepfun/step-3.7-flash",
979
+ displayName: "Step 3.7 Flash",
980
+ provider: "openrouter",
981
+ contextWindow: 256e3,
982
+ pricing: usd(0.04, 0.2, 1.15),
983
+ supportsVision: true,
984
+ clientType: "openai-responses",
985
+ baseUrl: OPENROUTER_BASE_URL
986
+ },
987
+ {
988
+ // Tencent's Hy4 preview, read 2026-08-28 from its OpenRouter page and the models API:
989
+ // $0.834 input / $2.501 output with a published $0.042 input_cache_read, a 1,048,576
990
+ // context window, and text-only modalities in and out. The same upstream model is sold
991
+ // in the TokenDance group at that gateway's own CNY rate; the two rows are priced by
992
+ // their sellers and are not copies of one another.
993
+ modelId: "tencent/hy4-preview",
994
+ displayName: "Hy4 preview",
995
+ provider: "openrouter",
996
+ contextWindow: 1048576,
997
+ pricing: usd(0.042, 0.834, 2.501),
998
+ supportsVision: false,
999
+ clientType: "openai-responses",
1000
+ baseUrl: OPENROUTER_BASE_URL
1001
+ },
1002
+ {
1003
+ modelId: "tencent/hy3",
1004
+ displayName: "Hy3",
1005
+ provider: "openrouter",
1006
+ contextWindow: 262144,
1007
+ pricing: usd(0.033, 0.132, 0.528),
1008
+ supportsVision: false,
1009
+ clientType: "openai-responses",
1010
+ baseUrl: OPENROUTER_BASE_URL
1011
+ },
1012
+ {
1013
+ // Thinking Machines Lab's Inkling (released 2026-07-14): multimodal (image + audio
1014
+ // input). Specs from its OpenRouter page; pricing from the models API (2026-08-07),
1015
+ // which publishes $1 input (the page shows $0.95) and a $0.17 cached-input price.
1016
+ modelId: "thinkingmachines/inkling",
1017
+ displayName: "Inkling",
1018
+ provider: "openrouter",
1019
+ contextWindow: 1e6,
1020
+ pricing: usd(0.17, 1, 4.05),
1021
+ supportsVision: true,
1022
+ clientType: "openai-responses",
1023
+ baseUrl: OPENROUTER_BASE_URL
1024
+ },
1025
+ {
1026
+ // Grok 4.7 keeps Grok 4.6's $2 input / $6 output / $0.50 cache hit and its 500,000 window,
1027
+ // with image input. The listing's `overrides` double every rate from 200,000 prompt tokens;
1028
+ // the base tier is recorded.
1029
+ modelId: "x-ai/grok-4.7",
1030
+ displayName: "Grok 4.7",
1031
+ provider: "openrouter",
1032
+ contextWindow: 5e5,
1033
+ pricing: usd(0.5, 2, 6),
1034
+ supportsVision: true,
1035
+ clientType: "openai-responses",
1036
+ baseUrl: OPENROUTER_BASE_URL
1037
+ },
1038
+ {
1039
+ // xAI's Grok 4.6 (OpenRouter listing dated 2026-08-12): same $2/$6 input/output rates as
1040
+ // Grok 4.5 with a raised $0.50 cache-hit price.
1041
+ modelId: "x-ai/grok-4.6",
1042
+ displayName: "Grok 4.6",
1043
+ provider: "openrouter",
1044
+ contextWindow: 5e5,
1045
+ pricing: usd(0.5, 2, 6),
1046
+ supportsVision: true,
1047
+ clientType: "openai-responses",
1048
+ baseUrl: OPENROUTER_BASE_URL
1049
+ },
1050
+ {
1051
+ modelId: "x-ai/grok-4.5",
1052
+ displayName: "Grok 4.5",
1053
+ provider: "openrouter",
1054
+ contextWindow: 5e5,
1055
+ pricing: usd(0.3, 2, 6),
1056
+ supportsVision: true,
1057
+ clientType: "openai-responses",
1058
+ baseUrl: OPENROUTER_BASE_URL
1059
+ },
1060
+ {
1061
+ // $0.14 input / $0.28 output with a published $0.0028 input_cache_read, the same rates as
1062
+ // MiMo-V2.5; text, image, video and audio input.
1063
+ modelId: "xiaomi/mimo-v2.6-flash",
1064
+ displayName: "MiMo-V2.6-Flash",
1065
+ provider: "openrouter",
1066
+ contextWindow: 1048576,
1067
+ pricing: usd(28e-4, 0.14, 0.28),
1068
+ supportsVision: true,
1069
+ clientType: "openai-responses",
1070
+ baseUrl: OPENROUTER_BASE_URL
1071
+ },
1072
+ {
1073
+ // $0.435 input / $0.87 output with a published $0.0036 input_cache_read (models API and
1074
+ // the per-model endpoints API, read 2026-10-10: Xiaomi's own endpoint, no discount — the
1075
+ // USD face of TokenDance's CNY 0.025 / 3 / 6); text, image, video and audio input.
1076
+ modelId: "xiaomi/mimo-v2.6-pro",
1077
+ displayName: "MiMo-V2.6-Pro",
1078
+ provider: "openrouter",
1079
+ contextWindow: 1048576,
1080
+ pricing: usd(36e-4, 0.435, 0.87),
1081
+ supportsVision: true,
1082
+ clientType: "openai-responses",
1083
+ baseUrl: OPENROUTER_BASE_URL
1084
+ },
1085
+ {
1086
+ modelId: "xiaomi/mimo-v2.5",
1087
+ displayName: "MiMo-V2.5",
1088
+ provider: "openrouter",
1089
+ contextWindow: 1048576,
1090
+ pricing: usd(28e-4, 0.14, 0.28),
1091
+ supportsVision: true,
1092
+ clientType: "openai-responses",
1093
+ baseUrl: OPENROUTER_BASE_URL
1094
+ },
1095
+ {
1096
+ // The gateway listing of the direct glm-5.3 row below; OpenRouter's single Z.AI endpoint
1097
+ // passes Z.AI's published price straight through (no discount), which is why the two
1098
+ // rows agree to the cent. Text-only, per the listing's modalities.
1099
+ modelId: "z-ai/glm-5.3",
1100
+ displayName: "GLM-5.3",
1101
+ provider: "openrouter",
1102
+ contextWindow: 1048576,
1103
+ pricing: usd(0.26, 1.4, 4.4),
1104
+ supportsVision: false,
1105
+ clientType: "openai-responses",
1106
+ baseUrl: OPENROUTER_BASE_URL
1107
+ },
1108
+ {
1109
+ // The gateway listing of the direct glm-5.3-flash row below. Stored at the rate OpenRouter's
1110
+ // default endpoint bills: DeepInfra (fp4), running `discount: 0.5` on the 0.03 / 0.15 / 0.5
1111
+ // list (endpoints API, re-read 2026-09-16) — restore the list rates when that endpoint's
1112
+ // promotion ends. Z.AI's own 50% promotion is a different one: it ended at 2026-09-09
1113
+ // 16:00 UTC, and the Z.AI endpoint on OpenRouter bills the list price since. The listing
1114
+ // takes text, images and video, and the generic Responses client it pins carries image
1115
+ // parts through.
1116
+ modelId: "z-ai/glm-5.3-flash",
1117
+ displayName: "GLM-5.3 Flash",
1118
+ provider: "openrouter",
1119
+ contextWindow: 1048576,
1120
+ pricing: usd(0.015, 0.075, 0.25),
1121
+ supportsVision: true,
1122
+ clientType: "openai-responses",
1123
+ baseUrl: OPENROUTER_BASE_URL
1124
+ },
1125
+ {
1126
+ modelId: "z-ai/glm-5.2",
1127
+ displayName: "GLM-5.2",
1128
+ provider: "openrouter",
1129
+ contextWindow: 1e6,
1130
+ pricing: usd(0.1261, 0.679, 2.134),
1131
+ supportsVision: false,
1132
+ clientType: "openai-responses",
1133
+ baseUrl: OPENROUTER_BASE_URL
1134
+ },
1135
+ // -- Fireworks AI (gateway, standard serverless USD pricing: cached input / uncached
1136
+ // input / output from each model's page; API ids use the accounts/fireworks/models/<slug>
1137
+ // form, where Fireworks spells a version's dot as `p`: deepseek-v4p1-flash, glm-5p3). The
1138
+ // DeepSeek V4.1 Flash, DeepSeek V4 Pro 0813, GLM-5.3, GLM-5.3 Flash and Qwen 3.8 Max rows
1139
+ // were added 2026-09-16 from their fireworks.ai/models pages. Fireworks publishes no context
1140
+ // length for qwen3p8-max, so that row records the vendor's 1M window, as the other
1141
+ // qwen3.8-max rows do. --
1142
+ {
1143
+ // Fireworks' listing of the model DeepSeek serves directly as `deepseek-flash`: 1,048,576
1144
+ // context, image input, and the single serverless price its page lists, so no schedule.
1145
+ modelId: "accounts/fireworks/models/deepseek-v4p1-flash",
1146
+ displayName: "DeepSeek V4.1 Flash",
1147
+ provider: "fireworks",
1148
+ contextWindow: 1048576,
1149
+ pricing: usd(7e-3, 0.22, 0.66),
1150
+ supportsVision: true,
1151
+ clientType: "openai-chat",
1152
+ baseUrl: FIREWORKS_BASE_URL
1153
+ },
1154
+ {
1155
+ modelId: "accounts/fireworks/models/deepseek-v4-flash-0731",
1156
+ displayName: "DeepSeek V4 Flash 0731",
1157
+ provider: "fireworks",
1158
+ contextWindow: 1e6,
1159
+ pricing: usd(0.028, 0.14, 0.28),
1160
+ supportsVision: false,
1161
+ clientType: "openai-chat",
1162
+ baseUrl: FIREWORKS_BASE_URL
1163
+ },
1164
+ {
1165
+ modelId: "accounts/fireworks/models/deepseek-v4-flash",
1166
+ displayName: "DeepSeek V4 Flash",
1167
+ provider: "fireworks",
1168
+ contextWindow: 1e6,
1169
+ pricing: usd(0.03, 0.14, 0.28),
1170
+ supportsVision: false,
1171
+ clientType: "openai-chat",
1172
+ baseUrl: FIREWORKS_BASE_URL
1173
+ },
1174
+ {
1175
+ modelId: "accounts/fireworks/models/deepseek-v4-pro-0813",
1176
+ displayName: "DeepSeek V4 Pro 0813",
1177
+ provider: "fireworks",
1178
+ contextWindow: 1048576,
1179
+ pricing: usd(0.044, 1.32, 3.96),
1180
+ supportsVision: false,
1181
+ clientType: "openai-chat",
1182
+ baseUrl: FIREWORKS_BASE_URL
1183
+ },
1184
+ {
1185
+ modelId: "accounts/fireworks/models/deepseek-v4-pro",
1186
+ displayName: "DeepSeek V4 Pro",
1187
+ provider: "fireworks",
1188
+ contextWindow: 1e6,
1189
+ pricing: usd(0.15, 1.74, 3.48),
1190
+ supportsVision: false,
1191
+ clientType: "openai-chat",
1192
+ baseUrl: FIREWORKS_BASE_URL
1193
+ },
1194
+ {
1195
+ modelId: "accounts/fireworks/models/glm-5p3",
1196
+ displayName: "GLM-5.3",
1197
+ provider: "fireworks",
1198
+ contextWindow: 1048576,
1199
+ pricing: usd(0.26, 1.4, 4.4),
1200
+ supportsVision: false,
1201
+ clientType: "openai-chat",
1202
+ baseUrl: FIREWORKS_BASE_URL
1203
+ },
1204
+ {
1205
+ // Natively multimodal like every other GLM-5.3 Flash row, and this group's generic
1206
+ // openai-chat client forwards image_url parts, so image input works on this path.
1207
+ modelId: "accounts/fireworks/models/glm-5p3-flash",
1208
+ displayName: "GLM-5.3 Flash",
1209
+ provider: "fireworks",
1210
+ contextWindow: 1048576,
1211
+ pricing: usd(0.03, 0.15, 0.5),
1212
+ supportsVision: true,
1213
+ clientType: "openai-chat",
1214
+ baseUrl: FIREWORKS_BASE_URL
1215
+ },
1216
+ {
1217
+ modelId: "accounts/fireworks/models/glm-5p2",
1218
+ displayName: "GLM-5.2",
1219
+ provider: "fireworks",
1220
+ contextWindow: 1e6,
1221
+ pricing: usd(0.14, 1.4, 4.4),
1222
+ supportsVision: false,
1223
+ clientType: "openai-chat",
1224
+ baseUrl: FIREWORKS_BASE_URL
1225
+ },
1226
+ {
1227
+ // Thinking Machines Lab's Inkling (released 2026-07-14): multimodal (image + audio
1228
+ // input); specs and serverless pricing from its Fireworks model page (2026-08-06).
1229
+ modelId: "accounts/fireworks/models/inkling",
1230
+ displayName: "Inkling",
1231
+ provider: "fireworks",
1232
+ contextWindow: 1e6,
1233
+ pricing: usd(0.17, 1, 4.05),
1234
+ supportsVision: true,
1235
+ clientType: "openai-chat",
1236
+ baseUrl: FIREWORKS_BASE_URL
1237
+ },
1238
+ {
1239
+ modelId: "accounts/fireworks/models/kimi-k3",
1240
+ displayName: "Kimi K3",
1241
+ provider: "fireworks",
1242
+ contextWindow: 1e6,
1243
+ pricing: usd(0.3, 3, 15),
1244
+ supportsVision: true,
1245
+ clientType: "openai-chat",
1246
+ baseUrl: FIREWORKS_BASE_URL
1247
+ },
1248
+ {
1249
+ modelId: "accounts/fireworks/models/kimi-k2p7-code",
1250
+ displayName: "Kimi K2.7 Code",
1251
+ provider: "fireworks",
1252
+ contextWindow: 262144,
1253
+ pricing: usd(0.19, 0.95, 4),
1254
+ supportsVision: true,
1255
+ clientType: "openai-chat",
1256
+ baseUrl: FIREWORKS_BASE_URL
1257
+ },
1258
+ {
1259
+ modelId: "accounts/fireworks/models/minimax-m3",
1260
+ displayName: "MiniMax M3",
1261
+ provider: "fireworks",
1262
+ contextWindow: 524288,
1263
+ pricing: usd(0.06, 0.3, 1.2),
1264
+ supportsVision: true,
1265
+ clientType: "openai-chat",
1266
+ baseUrl: FIREWORKS_BASE_URL
1267
+ },
1268
+ {
1269
+ modelId: "accounts/fireworks/models/qwen3p8-max",
1270
+ displayName: "Qwen 3.8 Max",
1271
+ provider: "fireworks",
1272
+ contextWindow: 1e6,
1273
+ pricing: usd(0.25, 2, 6),
1274
+ supportsVision: true,
1275
+ clientType: "openai-chat",
1276
+ baseUrl: FIREWORKS_BASE_URL
1277
+ },
1278
+ // -- SiliconFlow (gateway, official CNY pricing: cache hit / input / output) --
1279
+ {
1280
+ // CNY 1 input / 4 output / 0.02 cache hit over 1,048,576 tokens, image input (MMSP 0.5.5's
1281
+ // registry, SiliconFlow's price list).
1282
+ modelId: "deepseek-ai/DeepSeek-V4.1-Flash",
1283
+ displayName: "DeepSeek V4.1 Flash",
1284
+ provider: "siliconflow",
1285
+ contextWindow: 1048576,
1286
+ pricing: cny(0.02, 1, 4),
1287
+ supportsVision: true,
1288
+ clientType: "openai-chat",
1289
+ baseUrl: SILICONFLOW_BASE_URL
1290
+ },
1291
+ {
1292
+ // SiliconFlow repriced it to CNY 1.5 / 4.5 / 0.15 (MMSP 0.5.5's registry).
1293
+ modelId: "deepseek-ai/DeepSeek-V4-Flash",
1294
+ displayName: "DeepSeek V4 Flash",
1295
+ provider: "siliconflow",
1296
+ contextWindow: 1048576,
1297
+ pricing: cny(0.15, 1.5, 4.5),
1298
+ supportsVision: false,
1299
+ clientType: "openai-chat",
1300
+ baseUrl: SILICONFLOW_BASE_URL
1301
+ },
1302
+ {
1303
+ modelId: "deepseek-ai/DeepSeek-V4-Pro",
1304
+ displayName: "DeepSeek V4 Pro",
1305
+ provider: "siliconflow",
1306
+ contextWindow: 1048576,
1307
+ pricing: cny(1, 12, 24),
1308
+ supportsVision: false,
1309
+ clientType: "openai-chat",
1310
+ baseUrl: SILICONFLOW_BASE_URL
1311
+ },
1312
+ {
1313
+ modelId: "meituan-longcat/LongCat-2.0",
1314
+ displayName: "LongCat 2.0",
1315
+ provider: "siliconflow",
1316
+ contextWindow: 1048576,
1317
+ pricing: cny(0.1, 5, 20),
1318
+ supportsVision: false,
1319
+ clientType: "openai-chat",
1320
+ baseUrl: SILICONFLOW_BASE_URL
1321
+ },
1322
+ {
1323
+ modelId: "moonshotai/Kimi-K2.7-Code",
1324
+ displayName: "Kimi K2.7 Code",
1325
+ provider: "siliconflow",
1326
+ contextWindow: 262144,
1327
+ pricing: cny(1.3, 6.5, 27),
1328
+ supportsVision: true,
1329
+ clientType: "openai-chat",
1330
+ baseUrl: SILICONFLOW_BASE_URL
1331
+ },
1332
+ // The Pro/ and Qwen/ entries below were unpriced until 2026-08-03 (SiliconFlow's price
1333
+ // list sits behind an authenticated console); prices below are its official CNY list
1334
+ // prices.
1335
+ {
1336
+ modelId: "Pro/moonshotai/Kimi-K2.6",
1337
+ displayName: "Kimi K2.6",
1338
+ provider: "siliconflow",
1339
+ contextWindow: 262144,
1340
+ pricing: cny(1.1, 6.5, 27),
1341
+ supportsVision: true,
1342
+ clientType: "openai-chat",
1343
+ baseUrl: SILICONFLOW_BASE_URL
1344
+ },
1345
+ {
1346
+ // No cache-hit price on the list, so cache_read carries the input price.
1347
+ modelId: "Qwen/Qwen3.6-35B-A3B",
1348
+ displayName: "Qwen 3.6 35B A3B",
1349
+ provider: "siliconflow",
1350
+ contextWindow: 262144,
1351
+ pricing: cny(1.8, 1.8, 10.8),
1352
+ supportsVision: true,
1353
+ clientType: "openai-chat",
1354
+ baseUrl: SILICONFLOW_BASE_URL
1355
+ },
1356
+ {
1357
+ // Added 2026-09-16, both ids confirmed in SiliconFlow's /v1/models listing. Hy4 preview is
1358
+ // text only at CNY 6 input / 18 output / 0.3 cache hit, the list price as quoted again on
1359
+ // 2026-10-10; siliconflow.cn/pricing shows the same input and output figures and no cache
1360
+ // price. Its window is the 1,048,576 tokens that page now publishes for it (the row had
1361
+ // borrowed the TokenDance row's 1,024,000). GLM-5.3 below is text only at 8 / 28 / 2, with
1362
+ // the same 1M window as zai-org/GLM-5.2.
1363
+ modelId: "tencent/Hy4-preview",
1364
+ displayName: "Hy4 preview",
1365
+ provider: "siliconflow",
1366
+ contextWindow: 1048576,
1367
+ pricing: cny(0.3, 6, 18),
1368
+ supportsVision: false,
1369
+ clientType: "openai-chat",
1370
+ baseUrl: SILICONFLOW_BASE_URL
1371
+ },
1372
+ {
1373
+ modelId: "zai-org/GLM-5.3",
1374
+ displayName: "GLM-5.3",
1375
+ provider: "siliconflow",
1376
+ contextWindow: 1048576,
1377
+ pricing: cny(2, 8, 28),
1378
+ supportsVision: false,
1379
+ clientType: "openai-chat",
1380
+ baseUrl: SILICONFLOW_BASE_URL
1381
+ },
1382
+ {
1383
+ // Added 2026-10-10 at the list price quoted that day: CNY 0.23 cache hit / 0.8 input / 2.8
1384
+ // output, which is Z.AI's own CNY list for the model and what the TokenDance and Qwen
1385
+ // Pay-As-You-Go rows store. siliconflow.cn/pricing currently shows it at CNY 0, beside the
1386
+ // platform's free models; a free period is a rate no promotion field can hold, so the row
1387
+ // keeps the list price. The window is the 1,048,576 tokens that page publishes. Natively
1388
+ // multimodal (`vlm` there), and this group's openai-chat client forwards image_url parts.
1389
+ modelId: "zai-org/GLM-5.3-Flash",
1390
+ displayName: "GLM-5.3 Flash",
1391
+ provider: "siliconflow",
1392
+ contextWindow: 1048576,
1393
+ pricing: cny(0.23, 0.8, 2.8),
1394
+ supportsVision: true,
1395
+ clientType: "openai-chat",
1396
+ baseUrl: SILICONFLOW_BASE_URL
1397
+ },
1398
+ {
1399
+ modelId: "zai-org/GLM-5.2",
1400
+ displayName: "GLM-5.2",
1401
+ provider: "siliconflow",
1402
+ contextWindow: 1048576,
1403
+ pricing: cny(2, 8, 28),
1404
+ supportsVision: false,
1405
+ clientType: "openai-chat",
1406
+ baseUrl: SILICONFLOW_BASE_URL
1407
+ },
1408
+ // -- Atlas Cloud (gateway: OpenAI-compatible protocol, preset base URL). Read 2026-10-11 from
1409
+ // the public catalog API (GET https://api.atlascloud.ai/v1/models, no credential required):
1410
+ // the ids exactly as listed, context windows, output limits, input modalities, quantization
1411
+ // and prices. The API's `pricing` figures are USD per token; the pricing page
1412
+ // (https://www.atlascloud.ai/pricing/models) states the same rates in USD per million
1413
+ // tokens. The presets are DeepSeek and Qwen models the other gateway groups preset. For
1414
+ // DeepSeek they are the releases TokenDance presets instead of the bare V4 ids (the user's
1415
+ // call for TokenDance on 2026-10-10, made for this group on 2026-10-11), taken only where
1416
+ // Atlas Cloud serves them at fp8: V4.1 Flash and V4 Pro 0813. Its V4 Flash 0731 is served at
1417
+ // fp4, like the bare deepseek-v4-flash and deepseek-v4-pro, so none of the three is a preset.
1418
+ // Qwen 3.6 35B A3B is the one the SiliconFlow and OpenRouter groups preset. Rows run newest
1419
+ // release first within a series (V4.1 before V4). Neither source publishes a cache-write
1420
+ // price for these rows, so cache_write carries the input price, as with the TokenDance and
1421
+ // Qwen gateways below. Atlas Cloud bills both DeepSeek rows at one fixed rate
1422
+ // (`pricing_mode` fixed, no time-based overrides), so neither declares DeepSeek's off-peak
1423
+ // schedule. The DeepSeek rows have a 393,216-token output limit; Qwen 3.6 35B A3B, which
1424
+ // takes image and video input, has 65,536.
1425
+ {
1426
+ // Image input, as the listing says (`text`, `image`).
1427
+ modelId: "deepseek-ai/deepseek-v4.1-flash",
1428
+ displayName: "DeepSeek V4.1 Flash",
1429
+ provider: "atlascloud",
1430
+ contextWindow: 1048576,
1431
+ pricing: usd(0.03, 0.3, 1.2),
1432
+ supportsVision: true,
1433
+ clientType: "openai-chat",
1434
+ baseUrl: ATLASCLOUD_BASE_URL
1435
+ },
1436
+ {
1437
+ modelId: "deepseek-ai/deepseek-v4-pro-0813",
1438
+ displayName: "DeepSeek V4 Pro 0813",
1439
+ provider: "atlascloud",
1440
+ contextWindow: 1048576,
1441
+ pricing: usd(0.132, 1.32, 3.96),
1442
+ supportsVision: false,
1443
+ clientType: "openai-chat",
1444
+ baseUrl: ATLASCLOUD_BASE_URL
1445
+ },
1446
+ {
1447
+ // The API answers the rate billed today, USD 0.186 input / 1.11375 output, which the
1448
+ // pricing page shows as a 25% model discount on a 0.248 / 1.485 list price. The row stores
1449
+ // that list price and declares the promotion in `discount`, as every promoted row does.
1450
+ // No cache-hit price is published (the API repeats the input price), so cache_read carries
1451
+ // the input price too.
1452
+ modelId: "qwen/qwen3.6-35b-a3b",
1453
+ displayName: "Qwen 3.6 35B A3B",
1454
+ provider: "atlascloud",
1455
+ contextWindow: 262144,
1456
+ pricing: usd(0.248, 0.248, 1.485),
1457
+ discount: 0.25,
1458
+ supportsVision: true,
1459
+ clientType: "openai-chat",
1460
+ baseUrl: ATLASCLOUD_BASE_URL
1461
+ },
1462
+ // -- TokenDance (gateway: OpenAI-compatible protocol, preset base URL). Re-read in full on
1463
+ // 2026-10-10 from two public APIs that need no credential: the gateway's catalog (GET
1464
+ // https://tokendance.space/gateway/v1/models — ids, context windows and supported protocols)
1465
+ // and the portal's model list (GET https://tokendance.space/portal/api/models/all — names,
1466
+ // input modalities and prices). Prices are the gateway's own CNY rates. The portal publishes
1467
+ // what a model bills as `pricing.items` and, while a promotion runs, its list price beside
1468
+ // that as `pricing.reference`. TokenDance charges no separate cache-write fee, so cache_write
1469
+ // carries the input price. The per-model pages (tokendance.space/models/<id>) render in the
1470
+ // browser from the same data.
1471
+ //
1472
+ // Discounts: every row here stores the official LIST price — the portal's `reference`, or
1473
+ // its `items` where no promotion runs — the convention of the two Qwen groups below, and a
1474
+ // promoted row declares its rate in `discount` rather than having its price rewritten: a
1475
+ // promotion that lapses is then one field to delete, with the rate to return to still on the
1476
+ // row. effectivePricing() applies it; a new Project stores the list price and the fraction as
1477
+ // a promotion beside it, which the cost center applies, so it charges what the gateway
1478
+ // charges. Eight rows carry a flat promotion as of 2026-10-10: ling-3.0-flash at 65% off, the
1479
+ // three Doubao Seed rows (seed-2.1-pro, seed-2.1-turbo, seed-evolving) at 50%, glm-5.2 at 20%,
1480
+ // and glm-5.3, glm-5.3-flash and qwen3.8-max at 10%; deepseek-v4.1-flash carries one on top
1481
+ // of its schedule (below). The gateway also sells the DeepSeek V4 preview releases under the
1482
+ // bare ids deepseek-v4-flash and deepseek-v4-pro ("… Preview"); they are deliberately not
1483
+ // presets (the user's call, 2026-10-10): the dated rows below are the releases that
1484
+ // superseded them.
1485
+ //
1486
+ // Three DeepSeek rows — deepseek-v4.1-flash, deepseek-v4-flash-0731 and deepseek-v4-pro-0813 —
1487
+ // are priced by time instead (`pricing.time_pricing`): a peak price on weekdays 09:00-12:00
1488
+ // and 14:00-18:00 Beijing time, DeepSeek's own windows, and half the peak list price at every
1489
+ // other hour. They store the peak list price and declare DEEPSEEK_OFF_PEAK, as the direct
1490
+ // DeepSeek rows do; so does the retired deepseek-v4-flash-vision-exp row, which is no longer a
1491
+ // preset. On top of that schedule the gateway takes 20% off. On deepseek-v4.1-flash it does
1492
+ // so in both tiers, and the row declares it in `discount` beside its schedule (re-read
1493
+ // 2026-10-13). On the 0731 and 0813 rows it does so in the peak tier alone and bills
1494
+ // off-peak at exactly half the list; a declared discount would come off the off-peak tier
1495
+ // too, so theirs is not recorded, and the cost center prices their peak hours 25% above what
1496
+ // the gateway bills. The rest of the group carries neither, so list price and billed rate
1497
+ // coincide.
1498
+ //
1499
+ // A running promotion usually also shows in a model's `description`, which opens with a
1500
+ // bracketed 限时 ("limited-time") tag. The tag is neither exhaustive nor authoritative on the
1501
+ // rate: kimi-k3's still announces an offer that ended 2026-09-30, and the two Seed 2.1 rows'
1502
+ // say 20% while their prices are at 50% off. The rows follow the prices.
1503
+ //
1504
+ // Display names follow the catalog's spelling of a model family where it has one (GLM-5.3,
1505
+ // Qwen 3.8 Max, MiMo-V2.5), and otherwise the portal's name without its "Vendor: " prefix
1506
+ // (Seed-2.1-Pro, Ling-3.1-flash, Step 5 Preview). Rows are in plain dictionary order by id. --
1507
+ {
1508
+ // Text only, 1,048,576 window. Priced by time (see the block comment): a CNY 3 input / 9
1509
+ // output / 0.1 cache hit list, billed at 2.4 / 7.2 / 0.08 in the peak windows and at half
1510
+ // the list, 1.5 / 4.5 / 0.05, at every other hour. It had been quoted on 2026-09-16 as a
1511
+ // flat CNY 1.5 / 4.5 / 0.15 list at 10% off.
1512
+ modelId: "deepseek-v4-flash-0731",
1513
+ displayName: "DeepSeek V4 Flash 0731",
1514
+ provider: "tokendance",
1515
+ contextWindow: 1048576,
1516
+ pricing: cny(0.1, 3, 9),
1517
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
1518
+ supportsVision: false,
1519
+ clientType: "openai-chat",
1520
+ baseUrl: TOKENDANCE_BASE_URL
1521
+ },
1522
+ {
1523
+ // Retired from TokenDance's line-up 2026-09-16 (see ModelCatalogEntry.retired). It was sold
1524
+ // on DeepSeek's own peak/off-peak schedule at the peak tier CNY 0.04 / 2 / 8, the price a
1525
+ // sync keeps on the Projects still carrying it.
1526
+ modelId: "deepseek-v4-flash-vision-exp",
1527
+ displayName: "DeepSeek V4 Flash Vision Exp",
1528
+ provider: "tokendance",
1529
+ contextWindow: 1e6,
1530
+ pricing: cny(0.04, 2, 8),
1531
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
1532
+ supportsVision: true,
1533
+ clientType: "openai-chat",
1534
+ baseUrl: TOKENDANCE_BASE_URL,
1535
+ retired: true
1536
+ },
1537
+ {
1538
+ // Text only, 1,000,000 window. Priced by time like the 0731 row: a CNY 9 input / 27 output
1539
+ // / 0.3 cache hit list, DeepSeek's own peak price for V4 Pro 0813, billed at 7.2 / 21.6 /
1540
+ // 0.24 in the peak windows and at half the list, 4.5 / 13.5 / 0.15, at every other hour. It
1541
+ // had been quoted on 2026-09-16 as a flat CNY 4.5 / 13.5 / 0.45 list at 10% off.
1542
+ modelId: "deepseek-v4-pro-0813",
1543
+ displayName: "DeepSeek V4 Pro 0813",
1544
+ provider: "tokendance",
1545
+ contextWindow: 1e6,
1546
+ pricing: cny(0.3, 9, 27),
1547
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
1548
+ supportsVision: false,
1549
+ clientType: "openai-chat",
1550
+ baseUrl: TOKENDANCE_BASE_URL
1551
+ },
1552
+ {
1553
+ // Listed 2026-09-10; the dotted id is the seller's spelling of the model DeepSeek serves
1554
+ // directly as `deepseek-flash`. 1M context and native multimodality. Its list follows the
1555
+ // vendor's own schedule: the peak tier CNY 0.04 / 2 / 8, the direct row's figures, and half
1556
+ // that outside Beijing weekday 09:00-12:00 and 14:00-18:00. The row stores the peak tier
1557
+ // and declares DEEPSEEK_OFF_PEAK. The gateway also takes 20% off both tiers, declared in
1558
+ // `discount`: it bills 0.032 / 1.6 / 6.4 at peak and 0.016 / 0.8 / 3.2 off-peak (see the
1559
+ // block comment). Unlike the direct row this one needs no DeepSeek-specific pin — it is
1560
+ // reached through this group's generic openai-chat client, which forwards image_url parts.
1561
+ modelId: "deepseek-v4.1-flash",
1562
+ displayName: "DeepSeek V4.1 Flash",
1563
+ provider: "tokendance",
1564
+ contextWindow: 1e6,
1565
+ pricing: cny(0.04, 2, 8),
1566
+ discount: 0.2,
1567
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
1568
+ supportsVision: true,
1569
+ clientType: "openai-chat",
1570
+ baseUrl: TOKENDANCE_BASE_URL
1571
+ },
1572
+ {
1573
+ // The 1017 snapshot, priced exactly as the row above in the public catalog (re-read
1574
+ // 2026-10-23): the same peak tier, schedule and 20% promotion.
1575
+ modelId: "deepseek-v4.1-flash-1017",
1576
+ displayName: "DeepSeek V4.1 Flash 1017",
1577
+ provider: "tokendance",
1578
+ contextWindow: 1e6,
1579
+ pricing: cny(0.04, 2, 8),
1580
+ discount: 0.2,
1581
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
1582
+ supportsVision: true,
1583
+ clientType: "openai-chat",
1584
+ baseUrl: TOKENDANCE_BASE_URL
1585
+ },
1586
+ {
1587
+ // Dots Studio's (rednote / Xiaohongshu) Dots3-Note Preview: an open-weight MoE, 280B total
1588
+ // and 16B active, the lightest of the Dots 3 family. TokenDance lists it as "Dots3-Note
1589
+ // Preview(Free)": the words and the tag are kept as the seller spells them, as the
1590
+ // OpenRouter `(free)` rows keep theirs, but the full-width parentheses are the typesetting
1591
+ // of the seller's Chinese listing rather than part of the name, and a catalog name shows
1592
+ // untranslated in every UI language — so it takes the ASCII " (" of every other
1593
+ // parenthesised row, which reads right in both. The price is a
1594
+ // genuine CNY 0 on every bucket, the same treatment as the OpenRouter `:free` rows, so
1595
+ // costs compute to 0 and the free badge shows — over a 512,000-token context window, with
1596
+ // openai:chat-completions and anthropic:messages as its supported_protocols (this group's
1597
+ // openai-chat pin is a convention here, not the only shape the id serves). The gateway's
1598
+ // own listing describes it as covering multimodal understanding, which is what the
1599
+ // vision flag records; no image request was sent to it. Read 2026-09-15 from the
1600
+ // gateway's /models listing and tokendance.space/models/dots-3-note-preview, and unchanged
1601
+ // on 2026-10-10.
1602
+ modelId: "dots-3-note-preview",
1603
+ displayName: "Dots3-Note Preview (Free)",
1604
+ provider: "tokendance",
1605
+ contextWindow: 512e3,
1606
+ pricing: cny(0, 0, 0),
1607
+ supportsVision: true,
1608
+ clientType: "openai-chat",
1609
+ baseUrl: TOKENDANCE_BASE_URL
1610
+ },
1611
+ {
1612
+ // Text only, 1,000,000 window. 20% off a CNY 8 input / 28 output / 2 cache hit list, the
1613
+ // same list as glm-5.3, so the gateway bills 6.4 / 22.4 / 1.6.
1614
+ modelId: "glm-5.2",
1615
+ displayName: "GLM-5.2",
1616
+ provider: "tokendance",
1617
+ contextWindow: 1e6,
1618
+ pricing: cny(2, 8, 28),
1619
+ discount: 0.2,
1620
+ supportsVision: false,
1621
+ clientType: "openai-chat",
1622
+ baseUrl: TOKENDANCE_BASE_URL
1623
+ },
1624
+ {
1625
+ modelId: "glm-5.3",
1626
+ displayName: "GLM-5.3",
1627
+ provider: "tokendance",
1628
+ contextWindow: 1e6,
1629
+ pricing: cny(2, 8, 28),
1630
+ discount: 0.1,
1631
+ supportsVision: false,
1632
+ clientType: "openai-chat",
1633
+ baseUrl: TOKENDANCE_BASE_URL
1634
+ },
1635
+ {
1636
+ // Natively multimodal per TokenDance's catalog entry, and this group's generic
1637
+ // openai-chat client forwards image_url parts, so image input works on this path. Its
1638
+ // supported_protocols are openai:chat-completions and anthropic:messages.
1639
+ //
1640
+ // The 50% promotion this row used to carry ran through 2026-09-09 24:00 (the catalog
1641
+ // API's own description said so) and has been replaced by 10% off; the list price is
1642
+ // unchanged, only the `discount` fraction moved.
1643
+ modelId: "glm-5.3-flash",
1644
+ displayName: "GLM-5.3 Flash",
1645
+ provider: "tokendance",
1646
+ contextWindow: 1e6,
1647
+ pricing: cny(0.23, 0.8, 2.8),
1648
+ discount: 0.1,
1649
+ supportsVision: true,
1650
+ clientType: "openai-chat",
1651
+ baseUrl: TOKENDANCE_BASE_URL
1652
+ },
1653
+ {
1654
+ // A faster GLM-5.3 Flash (up to 200 tokens/s, per its listing), natively multimodal like
1655
+ // it: text, image and video input, which this group's openai-chat client forwards.
1656
+ // 1,000,000 window; CNY 2 input / 7 output / 0.57 cache hit, undiscounted.
1657
+ modelId: "glm-5.3-flashx",
1658
+ displayName: "GLM-5.3 FlashX",
1659
+ provider: "tokendance",
1660
+ contextWindow: 1e6,
1661
+ pricing: cny(0.57, 2, 7),
1662
+ supportsVision: true,
1663
+ clientType: "openai-chat",
1664
+ baseUrl: TOKENDANCE_BASE_URL
1665
+ },
1666
+ {
1667
+ // The same upstream model as the OpenRouter `tencent/hy4-preview` row above, reached
1668
+ // through a second seller: each row records what its own seller charges, so the two must
1669
+ // not be made to agree (the qwen3.8-flash pair below states the same rule). TokenDance
1670
+ // sells it at CNY 6 input / 18 output / 0.3 cache hit, undiscounted, over a 1,024,000
1671
+ // context window — both figures its own, neither copied from the OpenRouter listing.
1672
+ //
1673
+ // Text-only: the catalog entry advertises no image modality, matching the OpenRouter
1674
+ // listing's text-in/text-out. Its supported_protocols are openai:chat-completions and
1675
+ // openai:responses, so the openai-chat pin is this group's convention rather than the
1676
+ // only shape the id serves.
1677
+ modelId: "hy4-preview",
1678
+ displayName: "Hy4 preview",
1679
+ provider: "tokendance",
1680
+ contextWindow: 1024e3,
1681
+ pricing: cny(0.3, 6, 18),
1682
+ supportsVision: false,
1683
+ clientType: "openai-chat",
1684
+ baseUrl: TOKENDANCE_BASE_URL
1685
+ },
1686
+ {
1687
+ // CNY 20 input / 100 output / 2 cache hit, Moonshot's own list, undiscounted as of
1688
+ // 2026-10-10. The 40% promotion this row carried (seller's quote 2026-09-16, when the cache
1689
+ // hit listed at 1.6) has ended; the description still opens with the tag of an offer that
1690
+ // ran to 2026-09-30. Its supported_protocols is openai:chat-completions alone, so the
1691
+ // openai-chat pin is the only shape this id serves.
1692
+ modelId: "kimi-k3",
1693
+ displayName: "Kimi K3",
1694
+ provider: "tokendance",
1695
+ contextWindow: 1048576,
1696
+ pricing: cny(2, 20, 100),
1697
+ supportsVision: true,
1698
+ clientType: "openai-chat",
1699
+ baseUrl: TOKENDANCE_BASE_URL
1700
+ },
1701
+ {
1702
+ // Moonshot's Kimi K3.1 Pro (public catalog, read 2026-10-24): text, image and video input
1703
+ // over a 1,000,000-token window, at CNY 13 input / 68 output / 1.3 cache hit, undiscounted
1704
+ // and the same on both protocols the portal prices it on. Its supported_protocols are
1705
+ // openai:chat-completions and anthropic:messages, so the openai-chat pin is the group's
1706
+ // convention rather than the only shape the id serves; image parts go through this group's
1707
+ // openai-chat client.
1708
+ modelId: "kimi-k3.1-pro",
1709
+ displayName: "Kimi K3.1 Pro",
1710
+ provider: "tokendance",
1711
+ contextWindow: 1e6,
1712
+ pricing: cny(1.3, 13, 68),
1713
+ supportsVision: true,
1714
+ clientType: "openai-chat",
1715
+ baseUrl: TOKENDANCE_BASE_URL
1716
+ },
1717
+ {
1718
+ // inclusionAI's Ling-3.0-flash: text only, with the 256,000-token window the listing gives
1719
+ // (the model's native length; its description says it extends to 1M). 65% off a CNY 0.4
1720
+ // input / 1.2 output / 0.08 cache hit list, so the gateway bills 0.14 / 0.42 / 0.028.
1721
+ modelId: "ling-3.0-flash",
1722
+ displayName: "Ling-3.0-flash",
1723
+ provider: "tokendance",
1724
+ contextWindow: 256e3,
1725
+ pricing: cny(0.08, 0.4, 1.2),
1726
+ discount: 0.65,
1727
+ supportsVision: false,
1728
+ clientType: "openai-chat",
1729
+ baseUrl: TOKENDANCE_BASE_URL
1730
+ },
1731
+ {
1732
+ // Text only, 1,000,000 window, at a CNY 0.4 input / 1.2 output / 0.08 cache hit list (the
1733
+ // portal's `reference`, re-read 2026-10-14). Listed 2026-09-30 with a free trial served at
1734
+ // 256K, which the portal bills at 0 until 2026-10-14 10:00. A free period is no `discount`,
1735
+ // which is a fraction below 1. The row records the list price and the full window the
1736
+ // model is sold at after the trial.
1737
+ modelId: "ling-3.1-flash",
1738
+ displayName: "Ling-3.1-flash",
1739
+ provider: "tokendance",
1740
+ contextWindow: 1e6,
1741
+ pricing: cny(0.08, 0.4, 1.2),
1742
+ supportsVision: false,
1743
+ clientType: "openai-chat",
1744
+ baseUrl: TOKENDANCE_BASE_URL
1745
+ },
1746
+ {
1747
+ // Xiaomi's MiMo-V2.6 line, the three rows alike: text, image, audio and video input (image
1748
+ // parts go through this group's openai-chat client), a 1,000,000 window, no promotion, and
1749
+ // openai:chat-completions, openai:responses and anthropic:messages as supported_protocols.
1750
+ // Flash at CNY 1 input / 2 output / 0.02 cache hit.
1751
+ modelId: "mimo-v2.6-flash",
1752
+ displayName: "MiMo-V2.6-Flash",
1753
+ provider: "tokendance",
1754
+ contextWindow: 1e6,
1755
+ pricing: cny(0.02, 1, 2),
1756
+ supportsVision: true,
1757
+ clientType: "openai-chat",
1758
+ baseUrl: TOKENDANCE_BASE_URL
1759
+ },
1760
+ {
1761
+ // Pro at CNY 3 input / 6 output / 0.025 cache hit.
1762
+ modelId: "mimo-v2.6-pro",
1763
+ displayName: "MiMo-V2.6-Pro",
1764
+ provider: "tokendance",
1765
+ contextWindow: 1e6,
1766
+ pricing: cny(0.025, 3, 6),
1767
+ supportsVision: true,
1768
+ clientType: "openai-chat",
1769
+ baseUrl: TOKENDANCE_BASE_URL
1770
+ },
1771
+ {
1772
+ // The Pro model served up to 20x faster, at ten times its price on every bucket: CNY 30
1773
+ // input / 60 output / 0.25 cache hit (OpenRouter lists the same rates in USD for
1774
+ // xiaomi/mimo-v2.6-pro-ultraspeed). The seller's id drops "pro"; its name keeps it.
1775
+ modelId: "mimo-v2.6-ultraspeed",
1776
+ displayName: "MiMo-V2.6-Pro-UltraSpeed",
1777
+ provider: "tokendance",
1778
+ contextWindow: 1e6,
1779
+ pricing: cny(0.25, 30, 60),
1780
+ supportsVision: true,
1781
+ clientType: "openai-chat",
1782
+ baseUrl: TOKENDANCE_BASE_URL
1783
+ },
1784
+ {
1785
+ // CNY 1 input / 4 output / 0.1 cache hit over a 1,000,000-token window, undiscounted (public
1786
+ // catalog, re-read 2026-10-23). Pinned to Anthropic Messages: the gateway's Chat Completions
1787
+ // stream for this model ends in a chunk without `delta`, which openai-chat cannot read
1788
+ // (MMSP 0.5.5's registry pins the same).
1789
+ modelId: "minimax-m3.1-flash",
1790
+ displayName: "MiniMax M3.1 Flash",
1791
+ provider: "tokendance",
1792
+ contextWindow: 1e6,
1793
+ pricing: cny(0.1, 1, 4),
1794
+ supportsVision: true,
1795
+ clientType: "ant-messages",
1796
+ baseUrl: TOKENDANCE_MESSAGES_BASE_URL
1797
+ },
1798
+ {
1799
+ // One model reached two ways, priced by whoever is selling it: this row carries the
1800
+ // gateway's own CNY 0.8 input / 2.7 output / 0.1 cache hit, and the qwen-pay-as-you-go row
1801
+ // carries Qwen's direct list price for the same id. The two figures agree since Qwen's
1802
+ // 2026-09-16 re-pricing (its page had read 1 / 3 / 0.1), but only because the two sellers
1803
+ // do: each row still follows its own seller.
1804
+ //
1805
+ // Its supported_protocols are openai:chat-completions, openai:responses and
1806
+ // anthropic:messages, so the openai-chat pin here is the group's convention rather than the
1807
+ // only shape the id serves. Natively multimodal per the catalog entry, and this group's
1808
+ // openai-chat client forwards image_url parts, so image input works on this path.
1809
+ //
1810
+ // Undiscounted, so its list price and its billed rate coincide — unlike the
1811
+ // qwen3.8-max row below, which is on 10% off.
1812
+ modelId: "qwen3.8-flash",
1813
+ displayName: "Qwen 3.8 Flash",
1814
+ provider: "tokendance",
1815
+ contextWindow: 1e6,
1816
+ pricing: cny(0.1, 0.8, 2.7),
1817
+ supportsVision: true,
1818
+ clientType: "openai-chat",
1819
+ baseUrl: TOKENDANCE_BASE_URL
1820
+ },
1821
+ {
1822
+ modelId: "qwen3.8-max",
1823
+ displayName: "Qwen 3.8 Max",
1824
+ provider: "tokendance",
1825
+ contextWindow: 1e6,
1826
+ pricing: cny(1.5, 12, 36),
1827
+ discount: 0.1,
1828
+ supportsVision: true,
1829
+ clientType: "openai-chat",
1830
+ baseUrl: TOKENDANCE_BASE_URL
1831
+ },
1832
+ {
1833
+ // The three Doubao Seed rows share this note. Priced 2026-09-02 from the seller's quoted
1834
+ // 50%-off rates, doubled back to the list price a row stores, and re-read 2026-10-10 from
1835
+ // the portal, whose prices still put all three at 50% off a list of CNY 6 / 30 / 1.2
1836
+ // (Pro, Evolving) and 3 / 15 / 0.6 (Turbo), input / output / cache hit — although the two
1837
+ // 2.1 rows' descriptions announce 20%. Context windows and protocols from the catalog API,
1838
+ // whose descriptions call the 2.1 models multimodal Coding/Agent models (this group's
1839
+ // openai-chat client forwards image_url parts, so image input works on this path).
1840
+ // seed-2.1-pro and seed-2.1-turbo also list openai:responses, so their openai-chat pin is
1841
+ // the group's convention rather than the only shape they serve; seed-evolving lists
1842
+ // chat-completions alone.
1843
+ //
1844
+ // Display names are the seller's own, as the catalog API spells them (re-read
1845
+ // 2026-10-10): Seed-2.1-Pro, Seed-2.1-Turbo, Seed-Evolving.
1846
+ modelId: "seed-2.1-pro",
1847
+ displayName: "Seed-2.1-Pro",
1848
+ provider: "tokendance",
1849
+ contextWindow: 256e3,
1850
+ pricing: cny(1.2, 6, 30),
1851
+ discount: 0.5,
1852
+ supportsVision: true,
1853
+ clientType: "openai-chat",
1854
+ baseUrl: TOKENDANCE_BASE_URL
1855
+ },
1856
+ {
1857
+ modelId: "seed-2.1-turbo",
1858
+ displayName: "Seed-2.1-Turbo",
1859
+ provider: "tokendance",
1860
+ contextWindow: 256e3,
1861
+ pricing: cny(0.6, 3, 15),
1862
+ discount: 0.5,
1863
+ supportsVision: true,
1864
+ clientType: "openai-chat",
1865
+ baseUrl: TOKENDANCE_BASE_URL
1866
+ },
1867
+ {
1868
+ // A rolling id: the catalog API describes it as the newest Seed Coding/Agent model
1869
+ // under one stable id — the same model as seed-2.1-pro at the time of reading — and
1870
+ // the seller prices it the same.
1871
+ modelId: "seed-evolving",
1872
+ displayName: "Seed-Evolving",
1873
+ provider: "tokendance",
1874
+ contextWindow: 256e3,
1875
+ pricing: cny(1.2, 6, 30),
1876
+ discount: 0.5,
1877
+ supportsVision: true,
1878
+ clientType: "openai-chat",
1879
+ baseUrl: TOKENDANCE_BASE_URL
1880
+ },
1881
+ {
1882
+ // StepFun's Step 5 Preview: text, image and video input, a 1,000,000 window, and CNY 7
1883
+ // input / 20 output / 0.35 cache hit, undiscounted.
1884
+ modelId: "step-5-preview",
1885
+ displayName: "Step 5 Preview",
1886
+ provider: "tokendance",
1887
+ contextWindow: 1e6,
1888
+ pricing: cny(0.35, 7, 20),
1889
+ supportsVision: true,
1890
+ clientType: "openai-chat",
1891
+ baseUrl: TOKENDANCE_BASE_URL
1892
+ },
1893
+ // -- Penguin Go. All models use MMSP HTTP; the SDK appends /stream to /api/v1.
1894
+ // List prices are preset; authorization and sync supply the platform's promotions.
1895
+ // The DeepSeek rows follow
1896
+ // DeepSeek's own lineup (re-read 2026-09-16): V4.1 Flash as `deepseek-flash` and V4 Pro 0813
1897
+ // as `deepseek-v4-pro`; the two retired V4 Flash ids, served from V4.1 Flash, are not resold.
1898
+ // Gemini 3.7 Flash is no longer preset (2026-10-10): Google retires the id and reroutes it to
1899
+ // 3.8 Flash.
1900
+ {
1901
+ // Owner-confirmed relay list prices (2026-10-14), matching Google's introductory
1902
+ // rates. Any further Penguin Go promotion comes from authorization or model sync.
1903
+ modelId: "gemini-4-argon",
1904
+ displayName: "Gemini 4 Argon",
1905
+ provider: PENGUIN_GO_PROVIDER_ID,
1906
+ contextWindow: 1048576,
1907
+ pricing: usd(0.1, 2, 10),
1908
+ supportsVision: true,
1909
+ clientType: "mmsp",
1910
+ baseUrl: PENGUIN_GO_BASE_URL
1911
+ },
1912
+ {
1913
+ modelId: "gemini-3.8-flash",
1914
+ displayName: "Gemini 3.8 Flash",
1915
+ provider: PENGUIN_GO_PROVIDER_ID,
1916
+ contextWindow: 1048576,
1917
+ pricing: usd(0.075, 0.75, 3.75),
1918
+ supportsVision: true,
1919
+ clientType: "mmsp",
1920
+ baseUrl: PENGUIN_GO_BASE_URL
1921
+ },
1922
+ {
1923
+ modelId: "gemini-3.6-flash",
1924
+ displayName: "Gemini 3.6 Flash",
1925
+ provider: PENGUIN_GO_PROVIDER_ID,
1926
+ contextWindow: 1048576,
1927
+ pricing: usd(0.075, 0.75, 3.75),
1928
+ supportsVision: true,
1929
+ clientType: "mmsp",
1930
+ baseUrl: PENGUIN_GO_BASE_URL
1931
+ },
1932
+ {
1933
+ modelId: "gemini-3.5-flash",
1934
+ displayName: "Gemini 3.5 Flash",
1935
+ provider: PENGUIN_GO_PROVIDER_ID,
1936
+ contextWindow: 1048576,
1937
+ pricing: usd(0.15, 1.5, 9),
1938
+ supportsVision: true,
1939
+ clientType: "mmsp",
1940
+ baseUrl: PENGUIN_GO_BASE_URL
1941
+ },
1942
+ {
1943
+ modelId: "gemini-3.5-flash-lite",
1944
+ displayName: "Gemini 3.5 Flash-Lite",
1945
+ provider: PENGUIN_GO_PROVIDER_ID,
1946
+ contextWindow: 1048576,
1947
+ pricing: usd(0.03, 0.3, 2.5),
1948
+ supportsVision: true,
1949
+ clientType: "mmsp",
1950
+ baseUrl: PENGUIN_GO_BASE_URL
1951
+ },
1952
+ {
1953
+ modelId: "gemini-3.1-flash-lite",
1954
+ displayName: "Gemini 3.1 Flash-Lite",
1955
+ provider: PENGUIN_GO_PROVIDER_ID,
1956
+ contextWindow: 1048576,
1957
+ pricing: usd(0.025, 0.25, 1.5),
1958
+ supportsVision: true,
1959
+ clientType: "mmsp",
1960
+ baseUrl: PENGUIN_GO_BASE_URL
1961
+ },
1962
+ {
1963
+ modelId: "gemini-3.1-pro-preview",
1964
+ displayName: "Gemini 3.1 Pro (Preview)",
1965
+ provider: PENGUIN_GO_PROVIDER_ID,
1966
+ contextWindow: 1048576,
1967
+ pricing: usd(0.2, 2, 12),
1968
+ supportsVision: true,
1969
+ clientType: "mmsp",
1970
+ baseUrl: PENGUIN_GO_BASE_URL
1971
+ },
1972
+ {
1973
+ modelId: "deepseek-flash",
1974
+ displayName: "DeepSeek V4.1 Flash",
1975
+ provider: PENGUIN_GO_PROVIDER_ID,
1976
+ contextWindow: 1e6,
1977
+ pricing: cny(0.04, 2, 8),
1978
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
1979
+ supportsVision: true,
1980
+ clientType: "mmsp",
1981
+ baseUrl: PENGUIN_GO_BASE_URL
1982
+ },
1983
+ {
1984
+ modelId: "deepseek-v4-pro",
1985
+ displayName: "DeepSeek V4 Pro 0813",
1986
+ provider: PENGUIN_GO_PROVIDER_ID,
1987
+ contextWindow: 1e6,
1988
+ pricing: cny(0.3, 9, 27),
1989
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
1990
+ supportsVision: false,
1991
+ clientType: "mmsp",
1992
+ baseUrl: PENGUIN_GO_BASE_URL
1993
+ },
1994
+ // -- OpenCode Go. Latest generation of each model tier from opencode.ai/v2/docs/console/go/
1995
+ // (2026-10-14); context and vision from OpenCode's models.dev registry. The Code, Pro,
1996
+ // Flash, Max and Plus tiers are independent: a newer Flash does not replace a Pro.
1997
+ // Generic clients pin the documented wire protocol. The /zen/go aliases remain live;
1998
+ // keeping them avoids changing existing group endpoints. Requests name their conversation
1999
+ // through the x-opencode-session header core's GenerativeModel attaches.
2000
+ // Prices measure subscription allowance consumed, not the monthly fee. Cache writes use
2001
+ // the input price when no write premium is published. GPT Luna (>272K), Haiku (>100K),
2002
+ // Grok (>200K) and Qwen Plus (>256K) store the base tier. DeepSeek stores its peak rates
2003
+ // and DEEPSEEK_OFF_PEAK schedule. Allowance multipliers are not price discounts.
2004
+ // Superseded rows remain retired for saved Projects and historical off-peak pricing;
2005
+ // removal follows ModelCatalogEntry.retired and the backward-compatibility changelog.
2006
+ {
2007
+ modelId: "cat-jam-free",
2008
+ displayName: "Cat Jam Free",
2009
+ provider: "opencode-go",
2010
+ contextWindow: 262144,
2011
+ pricing: usd(0, 0, 0),
2012
+ supportsVision: false,
2013
+ clientType: "openai-chat",
2014
+ baseUrl: OPENCODE_GO_BASE_URL
2015
+ },
2016
+ {
2017
+ modelId: "claude-haiku-5-5",
2018
+ displayName: "Claude Haiku 5.5",
2019
+ provider: "opencode-go",
2020
+ contextWindow: 1e6,
2021
+ pricing: usd(0.01, 0.125, 0.5),
2022
+ supportsVision: true,
2023
+ clientType: "ant-messages",
2024
+ baseUrl: OPENCODE_GO_MESSAGES_BASE_URL
2025
+ },
2026
+ {
2027
+ modelId: "deepseek-v4.1-flash",
2028
+ displayName: "DeepSeek V4.1 Flash",
2029
+ provider: "opencode-go",
2030
+ contextWindow: 1e6,
2031
+ pricing: usd(6e-3, 0.3, 1.2),
2032
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
2033
+ supportsVision: true,
2034
+ clientType: "openai-chat",
2035
+ baseUrl: OPENCODE_GO_BASE_URL
2036
+ },
2037
+ {
2038
+ modelId: "deepseek-v4-flash",
2039
+ displayName: "DeepSeek V4 Flash",
2040
+ provider: "opencode-go",
2041
+ contextWindow: 1e6,
2042
+ pricing: usd(6e-3, 0.3, 1.2),
2043
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
2044
+ supportsVision: false,
2045
+ retired: true,
2046
+ clientType: "openai-chat",
2047
+ baseUrl: OPENCODE_GO_BASE_URL
2048
+ },
2049
+ {
2050
+ modelId: "deepseek-v4-flash-vision-exp",
2051
+ displayName: "DeepSeek V4 Flash Vision Exp",
2052
+ provider: "opencode-go",
2053
+ contextWindow: 1e6,
2054
+ pricing: usd(6e-3, 0.3, 1.2),
2055
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
2056
+ supportsVision: true,
2057
+ retired: true,
2058
+ clientType: "openai-chat",
2059
+ baseUrl: OPENCODE_GO_BASE_URL
2060
+ },
2061
+ {
2062
+ modelId: "deepseek-v4-pro",
2063
+ displayName: "DeepSeek V4 Pro",
2064
+ provider: "opencode-go",
2065
+ contextWindow: 1e6,
2066
+ pricing: usd(0.044, 1.32, 3.96),
2067
+ offPeakDiscount: DEEPSEEK_OFF_PEAK,
2068
+ supportsVision: false,
2069
+ clientType: "openai-chat",
2070
+ baseUrl: OPENCODE_GO_BASE_URL
2071
+ },
2072
+ {
2073
+ modelId: "gemini-4-argon-contributor",
2074
+ displayName: "Gemini 4 Argon Contributor",
2075
+ provider: "opencode-go",
2076
+ contextWindow: 1048576,
2077
+ pricing: usd(0.2, 4, 20),
2078
+ supportsVision: true,
2079
+ clientType: "google-genai",
2080
+ baseUrl: OPENCODE_GO_GOOGLE_BASE_URL
2081
+ },
2082
+ {
2083
+ modelId: "glm-5.3",
2084
+ displayName: "GLM-5.3",
2085
+ provider: "opencode-go",
2086
+ contextWindow: 1e6,
2087
+ pricing: usd(0.26, 1.4, 4.4),
2088
+ supportsVision: false,
2089
+ clientType: "openai-chat",
2090
+ baseUrl: OPENCODE_GO_BASE_URL
2091
+ },
2092
+ {
2093
+ modelId: "glm-5.3-flash",
2094
+ displayName: "GLM-5.3 Flash",
2095
+ provider: "opencode-go",
2096
+ contextWindow: 1e6,
2097
+ pricing: usd(0.03, 0.15, 0.5),
2098
+ supportsVision: true,
2099
+ clientType: "openai-chat",
2100
+ baseUrl: OPENCODE_GO_BASE_URL
2101
+ },
2102
+ {
2103
+ modelId: "glm-5.2",
2104
+ displayName: "GLM-5.2",
2105
+ provider: "opencode-go",
2106
+ contextWindow: 1e6,
2107
+ pricing: usd(0.26, 1.4, 4.4),
2108
+ supportsVision: false,
2109
+ retired: true,
2110
+ clientType: "openai-chat",
2111
+ baseUrl: OPENCODE_GO_BASE_URL
2112
+ },
2113
+ {
2114
+ modelId: "glm-5.1",
2115
+ displayName: "GLM-5.1",
2116
+ provider: "opencode-go",
2117
+ contextWindow: 202752,
2118
+ pricing: usd(0.26, 1.4, 4.4),
2119
+ supportsVision: false,
2120
+ retired: true,
2121
+ clientType: "openai-chat",
2122
+ baseUrl: OPENCODE_GO_BASE_URL
2123
+ },
2124
+ {
2125
+ modelId: "gpt-6-luna",
2126
+ displayName: "GPT-6 Luna",
2127
+ provider: "opencode-go",
2128
+ contextWindow: 105e4,
2129
+ pricing: usd(0.01, 0.125, 0.5),
2130
+ supportsVision: true,
2131
+ clientType: "openai-responses",
2132
+ baseUrl: OPENCODE_GO_BASE_URL
2133
+ },
2134
+ {
2135
+ modelId: "gpt-5.6-luna",
2136
+ displayName: "GPT-5.6 Luna",
2137
+ provider: "opencode-go",
2138
+ contextWindow: 105e4,
2139
+ pricing: usd(0.02, 0.25, 1.2),
2140
+ supportsVision: true,
2141
+ retired: true,
2142
+ clientType: "openai-responses",
2143
+ baseUrl: OPENCODE_GO_BASE_URL
2144
+ },
2145
+ {
2146
+ modelId: "grok-4.7",
2147
+ displayName: "Grok 4.7",
2148
+ provider: "opencode-go",
2149
+ contextWindow: 5e5,
2150
+ pricing: usd(0.5, 2, 6),
2151
+ supportsVision: true,
2152
+ clientType: "openai-responses",
2153
+ baseUrl: OPENCODE_GO_BASE_URL
2154
+ },
2155
+ {
2156
+ modelId: "grok-4.6",
2157
+ displayName: "Grok 4.6",
2158
+ provider: "opencode-go",
2159
+ contextWindow: 5e5,
2160
+ pricing: usd(0.5, 2, 6),
2161
+ supportsVision: true,
2162
+ retired: true,
2163
+ clientType: "openai-responses",
2164
+ baseUrl: OPENCODE_GO_BASE_URL
2165
+ },
2166
+ {
2167
+ modelId: "hy4-preview",
2168
+ displayName: "Hy4 preview",
2169
+ provider: "opencode-go",
2170
+ contextWindow: 1024e3,
2171
+ pricing: usd(0.042, 0.834, 2.501),
2172
+ supportsVision: false,
2173
+ clientType: "openai-chat",
2174
+ baseUrl: OPENCODE_GO_BASE_URL
2175
+ },
2176
+ {
2177
+ // models.dev lists a 256,000-token context for Hy3 but caps its input at 192,000. Compaction
2178
+ // derives from this field, so it records the input cap: at 256,000 a Session would keep
2179
+ // sending prompts the upstream refuses until it compacted at ~254K.
2180
+ modelId: "hy3",
2181
+ displayName: "Hy3",
2182
+ provider: "opencode-go",
2183
+ contextWindow: 192e3,
2184
+ pricing: usd(0.035, 0.14, 0.58),
2185
+ supportsVision: false,
2186
+ retired: true,
2187
+ clientType: "openai-chat",
2188
+ baseUrl: OPENCODE_GO_BASE_URL
2189
+ },
2190
+ {
2191
+ modelId: "kimi-k3",
2192
+ displayName: "Kimi K3",
2193
+ provider: "opencode-go",
2194
+ contextWindow: 1048576,
2195
+ pricing: usd(0.3, 3, 15),
2196
+ supportsVision: true,
2197
+ clientType: "openai-chat",
2198
+ baseUrl: OPENCODE_GO_BASE_URL
2199
+ },
2200
+ {
2201
+ modelId: "kimi-k2.7-code",
2202
+ displayName: "Kimi K2.7 Code",
2203
+ provider: "opencode-go",
2204
+ contextWindow: 262144,
2205
+ pricing: usd(0.19, 0.95, 4),
2206
+ supportsVision: true,
2207
+ clientType: "openai-chat",
2208
+ baseUrl: OPENCODE_GO_BASE_URL
2209
+ },
2210
+ {
2211
+ modelId: "kimi-k2.6",
2212
+ displayName: "Kimi K2.6",
2213
+ provider: "opencode-go",
2214
+ contextWindow: 262144,
2215
+ pricing: usd(0.16, 0.95, 4),
2216
+ supportsVision: true,
2217
+ retired: true,
2218
+ clientType: "openai-chat",
2219
+ baseUrl: OPENCODE_GO_BASE_URL
2220
+ },
2221
+ {
2222
+ modelId: "longcat-2.5-preview-free",
2223
+ displayName: "LongCat 2.5 Preview Free",
2224
+ provider: "opencode-go",
2225
+ contextWindow: 1e6,
2226
+ pricing: usd(0, 0, 0),
2227
+ supportsVision: true,
2228
+ clientType: "openai-chat",
2229
+ baseUrl: OPENCODE_GO_BASE_URL
2230
+ },
2231
+ {
2232
+ modelId: "longcat-2.0",
2233
+ displayName: "LongCat 2.0",
2234
+ provider: "opencode-go",
2235
+ contextWindow: 1e6,
2236
+ pricing: usd(6e-3, 0.3, 1.2),
2237
+ supportsVision: false,
2238
+ retired: true,
2239
+ clientType: "openai-chat",
2240
+ baseUrl: OPENCODE_GO_BASE_URL
2241
+ },
2242
+ {
2243
+ modelId: "mimo-v2.6-flash",
2244
+ displayName: "MiMo-V2.6-Flash",
2245
+ provider: "opencode-go",
2246
+ contextWindow: 1048576,
2247
+ pricing: usd(28e-4, 0.14, 0.28),
2248
+ supportsVision: true,
2249
+ clientType: "openai-chat",
2250
+ baseUrl: OPENCODE_GO_BASE_URL
2251
+ },
2252
+ {
2253
+ modelId: "mimo-v2.6-pro",
2254
+ displayName: "MiMo-V2.6-Pro",
2255
+ provider: "opencode-go",
2256
+ contextWindow: 1048576,
2257
+ pricing: usd(3625e-6, 0.435, 0.87),
2258
+ supportsVision: true,
2259
+ clientType: "openai-chat",
2260
+ baseUrl: OPENCODE_GO_BASE_URL
2261
+ },
2262
+ {
2263
+ modelId: "mimo-v2.5",
2264
+ displayName: "MiMo-V2.5",
2265
+ provider: "opencode-go",
2266
+ contextWindow: 1e6,
2267
+ pricing: usd(28e-4, 0.14, 0.28),
2268
+ supportsVision: true,
2269
+ retired: true,
2270
+ clientType: "openai-chat",
2271
+ baseUrl: OPENCODE_GO_BASE_URL
2272
+ },
2273
+ {
2274
+ modelId: "mimo-v2.5-pro",
2275
+ displayName: "MiMo-V2.5-Pro",
2276
+ provider: "opencode-go",
2277
+ contextWindow: 1048576,
2278
+ pricing: usd(3625e-6, 0.435, 0.87),
2279
+ supportsVision: false,
2280
+ retired: true,
2281
+ clientType: "openai-chat",
2282
+ baseUrl: OPENCODE_GO_BASE_URL
2283
+ },
2284
+ {
2285
+ modelId: "minimax-m3",
2286
+ displayName: "MiniMax M3",
2287
+ provider: "opencode-go",
2288
+ contextWindow: 1e6,
2289
+ pricing: usd(0.06, 0.3, 1.2),
2290
+ supportsVision: true,
2291
+ clientType: "ant-messages",
2292
+ baseUrl: OPENCODE_GO_MESSAGES_BASE_URL
2293
+ },
2294
+ {
2295
+ modelId: "minimax-m2.7",
2296
+ displayName: "MiniMax M2.7",
2297
+ provider: "opencode-go",
2298
+ contextWindow: 204800,
2299
+ pricing: usd(0.06, 0.375, 1.2),
2300
+ supportsVision: false,
2301
+ retired: true,
2302
+ clientType: "ant-messages",
2303
+ baseUrl: OPENCODE_GO_MESSAGES_BASE_URL
2304
+ },
2305
+ {
2306
+ modelId: "muse-spark-1.3-contributor",
2307
+ displayName: "Muse Spark 1.3 Contributor",
2308
+ provider: "opencode-go",
2309
+ contextWindow: 1048576,
2310
+ pricing: usd(2e-3, 0.1, 0.2),
2311
+ supportsVision: true,
2312
+ clientType: "openai-responses",
2313
+ baseUrl: OPENCODE_GO_BASE_URL
2314
+ },
2315
+ {
2316
+ modelId: "muse-spark-1.2-contributor",
2317
+ displayName: "Muse Spark 1.2 Contributor",
2318
+ provider: "opencode-go",
2319
+ contextWindow: 1048576,
2320
+ pricing: usd(2e-3, 0.1, 0.2),
2321
+ supportsVision: true,
2322
+ retired: true,
2323
+ clientType: "openai-responses",
2324
+ baseUrl: OPENCODE_GO_BASE_URL
2325
+ },
2326
+ {
2327
+ modelId: "qwen3.8-flash",
2328
+ displayName: "Qwen 3.8 Flash",
2329
+ provider: "opencode-go",
2330
+ contextWindow: 1e6,
2331
+ pricing: usd(0.016, 0.2, 0.47),
2332
+ supportsVision: true,
2333
+ clientType: "ant-messages",
2334
+ baseUrl: OPENCODE_GO_MESSAGES_BASE_URL
2335
+ },
2336
+ {
2337
+ modelId: "qwen3.8-max",
2338
+ displayName: "Qwen 3.8 Max",
2339
+ provider: "opencode-go",
2340
+ contextWindow: 1e6,
2341
+ pricing: usd(0.25, 2.5, 6),
2342
+ supportsVision: true,
2343
+ clientType: "ant-messages",
2344
+ baseUrl: OPENCODE_GO_MESSAGES_BASE_URL
2345
+ },
2346
+ {
2347
+ modelId: "qwen3.7-max",
2348
+ displayName: "Qwen 3.7 Max",
2349
+ provider: "opencode-go",
2350
+ contextWindow: 1e6,
2351
+ pricing: usd(0.5, 3.125, 7.5),
2352
+ supportsVision: false,
2353
+ retired: true,
2354
+ clientType: "ant-messages",
2355
+ baseUrl: OPENCODE_GO_MESSAGES_BASE_URL
2356
+ },
2357
+ {
2358
+ modelId: "qwen3.7-plus",
2359
+ displayName: "Qwen 3.7 Plus",
2360
+ provider: "opencode-go",
2361
+ contextWindow: 1e6,
2362
+ pricing: usd(0.04, 0.5, 1.6),
2363
+ supportsVision: true,
2364
+ clientType: "ant-messages",
2365
+ baseUrl: OPENCODE_GO_MESSAGES_BASE_URL
2366
+ },
2367
+ {
2368
+ modelId: "qwen3.6-plus",
2369
+ displayName: "Qwen 3.6 Plus",
2370
+ provider: "opencode-go",
2371
+ contextWindow: 1e6,
2372
+ pricing: usd(0.05, 0.625, 3),
2373
+ supportsVision: true,
2374
+ retired: true,
2375
+ clientType: "ant-messages",
2376
+ baseUrl: OPENCODE_GO_MESSAGES_BASE_URL
2377
+ },
2378
+ {
2379
+ // The context spans 1M tokens, but models.dev caps input at 524,288; compaction uses input.
2380
+ modelId: "space-bunny",
2381
+ displayName: "Space Bunny",
2382
+ provider: "opencode-go",
2383
+ contextWindow: 524288,
2384
+ pricing: usd(0.03, 0.15, 0.6),
2385
+ supportsVision: true,
2386
+ clientType: "openai-chat",
2387
+ baseUrl: OPENCODE_GO_BASE_URL
2388
+ },
2389
+ {
2390
+ modelId: "step-5-preview-free",
2391
+ displayName: "Step 5 Preview Free",
2392
+ provider: "opencode-go",
2393
+ contextWindow: 1e6,
2394
+ pricing: usd(0, 0, 0),
2395
+ supportsVision: true,
2396
+ clientType: "openai-chat",
2397
+ baseUrl: OPENCODE_GO_BASE_URL
2398
+ },
2399
+ // -- Qwen Token Plan (subscription gateway; vision flags per the plan's supported-model
2400
+ // table, and for the rows added 2026-09-16 per their model pages' input modalities).
2401
+ // Pricing and context windows from each model's page at www.qianwenai.com/models/<id>
2402
+ // (official CNY list prices; limited-time promotions such as the 20%/50% off discounts are
2403
+ // not stored). Lineup updated 2026-09-16: deepseek-v4.1-flash, deepseek-v4-pro-0813,
2404
+ // glm-5.3 and qwen3.8-flash join; deepseek-v4-flash-0731, deepseek-v4-pro and glm-5.2
2405
+ // leave the plan.
2406
+ //
2407
+ // The two DeepSeek rows are priced by time of day: their pages list a peak and an off-peak
2408
+ // price, the off-peak one exactly half on every bucket and in force from 22:00 to 08:00
2409
+ // Beijing time every day. They store the PEAK price and declare QWEN_OFF_PEAK, the same
2410
+ // shape the DeepSeek rows take with DeepSeek's own schedule. --
2411
+ {
2412
+ // Peak CNY 2 input / 8 output / 0.2 cache hit; off-peak 1 / 4 / 0.1. Text and image input.
2413
+ modelId: "deepseek-v4.1-flash",
2414
+ displayName: "DeepSeek V4.1 Flash",
2415
+ provider: "qwen-token-plan",
2416
+ contextWindow: 1e6,
2417
+ pricing: cny(0.2, 2, 8),
2418
+ offPeakDiscount: QWEN_OFF_PEAK,
2419
+ supportsVision: true,
2420
+ clientType: "openai-chat",
2421
+ baseUrl: QWEN_TOKEN_PLAN_BASE_URL
2422
+ },
2423
+ {
2424
+ // Peak CNY 9 input / 27 output / 0.9 cache hit; off-peak 4.5 / 13.5 / 0.45. Text only.
2425
+ modelId: "deepseek-v4-pro-0813",
2426
+ displayName: "DeepSeek V4 Pro 0813",
2427
+ provider: "qwen-token-plan",
2428
+ contextWindow: 1e6,
2429
+ pricing: cny(0.9, 9, 27),
2430
+ offPeakDiscount: QWEN_OFF_PEAK,
2431
+ supportsVision: false,
2432
+ clientType: "openai-chat",
2433
+ baseUrl: QWEN_TOKEN_PLAN_BASE_URL
2434
+ },
2435
+ {
2436
+ modelId: "glm-5.3",
2437
+ displayName: "GLM-5.3",
2438
+ provider: "qwen-token-plan",
2439
+ contextWindow: 1048576,
2440
+ pricing: cny(2, 8, 28),
2441
+ supportsVision: false,
2442
+ clientType: "openai-chat",
2443
+ baseUrl: QWEN_TOKEN_PLAN_BASE_URL
2444
+ },
2445
+ {
2446
+ modelId: "qwen3.8-flash",
2447
+ displayName: "Qwen 3.8 Flash",
2448
+ provider: "qwen-token-plan",
2449
+ contextWindow: 1e6,
2450
+ pricing: cny(0.1, 0.8, 2.7),
2451
+ supportsVision: true,
2452
+ clientType: "openai-chat",
2453
+ baseUrl: QWEN_TOKEN_PLAN_BASE_URL
2454
+ },
2455
+ {
2456
+ modelId: "qwen3.8-max",
2457
+ displayName: "Qwen 3.8 Max",
2458
+ provider: "qwen-token-plan",
2459
+ contextWindow: 1e6,
2460
+ pricing: cny(1.5, 12, 36),
2461
+ supportsVision: true,
2462
+ clientType: "openai-chat",
2463
+ baseUrl: QWEN_TOKEN_PLAN_BASE_URL
2464
+ },
2465
+ {
2466
+ modelId: "qwen3.7-plus",
2467
+ displayName: "Qwen 3.7 Plus",
2468
+ provider: "qwen-token-plan",
2469
+ contextWindow: 1e6,
2470
+ pricing: cny(0.4, 2, 8),
2471
+ supportsVision: true,
2472
+ clientType: "openai-chat",
2473
+ baseUrl: QWEN_TOKEN_PLAN_BASE_URL
2474
+ },
2475
+ // -- Qwen Pay-As-You-Go (DashScope's OpenAI-compatible pay-per-token marketplace; official
2476
+ // CNY list prices and specs from each model's page at www.qianwenai.com/models/<id> —
2477
+ // resold third-party models keep their upstream ids exactly as the page lists them: kimi/
2478
+ // and ZHIPU/ carry vendor prefixes, DeepSeek is listed bare). Lineup updated 2026-09-16:
2479
+ // deepseek-v4.1-flash, kimi/kimi-k2.8-preview and ZHIPU/GLM-5.3-Flash join;
2480
+ // deepseek-v4-flash-0731 and ZHIPU/GLM-5.2 leave. The DeepSeek row is priced by time of day
2481
+ // on QWEN_OFF_PEAK and stores its peak price, as in the Token Plan group above. --
2482
+ {
2483
+ // Peak CNY 2 input / 8 output / 0.2 cache hit; off-peak (22:00-08:00 Beijing) 1 / 4 / 0.1.
2484
+ // Text and image input, which this group's openai-chat client forwards.
2485
+ modelId: "deepseek-v4.1-flash",
2486
+ displayName: "DeepSeek V4.1 Flash",
2487
+ provider: "qwen-pay-as-you-go",
2488
+ contextWindow: 1e6,
2489
+ pricing: cny(0.2, 2, 8),
2490
+ offPeakDiscount: QWEN_OFF_PEAK,
2491
+ supportsVision: true,
2492
+ clientType: "openai-chat",
2493
+ baseUrl: QWEN_PAYG_BASE_URL
2494
+ },
2495
+ {
2496
+ modelId: "kimi/kimi-k3",
2497
+ displayName: "Kimi K3",
2498
+ provider: "qwen-pay-as-you-go",
2499
+ contextWindow: 1048576,
2500
+ pricing: cny(2, 20, 100),
2501
+ supportsVision: true,
2502
+ clientType: "openai-chat",
2503
+ baseUrl: QWEN_PAYG_BASE_URL
2504
+ },
2505
+ {
2506
+ // CNY 6.5 input / 27 output / 1.7 cache hit over a 1M window (1,048,576, as on the
2507
+ // kimi/kimi-k3 row); text, image and video input.
2508
+ modelId: "kimi/kimi-k2.8-preview",
2509
+ displayName: "Kimi K2.8 Preview",
2510
+ provider: "qwen-pay-as-you-go",
2511
+ contextWindow: 1048576,
2512
+ pricing: cny(1.7, 6.5, 27),
2513
+ supportsVision: true,
2514
+ clientType: "openai-chat",
2515
+ baseUrl: QWEN_PAYG_BASE_URL
2516
+ },
2517
+ {
2518
+ // Official CNY list price from www.qianwenai.com/models/qwen3.8-flash, re-read 2026-09-16:
2519
+ // CNY 0.8 input / CNY 0.1 cache hit / CNY 2.7 output per MTok (it had been 1 / 0.1 / 3),
2520
+ // over a 1M-token input window with a 131K output cap. Its input modalities include
2521
+ // images and video, and this group's openai-chat client converts image parts.
2522
+ modelId: "qwen3.8-flash",
2523
+ displayName: "Qwen 3.8 Flash",
2524
+ provider: "qwen-pay-as-you-go",
2525
+ contextWindow: 1e6,
2526
+ pricing: cny(0.1, 0.8, 2.7),
2527
+ supportsVision: true,
2528
+ clientType: "openai-chat",
2529
+ baseUrl: QWEN_PAYG_BASE_URL
2530
+ },
2531
+ {
2532
+ modelId: "qwen3.8-max",
2533
+ displayName: "Qwen 3.8 Max",
2534
+ provider: "qwen-pay-as-you-go",
2535
+ contextWindow: 1e6,
2536
+ pricing: cny(1.5, 12, 36),
2537
+ supportsVision: true,
2538
+ clientType: "openai-chat",
2539
+ baseUrl: QWEN_PAYG_BASE_URL
2540
+ },
2541
+ {
2542
+ modelId: "qwen3.7-plus",
2543
+ displayName: "Qwen 3.7 Plus",
2544
+ provider: "qwen-pay-as-you-go",
2545
+ contextWindow: 1e6,
2546
+ pricing: cny(0.4, 2, 8),
2547
+ supportsVision: true,
2548
+ clientType: "openai-chat",
2549
+ baseUrl: QWEN_PAYG_BASE_URL
2550
+ },
2551
+ {
2552
+ // CNY 0.8 input / 2.8 output / 0.23 cache hit over a 1M window with a 131K output cap;
2553
+ // natively multimodal like every other GLM-5.3 Flash row, and this group's openai-chat
2554
+ // client forwards image parts.
2555
+ modelId: "ZHIPU/GLM-5.3-Flash",
2556
+ displayName: "GLM-5.3 Flash",
2557
+ provider: "qwen-pay-as-you-go",
2558
+ contextWindow: 1e6,
2559
+ pricing: cny(0.23, 0.8, 2.8),
2560
+ supportsVision: true,
2561
+ clientType: "openai-chat",
2562
+ baseUrl: QWEN_PAYG_BASE_URL
2563
+ },
2564
+ // -- ModelScope (api-inference aggregate, preset base URL). Preset ids keep ModelScope's
2565
+ // own `org/Model-Name` spelling; DeepSeek was read from the endpoint's public /v1/models
2566
+ // listing (2026-09-18), and the Qwen additions from their public model pages (2026-09-20).
2567
+ //
2568
+ // ModelScope serves all three presets through its OpenAI Responses endpoint, so every row pins
2569
+ // MMSP's generic Responses client. Keeping the protocol explicit also prevents ids from
2570
+ // auto-routing to vendor-specific clients with a different request shape.
2571
+ //
2572
+ // The window and vision flags are NOT read from ModelScope's own docs — its model pages are
2573
+ // client-rendered and carry no price. They repeat what other rows of the same models record,
2574
+ // because ModelScope serves the same upstream ids.
2575
+ //
2576
+ // `pricing` is deliberately absent. ModelScope bills for api-inference and does not publish a
2577
+ // read-able rate, so an absent pricing — which the catalog reads as "nobody has looked this
2578
+ // up", leaving the row unbadged and the group's usage uncosted — is the honest state. A
2579
+ // three-zero pricing would be worse than absent here, not better: `isFreeModel` would badge a
2580
+ // billed gateway as "Free". Whoever next reads ModelScope's pricing page should fill it in. --
2581
+ {
2582
+ modelId: "deepseek-ai/DeepSeek-V4.1-Flash",
2583
+ displayName: "DeepSeek V4.1 Flash",
2584
+ provider: MODELSCOPE_PROVIDER_ID,
2585
+ contextWindow: 1e6,
2586
+ supportsVision: true,
2587
+ clientType: "openai-responses",
2588
+ baseUrl: MODELSCOPE_BASE_URL
2589
+ },
2590
+ {
2591
+ modelId: "Qwen/Qwen3.8-27B",
2592
+ displayName: "Qwen 3.8 27B",
2593
+ provider: MODELSCOPE_PROVIDER_ID,
2594
+ contextWindow: 262144,
2595
+ supportsVision: true,
2596
+ clientType: "openai-responses",
2597
+ baseUrl: MODELSCOPE_BASE_URL
2598
+ },
2599
+ {
2600
+ modelId: "Qwen/Qwen3.8-Flash-Next",
2601
+ displayName: "Qwen 3.8 Flash Next",
2602
+ provider: MODELSCOPE_PROVIDER_ID,
2603
+ contextWindow: 262144,
2604
+ supportsVision: true,
2605
+ clientType: "openai-responses",
2606
+ baseUrl: MODELSCOPE_BASE_URL
2607
+ },
2608
+ // -- MiniMax (official USD pay-as-you-go list prices, standard tier at <=512K input — every
2609
+ // rate doubles above 512K, and the priority tier is 1.5x). --
2610
+ {
2611
+ // Pay-as-you-go list price, one tier (MiniMax pricing guide, read 2026-10-19 by MMSP 0.5.5's
2612
+ // registry): $0.15 input / $0.60 output / $0.015 cache hit over a 1,000,000-token window.
2613
+ modelId: "MiniMax-M3.1-Flash",
2614
+ displayName: "MiniMax M3.1 Flash",
2615
+ provider: "minimax",
2616
+ contextWindow: 1e6,
2617
+ pricing: usd(0.015, 0.15, 0.6),
2618
+ supportsVision: true
2619
+ },
2620
+ {
2621
+ modelId: "MiniMax-M3",
2622
+ displayName: "MiniMax M3",
2623
+ provider: "minimax",
2624
+ contextWindow: 1e6,
2625
+ pricing: usd(0.06, 0.3, 1.2),
2626
+ supportsVision: true
2627
+ },
2628
+ // -- Google Gemini (official USD pricing). Gemini 3.7 Flash left the group on 2026-10-10:
2629
+ // Google retires the id and reroutes it to 3.8 Flash, at the same price. --
2630
+ {
2631
+ // ai.google.dev/gemini-api/docs/pricing#gemini-4-argon (2026-10-14): standard list
2632
+ // prices with a 50% introductory discount through 2026-11-30. Only implicit caching
2633
+ // is supported; cache_write is the ordinary input price.
2634
+ modelId: "gemini-4-argon",
2635
+ displayName: "Gemini 4 Argon",
2636
+ provider: "google",
2637
+ contextWindow: 1048576,
2638
+ pricing: usd(0.2, 4, 20),
2639
+ discount: 0.5,
2640
+ supportsVision: true
2641
+ },
2642
+ {
2643
+ // Same list price and same launch discount as the gemini-3.6-flash row below: Google
2644
+ // halves all three rates through 2026-12-31. Like that row this one declares the
2645
+ // promotion in `discount`, so the list price stays on file — here and in a Project, which
2646
+ // is seeded with the fraction beside it — while the cost center bills the 0.075/0.75/3.75
2647
+ // Google actually charges today. One field to delete when the promotion lapses.
2648
+ modelId: "gemini-3.8-flash",
2649
+ displayName: "Gemini 3.8 Flash",
2650
+ provider: "google",
2651
+ contextWindow: 1048576,
2652
+ pricing: usd(0.15, 1.5, 7.5),
2653
+ discount: 0.5,
2654
+ supportsVision: true
2655
+ },
2656
+ {
2657
+ // Same list price and same launch discount as the 3.8 row: Google halves all three rates
2658
+ // through 2026-12-31 (Google's pricing page, read 2026-09-09).
2659
+ modelId: "gemini-3.6-flash",
2660
+ displayName: "Gemini 3.6 Flash",
2661
+ provider: "google",
2662
+ contextWindow: 1048576,
2663
+ pricing: usd(0.15, 1.5, 7.5),
2664
+ discount: 0.5,
2665
+ supportsVision: true
2666
+ },
2667
+ {
2668
+ // Google's 3.5 tier list price ($1.50 / $9.00 / $0.15 cache hit), which carries no launch
2669
+ // discount — re-read 2026-09-09. The $9 output is what the tier costs, not a promotion.
2670
+ modelId: "gemini-3.5-flash",
2671
+ displayName: "Gemini 3.5 Flash",
2672
+ provider: "google",
2673
+ contextWindow: 1048576,
2674
+ pricing: usd(0.15, 1.5, 9),
2675
+ supportsVision: true
2676
+ },
2677
+ {
2678
+ modelId: "gemini-3.5-flash-lite",
2679
+ displayName: "Gemini 3.5 Flash-Lite",
2680
+ provider: "google",
2681
+ contextWindow: 1048576,
2682
+ pricing: usd(0.03, 0.3, 2.5),
2683
+ supportsVision: true
2684
+ },
2685
+ {
2686
+ modelId: "gemini-3.1-flash-lite",
2687
+ displayName: "Gemini 3.1 Flash-Lite",
2688
+ provider: "google",
2689
+ contextWindow: 1048576,
2690
+ pricing: usd(0.025, 0.25, 1.5),
2691
+ supportsVision: true
2692
+ },
2693
+ {
2694
+ // ≤200K input tier; >200K has official surcharge pricing (see file header comment).
2695
+ modelId: "gemini-3.1-pro-preview",
2696
+ displayName: "Gemini 3.1 Pro (Preview)",
2697
+ provider: "google",
2698
+ contextWindow: 1048576,
2699
+ pricing: usd(0.2, 2, 12),
2700
+ supportsVision: true
2701
+ },
2702
+ {
2703
+ modelId: "gemini-3-flash-preview",
2704
+ displayName: "Gemini 3 Flash (Preview)",
2705
+ provider: "google",
2706
+ contextWindow: 1048576,
2707
+ pricing: usd(0.05, 0.5, 3),
2708
+ supportsVision: true
2709
+ },
2710
+ // -- Anthropic (official USD pricing; cache write = 1.25 x input, the 5-minute write).
2711
+ // Re-read 2026-08-20 from platform.claude.com/docs/en/about-claude/pricing; the 5.5 / 5.1
2712
+ // generation added 2026-10-10 from MMSP 0.5.2's registry and the copy of that page it
2713
+ // carries (llmsdk_docs/claude5_5/docs/pricing.md). Sonnet 5's $2 input / $10 output is its
2714
+ // standard rate rather than an introductory one, so it prices below Sonnet 4.6 — that
2715
+ // inversion is Anthropic's list, not a transcription slip. The cache-hit multiplier is no
2716
+ // longer one figure: 0.025x input on Fable 5.1, 0.05x on Opus 5.5 and Sonnet 5.5, 0.1x on
2717
+ // every other row. Anthropic bills the full 1M window at a single rate on every row but
2718
+ // Haiku 5.5, which the file header's tier list names; and the fast-mode premium on Opus 5.5
2719
+ // ($8 input / $40 output) and Opus 5 / Opus 4.8 ($10 / $50) is a separate tier these rows do
2720
+ // not record. Every row takes image input over a 1,000,000-token window. --
2721
+ {
2722
+ // $10 input / $12.50 cache write / $0.25 cache hit / $50 output.
2723
+ modelId: "claude-fable-5-1",
2724
+ displayName: "Claude Fable 5.1",
2725
+ provider: "anthropic",
2726
+ contextWindow: 1e6,
2727
+ pricing: usd(0.25, 12.5, 50),
2728
+ supportsVision: true
2729
+ },
2730
+ {
2731
+ modelId: "claude-fable-5",
2732
+ displayName: "Claude Fable 5",
2733
+ provider: "anthropic",
2734
+ contextWindow: 1e6,
2735
+ pricing: usd(1, 12.5, 50),
2736
+ supportsVision: true
2737
+ },
2738
+ {
2739
+ // $0.10 input / $0.125 cache write / $0.01 cache hit / $0.50 output for a prompt of up to
2740
+ // 100,000 tokens, counting cache reads and writes; a longer prompt pays 5x on every rate,
2741
+ // for the whole request. The base tier is recorded. MMSP 0.5.2 is the first release whose
2742
+ // official Anthropic client knows the model: it runs `none` thinking at low effort, refuses
2743
+ // a forced tool choice, which Haiku 5.5 answers without thinking, and refuses fast mode,
2744
+ // which Haiku 5.5 rejects (fastModeProtocol offers no toggle for it either).
2745
+ modelId: "claude-haiku-5-5",
2746
+ displayName: "Claude Haiku 5.5",
2747
+ provider: "anthropic",
2748
+ contextWindow: 1e6,
2749
+ pricing: usd(0.01, 0.125, 0.5),
2750
+ supportsVision: true
2751
+ },
2752
+ {
2753
+ // $4 input / $5 cache write / $0.20 cache hit / $20 output.
2754
+ modelId: "claude-opus-5-5",
2755
+ displayName: "Claude Opus 5.5",
2756
+ provider: "anthropic",
2757
+ contextWindow: 1e6,
2758
+ pricing: usd(0.2, 5, 20),
2759
+ supportsVision: true
2760
+ },
2761
+ {
2762
+ modelId: "claude-opus-5",
2763
+ displayName: "Claude Opus 5",
2764
+ provider: "anthropic",
2765
+ contextWindow: 1e6,
2766
+ pricing: usd(0.5, 6.25, 25),
2767
+ supportsVision: true
2768
+ },
2769
+ {
2770
+ modelId: "claude-opus-4-8",
2771
+ displayName: "Claude Opus 4.8",
2772
+ provider: "anthropic",
2773
+ contextWindow: 1e6,
2774
+ pricing: usd(0.5, 6.25, 25),
2775
+ supportsVision: true
2776
+ },
2777
+ {
2778
+ modelId: "claude-opus-4-7",
2779
+ displayName: "Claude Opus 4.7",
2780
+ provider: "anthropic",
2781
+ contextWindow: 1e6,
2782
+ pricing: usd(0.5, 6.25, 25),
2783
+ supportsVision: true
2784
+ },
2785
+ {
2786
+ // $2 input / $2.50 cache write / $0.10 cache hit / $10 output. MMSP 0.5.0 listed the cache
2787
+ // hit at $0.20, Sonnet 5's figure; 0.5.2 lowered it to the 0.05x of input that Anthropic's
2788
+ // pricing page states for this model.
2789
+ modelId: "claude-sonnet-5-5",
2790
+ displayName: "Claude Sonnet 5.5",
2791
+ provider: "anthropic",
2792
+ contextWindow: 1e6,
2793
+ pricing: usd(0.1, 2.5, 10),
2794
+ supportsVision: true
2795
+ },
2796
+ {
2797
+ modelId: "claude-sonnet-5",
2798
+ displayName: "Claude Sonnet 5",
2799
+ provider: "anthropic",
2800
+ contextWindow: 1e6,
2801
+ pricing: usd(0.2, 2.5, 10),
2802
+ supportsVision: true
2803
+ },
2804
+ {
2805
+ modelId: "claude-sonnet-4-6",
2806
+ displayName: "Claude Sonnet 4.6",
2807
+ provider: "anthropic",
2808
+ contextWindow: 1e6,
2809
+ pricing: usd(0.3, 3.75, 15),
2810
+ supportsVision: true
2811
+ },
2812
+ // -- OpenAI (official USD pricing) --
2813
+ {
2814
+ // OpenAI's list price per MMSP 0.5.2's registry and the model page it carries
2815
+ // (llmsdk_docs/gpt6/docs/gpt-6.1-sol.md, read 2026-10-10): $2 input / $0.10 cached input
2816
+ // (5% of input) / $2.50 cache write / $10 output, over a 1,050,000-token window with text
2817
+ // and image input. As on gpt-6-astra below, cache_write carries the published cache-write
2818
+ // price; a prompt above 272K tokens pays 2x input and cache and 1.5x output for the whole
2819
+ // request, a tier this row does not record.
2820
+ modelId: "gpt-6.1-sol",
2821
+ displayName: "GPT-6.1 Sol",
2822
+ provider: "openai",
2823
+ contextWindow: 105e4,
2824
+ pricing: usd(0.1, 2.5, 10),
2825
+ supportsVision: true
2826
+ },
2827
+ {
2828
+ // OpenAI's list price (developers.openai.com/api/docs/models/gpt-6-astra, read
2829
+ // 2026-09-09) is $10 input / $1 cached input / $12.5 cache write / $50 output. Per the
2830
+ // bucket convention at the top of this file, cache_write carries the published
2831
+ // cache-write price of 12.5; the $10 rate applies only to input that is not written to
2832
+ // cache, a split the three buckets do not express. Every rate doubles above 272K input
2833
+ // tokens (output 1.5x) — the base tier is what this row records, as the header says.
2834
+ modelId: "gpt-6-astra",
2835
+ displayName: "GPT-6 Astra",
2836
+ provider: "openai",
2837
+ contextWindow: 105e4,
2838
+ pricing: usd(1, 12.5, 50),
2839
+ supportsVision: true
2840
+ },
2841
+ {
2842
+ // https://developers.openai.com/api/docs/models/gpt-6-luna (2026-10-14).
2843
+ // Base tier: above 272K input, input/cache rates double and output is 1.5x.
2844
+ modelId: "gpt-6-luna",
2845
+ displayName: "GPT-6 Luna",
2846
+ provider: "openai",
2847
+ contextWindow: 105e4,
2848
+ pricing: usd(0.01, 0.125, 0.5),
2849
+ supportsVision: true
2850
+ },
2851
+ {
2852
+ // The bare gpt-5.6 id routes to gpt-5.6-sol upstream and is priced as that tier, so the
2853
+ // row names the Sol codename its siblings and the openai/gpt-5.6-sol row already show —
2854
+ // the id stays bare, only the label says which variant this is. This row and the two
2855
+ // gpt-5.6 rows below mirror the
2856
+ // openai/gpt-5.6-* OpenRouter rows above, which carry the gateway's (currently
2857
+ // discounted) rates instead of this list price.
2858
+ modelId: "gpt-5.6",
2859
+ displayName: "GPT-5.6 Sol",
2860
+ provider: "openai",
2861
+ contextWindow: 105e4,
2862
+ pricing: usd(0.5, 5, 30),
2863
+ supportsVision: true
2864
+ },
2865
+ {
2866
+ modelId: "gpt-5.6-luna",
2867
+ displayName: "GPT-5.6 Luna",
2868
+ provider: "openai",
2869
+ contextWindow: 105e4,
2870
+ pricing: usd(0.02, 0.2, 1.2),
2871
+ supportsVision: true
2872
+ },
2873
+ {
2874
+ modelId: "gpt-5.6-terra",
2875
+ displayName: "GPT-5.6 Terra",
2876
+ provider: "openai",
2877
+ contextWindow: 105e4,
2878
+ pricing: usd(0.2, 2, 12),
2879
+ supportsVision: true
2880
+ },
2881
+ {
2882
+ modelId: "gpt-5.5",
2883
+ displayName: "GPT-5.5",
2884
+ provider: "openai",
2885
+ contextWindow: 105e4,
2886
+ pricing: usd(0.5, 5, 30),
2887
+ supportsVision: true
2888
+ },
2889
+ {
2890
+ // No official cache discount: cache_read uses the standard input price.
2891
+ modelId: "gpt-5.5-pro",
2892
+ displayName: "GPT-5.5 Pro",
2893
+ provider: "openai",
2894
+ contextWindow: 105e4,
2895
+ pricing: usd(30, 30, 180),
2896
+ supportsVision: true
2897
+ },
2898
+ {
2899
+ modelId: "gpt-5.4",
2900
+ displayName: "GPT-5.4",
2901
+ provider: "openai",
2902
+ contextWindow: 105e4,
2903
+ pricing: usd(0.25, 2.5, 15),
2904
+ supportsVision: true
2905
+ },
2906
+ {
2907
+ modelId: "gpt-5.4-mini",
2908
+ displayName: "GPT-5.4 mini",
2909
+ provider: "openai",
2910
+ contextWindow: 4e5,
2911
+ pricing: usd(0.075, 0.75, 4.5),
2912
+ supportsVision: true
2913
+ },
2914
+ {
2915
+ modelId: "gpt-5.4-nano",
2916
+ displayName: "GPT-5.4 nano",
2917
+ provider: "openai",
2918
+ contextWindow: 4e5,
2919
+ pricing: usd(0.02, 0.2, 1.25),
2920
+ supportsVision: true
2921
+ },
2922
+ {
2923
+ // No official cache discount: cache_read uses the standard input price.
2924
+ modelId: "gpt-5.4-pro",
2925
+ displayName: "GPT-5.4 Pro",
2926
+ provider: "openai",
2927
+ contextWindow: 105e4,
2928
+ pricing: usd(30, 30, 180),
2929
+ supportsVision: true
2930
+ },
2931
+ // -- Z.AI (GLM) --
2932
+ {
2933
+ // Announced 2026-08-14. Z.AI's price
2934
+ // list (docs.z.ai/guides/overview/pricing, read 2026-08-18) publishes the same USD rates
2935
+ // as glm-5.2 / glm-5.1.
2936
+ modelId: "glm-5.3",
2937
+ displayName: "GLM-5.3",
2938
+ provider: "zhipu",
2939
+ contextWindow: 1e6,
2940
+ pricing: usd(0.26, 1.4, 4.4),
2941
+ supportsVision: false
2942
+ },
2943
+ {
2944
+ // Z.AI's price list (docs.z.ai/guides/overview/pricing) publishes $0.15 input / $0.03
2945
+ // cached input / $0.50 output; a 50% promotion halved all three through 24:00 on
2946
+ // 2026-09-09 (UTC+8). Direct-vendor rows record the vendor's list price, so that is what
2947
+ // is stored here — the OpenRouter z-ai/glm-5.3-flash row above carries the rate its
2948
+ // default endpoint bills, which runs a promotion of its own.
2949
+ //
2950
+ // The model is natively multimodal (docs.z.ai/guides/vlm/glm-5.3-flash: images, video
2951
+ // and files), and it is the one GLM id whose images MMSP's Z.AI client forwards — as
2952
+ // image_url parts, in a prompt and in a tool result alike. Every other GLM id refuses
2953
+ // one outright ("GLM <id> does not support image inputs."), which is why the rest of
2954
+ // this group is vision-off.
2955
+ modelId: "glm-5.3-flash",
2956
+ displayName: "GLM-5.3 Flash",
2957
+ provider: "zhipu",
2958
+ contextWindow: 1e6,
2959
+ pricing: usd(0.03, 0.15, 0.5),
2960
+ supportsVision: true
2961
+ },
2962
+ {
2963
+ modelId: "glm-5.2",
2964
+ displayName: "GLM-5.2",
2965
+ provider: "zhipu",
2966
+ contextWindow: 1e6,
2967
+ pricing: usd(0.26, 1.4, 4.4),
2968
+ supportsVision: false
2969
+ },
2970
+ {
2971
+ modelId: "glm-5.1",
2972
+ displayName: "GLM-5.1",
2973
+ provider: "zhipu",
2974
+ contextWindow: 2e5,
2975
+ pricing: usd(0.26, 1.4, 4.4),
2976
+ supportsVision: false
2977
+ },
2978
+ {
2979
+ modelId: "glm-5",
2980
+ displayName: "GLM-5",
2981
+ provider: "zhipu",
2982
+ contextWindow: 2e5,
2983
+ pricing: usd(0.2, 1, 3.2),
2984
+ supportsVision: false
2985
+ },
2986
+ // -- Moonshot (Kimi) (official CNY pricing) --
2987
+ {
2988
+ // Moonshot's list (pricing page, read 2026-10-23 for MMSP 0.5.6's registry): CNY 13 input /
2989
+ // 68 output / 1.3 cache hit over a 1,048,576-token window, image input. The default
2990
+ // five-minute cache write bills at the input price, which is what cache_write stores; the
2991
+ // one-hour write, which only MMSP's `prompt_caching` enhance asks for, bills twice that.
2992
+ modelId: "kimi-k3.1-pro",
2993
+ displayName: "Kimi K3.1 Pro",
2994
+ provider: "moonshot",
2995
+ contextWindow: 1048576,
2996
+ pricing: cny(1.3, 13, 68),
2997
+ supportsVision: true
2998
+ },
2999
+ {
3000
+ // The same model at two to three times the output speed (Moonshot's model list), at twice
3001
+ // the input, output and cache-write prices and the same cache hit: CNY 26 / 136 / 1.3.
3002
+ // Moonshot's vision guide names only kimi-k3.1-pro, but its model list files both ids under
3003
+ // multimodal models, and MMSP's live probe read a base64 image through this one.
3004
+ modelId: "kimi-k3.1-pro-highspeed",
3005
+ displayName: "Kimi K3.1 Pro Highspeed",
3006
+ provider: "moonshot",
3007
+ contextWindow: 1048576,
3008
+ pricing: cny(1.3, 26, 136),
3009
+ supportsVision: true
3010
+ },
3011
+ {
3012
+ modelId: "kimi-k3",
3013
+ displayName: "Kimi K3",
3014
+ provider: "moonshot",
3015
+ contextWindow: 1048576,
3016
+ pricing: cny(2, 20, 100),
3017
+ supportsVision: true
3018
+ },
3019
+ {
3020
+ modelId: "kimi-k2.6",
3021
+ displayName: "Kimi K2.6",
3022
+ provider: "moonshot",
3023
+ contextWindow: 262144,
3024
+ pricing: cny(1.1, 6.5, 27),
3025
+ supportsVision: true
3026
+ },
3027
+ {
3028
+ modelId: "kimi-k2.5",
3029
+ displayName: "Kimi K2.5",
3030
+ provider: "moonshot",
3031
+ contextWindow: 262144,
3032
+ pricing: cny(0.7, 4, 21),
3033
+ supportsVision: true
3034
+ },
3035
+ // -- vLLM (self-hosted: the models MMSP's openai-chat-vllm-adapter client carries a
3036
+ // per-model thinking switch for, as published at recipes.vllm.ai — read 2026-09-03).
3037
+ //
3038
+ // Every row prices at zero, and omits two other things, all because the user runs the server:
3039
+ // - **zero pricing**. There is no seller charging per token: what the deployment costs is
3040
+ // the operator's own hardware, which no catalog rate could express. Three zero buckets are
3041
+ // the same genuine $0 tier the `:free` gateway rows carry, so these models show the free
3042
+ // badge and contribute 0 to the cost center rather than the "unpriced" mark — which is the
3043
+ // truthful reading of a self-hosted endpoint that bills nobody.
3044
+ // - **the local server's base URL** (VLLM_LOCAL_BASE_URL), where `vllm serve` answers when
3045
+ // it runs on the same machine with its default port. A new Project stores it once, on the
3046
+ // group's table; a deployment elsewhere changes the group's base URL.
3047
+ // - **no auto-routing**. Each row pins openai-chat-vllm-adapter explicitly, and the pin is
3048
+ // load-bearing twice over: `Qwen/*` begins with no family AutoLLMClient knows and would
3049
+ // be rejected outright, while `deepseek-ai/DeepSeek-V4-*` begins with "deepseek-" and
3050
+ // would reach DeepSeek's official Responses client — pointed at a vLLM server.
3051
+ //
3052
+ // contextWindow is the recipe's NATIVE length, which is the most a deployment can serve
3053
+ // without reconfiguration; an operator may serve less (`--max-model-len` below the native
3054
+ // limit) or, for the Qwen rows, far more with YaRN rope scaling. The catalog cannot know
3055
+ // which, and it derives the compaction thresholds from this number, so the honest default
3056
+ // is the checkpoint's own figure — an entry without one would be assumed to be 128000.
3057
+ // The DeepSeek rows additionally document `--max-model-len >= 393216` as the floor for
3058
+ // their top reasoning levels, which is well inside the window recorded here.
3059
+ {
3060
+ modelId: "deepseek-ai/DeepSeek-V4-Flash",
3061
+ displayName: "DeepSeek V4 Flash",
3062
+ provider: "vllm",
3063
+ contextWindow: 1e6,
3064
+ pricing: usd(0, 0, 0),
3065
+ supportsVision: false,
3066
+ clientType: VLLM_CLIENT_TYPE,
3067
+ baseUrl: VLLM_LOCAL_BASE_URL
3068
+ },
3069
+ {
3070
+ // The experimental vision revision: DeepSeek's first multimodal V4, a ViT tower on the
3071
+ // same language backbone. Its recipe verifies a 32K deployment and notes the 1M the
3072
+ // checkpoint advertises was not what was measured; the window below is the checkpoint's,
3073
+ // matching every other DeepSeek V4 row in this catalog.
3074
+ modelId: "deepseek-ai/DeepSeek-V4-Flash-Vision-Exp",
3075
+ displayName: "DeepSeek V4 Flash Vision Exp",
3076
+ provider: "vllm",
3077
+ contextWindow: 1e6,
3078
+ pricing: usd(0, 0, 0),
3079
+ supportsVision: true,
3080
+ clientType: VLLM_CLIENT_TYPE,
3081
+ baseUrl: VLLM_LOCAL_BASE_URL
3082
+ },
3083
+ {
3084
+ modelId: "deepseek-ai/DeepSeek-V4-Pro",
3085
+ displayName: "DeepSeek V4 Pro",
3086
+ provider: "vllm",
3087
+ contextWindow: 1e6,
3088
+ pricing: usd(0, 0, 0),
3089
+ supportsVision: false,
3090
+ clientType: VLLM_CLIENT_TYPE,
3091
+ baseUrl: VLLM_LOCAL_BASE_URL
3092
+ },
3093
+ {
3094
+ modelId: "Qwen/Qwen3.5-0.8B",
3095
+ displayName: "Qwen 3.5 0.8B",
3096
+ provider: "vllm",
3097
+ contextWindow: 262144,
3098
+ pricing: usd(0, 0, 0),
3099
+ supportsVision: true,
3100
+ clientType: VLLM_CLIENT_TYPE,
3101
+ baseUrl: VLLM_LOCAL_BASE_URL
3102
+ },
3103
+ {
3104
+ modelId: "Qwen/Qwen3.5-9B",
3105
+ displayName: "Qwen 3.5 9B",
3106
+ provider: "vllm",
3107
+ contextWindow: 262144,
3108
+ pricing: usd(0, 0, 0),
3109
+ supportsVision: true,
3110
+ clientType: VLLM_CLIENT_TYPE,
3111
+ baseUrl: VLLM_LOCAL_BASE_URL
3112
+ },
3113
+ {
3114
+ modelId: "Qwen/Qwen3.6-35B-A3B",
3115
+ displayName: "Qwen 3.6 35B A3B",
3116
+ provider: "vllm",
3117
+ contextWindow: 262144,
3118
+ pricing: usd(0, 0, 0),
3119
+ supportsVision: true,
3120
+ clientType: VLLM_CLIENT_TYPE,
3121
+ baseUrl: VLLM_LOCAL_BASE_URL
3122
+ },
3123
+ {
3124
+ modelId: "Qwen/Qwen3.8-27B",
3125
+ displayName: "Qwen 3.8 27B",
3126
+ provider: "vllm",
3127
+ contextWindow: 262144,
3128
+ pricing: usd(0, 0, 0),
3129
+ supportsVision: true,
3130
+ clientType: VLLM_CLIENT_TYPE,
3131
+ baseUrl: VLLM_LOCAL_BASE_URL
3132
+ },
3133
+ {
3134
+ modelId: "Qwen/Qwen3.8-Flash-Next",
3135
+ displayName: "Qwen 3.8 Flash Next",
3136
+ provider: "vllm",
3137
+ contextWindow: 262144,
3138
+ pricing: usd(0, 0, 0),
3139
+ supportsVision: true,
3140
+ clientType: VLLM_CLIENT_TYPE,
3141
+ baseUrl: VLLM_LOCAL_BASE_URL
3142
+ },
3143
+ // -- Custom (the group that otherwise holds only user-defined models). A preset may live
3144
+ // here only as a complete row — its own base URL and a pinned generic protocol — because the
3145
+ // group implies neither; it is where a vendor with a single preview model and no console
3146
+ // of its own goes rather than opening a group for it. Atria Dawn: the Anthropic
3147
+ // Messages API at api.atria-asi.ai (the client appends /v1/messages, so the base URL carries
3148
+ // no /v1; the endpoint also serves Chat Completions and Responses, but its Responses side
3149
+ // rejects the replayed assistant turn of a multi-turn conversation), a 256K window (262144 —
3150
+ // the API caps max_output_tokens at that minus the input), text only (the endpoint rejects
3151
+ // image input), and no published price yet, so the row records $0 until the vendor prices
3152
+ // it. Read 2026-09-15 from api.atria-asi.ai/docs.
3153
+ {
3154
+ modelId: "Atria-Dawn",
3155
+ displayName: "Atria Dawn",
3156
+ provider: "custom",
3157
+ contextWindow: 262144,
3158
+ pricing: usd(0, 0, 0),
3159
+ supportsVision: false,
3160
+ clientType: "ant-messages",
3161
+ baseUrl: "https://api.atria-asi.ai"
3162
+ }
3163
+ ];
3164
+ function catalogEntryFor(provider, upstreamId) {
3165
+ return MODEL_CATALOG.find((m) => m.provider === provider && m.modelId === upstreamId);
3166
+ }
3167
+ function providerInfo(providerId) {
3168
+ return MODEL_PROVIDERS.find((p) => p.id === providerId);
3169
+ }
3170
+ function providerClientType(providerId) {
3171
+ return providerInfo(providerId)?.clientType;
3172
+ }
3173
+ function isVendorGroup(providerId) {
3174
+ const info = providerInfo(providerId);
3175
+ return info !== void 0 && info.id !== "custom" && info.gatewayBaseUrl === void 0 && info.clientType === void 0;
3176
+ }
3177
+ function unroutableVendorModel(provider, modelId, clientType) {
3178
+ const id = modelId.trim();
3179
+ if (id === "" || !isVendorGroup(provider)) return false;
3180
+ return routedClientType(id, clientType?.trim() ? clientType : null) === null;
3181
+ }
3182
+ function vendorClientType(providerId) {
3183
+ if (!isVendorGroup(providerId)) return void 0;
3184
+ const envKey = providerInfo(providerId)?.envKey;
3185
+ return OFFICIAL_CLIENT_TYPES.find((t) => CLIENT_CREDENTIALS[t]?.apiKeyEnv === envKey);
3186
+ }
3187
+ function isAddableGroup(providerId) {
3188
+ const info = providerInfo(providerId);
3189
+ return info === void 0 || info.addable === true;
3190
+ }
3191
+ function unaddableModel(provider, modelId) {
3192
+ return !isAddableGroup(provider) && catalogEntryFor(provider, modelId.trim()) === void 0;
3193
+ }
3194
+ function retainedCatalogPricing(provider, modelId) {
3195
+ const entry = catalogEntryFor(provider, modelId);
3196
+ return entry?.wasDefault === true ? entry.pricing : void 0;
3197
+ }
3198
+ function modelHomepageUrl(provider, modelId) {
3199
+ if (provider === "openrouter") return `https://openrouter.ai/${modelId}`;
3200
+ if (provider === "qwen-token-plan") {
3201
+ return `https://www.qianwenai.com/models/${modelId}`;
3202
+ }
3203
+ if (provider === "fireworks") {
3204
+ const m = /^accounts\/([^/]+)\/models\/(.+)$/.exec(modelId);
3205
+ return m ? `https://app.fireworks.ai/models/${m[1]}/${m[2]}` : providerInfo(provider)?.modelsUrl;
3206
+ }
3207
+ if (provider === "tokendance") return `https://tokendance.space/models/${modelId}`;
3208
+ if (provider === "qwen-pay-as-you-go") {
3209
+ return `https://www.qianwenai.com/models/${encodeURIComponent(modelId)}`;
3210
+ }
3211
+ if (provider === "zhipu") {
3212
+ return `https://docs.z.ai/guides/llm/${modelId}`;
3213
+ }
3214
+ if (provider === "moonshot") {
3215
+ const m = /^kimi-k(\d+)\.(\d+)$/.exec(modelId);
3216
+ return m ? `https://platform.kimi.com/docs/pricing/chat-k${m[1]}${m[2]}` : providerInfo(provider)?.modelsUrl;
3217
+ }
3218
+ if (provider === "vllm") {
3219
+ return catalogEntryFor(provider, modelId) !== void 0 ? `https://recipes.vllm.ai/${modelId}` : providerInfo(provider)?.modelsUrl;
3220
+ }
3221
+ if (provider === "custom") return void 0;
3222
+ return providerInfo(provider)?.modelsUrl;
3223
+ }
3224
+
3225
+ // src/model-catalog/env-keys.ts
3226
+ import {
3227
+ CLIENT_CREDENTIALS as CLIENT_CREDENTIALS2,
3228
+ environmentCredential,
3229
+ routedClientType as routedClientType2
3230
+ } from "@prismshadow/mmsp/credentials";
3231
+ import { effectiveConnection } from "@prismshadow/penguin-core/model-connection";
3232
+ function clientEnvKey(clientType, baseUrl) {
3233
+ const credential = environmentCredential(clientType, baseUrl?.trim() || void 0);
3234
+ return credential?.kind === "env" ? credential.apiKeyEnv : void 0;
3235
+ }
3236
+ function calledKeyless(clientType, baseUrl) {
3237
+ const credential = environmentCredential(clientType, baseUrl?.trim() || void 0);
3238
+ if (credential?.kind === "keyless") return true;
3239
+ if (credential?.kind !== "env") return false;
3240
+ const routed = routedClientType2("", clientType);
3241
+ return routed !== null && CLIENT_CREDENTIALS2[routed]?.openServer === true;
3242
+ }
3243
+ function signInKeyed(providerId) {
3244
+ return providerInfo(providerId)?.bridgeAuth !== void 0;
3245
+ }
3246
+ function modelEnvironment(entry, group) {
3247
+ const effective = effectiveConnection(entry, group);
3248
+ const routed = routedClientType2(entry.modelId, effective.clientType ?? null);
3249
+ if (routed === null) return {};
3250
+ const credential = environmentCredential(routed, effective.baseUrl);
3251
+ if (credential?.kind !== "env") return {};
3252
+ const defaultBaseUrl = CLIENT_CREDENTIALS2[routed]?.defaultBaseUrl;
3253
+ return {
3254
+ ...effective.apiKey === void 0 ? { apiKeyEnv: credential.apiKeyEnv } : {},
3255
+ ...credential.baseUrlEnv !== null ? {
3256
+ baseUrlEnv: credential.baseUrlEnv,
3257
+ ...defaultBaseUrl !== void 0 ? { defaultBaseUrl } : {}
3258
+ } : {}
3259
+ };
3260
+ }
3261
+ function modelEnvPreviewKey(entry, group) {
3262
+ return modelEnvironment(entry, group).apiKeyEnv;
3263
+ }
3264
+ function groupClientType(providerId, group) {
3265
+ const pinned = group?.clientType?.trim() ? group.clientType : void 0;
3266
+ return pinned ?? vendorClientType(providerId);
3267
+ }
3268
+ function providerEnvFallbackKey(providerId, group) {
3269
+ const clientType = groupClientType(providerId, group);
3270
+ return clientType === void 0 ? void 0 : clientEnvKey(clientType, group?.baseUrl);
3271
+ }
3272
+ function providerCalledKeyless(providerId, group) {
3273
+ if (signInKeyed(providerId)) return false;
3274
+ const clientType = groupClientType(providerId, group);
3275
+ return clientType !== void 0 && calledKeyless(clientType, group?.baseUrl);
3276
+ }
3277
+ function modelCalledKeyless(entry, group) {
3278
+ if (signInKeyed(entry.provider)) return false;
3279
+ const effective = effectiveConnection(entry, group);
3280
+ if (effective.apiKey !== void 0) return false;
3281
+ const routed = routedClientType2(entry.modelId, effective.clientType ?? null);
3282
+ return routed !== null && calledKeyless(routed, effective.baseUrl);
3283
+ }
3284
+
3285
+ // src/model-catalog/seed.ts
3286
+ import {
3287
+ canonicalClientType,
3288
+ sameClientType as sameClientType2,
3289
+ sameEndpoint
3290
+ } from "@prismshadow/penguin-core/model-connection";
3291
+ function sharedValue(values, same) {
3292
+ const first = values[0];
3293
+ if (first === void 0) return void 0;
3294
+ return values.every((v) => v !== void 0 && same(v, first)) ? first : void 0;
3295
+ }
3296
+ function catalogGroupConnection(providerId) {
3297
+ const info = providerInfo(providerId);
3298
+ if (info === void 0 || info.id === "custom") return void 0;
3299
+ const rows = MODEL_CATALOG.filter((m) => m.provider === providerId);
3300
+ const baseUrl = info.gatewayBaseUrl ?? sharedValue(
3301
+ rows.map((m) => m.baseUrl),
3302
+ sameEndpoint
3303
+ );
3304
+ const clientType = canonicalClientType(
3305
+ providerClientType(providerId) ?? sharedValue(
3306
+ rows.map((m) => m.clientType),
3307
+ sameClientType2
3308
+ )
3309
+ );
3310
+ if (baseUrl === void 0 && clientType === void 0) return void 0;
3311
+ return {
3312
+ ...baseUrl !== void 0 ? { base_url: baseUrl } : {},
3313
+ ...clientType !== void 0 ? { client_type: clientType } : {}
3314
+ };
3315
+ }
3316
+ var PRESET_DEFAULT_MODEL = {
3317
+ provider: "deepseek",
3318
+ model_id: "deepseek-flash"
3319
+ };
3320
+ function presetProviderTable() {
3321
+ const table = {};
3322
+ for (const p of MODEL_PROVIDERS) {
3323
+ const connection = catalogGroupConnection(p.id);
3324
+ if (connection !== void 0) table[p.id] = connection;
3325
+ }
3326
+ return table;
3327
+ }
3328
+ function presetModelEntries(groups = presetProviderTable()) {
3329
+ const catalog = presetProviderTable();
3330
+ return MODEL_CATALOG.filter((m) => m.retired !== true).map(
3331
+ (m) => catalogModelEntry(m, catalog, groups)
3332
+ );
3333
+ }
3334
+ function catalogModelEntries(groups = presetProviderTable()) {
3335
+ const catalog = presetProviderTable();
3336
+ return MODEL_CATALOG.map((m) => catalogModelEntry(m, catalog, groups));
3337
+ }
3338
+ function catalogModelEntry(m, catalog, groups) {
3339
+ const group = groups[m.provider];
3340
+ const clientType = canonicalClientType(m.clientType ?? catalog[m.provider]?.client_type);
3341
+ const groupClientType2 = group?.client_type?.trim() || void 0;
3342
+ const ownClientType = clientType !== void 0 && (groupClientType2 === void 0 || !sameClientType2(clientType, groupClientType2)) ? clientType : void 0;
3343
+ const baseUrl = m.baseUrl ?? catalog[m.provider]?.base_url;
3344
+ const groupBaseUrl = group?.base_url?.trim() || void 0;
3345
+ const ownBaseUrl = baseUrl !== void 0 && (groupBaseUrl === void 0 || !sameEndpoint(baseUrl, groupBaseUrl)) ? baseUrl : void 0;
3346
+ return {
3347
+ provider: m.provider,
3348
+ model_id: m.modelId,
3349
+ ...m.contextWindow !== void 0 ? { context_window: m.contextWindow } : {},
3350
+ ...ownClientType !== void 0 ? { client_type: ownClientType } : {},
3351
+ ...m.pricing ? { pricing: { ...m.pricing } } : {},
3352
+ // ModelEntry.vision defaults to supported: only models that don't support images
3353
+ // explicitly persist false (drives read_file's hand-off of images to the vision model and input
3354
+ // image hand-off, see project-config.ts).
3355
+ ...m.supportsVision ? {} : { vision: false },
3356
+ ...ownBaseUrl !== void 0 ? { base_url: ownBaseUrl } : {}
3357
+ };
3358
+ }
3359
+ function presetPromotions() {
3360
+ return MODEL_CATALOG.flatMap(
3361
+ (m) => m.retired !== true && m.discount !== void 0 && m.discount > 0 && m.discount < 1 ? [{ provider: m.provider, modelId: m.modelId, discount: m.discount }] : []
3362
+ );
3363
+ }
3364
+
3365
+ export {
3366
+ PENGUIN_GO_BASE_URL,
3367
+ PENGUIN_GO_PROVIDER_ID,
3368
+ fixedClientType,
3369
+ fixedClientTypeRefuses,
3370
+ MODELSCOPE_PROVIDER_ID,
3371
+ MODEL_PROVIDERS,
3372
+ offPeakAt,
3373
+ DEEPSEEK_OFF_PEAK,
3374
+ QWEN_OFF_PEAK,
3375
+ offPeakScheduledRefs,
3376
+ effectivePricing,
3377
+ MODEL_CATALOG,
3378
+ catalogEntryFor,
3379
+ providerInfo,
3380
+ providerClientType,
3381
+ isVendorGroup,
3382
+ unroutableVendorModel,
3383
+ vendorClientType,
3384
+ isAddableGroup,
3385
+ unaddableModel,
3386
+ retainedCatalogPricing,
3387
+ modelHomepageUrl,
3388
+ clientEnvKey,
3389
+ modelEnvironment,
3390
+ modelEnvPreviewKey,
3391
+ providerEnvFallbackKey,
3392
+ providerCalledKeyless,
3393
+ modelCalledKeyless,
3394
+ catalogGroupConnection,
3395
+ PRESET_DEFAULT_MODEL,
3396
+ presetProviderTable,
3397
+ presetModelEntries,
3398
+ catalogModelEntries,
3399
+ presetPromotions
3400
+ };
3401
+ //# sourceMappingURL=chunk-GGIINEEK.js.map