diff --git a/CHANGELOG.md b/CHANGELOG.md index eda8b1f..503b806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ All notable changes to Franklin Trading. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.4 — 2026-10-20 + +### Added +- **Gemini 4 Argon.** `google/gemini-4-argon`, Google's frontier reasoning model, is live on Base and Solana at $2/$10 per 1M (Google's rate through 2026-11-30; $4/$20 from 2026-12-01). Priced offline, sized at its 1M window, flagged vision-capable, listed in the picker, and pinnable as `argon`, `gemini-4` or `gemini-4-argon`. Nothing routes to it by default: bare `gemini` stays on 3.1 Pro and the router is unchanged. + ## 0.3.3 — 2026-10-20 ### Added diff --git a/package-lock.json b/package-lock.json index c695c79..205fd83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@blockrun/franklin-trading", - "version": "0.3.3", + "version": "0.3.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@blockrun/franklin-trading", - "version": "0.3.3", + "version": "0.3.4", "license": "Apache-2.0", "dependencies": { "@blockrun/llm": "^3.13.1", diff --git a/package.json b/package.json index 4661c36..406bd90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@blockrun/franklin-trading", - "version": "0.3.3", + "version": "0.3.4", "description": "Franklin Trading — The AI trading agent with a wallet. Researches, backtests, paper-trades and live-trades autonomously, paying per call in USDC. Crypto-first. Apache-2.0.", "type": "module", "exports": { diff --git a/src/agent/tokens.ts b/src/agent/tokens.ts index b49851b..6665c49 100644 --- a/src/agent/tokens.ts +++ b/src/agent/tokens.ts @@ -276,6 +276,7 @@ const MODEL_CONTEXT_WINDOWS: Record = { 'google/gemini-2.5-flash': 1_000_000, 'google/gemini-2.5-flash-lite': 1_000_000, 'google/gemini-3.1-pro': 1_000_000, + 'google/gemini-4-argon': 1_048_576, 'google/gemini-3.5-flash': 1_000_000, 'google/gemini-3.1-flash-lite': 1_000_000, 'google/gemini-3-flash-preview': 1_048_576, diff --git a/src/pricing.ts b/src/pricing.ts index becb020..b451a05 100644 --- a/src/pricing.ts +++ b/src/pricing.ts @@ -118,6 +118,9 @@ export const MODEL_PRICING: Record=200K input) diff --git a/src/router/vision.ts b/src/router/vision.ts index 393f1c0..2bb9fd2 100644 --- a/src/router/vision.ts +++ b/src/router/vision.ts @@ -77,6 +77,7 @@ const VISION_MODELS = new Set([ 'xiaomi/mimo-v2.5', 'mistral/mistral-large-4', // Google — vision baked into every Gemini SKU we surface (flash-lite excepted) + 'google/gemini-4-argon', 'google/gemini-3.1-pro', 'google/gemini-3.6-flash', 'google/gemini-3.5-flash', diff --git a/src/ui/model-picker.ts b/src/ui/model-picker.ts index ca5b618..1fa3dee 100644 --- a/src/ui/model-picker.ts +++ b/src/ui/model-picker.ts @@ -134,6 +134,12 @@ export const MODEL_SHORTCUTS: Record = { 'gemini-3.5-flash-lite': 'google/gemini-3.5-flash-lite', 'gemini-3.1-flash-lite': 'google/gemini-3.1-flash-lite', 'gemini-2.5-flash-lite': 'google/gemini-2.5-flash-lite', + // Gemini 4 Argon (live 2026-10-20, both chains) — explicit pins only. Bare + // `gemini` stays on 3.1 Pro until Argon has production history; moving it + // would change which model (and price) existing users get. + argon: 'google/gemini-4-argon', + 'gemini-4': 'google/gemini-4-argon', + 'gemini-4-argon': 'google/gemini-4-argon', 'gemini-3': 'google/gemini-3.1-pro', 'gemini-3.1': 'google/gemini-3.1-pro', // xAI — grok-4.5 is the public flagship since 2026-07-14; `grok` follows it @@ -454,6 +460,7 @@ export const PICKER_CATEGORIES: ModelCategory[] = [ // superseded sibling listed directly under its successor is choice // paralysis, not choice. `gemini-2.5` still resolves to it. { id: 'google/gemini-3.1-pro', shortcut: 'gemini', label: 'Gemini 3.1 Pro', price: '$2/$12' }, + { id: 'google/gemini-4-argon', shortcut: 'argon', label: 'Gemini 4 Argon', price: '$2/$10' }, { id: 'xai/grok-4.5', shortcut: 'grok', label: 'Grok 4.5', price: '$2/$6' }, // Kimi K3 (2026-07): 2.8T open MoE, 1M context, multimodal + reasoning. // Replaced the budget K2.7 line — now premium-priced ($3/$15). diff --git a/test/local.mjs b/test/local.mjs index 65305ee..9193bf8 100644 --- a/test/local.mjs +++ b/test/local.mjs @@ -9570,6 +9570,7 @@ test('catalog sync 2026-10-20: every live gateway id is priced and pinnable', as const live = { 'openai/gpt-6.1-sol': [2, 10, 'gpt-6.1-sol'], 'google/gemini-3.8-flash': [0.75, 3.75, 'gemini-3.8-flash'], + 'google/gemini-4-argon': [2, 10, 'gemini-4-argon'], 'deepseek/deepseek-v4-flash-vision-exp': [0.3, 1.2, 'deepseek-vision'], 'qwen/qwen3.8-max': [2, 6, 'qwen3.8-max'], 'qwen/qwen3.8-flash': [0.15, 0.47, 'qwen3.8-flash'], @@ -9603,6 +9604,8 @@ test('2026-10-20: bare flash / glm follow their flagships, price-neutral and on const { MODEL_PRICING } = await import('../dist/pricing.js'); const { isVisionModel } = await import('../dist/router/vision.js'); assert.equal(resolveModel('flash'), 'google/gemini-3.8-flash'); + assert.equal(resolveModel('argon'), 'google/gemini-4-argon'); + assert.equal(resolveModel('gemini'), 'google/gemini-3.1-pro', 'bare gemini stays on 3.1 Pro'); assert.equal(resolveModel('gemini-flash'), 'google/gemini-3.8-flash'); assert.equal(resolveModel('gemini-3.6'), 'google/gemini-3.6-flash', '3.6 stays pinnable'); assert.deepEqual(MODEL_PRICING['google/gemini-3.8-flash'], MODEL_PRICING['google/gemini-3.6-flash']); @@ -9614,7 +9617,7 @@ test('2026-10-20: bare flash / glm follow their flagships, price-neutral and on assert.equal(resolveModel('qwen-max'), 'qwen/qwen3.7-max'); // A vision-tagged new id must be recognised as vision, or an image turn on // `/model flash` would be swapped to a "vision sibling" the user never chose. - for (const id of ['openai/gpt-6.1-sol', 'google/gemini-3.8-flash', 'deepseek/deepseek-v4-flash-vision-exp', + for (const id of ['openai/gpt-6.1-sol', 'google/gemini-3.8-flash', 'google/gemini-4-argon', 'deepseek/deepseek-v4-flash-vision-exp', 'qwen/qwen3.8-flash', 'xiaomi/mimo-v2.5', 'mistral/mistral-large-4']) { assert.equal(isVisionModel(id), true, `${id} is vision-tagged in the live catalog`); }