From 5947827c80516893e2805b8d2f93ef954eda4e4d Mon Sep 17 00:00:00 2001 From: t Date: Tue, 25 Aug 2026 15:39:18 +0200 Subject: [PATCH] =?UTF-8?q?chore(deps):=20ai-ration=20v0.2.1=20=E2=80=94?= =?UTF-8?q?=20the=20chain's=20Groq=20link=20was=20entirely=20dead?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Companion to #350. That PR fixed FleetCrown's own direct Groq calls; this one fixes the shared chain underneath Loki. `ai-ration` is the package that exists BECAUSE a single pinned free model is a scheduled outage. It had the same disease: checked against the live catalogues, four of its nine default ids were gone. groq llama-3.3-70b-versatile GONE groq llama-3.1-8b-instant GONE <- whole vendor dead openrouter openai/gpt-oss-20b:free GONE <- was FIRST in the list openrouter nvidia/nemotron-3-nano-30b-... GONE So Loki's chain burned two Groq 404s and then a third on its preferred OpenRouter fallback before reaching a model that could answer. Not an outage — OpenRouter's remaining links carried it — but the fastest vendor and the whole 100k/day Groq budget were unreachable. Checked the direction that costs money: every OpenRouter link carries `:free`, so nothing had silently moved to paid. Upstream (maonakamoto/ai-ration#4, tag v0.2.1) replaces the dead pins with `openai/gpt-oss-120b` / `openai/gpt-oss-20b` — probed with a real tool call, not guessed — and adds `checkCatalog()`: a zero-token existence check, three-state (present / retired / could-not-read), cheap enough to run on a schedule. The existing `probe:models` costs real tokens and so could never be scheduled, which is why five rots in a row went unnoticed. ── one test changed, and it was pinning a dead model ──────────────────────── `scripts/test/agent-name-lookup.ts` asserted the chain still contains `llama-3.1-8b-instant` — "a model verified to drive the loop". That model is one of the four the vendor retired. The guard was correct in intent and anchored to a single rotting id, so it failed because its one EXAMPLE died, not because the property broke. A rot-detector anchored to one pinned id reproduces the exact failure it is watching for. It now asserts the property against a set of models actually probed for tool-calling, with the probe date and an instruction not to add a model you have not run. Mutation-proven: emptying the verified set turns it red (exit 1). Verified end-to-end rather than assumed: the installed copy reports 0.2.1, resolves to 07c492c, and its dist/chain.js carries the live ids. The lockfile diff is exactly one dependency — no incidental churn. Co-Authored-By: Claude Opus 5 --- package-lock.json | 7 +++---- package.json | 2 +- scripts/test/agent-name-lookup.ts | 12 +++++++++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index ef54bd8e..78882785 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@xterm/addon-fit": "^0.11.0", "@xterm/addon-web-links": "^0.12.0", "@xterm/xterm": "^6.0.0", - "ai-ration": "github:maonakamoto/ai-ration#v0.2.0", + "ai-ration": "github:maonakamoto/ai-ration#v0.2.1", "bip-kit": "^0.1.0", "bs58check": "^4.0.0", "class-variance-authority": "^0.7.1", @@ -6006,9 +6006,8 @@ } }, "node_modules/ai-ration": { - "version": "0.2.0", - "resolved": "git+ssh://git@github.com/maonakamoto/ai-ration.git#14a41b0c3418d53a8163d4837b7df964cc26f6d3", - "integrity": "sha512-rLgkxX952XU6EjTWj8RCd04uTy3zuDYUx0H/fT8r11HuisDJfPVXWfAqh5zjdnf8MqQIqd3UqggAiRbktuRW3g==", + "version": "0.2.1", + "resolved": "git+ssh://git@github.com/maonakamoto/ai-ration.git#07c492ce27785d66d9623acf7b30874fb908da13", "license": "MIT", "engines": { "node": ">=18" diff --git a/package.json b/package.json index dbc6c3a6..72945913 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "@xterm/addon-fit": "^0.11.0", "@xterm/addon-web-links": "^0.12.0", "@xterm/xterm": "^6.0.0", - "ai-ration": "github:maonakamoto/ai-ration#v0.2.0", + "ai-ration": "github:maonakamoto/ai-ration#v0.2.1", "bip-kit": "^0.1.0", "bs58check": "^4.0.0", "class-variance-authority": "^0.7.1", diff --git a/scripts/test/agent-name-lookup.ts b/scripts/test/agent-name-lookup.ts index b93a46ef..f8a881ce 100644 --- a/scripts/test/agent-name-lookup.ts +++ b/scripts/test/agent-name-lookup.ts @@ -107,9 +107,19 @@ function candidates(message: string): string[] { // moment the chain moved into `ai-ration` — the property held perfectly and // the test failed anyway, because it was reading a source file rather than // the thing the source file produces. + // …and asserted as a SET rather than one id. The previous anchor was + // `llama-3.1-8b-instant` alone, which the vendor retired on 2026-08-18 — + // so the guard failed not because the property broke but because its single + // example rotted. Anchoring a rot-detector to one pinned id reproduces the + // exact failure it is watching for. Any probed model satisfies it. + // + // Membership here means: called with a real tool definition and observed to + // emit a parseable tool call. gpt-oss-120b / gpt-oss-20b probed 2026-08-25 + // (native tool_call, correct arguments). Do not add a model you have not run. + const LOOP_VERIFIED = ["openai/gpt-oss-120b", "openai/gpt-oss-20b"]; const models = CHAT_CHAIN.flatMap((p) => p.models); assert.ok( - models.includes("llama-3.1-8b-instant"), + models.some((m) => LOOP_VERIFIED.includes(m)), `the chain must keep a model verified to drive the loop, got: ${models.join(", ")}`, ); }