

















@@ -136,18 +136,24 @@ function mockMatrixQaRoomClient(params: {
136136events: Array<{
137137event:
138138| MatrixQaObservedEvent
139-| ((client: { sendTextMessage: ReturnType<typeof vi.fn> }) => MatrixQaObservedEvent);
139+| ((client: {
140+sendTextMessage: ReturnType<typeof vi.fn>;
141+}) => MatrixQaObservedEvent | Promise<MatrixQaObservedEvent>);
140142since: string;
141143}>;
142144}) {
143145const primeRoom = vi.fn().mockResolvedValue("driver-sync-start");
144146const sendTextMessage = vi.fn().mockResolvedValue(params.driverEventId);
145147const waitForRoomEvent = vi.fn();
146148for (const entry of params.events) {
147-waitForRoomEvent.mockImplementationOnce(async () => ({
148-event: typeof entry.event === "function" ? entry.event({ sendTextMessage }) : entry.event,
149-since: entry.since,
150-}));
149+waitForRoomEvent.mockImplementationOnce(async () => {
150+const event =
151+typeof entry.event === "function" ? await entry.event({ sendTextMessage }) : entry.event;
152+return {
153+ event,
154+since: entry.since,
155+};
156+});
151157}
152158createMatrixQaClient.mockReturnValue({
153159 primeRoom,
@@ -3078,56 +3084,73 @@ describe("matrix live qa scenarios", () => {
3078308430793085it("captures Matrix tool progress inside the quiet preview before finalizing", async () => {
30803086const previewEventId = "$tool-progress-preview";
3081-const { sendTextMessage } = mockMatrixQaRoomClient({
3082-driverEventId: "$tool-progress-trigger",
3083-events: [
3084-{
3085-event: matrixQaMessageEvent({
3086-kind: "notice",
3087-eventId: previewEventId,
3088-body: "Barnacling...\n`📖 Read: from /tmp/qa/workspace/QA_KICKOFF_TASK.md`",
3089-}),
3090-since: "driver-sync-preview",
3091-},
3092-{
3093-event: ({ sendTextMessage }) =>
3094-matrixQaMessageEvent({
3087+const gatewayWorkspaceDir = await mkdtemp(path.join(os.tmpdir(), "matrix-qa-workspace-"));
3088+try {
3089+const { sendTextMessage } = mockMatrixQaRoomClient({
3090+driverEventId: "$tool-progress-trigger",
3091+events: [
3092+{
3093+event: matrixQaMessageEvent({
30953094kind: "notice",
3096-eventId: "$tool-progress-final",
3097-body: readMatrixQaReplyDirective(
3098-mockMessageBody(sendTextMessage, "sendTextMessage"),
3099-"MATRIX_QA_TOOL_PROGRESS_FIXED",
3100-),
3101-relatesTo: {
3102-relType: "m.replace",
3103-eventId: previewEventId,
3104-},
3095+eventId: previewEventId,
3096+body: "Barnacling...\n`📖 Read: from /tmp/qa/workspace/QA_KICKOFF_TASK.md`",
31053097}),
3106-since: "driver-sync-next",
3107-},
3108-],
3109-});
3098+since: "driver-sync-preview",
3099+},
3100+{
3101+event: async () => {
3102+const task = await readFile(
3103+path.join(gatewayWorkspaceDir, "QA_KICKOFF_TASK.md"),
3104+"utf8",
3105+);
3106+const token = task.trim().split("\n").at(-1) ?? "";
3107+return matrixQaMessageEvent({
3108+kind: "notice",
3109+eventId: "$tool-progress-final",
3110+body: token,
3111+relatesTo: {
3112+relType: "m.replace",
3113+eventId: previewEventId,
3114+},
3115+});
3116+},
3117+since: "driver-sync-next",
3118+},
3119+],
3120+});
311031213111-const scenario = requireMatrixQaScenario("matrix-room-tool-progress-preview");
3122+ const scenario = requireMatrixQaScenario("matrix-room-tool-progress-preview");
311231233113-const result = await runMatrixQaScenario(scenario, matrixQaScenarioContext());
3114-const artifacts = result.artifacts as {
3115-driverEventId?: unknown;
3116-previewBodyPreview?: unknown;
3117-previewEventId?: unknown;
3118-reply?: { eventId?: unknown };
3119-};
3120-expect(artifacts.driverEventId).toBe("$tool-progress-trigger");
3121-expect(artifacts.previewBodyPreview).toBe(
3122-"Barnacling...\n`📖 Read: from /tmp/qa/workspace/QA_KICKOFF_TASK.md`",
3123-);
3124-expect(artifacts.previewEventId).toBe("$tool-progress-preview");
3125-expect(artifacts.reply?.eventId).toBe("$tool-progress-final");
3126-const prompt = mockMessageBody(sendTextMessage, "sendTextMessage");
3127-expect(prompt).toContain("call the read tool exactly once on `QA_KICKOFF_TASK.md`");
3128-expect(prompt).toContain("answering from memory or sending the marker before the tool result fails");
3129-expect(prompt).toContain("Do not read `HEARTBEAT.md`");
3130-expect(prompt).toContain("reply with only this exact marker and no other text");
3124+const result = await runMatrixQaScenario(scenario, {
3125+ ...matrixQaScenarioContext(),
3126+ gatewayWorkspaceDir,
3127+});
3128+const artifacts = result.artifacts as {
3129+driverEventId?: unknown;
3130+previewBodyPreview?: unknown;
3131+previewEventId?: unknown;
3132+reply?: { eventId?: unknown; tokenMatched?: unknown };
3133+token?: string;
3134+};
3135+expect(artifacts.driverEventId).toBe("$tool-progress-trigger");
3136+expect(artifacts.previewBodyPreview).toBe(
3137+"Barnacling...\n`📖 Read: from /tmp/qa/workspace/QA_KICKOFF_TASK.md`",
3138+);
3139+expect(artifacts.previewEventId).toBe("$tool-progress-preview");
3140+expect(artifacts.reply?.eventId).toBe("$tool-progress-final");
3141+expect(artifacts.reply?.tokenMatched).toBe(true);
3142+const prompt = mockMessageBody(sendTextMessage, "sendTextMessage");
3143+expect(prompt).toContain("call the read tool exactly once on `QA_KICKOFF_TASK.md`");
3144+expect(prompt).toContain("the only valid final marker is inside that file");
3145+expect(prompt).toContain("Do not read `HEARTBEAT.md`");
3146+expect(prompt).toContain("reply with only the exact marker from the file");
3147+expect(prompt).not.toContain(String(artifacts.token));
3148+await expect(
3149+readFile(path.join(gatewayWorkspaceDir, "QA_KICKOFF_TASK.md"), "utf8"),
3150+).resolves.toContain(String(artifacts.token));
3151+} finally {
3152+await rm(gatewayWorkspaceDir, { force: true, recursive: true });
3153+}
31313154});
3132315531333156it("accepts non-read Matrix tool progress lines in quiet previews", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。