78 lines
3.0 KiB
TypeScript
78 lines
3.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
import {
|
||
createMockMainAgentResponse,
|
||
createMockToolCall,
|
||
MockLlmProvider,
|
||
} from "../src/llm/client.js";
|
||
import { buildIntakeProgress, readIntakeValues } from "../src/intake/intake.js";
|
||
import { PhaseRuntime } from "../src/runtime/phase-runtime.js";
|
||
|
||
describe("phase runtime", () => {
|
||
it("selects basic skill and shows startup inquiry", async () => {
|
||
const runtime = new PhaseRuntime();
|
||
await runtime.start();
|
||
expect(runtime.getSession().waitingReason?.kind).toBe("skill_selection");
|
||
|
||
await runtime.selectSkill("basic");
|
||
expect(runtime.getSession().waitingReason?.kind).toBe("intake");
|
||
expect(runtime.getActiveSkill()?.name).toBe("basic");
|
||
});
|
||
|
||
it("writes book.brief after intake confirm", async () => {
|
||
const runtime = new PhaseRuntime();
|
||
await runtime.start();
|
||
await runtime.selectSkill("basic");
|
||
await runtime.submitInput("科幻中篇,第三人称");
|
||
await runtime.confirmIntake();
|
||
expect(runtime.getSession().slots["book.brief"]).toContain("科幻");
|
||
expect(runtime.getSession().slots.startupCompleted).toBe(true);
|
||
});
|
||
|
||
it("syncs demand tag to blackboard after intake confirm", async () => {
|
||
const runtime = new PhaseRuntime();
|
||
await runtime.start();
|
||
await runtime.selectSkill("roleplay-game-theory");
|
||
const fields = runtime.getActiveSkill()?.intakeFields ?? [];
|
||
await runtime.submitInput("德州扑克,经典博弈情境");
|
||
await runtime.submitInput("玩家A算计型,玩家B怕吃亏");
|
||
await runtime.submitInput("单轮定胜负,需要思考标签与场景描写");
|
||
const progress = buildIntakeProgress(
|
||
fields,
|
||
readIntakeValues(runtime.getSession().slots),
|
||
);
|
||
if (!progress.ready) {
|
||
const values = readIntakeValues(runtime.getSession().slots);
|
||
for (const f of fields.filter((x) => x.required && !values[x.id])) {
|
||
values[f.id] = "补充";
|
||
}
|
||
await runtime.dispatch({
|
||
type: "user_submitted_input",
|
||
payload: { text: "补充", intakeValues: values },
|
||
});
|
||
}
|
||
await runtime.confirmIntake();
|
||
const demand = runtime.getBlackboard().getContentByTag("用户.博弈需求") ?? "";
|
||
expect(demand).toContain("德州扑克");
|
||
expect(runtime.getSession().slots.startupCompleted).toBe(true);
|
||
});
|
||
|
||
it("mock main agent tool loop reads blackboard then proposes worker", async () => {
|
||
const runtime = new PhaseRuntime({
|
||
llm: new MockLlmProvider([
|
||
createMockToolCall("read_blackboard", { tags: ["book.brief"] }),
|
||
createMockToolCall("run_worker", {
|
||
workerId: "outline",
|
||
reason: "已读需求,生成大纲",
|
||
requiresApproval: true,
|
||
}),
|
||
]),
|
||
});
|
||
await runtime.start();
|
||
await runtime.selectSkill("basic");
|
||
await runtime.submitInput("科幻中篇,第三人称");
|
||
await runtime.confirmIntake();
|
||
expect(runtime.getSession().waitingReason?.kind).toBe("approve_step");
|
||
expect(runtime.getSession().pendingDecision?.workerId).toBe("outline");
|
||
});
|
||
});
|