fix: preserve inter-session input provenance (thanks @anbecker)

This commit is contained in:
Peter Steinberger
2026-02-13 02:01:53 +01:00
parent 7081dee1af
commit 85409e401b
25 changed files with 415 additions and 12 deletions

View File

@@ -161,6 +161,58 @@ describe("session-memory hook", () => {
expect(memoryContent).not.toContain("search");
});
it("filters out inter-session user messages", async () => {
const tempDir = await makeTempWorkspace("openclaw-session-memory-");
const sessionsDir = path.join(tempDir, "sessions");
await fs.mkdir(sessionsDir, { recursive: true });
const sessionContent = [
JSON.stringify({
type: "message",
message: {
role: "user",
content: "Forwarded internal instruction",
provenance: { kind: "inter_session", sourceTool: "sessions_send" },
},
}),
JSON.stringify({
type: "message",
message: { role: "assistant", content: "Acknowledged" },
}),
JSON.stringify({
type: "message",
message: { role: "user", content: "External follow-up" },
}),
].join("\n");
const sessionFile = await writeWorkspaceFile({
dir: sessionsDir,
name: "test-session.jsonl",
content: sessionContent,
});
const cfg: OpenClawConfig = {
agents: { defaults: { workspace: tempDir } },
};
const event = createHookEvent("command", "new", "agent:main:main", {
cfg,
previousSessionEntry: {
sessionId: "test-123",
sessionFile,
},
});
await handler(event);
const memoryDir = path.join(tempDir, "memory");
const files = await fs.readdir(memoryDir);
const memoryContent = await fs.readFile(path.join(memoryDir, files[0]), "utf-8");
expect(memoryContent).not.toContain("Forwarded internal instruction");
expect(memoryContent).toContain("assistant: Acknowledged");
expect(memoryContent).toContain("user: External follow-up");
});
it("filters out command messages starting with /", async () => {
const tempDir = await makeTempWorkspace("openclaw-session-memory-");
const sessionsDir = path.join(tempDir, "sessions");

View File

@@ -14,6 +14,7 @@ import { resolveAgentWorkspaceDir } from "../../../agents/agent-scope.js";
import { resolveStateDir } from "../../../config/paths.js";
import { createSubsystemLogger } from "../../../logging/subsystem.js";
import { resolveAgentIdFromSessionKey } from "../../../routing/session-key.js";
import { hasInterSessionUserProvenance } from "../../../sessions/input-provenance.js";
import { resolveHookConfig } from "../../config.js";
import { generateSlugViaLLM } from "../../llm-slug-generator.js";
@@ -40,6 +41,9 @@ async function getRecentSessionContent(
const msg = entry.message;
const role = msg.role;
if ((role === "user" || role === "assistant") && msg.content) {
if (role === "user" && hasInterSessionUserProvenance(msg)) {
continue;
}
// Extract text content
const text = Array.isArray(msg.content)
? // oxlint-disable-next-line typescript/no-explicit-any