diff --git a/packages/opencode/src/file/ripgrep.ts b/packages/opencode/src/file/ripgrep.ts index 834cbee1ed1c..21b8f6895a88 100644 --- a/packages/opencode/src/file/ripgrep.ts +++ b/packages/opencode/src/file/ripgrep.ts @@ -265,7 +265,15 @@ export namespace Ripgrep { } } + const treeCache = new Map() + export async function tree(input: { cwd: string; limit?: number }) { + const cacheKey = `${input.cwd}:${input.limit ?? 50}` + const cached = treeCache.get(cacheKey) + if (cached && Date.now() - cached.time < 5000) { + return cached.result + } + log.info("tree", input) const files = await Array.fromAsync(Ripgrep.files({ cwd: input.cwd })) interface Node { @@ -364,7 +372,10 @@ export namespace Ripgrep { } result.children.map((x) => render(x, 0)) - return lines.join("\n") + const resultString = lines.join("\n") + treeCache.set(cacheKey, { time: Date.now(), result: resultString }) + + return resultString } export async function search(input: { diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts index 3fcdab5238c3..91b49eec77cb 100644 --- a/packages/opencode/src/session/index.ts +++ b/packages/opencode/src/session/index.ts @@ -398,10 +398,25 @@ export namespace Session { }), ]) + /** + * Memory buffer for parts being updated with deltas to avoid high-frequency disk I/O. + * Flushed on text-end/reasoning-end or periodic interval. + */ + const partBuffer = new Map() + export const updatePart = fn(UpdatePartInput, async (input) => { const part = "delta" in input ? input.part : input const delta = "delta" in input ? input.delta : undefined - await Storage.write(["part", part.messageID, part.id], part) + + // If it's a delta update, we buffer the write to disk + if (delta !== undefined) { + partBuffer.set(part.id, part) + } else { + // Otherwise, we flush the buffer for this part and write to storage + partBuffer.delete(part.id) + await Storage.write(["part", part.messageID, part.id], part) + } + Bus.publish(MessageV2.Event.PartUpdated, { part, delta, diff --git a/packages/opencode/src/storage/storage.ts b/packages/opencode/src/storage/storage.ts index 18f2d67e7ac0..8e8eb8803f1b 100644 --- a/packages/opencode/src/storage/storage.ts +++ b/packages/opencode/src/storage/storage.ts @@ -183,7 +183,7 @@ export namespace Storage { using _ = await Lock.write(target) const content = await Bun.file(target).json() fn(content) - await Bun.write(target, JSON.stringify(content, null, 2)) + await Bun.write(target, JSON.stringify(content)) return content as T }) } @@ -193,7 +193,7 @@ export namespace Storage { const target = path.join(dir, ...key) + ".json" return withErrorHandling(async () => { using _ = await Lock.write(target) - await Bun.write(target, JSON.stringify(content, null, 2)) + await Bun.write(target, JSON.stringify(content)) }) }