Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified examples/server/public/index.html.gz
Binary file not shown.
10 changes: 10 additions & 0 deletions examples/server/webui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/server/webui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"preview": "vite preview"
},
"dependencies": {
"@heroicons/react": "^2.2.0",
"@sec-ant/readable-stream": "^0.6.0",
"@vscode/markdown-it-katex": "^1.1.1",
"autoprefixer": "^10.4.20",
Expand Down
15 changes: 13 additions & 2 deletions examples/server/webui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { HashRouter, Outlet, Route, Routes } from 'react-router';
import Header from './components/Header';
import Sidebar from './components/Sidebar';
import { AppContextProvider } from './utils/app.context';
import { AppContextProvider, useAppContext } from './utils/app.context';
import ChatScreen from './components/ChatScreen';
import SettingDialog from './components/SettingDialog';

function App() {
return (
Expand All @@ -22,13 +23,23 @@ function App() {
}

function AppLayout() {
const { showSettings, setShowSettings } = useAppContext();
return (
<>
<Sidebar />
<div className="chat-screen drawer-content grow flex flex-col h-screen w-screen mx-auto px-4">
<div
className="drawer-content grow flex flex-col h-screen w-screen mx-auto px-4 overflow-auto"
id="main-scroll"
>
<Header />
<Outlet />
</div>
{
<SettingDialog
show={showSettings}
onClose={() => setShowSettings(false)}
/>
}
</>
);
}
Expand Down
3 changes: 3 additions & 0 deletions examples/server/webui/src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const BASE_URL = new URL('.', document.baseURI).href

export const CONFIG_DEFAULT = {
// Note: in order not to introduce breaking changes, please keep the same data type (number, string, etc) if you want to change the default value. Do not use null or undefined for default value.
// Do not use nested objects, keep it single level. Prefix the key if you need to group them.
apiKey: '',
systemMessage: 'You are a helpful assistant.',
showTokensPerSecond: false,
Expand All @@ -36,6 +37,8 @@ export const CONFIG_DEFAULT = {
dry_penalty_last_n: -1,
max_tokens: -1,
custom: '', // custom json-stringified object
// experimental features
pyIntepreterEnabled: false,
};
export const CONFIG_INFO: Record<string, string> = {
apiKey: 'Set the API Key if you are using --api-key option for the server.',
Expand Down
115 changes: 115 additions & 0 deletions examples/server/webui/src/components/CanvasPyInterpreter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { useEffect, useState } from 'react';
import { useAppContext } from '../utils/app.context';
import { XCloseButton } from '../utils/common';
import { delay } from '../utils/misc';
import StorageUtils from '../utils/storage';
import { CanvasType } from '../utils/types';
import { PlayIcon } from '@heroicons/react/24/outline';

const PyodideWrapper = {
load: async function () {
// load pyodide from CDN
// @ts-expect-error experimental pyodide
if (window.addedScriptPyodide) return;
// @ts-expect-error experimental pyodide
window.addedScriptPyodide = true;
const scriptElem = document.createElement('script');
scriptElem.src = 'https://cdn.jsdelivr.net/pyodide/v0.27.2/full/pyodide.js';
document.body.appendChild(scriptElem);
},

run: async function (code: string) {
PyodideWrapper.load();

// wait for pyodide to be loaded
// @ts-expect-error experimental pyodide
while (!window.loadPyodide) {
await delay(100);
}
const stdOutAndErr: string[] = [];
// @ts-expect-error experimental pyodide
const pyodide = await window.loadPyodide({
stdout: (data: string) => stdOutAndErr.push(data),
stderr: (data: string) => stdOutAndErr.push(data),
});
try {
const result = await pyodide.runPythonAsync(code);
if (result) {
stdOutAndErr.push(result.toString());
}
} catch (e) {
console.error(e);
stdOutAndErr.push((e as Error).toString());
}
return stdOutAndErr.join('\n');
},
};

if (StorageUtils.getConfig().pyIntepreterEnabled) {
PyodideWrapper.load();
}

export default function CanvasPyInterpreter() {
const { canvasData, setCanvasData } = useAppContext();

const [code, setCode] = useState(canvasData?.content ?? ''); // copy to avoid direct mutation
const [running, setRunning] = useState(false);
const [output, setOutput] = useState('');

const runCode = async (pycode: string) => {
setRunning(true);
setOutput('Running...');
const out = await PyodideWrapper.run(pycode);
setOutput(out);
setRunning(false);
};

// run code on mount
useEffect(() => {
setCode(canvasData?.content ?? '');
runCode(canvasData?.content ?? '');
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [canvasData?.content]);

if (canvasData?.type !== CanvasType.PY_INTERPRETER) {
return null;
}

return (
<div className="card bg-base-200 w-full h-full shadow-xl">
<div className="card-body">
<div className="flex justify-between items-center mb-4">
<span className="text-lg font-bold">Python Interpreter</span>
<XCloseButton
className="bg-base-100"
onClick={() => setCanvasData(null)}
/>
</div>
<div className="grid grid-rows-3 gap-4 h-full">
<textarea
className="textarea textarea-bordered w-full h-full font-mono"
value={code}
onChange={(e) => setCode(e.target.value)}
></textarea>
<div className="font-mono flex flex-col row-span-2">
<div className="flex items-center mb-2">
<button
className="btn btn-sm bg-base-100"
onClick={() => runCode(code)}
disabled={running}
>
<PlayIcon className="h-6 w-6" />{' '}
{running ? 'Running...' : 'Run'}
</button>
</div>
<textarea
className="textarea textarea-bordered h-full dark-color"
value={output}
readOnly
></textarea>
</div>
</div>
</div>
</div>
);
}
10 changes: 8 additions & 2 deletions examples/server/webui/src/components/ChatMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,17 @@ export default function ChatMessage({
)}
</summary>
<div className="collapse-content">
<MarkdownDisplay content={thought} />
<MarkdownDisplay
content={thought}
isGenerating={isPending}
/>
</div>
</details>
)}
<MarkdownDisplay content={content} />
<MarkdownDisplay
content={content}
isGenerating={isPending}
/>
</div>
</>
)}
Expand Down
Loading