modelrig 0.3.0 → 0.4.0
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 +140 -0
- package/README.md +66 -14
- package/dist/adapters/deepseek.d.ts.map +1 -1
- package/dist/adapters/deepseek.js +8 -1
- package/dist/adapters/gemini.d.ts +6 -0
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +14 -4
- package/dist/adapters/grok.d.ts +7 -0
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +23 -1
- package/dist/adapters/openai-compat.d.ts +7 -0
- package/dist/adapters/openai-compat.d.ts.map +1 -1
- package/dist/adapters/openai-compat.js +24 -1
- package/dist/adapters/openai.d.ts +7 -0
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +23 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -4
- package/dist/config.d.ts +7 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -25
- package/dist/init/init-cli.d.ts.map +1 -1
- package/dist/init/init-cli.js +2 -1
- package/dist/init/observe-cli.d.ts.map +1 -1
- package/dist/init/observe-cli.js +2 -1
- package/dist/routes/sampling-config.d.ts.map +1 -1
- package/dist/routes/sampling-config.js +11 -0
- package/dist/run/dispatch.d.ts +14 -2
- package/dist/run/dispatch.d.ts.map +1 -1
- package/dist/run/dispatch.js +31 -2
- package/dist/run/ladder-key.d.ts +40 -0
- package/dist/run/ladder-key.d.ts.map +1 -0
- package/dist/run/ladder-key.js +39 -0
- package/dist/run/raw-support.d.ts +123 -0
- package/dist/run/raw-support.d.ts.map +1 -0
- package/dist/run/raw-support.js +150 -0
- package/dist/run/raw.d.ts +41 -11
- package/dist/run/raw.d.ts.map +1 -1
- package/dist/run/raw.js +67 -23
- package/dist/run/rawonly.d.ts +60 -0
- package/dist/run/rawonly.d.ts.map +1 -0
- package/dist/run/rawonly.js +120 -0
- package/dist/run/record-attempt.d.ts +14 -1
- package/dist/run/record-attempt.d.ts.map +1 -1
- package/dist/run/record-attempt.js +43 -2
- package/dist/run/resolve.d.ts +4 -0
- package/dist/run/resolve.d.ts.map +1 -1
- package/dist/run/resolve.js +9 -2
- package/dist/run/routing-docs.d.ts +73 -0
- package/dist/run/routing-docs.d.ts.map +1 -0
- package/dist/run/routing-docs.js +222 -0
- package/dist/run/run.d.ts.map +1 -1
- package/dist/run/run.js +24 -22
- package/dist/telemetry/exporter.d.ts.map +1 -1
- package/dist/telemetry/exporter.js +6 -0
- package/dist/telemetry/ingest-protocol.d.ts +7 -0
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
- package/dist/telemetry/load-error-report.d.ts.map +1 -1
- package/dist/telemetry/load-error-report.js +4 -1
- package/dist/telemetry/otel-map.d.ts.map +1 -1
- package/dist/telemetry/otel-map.js +8 -0
- package/dist/telemetry/store-migrations.d.ts +15 -0
- package/dist/telemetry/store-migrations.d.ts.map +1 -0
- package/dist/telemetry/store-migrations.js +119 -0
- package/dist/telemetry/store.d.ts.map +1 -1
- package/dist/telemetry/store.js +26 -93
- package/dist/types/failures-teaching.js +1 -1
- package/dist/types/provider.d.ts +13 -0
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/route.d.ts +6 -1
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +31 -0
- package/dist/types/telemetry.d.ts.map +1 -1
- package/dist/validate-cli.d.ts.map +1 -1
- package/dist/validate-cli.js +17 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,146 @@ published package diverge.
|
|
|
10
10
|
This project adheres to [Semantic Versioning](https://semver.org/). Dates are
|
|
11
11
|
UTC.
|
|
12
12
|
|
|
13
|
+
## [0.4.0] — 2026-08-22
|
|
14
|
+
|
|
15
|
+
Released with the docs/registry mirror in one R-A ceremony. NOT in this tag:
|
|
16
|
+
the R3 declare-first `trial:` candidate flag (#239) and raw-lane artifact
|
|
17
|
+
steps (G1) — both land in 0.5.0.
|
|
18
|
+
|
|
19
|
+
CE-9 raw-lane multi-provider parity — the `reasoning` and native-grounding knobs
|
|
20
|
+
generalize beyond gemini, a `responseFormat` knob joins the raw lane, and the
|
|
21
|
+
provider×knob support set becomes ONE table (`RAW_KNOB_SUPPORT`) that the runtime
|
|
22
|
+
guard AND the published docs matrix both read, so they can never disagree. Every
|
|
23
|
+
knob stays ADDITIVE: absent ⇒ byte-identical to the 0.3.0 request shape.
|
|
24
|
+
|
|
25
|
+
### Added — docs
|
|
26
|
+
|
|
27
|
+
- **Routing & reliability page** (`https://modelrig.dev/routing-reliability.html`) —
|
|
28
|
+
the runtime model in one concept page: resolve -> candidate ladder -> validate ->
|
|
29
|
+
repair -> fall-through -> exhaust, what is stored per attempt, and a **code-anchored
|
|
30
|
+
boundary** (`ROUTING_BOUNDARY`, one tripwire test per entry) that lists what does not
|
|
31
|
+
trigger fall-through and what is not built — the build fails if a listed feature ships
|
|
32
|
+
without the entry being updated.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **Failure-teaching links resolve.** `RigFailureError.docsUrl` (and the CLI/console
|
|
37
|
+
error render) now point at `routing-reliability.html#<class>` — one stable heading per
|
|
38
|
+
failure class — instead of the never-built `/docs/failures` path, which 404'd on
|
|
39
|
+
every typed failure.
|
|
40
|
+
|
|
41
|
+
### Added — `rig.runRaw` / `rig.runRawStream`
|
|
42
|
+
|
|
43
|
+
- **`reasoning` generalizes beyond gemini WITHOUT a per-model allowlist (R1).**
|
|
44
|
+
openai / deepinfra / fireworks forward `level` → `reasoning_effort` verbatim
|
|
45
|
+
and let the provider enforce — a model that does not accept it surfaces a
|
|
46
|
+
CLASSIFIED, teaching failure ("this model does not accept reasoning_effort —
|
|
47
|
+
remove reasoning or pick a reasoning model"), never a cryptic 400 or a silent
|
|
48
|
+
drop. grok forwards a DISCLOSED coarsening (`minimal,low → "low"`;
|
|
49
|
+
`medium,high → "high"`; xAI accepts `low|high` only). gemini stays
|
|
50
|
+
model-gated (thinking-capable models only). deepseek + anthropic FAIL CLOSED
|
|
51
|
+
pre-dispatch with a provider-specific fixHint (deepseek → select the
|
|
52
|
+
`deepseek-reasoner` model; anthropic → extended thinking unwired).
|
|
53
|
+
- **Grok native grounding (R2) — WITHDRAWN before release.** The CE-9 live gate hit xAI's `410 Live search is deprecated`; the replacement `web_search` tool is Responses-API-only, which the grok adapter does not speak yet. grok grounding FAILS CLOSED (matrix `supported: false`, teaching note) until CE-9b lands that path. Original entry, kept for the record: `grounding: { mode: "native" }` on grok →
|
|
54
|
+
xAI Live Search (`search_parameters: { mode: "on" }`). Citations are not
|
|
55
|
+
surfaced on `meta` in v1 (same documented limitation as gemini).
|
|
56
|
+
- **`responseFormat?: "json_object"` (R4).** MIME-shaping on the OpenAI-dialect
|
|
57
|
+
providers (openai/deepseek/grok/deepinfra/fireworks → `response_format: { type:
|
|
58
|
+
"json_object" }`) and gemini (`responseMimeType: "application/json"`, no
|
|
59
|
+
schema). This is syntactic-JSON forcing, NOT schema enforcement — F4 stands:
|
|
60
|
+
no validation, no repair, `meta.validated` stays false. anthropic has no
|
|
61
|
+
equivalent and FAILS CLOSED. DeepSeek's word-"JSON" prompt wrinkle is the
|
|
62
|
+
caller's responsibility on the raw lane (documented, never injected).
|
|
63
|
+
- **DeepInfra/Fireworks prompt-cache hint (R3).** `cache.key` now maps to
|
|
64
|
+
`prompt_cache_key` on the openai-compatible adapter, closing the DeepInfra cost
|
|
65
|
+
gap. (openai and grok already mapped `cache.key → prompt_cache_key` on 0.3.0 —
|
|
66
|
+
that was a docs gap, not a code gap; it is now documented as plain fact.)
|
|
67
|
+
|
|
68
|
+
### Added — exports (R5/R6)
|
|
69
|
+
|
|
70
|
+
- **`RAW_KNOB_SUPPORT`** (the provider×knob matrix) + **`rawKnobSupport(provider)`**
|
|
71
|
+
(a pure lookup) — a multi-provider dispatcher ASKS which knobs a provider
|
|
72
|
+
honors instead of duplicating our lists. The guard (`assertRawKnobsSupported`)
|
|
73
|
+
and the docs generator both import this table.
|
|
74
|
+
- **`GEMINI_THINKING_CAPABLE_MODELS`** — the thinking-capable set (previously
|
|
75
|
+
un-exported), so customers stop duplicating it (the §3.1 drift complaint).
|
|
76
|
+
- **`coarsenGrokReasoningEffort`** + **`renderRawKnobMatrix`** — the disclosed
|
|
77
|
+
grok coarsening and the docs matrix renderer.
|
|
78
|
+
|
|
79
|
+
### Docs
|
|
80
|
+
|
|
81
|
+
- A generated provider×knob matrix on the modelrig.dev route-bundles page and in
|
|
82
|
+
`llms.txt`, rendered FROM `RAW_KNOB_SUPPORT` (never a hand-written twin).
|
|
83
|
+
- `caching-lifecycle.md`: the cache directive is provider-neutral — a resource
|
|
84
|
+
HANDLE on gemini, a routing HINT (`prompt_cache_key`, retention on openai) on
|
|
85
|
+
the OpenAI-dialect providers.
|
|
86
|
+
|
|
87
|
+
CE-8 — first-class **runRaw-only construction**. A Lane-B customer who only calls
|
|
88
|
+
`rig.runRaw`/`runRawStream` can now build a rig with no routes at all, so a stray
|
|
89
|
+
route file it never serves cannot down construction — retiring the empty-temp-dir
|
|
90
|
+
workaround.
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
- **`RigConfig.routesDir` now accepts `null`** (was `string`). With `null`,
|
|
95
|
+
`createRig` SKIPS route loading, the `rig.yaml` manifest, and the
|
|
96
|
+
serveable-candidate gate; `runRaw`/`runRawStream` work exactly as before. The
|
|
97
|
+
`string` path is byte-identical to 0.3.0 (the existing serveability hard-error
|
|
98
|
+
on a zero-serveable route is unchanged and regression-pinned).
|
|
99
|
+
- **`requireRoutesDir(config, surface)`** exported — narrows `routesDir` to a
|
|
100
|
+
string for route-required contexts, throwing the teaching failure on `null`.
|
|
101
|
+
Used by `modelrig-server` and `modelrig-oracle` (both always serve routes).
|
|
102
|
+
|
|
103
|
+
### Behaviour
|
|
104
|
+
|
|
105
|
+
- On a `routesDir: null` rig, `run`/`runStream`/`runBundle`/`runBundleStream`/
|
|
106
|
+
`replay`/`bakeoff`/`bakeoffFromEvalCases`/`verifySwap` throw `RigFailureError`
|
|
107
|
+
class `invariant_violation` (no new failure class) with the fixHint
|
|
108
|
+
*"this rig was constructed runRaw-only (routesDir: null); give createRig a
|
|
109
|
+
routesDir to serve routes"*. `rig.serveability` is `[]`.
|
|
110
|
+
- `loadConfigFromEnv` stays string-only (no env var disables routes, by design);
|
|
111
|
+
opt out in code: `createRig({ ...loadConfigFromEnv(), routesDir: null })`.
|
|
112
|
+
|
|
113
|
+
### Docs
|
|
114
|
+
|
|
115
|
+
- README, `docs/migration-playbook.md` (Lane-B seam + C4 checkpoint), and the
|
|
116
|
+
generated `llms.txt` gain the runRaw-only construction snippet, the `apiKey`
|
|
117
|
+
BYOK line on every `runRaw` example, the combined-prompt → `userPrompt` note,
|
|
118
|
+
and the note that the cache-ratio-vs-baseline metric is a REAL-run measurement
|
|
119
|
+
(deferred-to-first-run at the checkpoint), not a probe.
|
|
120
|
+
|
|
121
|
+
R0 — the **per-call telemetry ladder key** (routing-console spec §2.1). Every
|
|
122
|
+
inference row now records which call it belongs to and its position in the
|
|
123
|
+
routing ladder, so a dashboard can reconstruct the exact sequence one `rig.run`
|
|
124
|
+
walked and compute fallback / repair rates.
|
|
125
|
+
|
|
126
|
+
### Added — telemetry ladder key
|
|
127
|
+
|
|
128
|
+
- **`RunMeta.callId`** — the `call_id` shared by every telemetry row a single
|
|
129
|
+
`run` / `runStream` / `runBundle` / `runRaw` invocation writes (primary, retry,
|
|
130
|
+
repair, grounding-search, tool-call), so a caller can correlate a `RunResult`
|
|
131
|
+
with its ladder in the console. Additive & OPTIONAL — a pre-0.4.0 caller's meta
|
|
132
|
+
omits it.
|
|
133
|
+
- Telemetry rows gain **`call_id`**, **`attempt_seq`** (1-based, monotonic across
|
|
134
|
+
every row of the call), and **`candidate_index`** (position of the dispatched
|
|
135
|
+
candidate in the call's EFFECTIVE declared list — after variant narrowing and
|
|
136
|
+
per-run filters; a repair row carries the repaired candidate's index; the raw
|
|
137
|
+
lane is seq 1 / index 0). All three are OPTIONAL on the wire and nullable in
|
|
138
|
+
storage: an older SDK OMITS them and the payload is byte-identical to before
|
|
139
|
+
R0; a reader treats null as *"recorded by an SDK older than 0.4.0."*
|
|
140
|
+
- OTLP spans gain `modelrig.call_id` / `modelrig.attempt_seq` /
|
|
141
|
+
`modelrig.candidate_index`, emitted only when present.
|
|
142
|
+
- **`CandidateIterator.index`** (read-only getter, public type) — the index of the
|
|
143
|
+
candidate the last `next()` returned (−1 before the first call). Additive for
|
|
144
|
+
callers; an external IMPLEMENTER of the interface must add the member.
|
|
145
|
+
- **`tags.rung`** on every telemetry row (R1 review, F1) — one of `primary` |
|
|
146
|
+
`retry` | `repair` | `search` | `tool_call` | `predispatch_fail`, so the routing
|
|
147
|
+
dashboard and ladder view can tell a real candidate dispatch from a tool-call
|
|
148
|
+
turn or a pre-dispatch failure without column heuristics. Additive (rides
|
|
149
|
+
`tags_json`, no schema change); a pre-0.4.0 row omits it and the rollup falls
|
|
150
|
+
back to `repaired_by` / `provider = "search"`. Public type `TelemetryRung` is
|
|
151
|
+
exported.
|
|
152
|
+
|
|
13
153
|
## [0.3.0] — 2026-08-21
|
|
14
154
|
|
|
15
155
|
The `modelrig-oracle` MCP server ships to npm alongside this release (its own
|
package/README.md
CHANGED
|
@@ -99,27 +99,75 @@ over the route's `cache: auto` stamp, and a non-matching fallback dispatches
|
|
|
99
99
|
without it. ModelRig carries the handle and prices the hits — it never creates,
|
|
100
100
|
refreshes, or deletes the resource, so a long job needs your own TTL heartbeat
|
|
101
101
|
(see the [caching lifecycle](https://modelrig.dev/caching-lifecycle.html) doc).
|
|
102
|
-
The Lane-B `rig.runRaw({ provider, model, …, cache: { key } })` seam takes
|
|
103
|
-
same field.
|
|
102
|
+
The Lane-B `rig.runRaw({ provider, model, apiKey, …, cache: { key } })` seam takes
|
|
103
|
+
the same field.
|
|
104
104
|
|
|
105
105
|
`rig.runRaw` also accepts
|
|
106
|
-
|
|
107
|
-
`grounding: { mode: "native" }` (native provider web grounding
|
|
108
|
-
|
|
109
|
-
`reasoning: { level: "minimal" | "low" | "medium" | "high" }` (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
106
|
+
provider knobs, each additive — absent ⇒ byte-identical dispatch:
|
|
107
|
+
`grounding: { mode: "native" }` (native provider web grounding —
|
|
108
|
+
gemini; grok fail-closed until CE-9b), `serviceTier: "standard" | "flex" | "priority"`,
|
|
109
|
+
`reasoning: { level: "minimal" | "low" | "medium" | "high" }` (reasoning effort¹),
|
|
110
|
+
and `responseFormat: "json_object"` (syntactic-JSON forcing¹ — MIME-shaping, NOT
|
|
111
|
+
schema enforcement, so `meta.validated` stays `false`). A declared directive a
|
|
112
|
+
provider cannot honor FAILS CLOSED — a thrown `RigFailureError` with class
|
|
113
|
+
`invariant_violation`, pre-dispatch (no meter, no provider call) — never a silent
|
|
114
|
+
drop. **Which provider honors which knob is one table** — the runtime guard and
|
|
115
|
+
the published
|
|
116
|
+
[provider × knob matrix](https://modelrig.dev/route-bundles.html#raw-lane-provider-knob-support-rigrunraw)
|
|
117
|
+
are generated from the same `RAW_KNOB_SUPPORT`; ask it in code with
|
|
118
|
+
`rawKnobSupport(provider)` (and `GEMINI_THINKING_CAPABLE_MODELS` is exported so
|
|
119
|
+
you don't duplicate the thinking-model set). A grounded step that also passes a
|
|
120
|
+
`cache.key` keeps its cached-token ratio: bake the `googleSearch` tool into the
|
|
121
|
+
cache resource at creation (ModelRig sends `cachedContent` without tools, which
|
|
122
|
+
the provider requires).
|
|
123
|
+
|
|
124
|
+
_¹ Multi-provider `reasoning` and `responseFormat` ship in
|
|
125
|
+
0.4.0; on the published package `reasoning`/`grounding` are gemini-only._
|
|
126
|
+
|
|
127
|
+
**runRaw — a BYOK passthrough (Lane B).** When you don't need a route — no
|
|
128
|
+
schema, no validation, no retries — call a `provider/model` directly with your
|
|
129
|
+
own provider key:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
const rig = createRig(loadConfigFromEnv());
|
|
133
|
+
const result = await rig.runRaw({
|
|
134
|
+
provider: "gemini",
|
|
135
|
+
model: "gemini-3.1-pro",
|
|
136
|
+
apiKey: process.env.GEMINI_API_KEY!, // runRaw is BYOK — pass your provider key
|
|
137
|
+
systemPrompt: "", // one combined prompt? put it ALL in userPrompt, leave systemPrompt empty
|
|
138
|
+
userPrompt: buildPrompt(input),
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`runRaw` is BYOK — pass your provider key; ModelRig holds it for the one call and
|
|
143
|
+
never stores it. It records one metered `lane=raw` telemetry row at the
|
|
144
|
+
provider's list price (zero ModelRig margin) and throws a typed `RigFailureError`
|
|
145
|
+
on failure, exactly like `rig.run`.
|
|
146
|
+
|
|
147
|
+
**runRaw-only construction (`routesDir: null`) — 0.4.0+.** A
|
|
148
|
+
Lane-B deployment that ONLY calls `runRaw`/`runRawStream` has no routes. Build it
|
|
149
|
+
with `routesDir: null` and `createRig` skips route loading, the `rig.yaml`
|
|
150
|
+
manifest, and the serveability gate entirely — so a stray route file it never
|
|
151
|
+
calls (or a route whose provider key is absent in this deployment) can no longer
|
|
152
|
+
down construction:
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
const rig = createRig({ ...loadConfigFromEnv(), routesDir: null });
|
|
156
|
+
await rig.runRaw({ provider, model, apiKey, systemPrompt, userPrompt });
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`loadConfigFromEnv()` always yields a string `routesDir`, so the opt-out is a
|
|
160
|
+
deliberate code-level choice — override it as above; there is no env var that
|
|
161
|
+
disables routes, by design. On such a rig, `rig.run` and every other
|
|
162
|
+
route-dependent surface (`runStream`, `runBundle`, bake-offs, watch, replay,
|
|
163
|
+
`verifySwap`) throws a terminal `invariant_violation` naming the fix.
|
|
116
164
|
|
|
117
165
|
Every attempt is recorded in a local SQLite file (`.modelrig/telemetry.db`)
|
|
118
166
|
tagged with your `tags`. Failures are typed —
|
|
119
167
|
`RigFailureError.failure.class` is one of `content_invalid`, `capacity_shed`,
|
|
120
|
-
`network`, `refusal`, `cache_invalid`, `timeout`, `budget_exhausted`,
|
|
168
|
+
`network`, `refusal`, `cache_invalid`, `timeout`, `config_auth`, `budget_exhausted`,
|
|
121
169
|
`invariant_violation` — with a separate retry budget per class, so a flaky
|
|
122
|
-
network never spends your content-validation retries.
|
|
170
|
+
network never spends your content-validation retries. What each class means, whether it retries, and how it backs off is on [Routing & reliability](https://modelrig.dev/routing-reliability.html#5-failure-classes).
|
|
123
171
|
|
|
124
172
|
## CLI
|
|
125
173
|
|
|
@@ -155,6 +203,10 @@ on the quickstart:
|
|
|
155
203
|
stable enough to build on, not frozen.
|
|
156
204
|
- **`modelrig serve` needs the `modelrig-server` package** — it is not bundled
|
|
157
205
|
here.
|
|
206
|
+
- **What the ladder does and does not do.** Fall-through is structural and
|
|
207
|
+
infrastructural, never a quality judgment; the full boundary (quality gate,
|
|
208
|
+
raw-lane structure, latency ordering…) is generated and tripwire-tested on
|
|
209
|
+
[Routing & reliability](https://modelrig.dev/routing-reliability.html#10-not-yet-implemented-the-boundary).
|
|
158
210
|
|
|
159
211
|
## License
|
|
160
212
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deepseek.d.ts","sourceRoot":"","sources":["../../src/adapters/deepseek.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAMhG,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAKD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAMhF;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAiB1E;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAC1D,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;KAAE,CAAC;IAC5D,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAOD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,oBAAoB,
|
|
1
|
+
{"version":3,"file":"deepseek.d.ts","sourceRoot":"","sources":["../../src/adapters/deepseek.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAMhG,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAKD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAMhF;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAiB1E;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAC1D,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;KAAE,CAAC;IAC5D,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAOD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,oBAAoB,CAkC1F;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CA8JpF"}
|
|
@@ -62,6 +62,13 @@ function classifyDeepSeekFailure(message) {
|
|
|
62
62
|
const JSON_GUARD = "Respond with a single valid JSON object.";
|
|
63
63
|
function buildDeepSeekParams(model, req) {
|
|
64
64
|
const wantJson = req.outputSchema !== null;
|
|
65
|
+
// CE-9 R4: the raw lane's `responseFormat: "json_object"` also drives DeepSeek's
|
|
66
|
+
// json_object mode (the flag previously fired ONLY on the routed outputSchema
|
|
67
|
+
// path, which is always null on the raw lane). Absent both ⇒ no key
|
|
68
|
+
// (byte-identical). The JSON_GUARD below stays keyed on the ROUTED path only:
|
|
69
|
+
// on the raw lane the word-"JSON" wrinkle is the caller's prompt responsibility
|
|
70
|
+
// (spec R4), not silently intercepted here.
|
|
71
|
+
const jsonObject = wantJson || req.responseFormat === "json_object";
|
|
65
72
|
let systemPrompt = req.systemPrompt;
|
|
66
73
|
if (wantJson && !req.systemPrompt.includes("JSON") && !req.userPrompt.includes("JSON")) {
|
|
67
74
|
systemPrompt = systemPrompt === "" ? JSON_GUARD : `${systemPrompt}\n\n${JSON_GUARD}`;
|
|
@@ -77,7 +84,7 @@ function buildDeepSeekParams(model, req) {
|
|
|
77
84
|
stream: true,
|
|
78
85
|
stream_options: { include_usage: true },
|
|
79
86
|
...(0, sampling_1.openAISamplingFields)(req),
|
|
80
|
-
...(
|
|
87
|
+
...(jsonObject ? { response_format: { type: "json_object" } } : {}),
|
|
81
88
|
...(req.tools !== undefined && req.tools.length > 0
|
|
82
89
|
? {
|
|
83
90
|
tools: (0, tool_mapping_1.toOpenAITools)(req.tools),
|
|
@@ -18,6 +18,12 @@ import type { FailureClass } from "../types/failures";
|
|
|
18
18
|
export interface GeminiAdapterConfig {
|
|
19
19
|
readonly apiKey: string;
|
|
20
20
|
}
|
|
21
|
+
/** Models that accept thinkingConfig — passing it to 2.x models 400s.
|
|
22
|
+
* Ported from the production THINKING_CAPABLE_MODELS set. EXPORTED (CE-9 R6) so
|
|
23
|
+
* a multi-provider customer's dispatcher reads THIS set instead of duplicating
|
|
24
|
+
* it (the §3.1 drift complaint) — the same fact the raw-lane guard uses to keep
|
|
25
|
+
* gemini reasoning model-gated. */
|
|
26
|
+
export declare const GEMINI_THINKING_CAPABLE_MODELS: ReadonlySet<string>;
|
|
21
27
|
export declare function geminiSupports(feature: CapabilityFlag, model: string): boolean;
|
|
22
28
|
export interface ClassifiedFailure {
|
|
23
29
|
readonly cls: FailureClass;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EACV,cAAc,EAGd,cAAc,EACd,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,mBAAmB,CAAC;AAKlE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EACV,cAAc,EAGd,cAAc,EACd,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,mBAAmB,CAAC;AAKlE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;mCAImC;AACnC,eAAO,MAAM,8BAA8B,EAAE,WAAW,CAAC,MAAM,CAI7D,CAAC;AA0BH,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAG9E;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAyCxE;AAED;6EAC6E;AAC7E,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AAE7D;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,iBAAiB,GAAG,IAAI,CAQrG;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,mBAAmB,CAqDxF;AA0BD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,eAAe,CA+JhF"}
|
package/dist/adapters/gemini.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* gemini transformation logic is consulted during the port.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.GEMINI_THINKING_CAPABLE_MODELS = void 0;
|
|
18
19
|
exports.geminiSupports = geminiSupports;
|
|
19
20
|
exports.classifyGeminiFailure = classifyGeminiFailure;
|
|
20
21
|
exports.geminiReasoningUnsupported = geminiReasoningUnsupported;
|
|
@@ -24,8 +25,11 @@ const genai_1 = require("@google/genai");
|
|
|
24
25
|
const tool_mapping_1 = require("./tool-mapping");
|
|
25
26
|
const sampling_1 = require("./sampling");
|
|
26
27
|
/** Models that accept thinkingConfig — passing it to 2.x models 400s.
|
|
27
|
-
* Ported from the production THINKING_CAPABLE_MODELS set.
|
|
28
|
-
|
|
28
|
+
* Ported from the production THINKING_CAPABLE_MODELS set. EXPORTED (CE-9 R6) so
|
|
29
|
+
* a multi-provider customer's dispatcher reads THIS set instead of duplicating
|
|
30
|
+
* it (the §3.1 drift complaint) — the same fact the raw-lane guard uses to keep
|
|
31
|
+
* gemini reasoning model-gated. */
|
|
32
|
+
exports.GEMINI_THINKING_CAPABLE_MODELS = new Set([
|
|
29
33
|
"gemini-3.1-pro-preview",
|
|
30
34
|
"gemini-3.0-pro-preview",
|
|
31
35
|
"gemini-3.1-flash-preview",
|
|
@@ -110,7 +114,7 @@ function classifyGeminiFailure(message) {
|
|
|
110
114
|
* reasoning declared, or a thinking-capable model). Pure — unit-tested directly.
|
|
111
115
|
*/
|
|
112
116
|
function geminiReasoningUnsupported(model, req) {
|
|
113
|
-
if (req.reasoning !== undefined && !
|
|
117
|
+
if (req.reasoning !== undefined && !exports.GEMINI_THINKING_CAPABLE_MODELS.has(model)) {
|
|
114
118
|
return {
|
|
115
119
|
cls: "invariant_violation",
|
|
116
120
|
fixHint: `reasoning control requires a thinking-capable Gemini model; "${model}" is not one — remove reasoning or choose a thinking-capable model`,
|
|
@@ -134,12 +138,18 @@ function buildGeminiRequest(model, req) {
|
|
|
134
138
|
maxOutputTokens: (0, sampling_1.effectiveMaxOutputTokens)(req, DEFAULT_MAX_OUTPUT_TOKENS),
|
|
135
139
|
topP: req.sampling?.topP ?? TOP_P,
|
|
136
140
|
topK: TOP_K,
|
|
137
|
-
...(
|
|
141
|
+
...(exports.GEMINI_THINKING_CAPABLE_MODELS.has(model) ? { thinkingConfig: { thinkingLevel } } : {}),
|
|
138
142
|
};
|
|
139
143
|
if (req.outputSchema !== null) {
|
|
140
144
|
config.responseMimeType = "application/json";
|
|
141
145
|
config.responseJsonSchema = req.outputSchema;
|
|
142
146
|
}
|
|
147
|
+
else if (req.responseFormat === "json_object") {
|
|
148
|
+
// CE-9 R4: mime-shaping ONLY — force a JSON mime type WITHOUT a schema. This
|
|
149
|
+
// is the raw lane, so F4 stands: no responseJsonSchema, no validation, no
|
|
150
|
+
// repair, `validated` stays false. Absent ⇒ no key (byte-identical).
|
|
151
|
+
config.responseMimeType = "application/json";
|
|
152
|
+
}
|
|
143
153
|
// cachedContent excludes systemInstruction and tools — the API rejects
|
|
144
154
|
// requests setting both (they are baked into the cache at creation time,
|
|
145
155
|
// including the googleSearch tool for cached grounded steps).
|
package/dist/adapters/grok.d.ts
CHANGED
|
@@ -36,7 +36,14 @@ export interface GrokShapedParams {
|
|
|
36
36
|
/** Prompt-cache routing hint (WS-C) — the stable-prefix fingerprint the run
|
|
37
37
|
* loop stamps; xAI keeps a warm cache keyed to it (writes free today). */
|
|
38
38
|
readonly prompt_cache_key?: string;
|
|
39
|
+
/** CE-9 R1 — xAI accepts `reasoning_effort: "low" | "high"` ONLY, so the
|
|
40
|
+
* neutral four-level `level` is coarsened by `coarsenGrokReasoningEffort`
|
|
41
|
+
* (a DISCLOSED, lossy mapping: `minimal,low → "low"`; `medium,high → "high"`).
|
|
42
|
+
* Present only when the caller declared `reasoning`. */
|
|
43
|
+
readonly reasoning_effort?: "low" | "high";
|
|
39
44
|
readonly response_format?: {
|
|
45
|
+
readonly type: "json_object";
|
|
46
|
+
} | {
|
|
40
47
|
readonly type: "json_schema";
|
|
41
48
|
readonly json_schema: {
|
|
42
49
|
readonly name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grok.d.ts","sourceRoot":"","sources":["../../src/adapters/grok.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"grok.d.ts","sourceRoot":"","sources":["../../src/adapters/grok.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAOhG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAKD,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAc7E;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CA+BtE;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAC1D,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;8EAC0E;IAC1E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;4DAGwD;IACxD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC3C,QAAQ,CAAC,eAAe,CAAC,EACrB;QAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;KAAE,GAChC;QACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,WAAW,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;SAAE,CAAC;KACjG,CAAC;IACN,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,gBAAgB,CAmDlF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,eAAe,CAgK5E"}
|
package/dist/adapters/grok.js
CHANGED
|
@@ -23,6 +23,7 @@ const openai_1 = __importDefault(require("openai"));
|
|
|
23
23
|
const tool_mapping_1 = require("./tool-mapping");
|
|
24
24
|
const openai_stream_1 = require("./openai-stream");
|
|
25
25
|
const sampling_1 = require("./sampling");
|
|
26
|
+
const raw_support_1 = require("../run/raw-support");
|
|
26
27
|
const GROK_BASE_URL = "https://api.x.ai/v1";
|
|
27
28
|
const DEFAULT_MAX_TOKENS = 32000;
|
|
28
29
|
function grokSupports(feature, _model) {
|
|
@@ -65,6 +66,14 @@ function classifyGrokFailure(message) {
|
|
|
65
66
|
fixHint: "the candidate model was not found — fix the model id in the route's candidate list",
|
|
66
67
|
};
|
|
67
68
|
}
|
|
69
|
+
// CE-9 R1: a non-reasoning grok variant rejects `reasoning_effort` — teach the
|
|
70
|
+
// fix (pick a reasoning variant) rather than surface a cryptic 400.
|
|
71
|
+
if (/reasoning_effort/.test(msg)) {
|
|
72
|
+
return {
|
|
73
|
+
cls: "network",
|
|
74
|
+
fixHint: "this Grok model does not accept reasoning_effort — remove reasoning or pick a Grok reasoning variant",
|
|
75
|
+
};
|
|
76
|
+
}
|
|
68
77
|
return { cls: "network" };
|
|
69
78
|
}
|
|
70
79
|
function buildGrokParams(model, req) {
|
|
@@ -84,6 +93,17 @@ function buildGrokParams(model, req) {
|
|
|
84
93
|
...(req.cache?.key !== undefined && req.cache.key !== ""
|
|
85
94
|
? { prompt_cache_key: req.cache.key }
|
|
86
95
|
: {}),
|
|
96
|
+
// CE-9 R1: coarsen the neutral level to xAI's low|high (disclosed mapping).
|
|
97
|
+
// Absent ⇒ no key. A non-reasoning grok model's rejection is taught below.
|
|
98
|
+
...(req.reasoning !== undefined
|
|
99
|
+
? { reasoning_effort: (0, raw_support_1.coarsenGrokReasoningEffort)(req.reasoning.level) }
|
|
100
|
+
: {}),
|
|
101
|
+
// CE-9b: grounding is NOT mapped here. xAI retired Live Search
|
|
102
|
+
// (`search_parameters` → HTTP 410 on the CE-9 live gate); the replacement
|
|
103
|
+
// `web_search` tool is Responses-API-only. The raw-lane guard fails grok
|
|
104
|
+
// grounding closed (matrix: supported=false) until CE-9b adds that path.
|
|
105
|
+
// response_format: a native strict json_schema (routed lane) wins; else the
|
|
106
|
+
// RAW lane's mime-shaping json_object (CE-9 R4). Absent both ⇒ no key.
|
|
87
107
|
...(req.outputSchema !== null
|
|
88
108
|
? {
|
|
89
109
|
response_format: {
|
|
@@ -95,7 +115,9 @@ function buildGrokParams(model, req) {
|
|
|
95
115
|
},
|
|
96
116
|
},
|
|
97
117
|
}
|
|
98
|
-
:
|
|
118
|
+
: req.responseFormat === "json_object"
|
|
119
|
+
? { response_format: { type: "json_object" } }
|
|
120
|
+
: {}),
|
|
99
121
|
...(req.tools !== undefined && req.tools.length > 0
|
|
100
122
|
? {
|
|
101
123
|
tools: (0, tool_mapping_1.toOpenAITools)(req.tools),
|
|
@@ -49,6 +49,13 @@ export interface OpenAICompatShapedParams {
|
|
|
49
49
|
/** CE-6 declared sampling — present only when the route/raw asks for them. */
|
|
50
50
|
readonly temperature?: number;
|
|
51
51
|
readonly top_p?: number;
|
|
52
|
+
/** CE-9 R1 — reasoning effort forwarded verbatim (1:1). Present only when the
|
|
53
|
+
* caller declared `reasoning`; a host/model that does not accept it rejects at
|
|
54
|
+
* the provider and `classifyCompatFailure` teaches (no per-model allowlist). */
|
|
55
|
+
readonly reasoning_effort?: "minimal" | "low" | "medium" | "high";
|
|
56
|
+
/** CE-9 R3 — the DeepInfra prompt_cache_key gap: `cache.key` → the routing
|
|
57
|
+
* hint. Present only when the caller supplies `cache.key`. */
|
|
58
|
+
readonly prompt_cache_key?: string;
|
|
52
59
|
readonly response_format?: {
|
|
53
60
|
readonly type: "json_object";
|
|
54
61
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-compat.d.ts","sourceRoot":"","sources":["../../src/adapters/openai-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EACf,UAAU,EACX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAQhG;;8CAE8C;AAC9C,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACnD;AAED;;;0EAG0E;AAC1E,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,GAAG,WAAW,EAAE,gBAAgB,CAAC,CAG7F,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"openai-compat.d.ts","sourceRoot":"","sources":["../../src/adapters/openai-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EACf,UAAU,EACX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAQhG;;8CAE8C;AAC9C,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACnD;AAED;;;0EAG0E;AAC1E,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,GAAG,WAAW,EAAE,gBAAgB,CAAC,CAG7F,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,CA2BtF;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAC1D,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;oFAEgF;IAChF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClE;kEAC8D;IAC9D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EACrB;QAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;KAAE,GAChC;QACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,WAAW,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KACjG,CAAC;IACN,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAOD;;2DAE2D;AAC3D,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,YAAY,EACjB,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,GACxC,wBAAwB,CAmD1B;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD;+DAC2D;IAC3D,QAAQ,CAAC,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC,cAAc,CAAC,CAAC;CAC5E;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,GAAG,eAAe,CAwK5F"}
|
|
@@ -66,6 +66,15 @@ function classifyCompatFailure(message, host) {
|
|
|
66
66
|
fixHint: "the candidate model was not found — fix the model id in the route's candidate list",
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
|
+
// CE-9 R1: a model that does not accept `reasoning_effort` rejects the request
|
|
70
|
+
// — teach it rather than surfacing a cryptic generic 400 (the reason we forward
|
|
71
|
+
// verbatim instead of keeping a per-model allowlist).
|
|
72
|
+
if (/reasoning_effort/.test(msg)) {
|
|
73
|
+
return {
|
|
74
|
+
cls: "network",
|
|
75
|
+
fixHint: `this ${host} model does not accept reasoning_effort — remove reasoning or pick a reasoning model`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
69
78
|
return { cls: "network" };
|
|
70
79
|
}
|
|
71
80
|
/** json_object mode 400s on several compat backends when the literal word
|
|
@@ -93,6 +102,18 @@ function buildOpenAICompatParams(model, req, profileFlags) {
|
|
|
93
102
|
stream: true,
|
|
94
103
|
stream_options: { include_usage: true },
|
|
95
104
|
...(0, sampling_1.openAISamplingFields)(req),
|
|
105
|
+
// CE-9 R1: forward reasoning effort verbatim (1:1). Absent ⇒ no key.
|
|
106
|
+
...(req.reasoning !== undefined ? { reasoning_effort: req.reasoning.level } : {}),
|
|
107
|
+
// CE-9 R3: the DeepInfra prompt_cache_key gap — map cache.key → the routing
|
|
108
|
+
// hint (absent ⇒ no key, byte-identical). Additive; unrecognized on a host
|
|
109
|
+
// that doesn't cache, the hint is simply ignored.
|
|
110
|
+
...(req.cache?.key !== undefined && req.cache.key !== ""
|
|
111
|
+
? { prompt_cache_key: req.cache.key }
|
|
112
|
+
: {}),
|
|
113
|
+
// response_format: a routed strict json_schema (structured_native profile)
|
|
114
|
+
// wins; else routed json_object; else the RAW lane's mime-shaping json_object
|
|
115
|
+
// (CE-9 R4). The raw path carries NO JSON_GUARD injection — the word-"JSON"
|
|
116
|
+
// wrinkle is the caller's prompt responsibility on the raw lane.
|
|
96
117
|
...(wantJson
|
|
97
118
|
? strict
|
|
98
119
|
? {
|
|
@@ -102,7 +123,9 @@ function buildOpenAICompatParams(model, req, profileFlags) {
|
|
|
102
123
|
},
|
|
103
124
|
}
|
|
104
125
|
: { response_format: { type: "json_object" } }
|
|
105
|
-
:
|
|
126
|
+
: req.responseFormat === "json_object"
|
|
127
|
+
? { response_format: { type: "json_object" } }
|
|
128
|
+
: {}),
|
|
106
129
|
...(req.tools !== undefined && req.tools.length > 0
|
|
107
130
|
? {
|
|
108
131
|
tools: (0, tool_mapping_1.toOpenAITools)(req.tools),
|
|
@@ -38,7 +38,14 @@ export interface OpenAIShapedParams {
|
|
|
38
38
|
readonly service_tier?: "flex" | "priority";
|
|
39
39
|
readonly prompt_cache_key?: string;
|
|
40
40
|
readonly prompt_cache_retention?: "24h";
|
|
41
|
+
/** CE-9 R1 — reasoning effort forwarded verbatim (1:1 from the neutral
|
|
42
|
+
* `level`). Present only when the caller declared `reasoning`. A model that
|
|
43
|
+
* does not accept it rejects at the provider; `classifyOpenAIFailure` turns
|
|
44
|
+
* that 400 into a teaching failure (no per-model allowlist). */
|
|
45
|
+
readonly reasoning_effort?: "minimal" | "low" | "medium" | "high";
|
|
41
46
|
readonly response_format?: {
|
|
47
|
+
readonly type: "json_object";
|
|
48
|
+
} | {
|
|
42
49
|
readonly type: "json_schema";
|
|
43
50
|
readonly json_schema: {
|
|
44
51
|
readonly name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAMhG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAMD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAI9D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAe9E;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMhE,OAAO,KAAK,EAAuB,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAMhG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAMD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAI9D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAe9E;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CA8BxE;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IAC1D,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC5C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,KAAK,CAAC;IACxC;;;oEAGgE;IAChE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClE,QAAQ,CAAC,eAAe,CAAC,EACrB;QAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;KAAE,GAChC;QACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,WAAW,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;SAAE,CAAC;KACjG,CAAC;IACN,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAID,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,kBAAkB,CAuDtF;AAcD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,eAAe,CAwMhF"}
|
package/dist/adapters/openai.js
CHANGED
|
@@ -71,6 +71,18 @@ function classifyOpenAIFailure(message) {
|
|
|
71
71
|
fixHint: "the candidate model was not found — fix the model id in the route's candidate list",
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
+
// CE-9 R1: a model that does not accept `reasoning_effort` rejects the request
|
|
75
|
+
// (400 "unsupported/unknown parameter reasoning_effort"). Teach it instead of
|
|
76
|
+
// surfacing a cryptic generic 400 — the whole point of forwarding verbatim
|
|
77
|
+
// rather than keeping a per-model allowlist. Mirrors gemini's invalid_argument
|
|
78
|
+
// → network + fixHint (a request-shape rejection, retryable to the next
|
|
79
|
+
// candidate, never terminal).
|
|
80
|
+
if (/reasoning_effort/.test(msg)) {
|
|
81
|
+
return {
|
|
82
|
+
cls: "network",
|
|
83
|
+
fixHint: "this model does not accept reasoning_effort — remove reasoning or pick a reasoning model (e.g. an o-series / gpt-5 reasoning model)",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
74
86
|
return { cls: "network" };
|
|
75
87
|
}
|
|
76
88
|
const DEFAULT_MAX_COMPLETION_TOKENS = 32000;
|
|
@@ -98,6 +110,14 @@ function buildOpenAIParams(model, req) {
|
|
|
98
110
|
...((req.cache.ttlSeconds ?? 0) >= 86400 ? { prompt_cache_retention: "24h" } : {}),
|
|
99
111
|
}
|
|
100
112
|
: {}),
|
|
113
|
+
// CE-9 R1: forward reasoning effort verbatim (1:1). Absent ⇒ no key
|
|
114
|
+
// (byte-identical). The provider — not an allowlist here — decides whether
|
|
115
|
+
// the model accepts it; a rejection is classified teachably below.
|
|
116
|
+
...(req.reasoning !== undefined ? { reasoning_effort: req.reasoning.level } : {}),
|
|
117
|
+
// response_format precedence: a native/strict json_schema (routed lane,
|
|
118
|
+
// outputSchema set) WINS; else the raw lane's mime-shaping json_object
|
|
119
|
+
// (CE-9 R4). The two never co-occur — the routed lane sets outputSchema, the
|
|
120
|
+
// raw lane responseFormat — but the precedence keeps resolution deterministic.
|
|
101
121
|
...(req.outputSchema !== null
|
|
102
122
|
? {
|
|
103
123
|
response_format: {
|
|
@@ -109,7 +129,9 @@ function buildOpenAIParams(model, req) {
|
|
|
109
129
|
},
|
|
110
130
|
},
|
|
111
131
|
}
|
|
112
|
-
:
|
|
132
|
+
: req.responseFormat === "json_object"
|
|
133
|
+
? { response_format: { type: "json_object" } }
|
|
134
|
+
: {}),
|
|
113
135
|
...(req.tools !== undefined && req.tools.length > 0
|
|
114
136
|
? {
|
|
115
137
|
tools: (0, tool_mapping_1.toOpenAITools)(req.tools),
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG;AAkCH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACpC;AAeD,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAuBxD;AA0gBD,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqCnE"}
|
package/dist/cli.js
CHANGED
|
@@ -35,6 +35,7 @@ const samples_1 = require("./bakeoff/samples");
|
|
|
35
35
|
const report_1 = require("./bakeoff/report");
|
|
36
36
|
const cli_run_1 = require("./verify/cli-run");
|
|
37
37
|
const loader_1 = require("./routes/loader");
|
|
38
|
+
const rawonly_1 = require("./run/rawonly");
|
|
38
39
|
const validate_cli_1 = require("./validate-cli");
|
|
39
40
|
const store_1 = require("./telemetry/store");
|
|
40
41
|
const budget_1 = require("./watch/budget");
|
|
@@ -156,7 +157,7 @@ async function cmdBakeoff(flags) {
|
|
|
156
157
|
throw new Error(`proposal ${proposalId} is ${proposal.status} — evidence runs apply to ` +
|
|
157
158
|
"suggested/evidenced proposals only");
|
|
158
159
|
}
|
|
159
|
-
const routes = (0, loader_1.loadRoutes)(
|
|
160
|
+
const routes = (0, loader_1.loadRoutes)((0, rawonly_1.requireRoutesDir)(config, "modelrig bakeoff"));
|
|
160
161
|
const bundle = routes.get(proposal.route);
|
|
161
162
|
const variants = ["default", ...bundle.variants.map((v) => v.name)];
|
|
162
163
|
const lastRaw = flags.named.get("replay-last");
|
|
@@ -243,7 +244,7 @@ async function cmdWatch(flags) {
|
|
|
243
244
|
}
|
|
244
245
|
const config = (0, config_1.loadConfigFromEnv)();
|
|
245
246
|
const client = proposalsClientFrom(config);
|
|
246
|
-
const routes = (0, loader_1.loadRoutes)(
|
|
247
|
+
const routes = (0, loader_1.loadRoutes)((0, rawonly_1.requireRoutesDir)(config, "modelrig watch"));
|
|
247
248
|
const routeEconomics = routes.list().map((b) => ({
|
|
248
249
|
route: b.route,
|
|
249
250
|
candidates: b.candidates.map((c) => ({ provider: c.provider, model: c.model })),
|
|
@@ -318,7 +319,7 @@ async function cmdSwapExecute(flags) {
|
|
|
318
319
|
const config = (0, config_1.loadConfigFromEnv)();
|
|
319
320
|
const proposals = proposalsClientFrom(config);
|
|
320
321
|
const swaps = swapsClientFrom(config);
|
|
321
|
-
const routes = (0, loader_1.loadRoutes)(
|
|
322
|
+
const routes = (0, loader_1.loadRoutes)((0, rawonly_1.requireRoutesDir)(config, "modelrig swap execute"));
|
|
322
323
|
// The orchestration (guards, ordering, baseline snapshot) lives in the
|
|
323
324
|
// hermetically-tested executeSwap; the CLI only injects the real config
|
|
324
325
|
// deps and prints. The --approve gate is enforced here (fast-fail before
|
|
@@ -359,7 +360,7 @@ async function cmdSwapRevert(flags) {
|
|
|
359
360
|
const incumbents = swap.baseline.incumbent_candidates ?? [];
|
|
360
361
|
console.log(`swap ${swapId} marked reverted — the odometer stops accruing it at ${revertedAt}\n`);
|
|
361
362
|
console.log("APPLY THIS CHANGE (git is the actuator, as always):\n");
|
|
362
|
-
const routes = (0, loader_1.loadRoutes)(
|
|
363
|
+
const routes = (0, loader_1.loadRoutes)((0, rawonly_1.requireRoutesDir)(config, "modelrig swap revert"));
|
|
363
364
|
let version = null;
|
|
364
365
|
try {
|
|
365
366
|
version = routes.get(swap.route).version + 1;
|