mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-01 06:24:41 +01:00
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:
1 parent
953a62a724
commit
15ebd85cdd
6 files changed
+38
-6
No files matched your search
@@ -1,5 +1,18 @@
|
|||||||
# Changelog
|
# 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
|
## [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`.
|
**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,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
|
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,
|
||||||
|
|||||||
+13
-3
@@ -21,7 +21,7 @@
|
|||||||
* - Anthropic: https://www.anthropic.com/pricing#api
|
* - Anthropic: https://www.anthropic.com/pricing#api
|
||||||
* - OpenAI: https://openai.com/api/pricing/
|
* - OpenAI: https://openai.com/api/pricing/
|
||||||
* - Google AI: https://ai.google.dev/gemini-api/docs/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 {
|
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)
|
// 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' },
|
||||||
'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;
|
||||||
|
// 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' },
|
'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' },
|
'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' },
|
'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-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-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
|
'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)
|
// 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-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' },
|
'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`,
|
* 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 {
|
export function pricingRow(model: string | undefined): ModelPricing | undefined {
|
||||||
if (!model) return undefined;
|
if (!model) return undefined;
|
||||||
const bare = model.replace(/^[a-z-]+[/:]/, '');
|
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 {
|
export function hasPricing(model: string | undefined): boolean {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gstack",
|
"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.",
|
"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",
|
||||||
|
|||||||
@@ -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(estimateCostUsd({ input: 1_000_000, output: 0 }, 'voyage:voyage-4')).toBe(0.06);
|
||||||
expect(hasPricing('voyage-4-nano')).toBe(false);
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user