Skip to content

Commit 682cfc7

Browse files
committed
webui: Client-side implementation of tool calling with calculator tool and (javascript) code interpreter tool
1 parent 96a181a commit 682cfc7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+3237
-392
lines changed

tools/server/public/index.html.gz

43.4 KB
Binary file not shown.

tools/server/webui/package-lock.json

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/server/webui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"@tailwindcss/forms": "^0.5.9",
4242
"@tailwindcss/typography": "^0.5.15",
4343
"@tailwindcss/vite": "^4.0.0",
44+
"@testing-library/svelte": "^5.2.9",
4445
"@types/node": "^22",
4546
"@vitest/browser": "^3.2.3",
4647
"bits-ui": "^2.14.4",

tools/server/webui/playwright.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { defineConfig } from '@playwright/test';
22

33
export default defineConfig({
44
webServer: {
5-
command: 'npm run build && http-server ../public -p 8181',
5+
command:
6+
'npm run build && gzip -dc ../public/index.html.gz > ../public/index.html && http-server ../public -p 8181',
67
port: 8181,
78
timeout: 120000,
89
reuseExistingServer: false

tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessage.svelte

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import ChatMessageAssistant from './ChatMessageAssistant.svelte';
55
import ChatMessageUser from './ChatMessageUser.svelte';
66
import ChatMessageSystem from './ChatMessageSystem.svelte';
7+
import { conversationsStore } from '$lib/stores/conversations.svelte';
78
89
interface Props {
910
class?: string;
@@ -21,6 +22,7 @@
2122
onNavigateToSibling?: (siblingId: string) => void;
2223
onRegenerateWithBranching?: (message: DatabaseMessage, modelOverride?: string) => void;
2324
siblingInfo?: ChatMessageSiblingInfo | null;
25+
toolParentIds?: string[];
2426
}
2527
2628
let {
@@ -34,9 +36,21 @@
3436
onEditUserMessagePreserveResponses,
3537
onNavigateToSibling,
3638
onRegenerateWithBranching,
37-
siblingInfo = null
39+
siblingInfo = null,
40+
toolParentIds
3841
}: Props = $props();
3942
43+
type MessageWithToolExtras = DatabaseMessage & {
44+
_actionTargetId?: string;
45+
_toolMessagesCollected?: { toolCallId?: string | null; parsed: unknown }[];
46+
};
47+
48+
const actionTargetId = $derived((message as MessageWithToolExtras)._actionTargetId ?? message.id);
49+
50+
function getActionTarget(): DatabaseMessage {
51+
return conversationsStore.activeMessages.find((m) => m.id === actionTargetId) ?? message;
52+
}
53+
4054
let deletionInfo = $state<{
4155
totalCount: number;
4256
userMessages: number;
@@ -97,7 +111,8 @@
97111
}
98112
99113
async function handleDelete() {
100-
deletionInfo = await chatStore.getDeletionInfo(message.id);
114+
const target = getActionTarget();
115+
deletionInfo = await chatStore.getDeletionInfo(target.id);
101116
showDeleteDialog = true;
102117
}
103118
@@ -133,11 +148,13 @@
133148
}
134149
135150
function handleRegenerate(modelOverride?: string) {
136-
onRegenerateWithBranching?.(message, modelOverride);
151+
const target = getActionTarget();
152+
onRegenerateWithBranching?.(target, modelOverride);
137153
}
138154
139155
function handleContinue() {
140-
onContinueAssistantMessage?.(message);
156+
const target = getActionTarget();
157+
onContinueAssistantMessage?.(target);
141158
}
142159
143160
function handleSaveEdit() {
@@ -210,7 +227,7 @@
210227
{showDeleteDialog}
211228
{siblingInfo}
212229
/>
213-
{:else}
230+
{:else if message.role === 'assistant'}
214231
<ChatMessageAssistant
215232
bind:textareaElement
216233
class={className}
@@ -237,5 +254,11 @@
237254
{siblingInfo}
238255
{thinkingContent}
239256
{toolCallContent}
257+
toolParentIds={toolParentIds ?? [message.id]}
258+
toolMessagesCollected={(message as MessageWithToolExtras)._toolMessagesCollected}
240259
/>
260+
{:else if message.role === 'tool'}
261+
<!-- Tool messages are rendered inline inside their parent assistant's reasoning block.
262+
Skip standalone rendering to avoid duplicate bubbles. -->
263+
<!-- Intentionally left blank -->
241264
{/if}

0 commit comments

Comments
 (0)