




















@@ -14,6 +14,7 @@ import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js";
1414import { clearMemoryPluginState, registerMemoryPromptSection } from "../../plugins/memory-state.js";
1515import { testing as cliBackendsTesting } from "../cli-backends.js";
1616import { hashCliSessionText } from "../cli-session.js";
17+import { resetContextWindowCacheForTest } from "../context.js";
1718import { buildActiveImageGenerationTaskPromptContextForSession } from "../image-generation-task-status.js";
1819import { buildActiveMusicGenerationTaskPromptContextForSession } from "../music-generation-task-status.js";
1920import { buildActiveVideoGenerationTaskPromptContextForSession } from "../video-generation-task-status.js";
@@ -218,6 +219,7 @@ describe("shouldSkipLocalCliCredentialEpoch", () => {
218219mockBuildActiveImageGenerationTaskPromptContextForSession.mockReset();
219220mockBuildActiveVideoGenerationTaskPromptContextForSession.mockReset();
220221mockBuildActiveMusicGenerationTaskPromptContextForSession.mockReset();
222+resetContextWindowCacheForTest();
221223clearMemoryPluginState();
222224vi.unstubAllEnvs();
223225});
@@ -1480,4 +1482,222 @@ describe("shouldSkipLocalCliCredentialEpoch", () => {
14801482fs.rmSync(dir, { recursive: true, force: true });
14811483}
14821484});
1485+1486+it("uses a larger automatic reseed history cap for Claude CLI", async () => {
1487+const { dir, sessionFile } = createSessionFile();
1488+try {
1489+cliBackendsTesting.setDepsForTest({
1490+resolvePluginSetupCliBackend: () => undefined,
1491+resolveRuntimeCliBackends: () => [
1492+{
1493+id: "claude-cli",
1494+pluginId: "anthropic",
1495+bundleMcp: false,
1496+config: {
1497+command: "claude",
1498+args: ["--print"],
1499+output: "jsonl",
1500+input: "stdin",
1501+sessionMode: "existing",
1502+},
1503+},
1504+],
1505+});
1506+1507+const summaryMarker = "RESEED_SUMMARY_MARKER_KEEP";
1508+const padding = "x".repeat(40_000);
1509+fs.appendFileSync(
1510+sessionFile,
1511+`${JSON.stringify({
1512+ type: "compaction",
1513+ summary: `${summaryMarker} ${padding}`,
1514+ })}\n`,
1515+"utf-8",
1516+);
1517+1518+const context = await prepareCliRunContext({
1519+sessionId: "session-test",
1520+ sessionFile,
1521+workspaceDir: dir,
1522+prompt: "latest ask",
1523+provider: "claude-cli",
1524+model: "claude-haiku-3-5",
1525+timeoutMs: 1_000,
1526+runId: "run-auto-claude-reseed-history-chars",
1527+config: createCliBackendConfig({ systemPromptOverride: null }),
1528+});
1529+1530+expect(context.openClawHistoryPrompt).toBeDefined();
1531+expect(context.openClawHistoryPrompt).toContain(summaryMarker);
1532+expect(context.openClawHistoryPrompt).not.toContain("OpenClaw reseed history truncated");
1533+} finally {
1534+fs.rmSync(dir, { recursive: true, force: true });
1535+}
1536+});
1537+1538+it("uses the automatic Claude CLI cap before mapping canonical models to CLI aliases", async () => {
1539+const { dir, sessionFile } = createSessionFile();
1540+try {
1541+cliBackendsTesting.setDepsForTest({
1542+resolvePluginSetupCliBackend: () => undefined,
1543+resolveRuntimeCliBackends: () => [
1544+{
1545+id: "claude-cli",
1546+pluginId: "anthropic",
1547+bundleMcp: false,
1548+config: {
1549+command: "claude",
1550+args: ["--print"],
1551+output: "jsonl",
1552+input: "stdin",
1553+sessionMode: "existing",
1554+modelAliases: {
1555+"claude-opus-4-7": "opus",
1556+},
1557+},
1558+},
1559+],
1560+});
1561+1562+const summaryMarker = "RESEED_ALIAS_SUMMARY_MARKER_KEEP";
1563+const padding = "x".repeat(90_000);
1564+fs.appendFileSync(
1565+sessionFile,
1566+`${JSON.stringify({
1567+ type: "compaction",
1568+ summary: `${summaryMarker} ${padding}`,
1569+ })}\n`,
1570+"utf-8",
1571+);
1572+1573+const context = await prepareCliRunContext({
1574+sessionId: "session-test",
1575+ sessionFile,
1576+workspaceDir: dir,
1577+prompt: "latest ask",
1578+provider: "claude-cli",
1579+model: "claude-opus-4-7",
1580+timeoutMs: 1_000,
1581+runId: "run-auto-claude-alias-reseed-history-chars",
1582+config: createCliBackendConfig({ systemPromptOverride: null }),
1583+});
1584+1585+expect(context.openClawHistoryPrompt).toBeDefined();
1586+expect(context.openClawHistoryPrompt).toContain(summaryMarker);
1587+expect(context.openClawHistoryPrompt).not.toContain("OpenClaw reseed history truncated");
1588+} finally {
1589+fs.rmSync(dir, { recursive: true, force: true });
1590+}
1591+});
1592+1593+it("keeps the default reseed history cap for non-Claude CLI backends", async () => {
1594+const { dir, sessionFile } = createSessionFile();
1595+try {
1596+const summaryMarker = "RESEED_SUMMARY_MARKER_DEFAULT";
1597+const padding = "x".repeat(20_000);
1598+fs.appendFileSync(
1599+sessionFile,
1600+`${JSON.stringify({
1601+ type: "compaction",
1602+ summary: `${summaryMarker} ${padding}`,
1603+ })}\n`,
1604+"utf-8",
1605+);
1606+1607+const context = await prepareCliRunContext({
1608+sessionId: "session-test",
1609+ sessionFile,
1610+workspaceDir: dir,
1611+prompt: "latest ask",
1612+provider: "test-cli",
1613+model: "test-model",
1614+timeoutMs: 1_000,
1615+runId: "run-default-reseed-history-chars",
1616+config: createCliBackendConfig({ systemPromptOverride: null }),
1617+});
1618+1619+expect(context.openClawHistoryPrompt).toBeDefined();
1620+expect(context.openClawHistoryPrompt).toContain("OpenClaw reseed history truncated");
1621+} finally {
1622+fs.rmSync(dir, { recursive: true, force: true });
1623+}
1624+});
1625+1626+it("uses the automatic Claude CLI cap through the raw-tail reseed path", async () => {
1627+const { dir, sessionFile } = createSessionFile();
1628+cliBackendsTesting.setDepsForTest({
1629+resolvePluginSetupCliBackend: () => undefined,
1630+resolveRuntimeCliBackends: () => [
1631+{
1632+id: "claude-cli",
1633+pluginId: "anthropic",
1634+bundleMcp: false,
1635+config: {
1636+command: "claude",
1637+args: ["--print"],
1638+output: "jsonl",
1639+input: "stdin",
1640+sessionMode: "existing",
1641+reseedFromRawTranscriptWhenUncompacted: true,
1642+},
1643+},
1644+],
1645+});
1646+setCliRunnerPrepareTestDeps({
1647+claudeCliSessionTranscriptHasContent: vi.fn(async () => true),
1648+});
1649+const recentMarker = "RAW_RESEED_RECENT_MARKER_KEEP";
1650+const padding = "x".repeat(8_000);
1651+appendTranscriptEntry(sessionFile, {
1652+id: "msg-1",
1653+parentId: null,
1654+timestamp: new Date(1).toISOString(),
1655+message: { role: "user", content: `EARLIEST_USER ${padding}`, timestamp: 1 },
1656+});
1657+appendTranscriptEntry(sessionFile, {
1658+id: "msg-2",
1659+parentId: "msg-1",
1660+timestamp: new Date(2).toISOString(),
1661+message: {
1662+role: "assistant",
1663+content: [{ type: "text", text: `${recentMarker} ${padding}` }],
1664+api: "responses",
1665+provider: "test-cli",
1666+model: "test-model",
1667+usage: {
1668+input: 0,
1669+output: 0,
1670+cacheRead: 0,
1671+cacheWrite: 0,
1672+totalTokens: 0,
1673+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
1674+},
1675+stopReason: "stop",
1676+timestamp: 2,
1677+},
1678+});
1679+1680+try {
1681+const context = await prepareCliRunContext({
1682+sessionId: "session-test",
1683+ sessionFile,
1684+workspaceDir: dir,
1685+prompt: "latest ask",
1686+provider: "claude-cli",
1687+model: "claude-haiku-3-5",
1688+timeoutMs: 1_000,
1689+runId: "run-raw-reseed-cap-override",
1690+cliSessionBinding: { sessionId: "cli-session" },
1691+config: createCliBackendConfig({ systemPromptOverride: null }),
1692+});
1693+1694+expect(context.reusableCliSession).toEqual({ sessionId: "cli-session" });
1695+expect(context.openClawHistoryPrompt).toBeDefined();
1696+expect(context.openClawHistoryPrompt).toContain(recentMarker);
1697+expect(context.openClawHistoryPrompt).toContain("EARLIEST_USER");
1698+expect(context.openClawHistoryPrompt).not.toContain("OpenClaw reseed history truncated");
1699+} finally {
1700+fs.rmSync(dir, { recursive: true, force: true });
1701+}
1702+});
14831703});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。