From c978504f4a91233c9b9a636d56409fc08392e8ed Mon Sep 17 00:00:00 2001 From: gaoziman <2942894660@qq.com> Date: Sat, 20 Dec 2025 01:04:02 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E5=BA=93):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=A4=9A=E6=A8=A1=E5=9E=8B=E7=B1=BB=E5=9E=8B=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 models 表中新增 modelType 字段,支持区分 claude 和 codex 类型 - 添加 Codex 系列模型数据(gpt-5.1-codex, gpt-5.1-codex-max, gpt-5.2-codex) - 更新 Claude 模型的 displayName 命名 - 新增数据库迁移文件 --- .../migrations/0005_spotty_sister_grimm.sql | 1 + .../migrations/meta/0005_snapshot.json | 798 ++++++++++++++++++ src/drizzle/migrations/meta/_journal.json | 7 + src/drizzle/schema.ts | 2 + src/drizzle/seed.ts | 54 +- 5 files changed, 860 insertions(+), 2 deletions(-) create mode 100644 src/drizzle/migrations/0005_spotty_sister_grimm.sql create mode 100644 src/drizzle/migrations/meta/0005_snapshot.json diff --git a/src/drizzle/migrations/0005_spotty_sister_grimm.sql b/src/drizzle/migrations/0005_spotty_sister_grimm.sql new file mode 100644 index 0000000..14e1a00 --- /dev/null +++ b/src/drizzle/migrations/0005_spotty_sister_grimm.sql @@ -0,0 +1 @@ +ALTER TABLE "models" ADD COLUMN "model_type" varchar(20) DEFAULT 'claude' NOT NULL; \ No newline at end of file diff --git a/src/drizzle/migrations/meta/0005_snapshot.json b/src/drizzle/migrations/meta/0005_snapshot.json new file mode 100644 index 0000000..36336e3 --- /dev/null +++ b/src/drizzle/migrations/meta/0005_snapshot.json @@ -0,0 +1,798 @@ +{ + "id": "49959b08-d376-4e91-ac85-116b888b6d9a", + "prevId": "593838ef-b7eb-4197-aa54-b1d2912da729", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.conversations": { + "name": "conversations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'新对话'" + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "tools": { + "name": "tools", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "enable_thinking": { + "name": "enable_thinking", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "system_prompt": { + "name": "system_prompt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "temperature": { + "name": "temperature", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "message_count": { + "name": "message_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "total_tokens": { + "name": "total_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "is_archived": { + "name": "is_archived", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "is_pinned": { + "name": "is_pinned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "last_message_at": { + "name": "last_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "conversations_conversation_id_unique": { + "name": "conversations_conversation_id_unique", + "nullsNotDistinct": false, + "columns": [ + "conversation_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.messages": { + "name": "messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "thinking_content": { + "name": "thinking_content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thinking_collapsed": { + "name": "thinking_collapsed", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "tool_calls": { + "name": "tool_calls", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "tool_results": { + "name": "tool_results", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "images": { + "name": "images", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "input_tokens": { + "name": "input_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "output_tokens": { + "name": "output_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'completed'" + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feedback": { + "name": "feedback", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "messages_message_id_unique": { + "name": "messages_message_id_unique", + "nullsNotDistinct": false, + "columns": [ + "message_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.models": { + "name": "models", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "model_id": { + "name": "model_id", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model_type": { + "name": "model_type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true, + "default": "'claude'" + }, + "supports_tools": { + "name": "supports_tools", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "supports_thinking": { + "name": "supports_thinking", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "supports_vision": { + "name": "supports_vision", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "max_tokens": { + "name": "max_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 8192 + }, + "context_window": { + "name": "context_window", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 200000 + }, + "is_enabled": { + "name": "is_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "models_model_id_unique": { + "name": "models_model_id_unique", + "nullsNotDistinct": false, + "columns": [ + "model_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tools": { + "name": "tools", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "tool_id": { + "name": "tool_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "input_schema": { + "name": "input_schema", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "is_enabled": { + "name": "is_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "tools_tool_id_unique": { + "name": "tools_tool_id_unique", + "nullsNotDistinct": false, + "columns": [ + "tool_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_settings": { + "name": "user_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "cch_url": { + "name": "cch_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true, + "default": "'http://localhost:13500'" + }, + "cch_api_key": { + "name": "cch_api_key", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "cch_api_key_configured": { + "name": "cch_api_key_configured", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "default_model": { + "name": "default_model", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "default": "'claude-sonnet-4-20250514'" + }, + "default_tools": { + "name": "default_tools", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[\"web_search\",\"code_execution\",\"web_fetch\"]'::jsonb" + }, + "system_prompt": { + "name": "system_prompt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "temperature": { + "name": "temperature", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false, + "default": "'0.7'" + }, + "theme": { + "name": "theme", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'light'" + }, + "language": { + "name": "language", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false, + "default": "'zh-CN'" + }, + "font_size": { + "name": "font_size", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 15 + }, + "enable_thinking": { + "name": "enable_thinking", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "save_chat_history": { + "name": "save_chat_history", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_settings_user_id_unique": { + "name": "user_settings_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "nickname": { + "name": "nickname", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "avatar": { + "name": "avatar", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'free'" + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'active'" + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "last_login_at": { + "name": "last_login_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_user_id_unique": { + "name": "users_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + }, + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification_codes": { + "name": "verification_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "code": { + "name": "code", + "type": "varchar(6)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "used": { + "name": "used", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/src/drizzle/migrations/meta/_journal.json b/src/drizzle/migrations/meta/_journal.json index f56f993..6b5fbce 100644 --- a/src/drizzle/migrations/meta/_journal.json +++ b/src/drizzle/migrations/meta/_journal.json @@ -36,6 +36,13 @@ "when": 1766149111995, "tag": "0004_lowly_red_shift", "breakpoints": true + }, + { + "idx": 5, + "version": "7", + "when": 1766155643018, + "tag": "0005_spotty_sister_grimm", + "breakpoints": true } ] } \ No newline at end of file diff --git a/src/drizzle/schema.ts b/src/drizzle/schema.ts index 8e5375a..f2f347d 100644 --- a/src/drizzle/schema.ts +++ b/src/drizzle/schema.ts @@ -178,6 +178,8 @@ export const models = pgTable('models', { name: varchar('name', { length: 64 }).notNull(), displayName: varchar('display_name', { length: 128 }).notNull(), description: text('description'), + // 模型类型:claude | codex + modelType: varchar('model_type', { length: 20 }).notNull().default('claude'), // 模型特性 supportsTools: boolean('supports_tools').default(true), supportsThinking: boolean('supports_thinking').default(true), diff --git a/src/drizzle/seed.ts b/src/drizzle/seed.ts index 8f627bb..641ca6c 100644 --- a/src/drizzle/seed.ts +++ b/src/drizzle/seed.ts @@ -100,11 +100,13 @@ async function seedTools() { // 初始化模型 async function seedModels() { const modelsData = [ + // Claude 模型 { modelId: 'claude-sonnet-4-5-20250929', name: 'claude-sonnet-4-5-20250929', - displayName: 'Default (recommended)', - description: '使用默认模型(Sonnet 4.5),$3/$15 per Mtok', + displayName: 'Sonnet', + description: 'Sonnet 4.5 - 智能与速度的最佳平衡,$3/$15 per Mtok', + modelType: 'claude', supportsTools: true, supportsThinking: true, supportsVision: true, @@ -119,6 +121,7 @@ async function seedModels() { name: 'claude-opus-4-5-20251101', displayName: 'Opus', description: 'Opus 4.5 - 最强大的复杂工作,$5/$25 per Mtok', + modelType: 'claude', supportsTools: true, supportsThinking: true, supportsVision: true, @@ -133,6 +136,7 @@ async function seedModels() { name: 'claude-haiku-4-5-20251001', displayName: 'Haiku', description: 'Haiku 4.5 - 快速回答,$1/$5 per Mtok', + modelType: 'claude', supportsTools: true, supportsThinking: false, supportsVision: false, @@ -142,6 +146,52 @@ async function seedModels() { 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) {