@oh-my-pi/pi-catalog 18.2.5 → 18.2.7
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 +14 -0
- package/THIRD-PARTY-NOTICES.txt +0 -37
- package/dist/types/build.d.ts +7 -1
- package/dist/types/compat/auth-ids.d.ts +1 -1
- package/dist/types/compat/axes.d.ts +1 -1
- package/dist/types/compat/cascade.d.ts +3 -2
- package/dist/types/compat/provider-ids.d.ts +1 -1
- package/dist/types/compat/resolve.d.ts +2 -0
- package/dist/types/compat/taxonomy.d.ts +2 -2
- package/dist/types/compat/types.d.ts +18 -7
- package/dist/types/discovery/index.d.ts +1 -0
- package/dist/types/discovery/openai-compatible.d.ts +2 -0
- package/dist/types/discovery/typesafe.d.ts +26 -0
- package/dist/types/model-manager.d.ts +1 -1
- package/dist/types/provider-models/openai-compat.d.ts +6 -4
- package/dist/types/provider-models/special.d.ts +10 -0
- package/dist/types/types.d.ts +20 -0
- package/package.json +4 -4
- package/src/build.ts +27 -5
- package/src/compat/auth-ids.ts +2 -0
- package/src/compat/axes.ts +9 -1
- package/src/compat/cascade.ts +45 -23
- package/src/compat/provider-ids.ts +3 -0
- package/src/compat/resolve.ts +24 -14
- package/src/compat/rules/README.md +5 -3
- package/src/compat/rules/auth/local.kdl +4 -0
- package/src/compat/rules/auth/typesafe.kdl +3 -6
- package/src/compat/rules/auth/web.kdl +4 -0
- package/src/compat/rules/classes/qwen.kdl +6 -5
- package/src/compat/rules/providers/anthropic.kdl +1 -0
- package/src/compat/rules/providers/deepinfra.kdl +28 -0
- package/src/compat/rules/providers/google-antigravity.kdl +17 -0
- package/src/compat/rules/providers/google.kdl +9 -0
- package/src/compat/rules/providers/llama.cpp.kdl +23 -0
- package/src/compat/rules/providers/local.kdl +110 -0
- package/src/compat/rules/providers/openai-codex.kdl +18 -0
- package/src/compat/rules/providers/openai.kdl +3 -0
- package/src/compat/rules/providers/openrouter.kdl +24 -0
- package/src/compat/rules/providers/typesafe.kdl +21 -0
- package/src/compat/rules/providers/web.kdl +153 -0
- package/src/compat/rules/providers/xai-oauth.kdl +26 -0
- package/src/compat/rules/providers/xai.kdl +22 -0
- package/src/compat/rules/runtime/behavior.kdl +2 -1
- package/src/compat/rules/taxonomy/qwen.kdl +2 -0
- package/src/compat/rules.json +1 -1
- package/src/compat/taxonomy.ts +92 -31
- package/src/compat/types.ts +22 -7
- package/src/discovery/index.ts +1 -0
- package/src/discovery/openai-compatible.ts +4 -1
- package/src/discovery/typesafe.ts +118 -0
- package/src/model-manager.ts +44 -15
- package/src/models.json +1 -1
- package/src/provider-models/descriptors.ts +6 -0
- package/src/provider-models/openai-compat.ts +246 -79
- package/src/provider-models/special.ts +53 -0
- package/src/types.ts +33 -0
package/src/compat/resolve.ts
CHANGED
|
@@ -311,6 +311,7 @@ function detectOpenAI(
|
|
|
311
311
|
reasoningCapable: boolean,
|
|
312
312
|
): OpenAIDetection {
|
|
313
313
|
const provider = spec.provider;
|
|
314
|
+
const backendProvider = spec.providerType ?? provider;
|
|
314
315
|
const baseUrl = spec.baseUrl;
|
|
315
316
|
const hostModel = { provider, baseUrl };
|
|
316
317
|
const isZai = modelMatchesHost(hostModel, "zai");
|
|
@@ -321,8 +322,8 @@ function detectOpenAI(
|
|
|
321
322
|
const isDeepseekFamily = modelMatchesHost(hostModel, "deepseekFamily") || facts.is("deepseek");
|
|
322
323
|
const isDeepseekReasoning = isDeepseekFamily && reasoningCapable;
|
|
323
324
|
const isLocalOpenAICompatBackend =
|
|
324
|
-
PROXY_OPENAI_COMPAT_PROVIDERS[
|
|
325
|
-
(LOCAL_OPENAI_COMPAT_PROVIDERS[
|
|
325
|
+
PROXY_OPENAI_COMPAT_PROVIDERS[backendProvider] !== true &&
|
|
326
|
+
(LOCAL_OPENAI_COMPAT_PROVIDERS[backendProvider] === true || hasLocalLoopbackBaseUrl(baseUrl));
|
|
326
327
|
return {
|
|
327
328
|
facts,
|
|
328
329
|
isClinePass: provider === "cline-pass",
|
|
@@ -521,12 +522,8 @@ function detectOpenAICompat(
|
|
|
521
522
|
replayReasoningContent: d.isLocalOpenAICompatBackend,
|
|
522
523
|
qwenPreserveThinking:
|
|
523
524
|
(thinkingFormat === "qwen" || thinkingFormat === "qwen-chat-template") && d.isLocalOpenAICompatBackend,
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
d.isLocalOpenAICompatBackend &&
|
|
527
|
-
provider !== "ollama" &&
|
|
528
|
-
isQwen &&
|
|
529
|
-
facts.revGte("3.8"),
|
|
525
|
+
// Template effort support is a reviewed backend × model contract in KDL.
|
|
526
|
+
qwenTemplateReasoningEffort: false,
|
|
530
527
|
requiresAssistantContentForToolCalls: facts.is("kimi") || d.isDirectDeepseekReasoning,
|
|
531
528
|
cacheControlFormat:
|
|
532
529
|
(d.isClinePass && (isQwen || isAnthropicModel)) || (d.isOpenRouter && isAnthropicModel)
|
|
@@ -692,6 +689,7 @@ function resolveOpenAIResponsesPolicy(
|
|
|
692
689
|
): ResolvedOpenAIResponsesCompat {
|
|
693
690
|
const baseUrl = spec.baseUrl ?? "";
|
|
694
691
|
const provider = spec.provider;
|
|
692
|
+
const backendProvider = spec.providerType ?? provider;
|
|
695
693
|
const hostModel = { provider, baseUrl };
|
|
696
694
|
const isAzure = modelMatchesHost(hostModel, "azureOpenAI");
|
|
697
695
|
const isOpenRouter = modelMatchesHost(hostModel, "openrouter");
|
|
@@ -703,7 +701,8 @@ function resolveOpenAIResponsesPolicy(
|
|
|
703
701
|
const thinkingFormat: ResolvedOpenAISharedCompat["thinkingFormat"] = isOpenRouter ? "openrouter" : "openai";
|
|
704
702
|
const reasoningCapable = compatReasoning(spec, axes);
|
|
705
703
|
const isLocalServingBackend =
|
|
706
|
-
(PROXY_OPENAI_COMPAT_PROVIDERS[
|
|
704
|
+
(PROXY_OPENAI_COMPAT_PROVIDERS[backendProvider] !== true &&
|
|
705
|
+
LOCAL_OPENAI_COMPAT_PROVIDERS[backendProvider] === true) ||
|
|
707
706
|
hasLocalLoopbackBaseUrl(baseUrl);
|
|
708
707
|
const isAnthropicModel = facts.is("anthropic");
|
|
709
708
|
const isDeepseekFamily = facts.is("deepseek");
|
|
@@ -1063,8 +1062,8 @@ function readRuleThinking(axes: ResolvedAxes): RuleThinking {
|
|
|
1063
1062
|
|
|
1064
1063
|
/**
|
|
1065
1064
|
* Compat-time reasoning capability. `axes.reasoning` also promotes targets on
|
|
1066
|
-
*
|
|
1067
|
-
*
|
|
1065
|
+
* reviewed effort corrections (the cascade's thinking-axis gate), but compat
|
|
1066
|
+
* may only be repaired where the matching contract opted in with
|
|
1068
1067
|
* `thinking-upgrade-neutral`; everywhere else a spec that reports no reasoning
|
|
1069
1068
|
* stays the authoritative capability surface.
|
|
1070
1069
|
*/
|
|
@@ -1104,7 +1103,7 @@ function resolveThinkingPolicy<TApi extends Api>(
|
|
|
1104
1103
|
// reasoning (e.g. Synthetic's `none`-only off-switch): reviewed KDL must
|
|
1105
1104
|
// not re-expand it into an unadvertised ladder. Absent metadata is
|
|
1106
1105
|
// repaired only where KDL opts in with `thinking-upgrade-neutral`
|
|
1107
|
-
// alongside
|
|
1106
|
+
// alongside a reviewed `thinking-efforts` ladder (the cascade upgrade for
|
|
1108
1107
|
// stale source capability data); otherwise the neutral default holds.
|
|
1109
1108
|
if (!spec.reasoning && (explicitThinking !== undefined || rule.upgradeNeutral !== true)) return undefined;
|
|
1110
1109
|
if (
|
|
@@ -1210,9 +1209,13 @@ function fillExplicitThinking<TApi extends Api>(
|
|
|
1210
1209
|
// Entry
|
|
1211
1210
|
// ---------------------------------------------------------------------------
|
|
1212
1211
|
|
|
1213
|
-
function buildResolveTarget<TApi extends Api>(
|
|
1212
|
+
function buildResolveTarget<TApi extends Api>(
|
|
1213
|
+
spec: ModelSpec<TApi>,
|
|
1214
|
+
identity: ModelIdentity,
|
|
1215
|
+
providerType = spec.providerType ?? spec.provider,
|
|
1216
|
+
): ResolveTarget {
|
|
1214
1217
|
const target: ResolveTarget = {
|
|
1215
|
-
provider:
|
|
1218
|
+
provider: providerType,
|
|
1216
1219
|
api: spec.api,
|
|
1217
1220
|
class: identity.class,
|
|
1218
1221
|
model: spec.id,
|
|
@@ -1227,6 +1230,13 @@ function specUsesApi<TApi extends Api>(spec: ModelSpec<Api>, api: TApi): spec is
|
|
|
1227
1230
|
return spec.api === api;
|
|
1228
1231
|
}
|
|
1229
1232
|
|
|
1233
|
+
/** Resolve the request adapter assigned to a discovery backend before materialization. */
|
|
1234
|
+
export function resolveDiscoveryApi(spec: ModelSpec<Api>, providerType: string): Api {
|
|
1235
|
+
const identity = resolveIdentity(spec);
|
|
1236
|
+
const discoveryApi = resolveCascade(buildResolveTarget(spec, identity, providerType)).catalog.discoveryApi;
|
|
1237
|
+
return typeof discoveryApi === "string" ? discoveryApi : spec.api;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1230
1240
|
/**
|
|
1231
1241
|
* Resolves the full policy surface for one model spec: structured identity,
|
|
1232
1242
|
* complete compat record, thinking metadata, and catalog-data corrections.
|
|
@@ -89,7 +89,7 @@ revision skip-bare "o1" "o3" "o4"
|
|
|
89
89
|
|
|
90
90
|
### Reviewed identity overrides
|
|
91
91
|
|
|
92
|
-
`override` has properties only and no child block. Required string properties are `id` (stable, globally unique review ID), `model` (exact bare
|
|
92
|
+
`override` has properties only and no child block. Required string properties are `id` (stable, globally unique review ID), `rationale`, and `provenance`, plus exactly one selector: `model` (exact bare identifier) or `glob` (anchored `*` wildcard over the bare identifier). Both selectors compare case-insensitively; namespace prefixes before the final `/` are ignored.
|
|
93
93
|
|
|
94
94
|
Optional properties are:
|
|
95
95
|
|
|
@@ -104,7 +104,7 @@ Optional properties are:
|
|
|
104
104
|
| `thinking-variant` | Boolean marker for a separately exposed thinking sibling. |
|
|
105
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
|
-
The
|
|
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
|
|
|
109
109
|
### Suffix collapse
|
|
110
110
|
|
|
@@ -194,6 +194,8 @@ A `models` string without `*` is an exact, case-sensitive match against the prov
|
|
|
194
194
|
|
|
195
195
|
`priority=N` is an optional signed integer property on the block that owns axis assignments. Its default is zero. Use it only to resolve an intentional equal-specificity overlap; do not use it to encode declaration order.
|
|
196
196
|
|
|
197
|
+
`buildDiscoveredModel(spec, providerType)` resolves the catalog `discovery-api` axis before materializing compatibility. It preserves the credential-bearing provider ID and records `providerType` as the backend used for provider selectors on subsequent rebuilds. Ordinary `buildModel` preserves its input API. This lets custom-named llama.cpp deployments reuse the same rules without model-specific discovery code.
|
|
198
|
+
|
|
197
199
|
### Axis vocabulary and value shapes
|
|
198
200
|
|
|
199
201
|
The directive vocabulary is closed and lives in **`src/compat/axes.ts`** — one table mapping each kebab-case directive to its resolved camelCase field, namespace (`wire` / `thinking` / `catalog`), value shape, applicable compat records, and (for enums) accepted values. The compiler rejects unknown directives and out-of-vocabulary values against that table; consult it rather than a duplicated table here.
|
|
@@ -262,7 +264,7 @@ The highest-ranked matching assignment wins for that axis. Two distinct rules th
|
|
|
262
264
|
|
|
263
265
|
### Capability gating
|
|
264
266
|
|
|
265
|
-
Wire axes are considered for every matching target. Thinking axes
|
|
267
|
+
Wire axes are considered for every matching target. Thinking axes require `reasoning`, except that an exact model selector declaring `thinking-efforts` opens the gate for reviewed corrections. A winning `thinking-upgrade-neutral #true` scoped to a recognized class, family, revision, or model selector also opens it when a matching effort ladder exists; provider-wide opt-in alone does not. Materializing a neutral spec as reasoning-capable requires that opt-in and no explicit thinking vocabulary. Family and revision selectors never match targets missing that rank. An unmatched target resolves to empty maps; the cascade does not infer negative capabilities from absence.
|
|
266
268
|
|
|
267
269
|
## Runtime behavior grammar
|
|
268
270
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
// TypeSafe (System One judgments)
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// No `providers/typesafe.kdl` entry exists on purpose — it has no chat models,
|
|
5
|
-
// so it never appears in the model picker; the credential alone is what the
|
|
6
|
-
// judgment resolver checks.
|
|
1
|
+
// TypeSafe (System One judgments) answers typed questions over JSON state via
|
|
2
|
+
// `POST /v1/systemone`. Its judgment models are catalogued under the `judge`
|
|
3
|
+
// kind; this auth entry supplies both live `/v1/models` discovery and requests.
|
|
7
4
|
auth "typesafe" {
|
|
8
5
|
name "TypeSafe"
|
|
9
6
|
env "TYPESAFE_API_KEY"
|
|
@@ -33,11 +33,12 @@ class "qwen" {
|
|
|
33
33
|
}
|
|
34
34
|
// Qwen 3.8+ open-weight chat templates steer thinking depth through the
|
|
35
35
|
// `reasoning_effort` template kwarg (wire-exact low/medium/xhigh, template
|
|
36
|
-
// default xhigh) and raise on `enable_thinking: false
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
// `enable_thinking`, so it rides the
|
|
40
|
-
|
|
36
|
+
// default xhigh) and raise on `enable_thinking: false`. LM Studio routes
|
|
37
|
+
// the selected effort onto the template instead of always reasoning at
|
|
38
|
+
// xhigh; llama.cpp owns its equivalent policy in the provider rule. vLLM
|
|
39
|
+
// ignores top-level `enable_thinking`, so it rides the
|
|
40
|
+
// chat-template-kwargs dialect.
|
|
41
|
+
on "lm-studio" {
|
|
41
42
|
revision ">=3.8" {
|
|
42
43
|
supports-reasoning-effort #true
|
|
43
44
|
template-reasoning-effort #true
|
|
@@ -4,6 +4,7 @@ provider "anthropic" {
|
|
|
4
4
|
default-model "claude-opus-4-8"
|
|
5
5
|
env "ANTHROPIC_API_KEY"
|
|
6
6
|
discovery label="Anthropic"
|
|
7
|
+
web-search "anthropic"
|
|
7
8
|
|
|
8
9
|
// Curated Anthropic models that are live or limited-availability on the
|
|
9
10
|
// first-party `/v1/models` endpoint but that stencil.so has not catalogued
|
|
@@ -5,4 +5,32 @@ provider "deepinfra" {
|
|
|
5
5
|
env "DEEPINFRA_API_KEY"
|
|
6
6
|
dynamic-models-authoritative #true
|
|
7
7
|
discovery label="DeepInfra" allow-unauthenticated=#true
|
|
8
|
+
kind-apis {
|
|
9
|
+
image "openai-images"
|
|
10
|
+
tts "openai-speech"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
seed base-url="https://api.deepinfra.com/v1/openai" bundle="always" {
|
|
14
|
+
model "black-forest-labs/FLUX-2-pro" name="FLUX.2 Pro" api="openai-images" {
|
|
15
|
+
reasoning #false
|
|
16
|
+
input "text" "image"
|
|
17
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
18
|
+
limits
|
|
19
|
+
supports-tools #false
|
|
20
|
+
}
|
|
21
|
+
model "hexgrad/Kokoro-82M" name="Kokoro-82M" api="openai-speech" {
|
|
22
|
+
reasoning #false
|
|
23
|
+
input "text"
|
|
24
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
25
|
+
limits
|
|
26
|
+
supports-tools #false
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
models "black-forest-labs/FLUX-2-pro" {
|
|
31
|
+
kind "image"
|
|
32
|
+
}
|
|
33
|
+
models "hexgrad/Kokoro-82M" {
|
|
34
|
+
kind "tts"
|
|
35
|
+
}
|
|
8
36
|
}
|
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
provider "google-antigravity" {
|
|
4
4
|
default-model "gemini-3.1-pro"
|
|
5
|
+
kind-apis {
|
|
6
|
+
image "google-gemini-cli"
|
|
7
|
+
}
|
|
8
|
+
web-search "gemini"
|
|
9
|
+
|
|
10
|
+
seed api="google-gemini-cli" base-url="https://daily-cloudcode-pa.googleapis.com" bundle="always" {
|
|
11
|
+
model "gemini-3-pro-image" name="Gemini 3 Pro Image" {
|
|
12
|
+
reasoning #false
|
|
13
|
+
input "text" "image"
|
|
14
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
15
|
+
limits
|
|
16
|
+
supports-tools #false
|
|
17
|
+
}
|
|
18
|
+
}
|
|
5
19
|
|
|
6
20
|
class "anthropic" {
|
|
7
21
|
family "opus" {
|
|
@@ -45,6 +59,9 @@ provider "google-antigravity" {
|
|
|
45
59
|
models "gemini-3-pro" {
|
|
46
60
|
thinking-mode "google-level"
|
|
47
61
|
}
|
|
62
|
+
models "gemini-3-pro-image" {
|
|
63
|
+
kind "image"
|
|
64
|
+
}
|
|
48
65
|
// residue: taxonomy ranks and exact globs do not isolate these models.
|
|
49
66
|
models "gemini-3.1-flash-lite" {
|
|
50
67
|
thinking-mode "google-level"
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
provider "google" {
|
|
4
4
|
default-model "gemini-3.1-pro-preview"
|
|
5
5
|
env "GEMINI_API_KEY"
|
|
6
|
+
kind-apis {
|
|
7
|
+
image "google-generative-ai"
|
|
8
|
+
}
|
|
9
|
+
web-search "gemini"
|
|
6
10
|
|
|
7
11
|
class "unknown" {
|
|
8
12
|
thinking-efforts "minimal" "low" "medium" "high"
|
|
@@ -17,4 +21,9 @@ provider "google" {
|
|
|
17
21
|
models "gemini-2.5-computer-use-preview-10-2025" "gemini-robotics-er-1.6-preview" {
|
|
18
22
|
thinking-efforts "minimal" "low" "medium" "high"
|
|
19
23
|
}
|
|
24
|
+
// The proxy conservatively classifies tool-capable text+image output as chat;
|
|
25
|
+
// this SKU is a native image generator on the Gemini image transport.
|
|
26
|
+
models "gemini-3.1-flash-lite-image" {
|
|
27
|
+
kind "image"
|
|
28
|
+
}
|
|
20
29
|
}
|
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
// Provider-wire compat for "llama.cpp".
|
|
2
2
|
|
|
3
3
|
provider "llama.cpp" {
|
|
4
|
+
supports-store #false
|
|
5
|
+
supports-developer-role #false
|
|
6
|
+
supports-reasoning-effort #false
|
|
4
7
|
// Replaces the string-only named-tool-choice provider table.
|
|
5
8
|
supports-named-tool-choice #false
|
|
9
|
+
|
|
10
|
+
class "qwen" {
|
|
11
|
+
// Responses cannot encode the template's thinking controls.
|
|
12
|
+
discovery-api "openai-completions"
|
|
13
|
+
// llama-server exposes the model's bundled chat template. Qwen templates
|
|
14
|
+
// preserve prior reasoning and accept the chat-template thinking controls.
|
|
15
|
+
thinking-upgrade-neutral #true
|
|
16
|
+
thinking-mode "effort"
|
|
17
|
+
thinking-efforts "low" "medium" "high" "max"
|
|
18
|
+
thinking-format "qwen"
|
|
19
|
+
reasoning-disable-mode "qwen-enable-thinking-false"
|
|
20
|
+
qwen-preserve-thinking #true
|
|
21
|
+
|
|
22
|
+
revision ">=3.8" {
|
|
23
|
+
supports-reasoning-effort #true
|
|
24
|
+
template-reasoning-effort #true
|
|
25
|
+
thinking-efforts "low" "medium" "xhigh"
|
|
26
|
+
thinking-requires-effort #true
|
|
27
|
+
}
|
|
28
|
+
}
|
|
6
29
|
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// On-device inference workers exposed as catalog models.
|
|
2
|
+
|
|
3
|
+
provider "local" {
|
|
4
|
+
default-model "lfm2.5-230m"
|
|
5
|
+
allow-unauthenticated #true
|
|
6
|
+
|
|
7
|
+
seed api="local-inference" base-url="local://inference" bundle="always" {
|
|
8
|
+
model "kokoro" name="Kokoro-82M" {
|
|
9
|
+
reasoning #false
|
|
10
|
+
input "text"
|
|
11
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
12
|
+
limits
|
|
13
|
+
supports-tools #false
|
|
14
|
+
}
|
|
15
|
+
model "parakeet-tdt-0.6b-v3" name="Parakeet TDT 0.6B v3" {
|
|
16
|
+
reasoning #false
|
|
17
|
+
input "text"
|
|
18
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
19
|
+
limits
|
|
20
|
+
supports-tools #false
|
|
21
|
+
}
|
|
22
|
+
model "whisper-base" name="Whisper Base" {
|
|
23
|
+
reasoning #false
|
|
24
|
+
input "text"
|
|
25
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
26
|
+
limits
|
|
27
|
+
supports-tools #false
|
|
28
|
+
}
|
|
29
|
+
model "whisper-small" name="Whisper Small" {
|
|
30
|
+
reasoning #false
|
|
31
|
+
input "text"
|
|
32
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
33
|
+
limits
|
|
34
|
+
supports-tools #false
|
|
35
|
+
}
|
|
36
|
+
model "whisper-large-v3-turbo" name="Whisper Large v3 Turbo" {
|
|
37
|
+
reasoning #false
|
|
38
|
+
input "text"
|
|
39
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
40
|
+
limits
|
|
41
|
+
supports-tools #false
|
|
42
|
+
}
|
|
43
|
+
model "lfm2.5-230m" name="LFM2.5 230M" {
|
|
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 "lfm2.5-350m" name="LFM2.5 350M" {
|
|
51
|
+
reasoning #false
|
|
52
|
+
input "text"
|
|
53
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
54
|
+
limits
|
|
55
|
+
supports-tools #false
|
|
56
|
+
}
|
|
57
|
+
model "falcon-h1-90m" name="Falcon H1 Tiny 90M" {
|
|
58
|
+
reasoning #false
|
|
59
|
+
input "text"
|
|
60
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
61
|
+
limits
|
|
62
|
+
supports-tools #false
|
|
63
|
+
}
|
|
64
|
+
model "qwen3-1.7b" name="Qwen3 1.7B" {
|
|
65
|
+
reasoning #true
|
|
66
|
+
input "text"
|
|
67
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
68
|
+
limits
|
|
69
|
+
supports-tools #false
|
|
70
|
+
}
|
|
71
|
+
model "llama3.2:3b" name="Llama 3.2 3B" {
|
|
72
|
+
reasoning #false
|
|
73
|
+
input "text"
|
|
74
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
75
|
+
limits
|
|
76
|
+
supports-tools #false
|
|
77
|
+
}
|
|
78
|
+
model "gemma-3-1b" name="Gemma 3 1B" {
|
|
79
|
+
reasoning #false
|
|
80
|
+
input "text"
|
|
81
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
82
|
+
limits
|
|
83
|
+
supports-tools #false
|
|
84
|
+
}
|
|
85
|
+
model "qwen2.5-1.5b" name="Qwen2.5 1.5B" {
|
|
86
|
+
reasoning #false
|
|
87
|
+
input "text"
|
|
88
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
89
|
+
limits
|
|
90
|
+
supports-tools #false
|
|
91
|
+
}
|
|
92
|
+
model "lfm2-1.2b" name="LFM2 1.2B" {
|
|
93
|
+
reasoning #false
|
|
94
|
+
input "text"
|
|
95
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
96
|
+
limits
|
|
97
|
+
supports-tools #false
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
models "kokoro" {
|
|
102
|
+
kind "tts"
|
|
103
|
+
}
|
|
104
|
+
models "parakeet-tdt-0.6b-v3" "whisper-*" {
|
|
105
|
+
kind "stt"
|
|
106
|
+
}
|
|
107
|
+
models "lfm*" "falcon-*" "qwen*" "llama3.2:3b" "gemma-3-1b" {
|
|
108
|
+
kind "tiny"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -3,6 +3,24 @@
|
|
|
3
3
|
provider "openai-codex" {
|
|
4
4
|
default-model "gpt-5.5"
|
|
5
5
|
env "OPENAI_CODEX_OAUTH_TOKEN"
|
|
6
|
+
kind-apis {
|
|
7
|
+
image "openai-codex-responses"
|
|
8
|
+
}
|
|
9
|
+
web-search "codex"
|
|
10
|
+
|
|
11
|
+
seed api="openai-codex-responses" base-url="https://chatgpt.com/backend-api" bundle="always" {
|
|
12
|
+
model "gpt-image-1" name="GPT Image 1" {
|
|
13
|
+
reasoning #false
|
|
14
|
+
input "text" "image"
|
|
15
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
16
|
+
limits
|
|
17
|
+
supports-tools #false
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
models "gpt-image-1" {
|
|
22
|
+
kind "image"
|
|
23
|
+
}
|
|
6
24
|
|
|
7
25
|
// Replaces the Codex provider's handwritten flex/priority pricing fallback.
|
|
8
26
|
service-tier-cost {
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
provider "openai" {
|
|
4
4
|
default-model "gpt-5.5"
|
|
5
5
|
env "OPENAI_API_KEY"
|
|
6
|
+
kind-apis {
|
|
7
|
+
image "openai-responses"
|
|
8
|
+
}
|
|
6
9
|
|
|
7
10
|
// Daybreak models are approval-gated first-party Responses models that are
|
|
8
11
|
// not yet present in stencil.so. Seed the documented aliases and current
|
|
@@ -4,6 +4,25 @@ provider "openrouter" {
|
|
|
4
4
|
default-model "openai/gpt-5.5"
|
|
5
5
|
env "OPENROUTER_API_KEY"
|
|
6
6
|
discovery label="OpenRouter" allow-unauthenticated=#true
|
|
7
|
+
kind-apis {
|
|
8
|
+
image "openrouter-images"
|
|
9
|
+
}
|
|
10
|
+
web-search "openrouter"
|
|
11
|
+
|
|
12
|
+
// TypeSafe's Jev answers only through the Decisions API (`/api/alpha/decisions`,
|
|
13
|
+
// System One wire shape); the default `/models` roster omits `text->decisions`
|
|
14
|
+
// rows, so the alias is authored here and discovery refreshes the family.
|
|
15
|
+
seed api="openrouter-decisions" base-url="https://openrouter.ai/api/alpha" bundle="always" {
|
|
16
|
+
model "~typesafe/jev-latest" name="TypeSafe: Jev Latest" {
|
|
17
|
+
reasoning #false
|
|
18
|
+
input "text"
|
|
19
|
+
cost input=0.042 output=0 cache-read=0 cache-write=0
|
|
20
|
+
limits context=32000 max-tokens=28800
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
models "~typesafe/*" "typesafe/*" {
|
|
24
|
+
kind "judge"
|
|
25
|
+
}
|
|
7
26
|
|
|
8
27
|
// Replaces the OpenRouter provider wire-model-id dispatch branch.
|
|
9
28
|
wire-model-id-mode "openrouter"
|
|
@@ -59,6 +78,11 @@ provider "openrouter" {
|
|
|
59
78
|
thinking-efforts "minimal" "low" "medium" "high"
|
|
60
79
|
thinking-requires-effort #true
|
|
61
80
|
}
|
|
81
|
+
// The proxy conservatively classifies this tool-capable text+image output row
|
|
82
|
+
// as chat; OpenRouter's dedicated image roster confirms the image transport.
|
|
83
|
+
models "google/gemini-3-pro-image" {
|
|
84
|
+
kind "image"
|
|
85
|
+
}
|
|
62
86
|
// residue: taxonomy ranks and exact globs do not isolate these models.
|
|
63
87
|
models "qwen/qwen3-coder" {
|
|
64
88
|
thinking-format "openrouter"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// TypeSafe System One judgment models.
|
|
2
|
+
|
|
3
|
+
provider "typesafe" {
|
|
4
|
+
default-model "jev-latest"
|
|
5
|
+
env "TYPESAFE_API_KEY"
|
|
6
|
+
|
|
7
|
+
seed api="typesafe" base-url="https://api.typesafe.ai" bundle="always" {
|
|
8
|
+
model "jev-latest" name="TypeSafe jev" {
|
|
9
|
+
reasoning #false
|
|
10
|
+
input "text"
|
|
11
|
+
// Jev bills input only; matches the OpenRouter route seed.
|
|
12
|
+
cost input=0.042 output=0 cache-read=0 cache-write=0
|
|
13
|
+
limits
|
|
14
|
+
supports-tools #false
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
models "*" {
|
|
19
|
+
kind "judge"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// Pure search engines exposed through the web-search runner.
|
|
2
|
+
|
|
3
|
+
provider "web" {
|
|
4
|
+
default-model "public"
|
|
5
|
+
allow-unauthenticated #true
|
|
6
|
+
|
|
7
|
+
seed api="web-search" base-url="web://search" bundle="always" {
|
|
8
|
+
model "parallel" name="Parallel" {
|
|
9
|
+
reasoning #false
|
|
10
|
+
input "text"
|
|
11
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
12
|
+
limits
|
|
13
|
+
supports-tools #false
|
|
14
|
+
}
|
|
15
|
+
model "perplexity" name="Perplexity" {
|
|
16
|
+
reasoning #false
|
|
17
|
+
input "text"
|
|
18
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
19
|
+
limits
|
|
20
|
+
supports-tools #false
|
|
21
|
+
}
|
|
22
|
+
model "zai" name="Z.AI" {
|
|
23
|
+
reasoning #false
|
|
24
|
+
input "text"
|
|
25
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
26
|
+
limits
|
|
27
|
+
supports-tools #false
|
|
28
|
+
}
|
|
29
|
+
model "exa" name="Exa" {
|
|
30
|
+
reasoning #false
|
|
31
|
+
input "text"
|
|
32
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
33
|
+
limits
|
|
34
|
+
supports-tools #false
|
|
35
|
+
}
|
|
36
|
+
model "tinyfish" name="TinyFish" {
|
|
37
|
+
reasoning #false
|
|
38
|
+
input "text"
|
|
39
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
40
|
+
limits
|
|
41
|
+
supports-tools #false
|
|
42
|
+
}
|
|
43
|
+
model "jina" name="Jina" {
|
|
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 "kagi" name="Kagi" {
|
|
51
|
+
reasoning #false
|
|
52
|
+
input "text"
|
|
53
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
54
|
+
limits
|
|
55
|
+
supports-tools #false
|
|
56
|
+
}
|
|
57
|
+
model "tavily" name="Tavily" {
|
|
58
|
+
reasoning #false
|
|
59
|
+
input "text"
|
|
60
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
61
|
+
limits
|
|
62
|
+
supports-tools #false
|
|
63
|
+
}
|
|
64
|
+
model "firecrawl" name="Firecrawl" {
|
|
65
|
+
reasoning #false
|
|
66
|
+
input "text"
|
|
67
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
68
|
+
limits
|
|
69
|
+
supports-tools #false
|
|
70
|
+
}
|
|
71
|
+
model "brave" name="Brave" {
|
|
72
|
+
reasoning #false
|
|
73
|
+
input "text"
|
|
74
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
75
|
+
limits
|
|
76
|
+
supports-tools #false
|
|
77
|
+
}
|
|
78
|
+
model "kimi" name="Kimi" {
|
|
79
|
+
reasoning #false
|
|
80
|
+
input "text"
|
|
81
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
82
|
+
limits
|
|
83
|
+
supports-tools #false
|
|
84
|
+
}
|
|
85
|
+
model "synthetic" name="Synthetic" {
|
|
86
|
+
reasoning #false
|
|
87
|
+
input "text"
|
|
88
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
89
|
+
limits
|
|
90
|
+
supports-tools #false
|
|
91
|
+
}
|
|
92
|
+
model "ollama" name="Ollama" {
|
|
93
|
+
reasoning #false
|
|
94
|
+
input "text"
|
|
95
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
96
|
+
limits
|
|
97
|
+
supports-tools #false
|
|
98
|
+
}
|
|
99
|
+
model "searxng" name="SearXNG" {
|
|
100
|
+
reasoning #false
|
|
101
|
+
input "text"
|
|
102
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
103
|
+
limits
|
|
104
|
+
supports-tools #false
|
|
105
|
+
}
|
|
106
|
+
model "startpage" name="Startpage" {
|
|
107
|
+
reasoning #false
|
|
108
|
+
input "text"
|
|
109
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
110
|
+
limits
|
|
111
|
+
supports-tools #false
|
|
112
|
+
}
|
|
113
|
+
model "duckduckgo" name="DuckDuckGo" {
|
|
114
|
+
reasoning #false
|
|
115
|
+
input "text"
|
|
116
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
117
|
+
limits
|
|
118
|
+
supports-tools #false
|
|
119
|
+
}
|
|
120
|
+
model "ecosia" name="Ecosia" {
|
|
121
|
+
reasoning #false
|
|
122
|
+
input "text"
|
|
123
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
124
|
+
limits
|
|
125
|
+
supports-tools #false
|
|
126
|
+
}
|
|
127
|
+
model "google" name="Google" {
|
|
128
|
+
reasoning #false
|
|
129
|
+
input "text"
|
|
130
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
131
|
+
limits
|
|
132
|
+
supports-tools #false
|
|
133
|
+
}
|
|
134
|
+
model "mojeek" name="Mojeek" {
|
|
135
|
+
reasoning #false
|
|
136
|
+
input "text"
|
|
137
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
138
|
+
limits
|
|
139
|
+
supports-tools #false
|
|
140
|
+
}
|
|
141
|
+
model "public" name="Public Web" {
|
|
142
|
+
reasoning #false
|
|
143
|
+
input "text"
|
|
144
|
+
cost input=0 output=0 cache-read=0 cache-write=0
|
|
145
|
+
limits
|
|
146
|
+
supports-tools #false
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
models "*" {
|
|
151
|
+
kind "search"
|
|
152
|
+
}
|
|
153
|
+
}
|