惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
腾讯CDC
爱范儿
爱范儿
Google DeepMind News
Google DeepMind News
V
V2EX
Blog — PlanetScale
Blog — PlanetScale
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
量子位
F
Fortinet All Blogs
G
Google Developers Blog
T
The Blog of Author Tim Ferriss
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hugging Face - Blog
Hugging Face - Blog
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
J
Java Code Geeks
S
SegmentFault 最新的问题
D
Docker
博客园 - 司徒正美
The GitHub Blog
The GitHub Blog
Jina AI
Jina AI
M
MIT News - Artificial intelligence
博客园 - 【当耐特】

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix(qa): hide Matrix tool progress marker in workspace · ...
vincentkoc · 2026-05-27 · via Recent Commits to openclaw:main

@@ -136,18 +136,24 @@ function mockMatrixQaRoomClient(params: {

136136

events: Array<{

137137

event:

138138

| MatrixQaObservedEvent

139-

| ((client: { sendTextMessage: ReturnType<typeof vi.fn> }) => MatrixQaObservedEvent);

139+

| ((client: {

140+

sendTextMessage: ReturnType<typeof vi.fn>;

141+

}) => MatrixQaObservedEvent | Promise<MatrixQaObservedEvent>);

140142

since: string;

141143

}>;

142144

}) {

143145

const primeRoom = vi.fn().mockResolvedValue("driver-sync-start");

144146

const sendTextMessage = vi.fn().mockResolvedValue(params.driverEventId);

145147

const waitForRoomEvent = vi.fn();

146148

for (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

}

152158

createMatrixQaClient.mockReturnValue({

153159

primeRoom,

@@ -3078,56 +3084,73 @@ describe("matrix live qa scenarios", () => {

3078308430793085

it("captures Matrix tool progress inside the quiet preview before finalizing", async () => {

30803086

const 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({

30953094

kind: "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

});

3132315531333156

it("accepts non-read Matrix tool progress lines in quiet previews", async () => {