Skip to content

Commit 621b06e

Browse files
committed
feat: show and auto-refresh Files panel for pyodide code executions
1 parent b8a952e commit 621b06e

5 files changed

Lines changed: 28 additions & 7 deletions

File tree

src/lib/components/chat/ChatControls.svelte

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
settings,
2121
showFileNavPath,
2222
selectedTerminalId,
23-
user
23+
user,
24+
pyodideWorker
2425
} from '$lib/stores';
2526
2627
import { uploadFile } from '$lib/apis/files';
@@ -73,7 +74,8 @@
7374
$: showControlsTab = $user?.role === 'admin' || ($user?.permissions?.chat?.controls ?? true);
7475
$: showFilesTab =
7576
!!$selectedTerminalId ||
76-
(codeInterpreterEnabled && $config?.code?.interpreter_engine !== 'jupyter');
77+
(codeInterpreterEnabled && $config?.code?.interpreter_engine !== 'jupyter') ||
78+
!!$pyodideWorker;
7779
$: showOverviewTab = hasMessages;
7880
7981
// Tab fallback: if active tab becomes hidden, switch to next available
@@ -361,7 +363,7 @@
361363
/>
362364
{:else if activeTab === 'files' && $selectedTerminalId}
363365
<FileNav onAttach={handleTerminalAttach} />
364-
{:else if activeTab === 'files' && codeInterpreterEnabled}
366+
{:else if activeTab === 'files' && (codeInterpreterEnabled || !!$pyodideWorker)}
365367
<PyodideFileNav />
366368
{:else}
367369
<Controls embed={true} {models} bind:chatFiles bind:params />
@@ -512,7 +514,7 @@
512514
/>
513515
{:else if activeTab === 'files' && $selectedTerminalId}
514516
<FileNav onAttach={handleTerminalAttach} overlay={dragged} />
515-
{:else if activeTab === 'files' && codeInterpreterEnabled}
517+
{:else if activeTab === 'files' && (codeInterpreterEnabled || !!$pyodideWorker)}
516518
<PyodideFileNav overlay={dragged} />
517519
{:else}
518520
<Controls embed={true} {models} bind:chatFiles bind:params />

src/lib/components/chat/PyodideFileNav.svelte

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<script lang="ts">
66
import { getContext, onMount, tick } from 'svelte';
7-
import { pyodideWorker } from '$lib/stores';
7+
import { pyodideWorker, pyodideExecutionCount } from '$lib/stores';
88
import PyodideWorkerConstructor from '$lib/workers/pyodide.worker?worker';
99
import type { FileEntry } from '$lib/apis/terminal';
1010
@@ -45,6 +45,12 @@
4545
let newFileInput: HTMLInputElement;
4646
4747
let _reqId = 0;
48+
let _mounted = false;
49+
50+
// Auto-refresh the file listing after each code execution
51+
$: if (_mounted && $pyodideExecutionCount > 0 && !selectedFile) {
52+
loadDir(currentPath);
53+
}
4854
4955
const IMAGE_EXTS = new Set(['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'ico', 'avif']);
5056
const isImage = (path: string) => IMAGE_EXTS.has(path.split('.').pop()?.toLowerCase() ?? '');
@@ -285,6 +291,7 @@
285291
onMount(() => {
286292
ensureWorker();
287293
loadDir(currentPath);
294+
_mounted = true;
288295
});
289296
</script>
290297

src/lib/stores/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export const terminalServers = writable([]);
7474

7575
// Persistent Pyodide worker for code interpreter FS
7676
export const pyodideWorker: Writable<Worker | null> = writable(null);
77+
export const pyodideExecutionCount: Writable<number> = writable(0);
7778

7879
export const banners: Writable<Banner[]> = writable([]);
7980

src/lib/workers/pyodide.worker.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ async function executeCode(
189189
persistFS();
190190
}
191191

192+
// Ensure working directory is /mnt/uploads so relative file writes appear in the panel
193+
try {
194+
await self.pyodide.runPythonAsync("import os; os.chdir('/mnt/uploads')");
195+
} catch (e) {
196+
console.warn('[pyodide] chdir to /mnt/uploads failed:', e);
197+
}
198+
192199
try {
193200
// check if matplotlib is imported in the code
194201
if (code.includes('matplotlib')) {

src/routes/+layout.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
showControls,
3636
showFileNavPath,
3737
showFileNavDir,
38-
pyodideWorker
38+
pyodideWorker,
39+
pyodideExecutionCount
3940
} from '$lib/stores';
4041
import { getFileContentById } from '$lib/apis/files';
4142
import { goto } from '$app/navigation';
@@ -476,7 +477,10 @@
476477
} else if (data?.session_id === $socket.id) {
477478
if (type === 'execute:python') {
478479
console.log('execute:python', data);
479-
executePythonAsWorker(data.id, data.code, cb, data.files || []);
480+
executePythonAsWorker(data.id, data.code, (result) => {
481+
cb(result);
482+
pyodideExecutionCount.update((n) => n + 1);
483+
}, data.files || []);
480484
} else if (type === 'execute:tool') {
481485
console.log('execute:tool', data);
482486
executeTool(data, cb);

0 commit comments

Comments
 (0)