Commit 58f1def1 authored by edy's avatar edy

feat(desktop): archive expert chat tasks

parent 5ce517c7
Pipeline #18470 failed
...@@ -1663,6 +1663,7 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc ...@@ -1663,6 +1663,7 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
const isXhsProject = (value: string): boolean => /xiaohongshu|xhs|小红书/.test(value); const isXhsProject = (value: string): boolean => /xiaohongshu|xhs|小红书/.test(value);
const isDouyinProject = (value: string): boolean => /douyin|抖音|tiktok/.test(value); const isDouyinProject = (value: string): boolean => /douyin|抖音|tiktok/.test(value);
const isZhihuProject = (value: string): boolean => /zhihu|知乎/.test(value);
const resolveTaskPanelExpertName = (projectId: string, projectRoot: string): string | null => { const resolveTaskPanelExpertName = (projectId: string, projectRoot: string): string | null => {
const normalizedProjectId = projectId.trim().toLowerCase(); const normalizedProjectId = projectId.trim().toLowerCase();
...@@ -1673,12 +1674,18 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc ...@@ -1673,12 +1674,18 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
if (isDouyinProject(normalizedProjectId)) { if (isDouyinProject(normalizedProjectId)) {
return "抖音专家"; return "抖音专家";
} }
if (isZhihuProject(normalizedProjectId)) {
return "知乎专家";
}
if (isXhsProject(projectBaseName)) { if (isXhsProject(projectBaseName)) {
return "小红书专家"; return "小红书专家";
} }
if (isDouyinProject(projectBaseName)) { if (isDouyinProject(projectBaseName)) {
return "抖音专家"; return "抖音专家";
} }
if (isZhihuProject(projectBaseName)) {
return "知乎专家";
}
return null; return null;
}; };
...@@ -1973,6 +1980,14 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc ...@@ -1973,6 +1980,14 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
await projectStore.appendSessionMessage(result.sessionId, result.reply); await projectStore.appendSessionMessage(result.sessionId, result.reply);
await projectStore.updateSessionLastActive(result.sessionId).catch(() => undefined); await projectStore.updateSessionLastActive(result.sessionId).catch(() => undefined);
runtimeCloudSupervisor.noteMessageSent(result.sessionId, result.reply.content, preparedExecution.executionPolicy.modelId, executionSkillId); runtimeCloudSupervisor.noteMessageSent(result.sessionId, result.reply.content, preparedExecution.executionPolicy.modelId, executionSkillId);
await recordWorkspaceTaskPanelExecution({
sessionId: result.sessionId,
projectId: preparedExecution.sessionState.projectId,
projectRoot: preparedExecution.sessionState.projectRoot,
prompt,
runId: result.reply.id || randomUUID(),
artifacts: []
});
return { ...result, executionPolicy: preparedExecution.executionPolicy }; return { ...result, executionPolicy: preparedExecution.executionPolicy };
} catch (error) { } catch (error) {
const message = error instanceof Error ? error.message : String(error); const message = error instanceof Error ? error.message : String(error);
...@@ -2653,6 +2668,14 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc ...@@ -2653,6 +2668,14 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
await projectStore.updateSessionLastActive(nextSessionId).catch(() => undefined); await projectStore.updateSessionLastActive(nextSessionId).catch(() => undefined);
})().catch(() => undefined); })().catch(() => undefined);
runtimeCloudSupervisor.noteMessageSent(nextSessionId, reply.content, executionPolicy?.modelId, executionSkillId); runtimeCloudSupervisor.noteMessageSent(nextSessionId, reply.content, executionPolicy?.modelId, executionSkillId);
void recordWorkspaceTaskPanelExecution({
sessionId: nextSessionId,
projectId: preparedExecution.sessionState.projectId,
projectRoot: preparedExecution.sessionState.projectRoot,
prompt,
runId,
artifacts: []
});
queueOrSend({ queueOrSend({
type: "completed", type: "completed",
requestId, requestId,
......
...@@ -17,6 +17,25 @@ test("workspace-entry success paths archive xhs and douyin executions without th ...@@ -17,6 +17,25 @@ test("workspace-entry success paths archive xhs and douyin executions without th
assert.match(ipcSource, /douyin\|抖音\|tiktok/) assert.match(ipcSource, /douyin\|抖音\|tiktok/)
}) })
test("workspace-entry task panel matching includes zhihu expert executions", () => {
assert.match(ipcSource, /zhihu\|知乎/)
assert.match(ipcSource, /知乎专家/)
})
test("non-workspace expert chat completions are archived to the task panel", () => {
const firstChatSendIndex = ipcSource.indexOf('reason: "chat-send"')
const nonWorkspaceChatSendIndex = ipcSource.indexOf('reason: "chat-send"', firstChatSendIndex + 1)
const nonWorkspaceChatSendBlock = ipcSource.slice(nonWorkspaceChatSendIndex, ipcSource.indexOf("return { ...result", nonWorkspaceChatSendIndex))
assert.match(nonWorkspaceChatSendBlock, /recordWorkspaceTaskPanelExecution\(\{[\s\S]*projectId: preparedExecution\.sessionState\.projectId/)
const nonWorkspaceStreamIndex = ipcSource.indexOf('reason: "chat-stream"')
const nonWorkspaceCompletedBlock = ipcSource.slice(
ipcSource.indexOf("onCompleted:", nonWorkspaceStreamIndex),
ipcSource.indexOf("onError:", nonWorkspaceStreamIndex)
)
assert.match(nonWorkspaceCompletedBlock, /recordWorkspaceTaskPanelExecution\(\{[\s\S]*projectId: preparedExecution\.sessionState\.projectId/)
})
test("task panel expert matching prioritizes project id before filesystem path", () => { test("task panel expert matching prioritizes project id before filesystem path", () => {
assert.match(ipcSource, /const normalizedProjectId = projectId\.trim\(\)\.toLowerCase\(\)/) assert.match(ipcSource, /const normalizedProjectId = projectId\.trim\(\)\.toLowerCase\(\)/)
assert.match(ipcSource, /const projectBaseName = path\.basename\(projectRoot\)\.toLowerCase\(\)/) assert.match(ipcSource, /const projectBaseName = path\.basename\(projectRoot\)\.toLowerCase\(\)/)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment