feat: 添加LLM模型清单、命令执行记录录制和LLM请求记录录制功能
This commit is contained in:
1 parent
0f94849012
commit
5b58330f01
14 files changed
+1546
-197
No files matched your search
@@ -12,6 +12,7 @@ import type {
|
||||
Tool, Conversation, AgentTrigger,
|
||||
InterceptRule, InterceptPending, InterceptApprovalRow,
|
||||
TaskAssetView, SSProject, SSTask, ConvTokenSummary,
|
||||
CommandRecord, LLMRecordItem, LLMRecordDetail,
|
||||
} from "@/lib/types";
|
||||
|
||||
function getToken(): string | null {
|
||||
@@ -248,6 +249,14 @@ export const api = {
|
||||
}) => post<{ id: number }>("/llm/profiles", p),
|
||||
deleteLLMProfile: (id: string) => del<{ deleted: number }>(`/llm/profiles/${id}`),
|
||||
activateLLMProfile: (id: string) => post<{ ok: boolean }>("/llm/profiles/active", { id: Number(id) }),
|
||||
fetchLLMModels: (provider: string, base_url: string, api_key: string, proxy = "", profile_id?: number) =>
|
||||
post<{ ok: boolean; error?: string; models?: string[] }>("/llm/models", {
|
||||
provider,
|
||||
base_url,
|
||||
api_key,
|
||||
proxy,
|
||||
profile_id,
|
||||
}),
|
||||
|
||||
// ---- agents ----
|
||||
agents: () => get<{ agents: Agent[] }>("/agents").then((r) => arr(r.agents)),
|
||||
@@ -440,4 +449,25 @@ export const api = {
|
||||
});
|
||||
if (!r.ok) throw new Error(await r.text());
|
||||
},
|
||||
|
||||
// ---- commands (Bash execution history) ----
|
||||
commands: (params?: { task?: string; q?: string; page?: number; size?: number }) => {
|
||||
const sp = new URLSearchParams();
|
||||
if (params?.task) sp.set("task", params.task);
|
||||
if (params?.q) sp.set("q", params.q);
|
||||
sp.set("page", String(params?.page ?? 0));
|
||||
sp.set("size", String(params?.size ?? 50));
|
||||
return get<{ commands: CommandRecord[]; total: number }>(`/commands?${sp}`);
|
||||
},
|
||||
|
||||
// ---- LLM records ----
|
||||
llmRecords: (params?: { model?: string; session?: string; page?: number; size?: number }) => {
|
||||
const sp = new URLSearchParams();
|
||||
if (params?.model) sp.set("model", params.model);
|
||||
if (params?.session) sp.set("session", params.session);
|
||||
sp.set("page", String(params?.page ?? 0));
|
||||
sp.set("size", String(params?.size ?? 50));
|
||||
return get<{ records: LLMRecordItem[]; total: number }>(`/llm/records?${sp}`);
|
||||
},
|
||||
llmRecordDetail: (id: number) => get<LLMRecordDetail>(`/llm/records/${id}`),
|
||||
};
|
||||
+39
-179
@@ -1,185 +1,45 @@
|
||||
import {
|
||||
DM_Sans,
|
||||
Figtree,
|
||||
Geist,
|
||||
Geist_Mono,
|
||||
Inter,
|
||||
JetBrains_Mono,
|
||||
Lora,
|
||||
Merriweather,
|
||||
Noto_Sans,
|
||||
Noto_Serif,
|
||||
Nunito_Sans,
|
||||
Outfit,
|
||||
Playfair_Display,
|
||||
Public_Sans,
|
||||
Raleway,
|
||||
Roboto,
|
||||
Roboto_Slab,
|
||||
} from "next/font/google";
|
||||
|
||||
// TEMPORARY: offline build fallback — uses local Geist fonts instead of Google Fonts.
|
||||
// Restore registry.ts.bak after build.
|
||||
import localFont from "next/font/local";
|
||||
import { GeistPixelSquare } from "geist/font/pixel";
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-inter",
|
||||
});
|
||||
|
||||
const notoSans = Noto_Sans({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-noto-sans",
|
||||
});
|
||||
|
||||
const roboto = Roboto({
|
||||
subsets: ["latin"],
|
||||
weight: ["400", "500", "700"],
|
||||
variable: "--font-roboto",
|
||||
});
|
||||
|
||||
const geist = Geist({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-geist",
|
||||
});
|
||||
|
||||
const outfit = Outfit({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-outfit",
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-geist-mono",
|
||||
});
|
||||
|
||||
const dmSans = DM_Sans({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-dm-sans",
|
||||
});
|
||||
|
||||
const nunitoSans = Nunito_Sans({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-nunito-sans",
|
||||
});
|
||||
|
||||
const figtree = Figtree({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-figtree",
|
||||
});
|
||||
|
||||
const raleway = Raleway({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-raleway",
|
||||
});
|
||||
|
||||
const publicSans = Public_Sans({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-public-sans",
|
||||
});
|
||||
|
||||
const jetBrainsMono = JetBrains_Mono({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-jetbrains-mono",
|
||||
});
|
||||
|
||||
const notoSerif = Noto_Serif({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-noto-serif",
|
||||
});
|
||||
|
||||
const robotoSlab = Roboto_Slab({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-roboto-slab",
|
||||
});
|
||||
|
||||
const merriweather = Merriweather({
|
||||
subsets: ["latin"],
|
||||
weight: ["400", "700"],
|
||||
variable: "--font-merriweather",
|
||||
});
|
||||
|
||||
const lora = Lora({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-lora",
|
||||
});
|
||||
|
||||
const playfairDisplay = Playfair_Display({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-playfair-display",
|
||||
});
|
||||
const geist = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-geist" });
|
||||
const inter = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-inter" });
|
||||
const notoSans = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-noto-sans" });
|
||||
const roboto = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-roboto" });
|
||||
const outfit = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-outfit" });
|
||||
const dmSans = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-dm-sans" });
|
||||
const nunitoSans = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-nunito-sans" });
|
||||
const figtree = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-figtree" });
|
||||
const raleway = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-raleway" });
|
||||
const publicSans = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-public-sans" });
|
||||
const notoSerif = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-noto-serif" });
|
||||
const robotoSlab = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-roboto-slab" });
|
||||
const merriweather = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-merriweather" });
|
||||
const lora = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-lora" });
|
||||
const playfairDisplay = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2", variable: "--font-playfair-display" });
|
||||
const geistMono = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-mono/GeistMono-Variable.woff2", variable: "--font-geist-mono" });
|
||||
const jetBrainsMono = localFont({ src: "../../../node_modules/geist/dist/fonts/geist-mono/GeistMono-Variable.woff2", variable: "--font-jetbrains-mono" });
|
||||
|
||||
export const fontRegistry = {
|
||||
geist: {
|
||||
label: "Geist",
|
||||
font: geist,
|
||||
},
|
||||
inter: {
|
||||
label: "Inter",
|
||||
font: inter,
|
||||
},
|
||||
notoSans: {
|
||||
label: "Noto Sans",
|
||||
font: notoSans,
|
||||
},
|
||||
nunitoSans: {
|
||||
label: "Nunito Sans",
|
||||
font: nunitoSans,
|
||||
},
|
||||
figtree: {
|
||||
label: "Figtree",
|
||||
font: figtree,
|
||||
},
|
||||
roboto: {
|
||||
label: "Roboto",
|
||||
font: roboto,
|
||||
},
|
||||
raleway: {
|
||||
label: "Raleway",
|
||||
font: raleway,
|
||||
},
|
||||
dmSans: {
|
||||
label: "DM Sans",
|
||||
font: dmSans,
|
||||
},
|
||||
publicSans: {
|
||||
label: "Public Sans",
|
||||
font: publicSans,
|
||||
},
|
||||
outfit: {
|
||||
label: "Outfit",
|
||||
font: outfit,
|
||||
},
|
||||
geistMono: {
|
||||
label: "Geist Mono",
|
||||
font: geistMono,
|
||||
},
|
||||
geistPixelSquare: {
|
||||
label: "Geist Pixel Square",
|
||||
font: GeistPixelSquare,
|
||||
},
|
||||
jetBrainsMono: {
|
||||
label: "JetBrains Mono",
|
||||
font: jetBrainsMono,
|
||||
},
|
||||
notoSerif: {
|
||||
label: "Noto Serif",
|
||||
font: notoSerif,
|
||||
},
|
||||
robotoSlab: {
|
||||
label: "Roboto Slab",
|
||||
font: robotoSlab,
|
||||
},
|
||||
merriweather: {
|
||||
label: "Merriweather",
|
||||
font: merriweather,
|
||||
},
|
||||
lora: {
|
||||
label: "Lora",
|
||||
font: lora,
|
||||
},
|
||||
playfairDisplay: {
|
||||
label: "Playfair Display",
|
||||
font: playfairDisplay,
|
||||
},
|
||||
geist: { label: "Geist", font: geist },
|
||||
inter: { label: "Inter", font: inter },
|
||||
notoSans: { label: "Noto Sans", font: notoSans },
|
||||
nunitoSans: { label: "Nunito Sans", font: nunitoSans },
|
||||
figtree: { label: "Figtree", font: figtree },
|
||||
roboto: { label: "Roboto", font: roboto },
|
||||
raleway: { label: "Raleway", font: raleway },
|
||||
dmSans: { label: "DM Sans", font: dmSans },
|
||||
publicSans: { label: "Public Sans", font: publicSans },
|
||||
outfit: { label: "Outfit", font: outfit },
|
||||
geistMono: { label: "Geist Mono", font: geistMono },
|
||||
geistPixelSquare: { label: "Geist Pixel Square", font: GeistPixelSquare },
|
||||
jetBrainsMono: { label: "JetBrains Mono", font: jetBrainsMono },
|
||||
notoSerif: { label: "Noto Serif", font: notoSerif },
|
||||
robotoSlab: { label: "Roboto Slab", font: robotoSlab },
|
||||
merriweather: { label: "Merriweather", font: merriweather },
|
||||
lora: { label: "Lora", font: lora },
|
||||
playfairDisplay: { label: "Playfair Display", font: playfairDisplay },
|
||||
} as const;
|
||||
|
||||
export type FontKey = keyof typeof fontRegistry;
|
||||
@@ -188,7 +48,7 @@ export const fontVars = (Object.values(fontRegistry) as Array<(typeof fontRegist
|
||||
.map((f) => f.font.variable)
|
||||
.join(" ");
|
||||
|
||||
export const fontOptions = (Object.entries(fontRegistry) as Array<[FontKey, (typeof fontRegistry)[FontKey]]>).map(
|
||||
export const fontOptions = (Object.entries(fontRegistry) as [FontKey, { label: string; font: { variable: string } }][]).map(
|
||||
([key, f]) => ({
|
||||
key,
|
||||
label: f.label,
|
||||
|
||||
@@ -549,3 +549,37 @@ export interface ConvTokenSummary {
|
||||
cache_read_tokens: number;
|
||||
cache_write_tokens: number;
|
||||
}
|
||||
|
||||
// ---- Command recording (Bash execution history) ----
|
||||
export interface CommandRecord {
|
||||
id: number;
|
||||
exploration_id: number;
|
||||
worker: string;
|
||||
command: string;
|
||||
output: string;
|
||||
is_error: boolean;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
// ---- LLM recording ----
|
||||
export interface LLMRecordItem {
|
||||
id: number;
|
||||
ts: string;
|
||||
model: string;
|
||||
profile_name: string;
|
||||
session_id: string;
|
||||
task_id: string;
|
||||
worker: string;
|
||||
latency_ms: number;
|
||||
input_tokens: number;
|
||||
output_tokens: number;
|
||||
cache_read: number;
|
||||
cache_write: number;
|
||||
status: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface LLMRecordDetail extends LLMRecordItem {
|
||||
request_body: string;
|
||||
response_body: string;
|
||||
}
|
||||
Reference in new issue
Block a user