You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
5.4 KiB
117 lines
5.4 KiB
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import test from "node:test";
|
|
|
|
const root = path.resolve(import.meta.dirname, "..");
|
|
const read = (...parts) => fs.readFileSync(path.join(root, ...parts), "utf8");
|
|
const sessionSource = read("client", "src", "sections", "superAgent", "utils", "session.js");
|
|
const sidebarHook = read("client", "src", "sections", "superAgent", "hooks", "useSuperAgentSidebar.js");
|
|
const chatHook = read("client", "src", "sections", "superAgent", "hooks", "useSuperAgentChat.js");
|
|
const actions = read("client", "src", "sections", "superAgent", "actions", "api.js");
|
|
const router = read("client", "src", "sections", "superAgent", "router.js");
|
|
const constants = read("client", "src", "sections", "superAgent", "constants.js");
|
|
|
|
function loadSessionUtils() {
|
|
const transformed =
|
|
sessionSource
|
|
.replace(/^import[\s\S]*?from\s+"[^"]+";\s*/gm, "")
|
|
.replace(/export const ([A-Za-z0-9_]+) =/g, "const $1 =") +
|
|
"\nconst DEFAULT_TASK_FOLDER_ID = '__default__';\nconst DEFAULT_TASK_FOLDER_NAME = '默认任务集';\nreturn { buildSidebarTreeFromAgentResources, normalizeSidebarSession, normalizeTaskRealmForDisplay };";
|
|
return new Function(transformed)();
|
|
}
|
|
|
|
const {
|
|
buildSidebarTreeFromAgentResources,
|
|
normalizeSidebarSession,
|
|
normalizeTaskRealmForDisplay,
|
|
} = loadSessionUtils();
|
|
|
|
test("chat route remains /chat", () => {
|
|
assert.match(router, /path: "\/chat"/);
|
|
});
|
|
|
|
test("superAgent storage keys are versioned and legacy ids are cleared", () => {
|
|
assert.match(constants, /superAgent_v2_active_conversation_id/);
|
|
assert.match(constants, /LEGACY_SUPER_AGENT_STORAGE_KEYS/);
|
|
assert.match(sessionSource, /ensureVersionedStorage/);
|
|
assert.match(sessionSource, /removeItem\(key\)/);
|
|
});
|
|
|
|
test("sidebar session keeps conversation id and thread id separate", () => {
|
|
const session = normalizeSidebarSession({
|
|
id: "11111111-1111-4111-8111-111111111111",
|
|
name: "采购任务",
|
|
type: "task",
|
|
taskset_id: "22222222-2222-4222-8222-222222222222",
|
|
thread_id: "33333333-3333-4333-8333-333333333333",
|
|
}, "task");
|
|
assert.equal(session.conversationId, "11111111-1111-4111-8111-111111111111");
|
|
assert.equal(session.threadId, "33333333-3333-4333-8333-333333333333");
|
|
assert.equal(session.tasksetId, "22222222-2222-4222-8222-222222222222");
|
|
});
|
|
|
|
test("tasksets become folders and conversations stay flat", () => {
|
|
const tree = buildSidebarTreeFromAgentResources(
|
|
[{ id: "ts-1", name: "2026 采购" }],
|
|
[
|
|
{ id: "c-1", name: "任务A", type: "task", taskset_id: "ts-1", thread_id: "th-1" },
|
|
{ id: "c-2", name: "闲聊", type: "conversation", taskset_id: null, thread_id: "th-2" },
|
|
],
|
|
);
|
|
const taskRealm = tree.realms.find((item) => item.realm === "task");
|
|
const chatRealm = tree.realms.find((item) => item.realm === "conversation");
|
|
assert.equal(taskRealm.folders[0].name, "2026 采购");
|
|
assert.equal(taskRealm.folders[0].sessions[0].id, "c-1");
|
|
assert.equal(chatRealm.sessions[0].id, "c-2");
|
|
assert.equal(chatRealm.folders.length, 0);
|
|
});
|
|
|
|
test("sidebar and CRUD use new resource paths and ids", () => {
|
|
assert.match(sidebarHook, /listAllTasksets/);
|
|
assert.match(sidebarHook, /listAllConversations/);
|
|
assert.match(actions, /params: \{ tasksetId: folderId \}/);
|
|
assert.match(actions, /params: \{ conversationId: sessionId \}/);
|
|
assert.match(chatHook, /thread_id/);
|
|
assert.match(chatHook, /taskset_id/);
|
|
assert.match(chatHook, /activeConversationId/);
|
|
});
|
|
|
|
test("first real default taskset binds to the fixed sidebar slot", () => {
|
|
const tree = buildSidebarTreeFromAgentResources(
|
|
[{ id: "ts-default", name: "默认任务集" }],
|
|
[{ id: "c-1", name: "任务A", type: "task", taskset_id: "ts-default", thread_id: "th-1" }],
|
|
);
|
|
const displayed = normalizeTaskRealmForDisplay(tree.realms.find((item) => item.realm === "task"));
|
|
assert.equal(displayed.folders.length, 1);
|
|
assert.equal(displayed.folders[0].name, "默认任务集");
|
|
assert.equal(displayed.folders[0].id, "ts-default");
|
|
assert.equal(displayed.folders[0].isVirtualDefault, true);
|
|
assert.equal(displayed.folders[0].sessions[0].id, "c-1");
|
|
});
|
|
|
|
test("empty tasksets still show one placeholder default taskset", () => {
|
|
const tree = buildSidebarTreeFromAgentResources([], []);
|
|
const displayed = normalizeTaskRealmForDisplay(tree.realms.find((item) => item.realm === "task"));
|
|
assert.equal(displayed.folders.length, 1);
|
|
assert.equal(displayed.folders[0].id, "__default__");
|
|
assert.equal(displayed.folders[0].name, "默认任务集");
|
|
assert.equal(displayed.folders[0].isVirtualDefault, true);
|
|
});
|
|
|
|
test("custom tasksets stay beside the bound default taskset", () => {
|
|
const tree = buildSidebarTreeFromAgentResources(
|
|
[
|
|
{ id: "ts-default", name: "默认任务集" },
|
|
{ id: "ts-2", name: "2026 采购" },
|
|
],
|
|
[
|
|
{ id: "c-1", name: "任务A", type: "task", taskset_id: "ts-default", thread_id: "th-1" },
|
|
{ id: "c-2", name: "任务B", type: "task", taskset_id: "ts-2", thread_id: "th-2" },
|
|
],
|
|
);
|
|
const displayed = normalizeTaskRealmForDisplay(tree.realms.find((item) => item.realm === "task"));
|
|
assert.equal(displayed.folders.map((folder) => folder.name).join(","), "默认任务集,2026 采购");
|
|
assert.equal(displayed.folders[0].id, "ts-default");
|
|
assert.equal(displayed.folders[1].id, "ts-2");
|
|
});
|
|
|