refactor(admin-web): 模型目录面板改走既有 API 层(adminGetLlmCatalog)
- 新增 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:
1 parent
fa33c79e11
commit
3972ea4007
4 files changed
+51
-6
No files matched your search
@@ -1,10 +1,6 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useAsyncData } from "../../../lib/useAsyncData";
|
import { useAsyncData } from "../../../lib/useAsyncData";
|
||||||
import { isNotImplemented } from "../../../lib/api";
|
import { adminGetLlmCatalog, isNotImplemented } from "../../../lib/api";
|
||||||
// 目录端点是本页新引入的调用;按仓库惯例它本该落在 lib/api/admin.ts 里,
|
|
||||||
// 但本批次只允许改 Llm.tsx(+ 本文件),因此经 lib/api 的传输层直接调用
|
|
||||||
// (信封解包 / 401 处理与其余端点一致)。
|
|
||||||
import { request } from "../../../lib/api/core";
|
|
||||||
import type { AdminLlmProvider } from "../../../lib/types";
|
import type { AdminLlmProvider } from "../../../lib/types";
|
||||||
import { Notice } from "../../components";
|
import { Notice } from "../../components";
|
||||||
import { Button, Surface, Tag } from "../../../components/primitives";
|
import { Button, Surface, Tag } from "../../../components/primitives";
|
||||||
@@ -382,7 +378,7 @@ export function CatalogPanel({ onPick }: { onPick: (draft: AdminLlmProvider) =>
|
|||||||
const [refreshSeq, setRefreshSeq] = useState(0);
|
const [refreshSeq, setRefreshSeq] = useState(0);
|
||||||
const force = refreshSeq > 0;
|
const force = refreshSeq > 0;
|
||||||
const { data, error, loading } = useAsyncData(
|
const { data, error, loading } = useAsyncData(
|
||||||
() => request<unknown>(force ? "/admin/llm/catalog?refresh=1" : "/admin/llm/catalog"),
|
() => adminGetLlmCatalog({ refresh: force }),
|
||||||
[refreshSeq]
|
[refreshSeq]
|
||||||
);
|
);
|
||||||
const [pasted, setPasted] = useState<CatalogProvider[]>([]);
|
const [pasted, setPasted] = useState<CatalogProvider[]>([]);
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ export {
|
|||||||
adminDeleteRag,
|
adminDeleteRag,
|
||||||
adminExportSession,
|
adminExportSession,
|
||||||
adminGetLlm,
|
adminGetLlm,
|
||||||
|
adminGetLlmCatalog,
|
||||||
adminGetOwnerProfile,
|
adminGetOwnerProfile,
|
||||||
adminIndexRag,
|
adminIndexRag,
|
||||||
adminIoTControl,
|
adminIoTControl,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type {
|
|||||||
AdminAutomationRecord,
|
AdminAutomationRecord,
|
||||||
AdminChannelRecord,
|
AdminChannelRecord,
|
||||||
AdminIoTDevice,
|
AdminIoTDevice,
|
||||||
|
AdminLlmCatalog,
|
||||||
AdminLlmConfig,
|
AdminLlmConfig,
|
||||||
AdminLlmProvider,
|
AdminLlmProvider,
|
||||||
AdminPluginRecord,
|
AdminPluginRecord,
|
||||||
@@ -90,6 +91,14 @@ export function adminListUsers(): Promise<AdminUserRecord[]> {
|
|||||||
export function adminGetLlm(): Promise<AdminLlmConfig> {
|
export function adminGetLlm(): Promise<AdminLlmConfig> {
|
||||||
return request<AdminLlmConfig>("/admin/llm");
|
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 */
|
/** GET /api/v1/admin/automations */
|
||||||
export function adminListAutomations(): Promise<AdminAutomationRecord[]> {
|
export function adminListAutomations(): Promise<AdminAutomationRecord[]> {
|
||||||
return request<AdminAutomationRecord[]>("/admin/automations");
|
return request<AdminAutomationRecord[]>("/admin/automations");
|
||||||
|
|||||||
@@ -142,6 +142,45 @@ export interface AdminLlmConfig {
|
|||||||
providers: AdminLlmProvider[];
|
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). */
|
/** An automation / reminder entry (GET/POST /api/v1/admin/automations, planned). */
|
||||||
export interface AdminAutomationRecord {
|
export interface AdminAutomationRecord {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
Reference in new issue
Block a user