feat(models): 「模型设置」接官方厂家目录 + 按官方页结构重做界面(档案 87 补做)
用户实测反馈:新增条目看不懂、厂家选择太少且国内一家都没有。根因是**第一版只做了手填表单**,没接官方 pi-ai 自带目录(实测 38 家,国内 11 家:蚂蚁 / 通义千问 / 小米 / 月之暗面 / 智谱 / MiniMax)。 - 新文件 src/web/model-catalog.ts:只读官方 data/*.json(10 分钟缓存,不导入 pi-ai 运行时);中文名走显示用静态表,选取范围以目录为准 - 新增 GET /api/me/model-providers(38 家 + cn 分组 + modelCount + 模型名;排除 deepseek —— 平台已有内置入口) - POST /api/me/keys 新增 provider 参数:**目录厂家只需 API 密钥**(端点/协议/模型全由官方目录兜底 —— 官方 config.d.ts 明示 route 命中即继承默认) - refForEntry 判据由「baseUrl 为空」改为「**没有 route**」:否则目录厂家的 key 会被写进 DEEPSEEK_API_KEY - SettingsEntry 的 baseURL/api/models 改为可选:目录厂家只写 apiKeyEnv(写得越少越不容易漂) - 前端按官方页结构重写:提供方行(厂家/说明/状态/操作)+ 新增**先选厂家**(中国大陆 / 国际分组 / 自定义)+ 保留并强化 admin 的「平台共享模型」区块 - 真环境验收:目录端点 38 家 / 国内 11 家;加 moonshotai-cn 只给 key → settings.yaml 仅 apiKeyEnv;删后整块消失
This commit is contained in:
1 parent
918f1d3a51
commit
022b1f770c
7 files changed
+489
-121
No files matched your search
@@ -65,6 +65,13 @@ const DATA = {
|
||||
sharedModelEnabled: true,
|
||||
protocols: ["openai-completions", "openai-responses", "anthropic-messages"],
|
||||
},
|
||||
// 档案 87 补做:官方 pi-ai 厂家目录(「新增」选择框的数据源)—— 国内 + 国际各一家代表
|
||||
"/api/me/model-providers": {
|
||||
providers: [
|
||||
{ id: "moonshotai-cn", label: "月之暗面 Moonshot(中国)", api: "openai-completions", baseURL: "https://api.moonshot.cn/v1", cn: true, modelCount: 12, models: ["kimi-k2", "moonshot-v1-8k"] },
|
||||
{ id: "openai", label: "OpenAI", api: "openai-responses", baseURL: null, cn: false, modelCount: 20, models: ["gpt-4o"] },
|
||||
],
|
||||
},
|
||||
};
|
||||
const sandbox = {
|
||||
console, setTimeout, clearTimeout,
|
||||
@@ -112,6 +119,8 @@ function text(n, out = [], depth = 0) {
|
||||
// 表单控件的占位符也是**用户可见文案**(输入框没有 children)⇒ 一并收集,
|
||||
// 否则「新增表单有哪些栏位」这类断言只能查到可见标签,漏掉真正的引导文案。
|
||||
if (typeof n.props.placeholder === "string") out.push(n.props.placeholder);
|
||||
// `<optgroup label="…">` 同理:分组名是 prop,不收就会漏掉「中国大陆 / 国际」这类分组断言。
|
||||
if (n.type === "optgroup" && typeof n.props.label === "string") out.push(n.props.label);
|
||||
text(n.props.children, out, depth + 1);
|
||||
}
|
||||
}
|
||||
@@ -222,11 +231,19 @@ ok("非 admin:不出现任何功能项", !PORTAL_ITEMS.some(k => tUser.include
|
||||
ok("模型设置:平台共享模型区块 + 开关按钮", tMs.includes("平台共享模型") && tMs.includes("停用共享模型"));
|
||||
// 口径①:条目各自开关 ⇒ 要有「启用/停用」而不是「设为当前」
|
||||
ok("模型设置:条目按各自状态渲染徽章(已启用 / 已停用)", tMs.includes("已启用") && tMs.includes("已停用"));
|
||||
ok("模型设置:内置与自定义两类条目都在列表里", tMs.includes("内置 DeepSeek") && tMs.includes("我的中转网关"));
|
||||
ok("模型设置:自定义条目显示厂家标识 / endpoint / 协议",
|
||||
tMs.includes("my-gw") && tMs.includes("https://api.example.com/v1") && tMs.includes("openai-completions"));
|
||||
ok("模型设置:新增表单(名称 / API Key / Endpoint / 模型清单栏位齐备)",
|
||||
tMs.includes("新增模型条目") && tMs.includes("模型 id,一行一个") && tMs.includes("留空 = 内置 DeepSeek"));
|
||||
ok("模型设置:内置条目显示为「内置 DeepSeek」、自定义条目显示其 route",
|
||||
tMs.includes("内置 DeepSeek") && tMs.includes("my-gw"));
|
||||
ok("模型设置:自定义条目副行显示 endpoint · 协议",
|
||||
tMs.includes("https://api.example.com/v1") && tMs.includes("openai-completions"));
|
||||
// 档案 87 补做:**按官方页的结构** —— 新增先「选厂家」,目录厂家只需填 API 密钥
|
||||
ok("模型设置:新增有厂家选择框(含内置 / 自定义两个端点选项)",
|
||||
tMs.includes("厂家:") && tMs.includes("内置 DeepSeek(平台共享)") && tMs.includes("自定义厂家(OpenAI 兼容网关)…"));
|
||||
ok("模型设置:选择框按「中国大陆 / 国际」分组,并列出目录厂家(含国内厂家)",
|
||||
tMs.includes("中国大陆") && tMs.includes("国际") && tMs.includes("月之暗面 Moonshot(中国)") && tMs.includes("OpenAI"));
|
||||
ok("模型设置:默认选中「内置 DeepSeek」时给出回落说明",
|
||||
tMs.includes("密钥留空则回落到平台共享密钥"));
|
||||
ok("模型设置:词典备齐「只填密钥」相关文案(目录提示 / 展开模型)",
|
||||
!!ZH["ms.catalogHint"] && !!ZH["ms.showModels"] && !!ZH["ms.hideModels"] && !!ZH["ms.pickProvider"]);
|
||||
// 落地在 spawn 时 ⇒ 文案必须说清"重启才生效",否则用户会以为保存即生效
|
||||
ok("模型设置:文案说明「重启实例生效」", tMs.includes("重启实例生效"));
|
||||
const cMs = classes(await render(ms.Comp));
|
||||
|
||||
Reference in new issue
Block a user