




























@@ -1672,3 +1672,91 @@ describe("archiveSessionTranscripts", () => {
16721672expect(fs.existsSync(transcriptPath)).toBe(false);
16731673});
16741674});
1675+1676+describe("oversized transcript line guards", () => {
1677+let tmpDir: string;
1678+let storePath: string;
1679+1680+registerTempSessionStore("openclaw-session-fs-oversized-", (nextTmpDir, nextStorePath) => {
1681+tmpDir = nextTmpDir;
1682+storePath = nextStorePath;
1683+});
1684+1685+test("readRecentSessionMessagesAsync replaces oversized JSONL lines with placeholders", async () => {
1686+const sessionId = "test-oversized-recent";
1687+const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
1688+const oversizedContent = "x".repeat(300 * 1024);
1689+const lines = [
1690+JSON.stringify({ type: "session", version: 1, id: sessionId }),
1691+JSON.stringify({ message: { role: "user", content: "start" } }),
1692+JSON.stringify({ message: { role: "assistant", content: oversizedContent } }),
1693+JSON.stringify({ message: { role: "user", content: "after oversized" } }),
1694+];
1695+fs.writeFileSync(transcriptPath, `${lines.join("\n")}\n`, "utf-8");
1696+1697+const out = await readRecentSessionMessagesAsync(sessionId, storePath, undefined, {
1698+maxMessages: 10,
1699+});
1700+1701+const serialized = JSON.stringify(out);
1702+expect(serialized).not.toContain(oversizedContent);
1703+expect(serialized).toContain("[chat.history omitted: message too large]");
1704+expect(serialized).toContain("after oversized");
1705+});
1706+1707+test("readRecentSessionUsageFromTranscriptAsync skips oversized lines", async () => {
1708+const sessionId = "test-oversized-usage";
1709+const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);
1710+const oversizedContent = "y".repeat(300 * 1024);
1711+const lines = [
1712+JSON.stringify({ type: "session", version: 1, id: sessionId }),
1713+JSON.stringify({
1714+message: {
1715+role: "assistant",
1716+content: oversizedContent,
1717+usage: { input: 9999, output: 9999 },
1718+provider: "oversized-provider",
1719+model: "oversized-model",
1720+},
1721+}),
1722+JSON.stringify({
1723+message: {
1724+role: "assistant",
1725+content: "normal",
1726+usage: { input: 100, output: 50 },
1727+provider: "test-provider",
1728+model: "test-model",
1729+},
1730+}),
1731+];
1732+fs.writeFileSync(transcriptPath, `${lines.join("\n")}\n`, "utf-8");
1733+1734+const usage = await readRecentSessionUsageFromTranscriptAsync(
1735+sessionId,
1736+storePath,
1737+undefined,
1738+undefined,
1739+512 * 1024,
1740+);
1741+1742+expect(usage).not.toBeNull();
1743+expect(usage?.modelProvider).not.toBe("oversized-provider");
1744+expect(usage?.modelProvider).toBe("test-provider");
1745+});
1746+1747+test("readSessionTitleFieldsFromTranscriptAsync delegates to bounded sync reader", async () => {
1748+const sessionId = "test-async-title-bounded";
1749+writeTranscript(
1750+tmpDir,
1751+sessionId,
1752+buildBasicSessionTranscript(sessionId, "User says hi", "Bot says hello"),
1753+);
1754+1755+const syncResult = readSessionTitleFieldsFromTranscript(sessionId, storePath);
1756+const asyncResult = await readSessionTitleFieldsFromTranscriptAsync(sessionId, storePath);
1757+1758+expect(asyncResult).toEqual(syncResult);
1759+expect(asyncResult.firstUserMessage).toBe("User says hi");
1760+expect(asyncResult.lastMessagePreview).toBe("Bot says hello");
1761+});
1762+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。