diff --git a/webui/src/App.tsx b/webui/src/App.tsx
index 7033f6e30..1b50e0ce6 100644
--- a/webui/src/App.tsx
+++ b/webui/src/App.tsx
@@ -64,6 +64,7 @@ import {
import { projectNameFromPath, scopeWithAccessMode } from "@/lib/workspace";
import {
createTemporaryChatSession,
+ deriveTemporaryChatTitle,
} from "@/lib/temporary-chat";
type BootState =
@@ -2069,7 +2070,7 @@ function Shell({
}, []);
const headerTitle = temporaryChatActive
- ? t("temporaryChat.title")
+ ? deriveTemporaryChatTitle(activeSession?.preview, t("temporaryChat.title"))
: activeSession
? sidebarState.title_overrides[activeSession.key] ||
activeSession.title ||
diff --git a/webui/src/components/ChatList.tsx b/webui/src/components/ChatList.tsx
index f71a4e32a..e4abc146f 100644
--- a/webui/src/components/ChatList.tsx
+++ b/webui/src/components/ChatList.tsx
@@ -44,6 +44,7 @@ import {
type ChatGroupLabels,
} from "@/lib/chat-groups";
import { clearDraggedSession, writeDraggedSession } from "@/lib/session-drag";
+import { deriveTemporaryChatTitle } from "@/lib/temporary-chat";
import { cn } from "@/lib/utils";
import type { ChatSummary, SidebarDensity, SidebarSortMode } from "@/lib/types";
@@ -537,7 +538,7 @@ function TemporaryChatSection({
{sessions.map((session) => {
const active = session.key === activeKey;
- const title = deriveTitle(session.preview, t("temporaryChat.title"));
+ const title = deriveTemporaryChatTitle(session.preview, t("temporaryChat.title"));
return (
-
60 ? `${oneLine.slice(0, 57)}…` : oneLine;
+}
+
export function createTemporaryChatSession(chatId: string): ChatSummary {
const now = new Date().toISOString();
return {
diff --git a/webui/src/tests/app-layout.test.tsx b/webui/src/tests/app-layout.test.tsx
index 0b37c16d2..96071dd2c 100644
--- a/webui/src/tests/app-layout.test.tsx
+++ b/webui/src/tests/app-layout.test.tsx
@@ -466,7 +466,10 @@ describe("App layout", () => {
name: "first private message",
}));
await waitFor(() => expect(window.location.hash).toBe(firstHash));
- expect(screen.getByText("Temporary chat")).toBeInTheDocument();
+ expect(within(screen.getByTestId("thread-header")).getByText(
+ "first private message",
+ )).toBeInTheDocument();
+ await waitFor(() => expect(document.title).toBe("first private message · nanobot"));
expect(screen.queryByRole("button", { name: "Temporary chat" })).not.toBeInTheDocument();
fireEvent.click(within(sidebar).getByRole("button", {
diff --git a/webui/src/tests/chat-list.test.tsx b/webui/src/tests/chat-list.test.tsx
index 97e2cccd1..fa2e3cb79 100644
--- a/webui/src/tests/chat-list.test.tsx
+++ b/webui/src/tests/chat-list.test.tsx
@@ -156,7 +156,7 @@ describe("ChatList", () => {
const temporarySession = session({
key: "temporary:temporary-one",
chatId: "temporary-one",
- preview: "Private planning",
+ preview: "hi",
});
const onSelect = vi.fn();
const onClose = vi.fn();
@@ -176,11 +176,11 @@ describe("ChatList", () => {
);
const section = screen.getByRole("region", { name: "Temporary chats" });
- fireEvent.click(within(section).getByRole("button", { name: "Private planning" }));
+ fireEvent.click(within(section).getByRole("button", { name: "hi" }));
expect(onSelect).toHaveBeenCalledWith("temporary:temporary-one");
fireEvent.click(within(section).getByRole("button", {
- name: "Close temporary chat: Private planning",
+ name: "Close temporary chat: hi",
}));
expect(onClose).toHaveBeenCalledWith("temporary:temporary-one");
});