@linxiraos/pi-catalog 1.1.7 → 1.1.9

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 (308) hide show
  1. package/CHANGELOG.md +7 -8
  2. package/README.md +9 -8
  3. package/package.json +96 -100
  4. package/src/build.ts +165 -48
  5. package/src/cline-pass-model-id.ts +11 -0
  6. package/src/compat/anthropic.ts +15 -136
  7. package/src/compat/auth-ids.ts +157 -0
  8. package/src/compat/auth.ts +60 -0
  9. package/src/compat/axes.ts +301 -0
  10. package/src/compat/behavior.ts +207 -0
  11. package/src/compat/cascade.ts +230 -0
  12. package/src/{variant-collapse.ts → compat/collapse.ts} +381 -773
  13. package/src/compat/delegation.ts +37 -0
  14. package/src/compat/openai.ts +17 -848
  15. package/src/compat/resolve.ts +1231 -0
  16. package/src/compat/revision.ts +154 -0
  17. package/src/compat/rules/README.md +315 -0
  18. package/src/compat/rules/auth/_order.kdl +13 -0
  19. package/src/compat/rules/auth/abliteration.kdl +9 -0
  20. package/src/compat/rules/auth/aiand.kdl +9 -0
  21. package/src/compat/rules/auth/aimlapi.kdl +3 -0
  22. package/src/compat/rules/auth/alibaba-coding-plan.kdl +5 -0
  23. package/src/compat/rules/auth/alibaba-token-plan.kdl +11 -0
  24. package/src/compat/rules/auth/amazon-bedrock.kdl +5 -0
  25. package/src/compat/rules/auth/anthropic.kdl +53 -0
  26. package/src/compat/rules/auth/azure.kdl +3 -0
  27. package/src/compat/rules/auth/baseten.kdl +9 -0
  28. package/src/compat/rules/auth/bedrock-mantle.kdl +5 -0
  29. package/src/compat/rules/auth/cerebras.kdl +9 -0
  30. package/src/compat/rules/auth/cline-pass.kdl +12 -0
  31. package/src/compat/rules/auth/cloudflare-ai-gateway.kdl +4 -0
  32. package/src/compat/rules/auth/coreweave.kdl +9 -0
  33. package/src/compat/rules/auth/cursor.kdl +5 -0
  34. package/src/compat/rules/auth/deepinfra.kdl +11 -0
  35. package/src/compat/rules/auth/deepseek.kdl +10 -0
  36. package/src/compat/rules/auth/devin.kdl +28 -0
  37. package/src/compat/rules/auth/exa.kdl +9 -0
  38. package/src/compat/rules/auth/firepass.kdl +14 -0
  39. package/src/compat/rules/auth/fireworks.kdl +16 -0
  40. package/src/compat/rules/auth/github-copilot.kdl +7 -0
  41. package/src/compat/rules/auth/gitlab-duo-agent.kdl +23 -0
  42. package/src/compat/rules/auth/gitlab-duo.kdl +24 -0
  43. package/src/compat/rules/auth/gmi-cloud.kdl +9 -0
  44. package/src/compat/rules/auth/google-antigravity.kdl +28 -0
  45. package/src/compat/rules/auth/google-gemini-cli.kdl +26 -0
  46. package/src/compat/rules/auth/google-vertex.kdl +5 -0
  47. package/src/compat/rules/auth/google.kdl +3 -0
  48. package/src/compat/rules/auth/groq.kdl +3 -0
  49. package/src/compat/rules/auth/huggingface.kdl +9 -0
  50. package/src/compat/rules/auth/kagi.kdl +9 -0
  51. package/src/compat/rules/auth/kilo.kdl +4 -0
  52. package/src/compat/rules/auth/kimi-code.kdl +18 -0
  53. package/src/compat/rules/auth/litellm.kdl +8 -0
  54. package/src/compat/rules/auth/llama.cpp.kdl +10 -0
  55. package/src/compat/rules/auth/lm-studio.kdl +7 -0
  56. package/src/compat/rules/auth/meta.kdl +9 -0
  57. package/src/compat/rules/auth/minimax-code-cn.kdl +9 -0
  58. package/src/compat/rules/auth/minimax-code.kdl +9 -0
  59. package/src/compat/rules/auth/minimax.kdl +3 -0
  60. package/src/compat/rules/auth/mistral.kdl +3 -0
  61. package/src/compat/rules/auth/moonshot.kdl +9 -0
  62. package/src/compat/rules/auth/nanogpt.kdl +9 -0
  63. package/src/compat/rules/auth/novita.kdl +12 -0
  64. package/src/compat/rules/auth/nvidia.kdl +11 -0
  65. package/src/compat/rules/auth/ollama-cloud.kdl +8 -0
  66. package/src/compat/rules/auth/ollama.kdl +9 -0
  67. package/src/compat/rules/auth/openai-codex-device.kdl +20 -0
  68. package/src/compat/rules/auth/openai-codex.kdl +33 -0
  69. package/src/compat/rules/auth/openai.kdl +3 -0
  70. package/src/compat/rules/auth/opencode-go.kdl +10 -0
  71. package/src/compat/rules/auth/opencode-zen.kdl +9 -0
  72. package/src/compat/rules/auth/openrouter.kdl +32 -0
  73. package/src/compat/rules/auth/parallel.kdl +9 -0
  74. package/src/compat/rules/auth/perplexity.kdl +7 -0
  75. package/src/compat/rules/auth/qianfan.kdl +9 -0
  76. package/src/compat/rules/auth/qwen-portal.kdl +9 -0
  77. package/src/compat/rules/auth/sakana.kdl +9 -0
  78. package/src/compat/rules/auth/siliconflow-cn.kdl +9 -0
  79. package/src/compat/rules/auth/siliconflow.kdl +9 -0
  80. package/src/compat/rules/auth/synthetic.kdl +9 -0
  81. package/src/compat/rules/auth/tavily.kdl +9 -0
  82. package/src/compat/rules/auth/together.kdl +14 -0
  83. package/src/compat/rules/auth/umans.kdl +9 -0
  84. package/src/compat/rules/auth/venice.kdl +9 -0
  85. package/src/compat/rules/auth/vercel-ai-gateway.kdl +8 -0
  86. package/src/compat/rules/auth/vllm.kdl +9 -0
  87. package/src/compat/rules/auth/wafer-serverless.kdl +11 -0
  88. package/src/compat/rules/auth/xai-oauth.kdl +27 -0
  89. package/src/compat/rules/auth/xai.kdl +9 -0
  90. package/src/compat/rules/auth/xiaomi-token-plan-ams.kdl +9 -0
  91. package/src/compat/rules/auth/xiaomi-token-plan-cn.kdl +9 -0
  92. package/src/compat/rules/auth/xiaomi-token-plan-sgp.kdl +9 -0
  93. package/src/compat/rules/auth/xiaomi.kdl +6 -0
  94. package/src/compat/rules/auth/yolo-auto.kdl +11 -0
  95. package/src/compat/rules/auth/zai-coding-plan.kdl +33 -0
  96. package/src/compat/rules/auth/zai.kdl +9 -0
  97. package/src/compat/rules/auth/zenmux.kdl +9 -0
  98. package/src/compat/rules/auth/zhipu-coding-plan.kdl +9 -0
  99. package/src/compat/rules/classes/amazon.kdl +21 -0
  100. package/src/compat/rules/classes/anthropic.kdl +285 -0
  101. package/src/compat/rules/classes/baidu.kdl +9 -0
  102. package/src/compat/rules/classes/bytedance.kdl +9 -0
  103. package/src/compat/rules/classes/cohere.kdl +7 -0
  104. package/src/compat/rules/classes/deepseek.kdl +80 -0
  105. package/src/compat/rules/classes/gemini.kdl +107 -0
  106. package/src/compat/rules/classes/gemma.kdl +14 -0
  107. package/src/compat/rules/classes/glm.kdl +115 -0
  108. package/src/compat/rules/classes/gpt-oss.kdl +16 -0
  109. package/src/compat/rules/classes/kimi.kdl +113 -0
  110. package/src/compat/rules/classes/meta.kdl +15 -0
  111. package/src/compat/rules/classes/mimo.kdl +32 -0
  112. package/src/compat/rules/classes/minimax.kdl +79 -0
  113. package/src/compat/rules/classes/mistral.kdl +19 -0
  114. package/src/compat/rules/classes/openai.kdl +58 -0
  115. package/src/compat/rules/classes/qwen.kdl +72 -0
  116. package/src/compat/rules/classes/stepfun.kdl +10 -0
  117. package/src/compat/rules/classes/xai.kdl +45 -0
  118. package/src/compat/rules/providers/abliteration.kdl +8 -0
  119. package/src/compat/rules/providers/aiand.kdl +19 -0
  120. package/src/compat/rules/providers/aimlapi.kdl +24 -0
  121. package/src/compat/rules/providers/alibaba-coding-plan.kdl +20 -0
  122. package/src/compat/rules/providers/alibaba-token-plan.kdl +35 -0
  123. package/src/compat/rules/providers/amazon-bedrock.kdl +36 -0
  124. package/src/compat/rules/providers/anthropic.kdl +24 -0
  125. package/src/compat/rules/providers/azure.kdl +19 -0
  126. package/src/compat/rules/providers/baseten.kdl +19 -0
  127. package/src/compat/rules/providers/bedrock-mantle.kdl +15 -0
  128. package/src/compat/rules/providers/cerebras.kdl +19 -0
  129. package/src/compat/rules/providers/cline-pass.kdl +8 -0
  130. package/src/compat/rules/providers/cloudflare-ai-gateway.kdl +26 -0
  131. package/src/compat/rules/providers/coreweave.kdl +16 -0
  132. package/src/compat/rules/providers/cursor.kdl +52 -0
  133. package/src/compat/rules/providers/deepseek.kdl +21 -0
  134. package/src/compat/rules/providers/firepass.kdl +15 -0
  135. package/src/compat/rules/providers/fireworks.kdl +43 -0
  136. package/src/compat/rules/providers/github-copilot.kdl +62 -0
  137. package/src/compat/rules/providers/gitlab-duo.kdl +24 -0
  138. package/src/compat/rules/providers/gmi-cloud.kdl +8 -0
  139. package/src/compat/rules/providers/google-antigravity.kdl +59 -0
  140. package/src/compat/rules/providers/google-gemini-cli.kdl +12 -0
  141. package/src/compat/rules/providers/google-vertex.kdl +25 -0
  142. package/src/compat/rules/providers/google.kdl +17 -0
  143. package/src/compat/rules/providers/groq.kdl +8 -0
  144. package/src/compat/rules/providers/huggingface.kdl +24 -0
  145. package/src/compat/rules/providers/kilo.kdl +51 -0
  146. package/src/compat/rules/providers/kimi-code.kdl +37 -0
  147. package/src/compat/rules/providers/llama.cpp.kdl +6 -0
  148. package/src/compat/rules/providers/lm-studio.kdl +6 -0
  149. package/src/compat/rules/providers/meta.kdl +10 -0
  150. package/src/compat/rules/providers/minimax-code-cn.kdl +13 -0
  151. package/src/compat/rules/providers/minimax-code.kdl +13 -0
  152. package/src/compat/rules/providers/minimax.kdl +6 -0
  153. package/src/compat/rules/providers/mistral.kdl +8 -0
  154. package/src/compat/rules/providers/moonshot.kdl +36 -0
  155. package/src/compat/rules/providers/nanogpt.kdl +100 -0
  156. package/src/compat/rules/providers/novita.kdl +34 -0
  157. package/src/compat/rules/providers/nvidia.kdl +27 -0
  158. package/src/compat/rules/providers/ollama-cloud.kdl +20 -0
  159. package/src/compat/rules/providers/ollama.kdl +12 -0
  160. package/src/compat/rules/providers/openai-codex.kdl +121 -0
  161. package/src/compat/rules/providers/openai.kdl +82 -0
  162. package/src/compat/rules/providers/opencode-go.kdl +97 -0
  163. package/src/compat/rules/providers/opencode-zen.kdl +103 -0
  164. package/src/compat/rules/providers/openrouter.kdl +66 -0
  165. package/src/compat/rules/providers/qianfan.kdl +8 -0
  166. package/src/compat/rules/providers/sakana.kdl +10 -0
  167. package/src/compat/rules/providers/synthetic.kdl +16 -0
  168. package/src/compat/rules/providers/together.kdl +22 -0
  169. package/src/compat/rules/providers/umans.kdl +28 -0
  170. package/src/compat/rules/providers/venice.kdl +46 -0
  171. package/src/compat/rules/providers/vercel-ai-gateway.kdl +73 -0
  172. package/src/compat/rules/providers/vllm.kdl +8 -0
  173. package/src/compat/rules/providers/wafer-serverless.kdl +35 -0
  174. package/src/compat/rules/providers/xai-oauth.kdl +48 -0
  175. package/src/compat/rules/providers/xai.kdl +50 -0
  176. package/src/compat/rules/providers/xiaomi-token-plan-ams.kdl +9 -0
  177. package/src/compat/rules/providers/xiaomi-token-plan-cn.kdl +9 -0
  178. package/src/compat/rules/providers/xiaomi-token-plan-sgp.kdl +9 -0
  179. package/src/compat/rules/providers/xiaomi.kdl +22 -0
  180. package/src/compat/rules/providers/yolo-auto.kdl +16 -0
  181. package/src/compat/rules/providers/zai.kdl +36 -0
  182. package/src/compat/rules/providers/zenmux.kdl +108 -0
  183. package/src/compat/rules/providers/zhipu-coding-plan.kdl +49 -0
  184. package/src/compat/rules/runtime/behavior.kdl +254 -0
  185. package/src/compat/rules/taxonomy/_collapse.kdl +747 -0
  186. package/src/compat/rules/taxonomy/_discovery.kdl +60 -0
  187. package/src/compat/rules/taxonomy/ai21.kdl +6 -0
  188. package/src/compat/rules/taxonomy/amazon.kdl +8 -0
  189. package/src/compat/rules/taxonomy/anthropic.kdl +17 -0
  190. package/src/compat/rules/taxonomy/baidu.kdl +5 -0
  191. package/src/compat/rules/taxonomy/bytedance.kdl +5 -0
  192. package/src/compat/rules/taxonomy/cohere.kdl +6 -0
  193. package/src/compat/rules/taxonomy/deepseek.kdl +18 -0
  194. package/src/compat/rules/taxonomy/gemini.kdl +9 -0
  195. package/src/compat/rules/taxonomy/gemma.kdl +3 -0
  196. package/src/compat/rules/taxonomy/glm.kdl +17 -0
  197. package/src/compat/rules/taxonomy/gpt-oss.kdl +11 -0
  198. package/src/compat/rules/taxonomy/kimi.kdl +20 -0
  199. package/src/compat/rules/taxonomy/meta.kdl +10 -0
  200. package/src/compat/rules/taxonomy/mimo.kdl +7 -0
  201. package/src/compat/rules/taxonomy/minimax.kdl +9 -0
  202. package/src/compat/rules/taxonomy/mistral.kdl +7 -0
  203. package/src/compat/rules/taxonomy/openai.kdl +43 -0
  204. package/src/compat/rules/taxonomy/qwen.kdl +33 -0
  205. package/src/compat/rules/taxonomy/stepfun.kdl +5 -0
  206. package/src/compat/rules/taxonomy/unknown.kdl +3 -0
  207. package/src/compat/rules/taxonomy/xai.kdl +12 -0
  208. package/src/compat/rules.d.json.ts +5 -0
  209. package/src/compat/rules.json +16984 -0
  210. package/src/compat/taxonomy.ts +452 -0
  211. package/src/compat/types.ts +588 -0
  212. package/src/discovery/antigravity.ts +5 -6
  213. package/src/discovery/codex.ts +22 -7
  214. package/src/discovery/cursor-proto.ts +7 -7
  215. package/src/discovery/cursor.ts +47 -58
  216. package/src/discovery/devin-proto.ts +613 -0
  217. package/src/discovery/devin.ts +358 -52
  218. package/src/discovery/gemini-cli.ts +14 -11
  219. package/src/discovery/gemini.ts +2 -0
  220. package/src/identity/dialect.ts +2 -2
  221. package/src/identity/id.ts +12 -0
  222. package/src/identity/index.ts +3 -3
  223. package/src/identity/metrics.ts +165 -0
  224. package/src/identity/reference.ts +37 -5
  225. package/src/index.ts +1 -1
  226. package/src/model-manager.ts +19 -6
  227. package/src/model-thinking.ts +6 -810
  228. package/src/model-tokenizer.ts +37 -44
  229. package/src/models.json +89584 -22358
  230. package/src/models.ts +6 -1
  231. package/src/provider-models/bundled-references.ts +3 -1
  232. package/src/provider-models/cline-pass.ts +226 -0
  233. package/src/provider-models/descriptors.ts +18 -0
  234. package/src/provider-models/google.ts +14 -5
  235. package/src/provider-models/models-dev-policies.ts +4 -29
  236. package/src/provider-models/ollama.ts +15 -2
  237. package/src/provider-models/openai-compat.ts +798 -520
  238. package/src/provider-models/special.ts +211 -12
  239. package/src/types.ts +214 -11
  240. package/src/wire/cline-pass.ts +35 -0
  241. package/src/wire/codex.ts +23 -2
  242. package/src/wire/devin-proto.ts +30 -0
  243. package/src/wire/devin.ts +72 -0
  244. package/src/wire/github-copilot.ts +49 -7
  245. package/THIRD-PARTY-NOTICES.txt +0 -22909
  246. package/dist/types/build.d.ts +0 -19
  247. package/dist/types/compat/anthropic.d.ts +0 -18
  248. package/dist/types/compat/apply.d.ts +0 -7
  249. package/dist/types/compat/bedrock.d.ts +0 -3
  250. package/dist/types/compat/devin.d.ts +0 -9
  251. package/dist/types/compat/openai.d.ts +0 -28
  252. package/dist/types/discovery/antigravity.d.ts +0 -70
  253. package/dist/types/discovery/codex.d.ts +0 -36
  254. package/dist/types/discovery/cursor-proto.d.ts +0 -5368
  255. package/dist/types/discovery/cursor.d.ts +0 -29
  256. package/dist/types/discovery/devin-proto.d.ts +0 -1549
  257. package/dist/types/discovery/devin.d.ts +0 -24
  258. package/dist/types/discovery/gemini-cli.d.ts +0 -33
  259. package/dist/types/discovery/gemini.d.ts +0 -25
  260. package/dist/types/discovery/gitlab-duo-workflow.d.ts +0 -30
  261. package/dist/types/discovery/index.d.ts +0 -7
  262. package/dist/types/discovery/openai-compatible.d.ts +0 -89
  263. package/dist/types/discovery/protobuf.d.ts +0 -102
  264. package/dist/types/effort.d.ts +0 -10
  265. package/dist/types/fireworks-model-id.d.ts +0 -23
  266. package/dist/types/hosts.d.ts +0 -169
  267. package/dist/types/identity/bundled.d.ts +0 -3
  268. package/dist/types/identity/classify.d.ts +0 -69
  269. package/dist/types/identity/dialect.d.ts +0 -3
  270. package/dist/types/identity/family.d.ts +0 -243
  271. package/dist/types/identity/id.d.ts +0 -12
  272. package/dist/types/identity/index.d.ts +0 -8
  273. package/dist/types/identity/markers.d.ts +0 -4
  274. package/dist/types/identity/priority.d.ts +0 -1
  275. package/dist/types/identity/reference.d.ts +0 -29
  276. package/dist/types/index.d.ts +0 -19
  277. package/dist/types/model-cache.d.ts +0 -23
  278. package/dist/types/model-manager.d.ts +0 -93
  279. package/dist/types/model-thinking.d.ts +0 -81
  280. package/dist/types/model-tokenizer.d.ts +0 -8
  281. package/dist/types/models.d.ts +0 -17
  282. package/dist/types/openai-pricing.d.ts +0 -17
  283. package/dist/types/provider-models/bundled-references.d.ts +0 -13
  284. package/dist/types/provider-models/cache-provider-id.d.ts +0 -11
  285. package/dist/types/provider-models/descriptor-types.d.ts +0 -76
  286. package/dist/types/provider-models/descriptors.d.ts +0 -524
  287. package/dist/types/provider-models/google.d.ts +0 -29
  288. package/dist/types/provider-models/index.d.ts +0 -7
  289. package/dist/types/provider-models/models-dev-policies.d.ts +0 -8
  290. package/dist/types/provider-models/ollama.d.ts +0 -22
  291. package/dist/types/provider-models/openai-compat.d.ts +0 -703
  292. package/dist/types/provider-models/special.d.ts +0 -53
  293. package/dist/types/types.d.ts +0 -879
  294. package/dist/types/utils.d.ts +0 -20
  295. package/dist/types/variant-collapse.d.ts +0 -146
  296. package/dist/types/wire/alibaba-token-plan.d.ts +0 -22
  297. package/dist/types/wire/cloudflare-ai-gateway.d.ts +0 -18
  298. package/dist/types/wire/codex.d.ts +0 -66
  299. package/dist/types/wire/coreweave.d.ts +0 -12
  300. package/dist/types/wire/gemini-headers.d.ts +0 -62
  301. package/dist/types/wire/github-copilot.d.ts +0 -47
  302. package/dist/types/wire/image-fetchers.d.ts +0 -76
  303. package/src/compat/bedrock.ts +0 -153
  304. package/src/compat/devin.ts +0 -12
  305. package/src/identity/classify.ts +0 -242
  306. package/src/identity/family.ts +0 -496
  307. package/src/identity/markers.ts +0 -49
  308. package/src/openai-pricing.ts +0 -29
package/CHANGELOG.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
- ## [1.1.7] - 2026-09-01
5
+ ## [1.1.9] - 2026-09-05
6
6
 
7
- - 同步上游 OMP v18.0.11(`b8ce33a58911c26bed1d84f0db9a5e2e727c49a2`)。
7
+ - v18.1.10 sync baseline; retired pi-hashline catalog entry removed from the version-line catalogs.
8
8
 
9
9
  ## [1.1.6] - 2026-08-30
10
10
 
@@ -14,12 +14,6 @@
14
14
 
15
15
  - 同步上游 OMP v18.0.5 / v18.0.6:新增 DeepInfra / Yolo-Auto 提供商标识。
16
16
 
17
- ## [1.1.3] - 2026-08-25
18
-
19
- ### Fixed
20
-
21
- - Republished as 1.1.3 to reset the latest tag after the broken 1.1.2 (no functional change over 1.1.1).
22
-
23
17
  ## [1.1.2] - 2026-08-25
24
18
 
25
19
  ### Fixed
@@ -47,3 +41,8 @@
47
41
  ### Changed
48
42
 
49
43
  - Reset the version to 1.0.0 and republished under the `@linxiraos/*` scope, breaking from the `@linxiraos` version lineage.
44
+ - Bundled model metadata is prebuilt during generation, reducing catalog startup work.
45
+
46
+ ### Fixed
47
+
48
+ - 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
 
package/package.json CHANGED
@@ -1,102 +1,98 @@
1
1
  {
2
- "type": "module",
3
- "name": "@linxiraos/pi-catalog",
4
- "version": "1.1.7",
5
- "description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
6
- "homepage": "https://linxira-os.github.io/zeta/",
7
- "author": "Can Boluk",
8
- "license": "MIT",
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/Linxira-OS/linxira-zeta.git",
12
- "directory": "packages/catalog"
13
- },
14
- "bugs": {
15
- "url": "https://github.com/Linxira-OS/linxira-zeta/issues"
16
- },
17
- "keywords": [
18
- "ai",
19
- "llm",
20
- "models",
21
- "catalog",
22
- "discovery"
23
- ],
24
- "main": "./src/index.ts",
25
- "types": "./dist/types/index.d.ts",
26
- "scripts": {
27
- "check": "biome check . && bun run check:types",
28
- "check:types": "tsgo -p tsconfig.json --noEmit",
29
- "lint": "biome lint .",
30
- "test": "bun test --parallel",
31
- "fix": "biome check --write --unsafe .",
32
- "fmt": "biome format --write .",
33
- "gen:models": "bun scripts/generate-models.ts",
34
- "gen:proto": "bun scripts/generate-protocols.ts"
35
- },
36
- "dependencies": {
37
- "@linxiraos/pi-omptype": "1.1.7",
38
- "@linxiraos/pi-utils": "1.1.7"
39
- },
40
- "devDependencies": {
41
- "@linxiraos/pi-ai": "1.1.7",
42
- "@types/bun": "^1.3.14"
43
- },
44
- "engines": {
45
- "bun": ">=1.3.14"
46
- },
47
- "files": [
48
- "src",
49
- "README.md",
50
- "CHANGELOG.md",
51
- "LICENSE",
52
- "THIRD-PARTY-NOTICES.txt",
53
- "dist/types"
54
- ],
55
- "exports": {
56
- ".": {
57
- "types": "./dist/types/index.d.ts",
58
- "import": "./src/index.ts"
59
- },
60
- "./models.json": {
61
- "types": "./dist/types/models.json.d.d.ts",
62
- "import": "./src/models.json"
63
- },
64
- "./provider-models": {
65
- "types": "./dist/types/provider-models/index.d.ts",
66
- "import": "./src/provider-models/index.ts"
67
- },
68
- "./provider-models/*": {
69
- "types": "./dist/types/provider-models/*.d.ts",
70
- "import": "./src/provider-models/*.ts"
71
- },
72
- "./discovery": {
73
- "types": "./dist/types/discovery/index.d.ts",
74
- "import": "./src/discovery/index.ts"
75
- },
76
- "./discovery/*": {
77
- "types": "./dist/types/discovery/*.d.ts",
78
- "import": "./src/discovery/*.ts"
79
- },
80
- "./identity": {
81
- "types": "./dist/types/identity/index.d.ts",
82
- "import": "./src/identity/index.ts"
83
- },
84
- "./identity/*": {
85
- "types": "./dist/types/identity/*.d.ts",
86
- "import": "./src/identity/*.ts"
87
- },
88
- "./wire/*": {
89
- "types": "./dist/types/wire/*.d.ts",
90
- "import": "./src/wire/*.ts"
91
- },
92
- "./compat/*": {
93
- "types": "./dist/types/compat/*.d.ts",
94
- "import": "./src/compat/*.ts"
95
- },
96
- "./*": {
97
- "types": "./dist/types/*.d.ts",
98
- "import": "./src/*.ts"
99
- },
100
- "./*.js": "./src/*.ts"
101
- }
2
+ "exports": {
3
+ "./*.js": "./src/*.ts",
4
+ "./*": {
5
+ "import": "./src/*.ts",
6
+ "types": "./src/*.ts"
7
+ },
8
+ "./compat/*": {
9
+ "import": "./src/compat/*.ts",
10
+ "types": "./src/compat/*.ts"
11
+ },
12
+ "./wire/*": {
13
+ "import": "./src/wire/*.ts",
14
+ "types": "./src/wire/*.ts"
15
+ },
16
+ "./identity/*": {
17
+ "import": "./src/identity/*.ts",
18
+ "types": "./src/identity/*.ts"
19
+ },
20
+ "./identity": {
21
+ "import": "./src/identity/index.ts",
22
+ "types": "./src/identity/index.ts"
23
+ },
24
+ "./discovery/*": {
25
+ "import": "./src/discovery/*.ts",
26
+ "types": "./src/discovery/*.ts"
27
+ },
28
+ "./discovery": {
29
+ "import": "./src/discovery/index.ts",
30
+ "types": "./src/discovery/index.ts"
31
+ },
32
+ "./provider-models/*": {
33
+ "import": "./src/provider-models/*.ts",
34
+ "types": "./src/provider-models/*.ts"
35
+ },
36
+ "./provider-models": {
37
+ "import": "./src/provider-models/index.ts",
38
+ "types": "./src/provider-models/index.ts"
39
+ },
40
+ "./models.json": {
41
+ "import": "./src/models.json",
42
+ "types": "./src/models.json.d.ts"
43
+ },
44
+ ".": {
45
+ "import": "./src/index.ts",
46
+ "types": "./src/index.ts"
47
+ }
48
+ },
49
+ "files": [
50
+ "src",
51
+ "README.md",
52
+ "CHANGELOG.md"
53
+ ],
54
+ "engines": {
55
+ "bun": ">=1.3.14"
56
+ },
57
+ "devDependencies": {
58
+ "@linxiraos/pi-ai": "1.1.9",
59
+ "@types/bun": "^1.3.14",
60
+ "@bgotink/kdl": "0.4.0"
61
+ },
62
+ "dependencies": {
63
+ "@linxiraos/pi-utils": "1.1.9",
64
+ "@linxiraos/pi-omptype": "1.1.9"
65
+ },
66
+ "scripts": {
67
+ "gen:proto": "bun scripts/generate-protocols.ts",
68
+ "gen:compat": "bun scripts/compile-compat.ts",
69
+ "gen:models": "bun scripts/generate-models.ts",
70
+ "test": "bun test --parallel",
71
+ "check:types": "tsgo -p tsconfig.json --noEmit",
72
+ "check": "tsgo -p tsconfig.json --noEmit"
73
+ },
74
+ "types": "./src/index.ts",
75
+ "main": "./src/index.ts",
76
+ "keywords": [
77
+ "ai",
78
+ "llm",
79
+ "models",
80
+ "catalog",
81
+ "discovery"
82
+ ],
83
+ "bugs": {
84
+ "url": "https://github.com/Linxira-OS/linxira-zeta/issues"
85
+ },
86
+ "repository": {
87
+ "directory": "packages/catalog",
88
+ "url": "git+https://github.com/Linxira-OS/linxira-zeta.git",
89
+ "type": "git"
90
+ },
91
+ "license": "MIT",
92
+ "author": "Can Boluk",
93
+ "homepage": "https://linxira-os.github.io/zeta/",
94
+ "description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
95
+ "version": "1.1.9",
96
+ "name": "@linxiraos/pi-catalog",
97
+ "type": "module"
102
98
  }
package/src/build.ts CHANGED
@@ -1,26 +1,149 @@
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
9
 
13
- import { buildAnthropicCompat } from "./compat/anthropic";
14
- import { buildBedrockCompat } from "./compat/bedrock";
15
- import { buildDevinCompat } from "./compat/devin";
16
- import { buildOpenAICompat, buildOpenAIResponsesCompat, buildOpenRouterCompat } from "./compat/openai";
17
- import { bareModelId, parseOpenAIModel, semverGte } from "./identity/classify";
18
- import { isClaudeModelId } from "./identity/family";
19
- import { resolveModelThinking } from "./model-thinking";
10
+ import { resolveModelPolicy } from "./compat/resolve";
11
+ import type { ModelIdentity } from "./compat/types";
20
12
  import { resolveModelTokenizer } from "./model-tokenizer";
21
- import type { Api, CompatOf, Model, ModelSpec } from "./types";
13
+ import type { Api, Model, ModelSpec } from "./types";
22
14
  import { cleanModelName } from "./utils";
23
15
 
16
+ function numberField(source: object, key: string): number | undefined {
17
+ const value: unknown = Reflect.get(source, key);
18
+ return typeof value === "number" ? value : undefined;
19
+ }
20
+
21
+ /** Narrow an unknown compiled-axis payload to an object payload. */
22
+ function objectPayload(value: unknown): object | undefined {
23
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
24
+ }
25
+
26
+ /** Narrow a compiled `input-modalities` axis value to the model input union. */
27
+ function isInputModalities(value: unknown): value is ("text" | "image")[] {
28
+ return Array.isArray(value) && value.every(entry => entry === "text" || entry === "image");
29
+ }
30
+
31
+ /**
32
+ * Applies resolved catalog-data axes onto the model: reviewed metadata
33
+ * corrections (`cost-patch`, `limits-patch`, `long-context-cost`,
34
+ * `context-window-floor`) overwrite upstream values; selection metadata
35
+ * (`priority`, `apply-patch-tool-type`, `service-tier-cost`,
36
+ * `requires-cursor-tool-schema-projection`) is rule-owned;
37
+ * `context-promotion-target` fills only when the spec left it unset.
38
+ */
39
+ function applyCatalogAssignments<TApi extends Api>(model: Model<TApi>, catalog: Record<string, unknown>): void {
40
+ const serviceTierCost = objectPayload(catalog.serviceTierCost);
41
+ if (serviceTierCost !== undefined) {
42
+ const flex = numberField(serviceTierCost, "flex");
43
+ const priorityTier = numberField(serviceTierCost, "priority");
44
+ model.serviceTierCost = {
45
+ ...(flex !== undefined && { flex }),
46
+ ...(priorityTier !== undefined && { priority: priorityTier }),
47
+ };
48
+ }
49
+ const priority = catalog.priority;
50
+ if (typeof priority === "number") model.priority = priority;
51
+ const applyPatchToolType = catalog.applyPatchToolType;
52
+ if (applyPatchToolType === "freeform" || applyPatchToolType === "function") {
53
+ model.applyPatchToolType = applyPatchToolType;
54
+ }
55
+ const requiresCursorToolSchemaProjection = catalog.requiresCursorToolSchemaProjection;
56
+ if (requiresCursorToolSchemaProjection === true) {
57
+ model.requiresCursorToolSchemaProjection = true;
58
+ } else {
59
+ delete model.requiresCursorToolSchemaProjection;
60
+ }
61
+ const contextPromotionTarget = catalog.contextPromotionTarget;
62
+ if (typeof contextPromotionTarget === "string" && model.contextPromotionTarget === undefined) {
63
+ model.contextPromotionTarget = contextPromotionTarget;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Applies reviewed catalog-data value corrections (`cost-patch`,
69
+ * `limits-patch`, `long-context-cost`, `context-window-floor`,
70
+ * `input-modalities`) onto an upstream-sourced spec. Applied by
71
+ * `buildModel` to every upstream-sourced spec; user-authored overrides are
72
+ * recomposed after building by the override applicators, so explicit user
73
+ * limits and pricing still win.
74
+ */
75
+ export function applyCatalogCorrections(
76
+ model: Pick<ModelSpec<Api>, "cost" | "contextWindow" | "maxTokens" | "input">,
77
+ catalog: Record<string, unknown>,
78
+ ): void {
79
+ const longContext = objectPayload(catalog.longContext);
80
+ if (longContext !== undefined) {
81
+ const inputThreshold = numberField(longContext, "inputThreshold");
82
+ const inclusive = Reflect.get(longContext, "inputThresholdInclusive") === true;
83
+ const multiplier = numberField(longContext, "multiplier");
84
+ const input = numberField(longContext, "input");
85
+ const output = numberField(longContext, "output");
86
+ const cacheRead = numberField(longContext, "cacheRead");
87
+ const cacheWrite = numberField(longContext, "cacheWrite");
88
+ const base = model.cost;
89
+ const hasTokenPrice = base.input !== 0 || base.output !== 0 || base.cacheRead !== 0 || base.cacheWrite !== 0;
90
+ if (inputThreshold !== undefined && multiplier !== undefined && hasTokenPrice) {
91
+ // Multiplier form: tier rates derive from the row's live list price.
92
+ model.cost = {
93
+ ...base,
94
+ longContext: {
95
+ inputThreshold,
96
+ ...(inclusive && { inputThresholdInclusive: true }),
97
+ input: base.input * multiplier,
98
+ output: base.output * multiplier,
99
+ cacheRead: base.cacheRead * multiplier,
100
+ cacheWrite: base.cacheWrite * multiplier,
101
+ },
102
+ };
103
+ } else if (
104
+ inputThreshold !== undefined &&
105
+ input !== undefined &&
106
+ output !== undefined &&
107
+ cacheRead !== undefined &&
108
+ cacheWrite !== undefined
109
+ ) {
110
+ model.cost = { ...model.cost, longContext: { inputThreshold, input, output, cacheRead, cacheWrite } };
111
+ }
112
+ }
113
+ const patch = objectPayload(catalog.costPatch);
114
+ if (patch !== undefined) {
115
+ model.cost = { ...model.cost };
116
+ const input = numberField(patch, "input");
117
+ if (input !== undefined) model.cost.input = input;
118
+ const output = numberField(patch, "output");
119
+ if (output !== undefined) model.cost.output = output;
120
+ const cacheRead = numberField(patch, "cacheRead");
121
+ if (cacheRead !== undefined) model.cost.cacheRead = cacheRead;
122
+ const cacheWrite = numberField(patch, "cacheWrite");
123
+ if (cacheWrite !== undefined) model.cost.cacheWrite = cacheWrite;
124
+ }
125
+ const limitsPatch = objectPayload(catalog.limitsPatch);
126
+ if (limitsPatch !== undefined) {
127
+ const contextWindow = numberField(limitsPatch, "contextWindow");
128
+ if (contextWindow !== undefined) model.contextWindow = contextWindow;
129
+ const maxTokens = numberField(limitsPatch, "maxTokens");
130
+ if (maxTokens !== undefined) model.maxTokens = maxTokens;
131
+ }
132
+ const contextWindowFloor = catalog.contextWindowFloor;
133
+ if (typeof contextWindowFloor === "number") {
134
+ model.contextWindow = Math.max(model.contextWindow ?? 0, contextWindowFloor);
135
+ }
136
+ const inputModalities = catalog.inputModalities;
137
+ if (isInputModalities(inputModalities)) {
138
+ model.input = inputModalities;
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Direct first-party OpenAI Responses endpoints (api.openai.com, Azure OpenAI
144
+ * deployments). Gates GA computer-use detection; identity supplies the model
145
+ * generation.
146
+ */
24
147
  function isDirectOpenAIResponsesEndpoint(spec: ModelSpec<Api>): boolean {
25
148
  if (spec.api === "openai-responses") {
26
149
  if (spec.provider !== "openai") return false;
@@ -48,16 +171,27 @@ function isDirectOpenAIResponsesEndpoint(spec: ModelSpec<Api>): boolean {
48
171
  }
49
172
 
50
173
  function explicitComputerUseConfig(spec: ModelSpec<Api>): boolean | undefined {
51
- return "supportsComputerUseConfig" in spec
52
- ? (spec as Model<Api>).supportsComputerUseConfig
53
- : spec.supportsComputerUse;
174
+ if (!("supportsComputerUseConfig" in spec)) return spec.supportsComputerUse;
175
+ const value: unknown = Reflect.get(spec, "supportsComputerUseConfig");
176
+ return typeof value === "boolean" ? value : undefined;
177
+ }
178
+
179
+ function revisionAtLeast(identity: ModelIdentity, major: number, minor: number): boolean {
180
+ if (identity.revision === undefined) return false;
181
+ const [revMajor = 0, revMinor = 0] = identity.revision.split(".").map(Number);
182
+ return revMajor > major || (revMajor === major && revMinor >= minor);
54
183
  }
55
184
 
56
- function supportsOpenAIGAComputerUse(spec: ModelSpec<Api>, explicitSupport: boolean | undefined): boolean {
185
+ function supportsOpenAIGAComputerUse(
186
+ spec: ModelSpec<Api>,
187
+ identity: ModelIdentity,
188
+ explicitSupport: boolean | undefined,
189
+ ): boolean {
57
190
  if (explicitSupport !== undefined) return explicitSupport;
58
191
  if (!isDirectOpenAIResponsesEndpoint(spec)) return false;
59
- const parsed = parseOpenAIModel(bareModelId(spec.requestModelId ?? spec.id));
60
- return parsed !== null && semverGte(parsed.version, "5.4");
192
+ const wireIdentity =
193
+ spec.requestModelId === undefined ? identity : resolveModelPolicy({ ...spec, id: spec.requestModelId }).identity;
194
+ return wireIdentity.class === "openai" && revisionAtLeast(wireIdentity, 5, 4);
61
195
  }
62
196
 
63
197
  /**
@@ -66,38 +200,21 @@ function supportsOpenAIGAComputerUse(spec: ModelSpec<Api>, explicitSupport: bool
66
200
  * this only runs for discovered/custom/override specs.
67
201
  */
68
202
  export function buildModel<TApi extends Api>(spec: ModelSpec<TApi>): Model<TApi> {
69
- const compat = buildCompat(spec) as CompatOf<TApi>;
203
+ const policy = resolveModelPolicy(spec);
70
204
  const supportsComputerUseConfig = explicitComputerUseConfig(spec);
71
- return {
205
+ const model: Model<TApi> = {
72
206
  ...spec,
73
207
  name: cleanModelName(spec.name),
74
- requiresGlyphTokenization: isClaudeModelId(spec.id),
208
+ identity: policy.identity,
209
+ requiresGlyphTokenization: policy.identity.class === "anthropic",
75
210
  tokenizer: spec.tokenizer ?? resolveModelTokenizer(spec.requestModelId ?? spec.id),
76
- thinking: resolveModelThinking(spec, compat),
77
- supportsComputerUse: supportsOpenAIGAComputerUse(spec, supportsComputerUseConfig),
211
+ thinking: policy.thinking,
212
+ supportsComputerUse: supportsOpenAIGAComputerUse(spec, policy.identity, supportsComputerUseConfig),
78
213
  supportsComputerUseConfig,
79
- compat,
214
+ compat: policy.compat,
80
215
  compatConfig: spec.compat,
81
- } as Model<TApi>;
82
- }
83
-
84
- export function buildCompat(spec: ModelSpec<Api>): CompatOf<Api> {
85
- switch (spec.api) {
86
- case "openrouter":
87
- return buildOpenRouterCompat(spec as ModelSpec<"openrouter">);
88
- case "openai-completions":
89
- return buildOpenAICompat(spec as ModelSpec<"openai-completions">);
90
- case "openai-responses":
91
- case "azure-openai-responses":
92
- case "openai-codex-responses":
93
- return buildOpenAIResponsesCompat(spec as ModelSpec<"openai-responses">);
94
- case "anthropic-messages":
95
- return buildAnthropicCompat(spec as ModelSpec<"anthropic-messages">);
96
- case "bedrock-converse-stream":
97
- return buildBedrockCompat(spec as ModelSpec<"bedrock-converse-stream">);
98
- case "devin-agent":
99
- return buildDevinCompat(spec as ModelSpec<"devin-agent">);
100
- default:
101
- return undefined;
102
- }
216
+ };
217
+ applyCatalogAssignments(model, policy.catalog);
218
+ applyCatalogCorrections(model, policy.catalog);
219
+ return model;
103
220
  }
@@ -0,0 +1,11 @@
1
+ const CLINEPASS_WIRE_PREFIX = "cline-pass/";
2
+
3
+ /** Convert a public ClinePass catalog id to the gateway's wire id. */
4
+ export function toClinePassWireModelId(modelId: string): string {
5
+ return modelId.startsWith(CLINEPASS_WIRE_PREFIX) ? modelId : `${CLINEPASS_WIRE_PREFIX}${modelId}`;
6
+ }
7
+
8
+ /** Convert a gateway ClinePass wire id to the public catalog id. */
9
+ export function toClinePassPublicModelId(modelId: string): string {
10
+ return modelId.startsWith(CLINEPASS_WIRE_PREFIX) ? modelId.slice(CLINEPASS_WIRE_PREFIX.length) : modelId;
11
+ }