## 核心变更 ### 🔧 关键Bug修复 - 修复LLM/Image服务运行时自定义参数丢失问题 - prepareRuntimeConfig()现在支持customParamOverrides向后兼容 - 确保用户配置的自定义API头、私有开关等参数不会在运行时丢失 ### 🏗️ 统一参数架构 - 新增parameter-schema.ts: 统一参数定义与安全验证 - 新增parameter-utils.ts: 参数合并、验证、拆分工具 - 实现优先级参数合并: requestOverrides > customOverrides > builtInOverrides > defaults - 安全过滤危险参数键(__proto__, apiKey, secret等) ### 📦 服务层改进 - llm/service.ts: 添加prepareRuntimeConfig()方法支持参数迁移 - image/service.ts: 同步实现参数迁移逻辑 - model/manager.ts: 添加读时迁移和弃用警告 - 所有Adapter统一使用UnifiedParameterDefinition ### 🎨 UI组件更新 - 新增ModelParameterEditor.vue: 统一参数编辑器 - 新增ModelAdvancedSection.vue: 高级参数折叠面板 - 简化TextModelEditModal和ImageModelEditModal逻辑 - 支持类型安全的参数编辑(number, boolean, string, select等) ### ✅ 测试覆盖 - 新增parameter-schema.test.ts: 参数定义验证测试 - 新增parameter-utils.test.ts: 参数工具函数测试 - 新增custom-params-migration.test.ts: 参数迁移全流程测试 - 修复anthropic-adapter和gemini-adapter测试以匹配新架构 - 所有582个测试通过(100%通过率) ## 向后兼容性 - 完全兼容旧格式配置(customParamOverrides独立字段) - 读时自动迁移,写时清理已弃用字段 - 保留customParamOverrides以防版本回退 ## 破坏性变更 - 无(完全向后兼容) ## 文档更新 - advancedParameterDefinitions.ts添加弃用说明 - 标注v3.0弃用,v4.0移除计划
66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
DANGEROUS_PARAM_KEY_PATTERNS,
|
|
isSafeCustomKey,
|
|
isValueEmpty,
|
|
normalizeDefaultValue,
|
|
type UnifiedParameterDefinition
|
|
} from '../../src/services/model/parameter-schema'
|
|
|
|
describe('parameter-schema helpers', () => {
|
|
it('checks empty values correctly', () => {
|
|
expect(isValueEmpty(undefined)).toBe(true)
|
|
expect(isValueEmpty(null)).toBe(true)
|
|
expect(isValueEmpty('')).toBe(true)
|
|
expect(isValueEmpty(' ')).toBe(true)
|
|
expect(isValueEmpty([])).toBe(true)
|
|
expect(isValueEmpty(['value'])).toBe(false)
|
|
expect(isValueEmpty(0)).toBe(false)
|
|
expect(isValueEmpty(false)).toBe(false)
|
|
})
|
|
|
|
it('normalizes default values', () => {
|
|
expect(normalizeDefaultValue('')).toBeUndefined()
|
|
expect(normalizeDefaultValue('value')).toBe('value')
|
|
expect(normalizeDefaultValue(null)).toBeUndefined()
|
|
expect(normalizeDefaultValue(undefined)).toBeUndefined()
|
|
expect(normalizeDefaultValue([])).toBeUndefined()
|
|
expect(normalizeDefaultValue(['foo'])).toEqual(['foo'])
|
|
})
|
|
|
|
it('validates safe custom keys', () => {
|
|
expect(isSafeCustomKey('temperature')).toBe(true)
|
|
expect(isSafeCustomKey('cfg-scale')).toBe(true)
|
|
expect(isSafeCustomKey('tool.call/limit')).toBe(true)
|
|
expect(isSafeCustomKey('')).toBe(false)
|
|
expect(isSafeCustomKey(' ')).toBe(false)
|
|
expect(isSafeCustomKey('max tokens')).toBe(false)
|
|
expect(isSafeCustomKey('bad$key')).toBe(false)
|
|
expect(isSafeCustomKey('apiKey')).toBe(false)
|
|
})
|
|
|
|
it('blocks dangerous key patterns', () => {
|
|
for (const pattern of DANGEROUS_PARAM_KEY_PATTERNS) {
|
|
expect(isSafeCustomKey(pattern)).toBe(false)
|
|
expect(isSafeCustomKey(`prefix.${pattern}`)).toBe(false)
|
|
}
|
|
})
|
|
|
|
it('allows interface shape compilation', () => {
|
|
const definition: UnifiedParameterDefinition = {
|
|
name: 'temperature',
|
|
type: 'number',
|
|
defaultValue: 1,
|
|
minValue: 0,
|
|
maxValue: 2,
|
|
step: 0.1,
|
|
labelKey: 'params.temperature.label',
|
|
descriptionKey: 'params.temperature.description',
|
|
required: false,
|
|
unitKey: 'params.temperature.unit',
|
|
tags: ['llm', 'sampling']
|
|
}
|
|
expect(definition.name).toBe('temperature')
|
|
})
|
|
})
|