Skip to content

Commit e20392e

Browse files
committed
Dont reload monaco edit thread slect, update ci to clean up containers after deploy
1 parent 86cb764 commit e20392e

6 files changed

Lines changed: 134 additions & 29 deletions

File tree

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Plan: Minimize Monaco Reloads on Thread Switch
2+
3+
## Context
4+
5+
Every time a user selects a different thread from the sidebar, all Monaco editor instances in the conversation unmount and remount. A typical thread has 5-20+ tool calls, each rendering a full Monaco editor instance via `DefaultTool` for read-only JSON/markdown display. This causes:
6+
7+
- Monaco CDN scripts to be re-validated (NetworkFirst caching strategy)
8+
- Hundreds of DOM nodes per editor instance to be destroyed and recreated
9+
- Visible UI jank during thread transitions
10+
11+
The root cause: `DefaultTool` uses the full Monaco Editor (`@monaco-editor/react`) just to display read-only snippets -- the heaviest code editor available used as a glorified `<pre>` tag.
12+
13+
## Approach: Replace Monaco with Lightweight Syntax Highlighter in Chat Messages
14+
15+
`react-syntax-highlighter` with Prism is **already installed and bundled** (used by `MarkdownCard.tsx`). Reusing it adds zero additional bundle cost.
16+
17+
### Step 1: Modify `DefaultTool` to use `react-syntax-highlighter`
18+
19+
**File:** `frontend/src/components/tools/Default.tsx`
20+
21+
Replace the Monaco `Editor` import with `SyntaxHighlighter` from `react-syntax-highlighter`, following the exact pattern from `MarkdownCard.tsx` (lines 4-8, 42-48):
22+
23+
```tsx
24+
// Replace:
25+
import Editor from "@monaco-editor/react";
26+
27+
// With:
28+
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
29+
import { oneDark, oneLight } from "react-syntax-highlighter/dist/esm/styles/prism";
30+
```
31+
32+
Keep all existing content/language/height derivation logic (lines 17-62) unchanged. Only replace the render output:
33+
34+
```tsx
35+
// Replace the <Editor .../> JSX with:
36+
<SyntaxHighlighter
37+
style={theme === "light" ? oneLight : oneDark}
38+
language={language}
39+
wrapLongLines={true}
40+
customStyle={{
41+
margin: 0,
42+
fontSize: "11px",
43+
maxHeight: height,
44+
overflow: "auto",
45+
borderRadius: "0.375rem",
46+
}}
47+
>
48+
{content}
49+
</SyntaxHighlighter>
50+
```
51+
52+
### Step 2: Verify no breaking changes
53+
54+
- `DefaultTool` props interface (`selectedToolMessage`, `collapsed`) stays the same
55+
- Consumers (`ChatMessages.tsx` line 171, `ToolTimelineItem.tsx` line 88) need zero changes
56+
- Visual output: Prism's `oneDark`/`oneLight` closely match Monaco's `vs-dark`/`light` themes
57+
58+
### Step 3: Verify build
59+
60+
Run `npm run build` to confirm:
61+
- Monaco chunk is no longer pulled into the chat message rendering path
62+
- Bundle size for chat path decreases significantly
63+
- No build errors
64+
65+
### Optional Future Enhancements (not in this PR)
66+
67+
1. **Lazy-load Monaco for FileEditorPanel** - Use `React.lazy()` for `MonacoEditor` component
68+
2. **Configure Monaco loader for local bundles** - Eliminate CDN dependency for remaining Monaco usages
69+
3. **Change PWA caching** to `CacheFirst` for Monaco scripts (versions are pinned)
70+
71+
## Files to Modify
72+
73+
| File | Change |
74+
|------|--------|
75+
| `frontend/src/components/tools/Default.tsx` | Replace Monaco with SyntaxHighlighter |
76+
77+
## Files for Reference (no changes needed)
78+
79+
| File | Why |
80+
|------|-----|
81+
| `frontend/src/components/cards/MarkdownCard.tsx` | Pattern to follow for SyntaxHighlighter usage |
82+
| `frontend/src/components/lists/ChatMessages.tsx` | Consumer - verify no breaking changes |
83+
| `frontend/src/components/timeline/ToolTimelineItem.tsx` | Consumer - verify no breaking changes |
84+
| `frontend/src/components/inputs/MonacoEditor.tsx` | Unchanged - still used for interactive editing |
85+
| `frontend/src/components/panels/FileEditorPanel.tsx` | Unchanged - legitimate Monaco use case |
86+
87+
## Verification
88+
89+
1. `npm run build` -- no errors, Monaco chunk not loaded on chat path
90+
2. `npm run test` -- existing tests pass
91+
3. Manual: switch between 3+ threads rapidly -- no Monaco network requests in DevTools
92+
4. Manual: expand tool outputs in chat -- JSON is syntax-highlighted correctly
93+
5. Manual: verify FileEditorPanel still works with full Monaco (split view mode)
94+
6. Manual: verify light/dark theme switching works for tool output highlighting
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Plan: Remove 24h filter from docker system prune in CI deploy
2+
3+
## Context
4+
After CI deploys, `docker system prune -a --filter "until=24h" -f` runs to clean up images. The 24h window is too generous — replaced images linger and fill disk. Shortening to 1h still protects the just-deployed images while reclaiming space much sooner.
5+
6+
## Changes
7+
8+
### 1. `.github/workflows/build.yml` (line 254)
9+
**Before:** `docker system prune -a --filter \"until=24h\" -f`
10+
**After:** `docker system prune -a --filter \"until=1h\" -f`
11+
12+
### 2. `.github/workflows/deploy-docker.yml` (line 134)
13+
**Before:** `docker system prune -a --filter "until=24h" -f`
14+
**After:** `docker system prune -a --filter "until=1h" -f`
15+
16+
## Verification
17+
- Review the diff to confirm only the filter flag was removed
18+
- Next CI deploy should show `docker system prune -a -f` in logs and reclaim more disk space

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ jobs:
251251
echo '--- Worker deployment complete ---'
252252
253253
echo '--- Cleaning up old images ---'
254-
docker system prune -a --filter \"until=24h\" -f
254+
docker system prune -a --filter \"until=1h\" -f
255255
256256
echo '--- Deployment successful! ---'
257257
"

.github/workflows/deploy-docker.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ jobs:
131131
echo '--- Worker deployment complete ---'
132132
133133
echo '--- Cleaning up old images ---'
134-
docker system prune -a --filter "until=24h" -f
134+
docker system prune -a --filter "until=1h" -f
135135
136136
echo '--- Deployment successful! ---'
137137
"

frontend/src/components/tools/Default.tsx

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { useMemo } from "react";
2-
import Editor from "@monaco-editor/react";
2+
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
3+
import {
4+
oneDark,
5+
oneLight,
6+
} from "react-syntax-highlighter/dist/esm/styles/prism";
37
import { useTheme } from "@/hooks/useTheme";
48

59
interface Props {
@@ -52,7 +56,7 @@ export default function DefaultTool({
5256
}
5357
}, [content]);
5458

55-
const height = useMemo(() => {
59+
const maxHeight = useMemo(() => {
5660
const lineCount = content.split("\n").length;
5761
const raw = lineCount * 18 + 10;
5862
if (collapsed) {
@@ -64,30 +68,19 @@ export default function DefaultTool({
6468
if (!selectedToolMessage || !content) return null;
6569

6670
return (
67-
<div style={{ height }}>
68-
<Editor
69-
value={content}
70-
language={language}
71-
height={height}
72-
theme={theme === "light" ? "light" : "vs-dark"}
73-
options={{
74-
readOnly: true,
75-
domReadOnly: true,
76-
minimap: { enabled: false },
77-
lineNumbers: "off",
78-
wordWrap: "on",
79-
fontSize: 11,
80-
scrollBeyondLastLine: false,
81-
renderLineHighlight: "none",
82-
contextmenu: false,
83-
folding: !collapsed,
84-
scrollbar: {
85-
vertical: "hidden",
86-
horizontal: "hidden",
87-
handleMouseWheel: true,
88-
},
89-
}}
90-
/>
91-
</div>
71+
<SyntaxHighlighter
72+
style={theme === "light" ? oneLight : oneDark}
73+
language={language}
74+
wrapLongLines={true}
75+
customStyle={{
76+
margin: 0,
77+
fontSize: "11px",
78+
maxHeight,
79+
overflow: "auto",
80+
borderRadius: "0.375rem",
81+
}}
82+
>
83+
{content}
84+
</SyntaxHighlighter>
9285
);
9386
}

specs/monaco-load.png

392 KB
Loading

0 commit comments

Comments
 (0)