v1.91.100.0 fix: a gbrain LongMemEval call plan prices in full (gpt-4o, Voyage rerankers, dated Claude snapshots) (#3172)

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-10-13 21:31:07 +00:00
1 parent 953a62a724
commit 15ebd85cdd
6 files changed
+38 -6

No files matched your search

+13
View File
@@ -1,5 +1,18 @@
# Changelog
## [1.91.100.0] - 2026-10-13
**A gbrain LongMemEval call plan now prices in full.** gbrain's `eval longmemeval --call-plan` (gbrain#6638) writes a `GSTACK_EVAL_CALLS` file for every lane of the run. `gstack-eval-plan price-gate` verified its binding but stopped at `EVAL_PRICE_MISSING` with the total unknown: it had no row for the judge (`gpt-4o`) or the reranker (`rerank-2.5`), and it did not recognize the dated Claude id gbrain resolves (`claude-haiku-4-5-20251001`). On the gbrain fixture plan (`--mode tokenmax --judge`) all seven lanes now price, for a total of $0.447.
### What this means for you
- **Dated Claude snapshots bill at their alias's price.** `claude-<name>-YYYYMMDD`, with or without a provider prefix, resolves to the `claude-<name>` row. Dated OpenAI snapshots are not folded, because some (`gpt-4o-2024-05-13`) have their own price.
- **New rows, sourced and dated in `lib/pricing.ts`:** `gpt-4o` ($2.50 in, $10 out, $1.25 cached per million tokens) and the Voyage rerankers `rerank-2.5` ($0.05) and `rerank-2.5-lite` ($0.02 per million processed tokens: query tokens × documents, plus document tokens).
### For contributors
- `test/pricing-eval-plan.test.ts` checks every model a gbrain call plan names. It failed before the change.
## [1.91.99.0] - 2026-10-13
**A Bun pin mismatch on Capy now names the one command that fixes it, and the skill says to run it.** After gbrain pinned Bun 1.4.3 in CI, a session-start check on a gbrain checkout ended `gstack: fail pins` with a fix line that offered two choices and no command, and the skill's repair step only covered `revision` and `runtime`, so an agent following the skill left the machine failing. The same bootstrapper run without `--check` already installs the pinned Bun (a verified 1.4.3 in about 4 s) and ends `gstack: ok`.
+1 -1
View File
@@ -1 +1 @@
1.91.99.0
1.91.100.0
+1 -1
View File
@@ -1,4 +1,4 @@
# gstack digest v1.91.99.0 — regenerate/re-copy after upgrading gstack
# gstack digest v1.91.100.0 — regenerate/re-copy after upgrading gstack
Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed
for agent hosts without a full skill install. The full skills add workflows,
+13 -3
View File
@@ -21,7 +21,7 @@
* - Anthropic: https://www.anthropic.com/pricing#api
* - OpenAI: https://openai.com/api/pricing/
* - Google AI: https://ai.google.dev/gemini-api/docs/pricing
* - Voyage AI (embeddings): https://docs.voyageai.com/docs/pricing
* - Voyage AI (embeddings, rerankers): https://docs.voyageai.com/docs/pricing
*/
export interface ModelPricing {
@@ -59,6 +59,9 @@ export const PRICING: Record<string, ModelPricing> = {
// 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-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;
// the alias only: the gpt-4o-2024-05-13 snapshot has its own price)
'gpt-4o': { input_per_mtok: 2.50, output_per_mtok: 10.00, cached_input_per_mtok: 1.25, as_of: '2026-10' },
'gpt-5.4-mini': { input_per_mtok: 0.60, output_per_mtok: 2.40, as_of: '2026-04' },
'o3': { input_per_mtok: 15.00, output_per_mtok: 60.00, as_of: '2026-04' },
'o4-mini': { input_per_mtok: 1.10, output_per_mtok: 4.40, as_of: '2026-04' },
@@ -89,6 +92,9 @@ export const EMBEDDING_PRICING: Record<string, ModelPricing> = {
'voyage-code-3': { input_per_mtok: 0.18, output_per_mtok: 0, as_of: '2026-10' },
'voyage-3-large': { input_per_mtok: 0.18, output_per_mtok: 0, as_of: '2026-10' },
'voyage-multimodal-3': { input_per_mtok: 0.12, output_per_mtok: 0, as_of: '2026-10' }, // text tokens; pixels excluded
// https://docs.voyageai.com/docs/pricing (fetched 2026-10-13; rerankers bill query tokens x documents plus document tokens)
'rerank-2.5': { input_per_mtok: 0.05, output_per_mtok: 0, as_of: '2026-10' },
'rerank-2.5-lite': { input_per_mtok: 0.02, output_per_mtok: 0, as_of: '2026-10' },
// https://developers.openai.com/api/docs/pricing (fetched 2026-10-12)
'text-embedding-3-large': { input_per_mtok: 0.13, output_per_mtok: 0, as_of: '2026-10' },
'text-embedding-3-small': { input_per_mtok: 0.02, output_per_mtok: 0, as_of: '2026-10' },
@@ -98,12 +104,16 @@ export const EMBEDDING_PRICING: Record<string, ModelPricing> = {
/**
* A provider-prefixed id (`openai/gpt-6-astra`, `anthropic/claude-fable-5-1`,
* or gbrain's `voyage:voyage-4`) resolves to its table row.
* or gbrain's `voyage:voyage-4`) resolves to its table row, and so does a
* dated Claude snapshot (`claude-haiku-4-5-20251001`, Anthropic's `-YYYYMMDD`
* form), which bills at its alias's price. Dated OpenAI snapshots are not
* folded: some are priced differently from their alias.
*/
export function pricingRow(model: string | undefined): ModelPricing | undefined {
if (!model) return undefined;
const bare = model.replace(/^[a-z-]+[/:]/, '');
return PRICING[model] ?? PRICING[bare] ?? EMBEDDING_PRICING[model] ?? EMBEDDING_PRICING[bare];
const undated = /^claude-/.test(bare) ? bare.replace(/-\d{8}$/, '') : bare;
return PRICING[model] ?? PRICING[bare] ?? PRICING[undated] ?? EMBEDDING_PRICING[model] ?? EMBEDDING_PRICING[bare];
}
export function hasPricing(model: string | undefined): boolean {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "gstack",
"version": "1.91.99",
"version": "1.91.100",
"description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.",
"license": "MIT",
"type": "module",
+9
View File
@@ -448,4 +448,13 @@ describe('pricing rows with fetched sources (2026-10-12)', () => {
expect(estimateCostUsd({ input: 1_000_000, output: 0 }, 'voyage:voyage-4')).toBe(0.06);
expect(hasPricing('voyage-4-nano')).toBe(false);
});
test('every model in a gbrain `eval longmemeval --call-plan` file is priced: dated Claude snapshots, the judge and the reranker', () => {
expect(pricingRow('anthropic:claude-haiku-4-5-20251001')).toBe(PRICING['claude-haiku-4-5']);
expect(estimateCostUsd({ input: 1_000_000, output: 1_000_000 }, 'openai:gpt-4o')).toBe(12.5);
expect(hasPricing('gpt-4o-2024-05-13')).toBe(false);
expect(estimateCostUsd({ input: 1_000_000, output: 0 }, 'voyage:rerank-2.5')).toBe(0.05);
expect(estimateCostUsd({ input: 1_000_000, output: 0 }, 'rerank-2.5-lite')).toBe(0.02);
expect(hasPricing('claude-haiku-4-5-2025100')).toBe(false);
});
});