Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

feat(server): Add tool call support to WebUI (LLama Server) #13501

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

Open
wants to merge 26 commits into
base: master
Choose a base branch
Loading
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
acd4767
feat(server): add basic js tool call support
samolego May 7, 2025
6236918
code abstraction for tool calling
samolego May 8, 2025
e84e819
minor changes, renames
samolego May 8, 2025
f6b1386
add tool call fields
samolego May 12, 2025
f2175cb
fix: Use structured `tool_calls` for tool handling
samolego May 13, 2025
4698b66
fix: forward tool call info back to api
samolego May 13, 2025
69e7119
provide tool call response in a dropdown
samolego May 13, 2025
75fd25e
Fix UI updates after tool call chains
samolego May 13, 2025
ae32a9a
move js evaluation to sandboxed iframe, remove debug logs
samolego May 13, 2025
00d911d
merge assistant messages on tool use
samolego May 18, 2025
d99808f
feat: populate settings tool calling section
samolego May 18, 2025
0b34d53
feat: add stream response setting
samolego May 18, 2025
0480054
fix: revert base url
samolego May 18, 2025
7fa0043
Merge remote-tracking branch 'upstream/master' into feat/tool-calling
samolego May 18, 2025
b128ca5
fix: readd missing comments
samolego May 19, 2025
c203815
fix: more cleanup
samolego May 19, 2025
cf110f9
minor changes
samolego May 19, 2025
4e7da1b
Delete deno.lock
samolego May 19, 2025
031e673
Update tools/server/webui/package.json
samolego May 20, 2025
c9ec6fa
fix: remove unused type, do not add tool calls in user messages
samolego May 20, 2025
3f76cac
feat: support streaming tool calls
samolego May 26, 2025
c98baef
bugfixes for streaming calls
samolego May 27, 2025
22a951b
fix demo conversation import
samolego May 27, 2025
798946e
fix: make chained message regeneratable
samolego May 29, 2025
92f8bb0
updates to config and available tools map
samolego May 29, 2025
5c898ec
better handling of logged variables in js repl
samolego May 29, 2025
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
Prev Previous commit
Next Next commit
fix demo conversation import
  • Loading branch information
samolego committed May 27, 2025
commit 22a951bfc9fb135bf94f4478979c1563d1dd52c5
30 changes: 30 additions & 0 deletions 30 tools/server/webui/public/demo-conversation.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,36 @@
"id": 1734087548329,
"role": "assistant",
"content": "Code block:\n```js\nconsole.log('hello world')\n```\n```sh\nls -la /dev\n```"
},
{
"id": 1734087548330,
"role": "user",
"content": "What is the weather in San Francisco?"
},
{
"id": 1734087548331,
"role": "assistant",
"content": "<think>User wants to know what's te weather like in San Francisco.</think>Let me check that for you!",
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_current_weather",
"arguments": "{\n\"location\": \"San Francisco\"\n}"
}
}
]
},
{
"id": 1734087548332,
"role": "tool",
"content": "{\"temperature\": 20, \"condition\": \"sunny\"}"
},
{
"id": 1734087548333,
"role": "assistant",
"content": "The weather in San Francisco is currently 20°C and sunny."
}
]
}
23 changes: 15 additions & 8 deletions 23 tools/server/webui/src/components/ChatMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ function MessagePart({
isMainMessage?: boolean;
}) {
const { config } = useAppContext();
const { content, thought, isThinking } = extractThoughts(message.content, message.role);
const { content, thought, isThinking } = extractThoughts(
message.content,
message.role
);

if (message.role === 'tool' && baseClassName) {
return (
Expand All @@ -89,10 +92,7 @@ function MessagePart({
) : (
content &&
content.trim() !== '' && (
<MarkdownDisplay
content={content}
isGenerating={isPending}
/>
<MarkdownDisplay content={content} isGenerating={isPending} />
)
)}

Expand Down Expand Up @@ -147,7 +147,10 @@ export default function ChatMessage({
const nextSibling = siblingLeafNodeIds[siblingCurrIdx + 1];
const prevSibling = siblingLeafNodeIds[siblingCurrIdx - 1];

const mainSplitMessage = useMemo(() => extractThoughts(msg.content, msg.role), [msg.content, msg.role]);
const mainSplitMessage = useMemo(
() => extractThoughts(msg.content, msg.role),
[msg.content, msg.role]
);

if (!viewingChat) return null;

Expand Down Expand Up @@ -246,7 +249,11 @@ export default function ChatMessage({
isPending={isPending}
showThoughts={true}
className={part.role === 'assistant' ? 'mt-2' : ''}
baseClassName={part.role === 'tool' ? 'collapse bg-base-200 collapse-arrow mb-4 mt-2' : ''}
baseClassName={
part.role === 'tool'
? 'collapse bg-base-200 collapse-arrow mb-4 mt-2'
: ''
}
/>
))}
</>
Expand Down Expand Up @@ -419,4 +426,4 @@ function ThoughtProcess({
</div>
</div>
);
}
}
5 changes: 1 addition & 4 deletions 5 tools/server/webui/src/components/SettingDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,7 @@ const SETTING_SECTIONS: SettingSection[] = [
const debugImportDemoConv = async () => {
const res = await fetch('/demo-conversation.json');
const demoConv = await res.json();
StorageUtils.remove(demoConv.id);
for (const msg of demoConv.messages) {
StorageUtils.appendMsg(demoConv.id, msg);
}
await StorageUtils.importDemoConversation(demoConv);
};
return (
<button className="btn" onClick={debugImportDemoConv}>
Expand Down
4 changes: 0 additions & 4 deletions 4 tools/server/webui/src/utils/app.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,6 @@ export const AppContextProvider = ({
lastMsgId = await generateMessage(convId, lastMsgId, onChunk);
}

// Fetch messages from DB
const savedMsgs = await StorageUtils.getMessages(convId);
console.log({ savedMsgs });

return lastMsgId;
} catch (err) {
setPending(convId, null);
Expand Down
43 changes: 43 additions & 0 deletions 43 tools/server/webui/src/utils/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,49 @@ const StorageUtils = {
localStorage.setItem('theme', theme);
}
},

/**
* Import a demo conversation from JSON data
*/
async importDemoConversation(demoConv: {
demo?: boolean;
id: string;
lastModified: number;
messages: Message[];
}): Promise<void> {
if (demoConv.messages.length === 0) return;

// Create a new conversation with a fresh ID
const conv = await this.createConversation('Demo Conversation');

// Get the root message to use as parent
const rootMessages = await this.getMessages(conv.id);
const rootMessage = rootMessages.find((msg) => msg.type === 'root');
if (!rootMessage) {
throw new Error('Failed to find root message in created conversation');
}

// Transform demo messages to the format expected by appendMsgChain
const now = Date.now();
const transformedMessages = demoConv.messages
.filter(
(msg) =>
msg && msg.role && msg.content !== undefined && msg.id !== undefined
)
.map((msg, index) => ({
id: now + index,
convId: conv.id,
type: 'text' as const,
tool_calls: msg.tool_calls || [],
timestamp: now + index,
role: msg.role,
content: msg.content,
timings: msg.timings,
})) as Exclude<Message, 'parent' | 'children'>[];

// Use appendMsgChain to add all messages at once
await this.appendMsgChain(transformedMessages, rootMessage.id);
},
};

export default StorageUtils;
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.