Improvements

This commit is contained in:
Nicolas Mowen
2026-02-27 08:57:41 -07:00
parent c9591225ba
commit d5aa2a0341
5 changed files with 171 additions and 16 deletions
+4 -1
View File
@@ -1,5 +1,8 @@
{
"placeholder": "Ask anything...",
"error": "Something went wrong. Please try again.",
"processing": "Processing..."
"processing": "Processing...",
"toolsUsed": "Used: {{tools}}",
"showTools": "Show tools ({{count}})",
"hideTools": "Hide tools"
}
@@ -0,0 +1,66 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import ReactMarkdown from "react-markdown";
import { Button } from "@/components/ui/button";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
export type ToolCall = {
name: string;
arguments?: Record<string, unknown>;
response?: string;
};
type AssistantMessageProps = {
content: string;
toolCalls?: ToolCall[];
};
export function AssistantMessage({
content,
toolCalls,
}: AssistantMessageProps) {
const { t } = useTranslation(["views/chat"]);
const [open, setOpen] = useState(false);
const hasToolCalls = toolCalls && toolCalls.length > 0;
return (
<div className="flex flex-col gap-2">
<ReactMarkdown>{content}</ReactMarkdown>
{hasToolCalls && (
<Collapsible open={open} onOpenChange={setOpen}>
<CollapsibleTrigger asChild>
<Button
variant="ghost"
size="sm"
className="h-auto py-1 text-xs text-muted-foreground hover:text-foreground"
>
{open
? t("hideTools")
: t("showTools", { count: toolCalls.length })}
</Button>
</CollapsibleTrigger>
<CollapsibleContent>
<ul className="mt-2 space-y-2 border-l-2 border-muted-foreground/30 pl-3">
{toolCalls.map((tc, idx) => (
<li key={idx} className="text-xs">
<span className="font-medium text-muted-foreground">
{tc.name}
</span>
{tc.response != null && tc.response !== "" && (
<pre className="mt-1 max-h-32 overflow-auto rounded bg-muted/50 p-2 text-[10px]">
{tc.response}
</pre>
)}
</li>
))}
</ul>
</CollapsibleContent>
</Collapsible>
)}
</div>
);
}
+19 -4
View File
@@ -4,9 +4,16 @@ import { FaArrowUpLong } from "react-icons/fa6";
import { useTranslation } from "react-i18next";
import { useState, useCallback } from "react";
import axios from "axios";
import ReactMarkdown from "react-markdown";
import {
AssistantMessage,
type ToolCall,
} from "@/components/chat/AssistantMessage";
type ChatMessage = { role: "user" | "assistant"; content: string };
type ChatMessage = {
role: "user" | "assistant";
content: string;
toolCalls?: ToolCall[];
};
export default function ChatPage() {
const { t } = useTranslation(["views/chat"]);
@@ -32,12 +39,17 @@ export default function ChatPage() {
}));
const { data } = await axios.post<{
message: { role: string; content: string | null };
tool_calls?: ToolCall[];
}>("chat/completion", { messages: apiMessages });
const content = data.message?.content ?? "";
setMessages((prev) => [
...prev,
{ role: "assistant", content: content || " " },
{
role: "assistant",
content: content || " ",
toolCalls: data.tool_calls?.length ? data.tool_calls : undefined,
},
]);
} catch {
setError(t("error"));
@@ -59,7 +71,10 @@ export default function ChatPage() {
}
>
{msg.role === "assistant" ? (
<ReactMarkdown>{msg.content}</ReactMarkdown>
<AssistantMessage
content={msg.content}
toolCalls={msg.toolCalls}
/>
) : (
msg.content
)}