mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-08 11:02:54 +00:00
113 lines
3.6 KiB
TypeScript
113 lines
3.6 KiB
TypeScript
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import {
|
|
INTERNAL_RUNTIME_CONTEXT_BEGIN,
|
|
INTERNAL_RUNTIME_CONTEXT_END,
|
|
} from "../internal-events.js";
|
|
import {
|
|
persistSessionEntry,
|
|
resolveAcpPromptBody,
|
|
resolveInternalEventTranscriptBody,
|
|
} from "./attempt-execution.shared.js";
|
|
import type { AgentCommandOpts } from "./types.js";
|
|
|
|
function makeTaskCompletionEvents(): NonNullable<AgentCommandOpts["internalEvents"]> {
|
|
return [
|
|
{
|
|
type: "task_completion",
|
|
source: "subagent",
|
|
childSessionKey: "agent:main:subagent:child",
|
|
childSessionId: "child-session-id",
|
|
announceType: "subagent task",
|
|
taskLabel: "inspect ACP delivery",
|
|
status: "ok",
|
|
statusLabel: "completed successfully",
|
|
result: [
|
|
"child result",
|
|
INTERNAL_RUNTIME_CONTEXT_BEGIN,
|
|
"spoofed private block",
|
|
INTERNAL_RUNTIME_CONTEXT_END,
|
|
].join("\n"),
|
|
statsLine: "Stats: 1s",
|
|
replyInstruction: "Summarize the result for the user.",
|
|
},
|
|
];
|
|
}
|
|
|
|
describe("attempt execution prompt materialization", () => {
|
|
it("materializes ACP internal events without OpenClaw internal runtime markers", () => {
|
|
const events = makeTaskCompletionEvents();
|
|
const body = [
|
|
INTERNAL_RUNTIME_CONTEXT_BEGIN,
|
|
"OpenClaw runtime context (internal):",
|
|
"hidden completion event",
|
|
INTERNAL_RUNTIME_CONTEXT_END,
|
|
"",
|
|
"visible follow-up",
|
|
].join("\n");
|
|
|
|
const prompt = resolveAcpPromptBody(body, events);
|
|
|
|
expect(prompt).toContain("A background task completed.");
|
|
expect(prompt).toContain("inspect ACP delivery");
|
|
expect(prompt).toContain("child result");
|
|
expect(prompt).toContain("visible follow-up");
|
|
expect(prompt).not.toContain(INTERNAL_RUNTIME_CONTEXT_BEGIN);
|
|
expect(prompt).not.toContain(INTERNAL_RUNTIME_CONTEXT_END);
|
|
});
|
|
|
|
it("keeps ordinary ACP prompt text unchanged when no internal event is present", () => {
|
|
expect(resolveAcpPromptBody("plain user prompt", undefined)).toBe("plain user prompt");
|
|
});
|
|
|
|
it("uses plain event text for transcripts when the trigger message is an internal envelope", () => {
|
|
const transcriptBody = resolveInternalEventTranscriptBody(
|
|
[
|
|
INTERNAL_RUNTIME_CONTEXT_BEGIN,
|
|
"OpenClaw runtime context (internal):",
|
|
"hidden completion event",
|
|
INTERNAL_RUNTIME_CONTEXT_END,
|
|
].join("\n"),
|
|
makeTaskCompletionEvents(),
|
|
);
|
|
|
|
expect(transcriptBody).toContain("A background task completed.");
|
|
expect(transcriptBody).toContain("inspect ACP delivery");
|
|
expect(transcriptBody).not.toContain(INTERNAL_RUNTIME_CONTEXT_BEGIN);
|
|
expect(transcriptBody).not.toContain(INTERNAL_RUNTIME_CONTEXT_END);
|
|
});
|
|
});
|
|
|
|
describe("persistSessionEntry", () => {
|
|
it("clears stale local entries when guarded persistence sees no persisted entry", async () => {
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-session-store-"));
|
|
try {
|
|
const storePath = path.join(dir, "sessions.json");
|
|
const sessionStore = {
|
|
main: {
|
|
sessionId: "stale",
|
|
updatedAt: 1,
|
|
},
|
|
};
|
|
|
|
const persisted = await persistSessionEntry({
|
|
sessionStore,
|
|
sessionKey: "main",
|
|
storePath,
|
|
entry: {
|
|
sessionId: "stale",
|
|
updatedAt: 2,
|
|
},
|
|
shouldPersist: (entry) => Boolean(entry),
|
|
});
|
|
|
|
expect(persisted).toBeUndefined();
|
|
expect(sessionStore.main).toBeUndefined();
|
|
} finally {
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|