





















@@ -9,7 +9,6 @@ import { clearSessionTranscriptIndexCache } from "./session-transcript-index.fs.
99import {
1010archiveSessionTranscripts,
1111readFirstUserMessageFromTranscript,
12-readLastMessagePreviewFromTranscript,
1312readLatestSessionUsageFromTranscript,
1413readLatestSessionUsageFromTranscriptAsync,
1514readLatestRecentSessionUsageFromTranscriptAsync,
@@ -275,176 +274,6 @@ describe("readFirstUserMessageFromTranscript", () => {
275274});
276275});
277276278-describe("readLastMessagePreviewFromTranscript", () => {
279-let tmpDir: string;
280-let storePath: string;
281-282-registerTempSessionStore("openclaw-session-fs-test-", (nextTmpDir, nextStorePath) => {
283-tmpDir = nextTmpDir;
284-storePath = nextStorePath;
285-});
286-287-test("returns null for empty file", () => {
288-const sessionId = "test-last-empty";
289-const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
290-fs.writeFileSync(transcriptPath, "", "utf-8");
291-292-const result = readLastMessagePreviewFromTranscript(sessionId, storePath);
293-expect(result).toBeNull();
294-});
295-296-test.each([
297-{
298-sessionId: "test-last-user",
299-lines: [
300-JSON.stringify({ message: { role: "user", content: "First user" } }),
301-JSON.stringify({ message: { role: "assistant", content: "First assistant" } }),
302-JSON.stringify({ message: { role: "user", content: "Last user message" } }),
303-],
304-expected: "Last user message",
305-},
306-{
307-sessionId: "test-last-assistant",
308-lines: [
309-JSON.stringify({ message: { role: "user", content: "User question" } }),
310-JSON.stringify({ message: { role: "assistant", content: "Final assistant reply" } }),
311-],
312-expected: "Final assistant reply",
313-},
314-] as const)(
315-"returns the last user or assistant message from transcript for $sessionId",
316-({ sessionId, lines, expected }) => {
317-const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
318-fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");
319-const result = readLastMessagePreviewFromTranscript(sessionId, storePath);
320-expect(result).toBe(expected);
321-},
322-);
323-324-test("skips system messages to find last user/assistant", () => {
325-const sessionId = "test-last-skip-system";
326-const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
327-const lines = [
328-JSON.stringify({ message: { role: "user", content: "Real last" } }),
329-JSON.stringify({ message: { role: "system", content: "System at end" } }),
330-];
331-fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");
332-333-const result = readLastMessagePreviewFromTranscript(sessionId, storePath);
334-expect(result).toBe("Real last");
335-});
336-337-test("returns null when no user/assistant messages exist", () => {
338-const sessionId = "test-last-no-match";
339-const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
340-const lines = [
341-JSON.stringify({ type: "session", version: 1, id: sessionId }),
342-JSON.stringify({ message: { role: "system", content: "Only system" } }),
343-];
344-fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");
345-346-const result = readLastMessagePreviewFromTranscript(sessionId, storePath);
347-expect(result).toBeNull();
348-});
349-350-test("handles malformed JSON lines gracefully (last preview)", () => {
351-const sessionId = "test-last-malformed";
352-const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
353-const lines = [
354-JSON.stringify({ message: { role: "user", content: "Valid first" } }),
355-"not valid json at end",
356-];
357-fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");
358-359-const result = readLastMessagePreviewFromTranscript(sessionId, storePath);
360-expect(result).toBe("Valid first");
361-});
362-363-test.each([
364-{
365-sessionId: "test-last-array",
366-message: {
367-role: "assistant",
368-content: [{ type: "text", text: "Array content response" }],
369-},
370-expected: "Array content response",
371-},
372-{
373-sessionId: "test-last-output-text",
374-message: {
375-role: "assistant",
376-content: [{ type: "output_text", text: "Output text response" }],
377-},
378-expected: "Output text response",
379-},
380-] as const)(
381-"handles array/output_text content format for $sessionId",
382-({ sessionId, message, expected }) => {
383-const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
384-fs.writeFileSync(transcriptPath, JSON.stringify({ message }), "utf-8");
385-const result = readLastMessagePreviewFromTranscript(sessionId, storePath);
386-expect(result, sessionId).toBe(expected);
387-},
388-);
389-390-test("skips empty content to find previous message", () => {
391-const sessionId = "test-last-skip-empty";
392-const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
393-const lines = [
394-JSON.stringify({ message: { role: "assistant", content: "Has content" } }),
395-JSON.stringify({ message: { role: "user", content: "" } }),
396-];
397-fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");
398-399-const result = readLastMessagePreviewFromTranscript(sessionId, storePath);
400-expect(result).toBe("Has content");
401-});
402-403-test("reads from end of large file (16KB window)", () => {
404-const sessionId = "test-last-large";
405-const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
406-const padding = JSON.stringify({ message: { role: "user", content: "x".repeat(500) } });
407-const lines: string[] = [];
408-for (let i = 0; i < 30; i++) {
409-lines.push(padding);
410-}
411-lines.push(JSON.stringify({ message: { role: "assistant", content: "Last in large file" } }));
412-fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");
413-414-const result = readLastMessagePreviewFromTranscript(sessionId, storePath);
415-expect(result).toBe("Last in large file");
416-});
417-418-test("handles valid UTF-8 content", () => {
419-const sessionId = "test-last-utf8";
420-const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
421-const validLine = JSON.stringify({
422-message: { role: "user", content: "Valid UTF-8: 你好世界 🌍" },
423-});
424-fs.writeFileSync(transcriptPath, validLine, "utf-8");
425-426-const result = readLastMessagePreviewFromTranscript(sessionId, storePath);
427-expect(result).toBe("Valid UTF-8: 你好世界 🌍");
428-});
429-430-test("strips inline directives from last preview text", () => {
431-const sessionId = "test-last-strip-inline-directives";
432-const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
433-const lines = [
434-JSON.stringify({
435-message: {
436-role: "assistant",
437-content: "Hello [[reply_to_current]] world [[audio_as_voice]]",
438-},
439-}),
440-];
441-fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");
442-443-const result = readLastMessagePreviewFromTranscript(sessionId, storePath);
444-expect(result).toBe("Hello world");
445-});
446-});
447-448277describe("shared transcript read behaviors", () => {
449278let tmpDir: string;
450279let storePath: string;
@@ -456,13 +285,11 @@ describe("shared transcript read behaviors", () => {
456285457286test("returns null for missing transcript files", () => {
458287expect(readFirstUserMessageFromTranscript("missing-session", storePath)).toBeNull();
459-expect(readLastMessagePreviewFromTranscript("missing-session", storePath)).toBeNull();
460288});
461289462290test("uses sessionFile overrides when provided", () => {
463291const sessionId = "test-shared-custom";
464292const firstPath = path.join(tmpDir, "custom-first.jsonl");
465-const lastPath = path.join(tmpDir, "custom-last.jsonl");
466293467294fs.writeFileSync(
468295firstPath,
@@ -472,37 +299,22 @@ describe("shared transcript read behaviors", () => {
472299].join("\n"),
473300"utf-8",
474301);
475-fs.writeFileSync(
476-lastPath,
477-JSON.stringify({ message: { role: "assistant", content: "Custom file last" } }),
478-"utf-8",
479-);
480302481303expect(readFirstUserMessageFromTranscript(sessionId, storePath, firstPath)).toBe(
482304"Custom file message",
483305);
484-expect(readLastMessagePreviewFromTranscript(sessionId, storePath, lastPath)).toBe(
485-"Custom file last",
486-);
487306});
488307489308test("trims whitespace in extracted previews", () => {
490309const firstSessionId = "test-shared-first-trim";
491-const lastSessionId = "test-shared-last-trim";
492310493311fs.writeFileSync(
494312path.join(tmpDir, `${firstSessionId}.jsonl`),
495313JSON.stringify({ message: { role: "user", content: " Padded message " } }),
496314"utf-8",
497315);
498-fs.writeFileSync(
499-path.join(tmpDir, `${lastSessionId}.jsonl`),
500-JSON.stringify({ message: { role: "assistant", content: " Padded response " } }),
501-"utf-8",
502-);
503316504317expect(readFirstUserMessageFromTranscript(firstSessionId, storePath)).toBe("Padded message");
505-expect(readLastMessagePreviewFromTranscript(lastSessionId, storePath)).toBe("Padded response");
506318});
507319});
508320此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。