feat(y-log): 问答按 LLM 调用各记一条 + 全量补齐各 API 操作埋点

- 问答日志从「每轮 onFinish 一条」改为 useThreadStream onLangChainEvent
  监听 on_chat_model_end,每次大模型调用结束各上报一条(含子代理)
- 广覆盖各 API client 成功路径:查看(view)/查询(search)/新增(create)/
  编辑(edit)/删除(delete)/启停(enabled·disabled)/导入导出,补齐此前
  整模块零埋点与漏掉的单条详情 GET;跳过高频 typeahead/轮询/bootstrap

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
AdministratorandClaude Opus 4.8 committed 2026-06-23 20:42:54 +08:00
1 parent 320f2ef814
commit df9c59e21c
35 files changed
+1569 -224

No files matched your search

+147 -17
View File
@@ -1,5 +1,6 @@
import { apiFetch } from "@/core/api";
import { getBackendBaseURL } from "@/core/config";
import { OptType, writeYLog } from "@/core/log/y-log";
export interface PromptPrefixSettings {
enabled: boolean;
@@ -20,7 +21,14 @@ export async function loadPromptPrefixSettings(): Promise<PromptPrefixSettings>
if (!response.ok) {
throw new Error(`Failed to load prompt prefix settings: ${response.status}`);
}
return (await response.json()) as PromptPrefixSettings;
const data = (await response.json()) as PromptPrefixSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-提示词前缀查看",
url: "/api/system-settings/prompt-prefix",
returnParam: data,
});
return data;
}
export async function updatePromptPrefixSettings(
@@ -40,7 +48,15 @@ export async function updatePromptPrefixSettings(
.catch(() => ({ detail: "Failed to update prompt prefix" }));
throw new Error(detail.detail ?? "Failed to update prompt prefix");
}
return (await response.json()) as PromptPrefixSettings;
const data = (await response.json()) as PromptPrefixSettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-提示词前缀编辑",
url: "/api/system-settings/prompt-prefix",
reqParam: body,
returnParam: data,
});
return data;
}
export interface PrivateSquareStatus {
@@ -86,7 +102,14 @@ export async function loadPrivateSquareStatus(): Promise<PrivateSquareStatus> {
`Failed to load private square settings: ${response.status}`,
);
}
return (await response.json()) as PrivateSquareStatus;
const data = (await response.json()) as PrivateSquareStatus;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-私密广场查看",
url: "/api/system-settings/private-square",
returnParam: data,
});
return data;
}
export interface PublishSquare {
@@ -112,7 +135,14 @@ export async function loadPublishSquares(): Promise<PublishSquaresSettings> {
if (!response.ok) {
throw new Error(`Failed to load publish squares: ${response.status}`);
}
return (await response.json()) as PublishSquaresSettings;
const data = (await response.json()) as PublishSquaresSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-发布广场查看",
url: "/api/system-settings/publish-squares",
returnParam: data,
});
return data;
}
export async function updatePublishSquares(
@@ -132,7 +162,15 @@ export async function updatePublishSquares(
.catch(() => ({ detail: "Failed to update publish squares" }));
throw new Error(detail.detail ?? "Failed to update publish squares");
}
return (await response.json()) as PublishSquaresSettings;
const data = (await response.json()) as PublishSquaresSettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-发布广场编辑",
url: "/api/system-settings/publish-squares",
reqParam: body,
returnParam: data,
});
return data;
}
export type ThemeMode = "light" | "dark" | "lightblue";
@@ -162,7 +200,14 @@ export async function loadAppearanceSettings(): Promise<AppearanceSettings> {
`Failed to load appearance settings: ${response.status}`,
);
}
return (await response.json()) as AppearanceSettings;
const data = (await response.json()) as AppearanceSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-外观查看",
url: "/api/system-settings/appearance",
returnParam: data,
});
return data;
}
export async function updateAppearanceSettings(
@@ -182,7 +227,15 @@ export async function updateAppearanceSettings(
.catch(() => ({ detail: "Failed to update appearance" }));
throw new Error(detail.detail ?? "Failed to update appearance");
}
return (await response.json()) as AppearanceSettings;
const data = (await response.json()) as AppearanceSettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-外观编辑",
url: "/api/system-settings/appearance",
reqParam: body,
returnParam: data,
});
return data;
}
export async function loadCitationDisplaySettings(): Promise<CitationDisplaySettings> {
@@ -194,7 +247,14 @@ export async function loadCitationDisplaySettings(): Promise<CitationDisplaySett
`Failed to load citation display settings: ${response.status}`,
);
}
return (await response.json()) as CitationDisplaySettings;
const data = (await response.json()) as CitationDisplaySettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-引用展示查看",
url: "/api/system-settings/citation-display",
returnParam: data,
});
return data;
}
export async function loadLeaderboardSettings(): Promise<LeaderboardSettings> {
@@ -204,7 +264,14 @@ export async function loadLeaderboardSettings(): Promise<LeaderboardSettings> {
if (!response.ok) {
throw new Error(`Failed to load leaderboard settings: ${response.status}`);
}
return (await response.json()) as LeaderboardSettings;
const data = (await response.json()) as LeaderboardSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-排行榜查看",
url: "/api/system-settings/leaderboard",
returnParam: data,
});
return data;
}
export async function updateLeaderboardSettings(
@@ -224,7 +291,15 @@ export async function updateLeaderboardSettings(
.catch(() => ({ detail: "Failed to update leaderboard settings" }));
throw new Error(detail.detail ?? "Failed to update leaderboard settings");
}
return (await response.json()) as LeaderboardSettings;
const data = (await response.json()) as LeaderboardSettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-排行榜编辑",
url: "/api/system-settings/leaderboard",
reqParam: body,
returnParam: data,
});
return data;
}
export async function updateCitationDisplaySettings(
@@ -244,7 +319,15 @@ export async function updateCitationDisplaySettings(
.catch(() => ({ detail: "Failed to update citation display" }));
throw new Error(detail.detail ?? "Failed to update citation display");
}
return (await response.json()) as CitationDisplaySettings;
const data = (await response.json()) as CitationDisplaySettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-引用展示编辑",
url: "/api/system-settings/citation-display",
reqParam: body,
returnParam: data,
});
return data;
}
export interface SkillCompressionSettings {
@@ -268,7 +351,14 @@ export async function loadSkillCompressionSettings(): Promise<SkillCompressionSe
`Failed to load skill compression settings: ${response.status}`,
);
}
return (await response.json()) as SkillCompressionSettings;
const data = (await response.json()) as SkillCompressionSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-技能压缩查看",
url: "/api/system-settings/skill-compression",
returnParam: data,
});
return data;
}
export async function updateSkillCompressionSettings(
@@ -288,7 +378,15 @@ export async function updateSkillCompressionSettings(
.catch(() => ({ detail: "Failed to update skill compression" }));
throw new Error(detail.detail ?? "Failed to update skill compression");
}
return (await response.json()) as SkillCompressionSettings;
const data = (await response.json()) as SkillCompressionSettings;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-技能压缩编辑",
url: "/api/system-settings/skill-compression",
reqParam: body,
returnParam: data,
});
return data;
}
/** 「按类型聚合」模块(zzJC / zzXD)选中的智能体标签配置(需求 0616 #3/#4)。 */
@@ -306,7 +404,15 @@ export async function loadAgentModuleConfig(
if (!response.ok) {
throw new Error(`Failed to load agent module config: ${response.status}`);
}
return (await response.json()) as AgentModuleConfig;
const data = (await response.json()) as AgentModuleConfig;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-智能体模块查看",
url: `/api/system-settings/agent-modules/${key}`,
reqParam: { key },
returnParam: data,
});
return data;
}
export async function updateAgentModuleConfig(
@@ -327,7 +433,15 @@ export async function updateAgentModuleConfig(
.catch(() => ({ detail: "Failed to update agent module config" }));
throw new Error(detail.detail ?? "Failed to update agent module config");
}
return (await response.json()) as AgentModuleConfig;
const data = (await response.json()) as AgentModuleConfig;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-智能体模块编辑",
url: `/api/system-settings/agent-modules/${key}`,
reqParam: { key, tag_ids: tagIds },
returnParam: data,
});
return data;
}
export interface LogSystemSettings {
@@ -343,7 +457,14 @@ export async function loadLogSystemSettings(): Promise<LogSystemSettings> {
if (!response.ok) {
throw new Error(`Failed to load log system settings: ${response.status}`);
}
return (await response.json()) as LogSystemSettings;
const data = (await response.json()) as LogSystemSettings;
writeYLog({
optType: OptType.view,
optDetail: "B1-CM助手-系统设置-日志系统查看",
url: "/api/system-settings/log-system",
returnParam: data,
});
return data;
}
export async function updatePrivateSquareSettings(
@@ -363,5 +484,14 @@ export async function updatePrivateSquareSettings(
.catch(() => ({ detail: "Failed to update private square" }));
throw new Error(detail.detail ?? "Failed to update private square");
}
return (await response.json()) as PrivateSquareStatus;
const data = (await response.json()) as PrivateSquareStatus;
writeYLog({
optType: OptType.edit,
optDetail: "B1-CM助手-系统设置-私密广场编辑",
url: "/api/system-settings/private-square",
// omit `password` (secret) from the logged request params
reqParam: { enabled: body.enabled, password_set: body.password != null },
returnParam: data,
});
return data;
}