Skip to content

server : (webui) revamp the input area, plus many small UI improvements #13365

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion common/chat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ std::vector<common_chat_msg> common_chat_msgs_parse_oaicompat(const json & messa
msgs.push_back(msg);
}
} catch (const std::exception & e) {
throw std::runtime_error("Failed to parse messages: " + std::string(e.what()) + "; messages = " + messages.dump(2));
// @ngxson : disable otherwise it's bloating the API response
// printf("%s\n", std::string("; messages = ") + messages.dump(2));
throw std::runtime_error("Failed to parse messages: " + std::string(e.what()));
Copy link
Collaborator Author

@ngxson ngxson May 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small note @ochafik , we should never reflect user input via the error message, as it usually comes with security risks. In this case, it's not a security risk, but it's a bit inconvenient to display the error in the UI

If you want to print the input for debugging, consider using LOG_DBG

}

return msgs;
Expand Down
Binary file modified tools/server/public/index.html.gz
Binary file not shown.
93 changes: 92 additions & 1 deletion tools/server/webui/package-lock.json

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

2 changes: 2 additions & 0 deletions tools/server/webui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"postcss": "^8.4.49",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-dropzone": "^14.3.8",
"react-hot-toast": "^2.5.2",
"react-markdown": "^9.0.3",
"react-router": "^7.1.5",
"rehype-highlight": "^7.0.2",
Expand Down
2 changes: 2 additions & 0 deletions tools/server/webui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Sidebar from './components/Sidebar';
import { AppContextProvider, useAppContext } from './utils/app.context';
import ChatScreen from './components/ChatScreen';
import SettingDialog from './components/SettingDialog';
import { Toaster } from 'react-hot-toast';

function App() {
return (
Expand Down Expand Up @@ -40,6 +41,7 @@ function AppLayout() {
onClose={() => setShowSettings(false)}
/>
}
<Toaster />
</>
);
}
Expand Down
2 changes: 1 addition & 1 deletion tools/server/webui/src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ 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.',
systemMessage: '',
showTokensPerSecond: false,
showThoughtInProgress: false,
excludeThoughtOnReq: true,
Expand Down
92 changes: 92 additions & 0 deletions tools/server/webui/src/components/ChatInputExtraContextItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { DocumentTextIcon, XMarkIcon } from '@heroicons/react/24/outline';
import { MessageExtra } from '../utils/types';
import { useState } from 'react';
import { classNames } from '../utils/misc';

export default function ChatInputExtraContextItem({
items,
removeItem,
clickToShow,
}: {
items?: MessageExtra[];
removeItem?: (index: number) => void;
clickToShow?: boolean;
}) {
const [show, setShow] = useState(-1);
const showingItem = show >= 0 ? items?.[show] : undefined;

if (!items) return null;

return (
<div className="flex flex-row gap-4 overflow-x-auto py-2 px-1 mb-1">
{items.map((item, i) => (
<div
className="indicator"
key={i}
onClick={() => clickToShow && setShow(i)}
>
{removeItem && (
<div className="indicator-item indicator-top">
<button
className="btn btn-neutral btn-sm w-4 h-4 p-0 rounded-full"
onClick={() => removeItem(i)}
>
<XMarkIcon className="h-3 w-3" />
</button>
</div>
)}

<div
className={classNames({
'flex flex-row rounded-md shadow-sm items-center m-0 p-0': true,
'cursor-pointer hover:shadow-md': !!clickToShow,
})}
>
{item.type === 'imageFile' ? (
<>
<img
src={item.base64Url}
alt={item.name}
className="w-14 h-14 object-cover rounded-md"
/>
</>
) : (
<>
<div className="w-14 h-14 flex items-center justify-center">
<DocumentTextIcon className="h-8 w-14 text-base-content/50" />
</div>

<div className="text-xs pr-4">
<b>{item.name ?? 'Extra content'}</b>
</div>
</>
)}
</div>
</div>
))}

{showingItem && (
<dialog className="modal modal-open">
<div className="modal-box">
<div className="flex justify-between items-center mb-4">
<b>{showingItem.name ?? 'Extra content'}</b>
<button className="btn btn-ghost btn-sm">
<XMarkIcon className="h-5 w-5" onClick={() => setShow(-1)} />
</button>
</div>
{showingItem.type === 'imageFile' ? (
<img src={showingItem.base64Url} alt={showingItem.name} />
) : (
<div className="overflow-x-auto">
<pre className="whitespace-pre-wrap break-words text-sm">
{showingItem.content}
</pre>
</div>
)}
</div>
<div className="modal-backdrop" onClick={() => setShow(-1)}></div>
</dialog>
)}
</div>
);
}
Loading
Loading