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

推荐订阅源

G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
雷峰网
雷峰网
博客园_首页
The Cloudflare Blog
Hugging Face - Blog
Hugging Face - Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
小众软件
小众软件
D
Docker
P
Proofpoint News Feed
B
Blog
Vercel News
Vercel News
B
Blog RSS Feed
U
Unit 42
月光博客
月光博客
The GitHub Blog
The GitHub Blog
Apple Machine Learning Research
Apple Machine Learning Research
Y
Y Combinator Blog
I
InfoQ
Recent Announcements
Recent Announcements

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
test: tighten embedded subscribe assertions · openclaw/op...
steipete · 2026-05-10 · via Recent Commits to openclaw:main

@@ -112,6 +112,42 @@ describe("subscribeEmbeddedPiSession", () => {

112112

});

113113

}

114114115+

function findBlockReplyPayload(

116+

onBlockReply: { mock: { calls: unknown[][] } },

117+

text: string,

118+

): { mediaUrls?: unknown } | undefined {

119+

return onBlockReply.mock.calls

120+

.map((call) => call[0] as { text?: unknown; mediaUrls?: unknown })

121+

.find((payload) => payload.text === text);

122+

}

123+124+

function expectBlockReplyPayload(

125+

onBlockReply: { mock: { calls: unknown[][] } },

126+

expected: { text: string; mediaUrls?: string[] },

127+

): void {

128+

const payload = findBlockReplyPayload(onBlockReply, expected.text);

129+

expect(payload).toBeDefined();

130+

if (!payload) {

131+

throw new Error(`Expected block reply text: ${expected.text}`);

132+

}

133+

if (expected.mediaUrls !== undefined) {

134+

expect(payload.mediaUrls).toStrictEqual(expected.mediaUrls);

135+

}

136+

}

137+138+

function expectLifecyclePayload(

139+

payloads: Array<Record<string, unknown>>,

140+

expected: { phase: string; livenessState: string; replayInvalid: boolean },

141+

): void {

142+

const payload = payloads.find(

143+

(item) =>

144+

item.phase === expected.phase &&

145+

item.livenessState === expected.livenessState &&

146+

item.replayInvalid === expected.replayInvalid,

147+

);

148+

expect(payload).toBeDefined();

149+

}

150+115151

it("captures usage from completions timings on done events", () => {

116152

const { emit, subscription } = createSubscribedSessionHarness({ runId: "run" });

117153

@@ -362,12 +398,10 @@ describe("subscribeEmbeddedPiSession", () => {

362398

});

363399

await flushBlockReplyCallbacks();

364400365-

expect(onBlockReply).toHaveBeenCalledWith(

366-

expect.objectContaining({

367-

text: "Here is the image.",

368-

mediaUrls: ["/tmp/generated.png"],

369-

}),

370-

);

401+

expectBlockReplyPayload(onBlockReply, {

402+

text: "Here is the image.",

403+

mediaUrls: ["/tmp/generated.png"],

404+

});

371405

});

372406373407

it("does not duplicate generated image media when the assistant reply has MEDIA lines", async () => {

@@ -417,12 +451,10 @@ describe("subscribeEmbeddedPiSession", () => {

417451

});

418452

await flushBlockReplyCallbacks();

419453420-

expect(onBlockReply).toHaveBeenCalledWith(

421-

expect.objectContaining({

422-

text: "Here is the selected image.",

423-

mediaUrls: ["./selected.png"],

424-

}),

425-

);

454+

expectBlockReplyPayload(onBlockReply, {

455+

text: "Here is the selected image.",

456+

mediaUrls: ["./selected.png"],

457+

});

426458

});

427459428460

it("does not attach generated image media to an early streamed chunk before explicit MEDIA", async () => {

@@ -465,11 +497,9 @@ describe("subscribeEmbeddedPiSession", () => {

465497

emit({ type: "message_start", message: { role: "assistant" } });

466498

emitAssistantTextDelta(emit, "Generated 1 image.\n");

467499468-

expect(onBlockReply).toHaveBeenCalledWith(

469-

expect.objectContaining({

470-

text: "Generated 1 image.",

471-

}),

472-

);

500+

expectBlockReplyPayload(onBlockReply, {

501+

text: "Generated 1 image.",

502+

});

473503

const earlyMediaPayloads = onBlockReply.mock.calls

474504

.map(([payload]) => payload)

475505

.filter((payload) => payload.mediaUrls?.length);

@@ -542,12 +572,10 @@ describe("subscribeEmbeddedPiSession", () => {

542572

emit({ type: "agent_end" });

543573

await flushBlockReplyCallbacks();

544574545-

expect(onBlockReply).toHaveBeenCalledWith(

546-

expect.objectContaining({

547-

text: "Here it is.",

548-

mediaUrls: ["/tmp/lobster-boss.mp3"],

549-

}),

550-

);

575+

expectBlockReplyPayload(onBlockReply, {

576+

text: "Here it is.",

577+

mediaUrls: ["/tmp/lobster-boss.mp3"],

578+

});

551579

});

552580553581

it.each([

@@ -610,11 +638,9 @@ describe("subscribeEmbeddedPiSession", () => {

610638

emit({ type: "message_start", message: { role: "assistant" } });

611639

emitAssistantTextDelta(emit, firstChunk);

612640613-

expect(onBlockReply).toHaveBeenCalledWith(

614-

expect.objectContaining({

615-

text: firstChunk.trim(),

616-

}),

617-

);

641+

expectBlockReplyPayload(onBlockReply, {

642+

text: firstChunk.trim(),

643+

});

618644

const earlyMediaPayloads = onBlockReply.mock.calls

619645

.map(([payload]) => payload)

620646

.filter((payload) => payload.mediaUrls?.length);

@@ -1031,9 +1057,10 @@ describe("subscribeEmbeddedPiSession", () => {

10311057

// Look for lifecycle:error event

10321058

const lifecycleError = findLifecycleErrorAgentEvent(onAgentEvent.mock.calls);

103310591034-

expect(lifecycleError).toMatchObject({

1035-

data: { error: expect.stringContaining("API rate limit reached") },

1036-

});

1060+

expect(lifecycleError).toBeDefined();

1061+

const error = (lifecycleError?.data as { error?: unknown } | undefined)?.error;

1062+

expect(typeof error).toBe("string");

1063+

expect(error).toContain("API rate limit reached");

10371064

});

1038106510391066

it("preserves replay-invalid lifecycle truth across compaction retries after mutating tools", () => {

@@ -1067,13 +1094,11 @@ describe("subscribeEmbeddedPiSession", () => {

10671094

hadPotentialSideEffects: true,

10681095

});

10691096

const payloads = extractAgentEventPayloads(onAgentEvent.mock.calls);

1070-

expect(payloads).toContainEqual(

1071-

expect.objectContaining({

1072-

phase: "end",

1073-

livenessState: "abandoned",

1074-

replayInvalid: true,

1075-

}),

1076-

);

1097+

expectLifecyclePayload(payloads, {

1098+

phase: "end",

1099+

livenessState: "abandoned",

1100+

replayInvalid: true,

1101+

});

10771102

});

1078110310791104

it("preserves deterministic side-effect liveness across compaction retries", () => {

@@ -1099,12 +1124,10 @@ describe("subscribeEmbeddedPiSession", () => {

10991124

emit({ type: "agent_end" });

1100112511011126

const payloads = extractAgentEventPayloads(onAgentEvent.mock.calls);

1102-

expect(payloads).toContainEqual(

1103-

expect.objectContaining({

1104-

phase: "end",

1105-

livenessState: "working",

1106-

replayInvalid: true,

1107-

}),

1108-

);

1127+

expectLifecyclePayload(payloads, {

1128+

phase: "end",

1129+

livenessState: "working",

1130+

replayInvalid: true,

1131+

});

11091132

});

11101133

});