























@@ -1,3 +1,5 @@
1+import fs from "node:fs";
2+import os from "node:os";
13import path from "node:path";
24import { beforeEach, describe, expect, it, vi } from "vitest";
35import type { ChannelMessagingAdapter } from "../channels/plugins/types.js";
@@ -297,9 +299,7 @@ describe("sessions tools", () => {
297299params: {
298300activeMinutes: undefined,
299301agentId: "main",
300-includeDerivedTitles: true,
301302includeGlobal: true,
302-includeLastMessage: true,
303303includeUnknown: true,
304304label: "mailbox",
305305limit: undefined,
@@ -356,6 +356,93 @@ describe("sessions tools", () => {
356356expect(cronDetails.sessions?.[0]?.kind).toBe("cron");
357357});
358358359+it("derives mailbox previews only after agent visibility filtering", async () => {
360+const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-sessions-list-preview-"));
361+const storePath = path.join(tmpDir, "sessions.json");
362+try {
363+fs.writeFileSync(
364+path.join(tmpDir, "visible.jsonl"),
365+[
366+JSON.stringify({ type: "session", id: "visible" }),
367+JSON.stringify({ message: { role: "user", content: "Visible project kickoff" } }),
368+JSON.stringify({ message: { role: "assistant", content: "Visible latest reply" } }),
369+].join("\n"),
370+"utf-8",
371+);
372+fs.writeFileSync(
373+path.join(tmpDir, "hidden.jsonl"),
374+[
375+JSON.stringify({ type: "session", id: "hidden" }),
376+JSON.stringify({ message: { role: "user", content: "Hidden cross-agent topic" } }),
377+JSON.stringify({ message: { role: "assistant", content: "Hidden latest reply" } }),
378+].join("\n"),
379+"utf-8",
380+);
381+382+callGatewayMock.mockImplementation(async (opts: unknown) => {
383+const request = opts as { method?: string; params?: Record<string, unknown> };
384+if (request.method === "sessions.list") {
385+expect(request.params?.includeDerivedTitles).toBeUndefined();
386+expect(request.params?.includeLastMessage).toBeUndefined();
387+return {
388+path: storePath,
389+sessions: [
390+{
391+key: "agent:main:main",
392+kind: "direct",
393+sessionId: "visible",
394+updatedAt: 20,
395+},
396+{
397+key: "agent:other:main",
398+kind: "direct",
399+sessionId: "hidden",
400+updatedAt: 21,
401+},
402+],
403+};
404+}
405+return {};
406+});
407+408+const tool = createOpenClawTools({
409+agentSessionKey: "agent:main:main",
410+config: {
411+ ...TEST_CONFIG,
412+tools: {
413+sessions: { visibility: "agent" },
414+agentToAgent: { enabled: false },
415+},
416+} as OpenClawConfig,
417+}).find((candidate) => candidate.name === "sessions_list");
418+expect(tool).toBeDefined();
419+if (!tool) {
420+throw new Error("missing sessions_list tool");
421+}
422+423+const result = await tool.execute("call-preview", {
424+includeDerivedTitles: true,
425+includeLastMessage: true,
426+});
427+const details = result.details as {
428+sessions?: Array<{
429+key?: string;
430+derivedTitle?: string;
431+lastMessagePreview?: string;
432+}>;
433+};
434+expect(details.sessions).toHaveLength(1);
435+expect(details.sessions?.[0]).toMatchObject({
436+key: "agent:main:main",
437+derivedTitle: "Visible project kickoff",
438+lastMessagePreview: "Visible latest reply",
439+});
440+expect(JSON.stringify(details.sessions)).not.toContain("Hidden");
441+} finally {
442+fs.rmSync(tmpDir, { recursive: true, force: true });
443+}
444+});
445+359446it("sessions_list resolves transcriptPath from agent state dir for multi-store listings", async () => {
360447callGatewayMock.mockImplementation(async (opts: unknown) => {
361448const request = opts as { method?: string };
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。