feat: initialize drainage network frontend
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
applyPermissionResponse,
|
||||
applyQuestionResponse,
|
||||
finalizeAssistantMessageAfterAbort,
|
||||
toTodoUpdate,
|
||||
upsertPermission,
|
||||
upsertProgress,
|
||||
upsertQuestion
|
||||
} from "./session-state";
|
||||
import type { AgentChatMessage } from "./types";
|
||||
|
||||
describe("agent session state", () => {
|
||||
it("upserts progress events by id", () => {
|
||||
const first = upsertProgress(undefined, {
|
||||
id: "tool-1",
|
||||
phase: "tool",
|
||||
status: "running",
|
||||
title: "调用工具",
|
||||
elapsed_ms: 20
|
||||
});
|
||||
const next = upsertProgress(first, {
|
||||
id: "tool-1",
|
||||
phase: "tool",
|
||||
status: "completed",
|
||||
title: "工具完成",
|
||||
duration_ms: 40
|
||||
});
|
||||
|
||||
expect(next).toHaveLength(1);
|
||||
expect(next[0]).toMatchObject({ id: "tool-1", status: "completed", title: "工具完成", durationMs: 40 });
|
||||
});
|
||||
|
||||
it("normalizes todo updates", () => {
|
||||
expect(
|
||||
toTodoUpdate({
|
||||
session_id: "session-1",
|
||||
todos: [{ id: "todo-1", content: "分析压力", status: "in_progress", priority: "high" }],
|
||||
created_at: 123
|
||||
})
|
||||
).toEqual({
|
||||
sessionId: "session-1",
|
||||
messageId: undefined,
|
||||
todos: [{ id: "todo-1", content: "分析压力", status: "in_progress", priority: "high" }],
|
||||
createdAt: 123
|
||||
});
|
||||
});
|
||||
|
||||
it("tracks permission request and response", () => {
|
||||
const permissions = upsertPermission(undefined, {
|
||||
session_id: "session-1",
|
||||
request_id: "permission-1",
|
||||
permission: "bash",
|
||||
patterns: ["pnpm test"],
|
||||
always: [],
|
||||
created_at: 100
|
||||
});
|
||||
const next = applyPermissionResponse(permissions, {
|
||||
request_id: "permission-1",
|
||||
reply: "once"
|
||||
});
|
||||
|
||||
expect(next?.[0]).toMatchObject({
|
||||
requestId: "permission-1",
|
||||
status: "approved_once"
|
||||
});
|
||||
});
|
||||
|
||||
it("dedupes question requests by tool call id", () => {
|
||||
const questions = upsertQuestion(undefined, {
|
||||
session_id: "session-1",
|
||||
request_id: "call-1",
|
||||
tool: { messageID: "message-1", callID: "call-1" },
|
||||
questions: [{ header: "范围", question: "选择范围", options: [] }],
|
||||
created_at: 100
|
||||
});
|
||||
const next = upsertQuestion(questions, {
|
||||
session_id: "session-1",
|
||||
request_id: "question-1",
|
||||
tool: { messageID: "message-1", callID: "call-1" },
|
||||
questions: [{ header: "范围", question: "选择范围", options: [] }],
|
||||
created_at: 120
|
||||
});
|
||||
const answered = applyQuestionResponse(next, {
|
||||
request_id: "question-1",
|
||||
answers: [["东部"]]
|
||||
});
|
||||
|
||||
expect(next).toHaveLength(1);
|
||||
expect(answered?.[0]).toMatchObject({
|
||||
requestId: "question-1",
|
||||
status: "answered",
|
||||
answers: [["东部"]]
|
||||
});
|
||||
});
|
||||
|
||||
it("finalizes open assistant state after abort", () => {
|
||||
const message: AgentChatMessage = {
|
||||
id: "assistant-1",
|
||||
role: "assistant",
|
||||
content: "",
|
||||
progress: [{ id: "run", phase: "run", status: "running", title: "处理中", startedAt: Date.now() }],
|
||||
permissions: [
|
||||
{
|
||||
requestId: "permission-1",
|
||||
sessionId: "session-1",
|
||||
permission: "bash",
|
||||
patterns: [],
|
||||
always: [],
|
||||
createdAt: 100,
|
||||
status: "pending"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const next = finalizeAssistantMessageAfterAbort(message);
|
||||
|
||||
expect(next.content).toBe("请求已中止。");
|
||||
expect(next.progress?.[0].status).toBe("completed");
|
||||
expect(next.permissions?.[0].status).toBe("aborted");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user