v1.93.37.0 Price Claude Haiku 5.5, GPT-6 Luna and Gemini 4 Argon for eval planning, and name the GPT-6 tiers in the Codex docs (#3732)

* pricing: rows for claude-haiku-5-5, gpt-6-luna and gemini-4-argon (#3640)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: name gpt-6.1-sol and gpt-6-luna as the current Codex tiers (#2943)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(hosts): gpt-6.1-sol is the default eval tier, not the outside-voice default

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* test(autoplan): use a model id with no price row for the unpriced-spend-cap case (claude-haiku-5-5 is priced now)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
Garry Tanandcapy-ai[bot] authored and GitHub committed 2026-11-03 02:18:33 +00:00
1 parent 5192908de4
commit 6f1dfd5b7c
10 files changed
+51 -11

No files matched your search

+12
View File
@@ -1,5 +1,17 @@
# Changelog # Changelog
## [1.93.37.0] - 2026-11-03
**Eval planning prices Claude Haiku 5.5, GPT-6 Luna and Gemini 4 Argon, and the Codex docs name the current OpenAI tiers (#3640, #2943).** Before, `gstack-eval-plan arms --arms claude-haiku-5-5` stopped with EVAL_PRICE_MISSING because `lib/pricing.ts` had no row for it. docs/hosts.md and the /codex example still named gpt-5.6-sol as the current Sol model.
### Added
- **Price rows** for `claude-haiku-5-5` ($0.10 / $0.50, cached $0.01, standard tier up to 100,000 tokens), `gpt-6-luna` ($0.10 / $0.50, cached $0.01) and `gemini-4-argon` ($4.00 / $20.00, cached $0.20). Each row cites its provider page. Argon uses the rates that start on 2026-12-01, so estimates never come in low after that date. A repository's model-policy document that names one of these models now gets it as an eval arm.
### Changed
- **docs/hosts.md and /codex** name `gpt-6-astra`, `gpt-6.1-sol` and `gpt-6-luna` as the current tiers. They also say the bounded-scope overlay still applies only to `gpt-5.6-sol` until it has its own eval.
Thanks to @exGeni (#3640) and @DanCanadian (#2943) for the reports. The TypeSafe Jev rows from #3640 are not included, because a $0 output price breaks the price table's rule that every row has an output price.
## [1.93.36.0] - 2026-11-03 ## [1.93.36.0] - 2026-11-03
- **/autoplan R65 defaults: no review for bug fixes, one lean review for features.** `gstack-autoplan next --kind fix` prints `AUTOPLAN: not needed (bug fix; R65)` and `status=skipped run=-` and writes nothing; the PR still needs the bug's proof. `--kind feature`, now the default for an unattended Capy run, runs the eng phase alone with one native reviewer whose brief merges the CEO and Eng lenses (Design and DX only when scope detects them), reads the draft code (a diff against `--base`, hashed into the snapshot, or an honest `DRAFT: none`), always asks "Any outside terms, licences or rights involved?", and has no outside voice, one round, one gate revision and no carry check. The reviewer's result must name the draft hash on its `DRAFT:` line. A failed git command reads `DRAFT: none (draft capture failed: …)`, untracked files named like secrets stay out of the draft, the `DRAFT:` line names the checkout it diffed, and a draft over 100,000 bytes is still inlined, cut there and marked. `run` stays the full run unless `--kind feature` asks for the lean one, `run --kind fix` skips like `next`, and `--kind fix --json` prints one skipped object. `--full` brings back every phase and voice; off Capy and in interactive sessions nothing changes. The gate cost line and the owner brief say a lean `rec` reopens nothing. - **/autoplan R65 defaults: no review for bug fixes, one lean review for features.** `gstack-autoplan next --kind fix` prints `AUTOPLAN: not needed (bug fix; R65)` and `status=skipped run=-` and writes nothing; the PR still needs the bug's proof. `--kind feature`, now the default for an unattended Capy run, runs the eng phase alone with one native reviewer whose brief merges the CEO and Eng lenses (Design and DX only when scope detects them), reads the draft code (a diff against `--base`, hashed into the snapshot, or an honest `DRAFT: none`), always asks "Any outside terms, licences or rights involved?", and has no outside voice, one round, one gate revision and no carry check. The reviewer's result must name the draft hash on its `DRAFT:` line. A failed git command reads `DRAFT: none (draft capture failed: …)`, untracked files named like secrets stay out of the draft, the `DRAFT:` line names the checkout it diffed, and a draft over 100,000 bytes is still inlined, cut there and marked. `run` stays the full run unless `--kind feature` asks for the lean one, `run --kind fix` skips like `next`, and `--kind fix --json` prints one skipped object. `--full` brings back every phase and voice; off Capy and in interactive sessions nothing changes. The gate cost line and the owner brief say a lean `rec` reopens nothing.
+1 -1
View File
@@ -1 +1 @@
1.93.36.0 1.93.37.0
+1 -1
View File
@@ -1,4 +1,4 @@
# gstack digest v1.93.36.0 — regenerate/re-copy after upgrading gstack # gstack digest v1.93.37.0 — regenerate/re-copy after upgrading gstack
Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed
for agent hosts without a full skill install. The full skills add workflows, for agent hosts without a full skill install. The full skills add workflows,
+1 -1
View File
@@ -550,7 +550,7 @@ codex >=0.144), the `-c` form explicitly overrides any top-level
web search regardless of configuration, so on the default Review path the flag is a web search regardless of configuration, so on the default Review path the flag is a
harmless no-op — only exec-based modes actually search. harmless no-op — only exec-based modes actually search.
If the user specifies a model (e.g., `/codex review -m gpt-5.6-sol` or If the user specifies a model (e.g., `/codex review -m gpt-6.1-sol` or
`/codex challenge --model gpt-daybreak-blue-latest`), translate it to the same config `/codex challenge --model gpt-daybreak-blue-latest`), translate it to the same config
form and replace the default model flag with `-c "model=\"<model>\""`. Native review form and replace the default model flag with `-c "model=\"<model>\""`. Native review
also requires `-c "review_model=\"<model>\""`; replace both model values together. also requires `-c "review_model=\"<model>\""`; replace both model values together.
+1 -1
View File
@@ -271,7 +271,7 @@ codex >=0.144), the `-c` form explicitly overrides any top-level
web search regardless of configuration, so on the default Review path the flag is a web search regardless of configuration, so on the default Review path the flag is a
harmless no-op — only exec-based modes actually search. harmless no-op — only exec-based modes actually search.
If the user specifies a model (e.g., `/codex review -m gpt-5.6-sol` or If the user specifies a model (e.g., `/codex review -m gpt-6.1-sol` or
`/codex challenge --model gpt-daybreak-blue-latest`), translate it to the same config `/codex challenge --model gpt-daybreak-blue-latest`), translate it to the same config
form and replace the default model flag with `-c "model=\"<model>\""`. Native review form and replace the default model flag with `-c "model=\"<model>\""`. Native review
also requires `-c "review_model=\"<model>\""`; replace both model values together. also requires `-c "review_model=\"<model>\""`; replace both model values together.
+8 -5
View File
@@ -188,11 +188,14 @@ digest's first line shows its gstack version; re-copy it after upgrading.
For Codex, setup reads the top-level `model` from For Codex, setup reads the top-level `model` from
`${CODEX_HOME:-~/.codex}/config.toml` and generates the matching behavioral `${CODEX_HOME:-~/.codex}/config.toml` and generates the matching behavioral
profile, falling back to `gpt-6-astra` when no usable model is configured. profile, falling back to `gpt-6-astra` when no usable model is configured.
`gpt-5.6-sol` automatically receives bounded-scope instructions that The current OpenAI tiers are `gpt-6-astra` (frontier), `gpt-6.1-sol` (smart, the
finish the requested lake without expanding into adjacent cleanup or speculative default eval tier) and `gpt-6-luna` (lowest cost); `gpt-6.1-sol`
hardening. The Sol profile is exact-match only: dated snapshots and other 5.6 and `gpt-6-luna` get the generic GPT profile. Only `gpt-5.6-sol` receives the
variants get the generic GPT profile, and setup warns on near-misses like bounded-scope instructions that finish the requested lake without expanding into
`gpt-5.6-sol-2026-08-01`. Override detection with `./setup --host codex --model <id>` — the adjacent cleanup or speculative hardening, because that patch was measured on 5.6
Sol; extending it to `gpt-6.1-sol` waits for its own scope eval. The Sol profile is
exact-match only: dated snapshots and other 5.6 variants get the generic GPT
profile, and setup warns on near-misses like `gpt-5.6-sol-2026-08-01`. Override detection with `./setup --host codex --model <id>` — the
override applies to that run only; set `model` in your Codex `config.toml` to override applies to that run only; set `model` in your Codex `config.toml` to
make it stick across upgrades. After changing your Codex model, rerun make it stick across upgrades. After changing your Codex model, rerun
`./setup --host codex` to regenerate the skills. `./setup --host codex` to regenerate the skills.
+8
View File
@@ -51,6 +51,9 @@ export const PRICING: Record<string, ModelPricing> = {
// https://platform.claude.com/docs/en/about-claude/pricing (fetched 2026-10-12) // https://platform.claude.com/docs/en/about-claude/pricing (fetched 2026-10-12)
'claude-sonnet-5-5': { input_per_mtok: 2.00, output_per_mtok: 10.00, cached_input_per_mtok: 0.10, as_of: '2026-10' }, 'claude-sonnet-5-5': { input_per_mtok: 2.00, output_per_mtok: 10.00, cached_input_per_mtok: 0.10, as_of: '2026-10' },
'claude-sonnet-4-6': { input_per_mtok: 3.00, output_per_mtok: 15.00, as_of: '2026-04' }, 'claude-sonnet-4-6': { input_per_mtok: 3.00, output_per_mtok: 15.00, as_of: '2026-04' },
// https://platform.claude.com/docs/en/about-claude/pricing (fetched 2026-10-31; standard tier, prompts up to
// 100,000 tokens; the $0.50 / $2.50 / $0.05 rate above that is excluded like the other long-context surcharges)
'claude-haiku-5-5': { input_per_mtok: 0.10, output_per_mtok: 0.50, cached_input_per_mtok: 0.01, as_of: '2026-10' },
'claude-haiku-4-5': { input_per_mtok: 1.00, output_per_mtok: 5.00, as_of: '2026-04' }, 'claude-haiku-4-5': { input_per_mtok: 1.00, output_per_mtok: 5.00, as_of: '2026-04' },
// OpenAI (GPT + o-series) // OpenAI (GPT + o-series)
@@ -58,6 +61,8 @@ export const PRICING: Record<string, ModelPricing> = {
'gpt-6-astra': { input_per_mtok: 10.00, output_per_mtok: 50.00, cached_input_per_mtok: 1.00, as_of: '2026-09' }, 'gpt-6-astra': { input_per_mtok: 10.00, output_per_mtok: 50.00, cached_input_per_mtok: 1.00, as_of: '2026-09' },
// https://developers.openai.com/api/docs/models/gpt-6.1-sol (standard tier, up to 272K input) // https://developers.openai.com/api/docs/models/gpt-6.1-sol (standard tier, up to 272K input)
'gpt-6.1-sol': { input_per_mtok: 2.00, output_per_mtok: 10.00, cached_input_per_mtok: 0.10, as_of: '2026-10' }, 'gpt-6.1-sol': { input_per_mtok: 2.00, output_per_mtok: 10.00, cached_input_per_mtok: 0.10, as_of: '2026-10' },
// https://developers.openai.com/api/docs/models/gpt-6-luna (fetched 2026-10-31; standard tier, up to 272K input)
'gpt-6-luna': { input_per_mtok: 0.10, output_per_mtok: 0.50, cached_input_per_mtok: 0.01, as_of: '2026-10' },
'gpt-5.4': { input_per_mtok: 2.50, output_per_mtok: 10.00, as_of: '2026-04' }, 'gpt-5.4': { input_per_mtok: 2.50, output_per_mtok: 10.00, as_of: '2026-04' },
// https://developers.openai.com/api/docs/models/gpt-4o (fetched 2026-10-13; gbrain's LongMemEval judge, the official scorer's model; // https://developers.openai.com/api/docs/models/gpt-4o (fetched 2026-10-13; gbrain's LongMemEval judge, the official scorer's model;
// the alias only: the gpt-4o-2024-05-13 snapshot has its own price) // the alias only: the gpt-4o-2024-05-13 snapshot has its own price)
@@ -67,6 +72,9 @@ export const PRICING: Record<string, ModelPricing> = {
'o4-mini': { input_per_mtok: 1.10, output_per_mtok: 4.40, as_of: '2026-04' }, 'o4-mini': { input_per_mtok: 1.10, output_per_mtok: 4.40, as_of: '2026-04' },
// Google // Google
// https://ai.google.dev/gemini-api/docs/pricing (fetched 2026-10-31; the rates starting 2026-12-01, so estimates
// never under-price; through 2026-11-30 the page lists $2.00 / $10.00 / $0.10 cached; thinking tokens bill as output)
'gemini-4-argon': { input_per_mtok: 4.00, output_per_mtok: 20.00, cached_input_per_mtok: 0.20, as_of: '2026-10' },
// https://ai.google.dev/gemini-api/docs/pricing (fetched 2026-10-12; standard tier through 2026-12-31, // https://ai.google.dev/gemini-api/docs/pricing (fetched 2026-10-12; standard tier through 2026-12-31,
// the page lists $1.50 / $7.50 / $0.15 cached starting 2027-01-01) // the page lists $1.50 / $7.50 / $0.15 cached starting 2027-01-01)
'gemini-3.8-flash': { input_per_mtok: 0.75, output_per_mtok: 3.75, cached_input_per_mtok: 0.075, as_of: '2026-10' }, 'gemini-3.8-flash': { input_per_mtok: 0.75, output_per_mtok: 3.75, cached_input_per_mtok: 0.075, as_of: '2026-10' },
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "gstack", "name": "gstack",
"version": "1.93.36", "version": "1.93.37",
"description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.", "description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.",
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",
+1 -1
View File
@@ -205,7 +205,7 @@ describe('gstack-autoplan run --native-runner api --runner api', () => {
mode = 'ok'; mode = 'ok';
calls = 0; calls = 0;
const kind = ['GSTACK', 'SESSION', 'KIND'].join('_'); const kind = ['GSTACK', 'SESSION', 'KIND'].join('_');
const r = await run('unpriced', ['--spend-cap', '1'], { ANTHROPIC_API_KEY: 'ak-test', OPENAI_API_KEY: 'sk-test', [kind]: 'spawned' }, 'anthropic/claude-haiku-5-5'); const r = await run('unpriced', ['--spend-cap', '1'], { ANTHROPIC_API_KEY: 'ak-test', OPENAI_API_KEY: 'sk-test', [kind]: 'spawned' }, 'anthropic/claude-unpriced-test-0');
expect(r.status).toBe(3); expect(r.status).toBe(3);
expect(r.stdout + r.stderr).toContain('SPEND_CAP_EXCEEDED'); expect(r.stdout + r.stderr).toContain('SPEND_CAP_EXCEEDED');
expect(calls).toBe(0); expect(calls).toBe(0);
+17
View File
@@ -41,6 +41,12 @@ describe('lib/pricing', () => {
test('the default eval-arms tier (smart) is priced out of the box', () => { test('the default eval-arms tier (smart) is priced out of the box', () => {
for (const model of ['claude-opus-5-5', 'gpt-6.1-sol']) expect(hasPricing(model)).toBe(true); for (const model of ['claude-opus-5-5', 'gpt-6.1-sol']) expect(hasPricing(model)).toBe(true);
}); });
test('claude-haiku-5-5, gpt-6-luna and gemini-4-argon are priced (#3640)', () => {
for (const model of ['claude-haiku-5-5', 'anthropic/claude-haiku-5-5', 'gpt-6-luna', 'openai/gpt-6-luna', 'gemini-4-argon']) expect(hasPricing(model)).toBe(true);
expect(estimateCostUsd({ input: 1_000_000, output: 1_000_000 }, 'claude-haiku-5-5')).toBe(0.6);
expect(estimateCostUsd({ input: 1_000_000, output: 1_000_000 }, 'gemini-4-argon')).toBe(24);
});
}); });
describe('preregistration', () => { describe('preregistration', () => {
@@ -67,6 +73,17 @@ describe('arms', () => {
const unpriced = resolveArms({ cwd: d, explicit: ['gpt-6-astra', 'made-up-model'] }); const unpriced = resolveArms({ cwd: d, explicit: ['gpt-6-astra', 'made-up-model'] });
expect(unpriced.errors.map(e => e.code)).toEqual(['EVAL_PRICE_MISSING']); expect(unpriced.errors.map(e => e.code)).toEqual(['EVAL_PRICE_MISSING']);
expect(renderArms(unpriced, { input: 1000, output: 1000 })).toContain('price=MISSING'); expect(renderArms(unpriced, { input: 1000, output: 1000 })).toContain('price=MISSING');
const added = resolveArms({ cwd: d, explicit: ['claude-haiku-5-5', 'gpt-6-luna', 'gemini-4-argon'] });
expect(added.errors).toEqual([]);
});
test('a policy document naming a newly priced model yields that arm', () => {
const d = tmp();
const doc = path.join(d, 'MODELS.md');
fs.writeFileSync(doc, '- cheap arm: claude-haiku-5-5\n- strong arm: claude-opus-5-5\n');
const r = resolveArms({ cwd: d, policyDoc: doc, modelsCli: () => ({ code: 1, stdout: '' }) });
expect(r.errors).toEqual([]);
expect(r.arms.map(a => a.model).sort()).toEqual(['claude-haiku-5-5', 'claude-opus-5-5']);
}); });
test('the eval-arms role is read through the models CLI seam, never the network', () => { test('the eval-arms role is read through the models CLI seam, never the network', () => {