Repository navigation
Per-version Anthropic prices; README builds the CLI from source - #52
Conversation
The table priced by family, so Haiku 5.5 billed at Haiku 4.5's $1/$5 per MTok instead of $0.10/$0.50, Opus 5.5 at $5/$25 instead of $4/$20, Sonnet 5 and 5.5 at $3/$15 instead of $2/$10, and Opus 4/4.1 at $5/$25 instead of $15/$75. Cache reads use each model's published rate. Adds a test that pins Haiku 5.5.
The npm package was unpublished on 2026-10-07. Clone, npm ci, npm run build, node dist/cli.js; npm run pack:cli && npm i -g ./out-cli for the maat and molt commands. Same fix in docs/versioning.md and docs/acp-server.md.
Solvyx
left a comment
There was a problem hiding this comment.
Review by Grok Bot at cb01d74. Verdict: request changes (two blocking items, both small).
I checked every row in the new table against platform.claude.com/docs/en/about-claude/pricing today and all the numbers match, including the Sonnet 5 footnote (the $2/$10 launch price is now standard, so moving it off $3/$15 doesn't break the file's standard-not-introductory rule). I also ran the README's from-source path in a fresh clone: npm ci, npm run pack:cli and npm i -g --prefix /tmp/gpfx ./out-cli all worked, and maat --version printed v0.2.2. Pairing rules are fine: this is a claude/ branch into claude/integration-all, it adds no subscription backend, it doesn't touch fine-tune data, and naming the Anthropic API provider in its own price table is product configuration, not competitor copy. CI is partly done: privsep-linux passed, while typecheck-and-test and test-linux were still pending when I looked.
Blocking
1. Haiku 5.5 uses the cheaper tier, which breaks the file's own safe-direction rule (src/providers.ts:304, with the comment at :288). Confidence: high on how it happens, medium that you'll want it blocking.
The doc comment says a budget that under-counts "stops you too late" and that over-counting is the safe direction. This row still picks the up-to-100k rate (0.10 / 0.50 / 0.01). A coding agent regularly sends prompts over 100k tokens on long sessions, and those are billed at 0.50 / 2.50 / 0.05, five times what the meter records. A /budget ceiling on Haiku 5.5 can then overrun by up to 5x before it trips. costUsd() works from session totals, so it can't pick a tier per request. The simplest fix that keeps to the rule is to use the over-100k rates as the default for this row (still half the price of Haiku 4.5) and say in the comment that /price lowers it. Add a test that pins those rates.
2. The release notes still tell people to npm i -g @solvyx/molt (.github/workflows/release.yml:119, :126-130, and the header comment at :2). Confidence: high.
This PR fixes the README because the package was unpublished, but the release workflow's body: template still says the CLI is "published as @solvyx/molt" and gives npm i -g @solvyx/molt as the install command. The next tagged release will publish a GitHub Release page whose CLI section points at a package that isn't there. That's the same problem this PR exists to fix, on the page users are most likely to read. Replace it with the clone, npm ci, npm run pack:cli, npm i -g ./out-cli steps, or a link to the README's CLI / TUI section.
Non-blocking
3. claude-opus-4-0 is billed at a third of its price (src/providers.ts:296). Confidence: high.
The anchored regex ^claude-opus-4(?:-\d{8})?$ matches claude-opus-4 and claude-opus-4-20250514, but not Anthropic's claude-opus-4-0 alias. That alias falls through to the generic Opus row at $5 / $25 instead of $15 / $75 (I confirmed this by running the table). Opus 4 is retired on the first-party API, so real exposure is low, but it's a one-character fix: ^claude-opus-4(?:-0)?(?:-\d{8})?$, plus a line in the version test.
4. Cache writes are still billed at the base input rate (src/providers.ts:285). Confidence: high. This isn't new.
The published multipliers are 1.25x for 5-minute writes and 2x for 1-hour writes, so sessions that write a lot of cache are under-counted. The comment now says this out loud, which helps. A cacheWrite column would be a good follow-up issue, since the engine already tracks cacheWriteTokens.
5. The README wording about linking depends on the npm version (README.md:159). Confidence: medium.
On npm 9.2, npm i -g ./out-cli put a full copy in the global prefix, including its own node_modules, rather than a symlink. So "npm links the commands to that folder, so keep the clone where it is" isn't true everywhere, and either way people need to re-run npm run pack:cli && npm i -g ./out-cli after pulling. Suggested wording: "after pulling, re-run both commands to update the installed CLI."
6. Leftover publish wording (CONTRIBUTING.md:89, package.cli.json:48). Confidence: medium.
CONTRIBUTING still calls @solvyx/molt the publishable CLI, and package.cli.json keeps publishConfig.access: public. An npm publish run by mistake from out-cli/ would bring the package back. If not publishing is the policy for now, consider setting "private": true in the staged package (or making prepare-cli-package.mjs add it) so it fails safe.
This routine doesn't merge, and nothing was pushed to this branch.
| { match: /^claude-sonnet-5(?![-.]?\d)|^claude-sonnet-5-\d{8}/, in: 2, out: 10, cached: 0.2 }, | ||
| // Sonnet 4.x, and any Sonnet not listed above. | ||
| { match: /^claude-sonnet-/, in: 3, out: 15, cached: 0.3 }, | ||
| { match: /^claude-haiku-5[-.]5(?!\d)/, in: 0.1, out: 0.5, cached: 0.01 }, |
There was a problem hiding this comment.
Blocking (confidence high on how it happens). This is the up-to-100k tier. Prompts over 100k cost 5x this (0.50 / 2.50 / 0.05), and agent sessions get there routinely, so the meter under-counts in the direction the doc comment above calls unsafe. Suggest making the over-100k rates the default here and pinning them in a test.
| { match: /^claude-(fable|mythos)-5/, in: 10, out: 50, cached: 1 }, | ||
| { match: /^claude-opus-5[-.]5(?!\d)/, in: 4, out: 20, cached: 0.2 }, | ||
| { match: /^claude-opus-4[-.]1(?!\d)/, in: 15, out: 75, cached: 1.5 }, | ||
| { match: /^claude-opus-4(?:-\d{8})?$/, in: 15, out: 75, cached: 1.5 }, |
There was a problem hiding this comment.
Non-blocking (confidence high). This misses the claude-opus-4-0 alias, which falls through to the $5 / $25 row (a 3x under-count). ^claude-opus-4(?:-0)?(?:-\d{8})?$ covers it.
| Or without installing: `npx @solvyx/molt`. | ||
| To get `maat` and `molt` commands on your PATH, stage the CLI package and | ||
| install it from the local folder (nothing is downloaded from the registry; npm | ||
| links the commands to that folder, so keep the clone where it is): |
There was a problem hiding this comment.
Non-blocking (confidence medium). On npm 9.2 this installs a copy, not a link (I checked in a fresh clone). Suggest saying to re-run npm run pack:cli && npm i -g ./out-cli after pulling, rather than relying on the link.
The meter prices session totals, so it cannot tell Haiku 5.5's prompt-length tiers apart. Use the over-100k rates (0.50 / 2.50 / 0.05) so a budget over-counts rather than under-counts; /price 0.1 0.5 0.01 sets the lower tier. claude-opus-4-0 fell through to the generic Opus row at 5 / 25 instead of 15 / 75. Tests pin both.
…is private release.yml still told people to npm i -g @solvyx/molt. The release body now gives clone, npm ci, npm run pack:cli, npm i -g ./out-cli at the tag. The staged out-cli package is "private": true (set in package.cli.json and forced by prepare-cli-package.mjs), so an accidental npm publish fails. README says to re-run both install commands after pulling.
|
Thanks for the review. All six items are addressed in fd5811f and bd5f195.
CHANGELOG entries are updated to match. Verification, with ~/.local/bin off PATH: |
solvyxtech
left a comment
There was a problem hiding this comment.
Re-review at bd5f195: both blockers fixed. No blockers left.
fd5811f and bd5f195 answer review 5454623610. My verdict is no blockers; this looks ready for Tyler to merge.
What I checked
| Item | Result | Confidence |
|---|---|---|
| (a) The tiered small-model row bills at the over-100k rate | Holds. src/providers.ts:309 is 0.50 / 2.50 / 0.05. The comment at :287-293 explains why and gives the /price override for the lower tier. The test pins it for the dashed, dotted and router-prefixed ids. |
High |
| (a) The large model's 4-0 alias bills 15 / 75 / 1.5 | Holds. :300 (4(?:-0)?(?:-\d{8})?$) is pinned for both the -4-0 and the bare -4 ids. I also probed the dated 5.5 id (0.5/2.5/0.05) and a dated 5 id; both get the right row. |
High |
(b) No npm i -g @solvyx/molt left |
Holds. git grep over the tree finds it only in the CHANGELOG line describing this fix. release.yml parses as YAML. The CLI section of the notes body renders as clone at steps.tag.outputs.name (that step exists at :80-86), then npm ci, pack:cli, npm i -g ./out-cli, maat --version. |
High |
| (c) The staged CLI is private | Holds. package.cli.json:3 has "private": true and no publishConfig. prepare-cli-package.mjs:45-46 forces both. npm run pack:cli produces out-cli/package.json with private: true and no publishConfig. As you noted, npm publish --dry-run exits 0 (it prints + @solvyx/molt@0.2.2), because dry-run returns before the private check. To check the real refusal, I ran npm publish against a dead local registry (127.0.0.1:9) with a fake token: it stops with EPRIVATE before any network call. A control copy with private removed went on to try the network. So an accidental publish fails. |
High |
| (d) Fresh clone following the README | Works. Fresh clone at bd5f195, then npm ci, npm run build, and node dist/cli.js --version gives v0.2.2. npm run pack:cli and npm i -g ./out-cli --prefix <scratch> give maat --version and molt --version as v0.2.2. That holds on npm 9 and on npm 10, and after re-running pack:cli. |
High |
| (e) Earlier non-blocking points | The README's npm wording is fixed (line 166: "re-run both commands"). CONTRIBUTING (:88-92) says the package is staged, installed from ./out-cli, and not published. Cache writes are unchanged and tracked in #53. |
High |
(f) CI on bd5f195 |
typecheck-and-test, test-linux and privsep-linux are all green. | — |
Non-blocking
- README
:157-166: on npm 10 the global install is a symlink into the clone. Confidence: high. With npm 10 (what current Node 20 ships),npm i -g ./out-clilinkslib/node_modules/@solvyx/moltto<clone>/out-cli.out-cli/has nonode_modules, somaatresolves its dependencies from the clone's rootnode_modules. I renamed that folder andmaat --versioncrashed. Moving or deleting the clone, or runninggit clean -xdf, silently breaks the installed command. One sentence would cover it ("keep the clone; the command runs from it"). Alternatively,npm i -g --install-links ./out-climakes a standalone copy (that's what npm 9 does by default). - Stale comment at
scripts/prepare-cli-package.mjs:3. It still says "Stage a publishable @solvyx/molt package". Confidence: high, trivial. - Cache writes are still billed at the base input rate. The meter under-counts written tokens, but that's tracked in #53, so it's fine to leave out of this PR. Confidence: high.
- Naming, for Tyler. The price table, its tests and the CHANGELOG name one provider's model families, building on the existing native-API module. Whether that fits the repo naming rule is Tyler's call; I haven't treated it as a blocker here.
Runs (box, Node 20.19, ~/.local/bin off PATH)
npm run check: 2,416 tests, 2,408 pass, 1 fail, 7 skipped. The failure was the sameacp-deadlinetiming case as on #51, from two suites running in parallel; rerun alone it passes 13/13. The skips are root-only tests that CI covers.e2ePASS andself-checkPASS, run separately. The provider pricing test passes 20/20, and lean-budget passes 7/7 with re-read at 40,688 / 115,003 / 9, since this branch doesn't have the #51 change.
This is a comment review only; nothing was pushed or merged. GitHub doesn't allow a formal approval from this account.
# Conflicts: # CHANGELOG.md
Two transparency fixes.
Anthropic price table (src/providers.ts, checked against platform.claude.com/docs/en/about-claude/pricing on 2026-10-08). The table priced by family, so:
Unchanged: Fable/Mythos 5, Opus 4.5-5, Sonnet 4.x, Haiku 4.5. Haiku 5.5 uses its up-to-100k-token rates (over 100k: 0.50 / 2.50 / 0.05); the table has no prompt-length tier. Cache writes have no column; the meter bills them at the base input rate as before. New tests pin Haiku 5.5 and each version row.
README install line.
npm i -g @solvyx/molt/npx @solvyx/moltpointed at a package unpublished on 2026-10-07. Replaced with clone,npm ci,npm run build,node dist/cli.js, andnpm run pack:cli && npm i -g ./out-clifor themaat/moltcommands (verified from a fresh clone). npm badges removed; docs/versioning.md and docs/acp-server.md updated. No npm publish, nobinadded.Verification:
npm run checkwith ~/.local/bin off PATH: 2414 tests, 2409 pass, 0 fail, 5 todo; e2e PASS, self-check PASS.node --test dist-test/test/lean-budget.test.js: 7/7.