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

推荐订阅源

D
DataBreaches.Net
N
Netflix TechBlog - Medium
F
Fortinet All Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
宝玉的分享
宝玉的分享
Y
Y Combinator Blog
博客园 - 聂微东
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
B
Blog RSS Feed
小众软件
小众软件
The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI
Microsoft Azure Blog
Microsoft Azure Blog
V
V2EX
B
Blog
H
Help Net Security
D
Docker
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
罗磊的独立博客
月光博客
月光博客
博客园 - 司徒正美

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: clear sessions tool broad matchers · openclaw/openc...
steipete · 2026-05-11 · via Recent Commits to openclaw:main

@@ -167,6 +167,60 @@ const waitForCalls = async (getCount: () => number, count: number, timeoutMs = 2

167167

);

168168

};

169169170+

type GatewayCall = {

171+

method?: string;

172+

params?: Record<string, unknown>;

173+

};

174+175+

type AgentCallParams = {

176+

message?: string;

177+

lane?: string;

178+

channel?: string;

179+

sessionKey?: string;

180+

extraSystemPrompt?: string;

181+

inputProvenance?: {

182+

kind?: string;

183+

sourceSessionKey?: string;

184+

};

185+

};

186+187+

type SessionsSendDetails = {

188+

status?: string;

189+

runId?: string;

190+

reply?: string;

191+

error?: string;

192+

sessionKey?: string;

193+

delivery?: {

194+

status?: string;

195+

mode?: string;

196+

};

197+

};

198+199+

function requireGatewayCall(call: unknown, method: string): GatewayCall {

200+

const request = call as GatewayCall | undefined;

201+

if (request?.method !== method) {

202+

throw new Error(`expected ${method} gateway call`);

203+

}

204+

return request;

205+

}

206+207+

function agentParams(call: { params?: unknown }): AgentCallParams {

208+

return (call.params ?? {}) as AgentCallParams;

209+

}

210+211+

function expectInterSessionAgentCall(call: { params?: unknown }): void {

212+

const params = agentParams(call);

213+

expect(params.message).toContain("[Inter-session message");

214+

expect(params.message).toContain("isUser=false");

215+

expect(params.lane).toMatch(/^nested(?::|$)/);

216+

expect(params.channel).toBe("webchat");

217+

expect(params.inputProvenance?.kind).toBe("inter_session");

218+

}

219+220+

function sessionsSendDetails(details: unknown): SessionsSendDetails {

221+

return details as SessionsSendDetails;

222+

}

223+170224

describe("sessions tools", () => {

171225

beforeEach(() => {

172226

callGatewayMock.mockClear();

@@ -450,11 +504,10 @@ describe("sessions tools", () => {

450504

}>;

451505

};

452506

expect(details.sessions).toHaveLength(1);

453-

expect(details.sessions?.[0]).toMatchObject({

454-

key: "agent:main:main",

455-

derivedTitle: "Visible project kickoff",

456-

lastMessagePreview: "Visible latest reply",

457-

});

507+

const visible = details.sessions?.[0];

508+

expect(visible?.key).toBe("agent:main:main");

509+

expect(visible?.derivedTitle).toBe("Visible project kickoff");

510+

expect(visible?.lastMessagePreview).toBe("Visible latest reply");

458511

expect(JSON.stringify(details.sessions)).not.toContain("Hidden");

459512

} finally {

460513

fs.rmSync(tmpDir, { recursive: true, force: true });

@@ -761,10 +814,8 @@ describe("sessions tools", () => {

761814

const historyCall = callGatewayMock.mock.calls.find(

762815

(call) => (call[0] as { method?: string }).method === "chat.history",

763816

);

764-

expect(historyCall?.[0]).toMatchObject({

765-

method: "chat.history",

766-

params: { sessionKey: targetKey },

767-

});

817+

const request = requireGatewayCall(historyCall?.[0], "chat.history");

818+

expect(request.params?.sessionKey).toBe(targetKey);

768819

});

769820770821

it("sessions_history errors on missing sessionId", async () => {

@@ -864,11 +915,11 @@ describe("sessions tools", () => {

864915

message: "ping",

865916

timeoutSeconds: 0,

866917

});

867-

expect(fire.details).toMatchObject({

868-

status: "accepted",

869-

runId: "run-1",

870-

delivery: { status: "pending", mode: "announce" },

871-

});

918+

const fireDetails = sessionsSendDetails(fire.details);

919+

expect(fireDetails.status).toBe("accepted");

920+

expect(fireDetails.runId).toBe("run-1");

921+

expect(fireDetails.delivery?.status).toBe("pending");

922+

expect(fireDetails.delivery?.mode).toBe("announce");

872923

await waitForCalls(() => agentCallCount, 3);

873924

await waitForCalls(() => waitCallCount, 3);

874925

await waitForCalls(() => historyCallCount, 3);

@@ -879,11 +930,11 @@ describe("sessions tools", () => {

879930

timeoutSeconds: 1,

880931

});

881932

const waited = await waitPromise;

882-

expect(waited.details).toMatchObject({

883-

status: "ok",

884-

reply: "done",

885-

delivery: { status: "pending", mode: "announce" },

886-

});

933+

const waitedDetails = sessionsSendDetails(waited.details);

934+

expect(waitedDetails.status).toBe("ok");

935+

expect(waitedDetails.reply).toBe("done");

936+

expect(waitedDetails.delivery?.status).toBe("pending");

937+

expect(waitedDetails.delivery?.mode).toBe("announce");

887938

expect(typeof (waited.details as { runId?: string }).runId).toBe("string");

888939

await waitForCalls(() => agentCallCount, 6);

889940

await waitForCalls(() => waitCallCount, 6);

@@ -894,13 +945,7 @@ describe("sessions tools", () => {

894945

const historyOnlyCalls = calls.filter((call) => call.method === "chat.history");

895946

expect(agentCalls).toHaveLength(6);

896947

for (const call of agentCalls) {

897-

expect(call.params).toMatchObject({

898-

message: expect.stringContaining("[Inter-session message"),

899-

lane: expect.stringMatching(/^nested(?::|$)/),

900-

channel: "webchat",

901-

inputProvenance: { kind: "inter_session" },

902-

});

903-

expect((call.params as { message?: string }).message).toContain("isUser=false");

948+

expectInterSessionAgentCall(call);

904949

}

905950

expect(

906951

agentCalls.some(

@@ -966,10 +1011,8 @@ describe("sessions tools", () => {

9661011

const agentCall = callGatewayMock.mock.calls.find(

9671012

(call) => (call[0] as { method?: string }).method === "agent",

9681013

);

969-

expect(agentCall?.[0]).toMatchObject({

970-

method: "agent",

971-

params: { sessionKey: targetKey },

972-

});

1014+

const request = requireGatewayCall(agentCall?.[0], "agent");

1015+

expect(request.params?.sessionKey).toBe(targetKey);

9731016

});

97410179751018

it("sessions_send runs ping-pong then announces", async () => {

@@ -1058,10 +1101,9 @@ describe("sessions tools", () => {

10581101

message: "ping",

10591102

timeoutSeconds: 1,

10601103

});

1061-

expect(waited.details).toMatchObject({

1062-

status: "ok",

1063-

reply: "initial",

1064-

});

1104+

const waitedDetails = sessionsSendDetails(waited.details);

1105+

expect(waitedDetails.status).toBe("ok");

1106+

expect(waitedDetails.reply).toBe("initial");

10651107

await vi.waitFor(

10661108

() => {

10671109

expect(countMatching(calls, (call) => call.method === "agent")).toBe(3);

@@ -1072,11 +1114,10 @@ describe("sessions tools", () => {

10721114

const agentCalls = calls.filter((call) => call.method === "agent");

10731115

expect(agentCalls).toHaveLength(3);

10741116

for (const call of agentCalls) {

1075-

expect(call.params).toMatchObject({

1076-

lane: expect.stringMatching(/^nested(?::|$)/),

1077-

channel: "webchat",

1078-

inputProvenance: { kind: "inter_session" },

1079-

});

1117+

const params = agentParams(call);

1118+

expect(params.lane).toMatch(/^nested(?::|$)/);

1119+

expect(params.channel).toBe("webchat");

1120+

expect(params.inputProvenance?.kind).toBe("inter_session");

10801121

}

1081112210821123

const replySteps = calls.filter(

@@ -1088,11 +1129,9 @@ describe("sessions tools", () => {

10881129

),

10891130

);

10901131

expect(replySteps).toHaveLength(2);

1091-

expect(sendParams).toMatchObject({

1092-

to: "group:target",

1093-

channel: "discord",

1094-

message: "announce now",

1095-

});

1132+

expect(sendParams.to).toBe("group:target");

1133+

expect(sendParams.channel).toBe("discord");

1134+

expect(sendParams.message).toBe("announce now");

10961135

});

1097113610981137

it("sessions_send keeps delayed requester replies alive after a wait timeout", async () => {

@@ -1173,11 +1212,11 @@ describe("sessions tools", () => {

11731212

message: "ping",

11741213

timeoutSeconds: 1,

11751214

});

1176-

expect(result.details).toMatchObject({

1177-

status: "accepted",

1178-

sessionKey: targetKey,

1179-

delivery: { status: "pending", mode: "announce" },

1180-

});

1215+

const details = sessionsSendDetails(result.details);

1216+

expect(details.status).toBe("accepted");

1217+

expect(details.sessionKey).toBe(targetKey);

1218+

expect(details.delivery?.status).toBe("pending");

1219+

expect(details.delivery?.mode).toBe("announce");

1181122011821221

await vi.waitFor(

11831222

() => {

@@ -1206,10 +1245,8 @@ describe("sessions tools", () => {

12061245

sessionKey?: string;

12071246

}

12081247

| undefined;

1209-

expect(replyParams).toMatchObject({

1210-

sessionKey: requesterKey,

1211-

inputProvenance: { sourceSessionKey: targetKey },

1212-

});

1248+

expect(replyParams?.sessionKey).toBe(requesterKey);

1249+

expect(replyParams?.inputProvenance?.sourceSessionKey).toBe(targetKey);

12131250

expect(replyParams?.message).toContain("late director reply");

12141251

expect(replyParams?.extraSystemPrompt).toContain("Agent-to-agent reply step");

12151252

expect(replyParams?.extraSystemPrompt).toContain("Current agent: Agent 1 (requester)");

@@ -1254,11 +1291,10 @@ describe("sessions tools", () => {

12541291

message: "ping",

12551292

timeoutSeconds: 1,

12561293

});

1257-

expect(result.details).toMatchObject({

1258-

status: "timeout",

1259-

error: "agent run timed out",

1260-

sessionKey: targetKey,

1261-

});

1294+

const details = sessionsSendDetails(result.details);

1295+

expect(details.status).toBe("timeout");

1296+

expect(details.error).toBe("agent run timed out");

1297+

expect(details.sessionKey).toBe(targetKey);

12621298

await new Promise((resolve) => setTimeout(resolve, 0));

12631299

expect(countMatching(calls, (call) => call.method === "agent")).toBe(1);

12641300

});

@@ -1322,11 +1358,11 @@ describe("sessions tools", () => {

13221358

timeoutSeconds: 1,

13231359

});

132413601325-

expect(waited.details).toMatchObject({

1326-

status: "ok",

1327-

reply: "child reply",

1328-

delivery: { status: "skipped", mode: "announce" },

1329-

});

1361+

const waitedDetails = sessionsSendDetails(waited.details);

1362+

expect(waitedDetails.status).toBe("ok");

1363+

expect(waitedDetails.reply).toBe("child reply");

1364+

expect(waitedDetails.delivery?.status).toBe("skipped");

1365+

expect(waitedDetails.delivery?.mode).toBe("announce");

13301366

expect(countMatching(calls, (call) => call.method === "agent")).toBe(1);

13311367

const replyPromptAgentCalls = calls.filter(

13321368

(call) =>

@@ -1455,23 +1491,20 @@ describe("sessions tools", () => {

14551491

message: "ping",

14561492

timeoutSeconds: 1,

14571493

});

1458-

expect(waited.details).toMatchObject({

1459-

status: "ok",

1460-

reply: "initial",

1461-

});

1494+

const waitedDetails = sessionsSendDetails(waited.details);

1495+

expect(waitedDetails.status).toBe("ok");

1496+

expect(waitedDetails.reply).toBe("initial");

14621497

await vi.waitFor(

14631498

() => {

14641499

expect(countMatching(calls, (call) => call.method === "send")).toBe(1);

14651500

},

14661501

{ timeout: 2_000, interval: 5 },

14671502

);

146815031469-

expect(sendParams).toMatchObject({

1470-

to: "123@g.us",

1471-

channel: "whatsapp",

1472-

accountId: "work",

1473-

message: "announce now",

1474-

threadId: "99",

1475-

});

1504+

expect(sendParams.to).toBe("123@g.us");

1505+

expect(sendParams.channel).toBe("whatsapp");

1506+

expect(sendParams.accountId).toBe("work");

1507+

expect(sendParams.message).toBe("announce now");

1508+

expect(sendParams.threadId).toBe("99");

14761509

});

14771510

});