Skip to content

agentcompass 0.1.4: canonicalModel resolves a multi-prefix model id by its last segment - #751

Merged
yetone merged 3 commits into
magpie-community:mainfrom
akiiwa-games:agentcompass-canonical-model
Nov 6, 2026
Merged

yetone merged 3 commits into
magpie-community:mainfrom
akiiwa-games:agentcompass-canonical-model

Conversation

@akiiwa-games

@akiiwa-games akiiwa-games commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

What

canonicalModel strips one provider prefix. openrouter/openai/gpt-5-mini looks up openai/gpt-5-mini, misses the gpt-5-mini alias and comes back unresolved.

Change

The alias lookup also tries the last path segment, first as written and then lowercased. This matches AgentCompass's resolve_canonical_model (model_resolution.py), which tries the raw name and then raw.rsplit('/', 1)[-1]. An id no alias knows keeps its current canonical form, openrouter/qwen/foo → qwen/foo, so the keys quota.js and continuity.js match on don't move.

One difference remains: upstream returns the raw id for an unknown model, while the plugin keeps returning it with the first prefix stripped, as it already does on main.

Tests

9.7 adds five assertions:

  • openrouter/openai/gpt-5-mini → gpt-6-luna, also in mixed case;
  • openrouter/minimax/MiniMax-M3 → minimax-m3 (the alias key has capitals, so this needs the exact-case last-segment lookup);
  • openrouter/qwen/foo → qwen/foo;
  • qwen/foo → foo.

Broken by hand, one at a time, each turns 9.7 red:

  • the old code;
  • dropping the exact last lookup;
  • dropping last.toLowerCase();
  • returning last for an unknown id.

bun test and node --test 34 pass. Built on main: once #749 and #750 merge, the version line and the test import line conflict trivially, and I'll merge main in.

🤖 Generated with Claude Code

…last segment

canonicalModel stripped one provider prefix, so openrouter/openai/gpt-5-mini looked up
openai/gpt-5-mini, missed the gpt-5-mini alias and came back unresolved. Also look the last
path segment up in the aliases, as AgentCompass's resolve_canonical_model tries the raw name and
then raw.rsplit('/', 1)[-1]. An id no alias knows keeps its old canonical form (openrouter/qwen/foo
-> qwen/foo), so the keys quota.js and continuity.js match on don't move.

9.7 covers both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@yetone yetone left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at ac45abd. The logic is right and matches upstream's resolve_canonical_model (model_resolution.py:25): try the raw id, then raw.rsplit('/', 1)[-1].

What was run (WSL, Bun 1.4.2, Node 22): bun test 34 pass, node --test 34 pass, bun scripts/check.mjs exit 0.

Hand breaks on catalog.js:1488. The old code, dropping last.toLowerCase() and returning last each turn 9.7 red.

One gap. Dropping the exact last lookup stays green. Some alias keys have uppercase letters (MiniMax-M3), so openrouter/minimax/MiniMax-M3 needs that exact last-segment lookup. Please add an assertion for it.

Order. This merges after #749 and #750. Rebase it once they land, and the version becomes the next one after theirs.

…router/minimax/MiniMax-M3`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@akiiwa-games

Copy link
Copy Markdown
Contributor Author

Thanks. Pushed 39f8c5d. 9.7 now also asserts openrouter/minimax/MiniMax-M3 → minimax-m3. The alias key is MiniMax-M3, so this needs the exact-case last-segment lookup.

Hand breaks on the lookup, each run myself; every one turns 9.7 red:

  • dropping the exact last;
  • dropping last.toLowerCase();
  • the old code;
  • returning last for an unknown id.

bun test 34 pass, node --test 34 pass, bun scripts/check.mjs agentcompass exit 0. I'll merge main in after #749 and #750, and the version becomes the next one after theirs.

@yetone

yetone commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Re-reviewed at 39f8c5d. The code holds, but it can't merge yet. #749 landed as bf959aa, #750 comes before this PR, and this PR now conflicts with main.

What was run at 39f8c5d (mote, macOS, Bun 1.4.2, Node 22.22.0): bun test 34 pass, node --test test/router.test.mjs 34 pass, bun scripts/check.mjs agentcompass exit 0.

Hand breaks. I broke each of these by hand on canonicalModel, one at a time. Every one turned 9.7 red:

  • dropping the exact last lookup (the gap from the last review; the new openrouter/minimax/MiniMax-M3 case catches it);
  • dropping last.toLowerCase();
  • returning last for an unknown id;
  • the old code.

Why it doesn't merge. I merged it onto main with #749 squashed in. Two files conflict:

Once #750 is merged, please merge main in. Take the version after #750's 0.1.3, then post the run, and I'll merge at that head.

@yetone

yetone commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Re-checked at 39f8c5d. The change holds. On mote (Bun 1.4.2, Node 22), bun test and node --test each pass 34. A Bun probe of canonicalModel against main gives:

  • openrouter/openai/gpt-5-mini → gpt-6-luna (main: openai/gpt-5-mini)
  • openrouter/minimax/MiniMax-M3 → minimax-m3, with the spec found (tier 3.2 → 3.8)
  • a/b/c/claude-opus-4-6 → claude-opus-5-5
  • openrouter/qwen/foo → qwen/foo, unchanged

The package also loads and runs in magpie's moejs middleware runner with no failures.

It still can't merge. It conflicts with main (package.json is at 0.1.1 here, and the test import line differs), and #750 goes first as 0.1.3, where I've asked for one more round. Once #750 lands, please merge main in and keep 0.1.4.

…cal-model

Keeps 0.1.4, the version after magpie-community#750's 0.1.3, and imports both sides' names in the test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@akiiwa-games

Copy link
Copy Markdown
Contributor Author

#750 landed as 10a61c2, and 0.1.3 is on the dist branch, so I merged main (beb6343) in. Head is now 2adb543. It's a normal merge with no force-push.

Conflicts, the two you predicted:

Against main, the diff is still only this PR's change: package.json, canonicalModel in catalog.js, and test 9.7.

What I ran at 2adb543 (Windows, Bun 1.4.0, Node 24.12, temp HOME): bun test 44 pass, node --test test/router.test.mjs 44 pass, bun scripts/check.mjs agentcompass exit 0.

canonicalModel at this head gives the same results as your probe:

  • openrouter/openai/gpt-5-mini → gpt-6-luna
  • openrouter/minimax/MiniMax-M3 → minimax-m3
  • a/b/c/claude-opus-4-6 → claude-opus-5-5
  • openrouter/qwen/foo → qwen/foo

@yetone yetone left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: approve at 2adb543.

Re-reviewed at 2adb543. The last review asked for two changes: an assertion that pins the exact-case last-segment lookup, and a merge of main once #750 landed. Both are done.

  1. The gap from the ac45abd review is closed. 39f8c5d adds canonicalModel("openrouter/minimax/MiniMax-M3") === "minimax-m3". Since ac45abd, that line is the PR's only change of its own.

  2. The merge is correct. 2adb543 is a normal merge of main at beb6343, with no force-push. A git show --remerge-diff shows only the two conflicts we expected, and both are resolved correctly:

    • package.json: 0.1.4, the version after #750's 0.1.3;
    • router.test.mjs: the import line takes both sides' names: CANONICAL_ROUTES, DEFAULT_SCORING_POLICY, EFFORT_CURVES, canonicalModel.

    Against main, the diff is only this PR's own 3 files and 17 added lines (package.json, canonicalModel in catalog.js, test 9.7).

  3. Current main merges cleanly. main has moved 4 commits past beb6343 (to 856ad93), and none of them touches packages/agentcompass, registry.json or scripts/. git merge-tree against origin/main is clean.

  4. The code is the same as at the last review, line by line. It tries unprefixed, unprefixed.toLowerCase(), last, then last.toLowerCase(), and falls back to unprefixed. This matches upstream's resolve_canonical_model. An id no alias knows keeps its old key (openrouter/qwen/foo → qwen/foo). Edge cases behave as on main: foo/ → "" and a//b → /b are unchanged. The order of the lookups doesn't matter today. The 8 alias keys that contain a slash are all opencode/*, and none of their last segments is an alias of its own. For that reason, moving last ahead of unprefixed stays green. That is not a gap in this PR.

  5. Hand breaks (mote). I made each one on canonicalModel at 2adb543, one at a time:

    • the old code (beb6343's catalog.js): 9.7 red, 43 pass and 1 fail;
    • dropping the exact last: 9.7 red;
    • dropping last.toLowerCase(): 9.7 red;
    • returning last for an unknown id: 9.7 red;
    • dropping unprefixed.toLowerCase(): stays green. That lookup was on main already and this PR didn't add it, so it doesn't block. last.toLowerCase() covers the cases that exist today.
  6. Callers. canonicalModel feeds quota.js, continuity.js, hooks.js, middleware.js, allocator.js and index.js. The only output that changes is for multi-prefix ids, which now resolve to their alias. That change is the fix. Every other output is unchanged.

  7. Conventions. The subject follows the <pkg> <version>: <what> form. The version is bumped once. The new tests sit in the existing 9.7 block. The new comment says why. No README or registry change is needed, since agentcompass keeps no changelog and the registry entry holds no version.

  8. Version. The package is not on npm. npm view --prefer-online --registry https://registry.npmjs.org @magpie-community/gateway-agentcompass version returns E404, as it has for every earlier version. It installs from the dist branch, where index.json lists 0.1.0 to 0.1.3. 0.1.4 is the next free version.

  9. No magpie min raise. No mover, pin or min in yetone/magpie mentions agentcompass (git grep -i agentcompass origin/main finds nothing).

  10. CI. PR run 42165215410 at 2adb543 is green on attempt 1: test and on-npm both pass.

What was run at 2adb543 (mote, macOS, Bun 1.4.2, Node 22.22.0, HOME=$(mktemp -d)):

  • in packages/agentcompass: bun test 44 pass, 0 fail; node --test test/router.test.mjs 44 pass, 0 fail;
  • bun scripts/check.mjs agentcompass: exit 0;
  • bun scripts/check.mjs (the whole repo): exit 0;
  • repo root bun test: 6244 pass, 0 fail, 6264 tests across 459 files, exit 0;
  • a Bun probe of canonicalModel: openrouter/openai/gpt-5-mini → gpt-6-luna, OpenRouter/OpenAI/GPT-5-Mini → gpt-6-luna, openrouter/minimax/MiniMax-M3 → minimax-m3, a/b/c/claude-opus-4-6 → claude-opus-5-5, openrouter/anthropic/claude-opus-4-6:high → claude-opus-5-5, openai/gpt-5-mini[1m] → gpt-6-luna, openrouter/qwen/foo → qwen/foo, qwen/foo → foo.

npm ci --ignore-scripts was not run: the repo and the package have no lockfile, and agentcompass has no dependencies.

Not tried: a real routed request through a live gateway with a multi-prefix model id. The ac45abd-era moejs runner load from the 11-05 re-check was not repeated at this head.

@yetone
yetone merged commit 6de02a0 into magpie-community:main Nov 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants