diff --git a/apps/code/src/renderer/features/sessions/components/ConversationView.tsx b/apps/code/src/renderer/features/sessions/components/ConversationView.tsx
index 04c4cd24d..cebbb6f25 100644
--- a/apps/code/src/renderer/features/sessions/components/ConversationView.tsx
+++ b/apps/code/src/renderer/features/sessions/components/ConversationView.tsx
@@ -10,6 +10,8 @@ import {
import { useSettingsStore } from "@features/settings/stores/settingsStore";
import { SkillButtonActionMessage } from "@features/skill-buttons/components/SkillButtonActionMessage";
import { ArrowDown, XCircle } from "@phosphor-icons/react";
+import { WorkerPoolContextProvider } from "@pierre/diffs/react";
+import WorkerUrl from "@pierre/diffs/worker/worker.js?worker&url";
import { Box, Button, Flex, Text } from "@radix-ui/themes";
import type { AcpMessage } from "@shared/types/session-events";
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -30,6 +32,19 @@ import { UserMessage } from "./session-update/UserMessage";
import { UserShellExecuteView } from "./session-update/UserShellExecuteView";
import { VirtualizedList, type VirtualizedListHandle } from "./VirtualizedList";
+function diffsWorkerFactory(): Worker {
+ return new Worker(WorkerUrl, { type: "module" });
+}
+
+const DIFFS_POOL_OPTIONS = {
+ workerFactory: diffsWorkerFactory,
+ totalASTLRUCacheSize: 200,
+};
+
+const DIFFS_HIGHLIGHTER_OPTIONS = {
+ theme: { dark: "github-dark" as const, light: "github-light" as const },
+};
+
interface ConversationViewProps {
events: AcpMessage[];
isPromptPending: boolean | null;
@@ -216,51 +231,56 @@ export function ConversationView({
const getItemKey = useCallback((item: ConversationItem) => item.id, []);
return (
-
-
+
+
+
-
- 0}
- pausedDurationMs={pausedDurationMs}
- isCompacting={isCompacting}
- usage={contextUsage}
- />
-
- }
- />
- {showScrollButton && (
-
-
-
- )}
-
+
+ 0}
+ pausedDurationMs={pausedDurationMs}
+ isCompacting={isCompacting}
+ usage={contextUsage}
+ />
+
+ }
+ />
+ {showScrollButton && (
+
+
+
+ )}
+
+
);
}
diff --git a/apps/code/src/renderer/features/sessions/components/session-update/CodePreview.tsx b/apps/code/src/renderer/features/sessions/components/session-update/CodePreview.tsx
index 1c75e6a82..0efe74dca 100644
--- a/apps/code/src/renderer/features/sessions/components/session-update/CodePreview.tsx
+++ b/apps/code/src/renderer/features/sessions/components/session-update/CodePreview.tsx
@@ -1,6 +1,5 @@
import { EditorView } from "@codemirror/view";
-import { MultiFileDiff, WorkerPoolContextProvider } from "@pierre/diffs/react";
-import WorkerUrl from "@pierre/diffs/worker/worker.js?worker&url";
+import { MultiFileDiff } from "@pierre/diffs/react";
import { Code } from "@radix-ui/themes";
import { useThemeStore } from "@stores/themeStore";
import { compactHomePath } from "@utils/path";
@@ -12,10 +11,6 @@ import {
useCodePreviewExtensions,
} from "./useCodePreviewExtensions";
-function workerFactory(): Worker {
- return new Worker(WorkerUrl, { type: "module" });
-}
-
interface CodePreviewProps {
content: string;
filePath?: string;
@@ -23,6 +18,7 @@ interface CodePreviewProps {
oldContent?: string | null;
firstLineNumber?: number;
maxHeight?: string;
+ cacheKey?: string;
}
export function CodePreview({
@@ -32,6 +28,7 @@ export function CodePreview({
oldContent,
firstLineNumber = 1,
maxHeight,
+ cacheKey,
}: CodePreviewProps) {
const isDiff = oldContent !== undefined && oldContent !== null;
@@ -43,6 +40,7 @@ export function CodePreview({
showPath={showPath}
oldContent={oldContent}
maxHeight={maxHeight}
+ cacheKey={cacheKey}
/>
);
}
@@ -64,23 +62,33 @@ function DiffPreview({
showPath,
oldContent,
maxHeight,
+ cacheKey,
}: {
content: string;
filePath?: string;
showPath?: boolean;
oldContent: string;
maxHeight?: string;
+ cacheKey?: string;
}) {
const isDarkMode = useThemeStore((s) => s.isDarkMode);
const fileName = filePath?.split("/").pop() ?? "file";
const oldFile = useMemo(
- () => ({ name: fileName, contents: oldContent }),
- [fileName, oldContent],
+ () => ({
+ name: fileName,
+ contents: oldContent,
+ ...(cacheKey ? { cacheKey: `${cacheKey}:old` } : {}),
+ }),
+ [fileName, oldContent, cacheKey],
);
const newFile = useMemo(
- () => ({ name: fileName, contents: content }),
- [fileName, content],
+ () => ({
+ name: fileName,
+ contents: content,
+ ...(cacheKey ? { cacheKey: `${cacheKey}:new` } : {}),
+ }),
+ [fileName, content, cacheKey],
);
const options = useMemo(
() => ({
@@ -103,18 +111,7 @@ function DiffPreview({
)}
-
-
-
+
);
diff --git a/apps/code/src/renderer/features/sessions/components/session-update/EditToolView.tsx b/apps/code/src/renderer/features/sessions/components/session-update/EditToolView.tsx
index dce57e648..c99401fc5 100644
--- a/apps/code/src/renderer/features/sessions/components/session-update/EditToolView.tsx
+++ b/apps/code/src/renderer/features/sessions/components/session-update/EditToolView.tsx
@@ -118,6 +118,7 @@ export function EditToolView({
filePath={filePath}
oldContent={isNewFile ? null : oldText}
maxHeight="700px"
+ cacheKey={toolCall.toolCallId}
/>
)}