File size: 4,342 Bytes
e249c6d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | import path from "node:path";
import { afterEach, expect, it, vi } from "vitest";
import { useAutoCleanupTempDirTracker } from "../../../test/helpers/temp-dir.js";
import { loadTranscriptEvents } from "../../config/sessions/session-accessor.js";
import { applyAssistantDeliveryDirectives } from "../../config/sessions/transcript-assistant-delivery.js";
import { sanitizeChatHistoryMessages } from "../../gateway/chat-display-projection.sanitize.js";
import type { AssistantMessage } from "../../llm/types.js";
import { upsertSessionEntry } from "../../plugin-sdk/session-store-runtime.js";
import {
onInternalSessionTranscriptUpdate,
type InternalSessionTranscriptUpdate,
} from "../../sessions/transcript-events.js";
import { closeOpenClawAgentDatabasesForTest } from "../../state/openclaw-agent-db.js";
import { isIntermediateAssistantTranscriptMessage } from "../embedded-agent-runner/message-visibility.js";
import { persistCliAssistantTranscript } from "./cli-run-transcript.js";
const tempDirs = useAutoCleanupTempDirTracker(afterEach);
afterEach(() => closeOpenClawAgentDatabasesForTest());
it.each([
{ kind: "completed", yielded: undefined, stopReason: "stop" },
{ kind: "yielded", yielded: true, stopReason: "stop" },
{ kind: "interrupted", yielded: undefined, stopReason: "aborted" },
{ kind: "interrupted after yielding", yielded: true, stopReason: "aborted" },
] as const)(
"prepares the $kind CLI assistant before its first transcript publication",
async ({ yielded, stopReason }) => {
const root = tempDirs.make("openclaw-cli-media-transcript-");
const target = {
agentId: "main",
sessionId: "cli-media-session",
sessionKey: "agent:main:cli-media",
storePath: path.join(root, "agents", "main", "agent", "openclaw-agent.sqlite"),
};
await upsertSessionEntry({
...target,
entry: { sessionId: target.sessionId, updatedAt: Date.now() },
});
const sourceText = "Artifacts ready\nMEDIA:./artifact.json";
const prepareAssistantTranscriptMessage = vi.fn((message: AssistantMessage) =>
applyAssistantDeliveryDirectives(message, { managedMediaUrls: ["./artifact.json"] }),
);
const updates: InternalSessionTranscriptUpdate[] = [];
const unsubscribe = onInternalSessionTranscriptUpdate((update) => updates.push(update));
try {
const result = await persistCliAssistantTranscript({
runParams: {
...target,
sessionFile: `sqlite://agents/main/${target.sessionId}`,
workspaceDir: root,
prompt: "make an artifact",
provider: "claude-cli",
runId: "cli-media-run",
timeoutMs: 1_000,
persistAssistantTranscript: true,
prepareAssistantTranscriptMessage,
},
text: sourceText,
modelId: "claude-sonnet-4-6",
stopReason,
yielded,
});
expect(result.owned).toBe(true);
expect(prepareAssistantTranscriptMessage).toHaveBeenCalledExactlyOnceWith(
expect.objectContaining({ content: [{ type: "text", text: sourceText }] }),
sourceText,
);
expect(updates).toHaveLength(1);
expect(updates[0]?.message).toMatchObject({
content: [{ type: "text", text: sourceText }],
idempotencyKey: result.idempotencyKey,
openclawDelivery: { mediaUrls: ["./artifact.json"] },
});
const messages = (await loadTranscriptEvents(target)).flatMap((event) =>
typeof event === "object" && event !== null && "message" in event ? [event.message] : [],
);
expect(messages).toHaveLength(1);
expect(isIntermediateAssistantTranscriptMessage(messages[0])).toBe(
yielded === true && stopReason === "stop",
);
expect(messages[0]).toMatchObject({ stopReason });
if (yielded && stopReason === "stop") {
expect(messages[0]).toMatchObject({
openclawStreamFallback: {
replacementText: sourceText,
source: "segment",
itemId: "cli-media-run",
},
});
} else {
expect(messages[0]).not.toHaveProperty("openclawStreamFallback");
}
expect(sanitizeChatHistoryMessages(messages)).toMatchObject([
{ content: [{ type: "text", text: "Artifacts ready" }] },
]);
} finally {
unsubscribe();
}
},
);
|