refactor(admin-web): 模型目录面板改走既有 API 层(adminGetLlmCatalog)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- 新增 lib/api/admin.ts 的 adminGetLlmCatalog({refresh}) + 目录响应类型(lib/types/admin.ts),并由 lib/api.ts 再导出
- LlmCatalogPanel 不再直连 lib/api/core(它曾是全仓唯一这样做的 admin 模块),行为不变:
  五种状态判定、gzip 响应、离线粘贴导入均保持
- 复核:grep lib/api/core 全仓前端 0 命中;npx tsc --noEmit 0 错;npm run build 成功
This commit is contained in:
AskaEth committed 2026-10-04 12:45:36 +08:00
1 parent fa33c79e11
commit 3972ea4007
4 files changed
+51 -6

No files matched your search

@@ -1,10 +1,6 @@
import { useState } from "react";
import { useAsyncData } from "../../../lib/useAsyncData";
import { isNotImplemented } from "../../../lib/api";
// 目录端点是本页新引入的调用;按仓库惯例它本该落在 lib/api/admin.ts 里,
// 但本批次只允许改 Llm.tsx(+ 本文件),因此经 lib/api 的传输层直接调用
// (信封解包 / 401 处理与其余端点一致)。
import { request } from "../../../lib/api/core";
import { adminGetLlmCatalog, isNotImplemented } from "../../../lib/api";
import type { AdminLlmProvider } from "../../../lib/types";
import { Notice } from "../../components";
import { Button, Surface, Tag } from "../../../components/primitives";
@@ -382,7 +378,7 @@ export function CatalogPanel({ onPick }: { onPick: (draft: AdminLlmProvider) =>
const [refreshSeq, setRefreshSeq] = useState(0);
const force = refreshSeq > 0;
const { data, error, loading } = useAsyncData(
() => request<unknown>(force ? "/admin/llm/catalog?refresh=1" : "/admin/llm/catalog"),
() => adminGetLlmCatalog({ refresh: force }),
[refreshSeq]
);
const [pasted, setPasted] = useState<CatalogProvider[]>([]);
+1
View File
@@ -58,6 +58,7 @@ export {
adminDeleteRag,
adminExportSession,
adminGetLlm,
adminGetLlmCatalog,
adminGetOwnerProfile,
adminIndexRag,
adminIoTControl,
+9
View File
@@ -2,6 +2,7 @@ import type {
AdminAutomationRecord,
AdminChannelRecord,
AdminIoTDevice,
AdminLlmCatalog,
AdminLlmConfig,
AdminLlmProvider,
AdminPluginRecord,
@@ -90,6 +91,14 @@ export function adminListUsers(): Promise<AdminUserRecord[]> {
export function adminGetLlm(): Promise<AdminLlmConfig> {
return request<AdminLlmConfig>("/admin/llm");
}
/** GET /api/v1/admin/llm/catalog — models.dev 候选目录(RBAC owner|admin),面板
* 「从模型目录自动化填入」的数据来源。服务端优先用本地快照,opts.refresh 时带
* `?refresh=1` 强制在线刷新;无快照又抓不到时后端回 503 catalog_unavailable,
* 调用方据此提示改用「粘贴导入」,而不是当空目录渲染。 */
export function adminGetLlmCatalog(opts: { refresh?: boolean } = {}): Promise<AdminLlmCatalog> {
const qs = opts.refresh ? "?refresh=1" : "";
return request<AdminLlmCatalog>(`/admin/llm/catalog${qs}`);
}
/** GET /api/v1/admin/automations */
export function adminListAutomations(): Promise<AdminAutomationRecord[]> {
return request<AdminAutomationRecord[]>("/admin/automations");
+39
View File
@@ -142,6 +142,45 @@ export interface AdminLlmConfig {
providers: AdminLlmProvider[];
}
/** 目录里的一个模型能力位(GET /api/v1/admin/llm/catalog)。attachment 为 true
* 表示该模型接受图片/文件输入(→ 面板的 multimodal);两个 limit 缺失/为 0
* 表示「目录未标注」,不是猜测值。 */
export interface AdminLlmCatalogModel {
id: string;
name: string;
attachment: boolean;
reasoning: boolean;
toolCall: boolean;
contextLimit?: number;
outputLimit?: number;
}
/** 目录里的一个供应商:baseURL + 模型清单 + 申请 key 的提示(env 只是变量名
* 提示,面板不写 .env)。 */
export interface AdminLlmCatalogProvider {
id: string;
name: string;
/** 目录未标注 baseURL 时缺省,面板会如实提示需手填。 */
api?: string;
doc?: string;
env?: string[];
/** 目录标注的 SDK 包名,面板据此推荐 wire 协议。 */
npm?: string;
models: AdminLlmCatalogModel[];
}
/** GET /api/v1/admin/llm/catalog 的响应(models.dev 候选目录)。source 说明候选
* 从哪来:`cache`(本地快照)或 `models.dev`(本次在线抓取);stale + warning
* 标记「在线刷新失败、退回上次快照」的离线兜底。两者都拿不到时后端回
* 503 catalog_unavailable(不是空目录)。 */
export interface AdminLlmCatalog {
source: string;
fetchedAt?: string;
stale?: boolean;
warning?: string;
providers: AdminLlmCatalogProvider[];
}
/** An automation / reminder entry (GET/POST /api/v1/admin/automations, planned). */
export interface AdminAutomationRecord {
id: string;