fix: history jsonl file corruption cases (#4364)

This commit is contained in:
Aiden Cline
2025-11-15 22:50:13 -08:00
committed by GitHub
parent 61fd21182c
commit 9b8a7da1e6

View File

@@ -4,7 +4,7 @@ import { onMount } from "solid-js"
import { createStore, produce } from "solid-js/store"
import { clone } from "remeda"
import { createSimpleContext } from "../../context/helper"
import { appendFile } from "fs/promises"
import { appendFile, writeFile } from "fs/promises"
import type { AgentPart, FilePart, TextPart } from "@opencode-ai/sdk"
export type PromptInfo = {
@@ -24,6 +24,8 @@ export type PromptInfo = {
)[]
}
const MAX_HISTORY_ENTRIES = 50
export const { use: usePromptHistory, provider: PromptHistoryProvider } = createSimpleContext({
name: "PromptHistory",
init: () => {
@@ -33,8 +35,23 @@ export const { use: usePromptHistory, provider: PromptHistoryProvider } = create
const lines = text
.split("\n")
.filter(Boolean)
.map((line) => JSON.parse(line))
setStore("history", lines as PromptInfo[])
.map((line) => {
try {
return JSON.parse(line)
} catch {
return null
}
})
.filter((line): line is PromptInfo => line !== null)
.slice(-MAX_HISTORY_ENTRIES)
setStore("history", lines)
// Rewrite file with only valid entries to self-heal corruption
if (lines.length > 0) {
const content = lines.map((line) => JSON.stringify(line)).join("\n") + "\n"
writeFile(historyFile.name!, content).catch(() => {})
}
})
const [store, setStore] = createStore({
@@ -64,14 +81,26 @@ export const { use: usePromptHistory, provider: PromptHistoryProvider } = create
return store.history.at(store.index)
},
append(item: PromptInfo) {
item = clone(item)
appendFile(historyFile.name!, JSON.stringify(item) + "\n")
const entry = clone(item)
let trimmed = false
setStore(
produce((draft) => {
draft.history.push(item)
draft.history.push(entry)
if (draft.history.length > MAX_HISTORY_ENTRIES) {
draft.history = draft.history.slice(-MAX_HISTORY_ENTRIES)
trimmed = true
}
draft.index = 0
}),
)
if (trimmed) {
const content = store.history.map((line) => JSON.stringify(line)).join("\n") + "\n"
writeFile(historyFile.name!, content).catch(() => {})
return
}
appendFile(historyFile.name!, JSON.stringify(entry) + "\n").catch(() => {})
},
}
},