refactor(chat): centralize session persistence

This commit is contained in:
2026-06-10 19:29:42 +08:00
parent cf6cada538
commit fa2c28c1c0
4 changed files with 227 additions and 77 deletions
+79
View File
@@ -1,5 +1,8 @@
import { describe, expect, it } from "bun:test";
import {
buildForkedSessionUiState,
} from "../../src/routes/chat.js";
import {
buildPromptWithLearningContext,
extractLatestFrontendTurn,
@@ -199,3 +202,79 @@ describe("extractLatestFrontendTurn", () => {
});
});
});
describe("buildForkedSessionUiState", () => {
it("copies truncated source messages and preserves tool artifacts", () => {
const forked = buildForkedSessionUiState(
{
messages: [
{ role: "user", content: "画压力曲线" },
{
role: "assistant",
content: "已生成图表",
artifacts: [
{
id: "chart-1",
tool: "show_chart",
kind: "chart",
params: { chart_type: "line" },
},
],
},
{ role: "user", content: "继续分析" },
],
},
{
keepMessageCount: 2,
targetSessionId: "forked-session",
},
);
expect(forked).toEqual({
sessionId: "forked-session",
isTitleManuallyEdited: false,
messages: [
{ role: "user", content: "画压力曲线" },
{
role: "assistant",
content: "已生成图表",
artifacts: [
{
id: "chart-1",
tool: "show_chart",
kind: "chart",
params: { chart_type: "line" },
},
],
},
],
});
});
it("creates an empty branch state when source UI state is missing or keep count is zero", () => {
expect(
buildForkedSessionUiState(null, {
keepMessageCount: 3,
targetSessionId: "forked-without-source",
}),
).toEqual({
sessionId: "forked-without-source",
isTitleManuallyEdited: false,
messages: [],
});
expect(
buildForkedSessionUiState(
{ messages: [{ role: "user", content: "不保留" }] },
{
keepMessageCount: 0,
targetSessionId: "forked-empty",
},
),
).toEqual({
sessionId: "forked-empty",
isTitleManuallyEdited: false,
messages: [],
});
});
});
+35
View File
@@ -1,10 +1,45 @@
import { describe, expect, it } from "bun:test";
import {
appendBackendToolArtifact,
cancelBackendTodos,
upsertBackendQuestion,
} from "../../src/routes/chatUiState.js";
describe("appendBackendToolArtifact", () => {
it("persists show_chart tool calls as chart artifacts", () => {
const artifacts = appendBackendToolArtifact([], {
session_id: "session-1",
tool: "show_chart",
reason: "测试折线图渲染",
params: {
title: "压力曲线",
chart_type: "line",
x_data: ["00:00", "01:00"],
series: [{ name: "P-101", data: [0.42, 0.41] }],
},
}) as Array<Record<string, unknown>>;
expect(artifacts).toHaveLength(1);
expect(artifacts[0]).toMatchObject({
tool: "show_chart",
kind: "chart",
title: "压力曲线",
description: "测试折线图渲染",
params: {
chart_type: "line",
x_data: ["00:00", "01:00"],
series: [{ name: "P-101", data: [0.42, 0.41] }],
},
});
expect(artifacts[0]).toEqual(
expect.objectContaining({
id: expect.stringMatching(/^show_chart-/),
}),
);
});
});
describe("upsertBackendQuestion", () => {
it("replaces a tool-call placeholder with the actionable question request", () => {
const questions = upsertBackendQuestion(