From 914976a52f250daf9481810908dcc763f64d32eb Mon Sep 17 00:00:00 2001 From: Arvin Xu Date: Thu, 11 Jun 2026 01:29:17 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(model-bank):=20knowledgeCutoff?= =?UTF-8?q?=20batch=202,=20metadata=20skill=20&=20always-visible=20tab=20b?= =?UTF-8?q?ar=20(#15663)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ feat(model-bank): backfill knowledgeCutoff batch 2 and restore lost Anthropic values Co-Authored-By: Claude Fable 5 * 📝 docs(skills): add model-bank-metadata skill for cutoff/family backfill Co-Authored-By: Claude Fable 5 * 🐛 fix(model-bank): Claude Fable 5 belongs to the claude-mythos family Co-Authored-By: Claude Fable 5 * 💄 style(desktop): always surface the tab bar by creating a tab on first navigation Co-Authored-By: Claude Fable 5 * ♻️ refactor(model-bank): family is the product lineage (claude-opus/sonnet/haiku), not the brand Co-Authored-By: Claude Fable 5 * 🐛 fix(agent): backfill activeAgentId before paint on tab/route switches Tab switches are plain route navigations, so leaving an agent page cleared activeAgentId via a passive useUnmount and the next page re-set it in a passive useEffect — the first painted frame always had no active id, flashing a skeleton even when agentMap already cached the config. Move both the backfill and the unmount clear to layout effects: removed-tree layout cleanups run before new-tree layout effects in one commit, so the clear can never wipe a freshly synced id and the id is in place before paint. Co-Authored-By: Claude Fable 5 * ✨ feat(agent): surface agent config fetch errors with a retry action isAgentConfigLoading only knows "no data yet", so a failed fetch (e.g. a 401 that SWR deliberately does not retry, with no focus revalidation inside a single Electron window) left the agent page on a skeleton forever — only a manual reload recovered. Record per-agent fetch errors in agentConfigErrorMap (set by onError, cleared on data / retry), expose currentAgentConfigError / isAgentConfigError selectors, add a retryAgentConfigFetch action that revalidates the agent's SWR entries, and show an error alert with a retry button above the main chat input while the config is still missing. Co-Authored-By: Claude Fable 5 * 🐛 fix(ci): sync model metadata test expectations --------- Co-authored-by: Claude Fable 5 --- .agents/skills/model-bank-metadata/SKILL.md | 69 +++++ .../scripts/apply-cutoffs.ts | 73 ++++++ .../scripts/apply-family.ts | 49 ++++ .../scripts/derive-family.ts | 237 ++++++++++++++++++ .../scripts/extract-model-ids.ts | 23 ++ .../config/__snapshots__/index.test.ts.snap | 12 +- locales/en-US/chat.json | 2 + locales/zh-CN/chat.json | 2 + packages/locales/src/default/chat.ts | 2 + packages/model-bank/src/aiModels/ai21.ts | 2 + packages/model-bank/src/aiModels/ai302.ts | 16 +- packages/model-bank/src/aiModels/aihubmix.ts | 53 +++- packages/model-bank/src/aiModels/anthropic.ts | 32 ++- packages/model-bank/src/aiModels/azure.ts | 15 ++ packages/model-bank/src/aiModels/azureai.ts | 6 + packages/model-bank/src/aiModels/bedrock.ts | 45 ++-- .../model-bank/src/aiModels/cloudflare.ts | 2 + packages/model-bank/src/aiModels/cohere.ts | 2 + packages/model-bank/src/aiModels/cometapi.ts | 28 ++- .../model-bank/src/aiModels/fireworksai.ts | 1 + packages/model-bank/src/aiModels/github.ts | 11 + .../model-bank/src/aiModels/githubCopilot.ts | 24 +- packages/model-bank/src/aiModels/google.ts | 20 ++ packages/model-bank/src/aiModels/higress.ts | 44 +++- packages/model-bank/src/aiModels/infiniai.ts | 1 + packages/model-bank/src/aiModels/mistral.ts | 5 + packages/model-bank/src/aiModels/nebius.ts | 1 + packages/model-bank/src/aiModels/novita.ts | 2 + packages/model-bank/src/aiModels/ollama.ts | 1 + .../model-bank/src/aiModels/ollamacloud.ts | 5 + packages/model-bank/src/aiModels/openai.ts | 37 +++ .../src/aiModels/opencodeCodingPlan.ts | 2 + .../model-bank/src/aiModels/opencodeZen.ts | 32 ++- .../model-bank/src/aiModels/openrouter.ts | 26 +- packages/model-bank/src/aiModels/sambanova.ts | 2 +- .../model-bank/src/aiModels/streamlake.ts | 1 + .../model-bank/src/aiModels/togetherai.ts | 1 + .../src/aiModels/vercelaigateway.ts | 38 ++- packages/model-bank/src/aiModels/vertexai.ts | 19 ++ packages/model-bank/src/aiModels/xai.ts | 1 + .../model-bank/src/aiModels/xiaomimimo.ts | 3 + packages/model-bank/src/aiModels/zenmux.ts | 44 +++- packages/model-bank/src/types/aiModel.ts | 6 +- .../openaiCompatibleFactory/index.test.ts | 2 +- .../Electron/navigation/useTabNavigation.ts | 11 +- .../Electron/titlebar/TabBar/TabItem.tsx | 6 +- .../(main)/agent/_layout/AgentIdSync.tsx | 51 ++-- .../MainChatInput/AgentConfigError.tsx | 41 +++ .../Conversation/MainChatInput/index.tsx | 30 ++- .../(main)/home/_layout/HomeAgentIdSync.tsx | 29 ++- src/store/agent/selectors/selectors.ts | 12 + src/store/agent/slices/agent/action.test.ts | 34 +++ src/store/agent/slices/agent/action.ts | 42 ++++ src/store/agent/slices/agent/initialState.ts | 7 + .../__snapshots__/parseModels.test.ts.snap | 2 +- 55 files changed, 1116 insertions(+), 148 deletions(-) create mode 100644 .agents/skills/model-bank-metadata/SKILL.md create mode 100644 .agents/skills/model-bank-metadata/scripts/apply-cutoffs.ts create mode 100644 .agents/skills/model-bank-metadata/scripts/apply-family.ts create mode 100644 .agents/skills/model-bank-metadata/scripts/derive-family.ts create mode 100644 .agents/skills/model-bank-metadata/scripts/extract-model-ids.ts create mode 100644 src/routes/(main)/agent/features/Conversation/MainChatInput/AgentConfigError.tsx diff --git a/.agents/skills/model-bank-metadata/SKILL.md b/.agents/skills/model-bank-metadata/SKILL.md new file mode 100644 index 0000000000..d99bd68683 --- /dev/null +++ b/.agents/skills/model-bank-metadata/SKILL.md @@ -0,0 +1,69 @@ +--- +name: model-bank-metadata +description: 'Backfill and maintain model-bank metadata (knowledgeCutoff, family, generation). Use when adding models, fixing cutoff/family data, running a metadata sweep across aiModels providers, or researching official knowledge cutoffs.' +user-invocable: false +--- + +# Model-Bank Metadata (knowledgeCutoff / family / generation) + +How to populate and maintain the three structured metadata fields on `packages/model-bank/src/aiModels/*.ts` model cards, at single-model scale (new model PR) or repo-wide scale (sweep across \~80 provider files / \~1900 entries). + +## Field semantics + +| Field | Format | Meaning | +| ----------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `knowledgeCutoff` | `'YYYY-MM'` (or `'YYYY'` if only the year is published) | World-knowledge cutoff. When a vendor distinguishes a **"reliable knowledge cutoff"** from the broader training-data cutoff (Anthropic does), always use the **reliable** one. | +| `family` | lowercase slug (`claude`, `gpt`, `o-series`, `qwen`, `deepseek`, `llama`, `glm`, …) | Model lineage, finer than `organization`. Lets the UI group models and match the same model across aggregator providers. | +| `generation` | family slug + version (`claude-4.6`, `gpt-5.2`, `qwen3.5`, `llama-3.1`) | Generation within the family. Only set when confidently derivable from the model line's naming. Rolling aliases (`qwen-max`, `deepseek-chat`, `gemini-flash-latest`) get `family` only. | + +All three are optional. **The cardinal rule: only fill what an authoritative source states or naming rules derive — never guess.** An empty field is correct for vendors that publish nothing. + +No DB migration is ever needed for these: builtin models are merged from model-bank at read time (`repositories/aiInfra/index.ts` spreads the whole card), so new card fields flow to the client automatically. + +## Sourcing rules for knowledgeCutoff + +Accept only: + +- Vendor official docs (platform.openai.com / developers.openai.com, docs.x.ai, ai.google.dev, docs.anthropic.com / platform.claude.com) +- Official Hugging Face org model cards (huggingface.co/meta-llama/..., etc.) +- Official tech reports / system cards / launch blog posts + +Reject: + +- **Third-party aggregator sites** (aiknowledgecutoff.com and similar) — proven to copy one model's value across a whole family. A Cohere sweep once claimed `2024-06` for four distinct base models; none of the cited Cohere pages said that, and the only cutoff Cohere actually publishes is Feb 2023 for the 08-2024 Command R/R+ refresh. +- **AWS Bedrock model cards as sole source** — proven to conflate launch date with knowledge cutoff (DeepSeek R1's card lists both as "Jan 2025"). If Bedrock is the only place a value appears, leave the field empty. +- Inference from `releasedAt` — a release date is not a cutoff. + +Variant inheritance: dated snapshots (`-2024-08-06`), speed/price tiers of the same checkpoint, quantizations (`-fp8`, `-awq`), context-length variants (`-32k`), ollama `:NNb` tags, and cloud-prefixed ids (`anthropic.`/`us.`/`global.` Bedrock ids) share their base model's cutoff. **Distills do not inherit** from teacher or base — use the distill's own published value or leave empty. **Sizes within one generation can genuinely differ**: Llama 3 8B is Mar 2023 while 70B is Dec 2023 (per Meta's own card) — don't "fix" that to one family-wide value. + +Vendors that publish no cutoffs (leave empty, don't chase): Qwen, DeepSeek, GLM/Zhipu, ERNIE, Doubao, Hunyuan, SenseNova, Spark, MiniMax, StepFun, Yi (mostly), Moonshot. + +Known per-vendor footguns: + +- **Anthropic**: Opus 4.6 reliable cutoff is `2025-05`, Sonnet 4.6 is `2025-08` — easy to swap. Claude 3.7 is `2024-10` (system card: trained through Nov 2024, knowledge cutoff end of Oct 2024). Cite system cards / the models overview, not the Help Center article (a living page that drops retired models — citation rot). +- **xAI**: docs.x.ai has one blanket sentence covering grok-3/grok-4; mini variants are not named there. Grok 4.20/4.3 have no official cutoff anywhere. +- **OpenAI**: per-model docs pages (developers.openai.com/api/docs/models/) state cutoffs explicitly, including snapshot differences (gpt-4-1106-preview `2023-04` vs gpt-4-0125-preview `2023-12`). + +## family/generation derivation + +Rule-based, no research needed: `scripts/derive-family.ts` holds the per-family regex rules. Traps already encoded there — keep them when extending: + +- Date suffixes are not versions: `claude-sonnet-4-20250514` is generation `claude-4`, not `claude-4.2`. +- Size suffixes are not versions: `llama-3-8b` → `llama-3` (not `llama-3.8`); `gemma-7b-it` is **gemma-1** (not gemma-7). +- Vendor spelling variants: `qwen2p5` = qwen2.5, `llama-v3p1` = llama-3.1, ollama `:NNb` tags, Bedrock `us.`/`global.`/`anthropic.` prefixes. +- `claude-X.0` normalizes to `claude-X`. +- Fable/Mythos-class ids (`claude-fable-5`) don't match the opus/sonnet/haiku regex — they are the Mythos class — `family: 'claude-mythos'`, `generation: 'mythos-5'` (set manually; the launch page calls Fable 5 "the generally available Mythos-class model"). + +## Repo-wide sweep workflow + +1. **Extract ids**: `bun .agents/skills/model-bank-metadata/scripts/extract-model-ids.ts` → unique normalized chat-model ids (normalization = last path segment, lowercased). Non-chat types (image/video/embedding/tts) have no knowledge cutoff — skip them. +2. **Research (multi-agent)**: chunk ids by family (≤50 per chunk) and fan out one research agent per chunk (Workflow tool), each returning `{id, cutoff, source}` with the sourcing rules above baked into the prompt, **plus** one adversarial verify agent per chunk that re-fetches cited sources and refutes unsupported claims. The verify pass is load-bearing: it caught the Cohere aggregator copy-paste and the AWS launch-date conflation. +3. **Policy filter**: before applying, drop entries whose only source is a rejected category (check the returned `sources` map — e.g. drop everything sourced to aws.amazon.com). +4. **Apply**: `bun scripts/apply-cutoffs.ts ` and `bun scripts/apply-family.ts ` (run from repo root). Both are idempotent codemods keyed on normalized id — aggregator providers get the same values automatically; entries that already have the field are skipped. They rely on the uniform prettier formatting of the data files (entries start ` {` / end ` },`, fields at 4-space indent). +5. **Verify**: `cd packages/model-bank && bunx vitest run src/aiModels/__tests__/index.test.ts && bunx tsc --noEmit`. + +## Maintenance rules + +- **New model PRs** should fill all three fields inline, citing the official source in the PR body (see the Anthropic entries in `anthropic.ts` for reference values). +- **After resolving merge conflicts** in model-bank data files, sanity-check that metadata didn't vanish: `git grep -c knowledgeCutoff -- 'packages/model-bank/src/aiModels/*.ts'` before vs after. A three-way stack of model PRs once silently dropped all 10 Anthropic cutoffs during conflict resolution. +- Dirty ids exist in aggregator data (a sambanova id once carried a trailing tab). The codemods match ids verbatim — if a map key won't apply, check for invisible characters before assuming the model is missing. diff --git a/.agents/skills/model-bank-metadata/scripts/apply-cutoffs.ts b/.agents/skills/model-bank-metadata/scripts/apply-cutoffs.ts new file mode 100644 index 0000000000..02e35b0126 --- /dev/null +++ b/.agents/skills/model-bank-metadata/scripts/apply-cutoffs.ts @@ -0,0 +1,73 @@ +/** + * One-off codemod: apply a canonical { normalizedModelId: 'YYYY-MM' } map onto + * packages/model-bank/src/aiModels/*.ts, inserting `knowledgeCutoff` after the + * `id:` line of every chat-model entry that matches and doesn't already have one. + * + * Relies on the uniform prettier formatting of these files: + * - each model entry starts with ` {` and ends with ` },` (2-space indent) + * - fields are at 4-space indent: ` id: '...'`, ` type: 'chat'` + * + * Usage: bun /tmp/apply-cutoffs.ts /tmp/cutoff-map.json + */ +import { readdirSync, readFileSync, writeFileSync } from 'node:fs'; +import { join } from 'node:path'; + +const mapPath = process.argv[2]; +if (!mapPath) throw new Error('usage: bun apply-cutoffs.ts '); +const map: Record = JSON.parse(readFileSync(mapPath, 'utf8')); + +const dir = 'packages/model-bank/src/aiModels'; +const normalize = (id: string) => id.split('/').pop()!.toLowerCase(); + +let touchedFiles = 0; +let inserted = 0; +const matchedIds = new Set(); + +for (const file of readdirSync(dir).filter((f) => f.endsWith('.ts'))) { + const path = join(dir, file); + const lines = readFileSync(path, 'utf8').split('\n'); + const out: string[] = []; + let changed = false; + + let i = 0; + while (i < lines.length) { + if (lines[i] !== ' {') { + out.push(lines[i]); + i++; + continue; + } + // collect one model entry block + const start = i; + let end = i; + while (end < lines.length && lines[end] !== ' },') end++; + const block = lines.slice(start, end + 1); + + const idLineIdx = block.findIndex((l) => /^ {4}id: '/.test(l)); + const isChat = block.some((l) => /^ {4}type: 'chat',?$/.test(l)); + const hasCutoff = block.some((l) => /^ {4}knowledgeCutoff:/.test(l)); + + if (idLineIdx >= 0 && isChat && !hasCutoff) { + const rawId = block[idLineIdx].match(/^ {4}id: '(.+)',$/)?.[1]; + const norm = rawId ? normalize(rawId) : undefined; + const cutoff = norm ? map[norm] : undefined; + if (cutoff && /^\d{4}(?:-\d{2})?$/.test(cutoff)) { + block.splice(idLineIdx + 1, 0, ` knowledgeCutoff: '${cutoff}',`); + inserted++; + changed = true; + matchedIds.add(norm!); + } + } + out.push(...block); + i = end + 1; + } + + if (changed) { + writeFileSync(path, out.join('\n')); + touchedFiles++; + } +} + +console.log(`inserted ${inserted} knowledgeCutoff fields across ${touchedFiles} files`); +console.log(`map ids used: ${matchedIds.size}/${Object.keys(map).length}`); +const unused = Object.keys(map).filter((k) => !matchedIds.has(k)); +if (unused.length) console.log('unused map keys (first 20):', unused.slice(0, 20)); diff --git a/.agents/skills/model-bank-metadata/scripts/apply-family.ts b/.agents/skills/model-bank-metadata/scripts/apply-family.ts new file mode 100644 index 0000000000..9975f2aaae --- /dev/null +++ b/.agents/skills/model-bank-metadata/scripts/apply-family.ts @@ -0,0 +1,49 @@ +import { readdirSync, readFileSync, writeFileSync } from 'node:fs'; +import { join } from 'node:path'; + +const map: Record = JSON.parse( + readFileSync('/tmp/family-map.json', 'utf8'), +); +const dir = 'packages/model-bank/src/aiModels'; +const normalize = (id: string) => id.split('/').pop()!.toLowerCase(); + +let inserted = 0; +let touchedFiles = 0; +for (const file of readdirSync(dir).filter((f) => f.endsWith('.ts'))) { + const path = join(dir, file); + const lines = readFileSync(path, 'utf8').split('\n'); + const out: string[] = []; + let changed = false; + let i = 0; + while (i < lines.length) { + if (lines[i] !== ' {') { + out.push(lines[i]); + i++; + continue; + } + let end = i; + while (end < lines.length && lines[end] !== ' },') end++; + const block = lines.slice(i, end + 1); + const idLineIdx = block.findIndex((l) => /^ {4}id: '/.test(l)); + const isChat = block.some((l) => /^ {4}type: 'chat',?$/.test(l)); + const hasFamily = block.some((l) => /^ {4}family:/.test(l)); + if (idLineIdx >= 0 && isChat && !hasFamily) { + const rawId = block[idLineIdx].match(/^ {4}id: '(.+)',$/)?.[1]; + const r = rawId ? map[normalize(rawId)] : undefined; + if (r) { + const add = [` family: '${r.family}',`]; + if (r.generation) add.push(` generation: '${r.generation}',`); + block.splice(idLineIdx, 0, ...add); + inserted++; + changed = true; + } + } + out.push(...block); + i = end + 1; + } + if (changed) { + writeFileSync(path, out.join('\n')); + touchedFiles++; + } +} +console.log(`annotated ${inserted} model entries across ${touchedFiles} files`); diff --git a/.agents/skills/model-bank-metadata/scripts/derive-family.ts b/.agents/skills/model-bank-metadata/scripts/derive-family.ts new file mode 100644 index 0000000000..6d5c654890 --- /dev/null +++ b/.agents/skills/model-bank-metadata/scripts/derive-family.ts @@ -0,0 +1,237 @@ +/* eslint-disable regexp/no-unused-capturing-group */ +/** + * Rule-based derivation of { family, generation } from normalized model ids. + * Principle: only fill what is confidently derivable; otherwise omit. + * + * Usage: bun /tmp/derive-family.ts # print distinct pairs for review + * bun /tmp/derive-family.ts --emit # write /tmp/family-map.json + */ +import { readFileSync, writeFileSync } from 'node:fs'; + +const ids: string[] = JSON.parse(readFileSync('/tmp/model-ids.json', 'utf8')); + +type R = { family: string; generation?: string }; + +const derive = (id: string): R | undefined => { + // strip cloud/bedrock prefixes for matching + const m = id.replace(/^(us\.|global\.|eu\.|apac\.)?(anthropic\.|meta\.|cohere\.|azure-)/, ''); + + // ---- anthropic ---- + if (m.startsWith('claude')) { + // family = product-line tier (claude-opus/sonnet/haiku/instant); bare claude-2.x has no tier + const tier = m.match(/(opus|sonnet|haiku|instant)/)?.[1]; + const family = tier ? `claude-${tier}` : 'claude'; + let g = m.match(/^claude-(?:opus|sonnet|haiku)-(\d)[.-](\d)(?!\d)/); // claude-opus-4-8 / claude-haiku-4.5 + if (g) return { family, generation: `claude-${g[1]}.${g[2]}` }; + g = m.match(/^claude-(?:opus|sonnet|haiku)-(\d)(?!\d)/); // claude-opus-4 + if (g) return { family, generation: `claude-${g[1]}` }; + g = m.match(/^claude-(\d)[.-](\d)(?!\d)/); // claude-3-5-haiku / claude-3.7-sonnet / claude-2.1 + if (g) return { family, generation: g[2] === '0' ? `claude-${g[1]}` : `claude-${g[1]}.${g[2]}` }; + g = m.match(/^claude-(\d)(?!\d)/); // claude-3-haiku + if (g) return { family, generation: `claude-${g[1]}` }; + if (m.startsWith('claude-instant')) return { family: 'claude-instant' }; + if (/^claude-v?2/.test(m)) return { family: 'claude', generation: 'claude-2' }; + return { family }; + } + + // ---- openai ---- + if (/^(gpt-oss|gpt_oss)/.test(m) || m.startsWith('gpt-oss:')) + return { family: 'gpt-oss', generation: 'gpt-oss' }; + if (/^(chatgpt-4o|gpt-4o)/.test(m)) return { family: 'gpt', generation: 'gpt-4o' }; + if (/^gpt-(3\.5|35)/.test(m)) return { family: 'gpt', generation: 'gpt-3.5' }; + if (m.startsWith('gpt-audio')) return { family: 'gpt', generation: 'gpt-audio' }; + { + const g = m.match(/^gpt-(\d)\.(\d)/); // gpt-4.1 / gpt-5.2 + if (g) return { family: 'gpt', generation: `gpt-${g[1]}.${g[2]}` }; + const g2 = m.match(/^gpt-(\d)(?!\d)/); // gpt-4 / gpt-5 + if (g2) return { family: 'gpt', generation: `gpt-${g2[1]}` }; + } + { + const g = m.match(/^o([134])(-|$)/); // o1 / o3 / o4 + if (g) return { family: 'o-series', generation: `o${g[1]}` }; + } + if (/^(codex|computer-use-preview)/.test(m)) return { family: 'gpt' }; + + // ---- google ---- + { + const g = m.match(/^gemini-(\d+(?:\.\d+)?)/); + if (g) return { family: 'gemini', generation: `gemini-${g[1]}` }; + if (/^gemini-(pro|flash)/.test(m)) return { family: 'gemini' }; // rolling aliases + if (m.startsWith('gemma')) { + if (/^gemma-?\db/.test(m)) return { family: 'gemma', generation: 'gemma-1' }; + const v = m.match(/^gemma-?(\d)(?!b)/); + return { family: 'gemma', generation: v ? `gemma-${v[1]}` : undefined }; + } + if (/^(codegemma|learnlm|palm)/.test(m)) return { family: m.match(/^[a-z]+/)![0] }; + } + + // ---- qwen ---- + if (m.startsWith('qwq')) return { family: 'qwen', generation: 'qwq' }; + if (m.startsWith('qvq')) return { family: 'qwen', generation: 'qvq' }; + if (m.startsWith('codeqwen')) return { family: 'qwen' }; + if (m.startsWith('qwen')) { + const g = + m.match(/^qwen-?([123](?:\.\d+)?)(?![0-9b])/) || // qwen3.5-plus / qwen-3-14b / qwen2-7b / qwen1.5 + m.match(/^qwen([23](?:\.\d+)?):/) || // qwen2.5:72b + m.match(/^qwen([23])p(\d)/); // qwen2p5 -> handled below + if (/^qwen(\d)p(\d)/.test(m)) { + const p = m.match(/^qwen(\d)p(\d)/)!; + return { family: 'qwen', generation: `qwen${p[1]}.${p[2]}` }; + } + if (g) return { family: 'qwen', generation: `qwen${g[1]}` }; + return { family: 'qwen' }; // qwen-max/plus/turbo/vl rolling aliases + } + + // ---- deepseek ---- + if (/^(deepseek|azure-deepseek|pro-deepseek)/.test(m) || m.startsWith('deepseek_')) { + const s = m.replace(/^pro-/, '').replaceAll('_', '-'); + if (s.startsWith('deepseek-r1-distill')) + return { family: 'deepseek', generation: 'deepseek-r1-distill' }; + if (s.startsWith('deepseek-r1')) return { family: 'deepseek', generation: 'deepseek-r1' }; + const g = s.match(/^deepseek-(?:chat-)?v(\d(?:\.\d)?)/); + if (g) return { family: 'deepseek', generation: `deepseek-v${g[1]}` }; + if (/^deepseek-(coder-v2|coder)/.test(s)) + return { family: 'deepseek', generation: 'deepseek-coder' }; + return { family: 'deepseek' }; // deepseek-chat / reasoner rolling aliases + } + + // ---- meta llama ---- + if (m.startsWith('codellama')) return { family: 'llama', generation: 'codellama' }; + if (/^(meta-)?llama|^l3(\d)?-|^llava/.test(m)) { + if (m.startsWith('llava')) return { family: 'llava' }; + const s = m.replace(/^meta-/, ''); + const g = + s.match(/^llama-?([234])(?:[.-](\d))?(?![0-9b])/) || // llama-3.1 / llama3.3 / llama-4 + s.match(/^llama-?v([234])p?(\d)?/) || // llama-v3p1 + s.match(/^llama([234])[.:-](\d)?/); + if (g) { + const gen = g[2] ? `llama-${g[1]}.${g[2]}` : `llama-${g[1]}`; + return { family: 'llama', generation: gen }; + } + if (m.startsWith('l3-')) return { family: 'llama', generation: 'llama-3' }; + if (m.startsWith('l31-')) return { family: 'llama', generation: 'llama-3.1' }; + return { family: 'llama' }; + } + + // ---- zhipu ---- + if (/^(zai-)?glm/.test(m)) { + const s = m.replace(/^zai-/, ''); + if (s.startsWith('glm-z1')) return { family: 'glm', generation: 'glm-z1' }; + if (s.startsWith('glm-zero')) return { family: 'glm', generation: 'glm-zero' }; + const g = s.match(/^glm-(\d(?:\.\d)?)/); + if (g) return { family: 'glm', generation: `glm-${g[1]}` }; + return { family: 'glm' }; + } + if (/^(charglm|codegeex|emohaa)/.test(m)) return { family: m.match(/^[a-z]+/)![0] }; + + // ---- mistral ---- + if ( + /^(open-)?(mistral|mixtral|ministral|codestral|devstral|magistral|pixtral|mathstral|labs-devstral|labs-leanstral|open-codestral)/.test( + m, + ) + ) { + const fam = m.replace(/^(open-|labs-)/, '').match(/^[a-z]+/)![0]; + return { family: fam }; + } + + // ---- xai ---- + if (m.startsWith('grok')) { + const g = m.match(/^grok-(\d(?:\.\d+)?)/); + return { family: 'grok', generation: g ? `grok-${g[1]}` : undefined }; + } + + // ---- moonshot ---- + if (m.startsWith('kimi')) { + const g = m.match(/^kimi-k(\d(?:\.\d)?)/); + return { family: 'kimi', generation: g ? `kimi-k${g[1]}` : undefined }; + } + if (m.startsWith('moonshot-kimi-k2')) return { family: 'kimi', generation: 'kimi-k2' }; + if (m.startsWith('moonshot-v1')) return { family: 'kimi', generation: 'moonshot-v1' }; + + // ---- minimax ---- + if (m.startsWith('minimax')) { + if (m.startsWith('minimax-text')) return { family: 'minimax', generation: 'minimax-text-01' }; + const g = m.match(/^minimax-m(\d(?:\.\d)?)/); + return { family: 'minimax', generation: g ? `minimax-m${g[1]}` : undefined }; + } + if (m.startsWith('abab')) return { family: 'minimax', generation: 'abab' }; + + // ---- baidu ---- + if (m.startsWith('ernie')) { + if (m.startsWith('ernie-x1')) return { family: 'ernie', generation: 'ernie-x1' }; + const g = m.match(/^ernie-(\d\.\d)/); + return { family: 'ernie', generation: g ? `ernie-${g[1]}` : undefined }; + } + if (m.startsWith('qianfan')) return { family: 'qianfan' }; + + // ---- bytedance ---- + if (m.startsWith('doubao')) { + const g = m.match(/^doubao-seed-(\d[.-]\d|\d)/) || m.match(/^doubao-(\d\.\d)/); + return { family: 'doubao', generation: g ? `doubao-${g[1].replace('-', '.')}` : undefined }; + } + if (/^(seed-oss|skylark)/.test(m)) return { family: m.startsWith('seed') ? 'doubao' : 'skylark' }; + + // ---- tencent ---- + if (m.startsWith('hunyuan')) { + const g = m.match(/^hunyuan-(\d\.\d)/); + return { family: 'hunyuan', generation: g ? `hunyuan-${g[1]}` : undefined }; + } + if (m.startsWith('hy3')) return { family: 'hunyuan', generation: 'hunyuan-3' }; + + // ---- others (family only / simple version) ---- + if (m.startsWith('yi-')) return { family: 'yi' }; + if (/^(command|c4ai-command)/.test(m)) return { family: 'command' }; + if (/^(aya|c4ai-aya)/.test(m)) return { family: 'aya' }; + if (/^phi-?(\d)?/.test(m) && m.startsWith('phi')) { + const g = m.match(/^phi-?(\d(?:\.\d)?)/); + return { family: 'phi', generation: g ? `phi-${g[1]}` : undefined }; + } + if (m.startsWith('wizardlm')) return { family: 'wizardlm' }; + if (m.startsWith('step-')) { + const g = m.match(/^step-(?:r1|(\d(?:\.\d)?))/); + return { family: 'step', generation: g?.[1] ? `step-${g[1]}` : undefined }; + } + if (/^(internlm|intern-)/.test(m)) return { family: 'intern' }; + if (m.startsWith('internvl')) return { family: 'internvl' }; + if (m.startsWith('baichuan')) { + const g = m.match(/^baichuan-?(m?\d)/); + return { family: 'baichuan', generation: g ? `baichuan-${g[1]}` : undefined }; + } + if (/^(sensechat|sensenova)/.test(m)) return { family: 'sensenova' }; + if (/^(spark|generalv|4\.0ultra)/.test(m)) return { family: 'spark' }; + if (/^(360gpt|360zhinao)/.test(m)) return { family: '360zhinao' }; + if (/^(jamba|ai21-jamba)/.test(m)) return { family: 'jamba' }; + if (m.startsWith('sonar')) return { family: 'sonar' }; + if (/^(nova-lite|nova-micro|nova-pro)/.test(m)) return { family: 'nova' }; + if (/^(ling|ring)-/.test(m)) return { family: m.match(/^[a-z]+/)![0] }; + if (m.startsWith('longcat')) return { family: 'longcat' }; + if (m.startsWith('mimo')) return { family: 'mimo' }; + if (m.startsWith('taichu')) return { family: 'taichu' }; + if (/^(hermes|nous-hermes)/.test(m)) return { family: 'hermes' }; + if (m.startsWith('solar')) return { family: 'solar' }; + if (m.startsWith('kat-coder')) return { family: 'kat-coder' }; + if (m.startsWith('dbrx')) return { family: 'dbrx' }; + if (m.startsWith('morph')) return { family: 'morph' }; + + return undefined; +}; + +const map: Record = {}; +const pairs = new Map(); +let derived = 0; +for (const id of ids) { + const r = derive(id); + if (!r) continue; + derived++; + map[id] = r; + const key = `${r.family} :: ${r.generation ?? '—'}`; + pairs.set(key, (pairs.get(key) || 0) + 1); +} + +console.log(`derived ${derived}/${ids.length}`); +for (const [k, n] of [...pairs.entries()].sort()) console.log(String(n).padStart(4), k); + +if (process.argv.includes('--emit')) { + writeFileSync('/tmp/family-map.json', JSON.stringify(map, null, 1)); + console.log('\nwritten /tmp/family-map.json'); +} diff --git a/.agents/skills/model-bank-metadata/scripts/extract-model-ids.ts b/.agents/skills/model-bank-metadata/scripts/extract-model-ids.ts new file mode 100644 index 0000000000..8d87f00e0c --- /dev/null +++ b/.agents/skills/model-bank-metadata/scripts/extract-model-ids.ts @@ -0,0 +1,23 @@ +/** + * Extract unique normalized chat-model ids from packages/model-bank/src/aiModels/*.ts. + * Normalization: last path segment, lowercased (matches the apply codemods). + * + * Usage (repo root): bun .agents/skills/model-bank-metadata/scripts/extract-model-ids.ts [out.json] + * Default output: /tmp/model-ids.json + */ +import { readdirSync, writeFileSync } from 'node:fs'; +import { join, resolve } from 'node:path'; + +const dir = resolve('packages/model-bank/src/aiModels'); +const out = process.argv[2] || '/tmp/model-ids.json'; + +const ids = new Set(); +for (const f of readdirSync(dir).filter((f) => f.endsWith('.ts'))) { + const mod = await import(join(dir, f)); + for (const m of mod.default || []) { + if (!m?.id || m.type !== 'chat') continue; + ids.add(m.id.split('/').pop()!.toLowerCase()); + } +} +writeFileSync(out, JSON.stringify([...ids].sort(), null, 1)); +console.log(`${ids.size} unique normalized chat ids -> ${out}`); diff --git a/apps/server/src/routers/lambda/config/__snapshots__/index.test.ts.snap b/apps/server/src/routers/lambda/config/__snapshots__/index.test.ts.snap index 3d081cee25..fac0ccf136 100644 --- a/apps/server/src/routers/lambda/config/__snapshots__/index.test.ts.snap +++ b/apps/server/src/routers/lambda/config/__snapshots__/index.test.ts.snap @@ -34,7 +34,7 @@ exports[`configRouter > getGlobalConfig > Model Provider env > OPENAI_MODEL_LIST "family": "gpt", "generation": "gpt-4", "id": "gpt-4-0125-preview", - "knowledgeCutoff": undefined, + "knowledgeCutoff": "2023-12", "pricing": { "units": [ { @@ -72,7 +72,7 @@ exports[`configRouter > getGlobalConfig > Model Provider env > OPENAI_MODEL_LIST "family": "gpt", "generation": "gpt-3.5", "id": "gpt-3.5-turbo-1106", - "knowledgeCutoff": undefined, + "knowledgeCutoff": "2021-09", "pricing": { "units": [ { @@ -137,7 +137,7 @@ exports[`configRouter > getGlobalConfig > Model Provider env > OPENAI_MODEL_LIST "family": "gpt", "generation": "gpt-4", "id": "gpt-4", - "knowledgeCutoff": "2023-12", + "knowledgeCutoff": "2021-09", "pricing": { "units": [ { @@ -169,7 +169,7 @@ exports[`configRouter > getGlobalConfig > Model Provider env > OPENAI_MODEL_LIST "family": "gpt", "generation": "gpt-4", "id": "gpt-4-32k", - "knowledgeCutoff": undefined, + "knowledgeCutoff": "2021-09", "pricing": { "units": [ { @@ -201,7 +201,7 @@ exports[`configRouter > getGlobalConfig > Model Provider env > OPENAI_MODEL_LIST "family": "gpt", "generation": "gpt-4", "id": "gpt-4-1106-preview", - "knowledgeCutoff": undefined, + "knowledgeCutoff": "2023-04", "pricing": { "units": [ { @@ -244,7 +244,7 @@ exports[`configRouter > getGlobalConfig > Model Provider env > OPENAI_MODEL_LIST "family": "gpt", "generation": "gpt-4", "id": "gpt-4-1106-preview", - "knowledgeCutoff": undefined, + "knowledgeCutoff": "2023-04", "pricing": { "units": [ { diff --git a/locales/en-US/chat.json b/locales/en-US/chat.json index f93f595c18..625054b879 100644 --- a/locales/en-US/chat.json +++ b/locales/en-US/chat.json @@ -15,6 +15,8 @@ "agentBuilder.installPlugin.retry": "Retry", "agentBuilder.title": "Agent Builder", "agentBuilder.welcome": "Tell me your use case.\n\nWriting, coding, or data analysis—anything works. You own the goal and standards; I’ll break it down into collaborative, runnable Agents.", + "agentConfigError.retry": "Retry", + "agentConfigError.title": "Failed to load agent settings", "agentDefaultMessage": "Hi, I’m **{{name}}**. One sentence is enough.\n\nWant me to match your workflow better? Go to [Agent Settings]({{url}}) and fill in the Agent Profile (you can edit it anytime).", "agentDefaultMessageWithSystemRole": "Hi, I’m **{{name}}**. One sentence is enough—you're in control.", "agentDefaultMessageWithoutEdit": "Hi, I’m **{{name}}**. One sentence is enough—you're in control.", diff --git a/locales/zh-CN/chat.json b/locales/zh-CN/chat.json index 7f26dffbab..7b7790212c 100644 --- a/locales/zh-CN/chat.json +++ b/locales/zh-CN/chat.json @@ -15,6 +15,8 @@ "agentBuilder.installPlugin.retry": "重试", "agentBuilder.title": "助理构建专家", "agentBuilder.welcome": "先说说你的使用场景吧。\n\n写作、编程、数据分析都可以——你负责目标与标准,我来帮你把想法拆成可协作、可运行的助理。", + "agentConfigError.retry": "重试", + "agentConfigError.title": "助理配置加载失败", "agentDefaultMessage": "你好,我是 **{{name}}**。从一句话开始就行。\n\n想让我更贴近你的工作方式:去 [助理设置]({{url}}) 补充助理档案(随时可改)", "agentDefaultMessageWithSystemRole": "你好,我是 **{{name}}**。从一句话开始就行——决定权在你", "agentDefaultMessageWithoutEdit": "你好,我是 **{{name}}**。从一句话开始就行——决定权在你", diff --git a/packages/locales/src/default/chat.ts b/packages/locales/src/default/chat.ts index 5470cf8dda..1d59b5f4c9 100644 --- a/packages/locales/src/default/chat.ts +++ b/packages/locales/src/default/chat.ts @@ -20,6 +20,8 @@ export default { 'agentBuilder.title': 'Agent Builder', 'agentBuilder.welcome': 'Tell me your use case.\n\nWriting, coding, or data analysis—anything works. You own the goal and standards; I’ll break it down into collaborative, runnable Agents.', + 'agentConfigError.retry': 'Retry', + 'agentConfigError.title': 'Failed to load agent settings', 'agentDefaultMessage': 'Hi, I’m **{{name}}**. One sentence is enough.\n\nWant me to match your workflow better? Go to [Agent Settings]({{url}}) and fill in the Agent Profile (you can edit it anytime).', 'agentDefaultMessageWithSystemRole': diff --git a/packages/model-bank/src/aiModels/ai21.ts b/packages/model-bank/src/aiModels/ai21.ts index 31f11e19bf..fc45db18d7 100644 --- a/packages/model-bank/src/aiModels/ai21.ts +++ b/packages/model-bank/src/aiModels/ai21.ts @@ -12,6 +12,7 @@ const ai21ChatModels: AIChatModelCard[] = [ enabled: true, family: 'jamba', id: 'jamba-mini', + knowledgeCutoff: '2024-08', pricing: { units: [ { name: 'textInput', rate: 0.2, strategy: 'fixed', unit: 'millionTokens' }, @@ -32,6 +33,7 @@ const ai21ChatModels: AIChatModelCard[] = [ enabled: true, family: 'jamba', id: 'jamba-large', + knowledgeCutoff: '2024-08', pricing: { units: [ { name: 'textInput', rate: 2, strategy: 'fixed', unit: 'millionTokens' }, diff --git a/packages/model-bank/src/aiModels/ai302.ts b/packages/model-bank/src/aiModels/ai302.ts index 49486afc98..c6da23c70a 100644 --- a/packages/model-bank/src/aiModels/ai302.ts +++ b/packages/model-bank/src/aiModels/ai302.ts @@ -16,6 +16,7 @@ const ai302ChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'chatgpt-4o-latest', + knowledgeCutoff: '2023-10', type: 'chat', }, { @@ -43,13 +44,14 @@ const ai302ChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'gemini-2.0-flash', + knowledgeCutoff: '2024-08', type: 'chat', }, { contextWindowTokens: 200_000, displayName: 'claude-3-7-sonnet-20250219', enabled: true, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.7', id: 'claude-3-7-sonnet-20250219', knowledgeCutoff: '2024-10', @@ -59,7 +61,7 @@ const ai302ChatModels: AIChatModelCard[] = [ contextWindowTokens: 200_000, displayName: 'claude-3-7-sonnet-latest', enabled: true, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.7', id: 'claude-3-7-sonnet-latest', knowledgeCutoff: '2024-10', @@ -72,6 +74,7 @@ const ai302ChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'grok-3-beta', + knowledgeCutoff: '2024-11', type: 'chat', }, { @@ -81,6 +84,7 @@ const ai302ChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'grok-3-mini-beta', + knowledgeCutoff: '2024-11', type: 'chat', }, { @@ -90,6 +94,7 @@ const ai302ChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1', + knowledgeCutoff: '2024-06', type: 'chat', }, { @@ -137,6 +142,7 @@ const ai302ChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-pro-preview-05-06', + knowledgeCutoff: '2025-01', type: 'chat', }, { @@ -156,13 +162,14 @@ const ai302ChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash', + knowledgeCutoff: '2025-01', type: 'chat', }, { contextWindowTokens: 200_000, displayName: 'claude-sonnet-4-20250514', enabled: true, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4', id: 'claude-sonnet-4-20250514', knowledgeCutoff: '2025-01', @@ -172,7 +179,7 @@ const ai302ChatModels: AIChatModelCard[] = [ contextWindowTokens: 200_000, displayName: 'claude-opus-4-20250514', enabled: true, - family: 'claude', + family: 'claude-opus', generation: 'claude-4', id: 'claude-opus-4-20250514', knowledgeCutoff: '2025-01', @@ -185,6 +192,7 @@ const ai302ChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-pro', + knowledgeCutoff: '2025-01', type: 'chat', }, ]; diff --git a/packages/model-bank/src/aiModels/aihubmix.ts b/packages/model-bank/src/aiModels/aihubmix.ts index ff2436ba65..7b616b785f 100644 --- a/packages/model-bank/src/aiModels/aihubmix.ts +++ b/packages/model-bank/src/aiModels/aihubmix.ts @@ -81,6 +81,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.4', id: 'gpt-5.4', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -256,6 +257,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.3', id: 'gpt-5.3-chat-latest', + knowledgeCutoff: '2025-08', maxOutput: 16_384, pricing: { units: [ @@ -282,6 +284,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -311,6 +314,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2-pro', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -337,6 +341,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2-chat-latest', + knowledgeCutoff: '2025-08', maxOutput: 16_384, pricing: { units: [ @@ -363,6 +368,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -389,6 +395,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1-chat-latest', + knowledgeCutoff: '2024-09', maxOutput: 16_384, pricing: { units: [ @@ -415,6 +422,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1-codex', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -445,6 +453,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1-codex-mini', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -474,6 +483,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-pro', + knowledgeCutoff: '2024-09', maxOutput: 272_000, pricing: { units: [ @@ -502,6 +512,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-codex', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -532,6 +543,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -562,6 +574,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-mini', + knowledgeCutoff: '2024-05', maxOutput: 128_000, pricing: { units: [ @@ -590,6 +603,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-nano', + knowledgeCutoff: '2024-05', maxOutput: 128_000, pricing: { units: [ @@ -617,6 +631,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-chat-latest', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -790,6 +805,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -816,6 +832,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1-mini', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -841,6 +858,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1-nano', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -863,6 +881,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'chatgpt-4o-latest', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 5, strategy: 'fixed', unit: 'millionTokens' }, @@ -969,6 +988,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'grok-3', + knowledgeCutoff: '2024-11', pricing: { units: [ { name: 'textInput', rate: 3, strategy: 'fixed', unit: 'millionTokens' }, @@ -991,6 +1011,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'grok-3-mini', + knowledgeCutoff: '2024-11', pricing: { units: [ { name: 'textInput', rate: 0.3, strategy: 'fixed', unit: 'millionTokens' }, @@ -1016,7 +1037,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ "Claude Opus 4.7 is Anthropic's most capable generally available model for complex reasoning and agentic coding.", displayName: 'Claude Opus 4.7', enabled: true, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.7', id: 'claude-opus-4-7', knowledgeCutoff: '2026-01', @@ -1048,7 +1069,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.6 is Anthropic’s most intelligent model for building agents and coding.', displayName: 'Claude Opus 4.6', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.6', id: 'claude-opus-4-6', knowledgeCutoff: '2025-05', @@ -1085,7 +1106,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.5 is Anthropic’s flagship model, combining top-tier intelligence with scalable performance for complex, high-quality reasoning tasks.', displayName: 'Claude Opus 4.5', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.5', id: 'claude-opus-4-5-20251101', knowledgeCutoff: '2025-05', @@ -1122,7 +1143,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.1 is Anthropic’s newest and most powerful model for highly complex tasks, excelling in performance, intelligence, fluency, and comprehension.', displayName: 'Claude Opus 4.1', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.1', id: 'claude-opus-4-1-20250805', knowledgeCutoff: '2025-01', @@ -1159,7 +1180,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4 is Anthropic’s most powerful model for highly complex tasks, excelling in performance, intelligence, fluency, and comprehension.', displayName: 'Claude Opus 4', - family: 'claude', + family: 'claude-opus', generation: 'claude-4', id: 'claude-opus-4-20250514', knowledgeCutoff: '2025-01', @@ -1196,7 +1217,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4.6 is Anthropic’s best combination of speed and intelligence.', displayName: 'Claude Sonnet 4.6', enabled: true, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.6', id: 'claude-sonnet-4-6', knowledgeCutoff: '2025-05', @@ -1239,7 +1260,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ description: 'Sonnet 4.5 is the world’s best model for agents, coding, and computer use. It is also our most accurate and detailed model on long-running tasks, with enhanced knowledge in coding, finance, and cybersecurity.', displayName: 'Claude Sonnet 4.5', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.5', id: 'claude-sonnet-4-5-20250929', knowledgeCutoff: '2025-01', @@ -1275,7 +1296,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4 can produce near-instant responses or extended step-by-step reasoning that users can see. API users can finely control how long the model thinks.', displayName: 'Claude Sonnet 4', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4', id: 'claude-sonnet-4-20250514', knowledgeCutoff: '2025-01', @@ -1311,7 +1332,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ description: 'Claude 3.7 Sonnet is Anthropic’s most intelligent model and the first hybrid reasoning model on the market. It can produce near-instant responses or extended step-by-step reasoning that users can see. Sonnet is especially strong at coding, data science, vision, and agent tasks.', displayName: 'Claude 3.7 Sonnet', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.7', id: 'claude-3-7-sonnet-20250219', knowledgeCutoff: '2024-10', @@ -1349,7 +1370,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ 'Claude Haiku 4.5 is Anthropic’s fastest and smartest Haiku model, with lightning speed and extended reasoning.', displayName: 'Claude Haiku 4.5', enabled: true, - family: 'claude', + family: 'claude-haiku', generation: 'claude-4.5', id: 'claude-haiku-4-5-20251001', knowledgeCutoff: '2025-02', @@ -1383,7 +1404,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ description: 'Claude 3.5 Haiku is Anthropic’s fastest next-gen model. Compared to Claude 3 Haiku, it improves across skills and surpasses the previous largest model Claude 3 Opus on many intelligence benchmarks.', displayName: 'Claude 3.5 Haiku', - family: 'claude', + family: 'claude-haiku', generation: 'claude-3.5', id: 'claude-3-5-haiku-20241022', knowledgeCutoff: '2024-07', @@ -1521,6 +1542,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-flash-image-preview', + knowledgeCutoff: '2025-01', maxOutput: 32_768, pricing: { approximatePricePerImage: 0.067, @@ -1555,6 +1577,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-pro-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -1617,6 +1640,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-flash-lite-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -1648,6 +1672,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'gemini-3-pro-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -1710,6 +1735,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'gemini-3-flash-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -1746,6 +1772,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'gemini-3-pro-image-preview', + knowledgeCutoff: '2025-01', maxOutput: 32_768, pricing: { approximatePricePerImage: 0.134, @@ -1777,6 +1804,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-pro', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -1806,6 +1834,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -1834,6 +1863,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash-image', + knowledgeCutoff: '2025-06', maxOutput: 8192, pricing: { approximatePricePerImage: 0.039, @@ -1861,6 +1891,7 @@ const aihubmixChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash-lite', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/anthropic.ts b/packages/model-bank/src/aiModels/anthropic.ts index e566cf0bfb..a1498c3713 100644 --- a/packages/model-bank/src/aiModels/anthropic.ts +++ b/packages/model-bank/src/aiModels/anthropic.ts @@ -14,6 +14,8 @@ const anthropicChatModels: AIChatModelCard[] = [ "Claude Fable 5 is Anthropic's most capable model — a new tier above Opus for the most demanding reasoning and long-horizon agentic work.", displayName: 'Claude Fable 5', enabled: true, + family: 'claude-mythos', + generation: 'mythos-5', id: 'claude-fable-5', maxOutput: 128_000, pricing: { @@ -45,9 +47,10 @@ const anthropicChatModels: AIChatModelCard[] = [ "Claude Opus 4.8 is Anthropic's most capable model, building on Opus 4.7 with improvements across reasoning, agentic coding, and tool use.", displayName: 'Claude Opus 4.8', enabled: true, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.8', id: 'claude-opus-4-8', + knowledgeCutoff: '2026-01', maxOutput: 128_000, pricing: { units: [ @@ -78,9 +81,10 @@ const anthropicChatModels: AIChatModelCard[] = [ "Claude Opus 4.7 is Anthropic's most capable generally available model for complex reasoning and agentic coding.", displayName: 'Claude Opus 4.7', enabled: true, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.7', id: 'claude-opus-4-7', + knowledgeCutoff: '2026-01', maxOutput: 128_000, pricing: { units: [ @@ -110,9 +114,10 @@ const anthropicChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.6 is Anthropic’s most intelligent model for building agents and coding.', displayName: 'Claude Opus 4.6', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.6', id: 'claude-opus-4-6', + knowledgeCutoff: '2025-05', maxOutput: 128_000, pricing: { units: [ @@ -146,9 +151,10 @@ const anthropicChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4.6 is Anthropic’s best combination of speed and intelligence.', displayName: 'Claude Sonnet 4.6', enabled: true, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.6', id: 'claude-sonnet-4-6', + knowledgeCutoff: '2025-08', maxOutput: 64_000, pricing: { units: [ @@ -188,9 +194,10 @@ const anthropicChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.5 is Anthropic’s flagship model, combining top-tier intelligence with scalable performance for complex, high-quality reasoning tasks.', displayName: 'Claude Opus 4.5', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.5', id: 'claude-opus-4-5-20251101', + knowledgeCutoff: '2025-05', maxOutput: 64_000, pricing: { units: [ @@ -223,9 +230,10 @@ const anthropicChatModels: AIChatModelCard[] = [ contextWindowTokens: 200_000, description: 'Claude Sonnet 4.5 is Anthropic’s most intelligent model to date.', displayName: 'Claude Sonnet 4.5', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.5', id: 'claude-sonnet-4-5-20250929', + knowledgeCutoff: '2025-01', maxOutput: 64_000, pricing: { units: [ @@ -255,9 +263,10 @@ const anthropicChatModels: AIChatModelCard[] = [ 'Claude Haiku 4.5 is Anthropic’s fastest and smartest Haiku model, with lightning speed and extended reasoning.', displayName: 'Claude Haiku 4.5', enabled: true, - family: 'claude', + family: 'claude-haiku', generation: 'claude-4.5', id: 'claude-haiku-4-5-20251001', + knowledgeCutoff: '2025-02', maxOutput: 64_000, pricing: { units: [ @@ -290,9 +299,10 @@ const anthropicChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.1 is Anthropic’s newest and most powerful model for highly complex tasks, excelling in performance, intelligence, fluency, and comprehension.', displayName: 'Claude Opus 4.1', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.1', id: 'claude-opus-4-1-20250805', + knowledgeCutoff: '2025-01', maxOutput: 32_000, pricing: { units: [ @@ -325,9 +335,10 @@ const anthropicChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4 is Anthropic’s most powerful model for highly complex tasks, excelling in performance, intelligence, fluency, and comprehension.', displayName: 'Claude Opus 4', - family: 'claude', + family: 'claude-opus', generation: 'claude-4', id: 'claude-opus-4-20250514', + knowledgeCutoff: '2025-01', maxOutput: 32_000, pricing: { units: [ @@ -360,9 +371,10 @@ const anthropicChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4 can produce near-instant responses or extended step-by-step reasoning that users can see. API users can finely control how long the model thinks.', displayName: 'Claude Sonnet 4', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4', id: 'claude-sonnet-4-20250514', + knowledgeCutoff: '2025-01', maxOutput: 64_000, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/azure.ts b/packages/model-bank/src/aiModels/azure.ts index 5c4ebe0761..6bb8ba8481 100644 --- a/packages/model-bank/src/aiModels/azure.ts +++ b/packages/model-bank/src/aiModels/azure.ts @@ -20,6 +20,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.4', id: 'gpt-5.4', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -195,6 +196,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -227,6 +229,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -260,6 +263,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-pro', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -286,6 +290,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-codex', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -315,6 +320,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -344,6 +350,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-mini', + knowledgeCutoff: '2024-05', maxOutput: 128_000, pricing: { units: [ @@ -373,6 +380,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-nano', + knowledgeCutoff: '2024-05', maxOutput: 128_000, pricing: { units: [ @@ -398,6 +406,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-chat', + knowledgeCutoff: '2024-09', maxOutput: 16_384, pricing: { units: [ @@ -484,6 +493,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -511,6 +521,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1-mini', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -537,6 +548,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1-nano', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -668,6 +680,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o', + knowledgeCutoff: '2023-10', maxOutput: 4096, pricing: { units: [ @@ -694,6 +707,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4', + knowledgeCutoff: '2021-09', maxOutput: 4096, type: 'chat', }, @@ -711,6 +725,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-mini', + knowledgeCutoff: '2023-10', maxOutput: 4096, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/azureai.ts b/packages/model-bank/src/aiModels/azureai.ts index da6495cdb6..5bb241ffef 100644 --- a/packages/model-bank/src/aiModels/azureai.ts +++ b/packages/model-bank/src/aiModels/azureai.ts @@ -98,6 +98,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -121,6 +122,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1-mini', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -144,6 +146,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1-nano', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -166,6 +169,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.5', id: 'gpt-4.5-preview', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput_cacheRead', rate: 37.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -255,6 +259,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o', + knowledgeCutoff: '2023-10', maxOutput: 4096, pricing: { units: [ @@ -277,6 +282,7 @@ const azureChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-mini', + knowledgeCutoff: '2023-10', maxOutput: 16_384, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/bedrock.ts b/packages/model-bank/src/aiModels/bedrock.ts index 273761215a..a62db61ef8 100644 --- a/packages/model-bank/src/aiModels/bedrock.ts +++ b/packages/model-bank/src/aiModels/bedrock.ts @@ -13,9 +13,10 @@ const bedrockChatModels: AIChatModelCard[] = [ "Claude Opus 4.7 is Anthropic's most capable generally available model for complex reasoning and agentic coding.", displayName: 'Claude Opus 4.7', enabled: true, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.7', id: 'global.anthropic.claude-opus-4-7', + knowledgeCutoff: '2026-01', maxOutput: 128_000, pricing: { units: [ @@ -43,9 +44,10 @@ const bedrockChatModels: AIChatModelCard[] = [ description: "Claude Opus 4.6 is Anthropic's most intelligent model for building agents and coding.", displayName: 'Claude Opus 4.6', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.6', id: 'global.anthropic.claude-opus-4-6-v1', + knowledgeCutoff: '2025-05', maxOutput: 128_000, pricing: { units: [ @@ -77,9 +79,10 @@ const bedrockChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4.6 is Anthropic’s best combination of speed and intelligence.', displayName: 'Claude Sonnet 4.6', enabled: true, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.6', id: 'global.anthropic.claude-sonnet-4-6', + knowledgeCutoff: '2025-08', maxOutput: 64_000, pricing: { units: [ @@ -117,9 +120,10 @@ const bedrockChatModels: AIChatModelCard[] = [ description: "Claude Opus 4.5 is Anthropic's flagship model, combining exceptional intelligence and scalable performance for complex tasks requiring the highest-quality responses and reasoning.", displayName: 'Claude Opus 4.5', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.5', id: 'global.anthropic.claude-opus-4-5-20251101-v1:0', + knowledgeCutoff: '2025-05', maxOutput: 64_000, pricing: { units: [ @@ -144,9 +148,10 @@ const bedrockChatModels: AIChatModelCard[] = [ contextWindowTokens: 200_000, description: "Claude Sonnet 4.5 is Anthropic's most intelligent model to date.", displayName: 'Claude Sonnet 4.5', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.5', id: 'global.anthropic.claude-sonnet-4-5-20250929-v1:0', + knowledgeCutoff: '2025-01', maxOutput: 64_000, pricing: { units: [ @@ -172,9 +177,10 @@ const bedrockChatModels: AIChatModelCard[] = [ "Claude Haiku 4.5 is Anthropic's fastest and most intelligent Haiku model, with lightning speed and extended thinking.", displayName: 'Claude Haiku 4.5', enabled: true, - family: 'claude', + family: 'claude-haiku', generation: 'claude-4.5', id: 'global.anthropic.claude-haiku-4-5-20251001-v1:0', + knowledgeCutoff: '2025-02', maxOutput: 64_000, pricing: { units: [ @@ -220,9 +226,10 @@ const bedrockChatModels: AIChatModelCard[] = [ description: "Claude 3.7 Sonnet is Anthropic's fastest next-gen model. Compared to Claude 3 Haiku, it improves across skills and surpasses the previous flagship Claude 3 Opus on many intelligence benchmarks.", displayName: 'Claude 3.7 Sonnet', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.7', id: 'us.anthropic.claude-3-7-sonnet-20250219-v1:0', + knowledgeCutoff: '2024-10', maxOutput: 64_000, pricing: { units: [ @@ -245,9 +252,10 @@ const bedrockChatModels: AIChatModelCard[] = [ description: 'Claude 3.5 Sonnet raises the industry standard, outperforming competitors and Claude 3 Opus across broad evaluations while keeping mid-tier speed and cost.', displayName: 'Claude 3.5 Sonnet', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.5', id: 'anthropic.claude-3-5-sonnet-20241022-v2:0', + knowledgeCutoff: '2024-04', maxOutput: 8192, pricing: { units: [ @@ -270,9 +278,10 @@ const bedrockChatModels: AIChatModelCard[] = [ description: 'Claude 3.5 Sonnet raises the industry standard, outperforming competitors and Claude 3 Opus across broad evaluations while keeping mid-tier speed and cost.', displayName: 'Claude 3.5 Sonnet v2 (Inference profile)', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.5', id: 'us.anthropic.claude-3-5-sonnet-20241022-v2:0', + knowledgeCutoff: '2024-04', maxOutput: 8192, pricing: { units: [ @@ -295,9 +304,10 @@ const bedrockChatModels: AIChatModelCard[] = [ description: 'Claude 3.5 Sonnet raises the industry standard, outperforming competitors and Claude 3 Opus across broad evaluations while keeping mid-tier speed and cost.', displayName: 'Claude 3.5 Sonnet 0620', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.5', id: 'anthropic.claude-3-5-sonnet-20240620-v1:0', + knowledgeCutoff: '2024-04', maxOutput: 8192, pricing: { units: [ @@ -320,9 +330,10 @@ const bedrockChatModels: AIChatModelCard[] = [ description: 'Claude 3 Haiku is Anthropic’s fastest, most compact model, delivering near-instant responses for simple queries. It enables seamless, human-like AI experiences and supports image input with a 200K context window.', displayName: 'Claude 3 Haiku', - family: 'claude', + family: 'claude-haiku', generation: 'claude-3', id: 'anthropic.claude-3-haiku-20240307-v1:0', + knowledgeCutoff: '2023-08', maxOutput: 4096, pricing: { units: [ @@ -345,9 +356,10 @@ const bedrockChatModels: AIChatModelCard[] = [ description: 'Claude 3 Sonnet balances intelligence and speed for enterprise workloads, offering strong value at lower cost. It is designed as a reliable workhorse for scaled AI deployments and supports image input with a 200K context window.', displayName: 'Claude 3 Sonnet', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3', id: 'anthropic.claude-3-sonnet-20240229-v1:0', + knowledgeCutoff: '2023-08', pricing: { units: [ { name: 'textInput', rate: 3, strategy: 'fixed', unit: 'millionTokens' }, @@ -364,9 +376,10 @@ const bedrockChatModels: AIChatModelCard[] = [ description: 'Claude 3 Opus is Anthropic’s most powerful AI model with state-of-the-art performance on highly complex tasks. It handles open-ended prompts and novel scenarios with exceptional fluency and human-like understanding, and supports image input with a 200K context window.', displayName: 'Claude 3 Opus', - family: 'claude', + family: 'claude-opus', generation: 'claude-3', id: 'anthropic.claude-3-opus-20240229-v1:0', + knowledgeCutoff: '2023-08', maxOutput: 4096, pricing: { units: [ @@ -388,6 +401,7 @@ const bedrockChatModels: AIChatModelCard[] = [ family: 'claude', generation: 'claude-2', id: 'anthropic.claude-v2:1', + knowledgeCutoff: '2023', pricing: { units: [ { name: 'textInput', rate: 8, strategy: 'fixed', unit: 'millionTokens' }, @@ -404,6 +418,7 @@ const bedrockChatModels: AIChatModelCard[] = [ family: 'claude', generation: 'claude-2', id: 'anthropic.claude-v2', + knowledgeCutoff: '2023', pricing: { units: [ { name: 'textInput', rate: 8, strategy: 'fixed', unit: 'millionTokens' }, @@ -417,9 +432,9 @@ const bedrockChatModels: AIChatModelCard[] = [ description: 'A fast, economical, yet capable model for everyday chat, text analysis, summarization, and document Q&A.', displayName: 'Claude Instant', - family: 'claude', - generation: 'claude-instant', + family: 'claude-instant', id: 'anthropic.claude-instant-v1', + knowledgeCutoff: '2023', maxOutput: 4096, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/cloudflare.ts b/packages/model-bank/src/aiModels/cloudflare.ts index 44fea21426..6d7bec6698 100644 --- a/packages/model-bank/src/aiModels/cloudflare.ts +++ b/packages/model-bank/src/aiModels/cloudflare.ts @@ -39,6 +39,7 @@ const cloudflareChatModels: AIChatModelCard[] = [ family: 'gemma', generation: 'gemma-3', id: '@cf/google/gemma-3-12b-it', + knowledgeCutoff: '2024-08', type: 'chat', }, { @@ -73,6 +74,7 @@ const cloudflareChatModels: AIChatModelCard[] = [ displayName: 'mistral small 3.1 24b', family: 'mistral', id: '@cf/mistralai/mistral-small-3.1-24b-instruct', + knowledgeCutoff: '2023-10', type: 'chat', }, { diff --git a/packages/model-bank/src/aiModels/cohere.ts b/packages/model-bank/src/aiModels/cohere.ts index 387dc1f024..29838cd2cf 100644 --- a/packages/model-bank/src/aiModels/cohere.ts +++ b/packages/model-bank/src/aiModels/cohere.ts @@ -51,6 +51,7 @@ const cohereChatModels: AIChatModelCard[] = [ enabled: true, family: 'command', id: 'command-r-plus-08-2024', + knowledgeCutoff: '2023-02', maxOutput: 4000, pricing: { units: [ @@ -89,6 +90,7 @@ const cohereChatModels: AIChatModelCard[] = [ enabled: true, family: 'command', id: 'command-r-08-2024', + knowledgeCutoff: '2023-02', maxOutput: 4000, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/cometapi.ts b/packages/model-bank/src/aiModels/cometapi.ts index f18ef36d37..08a1bc0e8b 100644 --- a/packages/model-bank/src/aiModels/cometapi.ts +++ b/packages/model-bank/src/aiModels/cometapi.ts @@ -13,6 +13,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-chat-latest', + knowledgeCutoff: '2024-09', maxOutput: 128_000, releasedAt: '2025-08-07', type: 'chat', @@ -26,6 +27,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-mini', + knowledgeCutoff: '2024-05', maxOutput: 128_000, type: 'chat', }, @@ -38,6 +40,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-nano', + knowledgeCutoff: '2024-05', maxOutput: 128_000, type: 'chat', }, @@ -50,6 +53,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5', + knowledgeCutoff: '2024-09', maxOutput: 128_000, type: 'chat', }, @@ -64,6 +68,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1', + knowledgeCutoff: '2024-06', maxOutput: 32_768, releasedAt: '2025-04-14', type: 'chat', @@ -78,6 +83,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1-mini', + knowledgeCutoff: '2024-06', maxOutput: 32_768, releasedAt: '2025-04-14', type: 'chat', @@ -91,6 +97,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1-nano', + knowledgeCutoff: '2024-06', maxOutput: 16_384, releasedAt: '2025-04-14', type: 'chat', @@ -104,6 +111,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-mini', + knowledgeCutoff: '2023-10', maxOutput: 16_384, type: 'chat', }, @@ -117,6 +125,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'chatgpt-4o-latest', + knowledgeCutoff: '2023-10', maxOutput: 16_384, type: 'chat', }, @@ -176,7 +185,7 @@ const cometapiChatModels: AIChatModelCard[] = [ 'Claude Opus 4.1 is Anthropic’s latest and most capable model for highly complex tasks, excelling in performance, intelligence, fluency, and understanding.', displayName: 'Claude Opus 4.1', enabled: true, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.1', id: 'claude-opus-4-1-20250805', knowledgeCutoff: '2025-01', @@ -191,7 +200,7 @@ const cometapiChatModels: AIChatModelCard[] = [ 'Claude Opus 4.1 Thinking is an advanced variant that can reveal its reasoning process.', displayName: 'Claude Opus 4.1 Thinking', enabled: true, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.1', id: 'claude-opus-4-1-20250805-thinking', knowledgeCutoff: '2025-01', @@ -206,7 +215,7 @@ const cometapiChatModels: AIChatModelCard[] = [ 'Claude Sonnet 4 can produce near-instant responses or extended step-by-step thinking with visible process.', displayName: 'Claude Sonnet 4', enabled: true, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4', id: 'claude-sonnet-4-20250514', knowledgeCutoff: '2025-01', @@ -221,7 +230,7 @@ const cometapiChatModels: AIChatModelCard[] = [ 'Claude Sonnet 4 Thinking can produce near-instant responses or extended step-by-step thinking with visible process.', displayName: 'Claude Sonnet 4 Thinking', enabled: true, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4', id: 'claude-sonnet-4-20250514-thinking', knowledgeCutoff: '2025-01', @@ -236,7 +245,7 @@ const cometapiChatModels: AIChatModelCard[] = [ 'Claude 3.7 Sonnet is Anthropic’s latest and most capable model for highly complex tasks, excelling in performance, intelligence, fluency, and understanding.', displayName: 'Claude 3.7 Sonnet Latest', enabled: true, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.7', id: 'claude-3-7-sonnet-latest', knowledgeCutoff: '2024-10', @@ -250,7 +259,7 @@ const cometapiChatModels: AIChatModelCard[] = [ description: 'Claude 3.5 Haiku delivers fast responses for lightweight tasks.', displayName: 'Claude 3.5 Haiku', enabled: true, - family: 'claude', + family: 'claude-haiku', generation: 'claude-3.5', id: 'claude-3-5-haiku-latest', knowledgeCutoff: '2024-07', @@ -269,6 +278,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-pro', + knowledgeCutoff: '2025-01', maxOutput: 65_536, releasedAt: '2025-03-25', type: 'chat', @@ -283,6 +293,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash', + knowledgeCutoff: '2025-01', maxOutput: 65_536, releasedAt: '2025-03-25', type: 'chat', @@ -296,6 +307,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash-lite', + knowledgeCutoff: '2025-01', maxOutput: 8192, releasedAt: '2025-06-17', type: 'chat', @@ -309,6 +321,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'gemini-2.0-flash', + knowledgeCutoff: '2024-08', maxOutput: 8192, type: 'chat', }, @@ -323,6 +336,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-4', id: 'grok-4-0709', + knowledgeCutoff: '2024-11', maxOutput: 4096, type: 'chat', }, @@ -335,6 +349,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'grok-3', + knowledgeCutoff: '2024-11', maxOutput: 4096, type: 'chat', }, @@ -347,6 +362,7 @@ const cometapiChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'grok-3-mini', + knowledgeCutoff: '2024-11', maxOutput: 32_000, type: 'chat', }, diff --git a/packages/model-bank/src/aiModels/fireworksai.ts b/packages/model-bank/src/aiModels/fireworksai.ts index 109e17d22d..013fcd78b7 100644 --- a/packages/model-bank/src/aiModels/fireworksai.ts +++ b/packages/model-bank/src/aiModels/fireworksai.ts @@ -195,6 +195,7 @@ const fireworksaiChatModels: AIChatModelCard[] = [ enabled: true, family: 'mistral', id: 'accounts/fireworks/models/mistral-small-24b-instruct-2501', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 0.9, strategy: 'fixed', unit: 'millionTokens' }, diff --git a/packages/model-bank/src/aiModels/github.ts b/packages/model-bank/src/aiModels/github.ts index dcca08c249..1f5241e2ff 100644 --- a/packages/model-bank/src/aiModels/github.ts +++ b/packages/model-bank/src/aiModels/github.ts @@ -65,6 +65,7 @@ const githubChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -89,6 +90,7 @@ const githubChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1-mini', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -111,6 +113,7 @@ const githubChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1-nano', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -226,6 +229,7 @@ const githubChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'openai/gpt-4o-mini', + knowledgeCutoff: '2023-10', maxOutput: 4096, type: 'chat', }, @@ -241,6 +245,7 @@ const githubChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'openai/gpt-4o', + knowledgeCutoff: '2023-10', maxOutput: 16_384, type: 'chat', }, @@ -253,6 +258,7 @@ const githubChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'xai/grok-3', + knowledgeCutoff: '2024-11', maxOutput: 4096, type: 'chat', }, @@ -266,6 +272,7 @@ const githubChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'xai/grok-3-mini', + knowledgeCutoff: '2024-11', maxOutput: 4096, type: 'chat', }, @@ -313,6 +320,7 @@ const githubChatModels: AIChatModelCard[] = [ displayName: 'AI21 Jamba 1.5 Mini', family: 'jamba', id: 'ai21-labs/AI21-Jamba-1.5-Mini', + knowledgeCutoff: '2024-03', maxOutput: 4096, type: 'chat', }, @@ -326,6 +334,7 @@ const githubChatModels: AIChatModelCard[] = [ displayName: 'AI21 Jamba 1.5 Large', family: 'jamba', id: 'ai21-labs/AI21-Jamba-1.5-Large', + knowledgeCutoff: '2024-03', maxOutput: 4096, type: 'chat', }, @@ -363,6 +372,7 @@ const githubChatModels: AIChatModelCard[] = [ displayName: 'Mistral Small', family: 'mistral', id: 'mistral-ai/mistral-small-2503', + knowledgeCutoff: '2023-10', maxOutput: 4096, type: 'chat', }, @@ -373,6 +383,7 @@ const githubChatModels: AIChatModelCard[] = [ displayName: 'Mistral Large', family: 'mistral', id: 'mistral-ai/Mistral-Large-2411', + knowledgeCutoff: '2023-10', maxOutput: 4096, type: 'chat', }, diff --git a/packages/model-bank/src/aiModels/githubCopilot.ts b/packages/model-bank/src/aiModels/githubCopilot.ts index 18794c90a5..f991ed474b 100644 --- a/packages/model-bank/src/aiModels/githubCopilot.ts +++ b/packages/model-bank/src/aiModels/githubCopilot.ts @@ -17,6 +17,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.4', id: 'gpt-5.4', + knowledgeCutoff: '2025-08', releasedAt: '2026-03-05', settings: { extendParams: ['gpt5_2ReasoningEffort', 'textVerbosity'], @@ -59,6 +60,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.3', id: 'gpt-5.3-codex', + knowledgeCutoff: '2025-08', releasedAt: '2026-02-05', settings: { extendParams: ['codexMaxReasoningEffort'], @@ -79,6 +81,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2', + knowledgeCutoff: '2025-08', releasedAt: '2025-12-11', settings: { extendParams: ['gpt5_2ReasoningEffort', 'textVerbosity'], @@ -99,6 +102,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2-codex', + knowledgeCutoff: '2025-08', releasedAt: '2025-12-18', settings: { extendParams: ['codexMaxReasoningEffort'], @@ -118,6 +122,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1', + knowledgeCutoff: '2024-09', releasedAt: '2025-11-13', settings: { extendParams: ['gpt5_1ReasoningEffort', 'textVerbosity'], @@ -138,6 +143,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-mini', + knowledgeCutoff: '2024-05', releasedAt: '2025-08-07', settings: { extendParams: ['gpt5ReasoningEffort', 'textVerbosity'], @@ -156,6 +162,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1', + knowledgeCutoff: '2024-06', releasedAt: '2025-04-14', type: 'chat', }, @@ -173,7 +180,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ 'Claude Opus 4.6 is Anthropic’s most intelligent model for building agents and coding.', displayName: 'Claude Opus 4.6', enabled: true, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.6', id: 'claude-opus-4.6', knowledgeCutoff: '2025-05', @@ -194,7 +201,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.6 is Anthropic’s most intelligent model for building agents and coding.', displayName: 'Claude Opus 4.6 (Fast Mode)', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.6', id: 'claude-opus-4.6-fast', knowledgeCutoff: '2025-05', @@ -215,7 +222,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4.6 is Anthropic’s best combination of speed and intelligence.', displayName: 'Claude Sonnet 4.6', enabled: true, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.6', id: 'claude-sonnet-4.6', knowledgeCutoff: '2025-05', @@ -236,7 +243,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.5 is Anthropic’s flagship model, combining top-tier intelligence with scalable performance for complex, high-quality reasoning tasks.', displayName: 'Claude Opus 4.5', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.5', id: 'claude-opus-4.5', knowledgeCutoff: '2025-05', @@ -256,7 +263,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ contextWindowTokens: 139_000, description: 'Claude Sonnet 4.5 is Anthropic’s most intelligent model to date.', displayName: 'Claude Sonnet 4.5', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.5', id: 'claude-sonnet-4.5', knowledgeCutoff: '2025-01', @@ -278,7 +285,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ 'Claude Haiku 4.5 is Anthropic’s fastest and smartest Haiku model, with lightning speed and extended reasoning.', displayName: 'Claude Haiku 4.5', enabled: true, - family: 'claude', + family: 'claude-haiku', generation: 'claude-4.5', id: 'claude-haiku-4.5', knowledgeCutoff: '2025-02', @@ -298,7 +305,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4 can produce near-instant responses or extended step-by-step reasoning that users can see. API users can finely control how long the model thinks.', displayName: 'Claude Sonnet 4', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4', id: 'claude-sonnet-4', knowledgeCutoff: '2025-01', @@ -325,6 +332,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-pro-preview', + knowledgeCutoff: '2025-01', releasedAt: '2026-02-19', type: 'chat', }, @@ -341,6 +349,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'gemini-3-flash-preview', + knowledgeCutoff: '2025-01', releasedAt: '2025-12-17', type: 'chat', }, @@ -357,6 +366,7 @@ const githubCopilotChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-pro', + knowledgeCutoff: '2025-01', releasedAt: '2025-06-17', type: 'chat', }, diff --git a/packages/model-bank/src/aiModels/google.ts b/packages/model-bank/src/aiModels/google.ts index 5391a83072..778fe0acd7 100644 --- a/packages/model-bank/src/aiModels/google.ts +++ b/packages/model-bank/src/aiModels/google.ts @@ -26,6 +26,7 @@ const googleChatModels: AIChatModelCard[] = [ displayName: 'Gemini Pro Latest', family: 'gemini', id: 'gemini-pro-latest', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -78,6 +79,7 @@ const googleChatModels: AIChatModelCard[] = [ displayName: 'Gemini Flash Latest', family: 'gemini', id: 'gemini-flash-latest', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -106,6 +108,7 @@ const googleChatModels: AIChatModelCard[] = [ displayName: 'Gemini Flash-Lite Latest', family: 'gemini', id: 'gemini-flash-lite-latest', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -138,6 +141,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.5', id: 'gemini-3.5-flash', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -178,6 +182,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-flash-image-preview', + knowledgeCutoff: '2025-01', maxOutput: 32_768, pricing: { approximatePricePerImage: 0.067, @@ -213,6 +218,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-pro-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -303,6 +309,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-flash-lite', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -340,6 +347,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-flash-lite-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -374,6 +382,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'gemini-3-flash-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -413,6 +422,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'gemini-3-pro-image-preview', + knowledgeCutoff: '2025-01', maxOutput: 32_768, pricing: { approximatePricePerImage: 0.134, @@ -443,6 +453,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemma', generation: 'gemma-4', id: 'gemma-4-26b-a4b-it', + knowledgeCutoff: '2025-01', maxOutput: 32_768, pricing: { units: [ @@ -470,6 +481,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemma', generation: 'gemma-4', id: 'gemma-4-31b-it', + knowledgeCutoff: '2025-01', maxOutput: 32_768, pricing: { units: [ @@ -500,6 +512,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-pro', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -587,6 +600,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -618,6 +632,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash-image', + knowledgeCutoff: '2025-06', maxOutput: 32_768, pricing: { approximatePricePerImage: 0.039, @@ -649,6 +664,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash-lite', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -678,6 +694,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'gemini-2.0-flash', + knowledgeCutoff: '2024-08', maxOutput: 8192, pricing: { units: [ @@ -707,6 +724,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'gemini-2.0-flash-001', + knowledgeCutoff: '2024-08', maxOutput: 8192, pricing: { units: [ @@ -733,6 +751,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'gemini-2.0-flash-lite', + knowledgeCutoff: '2024-08', maxOutput: 8192, pricing: { units: [ @@ -753,6 +772,7 @@ const googleChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'gemini-2.0-flash-lite-001', + knowledgeCutoff: '2024-08', maxOutput: 8192, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/higress.ts b/packages/model-bank/src/aiModels/higress.ts index e0825721df..dead874bfb 100644 --- a/packages/model-bank/src/aiModels/higress.ts +++ b/packages/model-bank/src/aiModels/higress.ts @@ -1686,6 +1686,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-mini', + knowledgeCutoff: '2023-10', maxOutput: 16_385, pricing: { units: [ @@ -1708,6 +1709,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 2.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1728,6 +1730,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-2024-08-06', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 2.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1748,6 +1751,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-2024-05-13', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1768,6 +1772,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'chatgpt-4o-latest', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1788,6 +1793,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-turbo', + knowledgeCutoff: '2023-12', pricing: { units: [ { name: 'textInput', rate: 10, strategy: 'fixed', unit: 'millionTokens' }, @@ -1808,6 +1814,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-turbo-2024-04-09', + knowledgeCutoff: '2023-12', pricing: { units: [ { name: 'textInput', rate: 10, strategy: 'fixed', unit: 'millionTokens' }, @@ -1827,6 +1834,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-turbo-preview', + knowledgeCutoff: '2023-12', pricing: { units: [ { name: 'textInput', rate: 10, strategy: 'fixed', unit: 'millionTokens' }, @@ -1846,6 +1854,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-0125-preview', + knowledgeCutoff: '2023-12', pricing: { units: [ { name: 'textInput', rate: 10, strategy: 'fixed', unit: 'millionTokens' }, @@ -1865,6 +1874,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-1106-preview', + knowledgeCutoff: '2023-04', pricing: { units: [ { name: 'textInput', rate: 10, strategy: 'fixed', unit: 'millionTokens' }, @@ -1884,6 +1894,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 30, strategy: 'fixed', unit: 'millionTokens' }, @@ -1903,6 +1914,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-0613', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 30, strategy: 'fixed', unit: 'millionTokens' }, @@ -1922,6 +1934,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-32k', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 60, strategy: 'fixed', unit: 'millionTokens' }, @@ -1941,6 +1954,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-32k-0613', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 60, strategy: 'fixed', unit: 'millionTokens' }, @@ -1960,6 +1974,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'gpt-3.5-turbo', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 0.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1979,6 +1994,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'gpt-3.5-turbo-0125', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 0.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1998,6 +2014,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'gpt-3.5-turbo-1106', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 1, strategy: 'fixed', unit: 'millionTokens' }, @@ -2014,6 +2031,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'gpt-3.5-turbo-instruct', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 1.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -2034,6 +2052,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'gpt-35-turbo', + knowledgeCutoff: '2021-09', maxOutput: 4096, type: 'chat', }, @@ -2047,6 +2066,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'gpt-35-turbo-16k', + knowledgeCutoff: '2021-09', type: 'chat', }, { @@ -2059,6 +2079,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-vision-preview', + knowledgeCutoff: '2023-04', type: 'chat', }, { @@ -2071,6 +2092,7 @@ const higressChatModels: AIChatModelCard[] = [ displayName: 'AI21 Jamba 1.5 Mini', family: 'jamba', id: 'ai21-jamba-1.5-mini', + knowledgeCutoff: '2024-03', maxOutput: 4096, type: 'chat', }, @@ -2084,6 +2106,7 @@ const higressChatModels: AIChatModelCard[] = [ displayName: 'AI21 Jamba 1.5 Large', family: 'jamba', id: 'ai21-jamba-1.5-large', + knowledgeCutoff: '2024-03', maxOutput: 4096, type: 'chat', }, @@ -2131,6 +2154,7 @@ const higressChatModels: AIChatModelCard[] = [ displayName: 'Mistral Large', family: 'mistral', id: 'mistral-large', + knowledgeCutoff: '2023-10', maxOutput: 4096, type: 'chat', }, @@ -2578,7 +2602,7 @@ const higressChatModels: AIChatModelCard[] = [ 'Claude 3.5 Haiku is Anthropic’s fastest next-gen model. Compared to Claude 3 Haiku, it improves across skills and surpasses the prior largest model Claude 3 Opus on many intelligence benchmarks.', displayName: 'Claude 3.5 Haiku', enabled: true, - family: 'claude', + family: 'claude-haiku', generation: 'claude-3.5', id: 'claude-3-5-haiku-20241022', knowledgeCutoff: '2024-07', @@ -2608,7 +2632,7 @@ const higressChatModels: AIChatModelCard[] = [ description: 'Claude 3 Haiku is Anthropic’s fastest and most compact model, designed for near-instant responses with fast, accurate performance.', displayName: 'Claude 3 Haiku', - family: 'claude', + family: 'claude-haiku', generation: 'claude-3', id: 'claude-3-haiku-20240307', knowledgeCutoff: '2023-08', @@ -2631,7 +2655,7 @@ const higressChatModels: AIChatModelCard[] = [ description: 'Claude 3 Sonnet balances intelligence and speed for enterprise workloads, delivering high utility at lower cost and reliable large-scale deployment.', displayName: 'Claude 3 Sonnet', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3', id: 'claude-3-sonnet-20240229', knowledgeCutoff: '2023-08', @@ -2655,7 +2679,7 @@ const higressChatModels: AIChatModelCard[] = [ 'Claude 3 Opus is Anthropic’s most powerful model for highly complex tasks, excelling in performance, intelligence, fluency, and comprehension.', displayName: 'Claude 3 Opus', enabled: true, - family: 'claude', + family: 'claude-opus', generation: 'claude-3', id: 'claude-3-opus-20240229', knowledgeCutoff: '2023-08', @@ -2677,6 +2701,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'claude', generation: 'claude-2.1', id: 'claude-2.1', + knowledgeCutoff: '2023', maxOutput: 4096, pricing: { units: [ @@ -2719,6 +2744,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-flash-latest', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ @@ -2742,6 +2768,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-flash-002', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ @@ -2765,6 +2792,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-flash-001', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ @@ -2787,6 +2815,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-flash-exp-0827', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ @@ -2858,6 +2887,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-pro-latest', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ @@ -2882,6 +2912,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-pro-002', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ @@ -2904,6 +2935,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-pro-001', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ @@ -2927,6 +2959,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-pro-exp-0827', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ @@ -2950,6 +2983,7 @@ const higressChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-pro-exp-0801', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ @@ -3048,6 +3082,7 @@ const higressChatModels: AIChatModelCard[] = [ enabled: true, family: 'mistral', id: 'mistral-small-latest', + knowledgeCutoff: '2024-11', pricing: { units: [ { name: 'textInput', rate: 0.2, strategy: 'fixed', unit: 'millionTokens' }, @@ -3067,6 +3102,7 @@ const higressChatModels: AIChatModelCard[] = [ enabled: true, family: 'mistral', id: 'mistral-large-latest', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 2, strategy: 'fixed', unit: 'millionTokens' }, diff --git a/packages/model-bank/src/aiModels/infiniai.ts b/packages/model-bank/src/aiModels/infiniai.ts index 1ac0cb9bbb..d38ca1ec89 100644 --- a/packages/model-bank/src/aiModels/infiniai.ts +++ b/packages/model-bank/src/aiModels/infiniai.ts @@ -122,6 +122,7 @@ const infiniaiChatModels: AIChatModelCard[] = [ displayName: 'MiMo-V2 Pro', family: 'mimo', id: 'mimo-v2-pro', + knowledgeCutoff: '2024-12', maxOutput: 262_144, pricing: { currency: 'CNY', diff --git a/packages/model-bank/src/aiModels/mistral.ts b/packages/model-bank/src/aiModels/mistral.ts index 413e6303f0..b20810ec1e 100644 --- a/packages/model-bank/src/aiModels/mistral.ts +++ b/packages/model-bank/src/aiModels/mistral.ts @@ -17,6 +17,7 @@ const mistralChatModels: AIChatModelCard[] = [ enabled: true, family: 'mistral', id: 'mistral-medium-3.5', + knowledgeCutoff: '2024-11', pricing: { units: [ { name: 'textInput', rate: 1.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -155,6 +156,7 @@ const mistralChatModels: AIChatModelCard[] = [ displayName: 'Mistral Small 4', family: 'mistral', id: 'mistral-small-2603', + knowledgeCutoff: '2024-11', pricing: { units: [ { name: 'textInput', rate: 0.15, strategy: 'fixed', unit: 'millionTokens' }, @@ -177,6 +179,7 @@ const mistralChatModels: AIChatModelCard[] = [ displayName: 'Mistral Small 3.2', family: 'mistral', id: 'mistral-small-2506', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 0.1, strategy: 'fixed', unit: 'millionTokens' }, @@ -197,6 +200,7 @@ const mistralChatModels: AIChatModelCard[] = [ enabled: true, family: 'mistral', id: 'mistral-large-2512', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 0.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -217,6 +221,7 @@ const mistralChatModels: AIChatModelCard[] = [ displayName: 'Mistral Large 2.1', family: 'mistral', id: 'mistral-large-2411', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 2, strategy: 'fixed', unit: 'millionTokens' }, diff --git a/packages/model-bank/src/aiModels/nebius.ts b/packages/model-bank/src/aiModels/nebius.ts index 91c84bee6e..11023f9307 100644 --- a/packages/model-bank/src/aiModels/nebius.ts +++ b/packages/model-bank/src/aiModels/nebius.ts @@ -33,6 +33,7 @@ const nebiusChatModels: AIChatModelCard[] = [ family: 'gemma', generation: 'gemma-3', id: 'google/gemma-3-27b-it', + knowledgeCutoff: '2024-08', organization: 'google', pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/novita.ts b/packages/model-bank/src/aiModels/novita.ts index fe7c0ff14e..b47930a1bd 100644 --- a/packages/model-bank/src/aiModels/novita.ts +++ b/packages/model-bank/src/aiModels/novita.ts @@ -658,6 +658,7 @@ const novitaChatModels: AIChatModelCard[] = [ family: 'gemma', generation: 'gemma-3', id: 'google/gemma-3-27b-it', + knowledgeCutoff: '2024-08', pricing: { units: [ { name: 'textInput', rate: 0.119, strategy: 'fixed', unit: 'millionTokens' }, @@ -674,6 +675,7 @@ const novitaChatModels: AIChatModelCard[] = [ family: 'gemma', generation: 'gemma-3', id: 'google/gemma-3-12b-it', + knowledgeCutoff: '2024-08', maxOutput: 8192, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/ollama.ts b/packages/model-bank/src/aiModels/ollama.ts index ed72c6acf1..730fbb7e70 100644 --- a/packages/model-bank/src/aiModels/ollama.ts +++ b/packages/model-bank/src/aiModels/ollama.ts @@ -433,6 +433,7 @@ const ollamaChatModels: AIChatModelCard[] = [ displayName: 'Mixtral Large 123B', family: 'mistral', id: 'mistral-large', + knowledgeCutoff: '2023-10', type: 'chat', }, { diff --git a/packages/model-bank/src/aiModels/ollamacloud.ts b/packages/model-bank/src/aiModels/ollamacloud.ts index 8025c15858..b016c6a0a4 100644 --- a/packages/model-bank/src/aiModels/ollamacloud.ts +++ b/packages/model-bank/src/aiModels/ollamacloud.ts @@ -183,6 +183,7 @@ const ollamaCloudModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'gemini-3-flash-preview', + knowledgeCutoff: '2025-01', releasedAt: '2025-12-17', type: 'chat', }, @@ -348,6 +349,7 @@ const ollamaCloudModels: AIChatModelCard[] = [ displayName: 'Ministral 3 3B', family: 'ministral', id: 'ministral-3:3b', + knowledgeCutoff: '2023-10', releasedAt: '2025-12-02', type: 'chat', }, @@ -362,6 +364,7 @@ const ollamaCloudModels: AIChatModelCard[] = [ displayName: 'Ministral 3 8B', family: 'ministral', id: 'ministral-3:8b', + knowledgeCutoff: '2023-10', releasedAt: '2025-12-02', type: 'chat', }, @@ -376,6 +379,7 @@ const ollamaCloudModels: AIChatModelCard[] = [ displayName: 'Ministral 3 14B', family: 'ministral', id: 'ministral-3:14b', + knowledgeCutoff: '2023-10', releasedAt: '2025-12-02', type: 'chat', }, @@ -390,6 +394,7 @@ const ollamaCloudModels: AIChatModelCard[] = [ displayName: 'Mistral Large 3', family: 'mistral', id: 'mistral-large-3:675b', + knowledgeCutoff: '2023-10', releasedAt: '2025-12-02', type: 'chat', }, diff --git a/packages/model-bank/src/aiModels/openai.ts b/packages/model-bank/src/aiModels/openai.ts index 0d44972149..39926b3265 100644 --- a/packages/model-bank/src/aiModels/openai.ts +++ b/packages/model-bank/src/aiModels/openai.ts @@ -21,6 +21,7 @@ export const openaiChatModels: AIChatModelCard[] = [ description: 'Latest Instant model used in ChatGPT.', displayName: 'Chat Latest', id: 'chat-latest', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -155,6 +156,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.4', id: 'gpt-5.4', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -330,6 +332,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.3', id: 'gpt-5.3-chat-latest', + knowledgeCutoff: '2025-08', maxOutput: 16_384, pricing: { units: [ @@ -356,6 +359,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.3', id: 'gpt-5.3-codex', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -386,6 +390,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -416,6 +421,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2-codex', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -445,6 +451,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2-pro', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -471,6 +478,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2-chat-latest', + knowledgeCutoff: '2025-08', maxOutput: 16_384, pricing: { units: [ @@ -496,6 +504,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -522,6 +531,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1-chat-latest', + knowledgeCutoff: '2024-09', maxOutput: 16_384, pricing: { units: [ @@ -547,6 +557,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1-codex-max', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -576,6 +587,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1-codex', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -605,6 +617,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1-codex-mini', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -634,6 +647,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-pro', + knowledgeCutoff: '2024-09', maxOutput: 272_000, pricing: { units: [ @@ -662,6 +676,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-codex', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -692,6 +707,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -722,6 +738,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-mini', + knowledgeCutoff: '2024-05', maxOutput: 128_000, pricing: { units: [ @@ -750,6 +767,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-nano', + knowledgeCutoff: '2024-05', maxOutput: 128_000, pricing: { units: [ @@ -775,6 +793,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-chat-latest', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -1030,6 +1049,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -1057,6 +1077,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1-mini', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -1082,6 +1103,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'gpt-4.1-nano', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -1106,6 +1128,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-mini', + knowledgeCutoff: '2023-10', maxOutput: 16_384, pricing: { units: [ @@ -1131,6 +1154,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-mini-search-preview', + knowledgeCutoff: '2023-10', maxOutput: 16_384, pricing: { units: [ @@ -1157,6 +1181,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput_cacheRead', rate: 1.25, strategy: 'fixed', unit: 'millionTokens' }, @@ -1181,6 +1206,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-search-preview', + knowledgeCutoff: '2023-10', maxOutput: 16_384, pricing: { units: [ @@ -1207,6 +1233,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-2024-11-20', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput_cacheRead', rate: 1.25, strategy: 'fixed', unit: 'millionTokens' }, @@ -1233,6 +1260,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'gpt-4o-2024-05-13', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1282,6 +1310,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-turbo', + knowledgeCutoff: '2023-12', pricing: { units: [ { name: 'textInput', rate: 10, strategy: 'fixed', unit: 'millionTokens' }, @@ -1302,6 +1331,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-turbo-2024-04-09', + knowledgeCutoff: '2023-12', pricing: { units: [ { name: 'textInput', rate: 10, strategy: 'fixed', unit: 'millionTokens' }, @@ -1322,6 +1352,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 30, strategy: 'fixed', unit: 'millionTokens' }, @@ -1341,6 +1372,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'gpt-4-0613', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 30, strategy: 'fixed', unit: 'millionTokens' }, @@ -1361,6 +1393,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'gpt-3.5-turbo', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 0.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1380,6 +1413,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'gpt-3.5-turbo-0125', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 0.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1400,6 +1434,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'gpt-3.5-turbo-1106', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 1, strategy: 'fixed', unit: 'millionTokens' }, @@ -1417,6 +1452,7 @@ export const openaiChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'gpt-3.5-turbo-instruct', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 1.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1437,6 +1473,7 @@ export const openaiChatModels: AIChatModelCard[] = [ displayName: 'Computer Use Preview', family: 'gpt', id: 'computer-use-preview', + knowledgeCutoff: '2023-10', maxOutput: 1024, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/opencodeCodingPlan.ts b/packages/model-bank/src/aiModels/opencodeCodingPlan.ts index a05ff2a424..248ccf7a02 100644 --- a/packages/model-bank/src/aiModels/opencodeCodingPlan.ts +++ b/packages/model-bank/src/aiModels/opencodeCodingPlan.ts @@ -117,6 +117,7 @@ const opencodeCodingPlanChatModels: AIChatModelCard[] = [ enabled: false, family: 'mimo', id: 'mimo-v2.5', + knowledgeCutoff: '2024-12', maxOutput: 128_000, organization: 'Xiaomi', pricing: { @@ -142,6 +143,7 @@ const opencodeCodingPlanChatModels: AIChatModelCard[] = [ enabled: false, family: 'mimo', id: 'mimo-v2.5-pro', + knowledgeCutoff: '2024-12', maxOutput: 128_000, organization: 'Xiaomi', pricing: { diff --git a/packages/model-bank/src/aiModels/opencodeZen.ts b/packages/model-bank/src/aiModels/opencodeZen.ts index 89e2bc9408..efe9e1e56c 100644 --- a/packages/model-bank/src/aiModels/opencodeZen.ts +++ b/packages/model-bank/src/aiModels/opencodeZen.ts @@ -12,7 +12,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ 'Claude Haiku 3.5 by Anthropic — fast and cost-efficient model with vision support.', displayName: 'Claude Haiku 3.5', enabled: false, - family: 'claude', + family: 'claude-haiku', generation: 'claude-3.5', id: 'claude-3-5-haiku', knowledgeCutoff: '2024-07', @@ -37,7 +37,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ 'Claude Haiku 4.5 by Anthropic — next-gen Haiku with enhanced reasoning and vision.', displayName: 'Claude Haiku 4.5', enabled: false, - family: 'claude', + family: 'claude-haiku', generation: 'claude-4.5', id: 'claude-haiku-4-5', knowledgeCutoff: '2025-02', @@ -62,7 +62,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ 'Claude Opus 4.1 by Anthropic — premium reasoning model with deep analysis capabilities.', displayName: 'Claude Opus 4.1', enabled: false, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.1', id: 'claude-opus-4-1', knowledgeCutoff: '2025-01', @@ -87,7 +87,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ 'Claude Opus 4.5 by Anthropic — flagship model with top-tier reasoning and coding.', displayName: 'Claude Opus 4.5', enabled: false, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.5', id: 'claude-opus-4-5', knowledgeCutoff: '2025-05', @@ -112,7 +112,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ 'Claude Opus 4.6 by Anthropic — 1M context window flagship with advanced reasoning.', displayName: 'Claude Opus 4.6', enabled: false, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.6', id: 'claude-opus-4-6', knowledgeCutoff: '2025-05', @@ -137,7 +137,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ 'Claude Opus 4.7 by Anthropic — latest Opus with state-of-the-art reasoning and coding.', displayName: 'Claude Opus 4.7', enabled: true, - family: 'claude', + family: 'claude-opus', generation: 'claude-4.7', id: 'claude-opus-4-7', knowledgeCutoff: '2026-01', @@ -162,7 +162,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ 'Claude Sonnet 4 by Anthropic — balanced model with strong coding and reasoning abilities.', displayName: 'Claude Sonnet 4', enabled: false, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4', id: 'claude-sonnet-4', knowledgeCutoff: '2025-01', @@ -187,7 +187,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ 'Claude Sonnet 4.5 by Anthropic — improved Sonnet with enhanced coding performance.', displayName: 'Claude Sonnet 4.5', enabled: false, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.5', id: 'claude-sonnet-4-5', knowledgeCutoff: '2025-01', @@ -212,7 +212,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ 'Claude Sonnet 4.6 by Anthropic — latest Sonnet with superior coding and tool use.', displayName: 'Claude Sonnet 4.6', enabled: false, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.6', id: 'claude-sonnet-4-6', knowledgeCutoff: '2025-05', @@ -241,6 +241,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'gemini-3-flash', + knowledgeCutoff: '2025-01', maxOutput: 32_000, organization: 'Google', pricing: { @@ -263,6 +264,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-pro', + knowledgeCutoff: '2025-01', maxOutput: 32_000, organization: 'Google', pricing: { @@ -334,6 +336,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5', + knowledgeCutoff: '2024-09', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -356,6 +359,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-codex', + knowledgeCutoff: '2024-09', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -378,6 +382,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'gpt-5-nano', + knowledgeCutoff: '2024-05', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -400,6 +405,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1', + knowledgeCutoff: '2024-09', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -422,6 +428,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1-codex', + knowledgeCutoff: '2024-09', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -444,6 +451,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1-codex-max', + knowledgeCutoff: '2024-09', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -466,6 +474,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'gpt-5.1-codex-mini', + knowledgeCutoff: '2024-09', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -488,6 +497,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2', + knowledgeCutoff: '2025-08', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -510,6 +520,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'gpt-5.2-codex', + knowledgeCutoff: '2025-08', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -532,6 +543,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.3', id: 'gpt-5.3-codex', + knowledgeCutoff: '2025-08', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -576,6 +588,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.4', id: 'gpt-5.4', + knowledgeCutoff: '2025-08', maxOutput: 32_000, organization: 'OpenAI', pricing: { @@ -739,6 +752,7 @@ const opencodeZenChatModels: AIChatModelCard[] = [ displayName: 'Nemotron 3 Super Free', enabled: true, id: 'nemotron-3-super-free', + knowledgeCutoff: '2025-06', maxOutput: 32_000, organization: 'Nvidia', pricing: { diff --git a/packages/model-bank/src/aiModels/openrouter.ts b/packages/model-bank/src/aiModels/openrouter.ts index b9e5ce3239..51bdea445d 100644 --- a/packages/model-bank/src/aiModels/openrouter.ts +++ b/packages/model-bank/src/aiModels/openrouter.ts @@ -45,6 +45,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'google/gemini-3.1-flash-image-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { approximatePricePerImage: 0.067, @@ -73,6 +74,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'google/gemini-3-pro-image-preview', + knowledgeCutoff: '2025-01', maxOutput: 32_768, pricing: { approximatePricePerImage: 0.134, @@ -100,6 +102,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-flash-image', + knowledgeCutoff: '2025-06', maxOutput: 8192, pricing: { approximatePricePerImage: 0.039, @@ -226,6 +229,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-pro', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -248,6 +252,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-pro-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -270,6 +275,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-flash', + knowledgeCutoff: '2025-01', maxOutput: 65_535, pricing: { units: [ @@ -366,6 +372,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -388,6 +395,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1-mini', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -410,6 +418,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1-nano', + knowledgeCutoff: '2024-06', maxOutput: 32_768, pricing: { units: [ @@ -481,6 +490,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'openai/gpt-4o-mini', + knowledgeCutoff: '2023-10', maxOutput: 16_385, pricing: { units: [ @@ -502,6 +512,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'openai/gpt-4o', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 2.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -579,7 +590,7 @@ const openrouterChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.5 is Anthropic’s flagship model, combining top-tier intelligence with scalable performance for complex, high-quality reasoning tasks.', displayName: 'Claude Opus 4.5', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.5', id: 'anthropic/claude-opus-4.5', knowledgeCutoff: '2025-05', @@ -609,7 +620,7 @@ const openrouterChatModels: AIChatModelCard[] = [ contextWindowTokens: 200_000, description: 'Claude Sonnet 4.5 is Anthropic’s most intelligent model to date.', displayName: 'Claude Sonnet 4.5', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.5', id: 'anthropic/claude-sonnet-4.5', knowledgeCutoff: '2025-01', @@ -638,7 +649,7 @@ const openrouterChatModels: AIChatModelCard[] = [ description: 'Claude 3 Haiku is Anthropic’s fastest and most compact model, designed for near-instant responses with fast, accurate performance.', displayName: 'Claude 3 Haiku', - family: 'claude', + family: 'claude-haiku', generation: 'claude-3', id: 'anthropic/claude-3-haiku', knowledgeCutoff: '2023-08', @@ -667,7 +678,7 @@ const openrouterChatModels: AIChatModelCard[] = [ description: 'Claude 3.5 Haiku is Anthropic’s fastest next-gen model. Compared to Claude 3 Haiku, it improves across skills and surpasses the previous largest model Claude 3 Opus on many intelligence benchmarks.', displayName: 'Claude 3.5 Haiku', - family: 'claude', + family: 'claude-haiku', generation: 'claude-3.5', id: 'anthropic/claude-3.5-haiku', knowledgeCutoff: '2024-07', @@ -698,7 +709,7 @@ const openrouterChatModels: AIChatModelCard[] = [ description: 'Claude 3.7 Sonnet is Anthropic’s most intelligent model and the first hybrid reasoning model on the market. It can produce near-instant responses or extended step-by-step reasoning that users can see. Sonnet is especially strong at coding, data science, vision, and agent tasks.', displayName: 'Claude 3.7 Sonnet', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.7', id: 'anthropic/claude-3.7-sonnet', knowledgeCutoff: '2024-10', @@ -732,7 +743,7 @@ const openrouterChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4 can produce near-instant responses or extended step-by-step reasoning that users can see. API users can finely control how long the model thinks.', displayName: 'Claude Sonnet 4', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4', id: 'anthropic/claude-sonnet-4', knowledgeCutoff: '2025-01', @@ -759,7 +770,7 @@ const openrouterChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4 is Anthropic’s most powerful model for highly complex tasks, excelling in performance, intelligence, fluency, and comprehension.', displayName: 'Claude Opus 4', - family: 'claude', + family: 'claude-opus', generation: 'claude-4', id: 'anthropic/claude-opus-4', knowledgeCutoff: '2025-01', @@ -788,6 +799,7 @@ const openrouterChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'google/gemini-2.0-flash-001', + knowledgeCutoff: '2024-08', maxOutput: 8192, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/sambanova.ts b/packages/model-bank/src/aiModels/sambanova.ts index e19ffbce1d..bf855ac5da 100644 --- a/packages/model-bank/src/aiModels/sambanova.ts +++ b/packages/model-bank/src/aiModels/sambanova.ts @@ -87,7 +87,7 @@ const sambanovaChatModels: AIChatModelCard[] = [ enabled: true, family: 'llama', generation: 'llama-3.2', - id: 'Llama-3.2-90B-Vision-Instruct ', + id: 'Llama-3.2-90B-Vision-Instruct', knowledgeCutoff: '2023-12', pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/streamlake.ts b/packages/model-bank/src/aiModels/streamlake.ts index 83ddfb8f18..d9d71e7014 100644 --- a/packages/model-bank/src/aiModels/streamlake.ts +++ b/packages/model-bank/src/aiModels/streamlake.ts @@ -354,6 +354,7 @@ const streamlakeModels: AIChatModelCard[] = [ displayName: 'MiMo-V2 Pro', family: 'mimo', id: 'MiMo-V2-Pro', + knowledgeCutoff: '2024-12', maxOutput: 131_072, pricing: { currency: 'CNY', diff --git a/packages/model-bank/src/aiModels/togetherai.ts b/packages/model-bank/src/aiModels/togetherai.ts index 40bba5f589..48dbce2d8e 100644 --- a/packages/model-bank/src/aiModels/togetherai.ts +++ b/packages/model-bank/src/aiModels/togetherai.ts @@ -464,6 +464,7 @@ const togetheraiChatModels: AIChatModelCard[] = [ displayName: 'DBRX Instruct', family: 'dbrx', id: 'databricks/dbrx-instruct', + knowledgeCutoff: '2023-12', type: 'chat', }, { diff --git a/packages/model-bank/src/aiModels/vercelaigateway.ts b/packages/model-bank/src/aiModels/vercelaigateway.ts index c73bb91631..11d3c0c1e4 100644 --- a/packages/model-bank/src/aiModels/vercelaigateway.ts +++ b/packages/model-bank/src/aiModels/vercelaigateway.ts @@ -16,6 +16,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-pro', + knowledgeCutoff: '2025-01', pricing: { units: [ { name: 'textInput', rate: 2.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -34,7 +35,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.1 is a drop-in replacement for Opus 4, delivering excellent performance and precision for real-world coding and agent tasks. It reaches 74.5% on SWE-bench Verified and handles complex multi-step problems with greater rigor and attention to detail.', displayName: 'Claude Opus 4.1', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.1', id: 'anthropic/claude-opus-4.1', knowledgeCutoff: '2025-01', @@ -58,7 +59,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4 is Anthropic’s most powerful model and a top coding model, leading on SWE-bench (72.5%) and Terminal-bench (43.2%). It sustains performance on long tasks with thousands of steps and can work for hours, significantly extending agent capabilities.', displayName: 'Claude Opus 4', - family: 'claude', + family: 'claude-opus', generation: 'claude-4', id: 'anthropic/claude-opus-4', knowledgeCutoff: '2025-01', @@ -81,7 +82,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4 significantly improves on Sonnet 3.7, excelling at coding with a 72.7% SWE-bench score. It balances performance and efficiency for internal and external use cases, with enhanced controllability.', displayName: 'Claude Sonnet 4', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4', id: 'anthropic/claude-sonnet-4', knowledgeCutoff: '2025-01', @@ -108,6 +109,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'openai/gpt-5', + knowledgeCutoff: '2024-09', pricing: { units: [ { name: 'textInput', rate: 1.25, strategy: 'fixed', unit: 'millionTokens' }, @@ -182,7 +184,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ description: 'Claude 3.7 Sonnet is the first hybrid reasoning model and Anthropic’s most intelligent to date, delivering SOTA performance in coding, content creation, data analysis, and planning on top of Claude 3.5 Sonnet.', displayName: 'Claude 3.7 Sonnet', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.7', id: 'anthropic/claude-3.7-sonnet', knowledgeCutoff: '2024-10', @@ -206,7 +208,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ description: 'Claude 3.5 Sonnet strikes an ideal balance between intelligence and speed, especially for enterprise workloads, offering strong performance at lower cost and durability for large-scale AI deployments.', displayName: 'Claude 3.5 Sonnet', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.5', id: 'anthropic/claude-3.5-sonnet', knowledgeCutoff: '2024-04', @@ -230,7 +232,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ description: 'Claude 3 Opus is Anthropic’s most intelligent model with market-leading performance on highly complex tasks, handling open-ended prompts and novel scenarios with exceptional fluency and human-like understanding.', displayName: 'Claude 3 Opus', - family: 'claude', + family: 'claude-opus', generation: 'claude-3', id: 'anthropic/claude-3-opus', knowledgeCutoff: '2023-08', @@ -257,6 +259,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'openai/gpt-4o', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 2.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -278,6 +281,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'openai/gpt-5-mini', + knowledgeCutoff: '2024-05', pricing: { units: [ { name: 'textInput', rate: 0.25, strategy: 'fixed', unit: 'millionTokens' }, @@ -302,6 +306,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'openai/gpt-5-nano', + knowledgeCutoff: '2024-05', pricing: { units: [ { name: 'textInput', rate: 0.05, strategy: 'fixed', unit: 'millionTokens' }, @@ -423,6 +428,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1', + knowledgeCutoff: '2024-06', pricing: { units: [ { name: 'textInput', rate: 2, strategy: 'fixed', unit: 'millionTokens' }, @@ -682,6 +688,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'google/gemini-2.0-flash', + knowledgeCutoff: '2024-08', pricing: { units: [ { name: 'textInput', rate: 0.1, strategy: 'fixed', unit: 'millionTokens' }, @@ -702,6 +709,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'google/gemini-2.0-flash-lite', + knowledgeCutoff: '2024-08', pricing: { units: [ { name: 'textInput', rate: 0.075, strategy: 'fixed', unit: 'millionTokens' }, @@ -723,6 +731,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-flash', + knowledgeCutoff: '2025-01', pricing: { units: [ { name: 'textInput', rate: 0.3, strategy: 'fixed', unit: 'millionTokens' }, @@ -744,6 +753,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-flash-lite', + knowledgeCutoff: '2025-01', pricing: { units: [ { name: 'textInput', rate: 0.1, strategy: 'fixed', unit: 'millionTokens' }, @@ -764,6 +774,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-4', id: 'xai/grok-4', + knowledgeCutoff: '2024-11', pricing: { units: [ { name: 'textInput', rate: 3, strategy: 'fixed', unit: 'millionTokens' }, @@ -784,6 +795,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'xai/grok-3-mini-fast', + knowledgeCutoff: '2024-11', pricing: { units: [ { name: 'textInput', rate: 0.6, strategy: 'fixed', unit: 'millionTokens' }, @@ -804,6 +816,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'xai/grok-3-mini', + knowledgeCutoff: '2024-11', pricing: { units: [ { name: 'textInput', rate: 0.3, strategy: 'fixed', unit: 'millionTokens' }, @@ -824,6 +837,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'xai/grok-3-fast', + knowledgeCutoff: '2024-11', pricing: { units: [ { name: 'textInput', rate: 5, strategy: 'fixed', unit: 'millionTokens' }, @@ -844,6 +858,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-3', id: 'xai/grok-3', + knowledgeCutoff: '2024-11', pricing: { units: [ { name: 'textInput', rate: 3, strategy: 'fixed', unit: 'millionTokens' }, @@ -1194,6 +1209,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ displayName: 'Mistral Large', family: 'mistral', id: 'mistral/mistral-large', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 2, strategy: 'fixed', unit: 'millionTokens' }, @@ -1338,6 +1354,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'openai/gpt-3.5-turbo', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 0.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1357,6 +1374,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-3.5', id: 'openai/gpt-3.5-turbo-instruct', + knowledgeCutoff: '2021-09', pricing: { units: [ { name: 'textInput', rate: 1.5, strategy: 'fixed', unit: 'millionTokens' }, @@ -1376,6 +1394,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4', id: 'openai/gpt-4-turbo', + knowledgeCutoff: '2023-12', pricing: { units: [ { name: 'textInput', rate: 10, strategy: 'fixed', unit: 'millionTokens' }, @@ -1396,6 +1415,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1-mini', + knowledgeCutoff: '2024-06', pricing: { units: [ { name: 'textInput', rate: 0.4, strategy: 'fixed', unit: 'millionTokens' }, @@ -1416,6 +1436,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1-nano', + knowledgeCutoff: '2024-06', pricing: { units: [ { name: 'textInput', rate: 0.1, strategy: 'fixed', unit: 'millionTokens' }, @@ -1437,6 +1458,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'openai/gpt-4o-mini', + knowledgeCutoff: '2023-10', pricing: { units: [ { name: 'textInput', rate: 0.15, strategy: 'fixed', unit: 'millionTokens' }, @@ -1598,7 +1620,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ description: 'Claude 3.5 Haiku is the next generation of our fastest model. It matches Claude 3 Haiku’s speed while improving across skills and surpassing the previous flagship Claude 3 Opus on many benchmarks.', displayName: 'Claude 3.5 Haiku', - family: 'claude', + family: 'claude-haiku', generation: 'claude-3.5', id: 'anthropic/claude-3.5-haiku', knowledgeCutoff: '2024-07', @@ -1621,7 +1643,7 @@ const vercelAIGatewayChatModels: AIChatModelCard[] = [ description: 'Claude 3 Haiku is Anthropic’s fastest model, designed for enterprise workloads with longer prompts. It can quickly analyze large documents like quarterly reports, contracts, or legal cases at half the cost of peers.', displayName: 'Claude 3 Haiku', - family: 'claude', + family: 'claude-haiku', generation: 'claude-3', id: 'anthropic/claude-3-haiku', knowledgeCutoff: '2023-08', diff --git a/packages/model-bank/src/aiModels/vertexai.ts b/packages/model-bank/src/aiModels/vertexai.ts index 7d88967c71..2c8f899eb4 100644 --- a/packages/model-bank/src/aiModels/vertexai.ts +++ b/packages/model-bank/src/aiModels/vertexai.ts @@ -21,6 +21,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.5', id: 'gemini-3.5-flash', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -61,6 +62,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-flash-image-preview', + knowledgeCutoff: '2025-01', maxOutput: 32_768, pricing: { approximatePricePerImage: 0.067, @@ -96,6 +98,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-pro-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -186,6 +189,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-flash-lite', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -223,6 +227,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3.1', id: 'gemini-3.1-flash-lite-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -316,6 +321,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'gemini-3-flash-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -355,6 +361,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'gemini-3-pro-image-preview', + knowledgeCutoff: '2025-01', maxOutput: 32_768, pricing: { approximatePricePerImage: 0.134, @@ -387,6 +394,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-pro', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -419,6 +427,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-pro-preview-05-06', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -442,6 +451,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-pro-preview-03-25', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -465,6 +475,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -496,6 +507,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash-preview-04-17', + knowledgeCutoff: '2025-01', maxOutput: 65_536, pricing: { units: [ @@ -518,6 +530,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash-image', + knowledgeCutoff: '2025-06', maxOutput: 8192, pricing: { approximatePricePerImage: 0.039, @@ -544,6 +557,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash-lite', + knowledgeCutoff: '2025-01', maxOutput: 64_000, pricing: { units: [ @@ -573,6 +587,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'gemini-2.5-flash-lite-preview-06-17', + knowledgeCutoff: '2025-01', maxOutput: 64_000, pricing: { units: [ @@ -600,6 +615,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'gemini-2.0-flash', + knowledgeCutoff: '2024-08', maxOutput: 8192, pricing: { units: [ @@ -622,6 +638,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'gemini-2.0-flash-lite', + knowledgeCutoff: '2024-08', maxOutput: 8192, pricing: { units: [ @@ -645,6 +662,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-flash-002', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ @@ -667,6 +685,7 @@ const vertexaiChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-1.5', id: 'gemini-1.5-pro-002', + knowledgeCutoff: '2024-05', maxOutput: 8192, pricing: { units: [ diff --git a/packages/model-bank/src/aiModels/xai.ts b/packages/model-bank/src/aiModels/xai.ts index 21331d159b..c8e01b8d8a 100644 --- a/packages/model-bank/src/aiModels/xai.ts +++ b/packages/model-bank/src/aiModels/xai.ts @@ -16,6 +16,7 @@ const xaiChatModels: AIChatModelCard[] = [ family: 'grok', generation: 'grok-4.3', id: 'grok-4.3', + knowledgeCutoff: '2025-12', pricing: { units: [ { diff --git a/packages/model-bank/src/aiModels/xiaomimimo.ts b/packages/model-bank/src/aiModels/xiaomimimo.ts index 30bc47fac0..77c991aa01 100644 --- a/packages/model-bank/src/aiModels/xiaomimimo.ts +++ b/packages/model-bank/src/aiModels/xiaomimimo.ts @@ -15,6 +15,7 @@ const xiaomimimoChatModels: AIChatModelCard[] = [ enabled: true, family: 'mimo', id: 'mimo-v2.5-pro', + knowledgeCutoff: '2024-12', maxOutput: 131_072, pricing: { currency: 'CNY', @@ -47,6 +48,7 @@ const xiaomimimoChatModels: AIChatModelCard[] = [ enabled: true, family: 'mimo', id: 'mimo-v2.5', + knowledgeCutoff: '2024-12', maxOutput: 131_072, pricing: { currency: 'CNY', @@ -76,6 +78,7 @@ const xiaomimimoChatModels: AIChatModelCard[] = [ displayName: 'MiMo-V2 Flash', family: 'mimo', id: 'mimo-v2-flash', + knowledgeCutoff: '2024-12', maxOutput: 65_536, pricing: { currency: 'CNY', diff --git a/packages/model-bank/src/aiModels/zenmux.ts b/packages/model-bank/src/aiModels/zenmux.ts index 1b41b547cb..9c3dafd7c9 100644 --- a/packages/model-bank/src/aiModels/zenmux.ts +++ b/packages/model-bank/src/aiModels/zenmux.ts @@ -24,6 +24,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'openai/gpt-5.2', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -53,6 +54,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'openai/gpt-5.2-pro', + knowledgeCutoff: '2025-08', maxOutput: 128_000, pricing: { units: [ @@ -79,6 +81,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.2', id: 'openai/gpt-5.2-chat', + knowledgeCutoff: '2025-08', maxOutput: 16_384, pricing: { units: [ @@ -104,6 +107,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'google/gemini-3-pro-image-preview', + knowledgeCutoff: '2025-01', maxOutput: 32_768, pricing: { units: [ @@ -128,6 +132,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-3', id: 'google/gemini-3-pro-preview', + knowledgeCutoff: '2025-01', maxOutput: 65_530, pricing: { units: [ @@ -156,6 +161,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'openai/gpt-5.1', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -181,6 +187,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'openai/gpt-5.1-chat', + knowledgeCutoff: '2024-09', maxOutput: 16_380, pricing: { units: [ @@ -203,6 +210,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'openai/gpt-5.1-codex', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -228,6 +236,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5.1', id: 'openai/gpt-5.1-codex-mini', + knowledgeCutoff: '2024-09', maxOutput: 100_000, pricing: { units: [ @@ -551,7 +560,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ description: 'Claude Haiku 4.5 is Anthropic’s high-performance fast model, delivering very low latency while maintaining high accuracy.', displayName: 'Claude Haiku 4.5', - family: 'claude', + family: 'claude-haiku', generation: 'claude-4.5', id: 'anthropic/claude-haiku-4.5', knowledgeCutoff: '2025-02', @@ -641,6 +650,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-pro', + knowledgeCutoff: '2025-01', maxOutput: 65_530, pricing: { units: [ @@ -669,6 +679,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-flash', + knowledgeCutoff: '2025-01', maxOutput: 65_530, pricing: { units: [ @@ -696,6 +707,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'openai/gpt-5-pro', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -721,6 +733,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'openai/gpt-5', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -745,6 +758,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'openai/gpt-5-chat', + knowledgeCutoff: '2024-09', maxOutput: 16_380, pricing: { units: [ @@ -766,6 +780,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'openai/gpt-5-mini', + knowledgeCutoff: '2024-05', maxOutput: 128_000, pricing: { units: [ @@ -790,6 +805,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'openai/gpt-5-nano', + knowledgeCutoff: '2024-05', maxOutput: 128_000, pricing: { units: [ @@ -814,6 +830,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-5', id: 'openai/gpt-5-codex', + knowledgeCutoff: '2024-09', maxOutput: 128_000, pricing: { units: [ @@ -838,6 +855,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1', + knowledgeCutoff: '2024-06', maxOutput: 32_770, pricing: { units: [ @@ -857,6 +875,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1-mini', + knowledgeCutoff: '2024-06', maxOutput: 32_770, pricing: { units: [ @@ -877,6 +896,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4.1', id: 'openai/gpt-4.1-nano', + knowledgeCutoff: '2024-06', maxOutput: 32_770, pricing: { units: [ @@ -1039,7 +1059,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ description: 'Claude Opus 4.5 is Anthropic’s flagship model, combining outstanding intelligence with scalable performance, ideal for complex tasks requiring the highest-quality responses and reasoning.', displayName: 'Claude Opus 4.5', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.5', id: 'claude-opus-4-5-20251101', knowledgeCutoff: '2025-05', @@ -1069,7 +1089,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ description: 'Opus 4.1 is Anthropic’s high-end model optimized for programming, complex reasoning, and long-running tasks.', displayName: 'Claude Opus 4.1', - family: 'claude', + family: 'claude-opus', generation: 'claude-4.1', id: 'anthropic/claude-opus-4.1', knowledgeCutoff: '2025-01', @@ -1097,7 +1117,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ description: 'Opus 4 is Anthropic’s flagship model designed for complex tasks and enterprise applications.', displayName: 'Claude Opus 4', - family: 'claude', + family: 'claude-opus', generation: 'claude-4', id: 'anthropic/claude-opus-4', knowledgeCutoff: '2025-01', @@ -1128,6 +1148,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-flash-image', + knowledgeCutoff: '2025-06', maxOutput: 8192, pricing: { approximatePricePerImage: 0.039, @@ -1150,7 +1171,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4.5 is Anthropic’s latest hybrid reasoning model optimized for complex reasoning and coding.', displayName: 'Claude Sonnet 4.5', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4.5', id: 'anthropic/claude-sonnet-4.5', knowledgeCutoff: '2025-01', @@ -1176,7 +1197,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ description: 'Claude Sonnet 4 is Anthropic’s hybrid reasoning model with mixed thinking and non-thinking capability.', displayName: 'Claude Sonnet 4', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-4', id: 'anthropic/claude-sonnet-4', knowledgeCutoff: '2025-01', @@ -1225,6 +1246,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'openai/gpt-4o', + knowledgeCutoff: '2023-10', maxOutput: 16_380, pricing: { units: [ @@ -1245,6 +1267,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gpt', generation: 'gpt-4o', id: 'openai/gpt-4o-mini', + knowledgeCutoff: '2023-10', maxOutput: 16_380, pricing: { units: [ @@ -1303,7 +1326,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ description: 'Claude 3.5 Haiku features enhanced speed, coding accuracy, and tool use, suitable for scenarios with demanding requirements for speed and tool interaction.', displayName: 'Claude 3.5 Haiku', - family: 'claude', + family: 'claude-haiku', generation: 'claude-3.5', id: 'anthropic/claude-3.5-haiku', knowledgeCutoff: '2024-07', @@ -1325,7 +1348,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ description: 'Claude 3.5 Sonnet is the fast, efficient model in the Sonnet family, offering better coding and reasoning performance, with some versions gradually replaced by Sonnet 3.7 and later.', displayName: 'Claude 3.5 Sonnet', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.5', id: 'anthropic/claude-3.5-sonnet', knowledgeCutoff: '2024-04', @@ -1347,7 +1370,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ description: 'Claude 3.7 Sonnet is an upgraded Sonnet model with stronger reasoning and coding, suitable for enterprise-grade complex tasks.', displayName: 'Claude 3.7 Sonnet', - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.7', id: 'anthropic/claude-3.7-sonnet', knowledgeCutoff: '2024-10', @@ -1395,6 +1418,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'google/gemini-2.0-flash', + knowledgeCutoff: '2024-08', maxOutput: 8192, pricing: { units: [ @@ -1417,6 +1441,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.0', id: 'google/gemini-2.0-flash-lite-001', + knowledgeCutoff: '2024-08', maxOutput: 8192, pricing: { units: [ @@ -1439,6 +1464,7 @@ const zenmuxChatModels: AIChatModelCard[] = [ family: 'gemini', generation: 'gemini-2.5', id: 'google/gemini-2.5-flash-lite', + knowledgeCutoff: '2025-01', maxOutput: 65_530, pricing: { units: [ diff --git a/packages/model-bank/src/types/aiModel.ts b/packages/model-bank/src/types/aiModel.ts index 24bd004410..3c45b53451 100644 --- a/packages/model-bank/src/types/aiModel.ts +++ b/packages/model-bank/src/types/aiModel.ts @@ -218,9 +218,9 @@ export interface AIBaseModelCard { displayName?: string; enabled?: boolean; /** - * model lineage, finer than `organization` (e.g. 'claude', 'gpt', 'o-series', - * 'qwen', 'deepseek'). Lets the UI group models and match the same model - * across aggregator providers. + * product-line lineage, finer than `organization` (e.g. 'claude-opus', + * 'claude-mythos', 'gpt', 'o-series', 'qwen'). Families contain generations; + * lets the UI group models and match the same model across aggregator providers. */ family?: string; /** diff --git a/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts b/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts index 4eabe5010a..71a1ead6b4 100644 --- a/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +++ b/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts @@ -3426,7 +3426,7 @@ describe('LobeOpenAICompatibleFactory', () => { "Claude 3.7 Sonnet is Anthropic's fastest next-gen model. Compared to Claude 3 Haiku, it improves across skills and surpasses the previous flagship Claude 3 Opus on many intelligence benchmarks.", displayName: 'Claude 3.7 Sonnet', enabled: false, - family: 'claude', + family: 'claude-sonnet', generation: 'claude-3.7', id: 'us.anthropic.claude-3-7-sonnet-20250219-v1:0', knowledgeCutoff: '2024-10', diff --git a/src/features/Electron/navigation/useTabNavigation.ts b/src/features/Electron/navigation/useTabNavigation.ts index 08b4197f11..225dcc9a75 100644 --- a/src/features/Electron/navigation/useTabNavigation.ts +++ b/src/features/Electron/navigation/useTabNavigation.ts @@ -10,6 +10,7 @@ export const useTabNavigation = () => { const location = useLocation(); const activateTab = useElectronStore((s) => s.activateTab); + const addTab = useElectronStore((s) => s.addTab); const updateTab = useElectronStore((s) => s.updateTab); const updateTabCache = useElectronStore((s) => s.updateTabCache); const loadTabs = useElectronStore((s) => s.loadTabs); @@ -41,8 +42,14 @@ export const useTabNavigation = () => { return; } - if (activeTabId) updateTab(activeTabId, currentUrl); - }, [location.pathname, location.search, activateTab, updateTab]); + if (activeTabId && tabs.some((t) => t.id === activeTabId)) { + updateTab(activeTabId, currentUrl); + } else { + // First launch (or stale activeTabId): make the current page visible as a tab, + // so the tab bar and its "+" entry are always discoverable. + addTab(currentUrl); + } + }, [location.pathname, location.search, activateTab, addTab, updateTab]); useEffect(() => { if (!currentRouteMeta || !currentRouteMetaUrl) return; diff --git a/src/features/Electron/titlebar/TabBar/TabItem.tsx b/src/features/Electron/titlebar/TabBar/TabItem.tsx index 49e2f73cfb..154a709db8 100644 --- a/src/features/Electron/titlebar/TabBar/TabItem.tsx +++ b/src/features/Electron/titlebar/TabBar/TabItem.tsx @@ -69,11 +69,13 @@ const TabItem = memo( const contextMenuItems = useCallback( (): GenericItemType[] => [ { + disabled: totalCount === 1, key: 'closeCurrentTab', label: t('tab.closeCurrentTab'), onClick: () => onClose(id), }, { + disabled: totalCount === 1, key: 'closeOtherTabs', label: t('tab.closeOtherTabs'), onClick: () => onCloseOthers(id), @@ -129,7 +131,9 @@ const TabItem = memo( ) )} {meta.title} - + {totalCount > 1 && ( + + )} ); diff --git a/src/routes/(main)/agent/_layout/AgentIdSync.tsx b/src/routes/(main)/agent/_layout/AgentIdSync.tsx index 8e60b1b576..9af604e2a2 100644 --- a/src/routes/(main)/agent/_layout/AgentIdSync.tsx +++ b/src/routes/(main)/agent/_layout/AgentIdSync.tsx @@ -1,19 +1,16 @@ import { BUILTIN_AGENT_SLUGS } from '@lobechat/builtin-agents'; -import { useMount, usePrevious, useUnmount } from 'ahooks'; -import { useEffect, useMemo, useRef } from 'react'; +import { usePrevious } from 'ahooks'; +import { useEffect, useLayoutEffect, useMemo, useRef } from 'react'; import { useLocation, useParams, useSearchParams } from 'react-router-dom'; import { useWorkspaceAwareNavigate } from '@/features/Workspace/useWorkspaceAwareNavigate'; import { useAgentStore } from '@/store/agent'; import { builtinAgentSelectors } from '@/store/agent/selectors'; import { useChatStore } from '@/store/chat'; -import { createStoreUpdater } from '@/store/utils/createStoreUpdater'; const BUILTIN_SLUG_SET = new Set(Object.values(BUILTIN_AGENT_SLUGS)); const AgentIdSync = () => { - const useStoreUpdater = createStoreUpdater(useAgentStore); - const useChatStoreUpdater = createStoreUpdater(useChatStore); const params = useParams<{ aid?: string; topicId?: string }>(); const [searchParams] = useSearchParams(); const searchParamsRef = useRef(searchParams); @@ -44,8 +41,18 @@ const AgentIdSync = () => { const prevAgentId = usePrevious(activeId); - useStoreUpdater('activeAgentId', activeId); - useChatStoreUpdater('activeAgentId', activeId); + // Sync activeAgentId before paint (layout effect, not passive effect) so a + // tab/route switch back to an agent with cached `agentMap` data renders the + // real UI on the first frame instead of flashing a skeleton. + useLayoutEffect(() => { + if (!activeId) return; + + if (useAgentStore.getState().activeAgentId !== activeId) + useAgentStore.setState({ activeAgentId: activeId }, false, 'AgentIdSync/syncAgentId'); + + if (useChatStore.getState().activeAgentId !== activeId) + useChatStore.setState({ activeAgentId: activeId }, false, 'AgentIdSync/syncAgentId'); + }, [activeId]); // Reset activeTopicId when switching to a different agent // This prevents messages from being saved to the wrong topic bucket @@ -65,19 +72,23 @@ const AgentIdSync = () => { // unread topics and is cleared per-topic when the user actually opens each one. }, [activeId, prevAgentId]); - useMount(() => { - useChatStore.setState({ activeAgentId: activeId }, false, 'AgentIdSync/mountAgentId'); - }); - - // Clear activeAgentId when unmounting (leaving chat page) - useUnmount(() => { - useAgentStore.setState({ activeAgentId: undefined }, false, 'AgentIdSync/unmountAgentId'); - useChatStore.setState( - { activeAgentId: undefined, activeTopicId: undefined }, - false, - 'AgentIdSync/unmountAgentId', - ); - }); + // Clear activeAgentId when unmounting (leaving chat page). + // Must be a layout-effect cleanup (not a passive `useUnmount`): in a route + // switch both run in one commit, and React runs all layout cleanups of the + // removed tree BEFORE the new tree's layout effects — so the next route's + // backfill above always wins over this clear. A passive cleanup would run + // after it and wipe the freshly synced id. + useLayoutEffect( + () => () => { + useAgentStore.setState({ activeAgentId: undefined }, false, 'AgentIdSync/unmountAgentId'); + useChatStore.setState( + { activeAgentId: undefined, activeTopicId: undefined }, + false, + 'AgentIdSync/unmountAgentId', + ); + }, + [], + ); return null; }; diff --git a/src/routes/(main)/agent/features/Conversation/MainChatInput/AgentConfigError.tsx b/src/routes/(main)/agent/features/Conversation/MainChatInput/AgentConfigError.tsx new file mode 100644 index 0000000000..de74ce08d0 --- /dev/null +++ b/src/routes/(main)/agent/features/Conversation/MainChatInput/AgentConfigError.tsx @@ -0,0 +1,41 @@ +'use client'; + +import { Alert, Button } from '@lobehub/ui'; +import { memo } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useAgentStore } from '@/store/agent'; +import { agentSelectors } from '@/store/agent/selectors'; + +/** + * Surfaces an agent-config fetch failure above the chat input with a retry + * button. Only shown when the config is still missing (`isAgentConfigLoading`) + * — a failed background revalidation over cached data stays silent. + */ +const AgentConfigError = memo(() => { + const { t } = useTranslation('chat'); + const errorMessage = useAgentStore(agentSelectors.currentAgentConfigError); + const isConfigMissing = useAgentStore(agentSelectors.isAgentConfigLoading); + const retryAgentConfigFetch = useAgentStore((s) => s.retryAgentConfigFetch); + + if (!errorMessage || !isConfigMissing) return null; + + return ( + retryAgentConfigFetch()}> + {t('agentConfigError.retry')} + + } + /> + ); +}); + +AgentConfigError.displayName = 'AgentConfigError'; + +export default AgentConfigError; diff --git a/src/routes/(main)/agent/features/Conversation/MainChatInput/index.tsx b/src/routes/(main)/agent/features/Conversation/MainChatInput/index.tsx index 8fa903c27a..ccc65dafa0 100644 --- a/src/routes/(main)/agent/features/Conversation/MainChatInput/index.tsx +++ b/src/routes/(main)/agent/features/Conversation/MainChatInput/index.tsx @@ -11,6 +11,7 @@ import { useChatStore } from '@/store/chat'; import { useUserStore } from '@/store/user'; import { userGeneralSettingsSelectors } from '@/store/user/selectors'; +import AgentConfigError from './AgentConfigError'; import { useSendMenuItems } from './useSendMenuItems'; const contextWindowRightActions: ActionKeys[] = ['contextWindow']; @@ -39,19 +40,22 @@ const MainChatInput = memo(() => { const leftActions: ActionKeys[] = useMemo(() => ['model', 'plus'], []); return ( - { - // Sync to global ChatStore for compatibility with other features - useChatStore.setState({ mainInputEditor: instance }); - }} - /> + <> + + { + // Sync to global ChatStore for compatibility with other features + useChatStore.setState({ mainInputEditor: instance }); + }} + /> + ); }); diff --git a/src/routes/(main)/home/_layout/HomeAgentIdSync.tsx b/src/routes/(main)/home/_layout/HomeAgentIdSync.tsx index 35bebdd361..1198d4eb4b 100644 --- a/src/routes/(main)/home/_layout/HomeAgentIdSync.tsx +++ b/src/routes/(main)/home/_layout/HomeAgentIdSync.tsx @@ -1,21 +1,30 @@ -import { useUnmount } from 'ahooks'; -import { createStoreUpdater } from 'zustand-utils'; +import { useLayoutEffect } from 'react'; import { useAgentStore } from '@/store/agent'; import { builtinAgentSelectors } from '@/store/agent/selectors'; const HomeAgentIdSync = () => { - const useAgentStoreUpdater = createStoreUpdater(useAgentStore); - const inboxAgentId = useAgentStore(builtinAgentSelectors.inboxAgentId); - // Sync inbox agent id to activeAgentId when on home page - useAgentStoreUpdater('activeAgentId', inboxAgentId); + // Sync inbox agent id to activeAgentId when on home page. Layout effect (not + // passive) so it stays ordered with AgentIdSync's layout-effect clear/backfill: + // in a single route-switch commit, removed-tree layout cleanups always run + // before new-tree layout effects. + useLayoutEffect(() => { + if (!inboxAgentId) return; - // Clear activeAgentId when unmounting (leaving home page) - useUnmount(() => { - useAgentStore.setState({ activeAgentId: undefined }); - }); + if (useAgentStore.getState().activeAgentId !== inboxAgentId) + useAgentStore.setState({ activeAgentId: inboxAgentId }, false, 'HomeAgentIdSync/syncAgentId'); + }, [inboxAgentId]); + + // Clear activeAgentId when unmounting (leaving home page) — layout cleanup + // for the same ordering reason as above. + useLayoutEffect( + () => () => { + useAgentStore.setState({ activeAgentId: undefined }, false, 'HomeAgentIdSync/unmountAgentId'); + }, + [], + ); return null; }; diff --git a/src/store/agent/selectors/selectors.ts b/src/store/agent/selectors/selectors.ts index 212b312656..a678af3355 100644 --- a/src/store/agent/selectors/selectors.ts +++ b/src/store/agent/selectors/selectors.ts @@ -227,6 +227,16 @@ const currentKnowledgeIds = (s: AgentStoreState) => { const isAgentConfigLoading = (s: AgentStoreState) => !s.activeAgentId || !s.agentMap[s.activeAgentId]; +/** + * Fetch error for the active agent's config (undefined when none). + * Distinguishes "fetch failed" from `isAgentConfigLoading`'s "no data yet", + * so failure surfaces a retry UI instead of an endless skeleton. + */ +const currentAgentConfigError = (s: AgentStoreState): string | undefined => + s.activeAgentId ? s.agentConfigErrorMap[s.activeAgentId] : undefined; + +const isAgentConfigError = (s: AgentStoreState) => !!currentAgentConfigError(s); + /** * Get agent's slug by ID (used to identify builtin agents) */ @@ -320,6 +330,7 @@ export const agentSelectors = { currentAgentAvatar, currentAgentBackgroundColor, currentAgentConfig, + currentAgentConfigError, currentAgentDescription, currentAgentFiles, currentAgentKnowledgeBases, @@ -348,6 +359,7 @@ export const agentSelectors = { hasSystemRole, inboxAgentConfig, inboxAgentModel, + isAgentConfigError, isAgentConfigLoading, isAgentModeEnabled, isCurrentAgentExternal, diff --git a/src/store/agent/slices/agent/action.test.ts b/src/store/agent/slices/agent/action.test.ts index eb46725160..ce4dad9cf9 100644 --- a/src/store/agent/slices/agent/action.test.ts +++ b/src/store/agent/slices/agent/action.test.ts @@ -546,6 +546,40 @@ describe('AgentSlice Actions', () => { expect(useAgentStore.getState().activeAgentId).toBe('agent-1'); expect(useAgentStore.getState().agentMap['agent-1']).toBeDefined(); }); + + it('should record fetch error in agentConfigErrorMap and clear it on retry', async () => { + const error = Object.assign(new Error('boom'), { meta: { shouldRetry: false } }); + vi.mocked(agentService.getAgentConfigById).mockRejectedValueOnce(error); + + renderHook(() => useAgentStore().useFetchAgentConfig(true, 'agent-err'), { + wrapper: withSWR, + }); + + await waitFor(() => + expect(useAgentStore.getState().agentConfigErrorMap['agent-err']).toBe('boom'), + ); + + await act(async () => { + await useAgentStore.getState().retryAgentConfigFetch('agent-err'); + }); + + expect(useAgentStore.getState().agentConfigErrorMap['agent-err']).toBeUndefined(); + }); + + it('should clear a stale fetch error once data arrives', async () => { + useAgentStore.setState({ agentConfigErrorMap: { 'agent-1': 'boom' } }); + + const mockAgentConfig = { id: 'agent-1', model: 'gpt-4' } as LobeAgentConfig; + vi.mocked(agentService.getAgentConfigById).mockResolvedValueOnce(mockAgentConfig as any); + + const { result } = renderHook(() => useAgentStore().useFetchAgentConfig(true, 'agent-1'), { + wrapper: withSWR, + }); + + await waitFor(() => expect(result.current.data).toEqual(mockAgentConfig)); + + expect(useAgentStore.getState().agentConfigErrorMap['agent-1']).toBeUndefined(); + }); }); describe('useHydrateAgentConfig', () => { diff --git a/src/store/agent/slices/agent/action.ts b/src/store/agent/slices/agent/action.ts index 033c5afeee..1dd5c7a044 100644 --- a/src/store/agent/slices/agent/action.ts +++ b/src/store/agent/slices/agent/action.ts @@ -300,11 +300,53 @@ export class AgentSliceActionImpl { if (!data) return; this.#get().internal_dispatchAgentMap(agentId, data); this.#set({ activeAgentId: data.id }, false, 'fetchAgentConfig'); + this.#clearAgentConfigError(agentId); + }, + onError: (error) => { + this.#set( + (state) => ({ + agentConfigErrorMap: { + ...state.agentConfigErrorMap, + [agentId]: error?.message || String(error), + }, + }), + false, + 'fetchAgentConfig/error', + ); }, }, ); }; + /** + * Re-trigger the agent config fetch after a failure. Clears the recorded + * error first so consumers fall back to the loading skeleton, then + * revalidates every SWR entry for this agent (keys may carry a workspace + * suffix, hence the filter form). + */ + retryAgentConfigFetch = async (agentId?: string): Promise => { + const id = agentId ?? this.#get().activeAgentId; + if (!id) return; + + this.#clearAgentConfigError(id); + + await mutate((key) => Array.isArray(key) && key[0] === FETCH_AGENT_CONFIG_KEY && key[1] === id); + }; + + #clearAgentConfigError = (agentId: string) => { + if (!this.#get().agentConfigErrorMap[agentId]) return; + + this.#set( + (state) => { + const next = { ...state.agentConfigErrorMap }; + delete next[agentId]; + return { agentConfigErrorMap: next }; + }, + false, + 'clearAgentConfigError', + ); + }; + useHydrateAgentConfig = ( isLogin: boolean | undefined, agentId: string, diff --git a/src/store/agent/slices/agent/initialState.ts b/src/store/agent/slices/agent/initialState.ts index 187da3b38f..cf3f359e2d 100644 --- a/src/store/agent/slices/agent/initialState.ts +++ b/src/store/agent/slices/agent/initialState.ts @@ -13,6 +13,12 @@ export type SaveStatus = 'idle' | 'saving' | 'saved'; export interface AgentSliceState { activeAgentId?: string; + /** + * Per-agent config fetch error message. Lets the UI distinguish "fetch + * failed" from "still loading" instead of showing an endless skeleton + * (e.g. 401s are not retried by SWR). Cleared on successful fetch / retry. + */ + agentConfigErrorMap: Record; agentDocumentsMap: Record; agentMap: Record>; agentSettingInstance?: AgentSettingsInstance | null; @@ -53,6 +59,7 @@ export interface AgentSliceState { } export const initialAgentSliceState: AgentSliceState = { + agentConfigErrorMap: {}, agentDocumentsMap: {}, agentMap: {}, availableAgents: undefined, diff --git a/src/utils/server/__snapshots__/parseModels.test.ts.snap b/src/utils/server/__snapshots__/parseModels.test.ts.snap index 421baa03ee..c40f612c59 100644 --- a/src/utils/server/__snapshots__/parseModels.test.ts.snap +++ b/src/utils/server/__snapshots__/parseModels.test.ts.snap @@ -113,7 +113,7 @@ exports[`transformToChatModelCards > should have file with builtin models like g "family": "gpt", "generation": "gpt-4", "id": "gpt-4-0125-preview", - "knowledgeCutoff": undefined, + "knowledgeCutoff": "2023-12", "pricing": { "units": [ {