Merge branch 'ji' into master (操作日志 Y-Log 上报)

# Conflicts:
#	CLAUDE.md
This commit is contained in:
Administrator committed 2026-06-23 19:22:53 +08:00
commit 053d3e300e
35 files changed
+1182 -125

No files matched your search

+16
View File
@@ -30,6 +30,7 @@ import { useNotification } from "@/core/notification/hooks";
import { saveLastAgentId, useThreadSettings } from "@/core/settings";
import { stopThreadRun, useThreadStream } from "@/core/threads/hooks";
import { textOfMessage } from "@/core/threads/utils";
import { OptType, writeYLog } from "@/core/log/y-log";
import { env } from "@/env";
import { readTaskContext, taskThreadMetadata } from "@/core/auth/task-purpose";
import { TaskPurposePanel } from "@/strategy-components/components/task-components/TaskPurposePanel";
@@ -157,6 +158,21 @@ export default function AgentChatPage({
);
},
onFinish: (state) => {
// 操作日志(Y-Log):专家代理问答完成(成功)后,用最终汇总文本上报一条。
try {
const msgs = state.messages ?? [];
const lastAi = [...msgs].reverse().find((m) => (m as { type?: string }).type === "ai");
const lastHuman = [...msgs].reverse().find((m) => (m as { type?: string }).type === "human");
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-专家代理问答",
url: `/api/threads/${threadId ?? ""}/runs/stream`,
reqParam: { agent_id, question: lastHuman ? textOfMessage(lastHuman) : "" },
returnParam: { data: lastAi ? textOfMessage(lastAi) : "" },
});
} catch {
/* 上报绝不影响问答 */
}
if (document.hidden || !document.hasFocus()) {
let body = "Conversation finished";
const lastMessage = state.messages[state.messages.length - 1];
+16
View File
@@ -53,6 +53,7 @@ import { useThreadStream } from "@/core/threads/hooks";
import { useLayoutMode } from "@/core/system-settings/hooks";
import { useRouteBase } from "@/core/route-base";
import { textOfMessage } from "@/core/threads/utils";
import { OptType, writeYLog } from "@/core/log/y-log";
import { env } from "@/env";
import { cn } from "@/lib/utils";
@@ -187,6 +188,21 @@ export default function ChatPage() {
);
},
onFinish: (state) => {
// 操作日志(Y-Log):问答完成(成功)后,用最终汇总文本上报一条。
try {
const msgs = state.messages ?? [];
const lastAi = [...msgs].reverse().find((m) => (m as { type?: string }).type === "ai");
const lastHuman = [...msgs].reverse().find((m) => (m as { type?: string }).type === "human");
writeYLog({
optType: OptType.other,
optDetail: "B1-CM助手-专家代理问答",
url: `/api/threads/${threadId ?? ""}/runs/stream`,
reqParam: { agent_id: selectedAgentId, question: lastHuman ? textOfMessage(lastHuman) : "" },
returnParam: { data: lastAi ? textOfMessage(lastAi) : "" },
});
} catch {
/* 上报绝不影响问答 */
}
if (document.hidden || !document.hasFocus()) {
let body = "Conversation finished";
const lastMessage = state.messages.at(-1);
+16
View File
@@ -31,6 +31,9 @@ import {
isSidebarEnabledFromSearch,
persistSidebarEnabled,
} from '@/core/page-layout/sidebar-enabled';
import { fetchYLogConfig } from '@/core/log/y-log-config';
import { persistYLogToken } from '@/core/log/y-log-token';
import { OptType, writeYLog } from '@/core/log/y-log';
const DEFAULT_USERNAME = 'guest';
const IFRAME_LOGIN_SOURCE = 'iframe';
@@ -160,6 +163,19 @@ export default function LoginPage() {
return;
}
setStoredAuth(auth);
// 操作日志(Y-Log):只有 token 登录(存在 token1=authToken)才上报。
// 持久化 token1(走 authStorage,嵌入态自动隔离)+ 预热上报配置 + 上报登录。
if (authToken) {
persistYLogToken(authToken);
void fetchYLogConfig();
writeYLog({
optType: OptType.login,
optDetail: 'B1-CM助手-登录',
url: '/api/v1/auth/login/token',
reqParam: { username: loginUserName || auth.user_id },
returnParam: { user_id: auth.user_id },
});
}
// 标准登录把用户名写入 userInfo,供顶栏用户区显示(已有则不覆盖)
setStoredUserName(loginUserName);
// 内网透传的 access_token 合并进 userInfo(在 loginByYUserId 覆盖之后),