Kode-cli/next_todo.md
CrazyBoyM 02c7c31a31 feat: Add GPT-5 Responses API support and model adapter system
- Implement model adapter factory for unified API handling
- Add response state manager for conversation continuity
- Support GPT-5 Responses API with continuation tokens
- Add model capabilities type system
- Include deployment guide and test infrastructure
- Enhance error handling and debugging for model interactions
2025-08-22 13:22:48 +08:00

25 KiB
Raw Blame History

Kode系统 Responses API 支持重构施工文档

📋 项目概述

目标

将Kode系统从硬编码的GPT-5检测升级为基于能力声明的模型系统支持所有Responses API类模型GPT-5、GPT-6、GLM-5等

核心原则

  1. 零破坏性: 100%保留现有功能
  2. 渐进式: 可随时回滚
  3. 可扩展: 新模型只需配置
  4. 优雅性: 消除硬编码,统一处理流程

🏗️ 系统架构概览

当前架构(问题)

用户输入 → REPL → query.ts → queryLLM 
                                ↓
                         [硬编码检测]
                    if (isGPT5Model()) {...}
                    if (isGPT4Model()) {...}
                                ↓
                         不同的API调用路径

目标架构(解决方案)

用户输入 → REPL → query.ts → queryLLM
                                ↓
                         [能力声明系统]
                    ModelCapabilities查询
                                ↓
                         [统一适配器]
                    ResponsesAPIAdapter / ChatCompletionsAdapter
                                ↓
                         统一的API调用

📁 文件结构规划

src/
├── types/
│   └── modelCapabilities.ts      # 新建:能力类型定义
├── constants/
│   └── modelCapabilities.ts      # 新建:模型能力注册表
├── services/
│   ├── adapters/                 # 新建目录:适配器
│   │   ├── base.ts              # 新建:基础适配器类
│   │   ├── responsesAPI.ts      # 新建Responses API适配器
│   │   └── chatCompletions.ts   # 新建Chat Completions适配器
│   ├── modelAdapterFactory.ts   # 新建:适配器工厂
│   ├── claude.ts                 # 修改:使用新系统
│   └── openai.ts                 # 修改:清理硬编码

🚀 Phase 1: 基础设施建设第1-2天

目标

创建能力声明系统的基础架构,不影响现有代码运行。

Step 1.1: 创建模型能力类型定义

文件: src/types/modelCapabilities.ts (新建)

任务: 定义模型能力接口

// 完整代码 - 直接复制粘贴
export interface ModelCapabilities {
  // API架构类型
  apiArchitecture: {
    primary: 'chat_completions' | 'responses_api'
    fallback?: 'chat_completions'  // Responses API模型可降级
  }
  
  // 参数映射
  parameters: {
    maxTokensField: 'max_tokens' | 'max_completion_tokens'
    supportsReasoningEffort: boolean
    supportsVerbosity: boolean
    temperatureMode: 'flexible' | 'fixed_one' | 'restricted'
  }
  
  // 工具调用能力
  toolCalling: {
    mode: 'none' | 'function_calling' | 'custom_tools'
    supportsFreeform: boolean
    supportsAllowedTools: boolean
    supportsParallelCalls: boolean
  }
  
  // 状态管理
  stateManagement: {
    supportsResponseId: boolean
    supportsConversationChaining: boolean
    supportsPreviousResponseId: boolean
  }
  
  // 流式支持
  streaming: {
    supported: boolean
    includesUsage: boolean
  }
}

// 统一的请求参数
export interface UnifiedRequestParams {
  messages: any[]
  systemPrompt: string[]
  tools?: any[]
  maxTokens: number
  stream?: boolean
  previousResponseId?: string
  reasoningEffort?: 'minimal' | 'low' | 'medium' | 'high'
  verbosity?: 'low' | 'medium' | 'high'
  temperature?: number
}

// 统一的响应格式
export interface UnifiedResponse {
  id: string
  content: string
  toolCalls?: any[]
  usage: {
    promptTokens: number
    completionTokens: number
    reasoningTokens?: number
  }
  responseId?: string  // 用于Responses API状态管理
}

Step 1.2: 创建模型能力注册表

文件: src/constants/modelCapabilities.ts (新建)

任务: 为所有模型定义能力

import { ModelCapabilities } from '../types/modelCapabilities'

// GPT-5的标准能力定义
const GPT5_CAPABILITIES: ModelCapabilities = {
  apiArchitecture: {
    primary: 'responses_api',
    fallback: 'chat_completions'
  },
  parameters: {
    maxTokensField: 'max_completion_tokens',
    supportsReasoningEffort: true,
    supportsVerbosity: true,
    temperatureMode: 'fixed_one'
  },
  toolCalling: {
    mode: 'custom_tools',
    supportsFreeform: true,
    supportsAllowedTools: true,
    supportsParallelCalls: true
  },
  stateManagement: {
    supportsResponseId: true,
    supportsConversationChaining: true,
    supportsPreviousResponseId: true
  },
  streaming: {
    supported: false,  // Responses API暂不支持流式
    includesUsage: true
  }
}

// Chat Completions的标准能力定义
const CHAT_COMPLETIONS_CAPABILITIES: ModelCapabilities = {
  apiArchitecture: {
    primary: 'chat_completions'
  },
  parameters: {
    maxTokensField: 'max_tokens',
    supportsReasoningEffort: false,
    supportsVerbosity: false,
    temperatureMode: 'flexible'
  },
  toolCalling: {
    mode: 'function_calling',
    supportsFreeform: false,
    supportsAllowedTools: false,
    supportsParallelCalls: true
  },
  stateManagement: {
    supportsResponseId: false,
    supportsConversationChaining: false,
    supportsPreviousResponseId: false
  },
  streaming: {
    supported: true,
    includesUsage: true
  }
}

// 完整的模型能力映射表
export const MODEL_CAPABILITIES_REGISTRY: Record<string, ModelCapabilities> = {
  // GPT-5系列
  'gpt-5': GPT5_CAPABILITIES,
  'gpt-5-mini': GPT5_CAPABILITIES,
  'gpt-5-nano': GPT5_CAPABILITIES,
  'gpt-5-chat-latest': GPT5_CAPABILITIES,
  
  // GPT-4系列
  'gpt-4o': CHAT_COMPLETIONS_CAPABILITIES,
  'gpt-4o-mini': CHAT_COMPLETIONS_CAPABILITIES,
  'gpt-4-turbo': CHAT_COMPLETIONS_CAPABILITIES,
  'gpt-4': CHAT_COMPLETIONS_CAPABILITIES,
  
  // Claude系列通过转换层支持
  'claude-3-5-sonnet-20241022': CHAT_COMPLETIONS_CAPABILITIES,
  'claude-3-5-haiku-20241022': CHAT_COMPLETIONS_CAPABILITIES,
  'claude-3-opus-20240229': CHAT_COMPLETIONS_CAPABILITIES,
  
  // O1系列特殊的推理模型
  'o1': {
    ...CHAT_COMPLETIONS_CAPABILITIES,
    parameters: {
      ...CHAT_COMPLETIONS_CAPABILITIES.parameters,
      maxTokensField: 'max_completion_tokens',
      temperatureMode: 'fixed_one'
    }
  },
  'o1-mini': {
    ...CHAT_COMPLETIONS_CAPABILITIES,
    parameters: {
      ...CHAT_COMPLETIONS_CAPABILITIES.parameters,
      maxTokensField: 'max_completion_tokens',
      temperatureMode: 'fixed_one'
    }
  }
}

// 智能推断未注册模型的能力
export function inferModelCapabilities(modelName: string): ModelCapabilities | null {
  if (!modelName) return null
  
  const lowerName = modelName.toLowerCase()
  
  // GPT-5系列
  if (lowerName.includes('gpt-5') || lowerName.includes('gpt5')) {
    return GPT5_CAPABILITIES
  }
  
  // GPT-6系列预留
  if (lowerName.includes('gpt-6') || lowerName.includes('gpt6')) {
    return {
      ...GPT5_CAPABILITIES,
      streaming: { supported: true, includesUsage: true }
    }
  }
  
  // GLM系列
  if (lowerName.includes('glm-5') || lowerName.includes('glm5')) {
    return {
      ...GPT5_CAPABILITIES,
      toolCalling: {
        ...GPT5_CAPABILITIES.toolCalling,
        supportsAllowedTools: false  // GLM可能不支持
      }
    }
  }
  
  // O1系列
  if (lowerName.startsWith('o1') || lowerName.includes('o1-')) {
    return {
      ...CHAT_COMPLETIONS_CAPABILITIES,
      parameters: {
        ...CHAT_COMPLETIONS_CAPABILITIES.parameters,
        maxTokensField: 'max_completion_tokens',
        temperatureMode: 'fixed_one'
      }
    }
  }
  
  // 默认返回null让系统使用默认行为
  return null
}

// 获取模型能力(带缓存)
const capabilityCache = new Map<string, ModelCapabilities>()

export function getModelCapabilities(modelName: string): ModelCapabilities {
  // 检查缓存
  if (capabilityCache.has(modelName)) {
    return capabilityCache.get(modelName)!
  }
  
  // 查找注册表
  if (MODEL_CAPABILITIES_REGISTRY[modelName]) {
    const capabilities = MODEL_CAPABILITIES_REGISTRY[modelName]
    capabilityCache.set(modelName, capabilities)
    return capabilities
  }
  
  // 尝试推断
  const inferred = inferModelCapabilities(modelName)
  if (inferred) {
    capabilityCache.set(modelName, inferred)
    return inferred
  }
  
  // 默认为Chat Completions
  const defaultCapabilities = CHAT_COMPLETIONS_CAPABILITIES
  capabilityCache.set(modelName, defaultCapabilities)
  return defaultCapabilities
}

Step 1.3: 创建基础适配器类

文件: src/services/adapters/base.ts (新建)

任务: 创建adapters目录和基础类

import { ModelCapabilities, UnifiedRequestParams, UnifiedResponse } from '../../types/modelCapabilities'
import { ModelProfile } from '../../utils/config'
import { Tool } from '../../Tool'

export abstract class ModelAPIAdapter {
  constructor(
    protected capabilities: ModelCapabilities,
    protected modelProfile: ModelProfile
  ) {}
  
  // 子类必须实现的方法
  abstract createRequest(params: UnifiedRequestParams): any
  abstract parseResponse(response: any): UnifiedResponse
  abstract buildTools(tools: Tool[]): any
  
  // 共享的工具方法
  protected getMaxTokensParam(): string {
    return this.capabilities.parameters.maxTokensField
  }
  
  protected getTemperature(): number {
    if (this.capabilities.parameters.temperatureMode === 'fixed_one') {
      return 1
    }
    if (this.capabilities.parameters.temperatureMode === 'restricted') {
      return Math.min(1, this.modelProfile.temperature || 0.7)
    }
    return this.modelProfile.temperature || 0.7
  }
  
  protected shouldIncludeReasoningEffort(): boolean {
    return this.capabilities.parameters.supportsReasoningEffort
  }
  
  protected shouldIncludeVerbosity(): boolean {
    return this.capabilities.parameters.supportsVerbosity
  }
}

Step 1.4: 创建Responses API适配器

文件: src/services/adapters/responsesAPI.ts (新建)

任务: 实现Responses API适配器

import { ModelAPIAdapter } from './base'
import { UnifiedRequestParams, UnifiedResponse } from '../../types/modelCapabilities'
import { Tool } from '../../Tool'
import { zodToJsonSchema } from '../../utils/zodToJsonSchema'

export class ResponsesAPIAdapter extends ModelAPIAdapter {
  createRequest(params: UnifiedRequestParams): any {
    const { messages, systemPrompt, tools, maxTokens } = params
    
    // 分离系统消息和用户消息
    const systemMessages = messages.filter(m => m.role === 'system')
    const nonSystemMessages = messages.filter(m => m.role !== 'system')
    
    // 构建基础请求
    const request: any = {
      model: this.modelProfile.modelName,
      input: this.convertMessagesToInput(nonSystemMessages),
      instructions: this.buildInstructions(systemPrompt, systemMessages)
    }
    
    // 添加token限制
    request[this.getMaxTokensParam()] = maxTokens
    
    // 添加温度GPT-5只支持1
    if (this.getTemperature() === 1) {
      request.temperature = 1
    }
    
    // 添加推理控制
    if (this.shouldIncludeReasoningEffort()) {
      request.reasoning = {
        effort: params.reasoningEffort || this.modelProfile.reasoningEffort || 'medium'
      }
    }
    
    // 添加详细度控制
    if (this.shouldIncludeVerbosity()) {
      request.text = {
        verbosity: params.verbosity || 'high'  // 编码任务默认高详细度
      }
    }
    
    // 添加工具
    if (tools && tools.length > 0) {
      request.tools = this.buildTools(tools)
      
      // 处理allowed_tools
      if (params.allowedTools && this.capabilities.toolCalling.supportsAllowedTools) {
        request.tool_choice = {
          type: 'allowed_tools',
          mode: 'auto',
          tools: params.allowedTools
        }
      }
    }
    
    // 添加状态管理
    if (params.previousResponseId && this.capabilities.stateManagement.supportsPreviousResponseId) {
      request.previous_response_id = params.previousResponseId
    }
    
    return request
  }
  
  buildTools(tools: Tool[]): any[] {
    // 如果不支持freeform使用传统格式
    if (!this.capabilities.toolCalling.supportsFreeform) {
      return tools.map(tool => ({
        type: 'function',
        function: {
          name: tool.name,
          description: tool.description || '',
          parameters: tool.inputJSONSchema || zodToJsonSchema(tool.inputSchema)
        }
      }))
    }
    
    // Custom tools格式GPT-5特性
    return tools.map(tool => {
      const hasSchema = tool.inputJSONSchema || tool.inputSchema
      const isCustom = !hasSchema || tool.freeformInput
      
      if (isCustom) {
        // Custom tool格式
        return {
          type: 'custom',
          name: tool.name,
          description: tool.description || ''
        }
      } else {
        // 传统function格式
        return {
          type: 'function',
          function: {
            name: tool.name,
            description: tool.description || '',
            parameters: tool.inputJSONSchema || zodToJsonSchema(tool.inputSchema)
          }
        }
      }
    })
  }
  
  parseResponse(response: any): UnifiedResponse {
    // 处理基础文本输出
    let content = response.output_text || ''
    
    // 处理结构化输出
    if (response.output && Array.isArray(response.output)) {
      const messageItems = response.output.filter(item => item.type === 'message')
      if (messageItems.length > 0) {
        content = messageItems
          .map(item => {
            if (item.content && Array.isArray(item.content)) {
              return item.content
                .filter(c => c.type === 'text')
                .map(c => c.text)
                .join('\n')
            }
            return item.content || ''
          })
          .filter(Boolean)
          .join('\n\n')
      }
    }
    
    // 解析工具调用
    const toolCalls = this.parseToolCalls(response)
    
    // 构建统一响应
    return {
      id: response.id || `resp_${Date.now()}`,
      content,
      toolCalls,
      usage: {
        promptTokens: response.usage?.input_tokens || 0,
        completionTokens: response.usage?.output_tokens || 0,
        reasoningTokens: response.usage?.output_tokens_details?.reasoning_tokens
      },
      responseId: response.id  // 保存用于状态管理
    }
  }
  
  private convertMessagesToInput(messages: any[]): any {
    // 将消息转换为Responses API的input格式
    // 可能需要根据实际API规范调整
    return messages
  }
  
  private buildInstructions(systemPrompt: string[], systemMessages: any[]): string {
    const systemContent = systemMessages.map(m => m.content).join('\n\n')
    const promptContent = systemPrompt.join('\n\n')
    return [systemContent, promptContent].filter(Boolean).join('\n\n')
  }
  
  private parseToolCalls(response: any): any[] {
    if (!response.output || !Array.isArray(response.output)) {
      return []
    }
    
    return response.output
      .filter(item => item.type === 'tool_call')
      .map(item => ({
        id: item.id || `tool_${Date.now()}`,
        type: 'tool_call',
        name: item.name,
        arguments: item.arguments  // 可能是文本或JSON
      }))
  }
}

Step 1.5: 创建Chat Completions适配器

文件: src/services/adapters/chatCompletions.ts (新建)

任务: 实现Chat Completions适配器

import { ModelAPIAdapter } from './base'
import { UnifiedRequestParams, UnifiedResponse } from '../../types/modelCapabilities'
import { Tool } from '../../Tool'
import { zodToJsonSchema } from '../../utils/zodToJsonSchema'

export class ChatCompletionsAdapter extends ModelAPIAdapter {
  createRequest(params: UnifiedRequestParams): any {
    const { messages, systemPrompt, tools, maxTokens, stream } = params
    
    // 构建完整消息列表(包含系统提示)
    const fullMessages = this.buildMessages(systemPrompt, messages)
    
    // 构建请求
    const request: any = {
      model: this.modelProfile.modelName,
      messages: fullMessages,
      [this.getMaxTokensParam()]: maxTokens,
      temperature: this.getTemperature()
    }
    
    // 添加工具
    if (tools && tools.length > 0) {
      request.tools = this.buildTools(tools)
      request.tool_choice = 'auto'
    }
    
    // 添加流式选项
    if (stream) {
      request.stream = true
      request.stream_options = {
        include_usage: true
      }
    }
    
    // O1模型的特殊处理
    if (this.modelProfile.modelName.startsWith('o1')) {
      delete request.temperature  // O1不支持temperature
      delete request.stream  // O1不支持流式
      delete request.stream_options
    }
    
    return request
  }
  
  buildTools(tools: Tool[]): any[] {
    // Chat Completions只支持传统的function calling
    return tools.map(tool => ({
      type: 'function',
      function: {
        name: tool.name,
        description: tool.description || '',
        parameters: tool.inputJSONSchema || zodToJsonSchema(tool.inputSchema)
      }
    }))
  }
  
  parseResponse(response: any): UnifiedResponse {
    const choice = response.choices?.[0]
    
    return {
      id: response.id || `chatcmpl_${Date.now()}`,
      content: choice?.message?.content || '',
      toolCalls: choice?.message?.tool_calls || [],
      usage: {
        promptTokens: response.usage?.prompt_tokens || 0,
        completionTokens: response.usage?.completion_tokens || 0
      }
    }
  }
  
  private buildMessages(systemPrompt: string[], messages: any[]): any[] {
    // 合并系统提示和消息
    const systemMessages = systemPrompt.map(prompt => ({
      role: 'system',
      content: prompt
    }))
    
    return [...systemMessages, ...messages]
  }
}

Step 1.6: 创建适配器工厂

文件: src/services/modelAdapterFactory.ts (新建)

任务: 创建工厂类来选择合适的适配器

import { ModelAPIAdapter } from './adapters/base'
import { ResponsesAPIAdapter } from './adapters/responsesAPI'
import { ChatCompletionsAdapter } from './adapters/chatCompletions'
import { getModelCapabilities } from '../constants/modelCapabilities'
import { ModelProfile, getGlobalConfig } from '../utils/config'
import { ModelCapabilities } from '../types/modelCapabilities'

export class ModelAdapterFactory {
  /**
   * 根据模型配置创建合适的适配器
   */
  static createAdapter(modelProfile: ModelProfile): ModelAPIAdapter {
    const capabilities = getModelCapabilities(modelProfile.modelName)
    
    // 决定使用哪种API
    const apiType = this.determineAPIType(modelProfile, capabilities)
    
    // 创建对应的适配器
    switch (apiType) {
      case 'responses_api':
        return new ResponsesAPIAdapter(capabilities, modelProfile)
      case 'chat_completions':
      default:
        return new ChatCompletionsAdapter(capabilities, modelProfile)
    }
  }
  
  /**
   * 决定应该使用哪种API
   */
  private static determineAPIType(
    modelProfile: ModelProfile,
    capabilities: ModelCapabilities
  ): 'responses_api' | 'chat_completions' {
    // 如果模型不支持Responses API直接使用Chat Completions
    if (capabilities.apiArchitecture.primary !== 'responses_api') {
      return 'chat_completions'
    }
    
    // 检查是否是官方OpenAI端点
    const isOfficialOpenAI = !modelProfile.baseURL || 
      modelProfile.baseURL.includes('api.openai.com')
    
    // 非官方端点使用Chat Completions即使模型支持Responses API
    if (!isOfficialOpenAI) {
      // 如果有fallback选项使用fallback
      if (capabilities.apiArchitecture.fallback === 'chat_completions') {
        return 'chat_completions'
      }
      // 否则使用primary可能会失败但让它尝试
      return capabilities.apiArchitecture.primary
    }
    
    // 检查是否需要流式Responses API暂不支持
    const config = getGlobalConfig()
    if (config.stream && !capabilities.streaming.supported) {
      // 需要流式但Responses API不支持降级到Chat Completions
      if (capabilities.apiArchitecture.fallback === 'chat_completions') {
        return 'chat_completions'
      }
    }
    
    // 使用主要API类型
    return capabilities.apiArchitecture.primary
  }
  
  /**
   * 检查模型是否应该使用Responses API
   */
  static shouldUseResponsesAPI(modelProfile: ModelProfile): boolean {
    const capabilities = getModelCapabilities(modelProfile.modelName)
    const apiType = this.determineAPIType(modelProfile, capabilities)
    return apiType === 'responses_api'
  }
}

🔄 Phase 2: 集成与测试第3-4天

目标

将新系统集成到现有代码中,与旧系统并行运行。

Step 2.1: 修改claude.ts使用新系统

文件: src/services/claude.ts (修改)

任务: 在queryLLMWithProfile中添加新的适配器路径

找到函数: queryLLMWithProfile (约第1182行)

修改内容:

// 在函数开头添加功能开关
const USE_NEW_ADAPTER_SYSTEM = process.env.USE_NEW_ADAPTERS !== 'false'

// 在获取modelProfile后添加新路径
if (USE_NEW_ADAPTER_SYSTEM) {
  // 🚀 新的适配器系统
  const adapter = ModelAdapterFactory.createAdapter(modelProfile)
  
  // 构建统一请求参数
  const unifiedParams: UnifiedRequestParams = {
    messages: openaiMessages,  // 使用已转换的OpenAI格式消息
    systemPrompt: openaiSystem.map(s => s.content),
    tools: toolSchemas,
    maxTokens: getMaxTokensFromProfile(modelProfile),
    stream: config.stream,
    reasoningEffort: modelProfile.reasoningEffort,
    temperature: isGPT5Model(model) ? 1 : MAIN_QUERY_TEMPERATURE
  }
  
  // 创建请求
  const request = adapter.createRequest(unifiedParams)
  
  // 判断使用哪个API端点
  if (ModelAdapterFactory.shouldUseResponsesAPI(modelProfile)) {
    // 调用Responses API复用现有的callGPT5ResponsesAPI
    const response = await callGPT5ResponsesAPI(modelProfile, request, signal)
    return adapter.parseResponse(response)
  } else {
    // 调用Chat Completions复用现有逻辑
    // ... 现有的Chat Completions调用代码
  }
} else {
  // 保留原有逻辑完全不变
  // ... 现有的所有代码
}

Step 2.2: 添加测试脚本

文件: src/test/testAdapters.ts (新建)

任务: 创建测试脚本验证新系统

import { ModelAdapterFactory } from '../services/modelAdapterFactory'
import { getGlobalConfig } from '../utils/config'

// 测试不同模型的适配器选择
const testModels = [
  { modelName: 'gpt-5', provider: 'openai' },
  { modelName: 'gpt-4o', provider: 'openai' },
  { modelName: 'claude-3-5-sonnet-20241022', provider: 'anthropic' },
  { modelName: 'o1', provider: 'openai' },
  { modelName: 'glm-5', provider: 'custom' }
]

testModels.forEach(model => {
  console.log(`Testing ${model.modelName}:`)
  const adapter = ModelAdapterFactory.createAdapter(model as any)
  console.log(`  Adapter type: ${adapter.constructor.name}`)
  console.log(`  Should use Responses API: ${ModelAdapterFactory.shouldUseResponsesAPI(model as any)}`)
})

Step 2.3: 清理硬编码可选Phase 3再做

文件: src/services/openai.ts (修改)

任务: 标记需要移除的硬编码部分(先不删除)

// 在isGPT5Model函数上添加注释
/**
 * @deprecated 将被ModelCapabilities系统替代
 */
function isGPT5Model(modelName: string): boolean {
  return modelName.startsWith('gpt-5')
}

🚀 Phase 3: 优化与清理第5-6天

目标

移除旧代码,完全切换到新系统。

Step 3.1: 移除功能开关

文件: src/services/claude.ts

任务: 移除USE_NEW_ADAPTER_SYSTEM检查默认使用新系统

Step 3.2: 清理硬编码函数

文件列表:

  • src/services/openai.ts - 移除isGPT5Model函数
  • src/services/claude.ts - 移除isGPT5Model函数
  • src/services/openai.ts - 移除MODEL_FEATURES常量

Step 3.3: 更新文档

文件: README.md

任务: 添加新模型支持说明

## 支持的模型

本系统通过能力声明系统支持以下API类型
- Chat Completions API: GPT-4, Claude等传统模型
- Responses API: GPT-5, GPT-6, GLM-5等新一代模型

添加新模型只需在 `src/constants/modelCapabilities.ts` 中配置即可。

验证清单

Phase 1完成标准

  • 所有新文件创建完成
  • 代码可以编译通过
  • 现有功能完全不受影响

Phase 2完成标准

  • 新旧系统可以通过环境变量切换
  • GPT-5可以正常使用
  • 所有现有模型功能正常

Phase 3完成标准

  • 完全使用新系统
  • 代码更简洁清晰
  • 新模型可通过配置添加

🎯 关键注意事项

  1. 不要删除任何现有功能代码直到Phase 3
  2. 始终保持向后兼容
  3. 每个Phase结束后都要测试
  4. 如果出现问题可以立即回滚

📝 外包程序员执行指南

  1. 严格按照Phase顺序执行,不要跳步
  2. 复制粘贴提供的代码,不要自己修改
  3. 遇到问题立即停止并报告
  4. 每完成一个Step都要git commit,方便回滚

此文档设计为"无脑执行"级别,外包程序员只需要:

  1. 创建指定的文件
  2. 复制粘贴提供的代码
  3. 在指定位置修改代码
  4. 运行测试验证

整个过程不需要理解业务逻辑,只需要机械执行即可。