feat(desktop): add Kimi and Yuanbao monitoring adapters

- implement kimi/yuanbao monitor adapters with dedicated citation panel detection
- detect Kimi session via kimi-auth cookie during account binding
- harden hidden Playwright and bound windows with skipTaskbar/focusable/hiddenInMissionControl to stop stealing focus
- tag hidden bootstrap windows with a unique token so CDP retention resolves the correct page
- enable yuanbao/kimi/wenxin platforms in dev-seed and default monitoring quota
- update kimi loginUrl to www.kimi.com

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-23 09:09:20 +08:00
parent 4142c53fa6
commit f91d2645d3
10 changed files with 4035 additions and 12 deletions
+87 -1
View File
@@ -1163,6 +1163,32 @@ async function detectQwenFromSession(
});
}
async function detectKimiFromSession(
session: Session,
hints: {
displayName?: string | null;
avatarUrl?: string | null;
} = {},
): Promise<DetectedAccount | null> {
const cookies = await session.cookies.get({ url: "https://www.kimi.com/" }).catch(() => []);
if (!cookies.length) {
return null;
}
const authCookie = cookies.find((cookie) =>
cookie.name === "kimi-auth" && isLikelyGenericAICredentialValue(cookie.value),
);
if (!authCookie) {
return null;
}
return sanitizeDetectedAccount({
platformUid: boundedIdentity("kimi-auth", authCookie.value),
displayName: hints.displayName ?? "Kimi 会话",
avatarUrl: hints.avatarUrl ?? null,
});
}
async function detectQwenPlatform(
platformId: string,
label: string,
@@ -1215,6 +1241,58 @@ async function detectQwenPlatform(
});
}
async function detectKimiPlatform(
platformId: string,
label: string,
context: DetectContext,
): Promise<DetectedAccount | null> {
const genericDetected = await detectGenericAIPlatform(platformId, label, context);
if (genericDetected) {
return genericDetected;
}
if (!context.webContents || context.webContents.isDestroyed()) {
return null;
}
const currentURL = context.webContents.getURL();
const platformMeta = aiPlatformCatalog.find((item) => item.id === platformId) ?? null;
if (!platformMeta) {
return null;
}
if (currentURL && looksLikeLoginRedirect(currentURL, platformMeta.loginUrl)) {
return null;
}
const pageState = await readGenericAIPageState(context.webContents).catch(() => null);
if ((pageState?.challengeSignalCount ?? 0) > 0) {
return null;
}
if ((pageState?.loggedOutSignalCount ?? 0) > 0) {
return null;
}
const fromSession = await detectKimiFromSession(context.session, {
displayName: pageState?.displayName ?? `${label} 会话`,
avatarUrl: pageState?.avatarUrl ?? null,
});
if (fromSession) {
return fromSession;
}
const fingerprint = await buildGenericAISessionFingerprint(platformId, context.session, pageState);
if (!fingerprint) {
return null;
}
return sanitizeDetectedAccount({
platformUid: fingerprint,
displayName: pageState?.displayName ?? `${label} 会话`,
avatarUrl: pageState?.avatarUrl ?? null,
});
}
async function detectAIPlatformAccount(
platformId: string,
label: string,
@@ -1224,6 +1302,10 @@ async function detectAIPlatformAccount(
return await detectQwenPlatform(platformId, label, context);
}
if (platformId === "kimi") {
return await detectKimiPlatform(platformId, label, context);
}
return await detectGenericAIPlatform(platformId, label, context);
}
@@ -2446,14 +2528,18 @@ function createBoundWindow(
sessionHandle: Session,
options: { show?: boolean } = {},
): BrowserWindow {
const show = options.show ?? true;
const window = new BrowserWindow({
show: options.show ?? true,
show,
width: 1320,
height: 900,
minWidth: 1100,
minHeight: 760,
title,
autoHideMenuBar: true,
skipTaskbar: !show,
focusable: show,
hiddenInMissionControl: !show,
backgroundColor: nativeTheme.shouldUseDarkColors ? "#15191a" : "#f4f1ea",
webPreferences: {
session: sessionHandle,