modelrig 0.9.0 → 0.10.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 +179 -0
- package/README.md +51 -27
- package/data/PROVENANCE.md +14 -0
- package/data/pricing-map.json +26 -0
- package/dist/adapters/attempt-meta-map.d.ts +8 -1
- package/dist/adapters/attempt-meta-map.d.ts.map +1 -1
- package/dist/adapters/attempt-meta-map.js +4 -0
- package/dist/adapters/build-adapters.js +2 -2
- package/dist/adapters/gemini.d.ts +28 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +38 -9
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +53 -4
- package/dist/adapters/openai-compat.d.ts +8 -2
- package/dist/adapters/openai-compat.d.ts.map +1 -1
- package/dist/adapters/openai-compat.js +8 -1
- package/dist/adapters/openai-stream.d.ts +10 -2
- package/dist/adapters/openai-stream.d.ts.map +1 -1
- package/dist/adapters/openai-stream.js +5 -1
- package/dist/adapters/openai.d.ts +10 -1
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +57 -7
- package/dist/adapters/responses-api.d.ts +61 -0
- package/dist/adapters/responses-api.d.ts.map +1 -0
- package/dist/adapters/responses-api.js +124 -0
- package/dist/artifacts/artifact.d.ts +20 -0
- package/dist/artifacts/artifact.d.ts.map +1 -1
- package/dist/artifacts/artifact.js +207 -171
- package/dist/artifacts/index.d.ts +3 -1
- package/dist/artifacts/index.d.ts.map +1 -1
- package/dist/artifacts/index.js +8 -1
- package/dist/bakeoff/groundedness.d.ts +58 -0
- package/dist/bakeoff/groundedness.d.ts.map +1 -0
- package/dist/bakeoff/groundedness.js +165 -0
- package/dist/bakeoff/quality.d.ts +14 -1
- package/dist/bakeoff/quality.d.ts.map +1 -1
- package/dist/bakeoff/quality.js +10 -0
- package/dist/bakeoff/replay.d.ts.map +1 -1
- package/dist/bakeoff/replay.js +4 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +23 -0
- package/dist/doctor-cli.d.ts +7 -0
- package/dist/doctor-cli.d.ts.map +1 -0
- package/dist/doctor-cli.js +67 -0
- package/dist/doctor-preflight.d.ts +52 -0
- package/dist/doctor-preflight.d.ts.map +1 -0
- package/dist/doctor-preflight.js +112 -0
- package/dist/feedback/grade.d.ts +8 -1
- package/dist/feedback/grade.d.ts.map +1 -1
- package/dist/feedback/grade.js +4 -0
- package/dist/gateway/http-protocol.d.ts +19 -0
- package/dist/gateway/http-protocol.d.ts.map +1 -1
- package/dist/gateway/serve-client.d.ts +99 -0
- package/dist/gateway/serve-client.d.ts.map +1 -0
- package/dist/gateway/serve-client.js +360 -0
- package/dist/index.d.ts +25 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -8
- package/dist/prompts/manifest.d.ts +128 -0
- package/dist/prompts/manifest.d.ts.map +1 -0
- package/dist/prompts/manifest.js +214 -0
- package/dist/prompts/prompt-fetch.d.ts +84 -0
- package/dist/prompts/prompt-fetch.d.ts.map +1 -0
- package/dist/prompts/prompt-fetch.js +120 -0
- package/dist/prompts/prompt-resolve.d.ts +76 -0
- package/dist/prompts/prompt-resolve.d.ts.map +1 -0
- package/dist/prompts/prompt-resolve.js +93 -0
- package/dist/prompts/slot-resolver.d.ts +91 -0
- package/dist/prompts/slot-resolver.d.ts.map +1 -0
- package/dist/prompts/slot-resolver.js +135 -0
- package/dist/prompts/tools-register.d.ts +60 -0
- package/dist/prompts/tools-register.d.ts.map +1 -0
- package/dist/prompts/tools-register.js +48 -0
- package/dist/prompts/version-hash.d.ts +29 -0
- package/dist/prompts/version-hash.d.ts.map +1 -0
- package/dist/prompts/version-hash.js +54 -0
- package/dist/prompts-export-cli.d.ts +21 -0
- package/dist/prompts-export-cli.d.ts.map +1 -0
- package/dist/prompts-export-cli.js +130 -0
- package/dist/registry/cache-policy.d.ts.map +1 -1
- package/dist/registry/cache-policy.js +22 -0
- package/dist/registry/pricing-shape.d.ts +38 -8
- package/dist/registry/pricing-shape.d.ts.map +1 -1
- package/dist/registry/pricing-shape.js +40 -12
- package/dist/registry/pricing.d.ts +6 -5
- package/dist/registry/pricing.d.ts.map +1 -1
- package/dist/registry/pricing.js +9 -5
- package/dist/routes/destination-loader.d.ts +16 -0
- package/dist/routes/destination-loader.d.ts.map +1 -0
- package/dist/routes/destination-loader.js +29 -0
- package/dist/routes/draft.d.ts +7 -0
- package/dist/routes/draft.d.ts.map +1 -1
- package/dist/routes/draft.js +12 -0
- package/dist/routes/loader.d.ts.map +1 -1
- package/dist/routes/loader.js +27 -54
- package/dist/routes/output-loader.d.ts +42 -0
- package/dist/routes/output-loader.d.ts.map +1 -0
- package/dist/routes/output-loader.js +112 -0
- package/dist/routes/prompt-loader.d.ts +49 -0
- package/dist/routes/prompt-loader.d.ts.map +1 -0
- package/dist/routes/prompt-loader.js +113 -0
- package/dist/routes/resolved-bundle.d.ts +19 -0
- package/dist/routes/resolved-bundle.d.ts.map +1 -1
- package/dist/routes/resolved-bundle.js +24 -0
- package/dist/routes/screen-loader.d.ts +1 -1
- package/dist/routes/screen-loader.d.ts.map +1 -1
- package/dist/routes/screen-loader.js +8 -1
- package/dist/run/accept.d.ts +3 -0
- package/dist/run/accept.d.ts.map +1 -1
- package/dist/run/accept.js +1 -0
- package/dist/run/cost.d.ts +31 -2
- package/dist/run/cost.d.ts.map +1 -1
- package/dist/run/cost.js +57 -2
- package/dist/run/destination.d.ts +39 -0
- package/dist/run/destination.d.ts.map +1 -0
- package/dist/run/destination.js +45 -0
- package/dist/run/dispatch.d.ts +25 -3
- package/dist/run/dispatch.d.ts.map +1 -1
- package/dist/run/dispatch.js +26 -4
- package/dist/run/raw-defaults.d.ts.map +1 -1
- package/dist/run/raw-defaults.js +6 -1
- package/dist/run/raw-finalize.d.ts +50 -0
- package/dist/run/raw-finalize.d.ts.map +1 -0
- package/dist/run/raw-finalize.js +266 -0
- package/dist/run/raw-knobs.d.ts +36 -0
- package/dist/run/raw-knobs.d.ts.map +1 -0
- package/dist/run/raw-knobs.js +99 -0
- package/dist/run/raw-request.d.ts +24 -0
- package/dist/run/raw-request.d.ts.map +1 -0
- package/dist/run/raw-request.js +69 -0
- package/dist/run/raw-schema.d.ts +76 -0
- package/dist/run/raw-schema.d.ts.map +1 -0
- package/dist/run/raw-schema.js +166 -0
- package/dist/run/raw-search-cost.d.ts +48 -0
- package/dist/run/raw-search-cost.d.ts.map +1 -0
- package/dist/run/raw-search-cost.js +78 -0
- package/dist/run/raw-support.d.ts +64 -6
- package/dist/run/raw-support.d.ts.map +1 -1
- package/dist/run/raw-support.js +84 -11
- package/dist/run/raw.d.ts +25 -26
- package/dist/run/raw.d.ts.map +1 -1
- package/dist/run/raw.js +30 -351
- package/dist/run/record-attempt.d.ts +8 -0
- package/dist/run/record-attempt.d.ts.map +1 -1
- package/dist/run/record-attempt.js +26 -12
- package/dist/run/repair-attempt.d.ts +68 -0
- package/dist/run/repair-attempt.d.ts.map +1 -0
- package/dist/run/repair-attempt.js +180 -0
- package/dist/run/resolve-destination.d.ts +49 -0
- package/dist/run/resolve-destination.d.ts.map +1 -0
- package/dist/run/resolve-destination.js +76 -0
- package/dist/run/routing-docs.d.ts.map +1 -1
- package/dist/run/routing-docs.js +9 -4
- package/dist/run/run.d.ts +30 -1
- package/dist/run/run.d.ts.map +1 -1
- package/dist/run/run.js +75 -148
- package/dist/run/telemetry-row.d.ts +92 -0
- package/dist/run/telemetry-row.d.ts.map +1 -0
- package/dist/run/telemetry-row.js +81 -0
- package/dist/run/validate.d.ts +12 -1
- package/dist/run/validate.d.ts.map +1 -1
- package/dist/run/validate.js +31 -0
- package/dist/run/web-search-pricing.d.ts +43 -0
- package/dist/run/web-search-pricing.d.ts.map +1 -0
- package/dist/run/web-search-pricing.js +56 -0
- package/dist/settings/grading-guide.d.ts +27 -1
- package/dist/settings/grading-guide.d.ts.map +1 -1
- package/dist/status.d.ts +6 -0
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +4 -1
- package/dist/telemetry/artifact-store.d.ts.map +1 -1
- package/dist/telemetry/artifact-store.js +11 -0
- package/dist/telemetry/attempt-meta.d.ts +55 -1
- package/dist/telemetry/attempt-meta.d.ts.map +1 -1
- package/dist/telemetry/attempt-meta.js +24 -1
- package/dist/telemetry/exporter-setup.d.ts +2 -0
- package/dist/telemetry/exporter-setup.d.ts.map +1 -1
- package/dist/telemetry/exporter-setup.js +6 -1
- package/dist/telemetry/grade-mappers.d.ts +5 -2
- package/dist/telemetry/grade-mappers.d.ts.map +1 -1
- package/dist/telemetry/grade-mappers.js +8 -2
- package/dist/telemetry/grades-sql.d.ts +4 -1
- package/dist/telemetry/grades-sql.d.ts.map +1 -1
- package/dist/telemetry/grades-sql.js +26 -3
- package/dist/telemetry/ingest-protocol.d.ts +26 -2
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
- package/dist/telemetry/ingest-protocol.js +32 -29
- package/dist/telemetry/org-identity.d.ts +44 -0
- package/dist/telemetry/org-identity.d.ts.map +1 -0
- package/dist/telemetry/org-identity.js +98 -0
- package/dist/telemetry/route-registration.d.ts +48 -0
- package/dist/telemetry/route-registration.d.ts.map +1 -0
- package/dist/telemetry/route-registration.js +77 -0
- package/dist/telemetry/sinks.d.ts +10 -1
- package/dist/telemetry/sinks.d.ts.map +1 -1
- package/dist/telemetry/sinks.js +52 -6
- package/dist/telemetry/store-migrations.d.ts.map +1 -1
- package/dist/telemetry/store-migrations.js +13 -0
- package/dist/tenancy/api-key-format.d.ts +16 -1
- package/dist/tenancy/api-key-format.d.ts.map +1 -1
- package/dist/tenancy/api-key-format.js +17 -0
- package/dist/types/provider.d.ts +20 -3
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/provider.js +1 -0
- package/dist/types/route.d.ts +76 -0
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +30 -2
- package/dist/types/telemetry.d.ts.map +1 -1
- package/docs/agent-skill/SKILL.md +73 -5
- package/docs/instrumentation.md +81 -36
- package/docs/llms.txt +95 -16
- package/docs/managed-serving.md +150 -0
- package/docs/mcp-oracle.md +75 -2
- package/docs/migration-playbook.md +5 -4
- package/docs/quickstart.md +169 -83
- package/package.json +3 -2
- package/registry/registry.json +82 -0
- package/dist/feedback/feedback.d.ts +0 -35
- package/dist/feedback/feedback.d.ts.map +0 -1
- package/dist/feedback/feedback.js +0 -39
package/docs/mcp-oracle.md
CHANGED
|
@@ -58,7 +58,7 @@ on purpose.
|
|
|
58
58
|
| Tool | Does | Never does |
|
|
59
59
|
|---|---|---|
|
|
60
60
|
| `get_proposals` | Lists open proposals for your routes — each carries an `evidence.change_spec` (the machine-readable diff + `apply_instructions` a coding agent applies) plus its evidence and savings. | Change anything. |
|
|
61
|
-
| `create_route` | Writes a **draft** route bundle — YAML, schema, prompt — into your drafts directory, candidates seeded from the registry, your current model first. | Edit your source, register a route, overwrite an existing draft. |
|
|
61
|
+
| `create_route` | Writes a **draft** route bundle — YAML, schema, prompt — into your drafts directory, candidates seeded from the registry, your current model first. `output_kind: text` drafts a prose route (`output: text`, no schema); `user_prompt` adds a `prompt.user` per-call user turn. | Edit your source, register a route, overwrite an existing draft. |
|
|
62
62
|
| `test_route` | Makes **one** real billed call through a route, under a fresh budget envelope (default $1). | Run unbounded. |
|
|
63
63
|
| `run_bakeoff` | Replays captured inputs through challenger variants, each arm under its own envelope (default $2). | Switch what serves your route. |
|
|
64
64
|
| `run_optimizer` | Runs **one** explicit optimizer cycle for a route — reflect, score candidates on your golden eval cases, file a proposal carrying a `change_spec`. Pass `{ estimate: true }` first for the cost preview. Needs the `oracle-act` scope. | Apply anything; run on a schedule (there is none). |
|
|
@@ -66,7 +66,7 @@ on purpose.
|
|
|
66
66
|
| `execute_swap` | Records an approved swap and **returns** the route-YAML diff to apply via a PR. Needs the `decision` scope. | Write any file; commit to your repo. |
|
|
67
67
|
| `record_grade` | Attaches a 0–1 grade (with an optional comment) to one inference or a whole run — the signal the next cycle learns from. Needs the `grade` scope on the HTTP path. | Spend a billed call; guess attribution for an unknown subject. |
|
|
68
68
|
| `get_task_settings` / `set_task_settings` | Reads / writes a task's governance settings and its **grading guide** (the rubric the task's grader is taught from). `set` needs the `task-settings` scope. | Change route config (the pass threshold lives in the route, and is refused here). |
|
|
69
|
-
| `get_call_config` | Reads a route's **current live** call-config — its version, mode,
|
|
69
|
+
| `get_call_config` | Reads a route's **current live** call-config — its version, mode, the model(s) it serves, the `effective` model + why (pin / YAML default), and any `drift`. Read-only. | Change anything. |
|
|
70
70
|
| `set_call_config` | **Sets what serves a route right now** — pins a model or starts a live A/B — on the human's behalf. A real, versioned control-plane change. | Bypass the eligibility gate or the `route-config` scope; imply it is a draft. |
|
|
71
71
|
| `rollback_call_config` | Restores a prior call-config version (re-appended as a new version — history is never deleted). | Delete history; escape the scope check. |
|
|
72
72
|
|
|
@@ -84,6 +84,55 @@ This is the half of the pivot where the agent sets routes *for the human*.
|
|
|
84
84
|
call-config tools deliberately **do**: they change what serves live traffic right
|
|
85
85
|
now, on the human's behalf, and say so unmistakably.
|
|
86
86
|
|
|
87
|
+
### Point a scoped key at the control plane (once)
|
|
88
|
+
|
|
89
|
+
The four read tools work with no account. The call-config tools do **not**: a
|
|
90
|
+
read needs a valid `rig_sk_` key, and a **write** (`set_call_config` /
|
|
91
|
+
`rollback_call_config`) needs that key to carry the **`route-config`** scope. Give
|
|
92
|
+
the MCP server both the key and the host so the tools can reach `/v1`:
|
|
93
|
+
|
|
94
|
+
```jsonc
|
|
95
|
+
{
|
|
96
|
+
"mcpServers": {
|
|
97
|
+
"modelrig": {
|
|
98
|
+
"command": "npx",
|
|
99
|
+
"args": ["modelrig-oracle"],
|
|
100
|
+
"env": {
|
|
101
|
+
// A rig_sk_ key minted at app.modelrig.ai (/keys). To FLIP a route it
|
|
102
|
+
// must carry the `route-config` scope; a read-only key still reads.
|
|
103
|
+
"MODELRIG_API_KEY": "rig_sk_…",
|
|
104
|
+
// The control plane the oracle's tools call. Omit to use the hosted
|
|
105
|
+
// default (https://api.modelrig.ai). The oracle reads MODELRIG_INGEST_URL
|
|
106
|
+
// ONLY — MODELRIG_SERVER_URL is an app-side var and is NOT honored here.
|
|
107
|
+
"MODELRIG_INGEST_URL": "https://api.modelrig.ai"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
A key without `route-config` authenticates fine and reads, then a write returns a
|
|
115
|
+
teaching **403** naming the missing scope — mint or rotate a key with it, or set
|
|
116
|
+
the config in the console.
|
|
117
|
+
|
|
118
|
+
### The flip, end to end
|
|
119
|
+
|
|
120
|
+
1. **Read the current config.** `get_call_config(route)` → the live `version`,
|
|
121
|
+
`mode`, and model(s) serving the route this instant. `version: 0` means no
|
|
122
|
+
override (the route resolves to its deployed bundle default).
|
|
123
|
+
2. **Set the new model.** `set_call_config({ route, mode: "pin", provider, model })`
|
|
124
|
+
(shape below). The response names the new **version** and a rollback hint.
|
|
125
|
+
3. **It takes effect at serve time — no redeploy.** The SDK reads the route's
|
|
126
|
+
config **just-before-call**, merges the pin over the deployed bundle, and
|
|
127
|
+
serves it. It is **fail-open**: on any control-plane error the last-known-good
|
|
128
|
+
(else the deployed bundle) serves, and a route with **no override resolves
|
|
129
|
+
byte-identical** to today. The change lands on the route's *next* request once
|
|
130
|
+
the resolver's short cache refreshes (TTL ~30–60s). (Serving requires the app
|
|
131
|
+
to overlay call-config on the route — see
|
|
132
|
+
[Change your route's model live](quickstart.md#change-your-routes-model-live-no-redeploy).)
|
|
133
|
+
4. **Undo when you want.** `rollback_call_config({ route, toVersion })` re-appends a
|
|
134
|
+
prior version as a new one (history is never deleted).
|
|
135
|
+
|
|
87
136
|
| Tool | Endpoint | Scope |
|
|
88
137
|
|---|---|---|
|
|
89
138
|
| `get_call_config` | `GET /v1/routes/:route/call-config` | any org-scoped key — a read needs none special |
|
|
@@ -96,6 +145,30 @@ Version `0` means there is no override yet — the route resolves to its deploye
|
|
|
96
145
|
(mirrored) bundle default. History (audit + rollback targets) is at
|
|
97
146
|
`GET /v1/routes/:route/call-config/history`.
|
|
98
147
|
|
|
148
|
+
**It also answers "what will this route serve, and why?"** (RV-1). The tool reads
|
|
149
|
+
`GET /v1/routes/:route/call-config?include=effective` and returns:
|
|
150
|
+
|
|
151
|
+
- `effective` — `{ source, provider, model, version, since }`, where `source` is
|
|
152
|
+
`pin` (a call-config pin serves; `version` = the call-config version),
|
|
153
|
+
`experiment` (a live A/B — no single model), `deployed_default` (no override; the
|
|
154
|
+
app's YAML default = the registered route's first candidate; `version` = the YAML
|
|
155
|
+
route version), or `unknown` (no deployment has registered the route in your org).
|
|
156
|
+
`serving` phrases it in one line.
|
|
157
|
+
- `drift` — non-null only when a pin is set but recent calls on the route (last 24h,
|
|
158
|
+
from 5 minutes after the pin, ≤500 sampled) served a **different** model:
|
|
159
|
+
`{ servedProvider, servedModel, calls, lastSeen, pinnedCalls, windowStart }`, plus a
|
|
160
|
+
`drift_warning` sentence. It means the app's resolver is failing open — check its SDK
|
|
161
|
+
version, its `MODELRIG_API_KEY`, and that the call path resolves call-config at
|
|
162
|
+
serve time. Setting the pin again will not fix drift; the app has to honor it.
|
|
163
|
+
|
|
164
|
+
Routes appear here before their first call: a rig created with routes and a
|
|
165
|
+
control-plane key registers them on startup — metadata plus the declared bundle
|
|
166
|
+
(prompt template, schema, policy), `ingest` scope only. That registered bundle is
|
|
167
|
+
what `set_call_config` checks a pin against, so **pins work for api-mode apps once
|
|
168
|
+
their routes register**; before that, a pin is refused with a teaching 422 ("no
|
|
169
|
+
servable bundle in your organization") — start the app (with an SDK that has
|
|
170
|
+
RV-1) and retry.
|
|
171
|
+
|
|
99
172
|
**Pin a model:**
|
|
100
173
|
|
|
101
174
|
```jsonc
|
|
@@ -213,8 +213,9 @@ regression). Silent is the only forbidden outcome.
|
|
|
213
213
|
`dimensions[].key` in `rig.yaml` (tag-safe `[A-Za-z0-9_]{1,64}`) so the
|
|
214
214
|
console can attribute cost by it. A `required: true` dimension missing from a
|
|
215
215
|
run's tags **warns once per process** (and under-attributes that run) — it
|
|
216
|
-
is never rejected.
|
|
217
|
-
|
|
216
|
+
is never rejected. Don't put `run_id` in your tags: inside a run the SDK stamps
|
|
217
|
+
it (it is reserved — see the
|
|
218
|
+
[reserved tag keys](instrumentation.md#reserved-tag-keys-the-one-list)).
|
|
218
219
|
- **`result.output` is already parsed and schema-validated** — delete the old
|
|
219
220
|
call site's `JSON.parse` and fence-stripping rather than keeping both.
|
|
220
221
|
- **Routes resolve from `./modelrig/routes` relative to the process CWD.** In a
|
|
@@ -391,7 +392,7 @@ through `rig.runRaw` without a `run.start` around it records inferences but no
|
|
|
391
392
|
run — `/runs` stays empty and `/projects` shows "(no run)". Open the run context
|
|
392
393
|
around each pipeline execution (`rig.artifacts.run.start({ pipeline, episodeKey })`
|
|
393
394
|
… `run.end()`); inside it the SDK names the step and stamps the `run_id` tag —
|
|
394
|
-
and the `step` tag too (
|
|
395
|
+
and the `step` tag too (`run_id` is reserved: never set it yourself) — you tag `subject` /
|
|
395
396
|
`feature` yourself. Do not declare a
|
|
396
397
|
migration done until one real execution shows a run with steps on `/runs`.
|
|
397
398
|
|
|
@@ -434,7 +435,7 @@ Because this is behaviour-affecting, the agent **proposes, never applies**:
|
|
|
434
435
|
keeps the diff inside the customer's codebase legible — a product surface.
|
|
435
436
|
5. **A human merges.** The skill's autonomy ends at a green report and an open PR.
|
|
436
437
|
|
|
437
|
-
### Replaced-call disposition
|
|
438
|
+
### Replaced-call disposition: DELETE the original, never comment it out
|
|
438
439
|
|
|
439
440
|
Rollback is git-native and the skill makes it explicit:
|
|
440
441
|
|
package/docs/quickstart.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# ModelRig quickstart — see, prove, and save on every model call
|
|
2
2
|
|
|
3
|
+
**The question this page answers: how do I get from nothing to my first run on `/runs`, with its steps and artifacts, in about ten minutes?**
|
|
4
|
+
|
|
3
5
|
ModelRig is the operating layer for your AI workstream. Each LLM task becomes a
|
|
4
6
|
**versioned route file** (prompt template + JSON schema + candidate models +
|
|
5
7
|
policy) that you call with one line — `rig.run("task.name", {input, tags})` —
|
|
@@ -15,22 +17,33 @@ and three things happen at once:
|
|
|
15
17
|
- **Save** — a winning candidate is a change to your YAML you review; nothing
|
|
16
18
|
swaps a model on its own, and your routes are always YAML in your git.
|
|
17
19
|
|
|
18
|
-
The
|
|
19
|
-
|
|
20
|
+
The path is the same whoever does the work: **mint a key → install → confirm the
|
|
21
|
+
org → define a route → wrap one pipeline execution in a run → see it on `/runs`.**
|
|
22
|
+
Step 0 is yours (two minutes, once); after that, point your coding agent at this
|
|
23
|
+
page or follow the steps by hand. Already have LLM calls you only want to *watch*
|
|
24
|
+
first? [Choosing a lane](https://modelrig.dev/choosing-a-lane.html) shows the observe path, which skips
|
|
25
|
+
the route.
|
|
20
26
|
|
|
21
27
|
## Step 0 — create your org and key (two minutes, human-only)
|
|
22
28
|
|
|
23
29
|
Account setup stays human: your coding agent never creates accounts, signs in,
|
|
24
|
-
or holds credentials. Once, up front
|
|
30
|
+
or holds credentials. Once, up front, sign up and create your organization at
|
|
31
|
+
[app.modelrig.ai](https://app.modelrig.ai) (email and an org name is the whole
|
|
32
|
+
form). Then:
|
|
33
|
+
|
|
34
|
+
<!-- BLOCK:KEY -->
|
|
35
|
+
**Mint a key in the org you want the data in.** Sign in at https://app.modelrig.ai, check the organization name in the header badge, and create a key on the API keys page. The `rig_sk_` secret is shown once. One key = one org: every row the key exports lands in the organization it was minted in, whichever organization you happen to be viewing in the console. Set it on every service, worker and cron that creates a rig; your provider keys stay where they are.
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
```bash
|
|
38
|
+
# Wherever your app reads configuration: .env.local, your platform's env vars, a secret manager. Never in code.
|
|
39
|
+
MODELRIG_API_KEY=rig_sk_…
|
|
40
|
+
```
|
|
41
|
+
<!-- /BLOCK:KEY -->
|
|
31
42
|
|
|
32
43
|
That key is the only ModelRig credential your app ever holds — never a database
|
|
33
|
-
URL, never a service-role key. Provider keys never leave your process.
|
|
44
|
+
URL, never a service-role key. Provider keys never leave your process. Which org
|
|
45
|
+
a key belongs to, and how the console chooses the org it shows you, is
|
|
46
|
+
[Orgs and keys](https://modelrig.dev/orgs-and-keys.html).
|
|
34
47
|
|
|
35
48
|
**No account needed for the open lane:** with only your provider keys set,
|
|
36
49
|
routes, probes and telemetry run entirely on your machine — the hosted console
|
|
@@ -51,33 +64,18 @@ Same flat 2% margin either way; your negotiated provider discounts stay yours.
|
|
|
51
64
|
|
|
52
65
|
## Point your coding agent at it
|
|
53
66
|
|
|
54
|
-
The fastest migration is the one your agent performs.
|
|
55
|
-
|
|
67
|
+
The fastest migration is the one your agent performs. Paste the migration prompt
|
|
68
|
+
from [modelrig.ai/get-started](https://modelrig.ai/get-started) (the console's
|
|
69
|
+
`/setup` page carries the same prompt) into Claude Code, Codex, or Cursor from
|
|
70
|
+
inside your project. It is the maintained version: it starts the agent at the
|
|
71
|
+
bottom of the [autonomy ladder](migration-playbook.md), has it confirm the org
|
|
72
|
+
your key exports to, wrap each pipeline execution in a run, and stop for your
|
|
73
|
+
approval at every checkpoint.
|
|
56
74
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
to create an org and issue a rig_sk_ key at https://app.modelrig.ai. Never
|
|
62
|
-
create accounts, sign in, or handle credentials yourself. Without the key,
|
|
63
|
-
proceed in local-only mode — that is fully supported.
|
|
64
|
-
1. Read https://modelrig.dev/quickstart.html and
|
|
65
|
-
https://modelrig.dev/route-bundles.html.
|
|
66
|
-
2. Find every place this codebase calls an LLM API directly.
|
|
67
|
-
3. For each call site, define a route bundle YAML (schema, candidate models,
|
|
68
|
-
policy, prompt template) and replace the direct call with
|
|
69
|
-
rig.run("<route.name>"). Keep prompt and schema semantics unchanged.
|
|
70
|
-
4. Before naming any model capability, check the probed registry — declared
|
|
71
|
-
flags and probed behavior differ; trust the probed layer.
|
|
72
|
-
5. Run the project's existing tests and report every file you changed.
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Your agent reads the docs, finds your LLM call sites, and turns them into
|
|
76
|
-
routes. It **won't** create accounts, sign in, or touch your API keys (those
|
|
77
|
-
stay in the environment you set in Step 0), and it swaps call sites to
|
|
78
|
-
`rig.run()` without changing prompt or schema semantics — same model, human-
|
|
79
|
-
reviewed. The full autonomy ladder and same-model guarantees are in the
|
|
80
|
-
[migration playbook](migration-playbook.md).
|
|
75
|
+
Your agent reads the docs, finds your LLM call sites, and wires them in. It
|
|
76
|
+
**won't** create accounts, sign in, or touch your API keys (those stay in the
|
|
77
|
+
environment you set in Step 0), and when it replaces a call site with `rig.run()`
|
|
78
|
+
it keeps prompt and schema semantics unchanged — same model, human-reviewed.
|
|
81
79
|
|
|
82
80
|
## Or set it up by hand
|
|
83
81
|
|
|
@@ -87,14 +85,15 @@ reviewed. The full autonomy ladder and same-model guarantees are in the
|
|
|
87
85
|
pnpm add modelrig # or npm i modelrig — Node >= 20
|
|
88
86
|
```
|
|
89
87
|
|
|
90
|
-
It installs a native module (`better-sqlite3`)
|
|
91
|
-
x64/arm64;
|
|
88
|
+
It installs a native module (`better-sqlite3`) from a prebuilt binary on
|
|
89
|
+
macOS and Linux (x64/arm64); any other platform compiles it at install time and
|
|
90
|
+
needs a C++ toolchain.
|
|
92
91
|
|
|
93
|
-
**Deploying:** `modelrig`
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
**Deploying:** `modelrig` needs a **Node** runtime (not Edge/Workers), and if
|
|
93
|
+
your deploy bundles server code you must mark it external — Next.js
|
|
94
|
+
`serverExternalPackages: ['modelrig']`, esbuild `--external:better-sqlite3`,
|
|
95
|
+
webpack `externals`. Set `MODELRIG_API_KEY` on every service, worker, and cron
|
|
96
|
+
that runs a rig; hosted-platform specifics are in [Deploying](https://modelrig.dev/deploying.html).
|
|
98
97
|
|
|
99
98
|
```ts
|
|
100
99
|
import { createRig, loadConfigFromEnv } from "modelrig";
|
|
@@ -117,12 +116,21 @@ MODELRIG_TELEMETRY_DB=./.modelrig/telemetry.db # default
|
|
|
117
116
|
MODELRIG_ENVELOPE_BUDGET_USD=25 # default envelope budget
|
|
118
117
|
```
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
in the console at [app.modelrig.ai](https://app.modelrig.ai) and is the only
|
|
122
|
-
ModelRig credential your app ever holds — never a database URL, never a
|
|
123
|
-
service-role key.
|
|
119
|
+
### 2. Confirm the org
|
|
124
120
|
|
|
125
|
-
|
|
121
|
+
<!-- BLOCK:CONFIRM_ORG -->
|
|
122
|
+
**Confirm the org before you trust an empty console.** Run `modelrig doctor` from the same environment your app runs in. It asks GET /v1/whoami which organization the key belongs to, and the name it prints must match the org badge in the console header. If it names a different organization, your data is landing there: switch the console to that organization, or mint a key in the one you meant (https://modelrig.dev/orgs-and-keys.html).
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
npx modelrig doctor
|
|
126
|
+
# [modelrig] key rig_sk_…AbCd → org «Your Org» ✓ (ingest https://api.modelrig.ai, …)
|
|
127
|
+
|
|
128
|
+
# No CLI in that environment? Ask the API directly:
|
|
129
|
+
curl -H "Authorization: Bearer $MODELRIG_API_KEY" https://api.modelrig.ai/v1/whoami
|
|
130
|
+
```
|
|
131
|
+
<!-- /BLOCK:CONFIRM_ORG -->
|
|
132
|
+
|
|
133
|
+
### 3. Define a route bundle
|
|
126
134
|
|
|
127
135
|
One YAML file per route under `modelrig/routes/`:
|
|
128
136
|
|
|
@@ -175,15 +183,15 @@ types allowed, and `format` is annotation-only — it is not asserted (an
|
|
|
175
183
|
`email`/`date-time` format is documentation, not a constraint). Author 2020-12
|
|
176
184
|
unless you have a draft-07 schema already; both work.
|
|
177
185
|
|
|
178
|
-
###
|
|
186
|
+
### 4. Call it
|
|
179
187
|
|
|
180
188
|
```ts
|
|
181
189
|
const rig = createRig(loadConfigFromEnv());
|
|
182
190
|
|
|
183
191
|
const result = await rig.run("example.support_summarize", {
|
|
184
192
|
input: { ticket: rawTicket, product: "Acme Cloud", priorContext: history },
|
|
185
|
-
tags: {
|
|
186
|
-
budget: { envelope: "
|
|
193
|
+
tags: { subject: "acme", feature: "summarize" },
|
|
194
|
+
budget: { envelope: "ticket-123" }, // hard-stop cost envelope for the run
|
|
187
195
|
});
|
|
188
196
|
|
|
189
197
|
result.output; // JSON, already validated against your schema
|
|
@@ -195,51 +203,70 @@ result.meta.attemptsByClass; // retries consumed, per failure class
|
|
|
195
203
|
rig.close();
|
|
196
204
|
```
|
|
197
205
|
|
|
198
|
-
###
|
|
206
|
+
### 5. Wrap it in a run — the standard path
|
|
199
207
|
|
|
200
208
|
**Every pipeline execution is a run.** A run is the standard way ModelRig records
|
|
201
|
-
what your workstream did — not an appendix.
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
209
|
+
what your workstream did — not an appendix. The console's **Runs** tab then shows
|
|
210
|
+
the run → step → artifact chain you can click through, and `/projects` groups it
|
|
211
|
+
by tag.
|
|
212
|
+
|
|
213
|
+
<!-- BLOCK:RUN_WRAP -->
|
|
214
|
+
**Wrap one pipeline execution in a run.** Every pipeline execution is a run. Wrap each execution in `run.scope` (or `run.start` / `run.end`), name one step per model call with `stepKey`, `artifact.save` the work products, and pass `environment` so the Env column on /runs is filled. Inside the run the SDK stamps `run_id` and `step` on every call. `run_id` is reserved: don't set it yourself.
|
|
205
215
|
|
|
206
216
|
```ts
|
|
217
|
+
import { createRig, loadConfigFromEnv } from "modelrig";
|
|
218
|
+
|
|
207
219
|
const rig = createRig(loadConfigFromEnv());
|
|
208
220
|
|
|
209
|
-
//
|
|
210
|
-
//
|
|
221
|
+
// Every pipeline execution is a run. Inside the scope the SDK records each
|
|
222
|
+
// rig.run / rig.runRaw call as a step and stamps run_id and step on every row.
|
|
223
|
+
// run_id is reserved: don't set it yourself (put your own attempt id in a tag of
|
|
224
|
+
// your own, such as pipeline_attempt_id).
|
|
211
225
|
await rig.artifacts.run.scope(
|
|
212
|
-
{ pipeline: "support", episodeKey: ticketId },
|
|
226
|
+
{ pipeline: "support", episodeKey: ticketId, environment: process.env.NODE_ENV ?? "development" },
|
|
213
227
|
async () => {
|
|
214
228
|
const result = await rig.run("example.support_summarize", {
|
|
215
229
|
input: { ticket, product, priorContext },
|
|
216
|
-
tags: { subject: customer, feature: "summarize" },
|
|
217
|
-
stepKey: "summarize",
|
|
230
|
+
tags: { subject: customer, feature: "summarize" },
|
|
231
|
+
stepKey: "summarize", // names this step on /runs
|
|
218
232
|
});
|
|
219
|
-
|
|
220
|
-
rig.artifacts.artifact.save(result.output, { name: "summary", type: "step_output" });
|
|
233
|
+
rig.artifacts.artifact.save(result.output, { name: "summary", type: "step_output", stepKey: "summarize" });
|
|
221
234
|
},
|
|
222
235
|
);
|
|
223
|
-
|
|
236
|
+
|
|
237
|
+
await rig.close(); // flushes the exporter — call once at shutdown
|
|
224
238
|
```
|
|
239
|
+
<!-- /BLOCK:RUN_WRAP -->
|
|
225
240
|
|
|
226
|
-
- **Tags:** carry `subject` (what the run is *about*) and `feature`. You no longer
|
|
227
|
-
hand-write `run_id` — **inside a run context the SDK stamps `tags.run_id`** (the
|
|
228
|
-
run's `episodeKey`, else its id) on every attempt row of both lanes; a value you
|
|
229
|
-
pass always wins, and outside a run context nothing is stamped. It also stamps
|
|
230
|
-
`tags.step` (the current step key) the same way; a value you pass always wins,
|
|
231
|
-
so name the step yourself with `stepKey` (or `tags.step`) when you want a
|
|
232
|
-
specific label.
|
|
233
241
|
- **Raw lane:** a `rig.runRaw` call inside a run context records a ground-truth
|
|
234
242
|
step too (since 0.5.0), so grounded/cached pipelines fill the same graph.
|
|
235
|
-
- **
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
The full artifact API — lineage (`link`),
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
+
- **Reserved tags:** `run_id` and `step` are stamped by the SDK; the full list of
|
|
244
|
+
reserved keys is in the
|
|
245
|
+
[instrumentation guide](instrumentation.md#reserved-tag-keys-the-one-list).
|
|
246
|
+
|
|
247
|
+
The full artifact API — lineage (`link`), grades, the reusable per-step seam, and
|
|
248
|
+
`run.scope` vs `run.start` — is the [instrumentation guide](instrumentation.md).
|
|
249
|
+
|
|
250
|
+
### 6. See it on /runs
|
|
251
|
+
|
|
252
|
+
Open `/runs` in the console, with the org badge showing the org `doctor` named:
|
|
253
|
+
the run, its steps in order, and the artifacts you saved. `modelrig status`
|
|
254
|
+
prints `runs recorded: N (last: …)` as the local mirror, and `modelrig validate`
|
|
255
|
+
warns if a rig records calls but never starts a run. If the page is empty:
|
|
256
|
+
|
|
257
|
+
<!-- BLOCK:EMPTY_CONSOLE -->
|
|
258
|
+
**The console is empty: five checks, in order.** If /runs (or /inferences) is empty for the org in the header badge, work these checks in order. The full tree is https://modelrig.dev/troubleshooting.html.
|
|
259
|
+
|
|
260
|
+
```text
|
|
261
|
+
1. npx modelrig doctor, from the environment your app runs in.
|
|
262
|
+
no export sink configured → this process does not see MODELRIG_API_KEY: set it, redeploy, open a new shell.
|
|
263
|
+
AUTH FAILED (401 / 403) → the key is mistyped, revoked or not accepted: mint a key, set it, redeploy, open a new shell.
|
|
264
|
+
2. The org doctor prints is not the org in the badge → wrong org: switch the console, or mint a key in the org you meant.
|
|
265
|
+
3. /inferences has rows but /runs is empty → the calls are not inside run.scope / run.start.
|
|
266
|
+
4. A run is missing a step or a cost → that call is not on a ModelRig lane (see not-captured).
|
|
267
|
+
5. A doc describes something your install lacks → compare `npm ls modelrig` with the version stamp in modelrig.dev/llms.txt.
|
|
268
|
+
```
|
|
269
|
+
<!-- /BLOCK:EMPTY_CONSOLE -->
|
|
243
270
|
|
|
244
271
|
## Change your route's model live (no redeploy)
|
|
245
272
|
|
|
@@ -253,6 +280,52 @@ merges it over your bundle. Two modes:
|
|
|
253
280
|
- **`experiment`** — a weighted live A/B across arms, with the chosen arm recorded on
|
|
254
281
|
every row so the console can score it.
|
|
255
282
|
|
|
283
|
+
**See what a route serves — before its first call.** Your YAML stays the deploy-time
|
|
284
|
+
default and the fail-open safety net; ModelRig is where you *see* and *change* it. A rig
|
|
285
|
+
created with a `routesDir` **and** a control-plane key registers each route the moment
|
|
286
|
+
`createRig()` runs — its metadata (route, version, candidates) **and its declared bundle**
|
|
287
|
+
(the prompt *template* with its `{{placeholders}}`, schema, policy, plus a content hash):
|
|
288
|
+
fire-and-forget, fail-open, through the same `/v1/ingest` call telemetry uses (the
|
|
289
|
+
`ingest` scope is enough). The bundle is stored as **route configuration**, not captured
|
|
290
|
+
content — it holds the authored template, never per-call values — so it is stored even when
|
|
291
|
+
your org's capture posture is `off` (telemetry rows are still dropped then). Registering
|
|
292
|
+
the bundle is what lets the control plane **validate and accept a pin** for the route: a
|
|
293
|
+
pin is checked against the route's `require` before it is written, so a route with no
|
|
294
|
+
registered bundle refuses pins with a teaching 422. If you promote a prompt version in
|
|
295
|
+
ModelRig (Prompt System of Record), the promoted template wins over the one in your YAML
|
|
296
|
+
on every later registration; everything else (candidates, schema, policy) follows your
|
|
297
|
+
deploy. So every route shows up in the console and over MCP right away, and one read
|
|
298
|
+
answers *"what will this route serve, and why?"*:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
curl -H "authorization: Bearer $MODELRIG_API_KEY" \
|
|
302
|
+
"${MODELRIG_INGEST_URL:-https://api.modelrig.ai}/v1/routes/example.support_summarize/call-config?include=effective"
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
```jsonc
|
|
306
|
+
{
|
|
307
|
+
"version": 0, "mode": null, "config": null, // no override yet
|
|
308
|
+
"effective": {
|
|
309
|
+
"source": "deployed_default", // pin | experiment | deployed_default | unknown
|
|
310
|
+
"provider": "openai", "model": "gpt-5.4-mini", // your YAML's first candidate
|
|
311
|
+
"version": 1, // the YAML route version
|
|
312
|
+
"since": "2026-10-10T12:00:00Z" // when the deployment last declared it
|
|
313
|
+
},
|
|
314
|
+
"drift": null
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
`source: "pin"` means a call-config pin is serving (its `version` is the call-config
|
|
319
|
+
version); `unknown` means no deployment has registered the route in your org yet. When a
|
|
320
|
+
pin is set but recent calls on the route served a **different** model, `drift` says so —
|
|
321
|
+
`{ servedProvider, servedModel, calls, lastSeen, pinnedCalls, windowStart }` (last 24h,
|
|
322
|
+
starting 5 minutes after the pin, ≤500 calls sampled). Drift means your app is not
|
|
323
|
+
honoring the pin: its resolver is failing open (an older SDK, a wrong `MODELRIG_API_KEY`,
|
|
324
|
+
or a call path that never resolves call-config — see below). The console's call-config
|
|
325
|
+
card shows the same thing as **Serving: \<model\> — \<pin vN | YAML default\>** plus a
|
|
326
|
+
drift warning; `get_call_config` over MCP returns it too. Without `?include=effective`
|
|
327
|
+
the response is unchanged (that is what the SDK's serve-time poll reads).
|
|
328
|
+
|
|
256
329
|
**Read call-config just-before-call.** Build a resolver once (it caches with a short TTL
|
|
257
330
|
and revalidates by ETag — no per-call network cost when fresh), then overlay the current
|
|
258
331
|
config onto a bundle and serve it through `rig.runBundle()`:
|
|
@@ -381,14 +454,26 @@ from the SDK or over HTTP for a non-SDK surface (see the
|
|
|
381
454
|
`run-outcome@v1` grade, with an explicit, bounded model judge available when
|
|
382
455
|
you want one (see the [grade protocol](grade-protocol.md#native-run-grades)).
|
|
383
456
|
|
|
457
|
+
## Serve without holding the provider key (optional)
|
|
458
|
+
|
|
459
|
+
Everything above runs on **your** provider key — `destination: direct`, the
|
|
460
|
+
default, and nothing here changes it. If you would rather ModelRig serve a
|
|
461
|
+
route's model on its own credentials and bill it from a prepaid balance, declare
|
|
462
|
+
`destination: modelrig-served` on the route, set `managedServing: true` in the
|
|
463
|
+
rig config, mint a key with the `serve` scope, and turn managed serving on in
|
|
464
|
+
Account settings. The walk-through, including what each refusal teaches, is
|
|
465
|
+
[Managed serving](managed-serving.md).
|
|
466
|
+
|
|
384
467
|
## Runtime requirements
|
|
385
468
|
|
|
386
469
|
ModelRig assumes a **long-lived Node process with a writable disk**, and a few
|
|
387
470
|
things follow from that. Check them before you deploy:
|
|
388
471
|
|
|
389
|
-
- **Node ≥ 20
|
|
390
|
-
|
|
391
|
-
|
|
472
|
+
- **Node ≥ 20.** The local telemetry buffer is `better-sqlite3` (a C/C++
|
|
473
|
+
addon): it installs from a prebuilt binary on macOS and Linux (x64/arm64), and
|
|
474
|
+
compiles at install time anywhere else — on such a platform, or a slim
|
|
475
|
+
container without the prebuilt, add the build essentials (`python3`, `make`, a
|
|
476
|
+
C++ compiler).
|
|
392
477
|
- **A writable disk.** Telemetry and captures go to a local SQLite file
|
|
393
478
|
(`MODELRIG_TELEMETRY_DB`, default `./.modelrig/telemetry.db`); the background
|
|
394
479
|
exporter batches from it. A read-only filesystem breaks this.
|
|
@@ -417,8 +502,9 @@ loader's own words, is in [route-bundles.md](./route-bundles.md#when-it-doesnt-w
|
|
|
417
502
|
- **The bundle won't load, naming an undeclared variable.** A `{{name}}` in the
|
|
418
503
|
template isn't in `prompt.variables`. Add it (or fix the typo).
|
|
419
504
|
- **The first call succeeds locally but nothing appears in the console.**
|
|
420
|
-
`MODELRIG_API_KEY` isn't set in that environment
|
|
421
|
-
|
|
505
|
+
Usually `MODELRIG_API_KEY` isn't set in that environment, or it belongs to a
|
|
506
|
+
different org than the one the console is showing. Run `npx modelrig doctor`
|
|
507
|
+
there and work through [Troubleshooting an empty console](https://modelrig.dev/troubleshooting.html).
|
|
422
508
|
- **The call runs but the output isn't what the old code produced.** Usually a
|
|
423
509
|
wrong `json: native` — a claim about the model, valid only for one whose
|
|
424
510
|
registry entry shows probed `structured_native`. Check the probed registry,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "modelrig",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "ModelRig — capability-aware AI gateway: routes-as-code, provider adapters, typed failures, budget envelopes, and local-first telemetry.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"docs/how-it-fits.md",
|
|
53
53
|
"docs/migration-playbook.md",
|
|
54
54
|
"docs/mcp-oracle.md",
|
|
55
|
+
"docs/managed-serving.md",
|
|
55
56
|
"docs/agent-skill/SKILL.md",
|
|
56
57
|
"docs/llms.txt",
|
|
57
58
|
"templates/ticket-triage.json",
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
"@google/genai": "^2.4.0",
|
|
76
77
|
"ajv": "^8.17.0",
|
|
77
78
|
"better-sqlite3": "^11.10.0",
|
|
78
|
-
"openai": "^
|
|
79
|
+
"openai": "^7.13.0",
|
|
79
80
|
"yaml": "^2.6.0"
|
|
80
81
|
},
|
|
81
82
|
"devDependencies": {
|
package/registry/registry.json
CHANGED
|
@@ -7296,6 +7296,88 @@
|
|
|
7296
7296
|
"NOT flex-eligible (mini/nano, Pro, and older families) — flex requests are silently served at default tier"
|
|
7297
7297
|
],
|
|
7298
7298
|
"facts": null
|
|
7299
|
+
},
|
|
7300
|
+
{
|
|
7301
|
+
"model_key": "zai/glm-5p2",
|
|
7302
|
+
"declared": {
|
|
7303
|
+
"as_of": "2026-09-08T00:00:00.000Z",
|
|
7304
|
+
"source": "z.ai-price-list(2026-09-08)+adapter-static",
|
|
7305
|
+
"pricing": {
|
|
7306
|
+
"input_usd_per_mtok": 1.4,
|
|
7307
|
+
"output_usd_per_mtok": 4.4,
|
|
7308
|
+
"cached_input_usd_per_mtok": null
|
|
7309
|
+
},
|
|
7310
|
+
"pricing_v2": {
|
|
7311
|
+
"base": {
|
|
7312
|
+
"input": 0.0000014,
|
|
7313
|
+
"output": 0.0000044,
|
|
7314
|
+
"cache_read": null
|
|
7315
|
+
},
|
|
7316
|
+
"tiers": null,
|
|
7317
|
+
"context_bands": null,
|
|
7318
|
+
"batch_discount": null,
|
|
7319
|
+
"modality": null,
|
|
7320
|
+
"source": "z.ai-website",
|
|
7321
|
+
"as_of": "2026-09-08T00:00:00.000Z",
|
|
7322
|
+
"basis": "base · standard tier · text"
|
|
7323
|
+
},
|
|
7324
|
+
"flags": {
|
|
7325
|
+
"supports_response_schema": true,
|
|
7326
|
+
"supports_web_search": true,
|
|
7327
|
+
"supports_prompt_caching": null,
|
|
7328
|
+
"adapter_structured_native": null,
|
|
7329
|
+
"adapter_grounded_native": false,
|
|
7330
|
+
"supports_image_input": false
|
|
7331
|
+
}
|
|
7332
|
+
},
|
|
7333
|
+
"probed": null,
|
|
7334
|
+
"observed": null,
|
|
7335
|
+
"discrepancies": [],
|
|
7336
|
+
"callNotes": [
|
|
7337
|
+
"B4a: reachable via the OpenAI-compat adapter on the Z.ai international endpoint (https://api.z.ai/api/paas/v4) keyed by ZAI_API_KEY; model id passes through verbatim (no wire prefix). Native GLM web_search (supports_web_search declared) is NOT wired on the ModelRig adapter until B4b — adapter_grounded_native is pinned false (so the derived grounded_native capability matches the fail-closed raw-lane grounding knob; B4b flips it true and wires the tool)."
|
|
7338
|
+
],
|
|
7339
|
+
"facts": null
|
|
7340
|
+
},
|
|
7341
|
+
{
|
|
7342
|
+
"model_key": "zai/glm-5p2-flash",
|
|
7343
|
+
"declared": {
|
|
7344
|
+
"as_of": "2026-09-08T00:00:00.000Z",
|
|
7345
|
+
"source": "z.ai-price-list(2026-09-08)+adapter-static",
|
|
7346
|
+
"pricing": {
|
|
7347
|
+
"input_usd_per_mtok": 0.08,
|
|
7348
|
+
"output_usd_per_mtok": 0.25,
|
|
7349
|
+
"cached_input_usd_per_mtok": null
|
|
7350
|
+
},
|
|
7351
|
+
"pricing_v2": {
|
|
7352
|
+
"base": {
|
|
7353
|
+
"input": 0.00000008,
|
|
7354
|
+
"output": 0.00000025,
|
|
7355
|
+
"cache_read": null
|
|
7356
|
+
},
|
|
7357
|
+
"tiers": null,
|
|
7358
|
+
"context_bands": null,
|
|
7359
|
+
"batch_discount": null,
|
|
7360
|
+
"modality": null,
|
|
7361
|
+
"source": "z.ai-website",
|
|
7362
|
+
"as_of": "2026-09-08T00:00:00.000Z",
|
|
7363
|
+
"basis": "base · standard tier · text"
|
|
7364
|
+
},
|
|
7365
|
+
"flags": {
|
|
7366
|
+
"supports_response_schema": true,
|
|
7367
|
+
"supports_web_search": true,
|
|
7368
|
+
"supports_prompt_caching": null,
|
|
7369
|
+
"adapter_structured_native": null,
|
|
7370
|
+
"adapter_grounded_native": false,
|
|
7371
|
+
"supports_image_input": false
|
|
7372
|
+
}
|
|
7373
|
+
},
|
|
7374
|
+
"probed": null,
|
|
7375
|
+
"observed": null,
|
|
7376
|
+
"discrepancies": [],
|
|
7377
|
+
"callNotes": [
|
|
7378
|
+
"B4a: budget GLM sibling reached via the OpenAI-compat adapter on the Z.ai international endpoint keyed by ZAI_API_KEY; model id passes through verbatim. Native web_search is B4b (adapter_grounded_native pinned false so the derived grounded_native capability matches the fail-closed raw-lane grounding knob)."
|
|
7379
|
+
],
|
|
7380
|
+
"facts": null
|
|
7299
7381
|
}
|
|
7300
7382
|
]
|
|
7301
7383
|
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* rig.feedback() — Phase 4 WS2 (spec: judgment starts accumulating).
|
|
3
|
-
* The SDK surface normalizes a target (inference id or {episode}) + opts
|
|
4
|
-
* into a FeedbackRow; the write is a synchronous local SQLite insert
|
|
5
|
-
* (fire-and-forget from the caller's view — no network, never throws for
|
|
6
|
-
* sink reasons). The Supabase mirror rides the exporter, dual-store style.
|
|
7
|
-
*/
|
|
8
|
-
import type { FeedbackRow } from "../types/telemetry";
|
|
9
|
-
export type FeedbackTarget = string | {
|
|
10
|
-
readonly episode: string;
|
|
11
|
-
};
|
|
12
|
-
export interface FeedbackOpts {
|
|
13
|
-
readonly verdict: "up" | "down";
|
|
14
|
-
/** Optional graded signal in [0, 1]; verdict remains the primary axis. */
|
|
15
|
-
readonly score?: number;
|
|
16
|
-
readonly note?: string;
|
|
17
|
-
/** Who judged: "sdk" (default), a review-agent name, "human", … */
|
|
18
|
-
readonly source?: string;
|
|
19
|
-
/**
|
|
20
|
-
* The org this verdict belongs to (Phase 6 WS2). Omit from application code
|
|
21
|
-
* — a rig has one org and the exporter knows it.
|
|
22
|
-
*
|
|
23
|
-
* Supplied by modelrig-server, and only ever with an org it has ALREADY
|
|
24
|
-
* authorized the caller into: a value that arrived in a request body and was
|
|
25
|
-
* passed through here would be a tenant chosen by the client (T3). Setting
|
|
26
|
-
* it is what lets one hosted server hold verdicts for many orgs without
|
|
27
|
-
* misfiling any of them (QA-P6-010).
|
|
28
|
-
*/
|
|
29
|
-
readonly orgId?: string;
|
|
30
|
-
/** Authenticated user who recorded it. Same provenance rule as `orgId`:
|
|
31
|
-
* resolved from a session, never read off a request body. */
|
|
32
|
-
readonly createdBy?: string | null;
|
|
33
|
-
}
|
|
34
|
-
export declare function buildFeedbackRow(target: FeedbackTarget, opts: FeedbackOpts): FeedbackRow;
|
|
35
|
-
//# sourceMappingURL=feedback.d.ts.map
|