mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-22 01:02:41 +00:00
fix(server): skip Claude request-journal records when loading history
Claude Code 2.1.304+ journals each API request into the transcript as api-request-blob records. They carry a message with a role and content, so the history loader rendered them as assistant messages: restored timelines gained the session's system context, including SessionStart hook output and skill and tool listings. Only user and assistant records are conversation turns once the system record handling has run, so short-circuit every other type. Closes #7102 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e522e6ea8e
commit
2425282e6d
@@ -141,6 +141,39 @@ describe("convertClaudeHistoryEntry", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test("ignores Claude Code request-journal records that carry a message", () => {
|
||||
// Claude Code 2.1.x journals each API request into the transcript. These records carry a
|
||||
// message with a role and content, but they are copies of the request, not conversation turns.
|
||||
const entries = [
|
||||
{
|
||||
type: "api-request-blob",
|
||||
message: {
|
||||
role: "system",
|
||||
content: [
|
||||
{ type: "text", text: "SessionStart:startup hook success: hook output" },
|
||||
{ type: "tool_addition", name: "Read" },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "api-request-blob",
|
||||
message: {
|
||||
role: "user",
|
||||
content: [{ type: "text", text: "<system-reminder>skills list</system-reminder>" }],
|
||||
},
|
||||
},
|
||||
];
|
||||
const leakedTimeline: AgentTimelineItem[] = [
|
||||
{ type: "assistant_message", text: "SessionStart:startup hook success: hook output" },
|
||||
];
|
||||
const mapBlocks = vi.fn().mockReturnValue(leakedTimeline);
|
||||
|
||||
for (const entry of entries) {
|
||||
expect(convertClaudeHistoryEntry(entry, mapBlocks)).toEqual([]);
|
||||
}
|
||||
expect(mapBlocks).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("converts compact boundary metadata variants", () => {
|
||||
const fixtures = [
|
||||
{
|
||||
|
||||
@@ -6403,6 +6403,11 @@ function convertClaudeHistoryEntryPreamble(
|
||||
if (entry.type === "user" && isSyntheticHistoryUserEntry(entry)) {
|
||||
return { shortCircuit: [] };
|
||||
}
|
||||
// Only user and assistant records are conversation turns. Claude Code 2.1.x also journals each
|
||||
// API request as `api-request-blob` records whose message replays the system context.
|
||||
if (entry.type !== "user" && entry.type !== "assistant") {
|
||||
return { shortCircuit: [] };
|
||||
}
|
||||
|
||||
const message = entry?.message;
|
||||
if (!message || !("content" in message)) {
|
||||
|
||||
Reference in New Issue
Block a user