Skip to content

Commit a0566aa

Browse files
ericyangpanclaude
andcommitted
refactor(lib): update library utilities and generators
Update metadata generators, pricing utilities, benchmark handling, and regenerate metadata/model/provider indexes to align with updated manifest schemas. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 249c7ad commit a0566aa

File tree

9 files changed

+86
-59
lines changed

9 files changed

+86
-59
lines changed

src/lib/benchmarks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export function formatBenchmarkValue(key: string, value: number): string {
2323
* @param benchmarks - The benchmarks object to check
2424
* @returns True if at least one benchmark has a non-null value
2525
*/
26-
export function hasBenchmarks(benchmarks: Record<string, number | null> | undefined): boolean {
26+
export function hasBenchmarks(benchmarks: object | null | undefined): boolean {
2727
if (!benchmarks) return false
2828
return Object.values(benchmarks).some(value => value !== null && value !== undefined)
2929
}

src/lib/generated/metadata.ts

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -46,64 +46,64 @@ export const articlesMetadata: Record<string, ArticleMetadata[]> = {
4646
es: [
4747
{
4848
slug: 'getting-started-with-ai-coding',
49-
title: 'Getting Started with AI Coding: A Comprehensive Guide',
49+
title: 'Comenzando con AI Coding: Una Guía Completa',
5050
description:
51-
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
51+
'Aprende cómo configurar tu primer entorno de desarrollo impulsado por IA con IDEs, CLIs y las herramientas esenciales que necesitas para impulsar tu productividad de programación.',
5252
date: '2025-01-15',
5353
},
5454
{
5555
slug: 'mcp-servers-explained',
56-
title: 'Understanding MCP Servers: The Future of AI Context',
56+
title: 'Entendiendo los Servidores MCP: El Futuro del Contexto de IA',
5757
description:
58-
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
58+
'Un análisis profundo de los servidores del Protocolo de Contexto de Modelo, cómo funcionan y por qué son cruciales para construir asistentes de programación con IA que realmente entiendan tu proyecto.',
5959
date: '2025-01-10',
6060
},
6161
],
6262
fr: [
6363
{
6464
slug: 'getting-started-with-ai-coding',
65-
title: 'Getting Started with AI Coding: A Comprehensive Guide',
65+
title: 'Commencer avec AI Coding : Un Guide Complet',
6666
description:
67-
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
67+
"Apprenez comment configurer votre premier environnement de développement propulsé par l'IA avec des IDE, des CLI et les outils essentiels dont vous avez besoin pour stimuler votre productivité de programmation.",
6868
date: '2025-01-15',
6969
},
7070
{
7171
slug: 'mcp-servers-explained',
72-
title: 'Understanding MCP Servers: The Future of AI Context',
72+
title: "Comprendre les Serveurs MCP : L'Avenir du Contexte IA",
7373
description:
74-
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
74+
'Un approfondissement des serveurs du Protocole de Contexte de Modèle, comment ils fonctionnent et pourquoi ils sont cruciaux pour construire des assistants de programmation IA intelligents qui comprennent vraiment votre projet.',
7575
date: '2025-01-10',
7676
},
7777
],
7878
id: [
7979
{
8080
slug: 'getting-started-with-ai-coding',
81-
title: 'Getting Started with AI Coding: A Comprehensive Guide',
81+
title: 'Memulai AI Coding: Panduan Lengkap',
8282
description:
83-
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
83+
'Pelajari cara menyiapkan lingkungan pengembangan bertenaga AI pertama Anda dengan IDE, CLI, dan alat penting yang Anda butuhkan untuk meningkatkan produktivitas pemrograman Anda.',
8484
date: '2025-01-15',
8585
},
8686
{
8787
slug: 'mcp-servers-explained',
88-
title: 'Understanding MCP Servers: The Future of AI Context',
88+
title: 'Memahami Server MCP: Masa Depan Konteks AI',
8989
description:
90-
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
90+
'Eksplorasi mendalam tentang server Model Context Protocol, cara kerjanya, dan mengapa mereka penting untuk membangun asisten pemrograman AI cerdas yang benar-benar memahami proyek Anda.',
9191
date: '2025-01-10',
9292
},
9393
],
9494
ja: [
9595
{
9696
slug: 'getting-started-with-ai-coding',
97-
title: 'Getting Started with AI Coding: A Comprehensive Guide',
97+
title: 'AIコーディングの始め方:包括ガイド',
9898
description:
99-
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
99+
'IDE、CLI、コーディング生産性を向上させる必須ツールを使って、初めてのAI搭載開発環境を設定する方法を学びます。',
100100
date: '2025-01-15',
101101
},
102102
{
103103
slug: 'mcp-servers-explained',
104-
title: 'Understanding MCP Servers: The Future of AI Context',
104+
title: 'MCPサーバーの理解:AIコンテキストの未来',
105105
description:
106-
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
106+
'モデルコンテキストプロトコルサーバーの詳細、その仕組み、およびプロジェクトを真に理解するインテリジェントなAIコーディングアシスタントを構築するために重要な理由について詳しく解説します。',
107107
date: '2025-01-10',
108108
},
109109
],
@@ -126,48 +126,48 @@ export const articlesMetadata: Record<string, ArticleMetadata[]> = {
126126
pt: [
127127
{
128128
slug: 'getting-started-with-ai-coding',
129-
title: 'Getting Started with AI Coding: A Comprehensive Guide',
129+
title: 'Começando com AI Coding: Um Guia Completo',
130130
description:
131-
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
131+
'Aprenda como configurar o seu primeiro ambiente de desenvolvimento alimentado por IA com IDEs, CLIs e as ferramentas essenciais que você precisa para aumentar a sua produtividade de programação.',
132132
date: '2025-01-15',
133133
},
134134
{
135135
slug: 'mcp-servers-explained',
136-
title: 'Understanding MCP Servers: The Future of AI Context',
136+
title: 'Entendendo Servidores MCP: O Futuro do Contexto de IA',
137137
description:
138-
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
138+
'Um mergulho profundo em servidores do Protocolo de Contexto de Modelo, como funcionam e por que são cruciais para construir assistentes de programação com IA inteligentes que realmente entendem o seu projeto.',
139139
date: '2025-01-10',
140140
},
141141
],
142142
ru: [
143143
{
144144
slug: 'getting-started-with-ai-coding',
145-
title: 'Getting Started with AI Coding: A Comprehensive Guide',
145+
title: 'Начало работы с AI Coding: Полное руководство',
146146
description:
147-
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
147+
'Узнайте, как настроить вашу первую среду разработки на базе ИИ с использованием IDE, CLI и необходимых инструментов для повышения вашей продуктивности программирования.',
148148
date: '2025-01-15',
149149
},
150150
{
151151
slug: 'mcp-servers-explained',
152-
title: 'Understanding MCP Servers: The Future of AI Context',
152+
title: 'Понимание серверов MCP: Будущее контекста ИИ',
153153
description:
154-
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
154+
'Глубокое погружение в серверы протокола контекста модели, как они работают и почему они критически важны для создания интеллектуальных ассистентов программирования на базе ИИ, которые действительно понимают ваш проект.',
155155
date: '2025-01-10',
156156
},
157157
],
158158
tr: [
159159
{
160160
slug: 'getting-started-with-ai-coding',
161-
title: 'Getting Started with AI Coding: A Comprehensive Guide',
161+
title: 'Yapay Zeka Kodlamaya Başlarken: Kapsamlı Bir Rehber',
162162
description:
163-
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
163+
"IDE'ler, CLI'ler ve kodlama verimliliğinizi artırmak için ihtiyacınız olan temel araçları kullanarak yapay zeka destekli ilk geliştirme ortamınızı nasıl kuracağınızı öğrenin.",
164164
date: '2025-01-15',
165165
},
166166
{
167167
slug: 'mcp-servers-explained',
168-
title: 'Understanding MCP Servers: The Future of AI Context',
168+
title: 'MCP Sunucularını Anlamak: Yapay Zeka Bağlamının Geleceği',
169169
description:
170-
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
170+
'Model Bağlam Protokolü sunucularını, nasıl çalıştıklarını ve projenizi gerçekten anlayan akıllı yapay zeka kodlama asistanları oluşturmak için neden kritik olduklarını derinlemesine anlayın.',
171171
date: '2025-01-10',
172172
},
173173
],
@@ -190,16 +190,16 @@ export const articlesMetadata: Record<string, ArticleMetadata[]> = {
190190
'zh-Hant': [
191191
{
192192
slug: 'getting-started-with-ai-coding',
193-
title: 'Getting Started with AI Coding: A Comprehensive Guide',
193+
title: 'AI 編碼入門:綜合指南',
194194
description:
195-
'Learn how to set up your first AI-powered development environment with IDEs, CLIs, and the essential tools you need to boost your coding productivity.',
195+
'學習如何使用 IDE、命令列和必備工具搭建你的第一個 AI 驅動開發環境,提升編碼生產力。',
196196
date: '2025-01-15',
197197
},
198198
{
199199
slug: 'mcp-servers-explained',
200-
title: 'Understanding MCP Servers: The Future of AI Context',
200+
title: '理解 MCP 伺服器:AI 上下文的未來',
201201
description:
202-
'Deep dive into Model Context Protocol servers, how they work, and why they are crucial for building intelligent AI coding assistants that truly understand your project.',
202+
'深入了解模型上下文協議伺服器的工作原理,以及為什麼它們對構建真正理解你項目的智能 AI 編碼助手至關重要。',
203203
date: '2025-01-10',
204204
},
205205
],
@@ -1110,7 +1110,7 @@ export const stackCounts: Record<string, number> = {
11101110
ides: 13,
11111111
clis: 20,
11121112
extensions: 15,
1113-
models: 26,
1114-
'model-providers': 7,
1113+
models: 32,
1114+
'model-providers': 13,
11151115
vendors: 36,
11161116
}

src/lib/generated/models.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,32 @@
77
import ClaudeHaiku45 from '../../../manifests/models/claude-haiku-4-5.json'
88
import ClaudeOpus4 from '../../../manifests/models/claude-opus-4.json'
99
import ClaudeOpus41 from '../../../manifests/models/claude-opus-4-1.json'
10+
import ClaudeOpus45 from '../../../manifests/models/claude-opus-4-5.json'
1011
import ClaudeSonnet4 from '../../../manifests/models/claude-sonnet-4.json'
1112
import ClaudeSonnet45 from '../../../manifests/models/claude-sonnet-4-5.json'
1213
import Composer from '../../../manifests/models/composer.json'
1314
import DeepseekR1 from '../../../manifests/models/deepseek-r1.json'
1415
import DeepseekV3Terminus from '../../../manifests/models/deepseek-v3-terminus.json'
1516
import Gemini25Flash from '../../../manifests/models/gemini-2-5-flash.json'
1617
import Gemini25Pro from '../../../manifests/models/gemini-2-5-pro.json'
18+
import Gemini3Flash from '../../../manifests/models/gemini-3-flash.json'
1719
import Gemini3Pro from '../../../manifests/models/gemini-3-pro.json'
1820
import Glm46 from '../../../manifests/models/glm-4-6.json'
1921
import Glm46v from '../../../manifests/models/glm-4-6v.json'
22+
import Glm47 from '../../../manifests/models/glm-4-7.json'
2023
import Gpt41 from '../../../manifests/models/gpt-4-1.json'
2124
import Gpt4o from '../../../manifests/models/gpt-4o.json'
2225
import Gpt5 from '../../../manifests/models/gpt-5.json'
2326
import Gpt51 from '../../../manifests/models/gpt-5-1.json'
2427
import Gpt51Codex from '../../../manifests/models/gpt-5-1-codex.json'
28+
import Gpt52 from '../../../manifests/models/gpt-5-2.json'
2529
import Gpt5Codex from '../../../manifests/models/gpt-5-codex.json'
2630
import GrokCodeFast1 from '../../../manifests/models/grok-code-fast-1.json'
31+
import KatCoderProV1 from '../../../manifests/models/kat-coder-pro-v1.json'
2732
import KimiK20905 from '../../../manifests/models/kimi-k2-0905.json'
28-
import Llama4Maverick from '../../../manifests/models/llama-4-maverick.json'
33+
import KimiK2Thinking from '../../../manifests/models/kimi-k2-thinking.json'
2934
import MinimaxM2 from '../../../manifests/models/minimax-m2.json'
35+
import MinimaxM21 from '../../../manifests/models/minimax-m2-1.json'
3036
import Qwen3Coder30bA3b from '../../../manifests/models/qwen3-coder-30b-a3b.json'
3137
import Qwen3Coder480bA35b from '../../../manifests/models/qwen3-coder-480b-a35b.json'
3238
import Qwen3CoderPlus from '../../../manifests/models/qwen3-coder-plus.json'
@@ -36,26 +42,32 @@ export const modelsData = [
3642
ClaudeHaiku45,
3743
ClaudeOpus4,
3844
ClaudeOpus41,
45+
ClaudeOpus45,
3946
ClaudeSonnet4,
4047
ClaudeSonnet45,
4148
Composer,
4249
DeepseekR1,
4350
DeepseekV3Terminus,
4451
Gemini25Flash,
4552
Gemini25Pro,
53+
Gemini3Flash,
4654
Gemini3Pro,
4755
Glm46,
4856
Glm46v,
57+
Glm47,
4958
Gpt41,
5059
Gpt4o,
5160
Gpt5,
5261
Gpt51,
5362
Gpt51Codex,
63+
Gpt52,
5464
Gpt5Codex,
5565
GrokCodeFast1,
66+
KatCoderProV1,
5667
KimiK20905,
57-
Llama4Maverick,
68+
KimiK2Thinking,
5869
MinimaxM2,
70+
MinimaxM21,
5971
Qwen3Coder30bA3b,
6072
Qwen3Coder480bA35b,
6173
Qwen3CoderPlus,

src/lib/generated/providers.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,37 @@
44
* Do not edit manually - run the script to regenerate
55
*/
66

7+
import Alibaba from '../../../manifests/providers/alibaba.json'
8+
import Anthropic from '../../../manifests/providers/anthropic.json'
79
import Deepseek from '../../../manifests/providers/deepseek.json'
10+
import Google from '../../../manifests/providers/google.json'
11+
import Kwaikatonai from '../../../manifests/providers/kwaikatonai.json'
12+
import Meta from '../../../manifests/providers/meta.json'
813
import Minimax from '../../../manifests/providers/minimax.json'
914
import Moonshot from '../../../manifests/providers/moonshot.json'
15+
import Openai from '../../../manifests/providers/openai.json'
1016
import Openrouter from '../../../manifests/providers/openrouter.json'
1117
import Siliconflow from '../../../manifests/providers/siliconflow.json'
1218
import Xai from '../../../manifests/providers/xai.json'
1319
import ZAi from '../../../manifests/providers/z-ai.json'
1420
import type { ManifestProvider } from '../../types/manifests'
1521

1622
export const providersData = [
23+
Alibaba,
24+
Anthropic,
1725
Deepseek,
26+
Google,
27+
Kwaikatonai,
28+
Meta,
1829
Minimax,
1930
Moonshot,
31+
Openai,
2032
Openrouter,
2133
Siliconflow,
2234
Xai,
2335
ZAi,
2436
] as unknown as ManifestProvider[]
2537

26-
export type Provider = typeof Deepseek
38+
export type Provider = typeof Alibaba
2739

2840
export default providersData

src/lib/metadata/generators.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@ export async function generateListPageMetadata(options: {
108108
}): Promise<Metadata> {
109109
const { locale, category, translationNamespace, additionalKeywords = [] } = options
110110

111-
const t = await getTranslations({ locale, namespace: translationNamespace })
111+
const tPage = await getTranslations({ locale, namespace: translationNamespace })
112112

113-
const translatedTitle = t('title')
114-
const description = t('subtitle')
113+
const translatedTitle = tPage('title')
114+
const description = tPage('subtitle')
115115

116116
// Build SEO-optimized title
117117
const categoryExamples = CATEGORY_EXAMPLES[category as keyof typeof CATEGORY_EXAMPLES]
@@ -165,7 +165,7 @@ export async function generateSoftwareDetailMetadata(options: {
165165
description: string
166166
vendor: string
167167
platforms?: Array<{ os: string }> | string[]
168-
pricing?: Array<{ value: number | null; currency: string | null; per: string | null }>
168+
pricing?: Array<{ value: number | null; currency?: string | null; per?: string | null }>
169169
license?: string
170170
}
171171
typeDescription: string
@@ -242,25 +242,26 @@ export async function generateModelDetailMetadata(options: {
242242
}): Promise<Metadata> {
243243
const { locale, slug, model, translationNamespace } = options
244244

245-
const t = await getTranslations({ locale, namespace: translationNamespace })
245+
const tPage = await getTranslations({ locale, namespace: translationNamespace })
246246

247247
// Build title with model-specific translation
248-
const title = `${model.name} - ${t('metaTitle')}`
248+
const title = `${model.name} - ${tPage('metaTitle')}`
249249

250250
// Build description with model specs
251251
const specs: string[] = []
252-
if (model.size) specs.push(`${t('modelSize')}: ${model.size}`)
252+
if (model.size) specs.push(`${tPage('modelSize')}: ${model.size}`)
253253
if (model.contextWindow)
254-
specs.push(`${t('contextWindow')}: ${formatTokenCount(model.contextWindow)} tokens`)
255-
if (model.maxOutput) specs.push(`${t('maxOutput')}: ${formatTokenCount(model.maxOutput)} tokens`)
254+
specs.push(`${tPage('contextWindow')}: ${formatTokenCount(model.contextWindow)} tokens`)
255+
if (model.maxOutput)
256+
specs.push(`${tPage('maxOutput')}: ${formatTokenCount(model.maxOutput)} tokens`)
256257

257258
const pricingDisplay = model.tokenPricing?.input
258259
? `$${model.tokenPricing.input}/M tokens`
259260
: model.tokenPricing?.output
260261
? `$${model.tokenPricing.output}/M tokens`
261262
: null
262263

263-
if (pricingDisplay) specs.push(`${t('pricing')}: ${pricingDisplay}`)
264+
if (pricingDisplay) specs.push(`${tPage('pricing')}: ${pricingDisplay}`)
264265

265266
const description = `${model.name} by ${model.vendor}. ${specs.join('. ')}. ${model.description}`
266267

@@ -273,7 +274,7 @@ export async function generateModelDetailMetadata(options: {
273274
])
274275

275276
// Social media titles
276-
const socialTitle = `${model.name} - ${t('metaTitle')}`
277+
const socialTitle = `${model.name} - ${tPage('metaTitle')}`
277278

278279
// Use common metadata builder
279280
// Note: OG and Twitter images are automatically detected from opengraph-image.tsx files
@@ -314,9 +315,9 @@ export async function generateComparisonMetadata(options: {
314315

315316
if (translationNamespace) {
316317
try {
317-
const t = await getTranslations({ locale, namespace: translationNamespace })
318-
title = `${t('title')} - ${categoryName} Comparison | ${METADATA_DEFAULTS.siteName}`
319-
description = t('description')
318+
const tPage = await getTranslations({ locale, namespace: translationNamespace })
319+
title = `${tPage('title')} - ${categoryName} Comparison | ${METADATA_DEFAULTS.siteName}`
320+
description = tPage('description')
320321
} catch {
321322
// Fallback to default English text if translations not available
322323
title = `Compare ${categoryName} - Side-by-Side Comparison | ${METADATA_DEFAULTS.siteName}`

src/lib/metadata/helpers.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,9 @@ export function buildAlternates(options: {
345345
* Format price for display in descriptions
346346
*/
347347
export function formatPriceForDescription(
348-
pricing: Array<{ value: number | null; currency: string | null; per: string | null }> | undefined
348+
pricing:
349+
| Array<{ value: number | null; currency?: string | null; per?: string | null }>
350+
| undefined
349351
): string | null {
350352
if (!pricing || pricing.length === 0) return null
351353

src/lib/metadata/schemas/builders.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export function buildPersonSchema(options: PersonSchemaOptions): SchemaPerson {
9090
export interface PricingTierData {
9191
name?: string
9292
value: number | null
93-
currency: string | null
93+
currency?: string | null
9494
per?: string | null
9595
category?: string
9696
}

0 commit comments

Comments
 (0)