|
|
@@ -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(() => {})
|
|
|
},
|
|
|
}
|
|
|
},
|