@oh-my-pi/pi-catalog 18.2.7 → 18.2.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 +26 -3
- package/README.md +18 -18
- package/dist/types/compat/auth-ids.d.ts +2 -2
- package/dist/types/compat/axes.d.ts +2 -2
- package/dist/types/compat/catalog-policy.d.ts +7 -0
- package/dist/types/compat/output-limits.d.ts +3 -0
- package/dist/types/compat/provider-ids.d.ts +1 -1
- package/dist/types/compat/tools.d.ts +5 -0
- package/dist/types/compat/types.d.ts +2 -2
- package/dist/types/provider-models/openai-compat.d.ts +26 -0
- package/dist/types/types.d.ts +5 -2
- package/dist/types/wire/singularityapi.d.ts +29 -0
- package/package.json +38 -38
- package/src/compat/auth-ids.ts +4 -0
- package/src/compat/axes.ts +21 -2
- package/src/compat/catalog-policy.ts +28 -0
- package/src/compat/output-limits.ts +12 -0
- package/src/compat/provider-ids.ts +2 -0
- package/src/compat/resolve.ts +4 -2
- package/src/compat/rules/README.md +34 -33
- package/src/compat/rules/auth/_order.kdl +1 -1
- package/src/compat/rules/auth/singularityapi-dev.kdl +22 -0
- package/src/compat/rules/auth/singularityapi-tech.kdl +23 -0
- package/src/compat/rules/classes/gpt-oss.kdl +3 -0
- package/src/compat/rules/classes/xai.kdl +3 -3
- package/src/compat/rules/providers/amazon-bedrock.kdl +1 -1
- package/src/compat/rules/providers/anthropic.kdl +1 -1
- package/src/compat/rules/providers/cloudflare-ai-gateway.kdl +1 -1
- package/src/compat/rules/providers/commandcode.kdl +1 -1
- package/src/compat/rules/providers/cursor.kdl +1 -1
- package/src/compat/rules/providers/google-antigravity.kdl +5 -0
- package/src/compat/rules/providers/kilo.kdl +1 -1
- package/src/compat/rules/providers/litellm.kdl +1 -1
- package/src/compat/rules/providers/native-tools.kdl +4 -0
- package/src/compat/rules/providers/openai.kdl +58 -0
- package/src/compat/rules/providers/opencode-zen.kdl +1 -1
- package/src/compat/rules/providers/openrouter.kdl +108 -0
- package/src/compat/rules/providers/output-limits.kdl +4 -0
- package/src/compat/rules/providers/singularityapi-dev.kdl +92 -0
- package/src/compat/rules/providers/singularityapi-tech.kdl +72 -0
- package/src/compat/rules/providers/tool-free-history.kdl +6 -0
- package/src/compat/rules/providers/vercel-ai-gateway.kdl +1 -1
- package/src/compat/rules/providers/xai-oauth.kdl +8 -1
- package/src/compat/rules/providers/xai.kdl +4 -4
- package/src/compat/rules/providers/xiaomi-token-plan-cn.kdl +23 -0
- package/src/compat/rules/providers/zenmux.kdl +1 -1
- package/src/compat/rules/runtime/behavior.kdl +2 -0
- package/src/compat/rules.json +1 -1
- package/src/compat/tools.ts +12 -0
- package/src/compat/types.ts +2 -2
- package/src/discovery/devin.ts +59 -34
- package/src/models.json +1 -1
- package/src/provider-models/cache-provider-id.ts +31 -0
- package/src/provider-models/descriptors.ts +4 -0
- package/src/provider-models/openai-compat.ts +390 -119
- package/src/types.ts +19 -1
- package/src/wire/singularityapi.ts +34 -0
|
@@ -50,14 +50,14 @@ class "anthropic" {
|
|
|
50
50
|
|
|
51
51
|
Classification trims and lowercases the full model identifier. The **bare name** is the segment after its final `/`. Matcher tokens are also lowercased while parsing.
|
|
52
52
|
|
|
53
|
-
| Node
|
|
54
|
-
|
|
|
55
|
-
| `exact "token"`
|
|
56
|
-
| `bounded "token"`
|
|
57
|
-
| `namespace "token"`
|
|
58
|
-
| `namespace "token" bounded=#true` |
|
|
59
|
-
| `prefix "token"`
|
|
60
|
-
| `glob "pattern"`
|
|
53
|
+
| Node | Rank | Match |
|
|
54
|
+
| --------------------------------- | ---: | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
55
|
+
| `exact "token"` | 4 | The whole bare name equals `token`. |
|
|
56
|
+
| `bounded "token"` | 3 | The bare name equals `token`, or starts with it followed by `-`, `_`, `.`, `:`, or an ASCII digit. |
|
|
57
|
+
| `namespace "token"` | 2 | A non-empty `/`-separated segment of the full identifier equals `token`. |
|
|
58
|
+
| `namespace "token" bounded=#true` | 2 | Split the full identifier on `/`, `.`, and `:`; a segment must satisfy the bounded rule above. This is the only matcher property. |
|
|
59
|
+
| `prefix "token"` | 1 | The bare name starts with `token`. |
|
|
60
|
+
| `glob "pattern"` | 0 | An anchored `*` wildcard match over the bare name. `*` spans any substring; all non-wildcard text remains anchored in order. |
|
|
61
61
|
|
|
62
62
|
A class match is ranked by `(matcher-kind rank, token byte length)`. The greatest tuple wins. Equal tuples from different classes are an ambiguity error; source order is not a tiebreak. If nothing matches, classification returns class `unknown` with no family or revision.
|
|
63
63
|
|
|
@@ -93,16 +93,16 @@ revision skip-bare "o1" "o3" "o4"
|
|
|
93
93
|
|
|
94
94
|
Optional properties are:
|
|
95
95
|
|
|
96
|
-
| Property
|
|
97
|
-
|
|
|
98
|
-
| `provider`
|
|
99
|
-
| `logical`
|
|
100
|
-
| `class`
|
|
101
|
-
| `family`
|
|
102
|
-
| `revision`
|
|
103
|
-
| `effort`
|
|
104
|
-
| `thinking-variant` | Boolean marker for a separately exposed thinking sibling.
|
|
105
|
-
| `expires-at-ms`
|
|
96
|
+
| Property | Shape and meaning |
|
|
97
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------------------- |
|
|
98
|
+
| `provider` | Exact provider key, compared case-insensitively. A matching provider-specific override wins over a provider-agnostic one. |
|
|
99
|
+
| `logical` | Corrected logical model identifier. |
|
|
100
|
+
| `class` | Corrected class ID; a non-empty string. |
|
|
101
|
+
| `family` | Corrected product-family ID; a non-empty string. |
|
|
102
|
+
| `revision` | One to three unsigned 8-bit components separated by `.` or `-`. |
|
|
103
|
+
| `effort` | `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`. |
|
|
104
|
+
| `thinking-variant` | Boolean marker for a separately exposed thinking sibling. |
|
|
105
|
+
| `expires-at-ms` | Non-negative Unix time in milliseconds. The override is inactive when the observation time is at or after this value. |
|
|
106
106
|
|
|
107
107
|
The tuple `(provider, selector-kind, selector)` must also be unique, including provider-agnostic selectors. Active exact overrides take precedence over every glob. Within each selector kind, provider-scoped overrides precede provider-agnostic ones; matching globs rank by non-wildcard byte count. Equal-ranked globs are an ambiguity error, never resolved by declaration order. When no observation time is supplied, an expiring override remains active.
|
|
108
108
|
|
|
@@ -124,6 +124,7 @@ collapse {
|
|
|
124
124
|
provider-alias "devin" "opus" "claude-opus-5"
|
|
125
125
|
}
|
|
126
126
|
```
|
|
127
|
+
|
|
127
128
|
`variant-family` declares one reviewed provider-scoped collapsed family: positional provider and logical id, `name=` display name, and a body of `members "a" "b" …` (wire ids in priority order), `route "<tier>" "<wire-id>"` per effort tier (`off` included), and optional `mode`, `efforts`, `default-level`, `default-member`, `retired-members`, `effort-budget "<tier>" <n>`, `requires-effort`, `suppress-when-off`, `no-thinking`, `preserve-absent-effort-routes`, and `extra-aliases`. A `{rev}` placeholder in the logical id makes the node a **template**: it is instantiated once per revision found in live ids (`gemini-{rev}-flash` matches `gemini-3.8-flash-low` → family `gemini-3.8-flash`), every wire id in the body and the `name=` carry the same placeholder, and an optional `revision=` constraint (`">=3.6"`) bounds the generations it applies to. A concrete family with the same instantiated id wins over the template. `provider-alias` maps one provider-scoped selector spelling onto a logical id without making it a family member.
|
|
128
129
|
|
|
129
130
|
`thinking-suffix` accepts one non-empty suffix and no properties. `pair-token` declares bounded (possibly infix) tokens naming the thinking sibling of a live bare twin (`sonar-reasoning-pro` beside `sonar-pro`); it drives thinking-pair derivation only — never identity suffix collapse — and negated `no-`/`non-` forms never match. `effort-suffix` additionally requires `tier` with one of the effort values above, and may have `except-bare-prefix`. `routing-variant-suffix` takes one non-empty suffix followed by one or more provider IDs: a wire identifier carrying the suffix on one of those providers is a **routing variant** of its plain identifier — discovery derives base-model metadata from the plain bundled SKU while keeping the suffixed wire identifier for requests; routing variants never participate in effort collapse. `effort-lane-suffix` takes one non-empty lane suffix followed by one or more provider IDs, plus an optional `bare-prefix` gate: on a declared provider, an identifier ending in the lane suffix collapses the effort suffix wedged before the lane token while keeping the lane on the logical id. `effort-family` takes a provider, the canonical logical id, and zero or more exact aliases that fold onto it.
|
|
@@ -151,7 +152,7 @@ discovery {
|
|
|
151
152
|
|
|
152
153
|
## Cascade grammar
|
|
153
154
|
|
|
154
|
-
A cascade document starts with `class` or `
|
|
155
|
+
A cascade document starts with `class`, `provider`, or `on-api`. Root `on-api` declares a transport contract independent of model identity and provider name. Every selector adds a conjunct to the current rule. `on` scopes by deployment provider; `on-api` scopes by request adapter, including custom provider names. Axis directives may appear directly in any permitted scope, and nested selector blocks may appear alongside them.
|
|
155
156
|
|
|
156
157
|
```kdl
|
|
157
158
|
class "gemini" {
|
|
@@ -178,15 +179,15 @@ provider "openrouter" {
|
|
|
178
179
|
|
|
179
180
|
### Selectors and nesting
|
|
180
181
|
|
|
181
|
-
| Selector
|
|
182
|
-
|
|
|
183
|
-
| `class`
|
|
184
|
-
| `provider` | `provider "id" { ... }`
|
|
185
|
-
| `on`
|
|
186
|
-
| `on-api`
|
|
187
|
-
| `family`
|
|
188
|
-
| `revision` | `revision ">=2.5 <4" { ... }`
|
|
189
|
-
| `models`
|
|
182
|
+
| Selector | Form | Matching semantics |
|
|
183
|
+
| ---------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
184
|
+
| `class` | `class "id" { ... }` | Exact class ID. At document root it may contain `on`, `on-api`, `family`, `revision`, and `models`. Under `provider` it may contain `family`, `revision`, and `models`. |
|
|
185
|
+
| `provider` | `provider "id" { ... }` | Exact provider ID. It is root-only and may contain `class` and `models`. |
|
|
186
|
+
| `on` | `on "provider-a" "provider-b" { ... }` | One or more provider IDs, combined as OR. It is allowed only under a root `class`, and may contain `family`, `revision`, and `models`. |
|
|
187
|
+
| `on-api` | `on-api "adapter-a" "adapter-b" { ... }` | One or more request adapter IDs, combined as OR. At document root it may contain `class` and `models`; under a root `class` it may contain `family`, `revision`, and `models`. |
|
|
188
|
+
| `family` | `family "id" { ... }` | Exact classified family ID. It may contain `revision` and `models`. A target with no family does not match. |
|
|
189
|
+
| `revision` | `revision ">=2.5 <4" { ... }` | A non-empty, whitespace-separated conjunction of comparisons. It may contain `models`. A target with no revision does not match. |
|
|
190
|
+
| `models` | `models "id" "vendor/*" { ... }` | One or more alternatives, combined as OR. It cannot contain another selector. `token="name"` matches an ASCII-case-insensitive token bounded by non-alphanumerics. |
|
|
190
191
|
|
|
191
192
|
Class, provider/`on`, `on-api`, and family selector values are compared exactly and case-sensitively to the structured resolve target. Revision operators are `>=`, `>`, `<=`, `<`, and `=`; operands have one to three dot-separated unsigned 8-bit components, omitted components zero.
|
|
192
193
|
|
|
@@ -401,17 +402,17 @@ Only `discovery` enrolls a provider in `generate-models.ts`; providers without i
|
|
|
401
402
|
|
|
402
403
|
### Seed rows
|
|
403
404
|
|
|
404
|
-
A `seed`
|
|
405
|
+
A `seed` _defines_ bundled rows for providers whose catalog cannot be discovered at generation time — credential-scoped rosters, unauthenticated regens, or models ahead of upstream catalogs. Every other stratum patches rows; this one authors them. Runtime model managers hand the rows to `staticModels` through `seedModels(provider)`; the generator bundles them per the seed's `bundle` policy. Values are literal — a seed never derives from another provider's row, and pricing is never borrowed.
|
|
405
406
|
|
|
406
407
|
`seed` properties: `api` and `base-url` are per-row defaults (a `model` may override either with the same property names); `bundle` defaults to `always`; `precedence="seed"` is optional. `model` takes the wire id positionally, requires `name=`, and its body MUST declare `reasoning`, `input` (`"text"` and/or `"image"`), `cost` (all four per-million rates), and `limits` (`context=` / `max-tokens=`, an omitted limit is `null`); `supports-tools #true` is optional. Any other directive is an axis from the cascade vocabulary: thinking axes become the row's explicit `thinking` (then `thinking-mode` and `thinking-efforts` are both required), wire axes become its explicit `compat` and must apply to the row's API, and catalog axes are rejected because they stay rule-owned in the cascade block. Explicit `thinking`/`compat` on a seed row win over the cascade exactly as they do for any authored spec.
|
|
407
408
|
|
|
408
409
|
`bundle` decides when the generator includes the rows:
|
|
409
410
|
|
|
410
|
-
| Policy
|
|
411
|
-
|
|
|
412
|
-
| `always`
|
|
411
|
+
| Policy | Rows enter the bundle |
|
|
412
|
+
| ---------- | ------------------------------------------------------------------------- |
|
|
413
|
+
| `always` | Every regeneration. Same-id upstream/discovery rows win dedup. |
|
|
413
414
|
| `fallback` | Only when the provider's authoritative catalog discovery did not succeed. |
|
|
414
|
-
| `empty`
|
|
415
|
+
| `empty` | Only when no other source produced a row for the provider. |
|
|
415
416
|
|
|
416
417
|
`precedence="seed"` prepends the rows after the previous-snapshot merge and cross-provider reference fills, so the authored row wins dedup and same-id rows on other hosts never overwrite its name or capabilities (QwenCloud Token Plan, Meta). The default `upstream` precedence appends before the snapshot merge, so the current seed — not a stale snapshot copy — is the fallback row.
|
|
417
418
|
|
|
@@ -10,4 +10,4 @@ login-order "openai-codex" "anthropic" "zai" "zai-coding-plan" "kimi-code" "open
|
|
|
10
10
|
"qianfan" "venice" "siliconflow" "siliconflow-cn" "synthetic" "nanogpt" "wafer-serverless" "coreweave" \
|
|
11
11
|
"vercel-ai-gateway" "cloudflare-ai-gateway" "litellm" "kilo" "zenmux" "opencode-zen" "opencode-go" \
|
|
12
12
|
"yolo-auto" "tavily" "kagi" "exa" "parallel" "typesafe" "ollama" "ollama-cloud" "lm-studio" "llama.cpp" "vllm" \
|
|
13
|
-
"gmi-cloud" "stencil"
|
|
13
|
+
"gmi-cloud" "stencil" "singularityapi-dev" "singularityapi-tech"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// SingularityAPI universal inference gateway (api.singularityapi.dev): 300+
|
|
2
|
+
// models behind one OpenAI-compatible endpoint, pay-as-you-go `sk-sapi-...`
|
|
3
|
+
// bearer keys, per-million-token tariffs published per model. SingularityAPI
|
|
4
|
+
// ships two unrelated products behind one brand — this gateway and the
|
|
5
|
+
// slot-reserved DeepSeek lanes on api.singularityapi.tech — with disjoint
|
|
6
|
+
// keys, dashboards, effort ladders, and billing, so each owns its own
|
|
7
|
+
// provider id, env var, and login flow (neither key works on the other host,
|
|
8
|
+
// verified 2026-09-22).
|
|
9
|
+
// Key validation probes the non-billable `GET /v1/models`: it answers 401
|
|
10
|
+
// `invalid_api_key` for a missing, malformed, or unknown key (verified
|
|
11
|
+
// 2026-09-22), so a bad key is rejected without spending.
|
|
12
|
+
auth "singularityapi-dev" {
|
|
13
|
+
name "SingularityAPI"
|
|
14
|
+
env "SINGULARITYAPI_DEV_API_KEY"
|
|
15
|
+
login "api-key" {
|
|
16
|
+
auth-url "https://app.singularityapi.dev"
|
|
17
|
+
instructions "Create an API key from the SingularityAPI dashboard, then paste it here"
|
|
18
|
+
prompt "Paste your SingularityAPI API key" placeholder="sk-sapi-..."
|
|
19
|
+
normalize "strip-bearer"
|
|
20
|
+
validate "models-endpoint" label="SingularityAPI" url="https://api.singularityapi.dev/v1/models"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// SingularityAPI reserved DeepSeek lanes (api.singularityapi.tech, a LiteLLM
|
|
2
|
+
// front end in front of slot-reserved lanes) — the vendor's other product,
|
|
3
|
+
// separated from api.singularityapi.dev because the two share no key, no
|
|
4
|
+
// billing model, and no effort ladder. Usage here is charged against a booked
|
|
5
|
+
// reservation slot rather than prepaid credit: a valid key with no active
|
|
6
|
+
// slot answers 403 `permission_error` ("No active lane reservation for this
|
|
7
|
+
// key", verified 2026-09-22), so login succeeds while a slot is idle and
|
|
8
|
+
// inference needs one. Keys are lane-scoped `sk-...` bearer tokens issued
|
|
9
|
+
// from the dashboard.
|
|
10
|
+
// Key validation probes the non-billable `GET /v1/models`: it answers 401
|
|
11
|
+
// for a missing, malformed, or unknown key (verified 2026-09-21), so a bad
|
|
12
|
+
// key is rejected without spending.
|
|
13
|
+
auth "singularityapi-tech" {
|
|
14
|
+
name "SingularityAPI Reserved Lanes"
|
|
15
|
+
env "SINGULARITYAPI_TECH_API_KEY"
|
|
16
|
+
login "api-key" {
|
|
17
|
+
auth-url "https://app.singularityapi.tech/compute/billing"
|
|
18
|
+
instructions "Create a key from the SingularityAPI lanes dashboard, then paste it here"
|
|
19
|
+
prompt "Paste your SingularityAPI lanes key" placeholder="sk-..."
|
|
20
|
+
normalize "strip-bearer"
|
|
21
|
+
validate "models-endpoint" label="SingularityAPI Reserved Lanes" url="https://api.singularityapi.tech/v1/models"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -5,7 +5,7 @@ class "xai" {
|
|
|
5
5
|
// on both the API and OAuth surfaces; the multiplier form tracks
|
|
6
6
|
// stencil.so price updates. Zero-cost subscription rows carry no tier.
|
|
7
7
|
on "xai" "xai-oauth" {
|
|
8
|
-
models "grok-4.3" "grok-4.5" "grok-4.6" "grok-build-0.1" "grok-4.20*" {
|
|
8
|
+
models "grok-4.3" "grok-4.5" "grok-4.6" "grok-4.7" "grok-build-0.1" "grok-4.20*" {
|
|
9
9
|
long-context-cost {
|
|
10
10
|
input-threshold 200000
|
|
11
11
|
input-threshold-inclusive #true
|
|
@@ -26,10 +26,10 @@ class "xai" {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
// First-party xhigh-capable SKUs (grok-4.6, multi-agent) advertise xhigh.
|
|
29
|
+
// First-party xhigh-capable SKUs (grok-4.6, grok-4.7, multi-agent) advertise xhigh.
|
|
30
30
|
on "xai" "xai-oauth" {
|
|
31
31
|
family "grok" {
|
|
32
|
-
models "grok-4.6*" "grok-4.20-multi-agent*" {
|
|
32
|
+
models "grok-4.6*" "grok-4.7*" "grok-4.20-multi-agent*" {
|
|
33
33
|
thinking-efforts "minimal" "low" "medium" "high" "xhigh"
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "amazon-bedrock"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "amazon-bedrock" {
|
|
4
|
-
default-model "us.anthropic.claude-opus-
|
|
4
|
+
default-model "us.anthropic.claude-opus-5-5"
|
|
5
5
|
|
|
6
6
|
// The Converse assembler positions content blocks by wire index
|
|
7
7
|
// (`amazon-bedrock.ts`), so a block can land above text already rendered.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "anthropic"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "anthropic" {
|
|
4
|
-
default-model "claude-opus-
|
|
4
|
+
default-model "claude-opus-5-5"
|
|
5
5
|
env "ANTHROPIC_API_KEY"
|
|
6
6
|
discovery label="Anthropic"
|
|
7
7
|
web-search "anthropic"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "cloudflare-ai-gateway"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "cloudflare-ai-gateway" {
|
|
4
|
-
default-model "anthropic/claude-opus-
|
|
4
|
+
default-model "anthropic/claude-opus-5"
|
|
5
5
|
env "CLOUDFLARE_AI_GATEWAY_API_KEY"
|
|
6
6
|
discovery label="Cloudflare AI Gateway"
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// dials to a few further ids — MiniMaxAI/MiniMax-M3 and meta/muse-spark-1.3's
|
|
10
10
|
// `max` — which stay out of this change.
|
|
11
11
|
provider "commandcode" {
|
|
12
|
-
default-model "claude-sonnet-
|
|
12
|
+
default-model "claude-sonnet-5"
|
|
13
13
|
env "COMMAND_CODE_API_KEY" "COMMANDCODE_API_KEY"
|
|
14
14
|
allow-unauthenticated #true
|
|
15
15
|
dynamic-models-authoritative #true
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "cursor"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "cursor" {
|
|
4
|
-
default-model "claude-
|
|
4
|
+
default-model "claude-opus-5-high"
|
|
5
5
|
env "CURSOR_ACCESS_TOKEN"
|
|
6
6
|
discovery label="Cursor" oauth-provider="cursor" {
|
|
7
7
|
env "CURSOR_API_KEY"
|
|
@@ -17,6 +17,11 @@ provider "google-antigravity" {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
// Routed wire profiles overwrite caller caps with fixed output limits.
|
|
21
|
+
// Conservatively reject requested bounds for this provider, including
|
|
22
|
+
// logical ids whose effort routing selects a profiled wire id later.
|
|
23
|
+
preserves-max-output-tokens #false
|
|
24
|
+
|
|
20
25
|
class "anthropic" {
|
|
21
26
|
family "opus" {
|
|
22
27
|
thinking-mode "budget"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "kilo"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "kilo" {
|
|
4
|
-
default-model "anthropic/claude-opus-
|
|
4
|
+
default-model "anthropic/claude-opus-5"
|
|
5
5
|
env "KILO_API_KEY"
|
|
6
6
|
discovery label="Kilo Gateway" allow-unauthenticated=#true
|
|
7
7
|
|
|
@@ -4,7 +4,9 @@ provider "openai" {
|
|
|
4
4
|
default-model "gpt-5.5"
|
|
5
5
|
env "OPENAI_API_KEY"
|
|
6
6
|
kind-apis {
|
|
7
|
+
embedding "openai-embeddings"
|
|
7
8
|
image "openai-responses"
|
|
9
|
+
stt "openai-transcriptions"
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
// Daybreak models are approval-gated first-party Responses models that are
|
|
@@ -33,6 +35,62 @@ provider "openai" {
|
|
|
33
35
|
cost input=12.5 output=75 cache-read=1.25 cache-write=15.625
|
|
34
36
|
limits context=400000 max-tokens=128000
|
|
35
37
|
}
|
|
38
|
+
|
|
39
|
+
// Catalog cost fields are per 1M tokens: GPT transcribers map documented
|
|
40
|
+
// audio-input/output-token rates directly. Whisper's $0.006/min duration
|
|
41
|
+
// tariff has no token-cost representation, so it remains zero and the
|
|
42
|
+
// transcription response's provider-reported usage/cost is authoritative.
|
|
43
|
+
model "whisper-1" name="Whisper 1" api="openai-transcriptions" base-url="https://api.openai.com/v1" {
|
|
44
|
+
reasoning #false
|
|
45
|
+
input "text"
|
|
46
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
47
|
+
limits
|
|
48
|
+
supports-tools #false
|
|
49
|
+
}
|
|
50
|
+
model "gpt-4o-transcribe" name="GPT-4o Transcribe" api="openai-transcriptions" base-url="https://api.openai.com/v1" {
|
|
51
|
+
reasoning #false
|
|
52
|
+
input "text"
|
|
53
|
+
cost input=2.5 output=10 cache-read=0 cache-write=0
|
|
54
|
+
limits context=16000 max-tokens=2000
|
|
55
|
+
supports-tools #false
|
|
56
|
+
}
|
|
57
|
+
model "gpt-4o-mini-transcribe" name="GPT-4o Mini Transcribe" api="openai-transcriptions" base-url="https://api.openai.com/v1" {
|
|
58
|
+
reasoning #false
|
|
59
|
+
input "text"
|
|
60
|
+
cost input=1.25 output=5 cache-read=0 cache-write=0
|
|
61
|
+
limits context=16000 max-tokens=2000
|
|
62
|
+
supports-tools #false
|
|
63
|
+
}
|
|
64
|
+
// OpenAI publishes embedding prices per million input tokens; embedding
|
|
65
|
+
// responses have no output-token charge.
|
|
66
|
+
model "text-embedding-3-small" name="Text Embedding 3 Small" api="openai-embeddings" base-url="https://api.openai.com/v1" {
|
|
67
|
+
reasoning #false
|
|
68
|
+
input "text"
|
|
69
|
+
cost input=0.02 output=0 cache-read=0 cache-write=0
|
|
70
|
+
limits context=8192
|
|
71
|
+
supports-tools #false
|
|
72
|
+
}
|
|
73
|
+
model "text-embedding-3-large" name="Text Embedding 3 Large" api="openai-embeddings" base-url="https://api.openai.com/v1" {
|
|
74
|
+
reasoning #false
|
|
75
|
+
input "text"
|
|
76
|
+
cost input=0.13 output=0 cache-read=0 cache-write=0
|
|
77
|
+
limits context=8192
|
|
78
|
+
supports-tools #false
|
|
79
|
+
}
|
|
80
|
+
model "text-embedding-ada-002" name="Text Embedding Ada 002" api="openai-embeddings" base-url="https://api.openai.com/v1" {
|
|
81
|
+
reasoning #false
|
|
82
|
+
input "text"
|
|
83
|
+
cost input=0.1 output=0 cache-read=0 cache-write=0
|
|
84
|
+
limits context=8192
|
|
85
|
+
supports-tools #false
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
models "whisper-1" "gpt-4o-transcribe" "gpt-4o-mini-transcribe" {
|
|
90
|
+
kind "stt"
|
|
91
|
+
}
|
|
92
|
+
models "text-embedding-3-small" "text-embedding-3-large" "text-embedding-ada-002" {
|
|
93
|
+
kind "embedding"
|
|
36
94
|
}
|
|
37
95
|
|
|
38
96
|
// Replaces the strict-mode provider whitelist entry.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "opencode-zen"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "opencode-zen" {
|
|
4
|
-
default-model "claude-opus-
|
|
4
|
+
default-model "claude-opus-5"
|
|
5
5
|
env "OPENCODE_API_KEY"
|
|
6
6
|
dynamic-models-authoritative #true
|
|
7
7
|
|
|
@@ -5,7 +5,12 @@ provider "openrouter" {
|
|
|
5
5
|
env "OPENROUTER_API_KEY"
|
|
6
6
|
discovery label="OpenRouter" allow-unauthenticated=#true
|
|
7
7
|
kind-apis {
|
|
8
|
+
embedding "openai-embeddings"
|
|
8
9
|
image "openrouter-images"
|
|
10
|
+
rerank "openrouter-rerank"
|
|
11
|
+
video "openrouter-video"
|
|
12
|
+
tts "openai-speech"
|
|
13
|
+
stt "openai-transcriptions"
|
|
9
14
|
}
|
|
10
15
|
web-search "openrouter"
|
|
11
16
|
|
|
@@ -19,10 +24,113 @@ provider "openrouter" {
|
|
|
19
24
|
cost input=0.042 output=0 cache-read=0 cache-write=0
|
|
20
25
|
limits context=32000 max-tokens=28800
|
|
21
26
|
}
|
|
27
|
+
|
|
28
|
+
// OpenRouter's STT roster mixes per-token and duration-based prices.
|
|
29
|
+
// Token-priced GPT rows map per-token rates to catalog per-million costs;
|
|
30
|
+
// duration-priced rows remain zero because ModelCost has no seconds axis.
|
|
31
|
+
model "openai/whisper-1" name="OpenAI: Whisper 1" api="openai-transcriptions" base-url="https://openrouter.ai/api/v1" {
|
|
32
|
+
reasoning #false
|
|
33
|
+
input "text"
|
|
34
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
35
|
+
limits
|
|
36
|
+
supports-tools #false
|
|
37
|
+
}
|
|
38
|
+
model "openai/whisper-large-v3" name="OpenAI: Whisper Large V3" api="openai-transcriptions" base-url="https://openrouter.ai/api/v1" {
|
|
39
|
+
reasoning #false
|
|
40
|
+
input "text"
|
|
41
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
42
|
+
limits
|
|
43
|
+
supports-tools #false
|
|
44
|
+
}
|
|
45
|
+
model "openai/gpt-4o-transcribe" name="OpenAI: GPT-4o Transcribe" api="openai-transcriptions" base-url="https://openrouter.ai/api/v1" {
|
|
46
|
+
reasoning #false
|
|
47
|
+
input "text"
|
|
48
|
+
cost input=2.5 output=10 cache-read=0 cache-write=0
|
|
49
|
+
limits context=128000 max-tokens=115200
|
|
50
|
+
supports-tools #false
|
|
51
|
+
}
|
|
52
|
+
model "microsoft/mai-transcribe-1.5" name="Microsoft AI: MAI-Transcribe 1.5" api="openai-transcriptions" base-url="https://openrouter.ai/api/v1" {
|
|
53
|
+
reasoning #false
|
|
54
|
+
input "text"
|
|
55
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
56
|
+
limits
|
|
57
|
+
supports-tools #false
|
|
58
|
+
}
|
|
59
|
+
model "microsoft/mai-transcribe-2" name="Microsoft AI: MAI-Transcribe 2" api="openai-transcriptions" base-url="https://openrouter.ai/api/v1" {
|
|
60
|
+
reasoning #false
|
|
61
|
+
input "text"
|
|
62
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
63
|
+
limits
|
|
64
|
+
supports-tools #false
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// OpenRouter bills reranking per 1,000 searches, which has no catalog cost
|
|
68
|
+
// axis. Keep token costs at zero; the provider-reported response cost is authoritative.
|
|
69
|
+
model "cohere/rerank-v3.5" name="Cohere: Rerank v3.5" api="openrouter-rerank" base-url="https://openrouter.ai/api/v1" {
|
|
70
|
+
reasoning #false
|
|
71
|
+
input "text"
|
|
72
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
73
|
+
limits context=4096 max-tokens=3686
|
|
74
|
+
supports-tools #false
|
|
75
|
+
}
|
|
76
|
+
// Bundled fallbacks keep the gateway useful offline; live
|
|
77
|
+
// `/embeddings/models` discovery refreshes this roster and its per-token
|
|
78
|
+
// pricing. Catalog token costs are per million input tokens.
|
|
79
|
+
model "openai/text-embedding-3-small" name="OpenAI: Text Embedding 3 Small" api="openai-embeddings" base-url="https://openrouter.ai/api/v1" {
|
|
80
|
+
reasoning #false
|
|
81
|
+
input "text"
|
|
82
|
+
cost input=0.02 output=0 cache-read=0 cache-write=0
|
|
83
|
+
limits context=8192
|
|
84
|
+
supports-tools #false
|
|
85
|
+
}
|
|
86
|
+
model "qwen/qwen3-embedding-8b" name="Qwen: Qwen3 Embedding 8B" api="openai-embeddings" base-url="https://openrouter.ai/api/v1" {
|
|
87
|
+
reasoning #false
|
|
88
|
+
input "text"
|
|
89
|
+
cost input=0.01 output=0 cache-read=0 cache-write=0
|
|
90
|
+
limits context=32768
|
|
91
|
+
supports-tools #false
|
|
92
|
+
}
|
|
93
|
+
// OpenRouter bills generated video by output second and resolution/SKU,
|
|
94
|
+
// which ModelCost cannot represent. Keep token costs at zero; poll-reported
|
|
95
|
+
// cost is authoritative. Live `/videos/models` discovery refreshes the roster.
|
|
96
|
+
model "google/veo-3.1" name="Google: Veo 3.1" api="openrouter-video" base-url="https://openrouter.ai/api/v1" {
|
|
97
|
+
reasoning #false
|
|
98
|
+
input "text" "image"
|
|
99
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
100
|
+
limits
|
|
101
|
+
supports-tools #false
|
|
102
|
+
}
|
|
103
|
+
model "minimax/hailuo-3" name="MiniMax: H3" api="openrouter-video" base-url="https://openrouter.ai/api/v1" {
|
|
104
|
+
reasoning #false
|
|
105
|
+
input "text" "image"
|
|
106
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
107
|
+
limits
|
|
108
|
+
supports-tools #false
|
|
109
|
+
}
|
|
110
|
+
model "alibaba/wan-2.7" name="Alibaba: Wan 2.7" api="openrouter-video" base-url="https://openrouter.ai/api/v1" {
|
|
111
|
+
reasoning #false
|
|
112
|
+
input "text" "image"
|
|
113
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
114
|
+
limits
|
|
115
|
+
supports-tools #false
|
|
116
|
+
}
|
|
22
117
|
}
|
|
23
118
|
models "~typesafe/*" "typesafe/*" {
|
|
24
119
|
kind "judge"
|
|
25
120
|
}
|
|
121
|
+
models "cohere/rerank-v3.5" {
|
|
122
|
+
kind "rerank"
|
|
123
|
+
}
|
|
124
|
+
models "openai/text-embedding-3-small" "qwen/qwen3-embedding-8b" {
|
|
125
|
+
kind "embedding"
|
|
126
|
+
}
|
|
127
|
+
models "google/veo-3.1" "minimax/hailuo-3" "alibaba/wan-2.7" {
|
|
128
|
+
kind "video"
|
|
129
|
+
}
|
|
130
|
+
models "openai/whisper-1" "openai/whisper-large-v3" "openai/gpt-4o-transcribe" \
|
|
131
|
+
"microsoft/mai-transcribe-1.5" "microsoft/mai-transcribe-2" {
|
|
132
|
+
kind "stt"
|
|
133
|
+
}
|
|
26
134
|
|
|
27
135
|
// Replaces the OpenRouter provider wire-model-id dispatch branch.
|
|
28
136
|
wire-model-id-mode "openrouter"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// SingularityAPI universal inference gateway (api.singularityapi.dev):
|
|
2
|
+
// one OpenAI-compatible endpoint for 300+ models (DeepSeek, Kimi, GLM,
|
|
3
|
+
// frontier flagships), `sapi_...` bearer keys issued from the dashboard at
|
|
4
|
+
// app.singularityapi.dev. `GET /v1/models` publishes each row's per-endpoint
|
|
5
|
+
// capabilities — context window, max/default output tokens, and per-million
|
|
6
|
+
// 12-decimal pricing strings — with `cache-control: no-store`, so discovery
|
|
7
|
+
// reads limits and tariffs live and no rows are frozen here.
|
|
8
|
+
//
|
|
9
|
+
// Deliberately no `discovery` node: live discovery needs a user credential,
|
|
10
|
+
// and enrolling would freeze one account's snapshot into models.json on every
|
|
11
|
+
// credential-less regen. The provider stays runtime-only and
|
|
12
|
+
// `dynamic-models-authoritative` prunes stale rows.
|
|
13
|
+
// The vendor's second product — slot-reserved DeepSeek lanes on
|
|
14
|
+
// api.singularityapi.tech — lives in `singularityapi-tech`: separate provider
|
|
15
|
+
// id because the two gateways publish conflicting effort ladders (`max`
|
|
16
|
+
// passes there and 400s here; `medium` is the reverse, both measured live
|
|
17
|
+
// 2026-09-22) and neither key works on the other host.
|
|
18
|
+
provider "singularityapi-dev" {
|
|
19
|
+
default-model "deepseek-v4-flash"
|
|
20
|
+
env "SINGULARITYAPI_DEV_API_KEY"
|
|
21
|
+
dynamic-models-authoritative #true
|
|
22
|
+
|
|
23
|
+
// Gateway-wide request shape, from the OpenAI-compatibility contract
|
|
24
|
+
// (docs.singularityapi.dev/get-started/open-ai-compatibility): chat
|
|
25
|
+
// completions accept `max_tokens` and `max_completion_tokens`
|
|
26
|
+
// interchangeably; the gateway normalizes to the model's canonical
|
|
27
|
+
// field. Unknown/reserved fields 400 instead of dropping, duplicate
|
|
28
|
+
// JSON keys and NaN/Infinity 400, context overflow 400s before spend.
|
|
29
|
+
// Rows the `models` rules below do not review inherit exactly this
|
|
30
|
+
// shape instead of the openai-completions default, because the roster
|
|
31
|
+
// is account-scoped and unreviewed model ids are expected.
|
|
32
|
+
max-tokens-field "max_tokens"
|
|
33
|
+
|
|
34
|
+
// Reviewed lane rules for the DeepSeek rows the gateway publishes,
|
|
35
|
+
// keyed as case-insensitive globs (`models` exact selectors compare the
|
|
36
|
+
// raw id verbatim while the compiler lowercases them, so exact rules
|
|
37
|
+
// can never match mixed-case wire ids). DeepSeek V4 Flash rows classify
|
|
38
|
+
// deepseek/flash by taxonomy but publish no reasoning metadata, so the
|
|
39
|
+
// upgrade rule owns the measured low/medium/high ladder; reasoning arrives
|
|
40
|
+
// as top-level `reasoning_content` on messages and streamed deltas, and
|
|
41
|
+
// `none` forces it off. V4 Pro the same, with the Pro ladder.
|
|
42
|
+
//
|
|
43
|
+
// Ladder measured against the live gateway 2026-09-22: `none`, `minimal`,
|
|
44
|
+
// `low`, `medium`, `high` pass admission while `xhigh`, `max`, integer and
|
|
45
|
+
// unknown efforts answer 400 `invalid_request` — admission validation runs
|
|
46
|
+
// before the credit reservation, so the probe sorted accepted from rejected
|
|
47
|
+
// at 402 vs 400 without spending a cent. `max` in particular is a
|
|
48
|
+
// reserve-lane-only tier (`singularityapi-tech`); sending it here turned
|
|
49
|
+
// every DeepSeek request into a 400.
|
|
50
|
+
models "*deepseek-v4-flash*" {
|
|
51
|
+
thinking-upgrade-neutral #true
|
|
52
|
+
max-tokens-field "max_tokens"
|
|
53
|
+
thinking-efforts "low" "medium" "high"
|
|
54
|
+
reasoning-disable-mode "none-effort"
|
|
55
|
+
reasoning-content-field "reasoning_content"
|
|
56
|
+
}
|
|
57
|
+
models "*deepseek-v4-pro*" {
|
|
58
|
+
thinking-upgrade-neutral #true
|
|
59
|
+
max-tokens-field "max_tokens"
|
|
60
|
+
thinking-efforts "low" "medium" "high"
|
|
61
|
+
reasoning-disable-mode "none-effort"
|
|
62
|
+
reasoning-content-field "reasoning_content"
|
|
63
|
+
}
|
|
64
|
+
// Responses-capable flagships (gpt-5.6-sol/terra/luna): five-tier
|
|
65
|
+
// low..max ladder with the wire-exact off switch, matching the
|
|
66
|
+
// first-party GPT-5.6 rows. `thinking-upgrade-neutral` is what makes the
|
|
67
|
+
// ladder real: the wire publishes no reasoning metadata, so without it the
|
|
68
|
+
// rows stay non-reasoning and omp sends no `reasoning_effort` at all —
|
|
69
|
+
// which the gateway rejects (400 from upstream) on chat completions
|
|
70
|
+
// whenever `tools` are present, exactly the case a coding agent hits.
|
|
71
|
+
models "gpt-5.6-sol" "gpt-5.6-terra" "gpt-5.6-luna" {
|
|
72
|
+
thinking-upgrade-neutral #true
|
|
73
|
+
thinking-efforts "low" "medium" "high" "xhigh" "max"
|
|
74
|
+
reasoning-disable-mode "none-effort"
|
|
75
|
+
}
|
|
76
|
+
// Gateway image models serve POST /v1/images/generations, never billed
|
|
77
|
+
// by tokens: FLUX per megapixel, GPT Image per image. The `kind` rules
|
|
78
|
+
// keep them out of chat; `mapSingularityApiModel` reads the same rows'
|
|
79
|
+
// `capabilities` and assigns the `openai-images` transport, so a new
|
|
80
|
+
// image id the roster adds works without a rule edit here.
|
|
81
|
+
models "flux-1-schnell" "flux-pro-1.1" {
|
|
82
|
+
kind "image"
|
|
83
|
+
}
|
|
84
|
+
models "gpt-image-2" "gpt-image-1.5" {
|
|
85
|
+
kind "image"
|
|
86
|
+
}
|
|
87
|
+
// The gateway's DeepSeek rows reject tool_choice: the API defaults to
|
|
88
|
+
// auto when tools exist. Matches the first-party DeepSeek transport.
|
|
89
|
+
models "*deepseek*" {
|
|
90
|
+
supports-tool-choice #false
|
|
91
|
+
}
|
|
92
|
+
}
|