- 在 models 表中新增 modelType 字段,支持区分 claude 和 codex 类型 - 添加 Codex 系列模型数据(gpt-5.1-codex, gpt-5.1-codex-max, gpt-5.2-codex) - 更新 Claude 模型的 displayName 命名 - 新增数据库迁移文件
233 lines
5.9 KiB
TypeScript
233 lines
5.9 KiB
TypeScript
import { db } from './db';
|
|
import { userSettings, tools, models } from './schema';
|
|
import { eq } from 'drizzle-orm';
|
|
|
|
// 初始化用户设置
|
|
async function seedUserSettings() {
|
|
const existing = await db.query.userSettings.findFirst({
|
|
where: eq(userSettings.id, 1),
|
|
});
|
|
|
|
if (!existing) {
|
|
await db.insert(userSettings).values({
|
|
id: 1,
|
|
cchUrl: 'http://localhost:13500',
|
|
cchApiKeyConfigured: false,
|
|
defaultModel: 'claude-sonnet-4-5-20250929',
|
|
defaultTools: ['web_search', 'code_execution', 'web_fetch'],
|
|
theme: 'light',
|
|
language: 'zh-CN',
|
|
enableThinking: false,
|
|
saveChatHistory: true,
|
|
});
|
|
console.log('✓ User settings initialized');
|
|
} else {
|
|
console.log('→ User settings already exist');
|
|
}
|
|
}
|
|
|
|
// 初始化工具
|
|
async function seedTools() {
|
|
const toolsData = [
|
|
{
|
|
toolId: 'web_search',
|
|
name: 'web_search',
|
|
displayName: 'Web Search',
|
|
description: '搜索互联网获取最新信息',
|
|
icon: 'Search',
|
|
inputSchema: {
|
|
type: 'object',
|
|
properties: {
|
|
query: { type: 'string', description: '搜索查询' },
|
|
},
|
|
required: ['query'],
|
|
},
|
|
isEnabled: true,
|
|
isDefault: true,
|
|
sortOrder: 1,
|
|
},
|
|
{
|
|
toolId: 'code_execution',
|
|
name: 'code_execution',
|
|
displayName: 'Code Execution',
|
|
description: '执行代码片段并返回结果',
|
|
icon: 'Terminal',
|
|
inputSchema: {
|
|
type: 'object',
|
|
properties: {
|
|
code: { type: 'string', description: '要执行的代码' },
|
|
language: { type: 'string', description: '编程语言' },
|
|
},
|
|
required: ['code', 'language'],
|
|
},
|
|
isEnabled: true,
|
|
isDefault: true,
|
|
sortOrder: 2,
|
|
},
|
|
{
|
|
toolId: 'web_fetch',
|
|
name: 'web_fetch',
|
|
displayName: 'Web Fetch',
|
|
description: '获取网页内容',
|
|
icon: 'Globe',
|
|
inputSchema: {
|
|
type: 'object',
|
|
properties: {
|
|
url: { type: 'string', description: '要获取的URL' },
|
|
},
|
|
required: ['url'],
|
|
},
|
|
isEnabled: true,
|
|
isDefault: true,
|
|
sortOrder: 3,
|
|
},
|
|
];
|
|
|
|
for (const tool of toolsData) {
|
|
const existing = await db.query.tools.findFirst({
|
|
where: eq(tools.toolId, tool.toolId),
|
|
});
|
|
|
|
if (!existing) {
|
|
await db.insert(tools).values(tool);
|
|
console.log(`✓ Tool "${tool.displayName}" initialized`);
|
|
} else {
|
|
console.log(`→ Tool "${tool.displayName}" already exists`);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 初始化模型
|
|
async function seedModels() {
|
|
const modelsData = [
|
|
// Claude 模型
|
|
{
|
|
modelId: 'claude-sonnet-4-5-20250929',
|
|
name: 'claude-sonnet-4-5-20250929',
|
|
displayName: 'Sonnet',
|
|
description: 'Sonnet 4.5 - 智能与速度的最佳平衡,$3/$15 per Mtok',
|
|
modelType: 'claude',
|
|
supportsTools: true,
|
|
supportsThinking: true,
|
|
supportsVision: true,
|
|
maxTokens: 8192,
|
|
contextWindow: 200000,
|
|
isEnabled: true,
|
|
isDefault: true,
|
|
sortOrder: 1,
|
|
},
|
|
{
|
|
modelId: 'claude-opus-4-5-20251101',
|
|
name: 'claude-opus-4-5-20251101',
|
|
displayName: 'Opus',
|
|
description: 'Opus 4.5 - 最强大的复杂工作,$5/$25 per Mtok',
|
|
modelType: 'claude',
|
|
supportsTools: true,
|
|
supportsThinking: true,
|
|
supportsVision: true,
|
|
maxTokens: 8192,
|
|
contextWindow: 200000,
|
|
isEnabled: true,
|
|
isDefault: false,
|
|
sortOrder: 2,
|
|
},
|
|
{
|
|
modelId: 'claude-haiku-4-5-20251001',
|
|
name: 'claude-haiku-4-5-20251001',
|
|
displayName: 'Haiku',
|
|
description: 'Haiku 4.5 - 快速回答,$1/$5 per Mtok',
|
|
modelType: 'claude',
|
|
supportsTools: true,
|
|
supportsThinking: false,
|
|
supportsVision: false,
|
|
maxTokens: 8192,
|
|
contextWindow: 200000,
|
|
isEnabled: true,
|
|
isDefault: false,
|
|
sortOrder: 3,
|
|
},
|
|
// Codex 模型
|
|
{
|
|
modelId: 'gpt-5.1-codex',
|
|
name: 'gpt-5.1-codex',
|
|
displayName: 'Codex',
|
|
description: 'Codex 标准版 - 快速高效的代码生成',
|
|
modelType: 'codex',
|
|
supportsTools: true,
|
|
supportsThinking: false,
|
|
supportsVision: false,
|
|
maxTokens: 8192,
|
|
contextWindow: 128000,
|
|
isEnabled: true,
|
|
isDefault: false,
|
|
sortOrder: 10,
|
|
},
|
|
{
|
|
modelId: 'gpt-5.1-codex-max',
|
|
name: 'gpt-5.1-codex-max',
|
|
displayName: 'Codex Max',
|
|
description: 'Codex 增强版 - 更强的上下文理解能力',
|
|
modelType: 'codex',
|
|
supportsTools: true,
|
|
supportsThinking: false,
|
|
supportsVision: false,
|
|
maxTokens: 16384,
|
|
contextWindow: 128000,
|
|
isEnabled: true,
|
|
isDefault: false,
|
|
sortOrder: 11,
|
|
},
|
|
{
|
|
modelId: 'gpt-5.2-codex',
|
|
name: 'gpt-5.2-codex',
|
|
displayName: 'Codex Pro',
|
|
description: 'Codex 专业版 - 最新最强的代码模型',
|
|
modelType: 'codex',
|
|
supportsTools: true,
|
|
supportsThinking: false,
|
|
supportsVision: false,
|
|
maxTokens: 16384,
|
|
contextWindow: 200000,
|
|
isEnabled: true,
|
|
isDefault: false,
|
|
sortOrder: 12,
|
|
},
|
|
];
|
|
|
|
for (const model of modelsData) {
|
|
const existing = await db.query.models.findFirst({
|
|
where: eq(models.modelId, model.modelId),
|
|
});
|
|
|
|
if (!existing) {
|
|
await db.insert(models).values(model);
|
|
console.log(`✓ Model "${model.displayName}" initialized`);
|
|
} else {
|
|
console.log(`→ Model "${model.displayName}" already exists`);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 主函数
|
|
export async function seed() {
|
|
console.log('\n🌱 Starting database seed...\n');
|
|
|
|
try {
|
|
await seedUserSettings();
|
|
await seedTools();
|
|
await seedModels();
|
|
|
|
console.log('\n✅ Database seed completed!\n');
|
|
} catch (error) {
|
|
console.error('\n❌ Database seed failed:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// 如果直接运行此文件
|
|
if (require.main === module) {
|
|
seed()
|
|
.then(() => process.exit(0))
|
|
.catch(() => process.exit(1));
|
|
}
|