@linxiraos/pi-catalog 1.1.6 → 1.1.8

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 (287) hide show
  1. package/CHANGELOG.md +10 -6
  2. package/README.md +9 -8
  3. package/dist/types/build.d.ts +13 -8
  4. package/dist/types/cline-pass-model-id.d.ts +4 -0
  5. package/dist/types/compat/anthropic.d.ts +10 -4
  6. package/dist/types/compat/auth-ids.d.ts +4 -0
  7. package/dist/types/compat/auth.d.ts +7 -0
  8. package/dist/types/compat/axes.d.ts +50 -0
  9. package/dist/types/compat/behavior.d.ts +69 -0
  10. package/dist/types/compat/cascade.d.ts +37 -0
  11. package/dist/types/{variant-collapse.d.ts → compat/collapse.d.ts} +60 -35
  12. package/dist/types/compat/openai.d.ts +7 -26
  13. package/dist/types/compat/resolve.d.ts +15 -0
  14. package/dist/types/compat/revision.d.ts +41 -0
  15. package/dist/types/compat/taxonomy.d.ts +93 -0
  16. package/dist/types/compat/types.d.ts +565 -0
  17. package/dist/types/discovery/antigravity.d.ts +1 -1
  18. package/dist/types/discovery/cursor-proto.d.ts +6 -6
  19. package/dist/types/discovery/cursor.d.ts +8 -0
  20. package/dist/types/discovery/devin-proto.d.ts +363 -0
  21. package/dist/types/discovery/gemini-cli.d.ts +1 -1
  22. package/dist/types/identity/id.d.ts +1 -0
  23. package/dist/types/identity/index.d.ts +3 -3
  24. package/dist/types/identity/reference.d.ts +0 -10
  25. package/dist/types/index.d.ts +1 -1
  26. package/dist/types/model-thinking.d.ts +6 -24
  27. package/dist/types/provider-models/cline-pass.d.ts +22 -0
  28. package/dist/types/provider-models/descriptors.d.ts +20 -1
  29. package/dist/types/provider-models/models-dev-policies.d.ts +2 -1
  30. package/dist/types/provider-models/openai-compat.d.ts +59 -46
  31. package/dist/types/provider-models/special.d.ts +23 -2
  32. package/dist/types/types.d.ts +177 -13
  33. package/dist/types/wire/cline-pass.d.ts +21 -0
  34. package/dist/types/wire/devin-proto.d.ts +14 -0
  35. package/dist/types/wire/devin.d.ts +36 -0
  36. package/dist/types/wire/github-copilot.d.ts +31 -12
  37. package/package.json +6 -4
  38. package/src/build.ts +165 -48
  39. package/src/cline-pass-model-id.ts +11 -0
  40. package/src/compat/anthropic.ts +15 -136
  41. package/src/compat/auth-ids.ts +157 -0
  42. package/src/compat/auth.ts +60 -0
  43. package/src/compat/axes.ts +290 -0
  44. package/src/compat/behavior.ts +207 -0
  45. package/src/compat/cascade.ts +230 -0
  46. package/src/{variant-collapse.ts → compat/collapse.ts} +381 -773
  47. package/src/compat/openai.ts +17 -848
  48. package/src/compat/resolve.ts +1229 -0
  49. package/src/compat/revision.ts +154 -0
  50. package/src/compat/rules/README.md +315 -0
  51. package/src/compat/rules/auth/_order.kdl +13 -0
  52. package/src/compat/rules/auth/abliteration.kdl +9 -0
  53. package/src/compat/rules/auth/aiand.kdl +9 -0
  54. package/src/compat/rules/auth/aimlapi.kdl +3 -0
  55. package/src/compat/rules/auth/alibaba-coding-plan.kdl +5 -0
  56. package/src/compat/rules/auth/alibaba-token-plan.kdl +11 -0
  57. package/src/compat/rules/auth/amazon-bedrock.kdl +5 -0
  58. package/src/compat/rules/auth/anthropic.kdl +53 -0
  59. package/src/compat/rules/auth/azure.kdl +3 -0
  60. package/src/compat/rules/auth/baseten.kdl +9 -0
  61. package/src/compat/rules/auth/bedrock-mantle.kdl +5 -0
  62. package/src/compat/rules/auth/cerebras.kdl +9 -0
  63. package/src/compat/rules/auth/cline-pass.kdl +12 -0
  64. package/src/compat/rules/auth/cloudflare-ai-gateway.kdl +4 -0
  65. package/src/compat/rules/auth/coreweave.kdl +9 -0
  66. package/src/compat/rules/auth/cursor.kdl +5 -0
  67. package/src/compat/rules/auth/deepinfra.kdl +11 -0
  68. package/src/compat/rules/auth/deepseek.kdl +10 -0
  69. package/src/compat/rules/auth/devin.kdl +28 -0
  70. package/src/compat/rules/auth/exa.kdl +9 -0
  71. package/src/compat/rules/auth/firepass.kdl +14 -0
  72. package/src/compat/rules/auth/fireworks.kdl +16 -0
  73. package/src/compat/rules/auth/github-copilot.kdl +7 -0
  74. package/src/compat/rules/auth/gitlab-duo-agent.kdl +23 -0
  75. package/src/compat/rules/auth/gitlab-duo.kdl +24 -0
  76. package/src/compat/rules/auth/gmi-cloud.kdl +9 -0
  77. package/src/compat/rules/auth/google-antigravity.kdl +28 -0
  78. package/src/compat/rules/auth/google-gemini-cli.kdl +26 -0
  79. package/src/compat/rules/auth/google-vertex.kdl +5 -0
  80. package/src/compat/rules/auth/google.kdl +3 -0
  81. package/src/compat/rules/auth/groq.kdl +3 -0
  82. package/src/compat/rules/auth/huggingface.kdl +9 -0
  83. package/src/compat/rules/auth/kagi.kdl +9 -0
  84. package/src/compat/rules/auth/kilo.kdl +4 -0
  85. package/src/compat/rules/auth/kimi-code.kdl +18 -0
  86. package/src/compat/rules/auth/litellm.kdl +8 -0
  87. package/src/compat/rules/auth/llama.cpp.kdl +10 -0
  88. package/src/compat/rules/auth/lm-studio.kdl +7 -0
  89. package/src/compat/rules/auth/meta.kdl +9 -0
  90. package/src/compat/rules/auth/minimax-code-cn.kdl +9 -0
  91. package/src/compat/rules/auth/minimax-code.kdl +9 -0
  92. package/src/compat/rules/auth/minimax.kdl +3 -0
  93. package/src/compat/rules/auth/mistral.kdl +3 -0
  94. package/src/compat/rules/auth/moonshot.kdl +9 -0
  95. package/src/compat/rules/auth/nanogpt.kdl +9 -0
  96. package/src/compat/rules/auth/novita.kdl +12 -0
  97. package/src/compat/rules/auth/nvidia.kdl +11 -0
  98. package/src/compat/rules/auth/ollama-cloud.kdl +8 -0
  99. package/src/compat/rules/auth/ollama.kdl +9 -0
  100. package/src/compat/rules/auth/openai-codex-device.kdl +20 -0
  101. package/src/compat/rules/auth/openai-codex.kdl +33 -0
  102. package/src/compat/rules/auth/openai.kdl +3 -0
  103. package/src/compat/rules/auth/opencode-go.kdl +10 -0
  104. package/src/compat/rules/auth/opencode-zen.kdl +9 -0
  105. package/src/compat/rules/auth/openrouter.kdl +32 -0
  106. package/src/compat/rules/auth/parallel.kdl +9 -0
  107. package/src/compat/rules/auth/perplexity.kdl +7 -0
  108. package/src/compat/rules/auth/qianfan.kdl +9 -0
  109. package/src/compat/rules/auth/qwen-portal.kdl +9 -0
  110. package/src/compat/rules/auth/sakana.kdl +9 -0
  111. package/src/compat/rules/auth/siliconflow-cn.kdl +9 -0
  112. package/src/compat/rules/auth/siliconflow.kdl +9 -0
  113. package/src/compat/rules/auth/synthetic.kdl +9 -0
  114. package/src/compat/rules/auth/tavily.kdl +9 -0
  115. package/src/compat/rules/auth/together.kdl +14 -0
  116. package/src/compat/rules/auth/umans.kdl +9 -0
  117. package/src/compat/rules/auth/venice.kdl +9 -0
  118. package/src/compat/rules/auth/vercel-ai-gateway.kdl +8 -0
  119. package/src/compat/rules/auth/vllm.kdl +9 -0
  120. package/src/compat/rules/auth/wafer-serverless.kdl +11 -0
  121. package/src/compat/rules/auth/xai-oauth.kdl +27 -0
  122. package/src/compat/rules/auth/xai.kdl +9 -0
  123. package/src/compat/rules/auth/xiaomi-token-plan-ams.kdl +9 -0
  124. package/src/compat/rules/auth/xiaomi-token-plan-cn.kdl +9 -0
  125. package/src/compat/rules/auth/xiaomi-token-plan-sgp.kdl +9 -0
  126. package/src/compat/rules/auth/xiaomi.kdl +6 -0
  127. package/src/compat/rules/auth/yolo-auto.kdl +11 -0
  128. package/src/compat/rules/auth/zai-coding-plan.kdl +29 -0
  129. package/src/compat/rules/auth/zai.kdl +9 -0
  130. package/src/compat/rules/auth/zenmux.kdl +9 -0
  131. package/src/compat/rules/auth/zhipu-coding-plan.kdl +9 -0
  132. package/src/compat/rules/classes/amazon.kdl +21 -0
  133. package/src/compat/rules/classes/anthropic.kdl +285 -0
  134. package/src/compat/rules/classes/baidu.kdl +9 -0
  135. package/src/compat/rules/classes/bytedance.kdl +9 -0
  136. package/src/compat/rules/classes/cohere.kdl +7 -0
  137. package/src/compat/rules/classes/deepseek.kdl +80 -0
  138. package/src/compat/rules/classes/gemini.kdl +107 -0
  139. package/src/compat/rules/classes/gemma.kdl +14 -0
  140. package/src/compat/rules/classes/glm.kdl +115 -0
  141. package/src/compat/rules/classes/gpt-oss.kdl +16 -0
  142. package/src/compat/rules/classes/kimi.kdl +113 -0
  143. package/src/compat/rules/classes/meta.kdl +15 -0
  144. package/src/compat/rules/classes/mimo.kdl +32 -0
  145. package/src/compat/rules/classes/minimax.kdl +79 -0
  146. package/src/compat/rules/classes/mistral.kdl +19 -0
  147. package/src/compat/rules/classes/openai.kdl +42 -0
  148. package/src/compat/rules/classes/qwen.kdl +72 -0
  149. package/src/compat/rules/classes/stepfun.kdl +10 -0
  150. package/src/compat/rules/classes/xai.kdl +45 -0
  151. package/src/compat/rules/providers/abliteration.kdl +8 -0
  152. package/src/compat/rules/providers/aiand.kdl +19 -0
  153. package/src/compat/rules/providers/aimlapi.kdl +24 -0
  154. package/src/compat/rules/providers/alibaba-coding-plan.kdl +20 -0
  155. package/src/compat/rules/providers/alibaba-token-plan.kdl +35 -0
  156. package/src/compat/rules/providers/amazon-bedrock.kdl +36 -0
  157. package/src/compat/rules/providers/anthropic.kdl +24 -0
  158. package/src/compat/rules/providers/azure.kdl +19 -0
  159. package/src/compat/rules/providers/baseten.kdl +19 -0
  160. package/src/compat/rules/providers/bedrock-mantle.kdl +15 -0
  161. package/src/compat/rules/providers/cerebras.kdl +19 -0
  162. package/src/compat/rules/providers/cline-pass.kdl +8 -0
  163. package/src/compat/rules/providers/cloudflare-ai-gateway.kdl +26 -0
  164. package/src/compat/rules/providers/coreweave.kdl +16 -0
  165. package/src/compat/rules/providers/cursor.kdl +52 -0
  166. package/src/compat/rules/providers/deepseek.kdl +21 -0
  167. package/src/compat/rules/providers/firepass.kdl +15 -0
  168. package/src/compat/rules/providers/fireworks.kdl +43 -0
  169. package/src/compat/rules/providers/github-copilot.kdl +62 -0
  170. package/src/compat/rules/providers/gitlab-duo.kdl +24 -0
  171. package/src/compat/rules/providers/gmi-cloud.kdl +8 -0
  172. package/src/compat/rules/providers/google-antigravity.kdl +59 -0
  173. package/src/compat/rules/providers/google-gemini-cli.kdl +12 -0
  174. package/src/compat/rules/providers/google-vertex.kdl +25 -0
  175. package/src/compat/rules/providers/google.kdl +17 -0
  176. package/src/compat/rules/providers/groq.kdl +8 -0
  177. package/src/compat/rules/providers/huggingface.kdl +24 -0
  178. package/src/compat/rules/providers/kilo.kdl +51 -0
  179. package/src/compat/rules/providers/kimi-code.kdl +37 -0
  180. package/src/compat/rules/providers/llama.cpp.kdl +6 -0
  181. package/src/compat/rules/providers/lm-studio.kdl +6 -0
  182. package/src/compat/rules/providers/meta.kdl +10 -0
  183. package/src/compat/rules/providers/minimax-code-cn.kdl +13 -0
  184. package/src/compat/rules/providers/minimax-code.kdl +13 -0
  185. package/src/compat/rules/providers/minimax.kdl +6 -0
  186. package/src/compat/rules/providers/mistral.kdl +8 -0
  187. package/src/compat/rules/providers/moonshot.kdl +36 -0
  188. package/src/compat/rules/providers/nanogpt.kdl +100 -0
  189. package/src/compat/rules/providers/novita.kdl +34 -0
  190. package/src/compat/rules/providers/nvidia.kdl +27 -0
  191. package/src/compat/rules/providers/ollama-cloud.kdl +20 -0
  192. package/src/compat/rules/providers/ollama.kdl +12 -0
  193. package/src/compat/rules/providers/openai-codex.kdl +121 -0
  194. package/src/compat/rules/providers/openai.kdl +82 -0
  195. package/src/compat/rules/providers/opencode-go.kdl +97 -0
  196. package/src/compat/rules/providers/opencode-zen.kdl +103 -0
  197. package/src/compat/rules/providers/openrouter.kdl +66 -0
  198. package/src/compat/rules/providers/qianfan.kdl +8 -0
  199. package/src/compat/rules/providers/sakana.kdl +10 -0
  200. package/src/compat/rules/providers/synthetic.kdl +16 -0
  201. package/src/compat/rules/providers/together.kdl +22 -0
  202. package/src/compat/rules/providers/umans.kdl +28 -0
  203. package/src/compat/rules/providers/venice.kdl +46 -0
  204. package/src/compat/rules/providers/vercel-ai-gateway.kdl +73 -0
  205. package/src/compat/rules/providers/vllm.kdl +8 -0
  206. package/src/compat/rules/providers/wafer-serverless.kdl +35 -0
  207. package/src/compat/rules/providers/xai-oauth.kdl +48 -0
  208. package/src/compat/rules/providers/xai.kdl +50 -0
  209. package/src/compat/rules/providers/xiaomi-token-plan-ams.kdl +9 -0
  210. package/src/compat/rules/providers/xiaomi-token-plan-cn.kdl +9 -0
  211. package/src/compat/rules/providers/xiaomi-token-plan-sgp.kdl +9 -0
  212. package/src/compat/rules/providers/xiaomi.kdl +22 -0
  213. package/src/compat/rules/providers/yolo-auto.kdl +16 -0
  214. package/src/compat/rules/providers/zai.kdl +36 -0
  215. package/src/compat/rules/providers/zenmux.kdl +108 -0
  216. package/src/compat/rules/providers/zhipu-coding-plan.kdl +49 -0
  217. package/src/compat/rules/runtime/behavior.kdl +254 -0
  218. package/src/compat/rules/taxonomy/_collapse.kdl +747 -0
  219. package/src/compat/rules/taxonomy/_discovery.kdl +60 -0
  220. package/src/compat/rules/taxonomy/ai21.kdl +6 -0
  221. package/src/compat/rules/taxonomy/amazon.kdl +8 -0
  222. package/src/compat/rules/taxonomy/anthropic.kdl +17 -0
  223. package/src/compat/rules/taxonomy/baidu.kdl +5 -0
  224. package/src/compat/rules/taxonomy/bytedance.kdl +5 -0
  225. package/src/compat/rules/taxonomy/cohere.kdl +6 -0
  226. package/src/compat/rules/taxonomy/deepseek.kdl +18 -0
  227. package/src/compat/rules/taxonomy/gemini.kdl +9 -0
  228. package/src/compat/rules/taxonomy/gemma.kdl +3 -0
  229. package/src/compat/rules/taxonomy/glm.kdl +17 -0
  230. package/src/compat/rules/taxonomy/gpt-oss.kdl +11 -0
  231. package/src/compat/rules/taxonomy/kimi.kdl +20 -0
  232. package/src/compat/rules/taxonomy/meta.kdl +10 -0
  233. package/src/compat/rules/taxonomy/mimo.kdl +7 -0
  234. package/src/compat/rules/taxonomy/minimax.kdl +9 -0
  235. package/src/compat/rules/taxonomy/mistral.kdl +7 -0
  236. package/src/compat/rules/taxonomy/openai.kdl +43 -0
  237. package/src/compat/rules/taxonomy/qwen.kdl +33 -0
  238. package/src/compat/rules/taxonomy/stepfun.kdl +5 -0
  239. package/src/compat/rules/taxonomy/unknown.kdl +3 -0
  240. package/src/compat/rules/taxonomy/xai.kdl +12 -0
  241. package/src/compat/rules.d.json.ts +5 -0
  242. package/src/compat/rules.json +16933 -0
  243. package/src/compat/taxonomy.ts +452 -0
  244. package/src/compat/types.ts +586 -0
  245. package/src/discovery/antigravity.ts +5 -6
  246. package/src/discovery/codex.ts +12 -7
  247. package/src/discovery/cursor-proto.ts +7 -7
  248. package/src/discovery/cursor.ts +53 -49
  249. package/src/discovery/devin-proto.ts +613 -0
  250. package/src/discovery/devin.ts +358 -52
  251. package/src/discovery/gemini-cli.ts +14 -11
  252. package/src/discovery/gemini.ts +2 -0
  253. package/src/identity/dialect.ts +2 -2
  254. package/src/identity/id.ts +12 -0
  255. package/src/identity/index.ts +3 -3
  256. package/src/identity/reference.ts +30 -4
  257. package/src/index.ts +1 -1
  258. package/src/model-manager.ts +4 -4
  259. package/src/model-thinking.ts +6 -807
  260. package/src/model-tokenizer.ts +37 -44
  261. package/src/models.json +118192 -44573
  262. package/src/models.ts +6 -1
  263. package/src/provider-models/bundled-references.ts +3 -1
  264. package/src/provider-models/cline-pass.ts +226 -0
  265. package/src/provider-models/descriptors.ts +18 -0
  266. package/src/provider-models/google.ts +14 -5
  267. package/src/provider-models/models-dev-policies.ts +4 -29
  268. package/src/provider-models/ollama.ts +15 -2
  269. package/src/provider-models/openai-compat.ts +827 -524
  270. package/src/provider-models/special.ts +186 -2
  271. package/src/types.ts +197 -11
  272. package/src/wire/cline-pass.ts +35 -0
  273. package/src/wire/devin-proto.ts +30 -0
  274. package/src/wire/devin.ts +72 -0
  275. package/src/wire/github-copilot.ts +49 -7
  276. package/dist/types/compat/bedrock.d.ts +0 -3
  277. package/dist/types/compat/devin.d.ts +0 -9
  278. package/dist/types/identity/classify.d.ts +0 -69
  279. package/dist/types/identity/family.d.ts +0 -243
  280. package/dist/types/identity/markers.d.ts +0 -4
  281. package/dist/types/openai-pricing.d.ts +0 -17
  282. package/src/compat/bedrock.ts +0 -153
  283. package/src/compat/devin.ts +0 -12
  284. package/src/identity/classify.ts +0 -242
  285. package/src/identity/family.ts +0 -496
  286. package/src/identity/markers.ts +0 -49
  287. package/src/openai-pricing.ts +0 -29
package/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.1.8] - 2026-09-04
6
+
7
+ - OMP sync v18.1.2–v18.1.5: declarative KDL auth contract compiler (`@bgotink/kdl` now a devDependency), provider auth definitions, and model-policy rule updates.
8
+ - Restored the biome toolchain for catalog scripts after the v18.1.5 merge briefly adopted the upstream oxlint/oxfmt configuration.
9
+
5
10
  ## [1.1.6] - 2026-08-30
6
11
 
7
12
  - 同步上游 OMP v18.0.9(`cc14e04f075d`)。
@@ -10,12 +15,6 @@
10
15
 
11
16
  - 同步上游 OMP v18.0.5 / v18.0.6:新增 DeepInfra / Yolo-Auto 提供商标识。
12
17
 
13
- ## [1.1.3] - 2026-08-25
14
-
15
- ### Fixed
16
-
17
- - Republished as 1.1.3 to reset the latest tag after the broken 1.1.2 (no functional change over 1.1.1).
18
-
19
18
  ## [1.1.2] - 2026-08-25
20
19
 
21
20
  ### Fixed
@@ -43,3 +42,8 @@
43
42
  ### Changed
44
43
 
45
44
  - Reset the version to 1.0.0 and republished under the `@linxiraos/*` scope, breaking from the `@linxiraos` version lineage.
45
+ - Bundled model metadata is prebuilt during generation, reducing catalog startup work.
46
+
47
+ ### Fixed
48
+
49
+ - Fixed tool-call turn failures for `opencode-go/muse-spark-1.2` and related variants by ensuring API transport pins apply to live discovery and automatically inferring response routes for gateway-first OpenCode models ([#8957](https://github.com/can1357/oh-my-pi/issues/8957)).
package/README.md CHANGED
@@ -9,25 +9,26 @@ Model catalog for [Zeta](https://github.com/Linxira-OS/linxira-zeta): bundled mo
9
9
  | `models.json` + `models` | Bundled model database (pricing, context windows, modalities, thinking support) |
10
10
  | `provider-models` | Provider catalog descriptors (`CATALOG_PROVIDERS`), per-provider model resolution rules |
11
11
  | `discovery` | Runtime model discovery for OpenAI-compatible endpoints, Gemini, Codex, Cursor, Antigravity, Ollama |
12
- | `identity` | Model id parsing and classification (family/version), reference resolution, equivalence, selection priority |
13
- | `model-thinking` | Thinking/reasoning metadata and generated per-model policies |
12
+ | `compat/rules` | Checked-in KDL policy tree: taxonomy (classes/families/revisions), class/provider cascade rules, runtime behavior vocabulary; compiled by `bun run gen:compat` into the committed `rules.json` |
13
+ | `compat` | The rule engine: `classifyModel` (taxonomy), `resolveModelPolicy` (cascade), behavior accessors (`api-routes`, `model-limits`, `exclude-models`, `pricing-peer`), collapse, and OpenAI/Anthropic wire builders that consume resolved records |
14
+ | `identity` | Mechanical id utilities: reference resolution against the bundled index, dialects, selection priority, tokenizer families |
15
+ | `model-thinking` | Runtime thinking helpers (`getSupportedEfforts`, effort clamping/mapping, wire-id routing) over resolved model records |
14
16
  | `model-manager` / `model-cache` | Runtime model registry with discovery refresh and on-disk caching |
15
- | `variant-collapse` | Collapsing provider-specific variants of the same underlying model |
16
- | `compat` | Request/response compatibility fixups for OpenAI- and Anthropic-shaped APIs |
17
17
  | `wire` | Wire-level helpers: Codex, Gemini headers, GitHub Copilot |
18
18
  | `effort` | Reasoning-effort level definitions |
19
19
 
20
20
  Import from subpaths (`@linxiraos/pi-catalog/<module>`) or the root barrel.
21
21
 
22
- ## models.json is generated
22
+ ## models.json and rules.json are generated
23
23
 
24
- Never edit `src/models.json` by hand — it is produced from upstream sources (stencil.so, provider catalog discovery, OpenCode docs) by `scripts/generate-models.ts` and the resolvers in `src/provider-models/`. Regenerate with:
24
+ Never edit `src/models.json` or `src/compat/rules.json` by hand. `models.json` is produced from upstream sources (stencil.so, provider catalog discovery, OpenCode docs) by `scripts/generate-models.ts`; `rules.json` is compiled from the KDL tree in `src/compat/rules/`. Regenerate with:
25
25
 
26
26
  ```sh
27
- bun run gen:models
27
+ bun run gen:compat # src/compat/rules/**/*.kdl -> src/compat/rules.json
28
+ bun run gen:models # upstream sources + rules -> src/models.json
28
29
  ```
29
30
 
30
- To change an entry, fix the source: resolver overrides in `provider-models/openai-compat.ts`, provider entries in `provider-models/descriptors.ts`, generator fixups in `scripts/generate-models.ts`, or thinking policies in `model-thinking.ts`.
31
+ Model- or provider-conditional policy (identity, effort ladders, wire quirks, modality/limit/pricing corrections, API routing, roster exclusions) lives in the KDL tree — see `src/compat/rules/README.md` for the grammar and axis vocabulary. TypeScript changes are only for transport mechanics: provider entries in `provider-models/descriptors.ts`, discovery/request plumbing in `provider-models/openai-compat.ts`, and generator wiring in `scripts/generate-models.ts`. Commit `rules.json` (and a rebaked `models.json` when values change) alongside the `.kdl` edit.
31
32
 
32
33
  ## Install
33
34
 
@@ -1,19 +1,24 @@
1
1
  /**
2
- * The single Model constructor. Resolution order is a dependency chain, each
3
- * step materialized exactly once per spec:
4
- *
5
- * 1. compat — URL/provider/id detection resolved into a complete record;
6
- * 2. thinking — derived from identity + resolved compat (or trusted verbatim
7
- * when the spec carries explicit metadata);
2
+ * The single Model constructor. Resolution runs through the compat engine
3
+ * (`compat/resolve`): identity classification, cascade-rule axes, host
4
+ * detection, and spec overrides materialize exactly once per spec.
8
5
  *
9
6
  * Request handlers read fields — they never detect, parse ids, or allocate
10
7
  * compat per request.
11
8
  */
12
- import type { Api, CompatOf, Model, ModelSpec } from "./types.js";
9
+ import type { Api, Model, ModelSpec } from "./types.js";
10
+ /**
11
+ * Applies reviewed catalog-data value corrections (`cost-patch`,
12
+ * `limits-patch`, `long-context-cost`, `context-window-floor`,
13
+ * `input-modalities`) onto an upstream-sourced spec. Applied by
14
+ * `buildModel` to every upstream-sourced spec; user-authored overrides are
15
+ * recomposed after building by the override applicators, so explicit user
16
+ * limits and pricing still win.
17
+ */
18
+ export declare function applyCatalogCorrections(model: Pick<ModelSpec<Api>, "cost" | "contextWindow" | "maxTokens" | "input">, catalog: Record<string, unknown>): void;
13
19
  /**
14
20
  * Build one model from an authored spec. Bundled models.json rows are fully
15
21
  * materialized by the generator and consumed directly (see `models.ts`), so
16
22
  * this only runs for discovered/custom/override specs.
17
23
  */
18
24
  export declare function buildModel<TApi extends Api>(spec: ModelSpec<TApi>): Model<TApi>;
19
- export declare function buildCompat(spec: ModelSpec<Api>): CompatOf<Api>;
@@ -0,0 +1,4 @@
1
+ /** Convert a public ClinePass catalog id to the gateway's wire id. */
2
+ export declare function toClinePassWireModelId(modelId: string): string;
3
+ /** Convert a gateway ClinePass wire id to the public catalog id. */
4
+ export declare function toClinePassPublicModelId(modelId: string): string;
@@ -1,4 +1,3 @@
1
- import type { ModelSpec, ResolvedAnthropicCompat } from "../types.js";
2
1
  /**
3
2
  * Official first-party Anthropic API. A missing baseUrl is official on purpose:
4
3
  * request dispatch falls back to `https://api.anthropic.com`. This is the one
@@ -8,11 +7,18 @@ import type { ModelSpec, ResolvedAnthropicCompat } from "../types.js";
8
7
  */
9
8
  export declare function isOfficialAnthropicApiUrl(baseUrl?: string): boolean;
10
9
  /**
11
- * Known non-official URLs that enforce Anthropic thinking signatures on replay.
10
+ * Azure AI Inference / Foundry Anthropic route
11
+ * (`<resource>.inference.ai.azure.com`, `<resource>.services.ai.azure.com`).
12
+ * Fronts Claude behind Azure identity and enforces Anthropic signatures on
13
+ * replay; it also rejects the top-level `strict` tool field.
14
+ */
15
+ export declare function isAzureAnthropicRoute(baseUrl?: string): boolean;
16
+ /**
17
+ * Known non-official URLs that enforce Anthropic thinking signatures on replay
18
+ * (GitHub Copilot, ZenMux, Cloudflare AI Gateway `/anthropic`, Google Vertex
19
+ * `publishers/anthropic`, AWS Bedrock, Azure Foundry).
12
20
  *
13
21
  * Runtime routing calls this with the effective URL because a model's resolved
14
22
  * compat can be stale after Foundry or a provider base-URL override reroutes it.
15
23
  */
16
24
  export declare function isAnthropicSigningProxyUrl(baseUrl?: string): boolean;
17
- /** Build the resolved anthropic-messages compat record for a model spec. */
18
- export declare function buildAnthropicCompat(spec: ModelSpec<"anthropic-messages">): ResolvedAnthropicCompat;
@@ -0,0 +1,4 @@
1
+ /** Every provider with an `auth/<id>.kdl` policy. */
2
+ export type AuthProviderId = "abliteration" | "aiand" | "aimlapi" | "alibaba-coding-plan" | "alibaba-token-plan" | "amazon-bedrock" | "anthropic" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "cline-pass" | "cloudflare-ai-gateway" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "huggingface" | "kagi" | "kilo" | "kimi-code" | "litellm" | "llama.cpp" | "lm-studio" | "meta" | "minimax" | "minimax-code" | "minimax-code-cn" | "mistral" | "moonshot" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sakana" | "siliconflow" | "siliconflow-cn" | "synthetic" | "tavily" | "together" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zai-coding-plan" | "zenmux" | "zhipu-coding-plan";
3
+ /** Providers whose policy declares a `login` flow (the `/login` roster). */
4
+ export type LoginProviderId = "abliteration" | "aiand" | "alibaba-coding-plan" | "alibaba-token-plan" | "anthropic" | "baseten" | "cerebras" | "cline-pass" | "cloudflare-ai-gateway" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google-antigravity" | "google-gemini-cli" | "huggingface" | "kagi" | "kilo" | "kimi-code" | "litellm" | "llama.cpp" | "lm-studio" | "meta" | "minimax-code" | "minimax-code-cn" | "moonshot" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sakana" | "siliconflow" | "siliconflow-cn" | "synthetic" | "tavily" | "together" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zai-coding-plan" | "zenmux" | "zhipu-coding-plan";
@@ -0,0 +1,7 @@
1
+ import type { CompiledAuthProvider } from "./types.js";
2
+ /** Every compiled auth provider in `/login` display order. */
3
+ export declare function authProviders(): readonly CompiledAuthProvider[];
4
+ /** The compiled auth policy for one provider id, if declared. */
5
+ export declare function authPolicyFor(provider: string): CompiledAuthProvider | undefined;
6
+ /** Every hook name referenced anywhere in the auth stratum, for registry completeness checks. */
7
+ export declare function authHookNames(): Record<string, string[]>;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The closed compat-axis vocabulary: every KDL cascade directive, the resolved
3
+ * camelCase field it assigns, its value shape, and — for wire axes — the
4
+ * compat records it applies to.
5
+ *
6
+ * Single source of truth shared by the compile-time rule compiler
7
+ * (`scripts/compat-compiler`) and the runtime engine (`./resolve`). The
8
+ * compiler rejects any directive absent from this table; the runtime assigns
9
+ * a wire axis onto a model's compat record only when the model's API maps to
10
+ * one of the axis's declared records.
11
+ */
12
+ import type { Effort } from "../effort.js";
13
+ import type { ThinkingControlMode } from "../types.js";
14
+ /** Value shape a directive accepts (see `rules/README.md`). */
15
+ export type AxisShape = "scalar" | "array" | "object";
16
+ /** Axis namespace: request-wire compat, thinking control surface, or catalog metadata. */
17
+ export type AxisSet = "wire" | "thinking" | "catalog";
18
+ /** Resolved compat record families a wire axis may be assigned onto. */
19
+ export type CompatRecordName = "openai" | "openai-responses" | "anthropic" | "bedrock" | "devin" | "google";
20
+ /** One axis definition: resolved key, namespace, shape, and applicability. */
21
+ export interface AxisDef {
22
+ /** Resolved camelCase field the directive assigns. */
23
+ key: string;
24
+ set: AxisSet;
25
+ shape: AxisShape;
26
+ /** Wire axes only: records this key exists on. */
27
+ records?: readonly CompatRecordName[];
28
+ /** Closed value vocabulary for string scalars / string arrays. */
29
+ values?: readonly string[];
30
+ /**
31
+ * Object axes only: payload child names are literal wire JSON keys copied
32
+ * verbatim (`extra-body`). Default object payloads author kebab-case names
33
+ * that compile to camelCase resolved keys.
34
+ */
35
+ verbatimKeys?: true;
36
+ }
37
+ /** Effort tiers accepted by taxonomy collapse/override vocabulary (`Effort` ∪ `"off"`). */
38
+ export declare const EFFORT_TIERS: readonly string[];
39
+ /** Narrow a KDL string to an effort tier (`Effort` ∪ `"off"`). */
40
+ export declare function isEffortTier(value: string): value is Effort | "off";
41
+ /** Narrow a KDL string to a thinking control mode. */
42
+ export declare function isThinkingMode(value: string): value is ThinkingControlMode;
43
+ /**
44
+ * KDL directive → axis definition. Keys are the kebab-case directive
45
+ * spellings accepted inside `classes/*.kdl` and `providers/*.kdl` rule
46
+ * blocks.
47
+ */
48
+ export declare const AXES: Readonly<Record<string, AxisDef>>;
49
+ /** Records applicable to each API family; used by `resolve.ts` when applying wire axes. */
50
+ export declare const API_COMPAT_RECORDS: Readonly<Record<string, readonly CompatRecordName[]>>;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Conservative heuristic for a normalized, lowercase discovered model id with
3
+ * no exact bundled record: whether it likely rides the OpenAI Responses API.
4
+ */
5
+ export declare function isLikelyOpenAIResponsesId(model: string): boolean;
6
+ /**
7
+ * Additional catalog-declared operations for a discovered provider/model pair
8
+ * (e.g. `generate_image`), augmenting provider discovery metadata.
9
+ */
10
+ export declare function modelOperationOverrides(provider: string, model: string): readonly string[];
11
+ /**
12
+ * Splits a Cursor effort-suffixed OpenAI sibling id into its base id and
13
+ * declared effort tier. The family gate requires the declared marker
14
+ * (`gpt-`) followed immediately by an ASCII digit; matching stays
15
+ * case-sensitive to preserve Cursor wire-id behavior.
16
+ */
17
+ export declare function cursorEffortSuffix(model: string): {
18
+ base: string;
19
+ tier: string;
20
+ } | undefined;
21
+ /** Fixed Cursor `requestedModel` parameters declared for an exact wire model. */
22
+ export declare function cursorModelParameters(model: string): readonly {
23
+ id: string;
24
+ value: string;
25
+ }[];
26
+ /**
27
+ * The catalog-declared quota scope or display tier for a provider model id.
28
+ * Exact authored memberships win; provider-authored substring fallbacks
29
+ * preserve quota semantics for newly discovered ids.
30
+ */
31
+ export declare function quotaTierFor(provider: string, model: string): string | undefined;
32
+ /** Whether a provider has catalog-authored model quota scopes. */
33
+ export declare function hasQuotaTierPolicy(provider: string): boolean;
34
+ /** The provider-default wire model for a model-less hosted operation. */
35
+ export declare function hostedDefaultModel(provider: string): string | undefined;
36
+ /** One resolved API route for a provider model id. */
37
+ export interface ApiRouteMatch {
38
+ /** Transport API the id rides. */
39
+ api: string;
40
+ /** Wire id after prefix stripping, when the route declares `strip-prefix`. */
41
+ requestModelId?: string;
42
+ }
43
+ /**
44
+ * Resolves the declared API route for a provider model id. Routes match in
45
+ * declaration order; a `strip-prefix` route with a prefix matcher strips the
46
+ * matched prefix off the wire id. Falls back to the node's `default` API.
47
+ */
48
+ export declare function apiRouteFor(provider: string, model: string): ApiRouteMatch | undefined;
49
+ /** Exact model ids named by a provider's api-routes rules (cache-migration drop lists). */
50
+ export declare function apiRouteExactModelIds(provider: string): string[];
51
+ /** Declared context-window / max-token pins for a provider model id. */
52
+ export declare function modelLimitsFor(provider: string, model: string): {
53
+ context?: number;
54
+ maxTokens?: number;
55
+ } | undefined;
56
+ /** Whether a provider roster entry is a declared non-chat/unsupported SKU. */
57
+ export declare function isExcludedModel(provider: string, model: string): boolean;
58
+ /**
59
+ * Whether a provider is retired: its entire roster is excluded from the
60
+ * generated bundle and must never be resurrected from the previous snapshot.
61
+ */
62
+ export declare function isRetiredProvider(provider: string): boolean;
63
+ /** The declared subscription tier required to use a provider model id, if any. */
64
+ export declare function planRequirementFor(provider: string, model: string): string | undefined;
65
+ /** Cross-provider pricing-peer resolution for one provider model id. */
66
+ export declare function pricingPeerFor(provider: string, model: string): {
67
+ peers: readonly string[];
68
+ peerId: string;
69
+ } | undefined;
@@ -0,0 +1,37 @@
1
+ import type { CompiledCascade, ResolvedAxes, ResolveTarget } from "./types.js";
2
+ /**
3
+ * Two equal-rank rules contest one axis for a target. CI-time for bundled
4
+ * targets (the parity sweep exercises every catalog row); fix with an
5
+ * explicit `priority=` in the KDL, never in code.
6
+ */
7
+ export declare class AmbiguousOverlapError extends Error {
8
+ readonly provider: string;
9
+ readonly model: string;
10
+ readonly axis: string;
11
+ readonly first: string;
12
+ readonly second: string;
13
+ constructor(provider: string, model: string, axis: string, first: string, second: string);
14
+ }
15
+ /**
16
+ * Anchored `*`-wildcard match; both sides must be pre-lowercased. `*` spans
17
+ * any substring; non-wildcard text stays anchored in order.
18
+ */
19
+ export declare function globMatch(pattern: string, value: string): boolean;
20
+ /**
21
+ * Resolves wire, thinking, and catalog assignments for one structured target.
22
+ *
23
+ * Thinking axes are gated on `target.reasoning`, except that an exact model
24
+ * selector declaring `thinking-efforts` upgrades the target (a reviewed
25
+ * correction to stale capability metadata). Family and revision selectors
26
+ * never match targets missing that identity rank. Unmatched targets resolve
27
+ * to empty maps.
28
+ *
29
+ * @throws AmbiguousOverlapError when two equal-rank rules contest one axis.
30
+ */
31
+ export declare function resolveCascade(target: ResolveTarget): ResolvedAxes;
32
+ /**
33
+ * Resolves a target against an arbitrary compiled cascade (test seam and
34
+ * scratch evaluations); `resolveCascade` delegates here with the bundled
35
+ * rule index.
36
+ */
37
+ export declare function resolveCascadeRules(cascade: CompiledCascade, target: ResolveTarget): ResolvedAxes;
@@ -1,5 +1,6 @@
1
- import { Effort } from "./effort.js";
2
- import type { Api, Model, ModelSpec, Provider, ThinkingConfig } from "./types.js";
1
+ import { Effort } from "../effort.js";
2
+ import type { Api, Model, ModelSpec, Provider, ThinkingConfig } from "../types.js";
3
+ import { type RevisionTerm } from "./revision.js";
3
4
  /**
4
5
  * Structural bound for collapse inputs: both raw `ModelSpec`s and built
5
6
  * `Model`s qualify. (`Model.compat` is the resolved record, not the sparse
@@ -45,8 +46,14 @@ export interface EffortVariantFamily {
45
46
  * efforts fall back to `requestModelId ?? id`.
46
47
  */
47
48
  routing: Readonly<Partial<Record<Effort | "off", string>>>;
48
- /** Explicit capability surface for the collapsed spec — no inference. */
49
- thinking: Readonly<Omit<ThinkingConfig, "effortRouting" | "suppressWhenOff">>;
49
+ /**
50
+ * Explicit capability surface for the collapsed spec — no inference. Omit
51
+ * for single-wire-id renames on providers where effort is encoded in the
52
+ * upstream id itself (Devin): with one member and no routing there is no
53
+ * controllable surface, and the collapsed spec must carry no thinking
54
+ * rather than an effort ladder whose every tier resolves to one wire id.
55
+ */
56
+ thinking?: Readonly<Omit<ThinkingConfig, "effortRouting" | "suppressWhenOff">>;
50
57
  /** Thinking-off requests must explicitly suppress thinking on the wire. */
51
58
  suppressWhenOff?: boolean;
52
59
  /**
@@ -59,18 +66,42 @@ export interface EffortVariantFamily {
59
66
  /** Retired/recycled selector ids that alias to this family without being members. */
60
67
  extraAliases?: readonly string[];
61
68
  }
69
+ /**
70
+ * A reviewed family whose ids carry {@link REVISION_PLACEHOLDER}: one
71
+ * `gemini-{rev}-flash` entry stands for every Flash generation the provider
72
+ * serves with the same sibling layout. Concrete families with the same
73
+ * instantiated id take precedence.
74
+ */
75
+ export interface VariantFamilyTemplate {
76
+ /** Family with placeholders still in every id and the display name. */
77
+ family: EffortVariantFamily;
78
+ /** Revisions the template applies to; unbounded when absent. */
79
+ revision?: readonly RevisionTerm[];
80
+ /**
81
+ * Matches the logical id, any member, or any extra alias (case-insensitive);
82
+ * one alternative per id, each capturing the revision.
83
+ */
84
+ pattern: RegExp;
85
+ }
62
86
  export interface VariantCollapseTable {
63
87
  families: readonly EffortVariantFamily[];
88
+ /** Revision-templated families, instantiated against live ids. */
89
+ templates?: readonly VariantFamilyTemplate[];
90
+ /**
91
+ * Provider-scoped selector aliases: short native-CLI names and dotted
92
+ * upstream spellings → logical model id. Unlike family members and
93
+ * `extraAliases` these are deliberately invisible to the bare-id lookup
94
+ * ({@link resolveBareVariantSelector}) and to the reverse index — a generic
95
+ * label like `gpt` or `opus` only means something once a provider is
96
+ * named, and must never hijack an unqualified selector or re-key config.
97
+ */
98
+ providerAliases?: Readonly<Record<string, string>>;
64
99
  }
65
- /** `google-antigravity` Gemini families, using each generation's native transport. */
66
- export declare const ANTIGRAVITY_VARIANT_COLLAPSE_TABLE: VariantCollapseTable;
67
- /** `google-gemini-cli` Gemini families on the official CLI's level transport. */
68
- export declare const GEMINI_CLI_VARIANT_COLLAPSE_TABLE: VariantCollapseTable;
69
- export declare const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable;
70
- /** `cursor` per-effort sibling families collapsed per service-tier lane: Grok 4.5/4.6 plus GPT-5.6 Luna/Sol/Terra. */
71
- export declare const CURSOR_VARIANT_COLLAPSE_TABLE: VariantCollapseTable;
72
- /** Provider id → hand collapse table. The CCA providers diverge on thinking transport. */
73
- export declare const VARIANT_COLLAPSE_TABLES: Readonly<Record<string, VariantCollapseTable>>;
100
+ /**
101
+ * Return the reviewed collapse table compiled for `provider`, when declared.
102
+ * Discovery uses this accessor to preserve injectable table seams.
103
+ */
104
+ export declare function reviewedCollapseTable(provider: string): VariantCollapseTable | undefined;
74
105
  /**
75
106
  * The global automatic rule: derive an `X` + `X-thinking` family for every
76
107
  * pair where both ids are live in `specs` (trailing or infix token). Gates:
@@ -78,35 +109,31 @@ export declare const VARIANT_COLLAPSE_TABLES: Readonly<Record<string, VariantCol
78
109
  * - known pricing must match — all-zero cost rows count as unknown
79
110
  * (aggregators routinely ship them), but twins that BOTH carry real,
80
111
  * differing prices are distinct SKUs and never merge,
81
- * - ids claimed by the provider's hand `table` are skipped (curation wins).
112
+ * - ids claimed by the provider's reviewed table are skipped (curation wins).
82
113
  * The capability surface prefers the thinking member's metadata, then the
83
114
  * bare member's, then the canonical deriver (aggregators often ship
84
115
  * `reasoning: false` and no thinking config on the twin), then a budget
85
116
  * default. `off` routes to the bare id; every supported effort routes to the
86
117
  * thinking id.
87
118
  */
88
- export declare function deriveThinkingPairFamilies<TSpec extends VariantSpecLike>(specs: readonly TSpec[], table?: VariantCollapseTable): EffortVariantFamily[];
119
+ export declare function deriveThinkingPairFamilies<TSpec extends VariantSpecLike>(specs: readonly TSpec[], table?: VariantCollapseTable, provider?: string): EffortVariantFamily[];
89
120
  /**
90
121
  * True when `spec` is the output of collapsing rather than a raw upstream
91
122
  * member. `thinking.effortRouting` is written only by collapsing; the
92
- * `requestModelId` arm is scoped to the provider's hand-table family ids so
123
+ * `requestModelId` arm is scoped to the provider's reviewed-table family ids so
93
124
  * unrelated carriers (GitHub Copilot `-1m` context variants) never match.
94
125
  */
95
- export declare function isVariantCollapsedSpec(spec: VariantSpecLike): boolean;
96
- /**
97
- * Collapse every family in `table` found in `specs`. Non-member specs pass
98
- * through verbatim (by reference), order preserved; the collapsed spec
99
- * replaces the first occurrence of its family.
100
- */
101
- export declare function collapseEffortVariants<TSpec extends VariantSpecLike>(specs: readonly TSpec[], table: VariantCollapseTable): TSpec[];
126
+ export declare function isCollapsedVariantSpec(spec: VariantSpecLike): boolean;
102
127
  /**
103
- * Collapse a full mixed-provider list: per provider, the hand table, Cursor's
128
+ * Collapse a full mixed-provider list: per provider, the compiled reviewed table, Cursor's
104
129
  * conservative live effort-sibling rule, and the automatic `X`/`X-thinking`
105
130
  * pair rule. Used by the catalog generator; the runtime equivalent lives at
106
131
  * the model-manager merge point. Output is regrouped by provider — callers
107
132
  * re-sort.
108
133
  */
109
- export declare function collapseEffortVariantsAcrossProviders<TSpec extends VariantSpecLike>(specs: readonly TSpec[]): TSpec[];
134
+ export declare function collapseVariants<TSpec extends VariantSpecLike>(specs: readonly TSpec[], opts?: {
135
+ table?: VariantCollapseTable;
136
+ }): TSpec[];
110
137
  /**
111
138
  * Runtime entry point for already-built `Model` lists (the model-manager
112
139
  * merge point, coding-agent registry custom providers): collapses hand
@@ -114,16 +141,14 @@ export declare function collapseEffortVariantsAcrossProviders<TSpec extends Vari
114
141
  * logical specs so thinking wire defaults stay resolved. Untouched entries
115
142
  * pass through by reference.
116
143
  */
117
- export declare function collapseBuiltModelVariants<TApi extends Api>(models: readonly Model<TApi>[]): Model<TApi>[];
144
+ export declare function collapseBuiltVariants<TApi extends Api>(models: readonly Model<TApi>[]): Model<TApi>[];
118
145
  /**
119
- * Resolve a retired effort-tier variant id (collapsed member, recycled id) to
120
- * its replacement model id for `provider` via hand-table or registered live
121
- * aliases. Returns `undefined` when the id is not a known alias; derived
122
- * `X-thinking` members also resolve through `stripThinkingVariantToken`.
123
- * Callers must try an exact model lookup first — a live model always wins over
124
- * an alias.
146
+ * Resolve a retired effort-tier variant id, registered live alias, or
147
+ * provider-scoped native alias to its replacement model id for `provider`.
148
+ * Returns `undefined` when the id is unknown. Callers must try an exact model
149
+ * lookup first because a live model always wins over an alias.
125
150
  */
126
- export declare function resolveVariantAlias(provider: Provider, modelId: string): string | undefined;
151
+ export declare function resolveVariantSelector(provider: Provider, modelId: string): string | undefined;
127
152
  /** Bare-id alias hit: replacement id plus the providers declaring it. */
128
153
  export interface BareVariantAliasHit {
129
154
  id: string;
@@ -136,10 +161,10 @@ export interface BareVariantAliasHit {
136
161
  * on unrelated providers too (e.g. a retired Cursor tier id must not resolve
137
162
  * to `openai/gpt-5.4`).
138
163
  */
139
- export declare function resolveBareVariantAlias(modelId: string): BareVariantAliasHit | undefined;
164
+ export declare function resolveBareVariantSelector(modelId: string): BareVariantAliasHit | undefined;
140
165
  /**
141
166
  * Reverse alias lookup: the retired ids that resolve to `modelId` for
142
- * `provider` via hand-table or registered live aliases. Used to re-key config
167
+ * `provider` via reviewed-table or registered live aliases. Used to re-key config
143
168
  * keyed by raw member ids (models.yml `modelOverrides`, suppressed selectors)
144
169
  * onto the collapsed model.
145
170
  */
@@ -1,28 +1,9 @@
1
- import type { ModelSpec, OpenAICompat, ResolvedOpenAICompat, ResolvedOpenAIResponsesCompat, ResolvedOpenRouterCompat } from "../types.js";
2
- /** Wire effort remap for first-party xAI Responses. */
3
- export declare function xaiResponsesReasoningEffortMap(modelId: string): NonNullable<OpenAICompat["reasoningEffortMap"]>;
4
- /**
5
- * Build the resolved chat-completions compat record for a model spec.
6
- * Provider takes precedence over URL-based detection since it's explicitly configured.
7
- */
8
- export declare function buildOpenAICompat(spec: ModelSpec<"openai-completions">): ResolvedOpenAICompat;
9
- interface OpenAIResponsesSpecLike {
10
- id?: string;
11
- provider: string;
12
- name: string;
13
- baseUrl: string;
14
- reasoning?: boolean;
15
- compat?: OpenAICompat;
16
- }
17
1
  /**
18
- * Build the resolved Responses-API compat record. Most shared OpenAI-compatible
19
- * capability defaults intentionally mirror chat-completions, while Responses-
20
- * only behavior (developer role, prompt cache, pairing strictness, image detail)
21
- * keeps endpoint-specific detection. Azure is detected by provider id as well
22
- * as URL — bundled `azure` models carry no baseUrl (the deployment host is per-
23
- * resource, resolved at runtime) — while OpenAI/Copilot developer-role and
24
- * prompt-cache detection stay URL-keyed, as the historical call sites were.
2
+ * OpenAI-side compat residue: the first-party xAI Responses effort remap used
3
+ * by the xai-oauth discovery mapper when curating sparse rows. Everything else
4
+ * that lived here (the chat-completions/Responses compat builders) moved into
5
+ * the compat engine (`./resolve`) and the KDL rules.
25
6
  */
26
- export declare function buildOpenAIResponsesCompat(spec: OpenAIResponsesSpecLike): ResolvedOpenAIResponsesCompat;
27
- export declare function buildOpenRouterCompat(spec: ModelSpec<"openrouter">): ResolvedOpenRouterCompat;
28
- export {};
7
+ import type { OpenAICompat } from "../types.js";
8
+ /** Wire effort remap for first-party xAI Responses. */
9
+ export declare function xaiResponsesReasoningEffortMap(modelId: string): NonNullable<OpenAICompat["reasoningEffortMap"]>;
@@ -0,0 +1,15 @@
1
+ import type { Api, CompatOf, ModelSpec, ThinkingConfig } from "../types.js";
2
+ import type { ModelIdentity } from "./types.js";
3
+ /** Result of resolving one model spec through the compat engine. */
4
+ export interface ResolvedModelPolicy<TApi extends Api = Api> {
5
+ identity: ModelIdentity;
6
+ compat: CompatOf<TApi>;
7
+ thinking: ThinkingConfig | undefined;
8
+ /** Catalog-data axis assignments (longContext, priority, …) for generation. */
9
+ catalog: Record<string, unknown>;
10
+ }
11
+ /**
12
+ * Resolves the full policy surface for one model spec: structured identity,
13
+ * complete compat record, thinking metadata, and catalog-data corrections.
14
+ */
15
+ export declare function resolveModelPolicy<TApi extends Api>(spec: ModelSpec<TApi>): ResolvedModelPolicy<TApi>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Revision triples (`major.minor.patch`) extracted from model identifiers.
3
+ *
4
+ * The compat engine compares revisions as three unsigned 8-bit components;
5
+ * omitted components are zero (`4.6` ≡ `4.6.0`). Shared by the compile-time
6
+ * rule compiler and the runtime taxonomy/cascade.
7
+ */
8
+ /** A parsed `major.minor.patch` revision. */
9
+ export type Revision = readonly [number, number, number];
10
+ /**
11
+ * Parses an explicit revision literal: one to three components separated by
12
+ * `.` or `-` (`"4.6"`, `"4-6-1"`). Returns undefined on malformed input.
13
+ */
14
+ export declare function parseRevision(value: string): Revision | undefined;
15
+ /**
16
+ * Extracts a leading revision from an identifier tail that begins with a
17
+ * digit: up to three components separated by `.` or by `-` followed by a
18
+ * digit (`"4-6-turbo"` → `[4, 6, 0]`). Mirrors o2 `parse_revision_prefix`.
19
+ * A component whose digits run directly into a letter is a parameter-count
20
+ * or size token (`qwen3-32b`, `llama-3.3-70b`), never a revision component.
21
+ */
22
+ export declare function parseRevisionPrefix(value: string): Revision | undefined;
23
+ /** Lexicographic triple comparison: negative, zero, or positive. */
24
+ export declare function compareRevision(a: Revision, b: Revision): number;
25
+ /** Renders a revision as its canonical `major.minor.patch` string. */
26
+ export declare function formatRevision(revision: Revision): string;
27
+ /** Comparison operator inside a `revision ">=2.5 <4"` cascade constraint. */
28
+ export type RevisionOp = ">=" | ">" | "<=" | "<" | "=";
29
+ /** One comparison term of a revision constraint conjunction. */
30
+ export interface RevisionTerm {
31
+ op: RevisionOp;
32
+ revision: Revision;
33
+ }
34
+ /** Whether `revision` satisfies every term of the conjunction. */
35
+ export declare function revisionSatisfies(revision: Revision, terms: readonly RevisionTerm[]): boolean;
36
+ /**
37
+ * Parses a whitespace-separated conjunction of comparisons
38
+ * (`">=2.5 <3.8"`). Operands allow one to three dot-separated components.
39
+ * Returns undefined when empty or malformed.
40
+ */
41
+ export declare function parseRevisionConstraint(expression: string): RevisionTerm[] | undefined;