@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.
- package/CHANGELOG.md +7 -8
- package/README.md +9 -8
- package/package.json +96 -100
- package/src/build.ts +165 -48
- package/src/cline-pass-model-id.ts +11 -0
- package/src/compat/anthropic.ts +15 -136
- package/src/compat/auth-ids.ts +157 -0
- package/src/compat/auth.ts +60 -0
- package/src/compat/axes.ts +301 -0
- package/src/compat/behavior.ts +207 -0
- package/src/compat/cascade.ts +230 -0
- package/src/{variant-collapse.ts → compat/collapse.ts} +381 -773
- package/src/compat/delegation.ts +37 -0
- package/src/compat/openai.ts +17 -848
- package/src/compat/resolve.ts +1231 -0
- package/src/compat/revision.ts +154 -0
- package/src/compat/rules/README.md +315 -0
- package/src/compat/rules/auth/_order.kdl +13 -0
- package/src/compat/rules/auth/abliteration.kdl +9 -0
- package/src/compat/rules/auth/aiand.kdl +9 -0
- package/src/compat/rules/auth/aimlapi.kdl +3 -0
- package/src/compat/rules/auth/alibaba-coding-plan.kdl +5 -0
- package/src/compat/rules/auth/alibaba-token-plan.kdl +11 -0
- package/src/compat/rules/auth/amazon-bedrock.kdl +5 -0
- package/src/compat/rules/auth/anthropic.kdl +53 -0
- package/src/compat/rules/auth/azure.kdl +3 -0
- package/src/compat/rules/auth/baseten.kdl +9 -0
- package/src/compat/rules/auth/bedrock-mantle.kdl +5 -0
- package/src/compat/rules/auth/cerebras.kdl +9 -0
- package/src/compat/rules/auth/cline-pass.kdl +12 -0
- package/src/compat/rules/auth/cloudflare-ai-gateway.kdl +4 -0
- package/src/compat/rules/auth/coreweave.kdl +9 -0
- package/src/compat/rules/auth/cursor.kdl +5 -0
- package/src/compat/rules/auth/deepinfra.kdl +11 -0
- package/src/compat/rules/auth/deepseek.kdl +10 -0
- package/src/compat/rules/auth/devin.kdl +28 -0
- package/src/compat/rules/auth/exa.kdl +9 -0
- package/src/compat/rules/auth/firepass.kdl +14 -0
- package/src/compat/rules/auth/fireworks.kdl +16 -0
- package/src/compat/rules/auth/github-copilot.kdl +7 -0
- package/src/compat/rules/auth/gitlab-duo-agent.kdl +23 -0
- package/src/compat/rules/auth/gitlab-duo.kdl +24 -0
- package/src/compat/rules/auth/gmi-cloud.kdl +9 -0
- package/src/compat/rules/auth/google-antigravity.kdl +28 -0
- package/src/compat/rules/auth/google-gemini-cli.kdl +26 -0
- package/src/compat/rules/auth/google-vertex.kdl +5 -0
- package/src/compat/rules/auth/google.kdl +3 -0
- package/src/compat/rules/auth/groq.kdl +3 -0
- package/src/compat/rules/auth/huggingface.kdl +9 -0
- package/src/compat/rules/auth/kagi.kdl +9 -0
- package/src/compat/rules/auth/kilo.kdl +4 -0
- package/src/compat/rules/auth/kimi-code.kdl +18 -0
- package/src/compat/rules/auth/litellm.kdl +8 -0
- package/src/compat/rules/auth/llama.cpp.kdl +10 -0
- package/src/compat/rules/auth/lm-studio.kdl +7 -0
- package/src/compat/rules/auth/meta.kdl +9 -0
- package/src/compat/rules/auth/minimax-code-cn.kdl +9 -0
- package/src/compat/rules/auth/minimax-code.kdl +9 -0
- package/src/compat/rules/auth/minimax.kdl +3 -0
- package/src/compat/rules/auth/mistral.kdl +3 -0
- package/src/compat/rules/auth/moonshot.kdl +9 -0
- package/src/compat/rules/auth/nanogpt.kdl +9 -0
- package/src/compat/rules/auth/novita.kdl +12 -0
- package/src/compat/rules/auth/nvidia.kdl +11 -0
- package/src/compat/rules/auth/ollama-cloud.kdl +8 -0
- package/src/compat/rules/auth/ollama.kdl +9 -0
- package/src/compat/rules/auth/openai-codex-device.kdl +20 -0
- package/src/compat/rules/auth/openai-codex.kdl +33 -0
- package/src/compat/rules/auth/openai.kdl +3 -0
- package/src/compat/rules/auth/opencode-go.kdl +10 -0
- package/src/compat/rules/auth/opencode-zen.kdl +9 -0
- package/src/compat/rules/auth/openrouter.kdl +32 -0
- package/src/compat/rules/auth/parallel.kdl +9 -0
- package/src/compat/rules/auth/perplexity.kdl +7 -0
- package/src/compat/rules/auth/qianfan.kdl +9 -0
- package/src/compat/rules/auth/qwen-portal.kdl +9 -0
- package/src/compat/rules/auth/sakana.kdl +9 -0
- package/src/compat/rules/auth/siliconflow-cn.kdl +9 -0
- package/src/compat/rules/auth/siliconflow.kdl +9 -0
- package/src/compat/rules/auth/synthetic.kdl +9 -0
- package/src/compat/rules/auth/tavily.kdl +9 -0
- package/src/compat/rules/auth/together.kdl +14 -0
- package/src/compat/rules/auth/umans.kdl +9 -0
- package/src/compat/rules/auth/venice.kdl +9 -0
- package/src/compat/rules/auth/vercel-ai-gateway.kdl +8 -0
- package/src/compat/rules/auth/vllm.kdl +9 -0
- package/src/compat/rules/auth/wafer-serverless.kdl +11 -0
- package/src/compat/rules/auth/xai-oauth.kdl +27 -0
- package/src/compat/rules/auth/xai.kdl +9 -0
- package/src/compat/rules/auth/xiaomi-token-plan-ams.kdl +9 -0
- package/src/compat/rules/auth/xiaomi-token-plan-cn.kdl +9 -0
- package/src/compat/rules/auth/xiaomi-token-plan-sgp.kdl +9 -0
- package/src/compat/rules/auth/xiaomi.kdl +6 -0
- package/src/compat/rules/auth/yolo-auto.kdl +11 -0
- package/src/compat/rules/auth/zai-coding-plan.kdl +33 -0
- package/src/compat/rules/auth/zai.kdl +9 -0
- package/src/compat/rules/auth/zenmux.kdl +9 -0
- package/src/compat/rules/auth/zhipu-coding-plan.kdl +9 -0
- package/src/compat/rules/classes/amazon.kdl +21 -0
- package/src/compat/rules/classes/anthropic.kdl +285 -0
- package/src/compat/rules/classes/baidu.kdl +9 -0
- package/src/compat/rules/classes/bytedance.kdl +9 -0
- package/src/compat/rules/classes/cohere.kdl +7 -0
- package/src/compat/rules/classes/deepseek.kdl +80 -0
- package/src/compat/rules/classes/gemini.kdl +107 -0
- package/src/compat/rules/classes/gemma.kdl +14 -0
- package/src/compat/rules/classes/glm.kdl +115 -0
- package/src/compat/rules/classes/gpt-oss.kdl +16 -0
- package/src/compat/rules/classes/kimi.kdl +113 -0
- package/src/compat/rules/classes/meta.kdl +15 -0
- package/src/compat/rules/classes/mimo.kdl +32 -0
- package/src/compat/rules/classes/minimax.kdl +79 -0
- package/src/compat/rules/classes/mistral.kdl +19 -0
- package/src/compat/rules/classes/openai.kdl +58 -0
- package/src/compat/rules/classes/qwen.kdl +72 -0
- package/src/compat/rules/classes/stepfun.kdl +10 -0
- package/src/compat/rules/classes/xai.kdl +45 -0
- package/src/compat/rules/providers/abliteration.kdl +8 -0
- package/src/compat/rules/providers/aiand.kdl +19 -0
- package/src/compat/rules/providers/aimlapi.kdl +24 -0
- package/src/compat/rules/providers/alibaba-coding-plan.kdl +20 -0
- package/src/compat/rules/providers/alibaba-token-plan.kdl +35 -0
- package/src/compat/rules/providers/amazon-bedrock.kdl +36 -0
- package/src/compat/rules/providers/anthropic.kdl +24 -0
- package/src/compat/rules/providers/azure.kdl +19 -0
- package/src/compat/rules/providers/baseten.kdl +19 -0
- package/src/compat/rules/providers/bedrock-mantle.kdl +15 -0
- package/src/compat/rules/providers/cerebras.kdl +19 -0
- package/src/compat/rules/providers/cline-pass.kdl +8 -0
- package/src/compat/rules/providers/cloudflare-ai-gateway.kdl +26 -0
- package/src/compat/rules/providers/coreweave.kdl +16 -0
- package/src/compat/rules/providers/cursor.kdl +52 -0
- package/src/compat/rules/providers/deepseek.kdl +21 -0
- package/src/compat/rules/providers/firepass.kdl +15 -0
- package/src/compat/rules/providers/fireworks.kdl +43 -0
- package/src/compat/rules/providers/github-copilot.kdl +62 -0
- package/src/compat/rules/providers/gitlab-duo.kdl +24 -0
- package/src/compat/rules/providers/gmi-cloud.kdl +8 -0
- package/src/compat/rules/providers/google-antigravity.kdl +59 -0
- package/src/compat/rules/providers/google-gemini-cli.kdl +12 -0
- package/src/compat/rules/providers/google-vertex.kdl +25 -0
- package/src/compat/rules/providers/google.kdl +17 -0
- package/src/compat/rules/providers/groq.kdl +8 -0
- package/src/compat/rules/providers/huggingface.kdl +24 -0
- package/src/compat/rules/providers/kilo.kdl +51 -0
- package/src/compat/rules/providers/kimi-code.kdl +37 -0
- package/src/compat/rules/providers/llama.cpp.kdl +6 -0
- package/src/compat/rules/providers/lm-studio.kdl +6 -0
- package/src/compat/rules/providers/meta.kdl +10 -0
- package/src/compat/rules/providers/minimax-code-cn.kdl +13 -0
- package/src/compat/rules/providers/minimax-code.kdl +13 -0
- package/src/compat/rules/providers/minimax.kdl +6 -0
- package/src/compat/rules/providers/mistral.kdl +8 -0
- package/src/compat/rules/providers/moonshot.kdl +36 -0
- package/src/compat/rules/providers/nanogpt.kdl +100 -0
- package/src/compat/rules/providers/novita.kdl +34 -0
- package/src/compat/rules/providers/nvidia.kdl +27 -0
- package/src/compat/rules/providers/ollama-cloud.kdl +20 -0
- package/src/compat/rules/providers/ollama.kdl +12 -0
- package/src/compat/rules/providers/openai-codex.kdl +121 -0
- package/src/compat/rules/providers/openai.kdl +82 -0
- package/src/compat/rules/providers/opencode-go.kdl +97 -0
- package/src/compat/rules/providers/opencode-zen.kdl +103 -0
- package/src/compat/rules/providers/openrouter.kdl +66 -0
- package/src/compat/rules/providers/qianfan.kdl +8 -0
- package/src/compat/rules/providers/sakana.kdl +10 -0
- package/src/compat/rules/providers/synthetic.kdl +16 -0
- package/src/compat/rules/providers/together.kdl +22 -0
- package/src/compat/rules/providers/umans.kdl +28 -0
- package/src/compat/rules/providers/venice.kdl +46 -0
- package/src/compat/rules/providers/vercel-ai-gateway.kdl +73 -0
- package/src/compat/rules/providers/vllm.kdl +8 -0
- package/src/compat/rules/providers/wafer-serverless.kdl +35 -0
- package/src/compat/rules/providers/xai-oauth.kdl +48 -0
- package/src/compat/rules/providers/xai.kdl +50 -0
- package/src/compat/rules/providers/xiaomi-token-plan-ams.kdl +9 -0
- package/src/compat/rules/providers/xiaomi-token-plan-cn.kdl +9 -0
- package/src/compat/rules/providers/xiaomi-token-plan-sgp.kdl +9 -0
- package/src/compat/rules/providers/xiaomi.kdl +22 -0
- package/src/compat/rules/providers/yolo-auto.kdl +16 -0
- package/src/compat/rules/providers/zai.kdl +36 -0
- package/src/compat/rules/providers/zenmux.kdl +108 -0
- package/src/compat/rules/providers/zhipu-coding-plan.kdl +49 -0
- package/src/compat/rules/runtime/behavior.kdl +254 -0
- package/src/compat/rules/taxonomy/_collapse.kdl +747 -0
- package/src/compat/rules/taxonomy/_discovery.kdl +60 -0
- package/src/compat/rules/taxonomy/ai21.kdl +6 -0
- package/src/compat/rules/taxonomy/amazon.kdl +8 -0
- package/src/compat/rules/taxonomy/anthropic.kdl +17 -0
- package/src/compat/rules/taxonomy/baidu.kdl +5 -0
- package/src/compat/rules/taxonomy/bytedance.kdl +5 -0
- package/src/compat/rules/taxonomy/cohere.kdl +6 -0
- package/src/compat/rules/taxonomy/deepseek.kdl +18 -0
- package/src/compat/rules/taxonomy/gemini.kdl +9 -0
- package/src/compat/rules/taxonomy/gemma.kdl +3 -0
- package/src/compat/rules/taxonomy/glm.kdl +17 -0
- package/src/compat/rules/taxonomy/gpt-oss.kdl +11 -0
- package/src/compat/rules/taxonomy/kimi.kdl +20 -0
- package/src/compat/rules/taxonomy/meta.kdl +10 -0
- package/src/compat/rules/taxonomy/mimo.kdl +7 -0
- package/src/compat/rules/taxonomy/minimax.kdl +9 -0
- package/src/compat/rules/taxonomy/mistral.kdl +7 -0
- package/src/compat/rules/taxonomy/openai.kdl +43 -0
- package/src/compat/rules/taxonomy/qwen.kdl +33 -0
- package/src/compat/rules/taxonomy/stepfun.kdl +5 -0
- package/src/compat/rules/taxonomy/unknown.kdl +3 -0
- package/src/compat/rules/taxonomy/xai.kdl +12 -0
- package/src/compat/rules.d.json.ts +5 -0
- package/src/compat/rules.json +16984 -0
- package/src/compat/taxonomy.ts +452 -0
- package/src/compat/types.ts +588 -0
- package/src/discovery/antigravity.ts +5 -6
- package/src/discovery/codex.ts +22 -7
- package/src/discovery/cursor-proto.ts +7 -7
- package/src/discovery/cursor.ts +47 -58
- package/src/discovery/devin-proto.ts +613 -0
- package/src/discovery/devin.ts +358 -52
- package/src/discovery/gemini-cli.ts +14 -11
- package/src/discovery/gemini.ts +2 -0
- package/src/identity/dialect.ts +2 -2
- package/src/identity/id.ts +12 -0
- package/src/identity/index.ts +3 -3
- package/src/identity/metrics.ts +165 -0
- package/src/identity/reference.ts +37 -5
- package/src/index.ts +1 -1
- package/src/model-manager.ts +19 -6
- package/src/model-thinking.ts +6 -810
- package/src/model-tokenizer.ts +37 -44
- package/src/models.json +89584 -22358
- package/src/models.ts +6 -1
- package/src/provider-models/bundled-references.ts +3 -1
- package/src/provider-models/cline-pass.ts +226 -0
- package/src/provider-models/descriptors.ts +18 -0
- package/src/provider-models/google.ts +14 -5
- package/src/provider-models/models-dev-policies.ts +4 -29
- package/src/provider-models/ollama.ts +15 -2
- package/src/provider-models/openai-compat.ts +798 -520
- package/src/provider-models/special.ts +211 -12
- package/src/types.ts +214 -11
- package/src/wire/cline-pass.ts +35 -0
- package/src/wire/codex.ts +23 -2
- package/src/wire/devin-proto.ts +30 -0
- package/src/wire/devin.ts +72 -0
- package/src/wire/github-copilot.ts +49 -7
- package/THIRD-PARTY-NOTICES.txt +0 -22909
- package/dist/types/build.d.ts +0 -19
- package/dist/types/compat/anthropic.d.ts +0 -18
- package/dist/types/compat/apply.d.ts +0 -7
- package/dist/types/compat/bedrock.d.ts +0 -3
- package/dist/types/compat/devin.d.ts +0 -9
- package/dist/types/compat/openai.d.ts +0 -28
- package/dist/types/discovery/antigravity.d.ts +0 -70
- package/dist/types/discovery/codex.d.ts +0 -36
- package/dist/types/discovery/cursor-proto.d.ts +0 -5368
- package/dist/types/discovery/cursor.d.ts +0 -29
- package/dist/types/discovery/devin-proto.d.ts +0 -1549
- package/dist/types/discovery/devin.d.ts +0 -24
- package/dist/types/discovery/gemini-cli.d.ts +0 -33
- package/dist/types/discovery/gemini.d.ts +0 -25
- package/dist/types/discovery/gitlab-duo-workflow.d.ts +0 -30
- package/dist/types/discovery/index.d.ts +0 -7
- package/dist/types/discovery/openai-compatible.d.ts +0 -89
- package/dist/types/discovery/protobuf.d.ts +0 -102
- package/dist/types/effort.d.ts +0 -10
- package/dist/types/fireworks-model-id.d.ts +0 -23
- package/dist/types/hosts.d.ts +0 -169
- package/dist/types/identity/bundled.d.ts +0 -3
- package/dist/types/identity/classify.d.ts +0 -69
- package/dist/types/identity/dialect.d.ts +0 -3
- package/dist/types/identity/family.d.ts +0 -243
- package/dist/types/identity/id.d.ts +0 -12
- package/dist/types/identity/index.d.ts +0 -8
- package/dist/types/identity/markers.d.ts +0 -4
- package/dist/types/identity/priority.d.ts +0 -1
- package/dist/types/identity/reference.d.ts +0 -29
- package/dist/types/index.d.ts +0 -19
- package/dist/types/model-cache.d.ts +0 -23
- package/dist/types/model-manager.d.ts +0 -93
- package/dist/types/model-thinking.d.ts +0 -81
- package/dist/types/model-tokenizer.d.ts +0 -8
- package/dist/types/models.d.ts +0 -17
- package/dist/types/openai-pricing.d.ts +0 -17
- package/dist/types/provider-models/bundled-references.d.ts +0 -13
- package/dist/types/provider-models/cache-provider-id.d.ts +0 -11
- package/dist/types/provider-models/descriptor-types.d.ts +0 -76
- package/dist/types/provider-models/descriptors.d.ts +0 -524
- package/dist/types/provider-models/google.d.ts +0 -29
- package/dist/types/provider-models/index.d.ts +0 -7
- package/dist/types/provider-models/models-dev-policies.d.ts +0 -8
- package/dist/types/provider-models/ollama.d.ts +0 -22
- package/dist/types/provider-models/openai-compat.d.ts +0 -703
- package/dist/types/provider-models/special.d.ts +0 -53
- package/dist/types/types.d.ts +0 -879
- package/dist/types/utils.d.ts +0 -20
- package/dist/types/variant-collapse.d.ts +0 -146
- package/dist/types/wire/alibaba-token-plan.d.ts +0 -22
- package/dist/types/wire/cloudflare-ai-gateway.d.ts +0 -18
- package/dist/types/wire/codex.d.ts +0 -66
- package/dist/types/wire/coreweave.d.ts +0 -12
- package/dist/types/wire/gemini-headers.d.ts +0 -62
- package/dist/types/wire/github-copilot.d.ts +0 -47
- package/dist/types/wire/image-fetchers.d.ts +0 -76
- package/src/compat/bedrock.ts +0 -153
- package/src/compat/devin.ts +0 -12
- package/src/identity/classify.ts +0 -242
- package/src/identity/family.ts +0 -496
- package/src/identity/markers.ts +0 -49
- 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.
|
|
5
|
+
## [1.1.9] - 2026-09-05
|
|
6
6
|
|
|
7
|
-
-
|
|
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
|
-
| `
|
|
13
|
-
| `
|
|
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
|
|
22
|
+
## models.json and rules.json are generated
|
|
23
23
|
|
|
24
|
-
Never edit `src/models.json` by hand
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
3
|
-
*
|
|
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 {
|
|
14
|
-
import {
|
|
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,
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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(
|
|
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
|
|
60
|
-
|
|
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
|
|
203
|
+
const policy = resolveModelPolicy(spec);
|
|
70
204
|
const supportsComputerUseConfig = explicitComputerUseConfig(spec);
|
|
71
|
-
|
|
205
|
+
const model: Model<TApi> = {
|
|
72
206
|
...spec,
|
|
73
207
|
name: cleanModelName(spec.name),
|
|
74
|
-
|
|
208
|
+
identity: policy.identity,
|
|
209
|
+
requiresGlyphTokenization: policy.identity.class === "anthropic",
|
|
75
210
|
tokenizer: spec.tokenizer ?? resolveModelTokenizer(spec.requestModelId ?? spec.id),
|
|
76
|
-
thinking:
|
|
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
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
+
}
|