diff --git a/src/components/chat/AgentHistoryPanel.tsx b/src/components/chat/AgentHistoryPanel.tsx
index 79230a2..668c5a2 100644
--- a/src/components/chat/AgentHistoryPanel.tsx
+++ b/src/components/chat/AgentHistoryPanel.tsx
@@ -165,9 +165,6 @@ export const AgentHistoryPanel = ({
历史会话
-
- 本地保存于浏览器
-
diff --git a/src/components/chat/GlobalChatbox.tsx b/src/components/chat/GlobalChatbox.tsx
index a199342..a56c79e 100644
--- a/src/components/chat/GlobalChatbox.tsx
+++ b/src/components/chat/GlobalChatbox.tsx
@@ -60,7 +60,7 @@ export const GlobalChatbox: React.FC = ({ open, onClose }) => {
const {
messages,
chatSessions,
- activeStorageSessionId,
+ activeSessionId,
branchGroups,
branchTransition,
isHydrating,
@@ -129,33 +129,33 @@ export const GlobalChatbox: React.FC = ({ open, onClose }) => {
}, []);
const handleSelectSession = useCallback(
- (storageSessionId: string) => {
+ (sessionId: string) => {
composerRef.current?.clear();
- void switchSession(storageSessionId);
+ void switchSession(sessionId);
},
[switchSession],
);
const handleDeleteSession = useCallback(
- (storageSessionId: string) => {
- void removeSession(storageSessionId);
+ (sessionId: string) => {
+ void removeSession(sessionId);
},
[removeSession],
);
const handleRenameSession = useCallback(
- (storageSessionId: string, title: string) => {
- void renameSession(storageSessionId, title);
+ (sessionId: string, title: string) => {
+ void renameSession(sessionId, title);
},
[renameSession],
);
const handleRenameActiveSession = useCallback(
(title: string) => {
- if (!activeStorageSessionId) return;
- void renameSession(activeStorageSessionId, title);
+ if (!activeSessionId) return;
+ void renameSession(activeSessionId, title);
},
- [activeStorageSessionId, renameSession],
+ [activeSessionId, renameSession],
);
const handleMouseDown = useCallback((event: React.MouseEvent) => {
@@ -255,7 +255,7 @@ export const GlobalChatbox: React.FC = ({ open, onClose }) => {
= ({ open, onClose }) => {
>
{
handleNewConversation();
diff --git a/src/components/chat/GlobalChatbox.types.ts b/src/components/chat/GlobalChatbox.types.ts
index acba4e7..4ac085b 100644
--- a/src/components/chat/GlobalChatbox.types.ts
+++ b/src/components/chat/GlobalChatbox.types.ts
@@ -66,23 +66,6 @@ export type Props = {
export type SpeechState = "idle" | "playing" | "paused";
-export type LegacyPersistedChatState = {
- messages: Message[];
- sessionId?: string;
- branchGroups?: BranchGroup[];
-};
-
-export type ChatSessionRecord = {
- id: string;
- title: string;
- isTitleManuallyEdited?: boolean;
- createdAt: number;
- updatedAt: number;
- sessionId?: string;
- messages: Message[];
- branchGroups: BranchGroup[];
-};
-
export type ChatSessionSummary = {
id: string;
title: string;
@@ -90,17 +73,10 @@ export type ChatSessionSummary = {
updatedAt: number;
};
-export type ChatStorageMeta = {
- key: "chat-meta";
- activeSessionId?: string;
- migratedFromLocalStorage?: boolean;
-};
-
export type LoadedChatState = {
- storageSessionId?: string;
+ sessionId?: string;
title?: string;
isTitleManuallyEdited?: boolean;
messages: Message[];
- sessionId?: string;
branchGroups: BranchGroup[];
};
diff --git a/src/components/chat/chatStorage.test.ts b/src/components/chat/chatStorage.test.ts
index ffbef3d..f1117c9 100644
--- a/src/components/chat/chatStorage.test.ts
+++ b/src/components/chat/chatStorage.test.ts
@@ -1,5 +1,5 @@
import {
- loadActiveChatState,
+ createEmptyChatState,
saveActiveChatState,
} from "./chatStorage";
@@ -11,17 +11,13 @@ jest.mock("@/lib/apiFetch", () => ({
describe("chatStorage backend-only persistence", () => {
beforeEach(() => {
- window.localStorage.clear();
apiFetch.mockReset();
});
- it("starts from an empty conversation instead of restoring a stored active id", async () => {
- window.localStorage.setItem("tjwater_agent_active_session_id_v2", "chat-active-1");
-
- const loaded = await loadActiveChatState();
+ it("creates an empty initial conversation state without backend calls", () => {
+ const loaded = createEmptyChatState();
expect(loaded).toMatchObject({
- storageSessionId: undefined,
title: undefined,
messages: [],
sessionId: undefined,
@@ -30,24 +26,6 @@ describe("chatStorage backend-only persistence", () => {
expect(apiFetch).not.toHaveBeenCalled();
});
- it("starts from an empty conversation when a project has a stored active id", async () => {
- window.localStorage.setItem(
- "tjwater_agent_active_session_id_v2:project-a",
- "chat-project-a",
- );
- window.localStorage.setItem(
- "tjwater_agent_active_session_id_v2:project-b",
- "chat-project-b",
- );
-
- const loaded = await loadActiveChatState("project-b");
-
- expect(loaded.storageSessionId).toBeUndefined();
- expect(loaded.title).toBeUndefined();
- expect(loaded.messages).toEqual([]);
- expect(apiFetch).not.toHaveBeenCalled();
- });
-
it("creates a backend conversation when saving the first non-empty state", async () => {
apiFetch.mockImplementation(async (url: string, init?: RequestInit) => {
if (url.endsWith("/api/v1/agent/chat/session")) {
@@ -75,7 +53,6 @@ describe("chatStorage backend-only persistence", () => {
const savedSessionId = await saveActiveChatState(
{
- storageSessionId: undefined,
title: "新对话",
isTitleManuallyEdited: false,
messages: [
@@ -89,13 +66,8 @@ describe("chatStorage backend-only persistence", () => {
sessionId: undefined,
branchGroups: [],
},
- "project-a",
);
expect(savedSessionId).toBe("chat-new-1");
- expect(
- window.localStorage.getItem("tjwater_agent_active_session_id_v2:project-a"),
- ).toBeNull();
});
-
});
diff --git a/src/components/chat/chatStorage.ts b/src/components/chat/chatStorage.ts
index bda1fbc..5cfed97 100644
--- a/src/components/chat/chatStorage.ts
+++ b/src/components/chat/chatStorage.ts
@@ -9,15 +9,14 @@ import type {
} from "./GlobalChatbox.types";
import { cloneBranchGroups, cloneMessages } from "./GlobalChatbox.utils";
-type RemoteSessionPayload = {
+type BackendSessionPayload = {
id?: string;
title?: string;
created_at?: string | number;
updated_at?: string | number;
};
-const emptyLoadedChatState = (): LoadedChatState => ({
- storageSessionId: undefined,
+export const createEmptyChatState = (): LoadedChatState => ({
title: undefined,
isTitleManuallyEdited: false,
messages: [],
@@ -58,7 +57,7 @@ const toMillis = (value: string | number | undefined) =>
const normalizeTitle = (value?: string) => value?.trim() || "新对话";
-const fetchRemoteChatSessions = async (): Promise => {
+const fetchBackendChatSessions = async (): Promise => {
const response = await apiFetch(`${config.AGENT_URL}/api/v1/agent/chat/sessions`, {
method: "GET",
projectHeaderMode: "include",
@@ -69,7 +68,7 @@ const fetchRemoteChatSessions = async (): Promise => {
throw new Error(await response.text());
}
const payload = (await response.json()) as {
- sessions?: RemoteSessionPayload[];
+ sessions?: BackendSessionPayload[];
};
return (payload.sessions ?? [])
.map((session) => ({
@@ -82,7 +81,7 @@ const fetchRemoteChatSessions = async (): Promise => {
.sort(compareSessionsByAnchorTime);
};
-const fetchRemoteChatSession = async (sessionId: string): Promise => {
+const fetchBackendChatSession = async (sessionId: string): Promise => {
const response = await apiFetch(
`${config.AGENT_URL}/api/v1/agent/chat/session/${encodeURIComponent(sessionId)}`,
{
@@ -94,7 +93,7 @@ const fetchRemoteChatSession = async (sessionId: string): Promise {
@@ -146,7 +144,7 @@ const createRemoteChatSession = async (payload?: {
return sessionId;
};
-const saveRemoteChatState = async (
+const saveBackendChatState = async (
sessionId: string,
state: LoadedChatState,
): Promise => {
@@ -175,7 +173,7 @@ const saveRemoteChatState = async (
return payload.id ?? payload.session_id ?? sessionId;
};
-const updateRemoteChatSessionTitle = async (
+const updateBackendChatSessionTitle = async (
sessionId: string,
title: string,
isTitleManuallyEdited?: boolean,
@@ -201,7 +199,7 @@ const updateRemoteChatSessionTitle = async (
}
};
-const deleteRemoteChatSession = async (sessionId: string) => {
+const deleteBackendChatSession = async (sessionId: string) => {
const response = await apiFetch(
`${config.AGENT_URL}/api/v1/agent/chat/session/${encodeURIComponent(sessionId)}`,
{
@@ -216,42 +214,34 @@ const deleteRemoteChatSession = async (sessionId: string) => {
}
};
-export const loadActiveChatState = async (
- _projectId?: string | null,
-): Promise => {
- return emptyLoadedChatState();
-};
-
export const saveActiveChatState = async (
state: LoadedChatState,
- _projectId?: string | null,
): Promise => {
- if (typeof window === "undefined") return state.storageSessionId;
+ if (typeof window === "undefined") return state.sessionId;
if (!hasChatContent(state)) {
return undefined;
}
- let remoteSessionId = state.sessionId ?? state.storageSessionId;
- if (!remoteSessionId) {
- remoteSessionId = await createRemoteChatSession();
+ let backendSessionId = state.sessionId;
+ if (!backendSessionId) {
+ backendSessionId = await createBackendChatSession();
}
- const savedSessionId = await saveRemoteChatState(remoteSessionId, {
+ const savedSessionId = await saveBackendChatState(backendSessionId, {
...state,
- storageSessionId: remoteSessionId,
- sessionId: remoteSessionId,
+ sessionId: backendSessionId,
});
return savedSessionId;
};
export const listChatSessions = async (): Promise => {
if (typeof window === "undefined") return [];
- return await fetchRemoteChatSessions();
+ return await fetchBackendChatSessions();
};
export const updateChatSessionTitle = async (
- storageSessionId: string,
+ sessionId: string,
title: string,
options?: {
isTitleManuallyEdited?: boolean;
@@ -261,8 +251,8 @@ export const updateChatSessionTitle = async (
const normalizedTitle = title.trim();
if (!normalizedTitle) return;
- await updateRemoteChatSessionTitle(
- storageSessionId,
+ await updateBackendChatSessionTitle(
+ sessionId,
normalizedTitle,
options?.isTitleManuallyEdited,
);
@@ -270,20 +260,18 @@ export const updateChatSessionTitle = async (
export const loadChatSessionById = async (
sessionId: string,
- _projectId?: string | null,
): Promise => {
- if (typeof window === "undefined") return emptyLoadedChatState();
+ if (typeof window === "undefined") return createEmptyChatState();
- return await fetchRemoteChatSession(sessionId);
+ return await fetchBackendChatSession(sessionId);
};
export const deleteChatSession = async (
sessionId: string,
- _projectId?: string | null,
): Promise => {
if (typeof window === "undefined") return undefined;
- await deleteRemoteChatSession(sessionId);
+ await deleteBackendChatSession(sessionId);
const nextActiveSession = (await listChatSessions())[0];
return nextActiveSession?.id;
};
diff --git a/src/components/chat/hooks/useAgentChatSession.test.tsx b/src/components/chat/hooks/useAgentChatSession.test.tsx
index d321c55..eba37a8 100644
--- a/src/components/chat/hooks/useAgentChatSession.test.tsx
+++ b/src/components/chat/hooks/useAgentChatSession.test.tsx
@@ -12,44 +12,38 @@ jest.mock("@/lib/chatStream", () => ({
streamAgentChat: jest.fn(async () => undefined),
}));
-const loadActiveChatState = jest.fn();
const listChatSessions = jest.fn();
const saveActiveChatState = jest.fn();
const updateChatSessionTitle = jest.fn();
jest.mock("../chatStorage", () => ({
- deleteChatSession: jest.fn(async () => undefined),
- listChatSessions: (...args: unknown[]) => listChatSessions(...args),
- loadActiveChatState: (...args: unknown[]) => loadActiveChatState(...args),
- loadChatSessionById: jest.fn(async () => ({
- storageSessionId: "session-loaded",
- title: "已存在会话",
+ createEmptyChatState: jest.fn(() => ({
+ title: undefined,
isTitleManuallyEdited: false,
messages: [],
sessionId: undefined,
branchGroups: [],
})),
+ deleteChatSession: jest.fn(async () => undefined),
+ listChatSessions: (...args: unknown[]) => listChatSessions(...args),
+ loadChatSessionById: jest.fn(async () => ({
+ title: "已存在会话",
+ isTitleManuallyEdited: false,
+ messages: [],
+ sessionId: "session-loaded",
+ branchGroups: [],
+ })),
saveActiveChatState: (...args: unknown[]) => saveActiveChatState(...args),
updateChatSessionTitle: (...args: unknown[]) => updateChatSessionTitle(...args),
}));
describe("useAgentChatSession", () => {
beforeEach(() => {
- loadActiveChatState.mockReset();
listChatSessions.mockReset();
saveActiveChatState.mockReset();
updateChatSessionTitle.mockReset();
jest.mocked(streamAgentChat).mockReset();
- saveActiveChatState.mockImplementation(async (state) => state.storageSessionId);
-
- loadActiveChatState.mockResolvedValue({
- storageSessionId: undefined,
- title: undefined,
- isTitleManuallyEdited: false,
- messages: [],
- sessionId: undefined,
- branchGroups: [],
- });
+ saveActiveChatState.mockImplementation(async (state) => state.sessionId);
});
it("does not add a new empty session to history until there is actual chat content", async () => {
@@ -70,7 +64,7 @@ describe("useAgentChatSession", () => {
await waitFor(() => expect(result.current.sessionTitle).toBe("新对话"));
expect(result.current.chatSessions).toEqual([]);
- expect(result.current.activeStorageSessionId).toBeUndefined();
+ expect(result.current.activeSessionId).toBeUndefined();
expect(result.current.messages).toEqual([]);
expect(result.current.isStreaming).toBe(false);
expect(listChatSessions).toHaveBeenCalledTimes(1);
@@ -164,14 +158,6 @@ describe("useAgentChatSession", () => {
it("ignores generated session titles after the title was edited manually", async () => {
listChatSessions.mockResolvedValue([]);
- loadActiveChatState.mockResolvedValue({
- storageSessionId: "session-1",
- title: "手动标题",
- isTitleManuallyEdited: true,
- messages: [],
- sessionId: "session-1",
- branchGroups: [],
- });
jest.mocked(streamAgentChat).mockImplementationOnce(async ({ onEvent }) => {
onEvent({
type: "session_title",
@@ -193,13 +179,23 @@ describe("useAgentChatSession", () => {
await waitFor(() => expect(result.current.isHydrating).toBe(false));
+ await act(async () => {
+ await result.current.switchSession("session-loaded");
+ });
+
+ await act(async () => {
+ await result.current.renameSession("session-loaded", "手动标题");
+ });
+
+ await waitFor(() => expect(updateChatSessionTitle).toHaveBeenCalled());
+
await act(async () => {
await result.current.sendPrompt("帮我分析一下");
});
expect(result.current.sessionTitle).toBe("手动标题");
expect(updateChatSessionTitle).not.toHaveBeenCalledWith(
- "session-1",
+ "session-loaded",
"自动标题",
expect.anything(),
);
diff --git a/src/components/chat/hooks/useAgentChatSession.ts b/src/components/chat/hooks/useAgentChatSession.ts
index ac0feb8..8252bdf 100644
--- a/src/components/chat/hooks/useAgentChatSession.ts
+++ b/src/components/chat/hooks/useAgentChatSession.ts
@@ -19,9 +19,9 @@ import {
createId,
} from "../GlobalChatbox.utils";
import {
+ createEmptyChatState,
deleteChatSession,
listChatSessions,
- loadActiveChatState,
loadChatSessionById,
saveActiveChatState,
updateChatSessionTitle,
@@ -50,7 +50,6 @@ type PromptRunOptions = {
const createPersistedStateKey = (state: LoadedChatState) =>
JSON.stringify({
- storageSessionId: state.storageSessionId ?? null,
title: state.title ?? null,
isTitleManuallyEdited: state.isTitleManuallyEdited ?? false,
sessionId: state.sessionId ?? null,
@@ -151,7 +150,6 @@ export const useAgentChatSession = ({
onBeforeSend,
getModel,
}: UseAgentChatSessionOptions) => {
- const storageSessionIdRef = useRef(undefined);
const hydrationCompletedRef = useRef(false);
const hydrationNonceRef = useRef(0);
@@ -171,11 +169,10 @@ export const useAgentChatSession = ({
const titleUpdateNonceRef = useRef(0);
const lastPersistedStateKeyRef = useRef(
createPersistedStateKey({
- storageSessionId: undefined,
+ sessionId: undefined,
title: undefined,
isTitleManuallyEdited: false,
messages: [],
- sessionId: undefined,
branchGroups: [],
}),
);
@@ -196,10 +193,8 @@ export const useAgentChatSession = ({
hydrationCompletedRef.current = false;
if (!projectId) {
- storageSessionIdRef.current = undefined;
sessionIdRef.current = undefined;
lastPersistedStateKeyRef.current = createPersistedStateKey({
- storageSessionId: undefined,
title: undefined,
isTitleManuallyEdited: false,
messages: [],
@@ -222,12 +217,11 @@ export const useAgentChatSession = ({
try {
const [loadedState, sessions] = await Promise.all([
- loadActiveChatState(projectId),
+ Promise.resolve(createEmptyChatState()),
listChatSessions(),
]);
if (cancelled) return;
- storageSessionIdRef.current = loadedState.storageSessionId;
sessionIdRef.current = loadedState.sessionId;
lastPersistedStateKeyRef.current = createPersistedStateKey(loadedState);
hydrationCompletedRef.current = true;
@@ -262,7 +256,6 @@ export const useAgentChatSession = ({
const currentHydrationNonce = hydrationNonceRef.current;
const persistTimer = window.setTimeout(() => {
const state: LoadedChatState = {
- storageSessionId: storageSessionIdRef.current,
title: sessionTitle,
isTitleManuallyEdited: isSessionTitleManuallyEdited,
messages,
@@ -271,7 +264,6 @@ export const useAgentChatSession = ({
};
if (
isStreaming &&
- !state.storageSessionId &&
!state.sessionId &&
state.messages.length > 0
) {
@@ -283,13 +275,13 @@ export const useAgentChatSession = ({
return;
}
- void saveActiveChatState(state, projectId)
- .then((storageSessionId) => {
+ void saveActiveChatState(state)
+ .then((sessionId) => {
if (hydrationNonceRef.current !== currentHydrationNonce) return;
- storageSessionIdRef.current = storageSessionId;
+ sessionIdRef.current = sessionId;
lastPersistedStateKeyRef.current = createPersistedStateKey({
...state,
- storageSessionId,
+ sessionId,
});
return listChatSessions();
})
@@ -431,10 +423,10 @@ export const useAgentChatSession = ({
const nextTitle = event.title.trim();
if (nextTitle && !isSessionTitleManuallyEditedRef.current) {
setSessionTitle(nextTitle);
- const currentStorageSessionId = storageSessionIdRef.current;
- if (currentStorageSessionId) {
+ const currentSessionId = sessionIdRef.current;
+ if (currentSessionId) {
const currentNonce = ++titleUpdateNonceRef.current;
- void updateChatSessionTitle(currentStorageSessionId, nextTitle, {
+ void updateChatSessionTitle(currentSessionId, nextTitle, {
isTitleManuallyEdited: false,
})
.then(() => listChatSessions())
@@ -555,10 +547,8 @@ export const useAgentChatSession = ({
setBranchTransition(null);
hydrationNonceRef.current += 1;
titleUpdateNonceRef.current += 1;
- storageSessionIdRef.current = undefined;
sessionIdRef.current = undefined;
lastPersistedStateKeyRef.current = createPersistedStateKey({
- storageSessionId: undefined,
title: "新对话",
isTitleManuallyEdited: false,
messages: [],
@@ -574,21 +564,20 @@ export const useAgentChatSession = ({
}, [isHydrating, isStreaming]);
const switchSession = useCallback(
- async (nextStorageSessionId: string) => {
- if (isHydrating || isStreaming || storageSessionIdRef.current === nextStorageSessionId) {
+ async (nextSessionId: string) => {
+ if (isHydrating || isStreaming || sessionIdRef.current === nextSessionId) {
return;
}
setIsHydrating(true);
try {
const [nextState, sessions] = await Promise.all([
- loadChatSessionById(nextStorageSessionId, projectId),
+ loadChatSessionById(nextSessionId),
listChatSessions(),
]);
hydrationNonceRef.current += 1;
titleUpdateNonceRef.current += 1;
- storageSessionIdRef.current = nextState.storageSessionId;
sessionIdRef.current = nextState.sessionId;
lastPersistedStateKeyRef.current = createPersistedStateKey(nextState);
setBranchTransition(null);
@@ -604,32 +593,29 @@ export const useAgentChatSession = ({
setIsHydrating(false);
}
},
- [isHydrating, isStreaming, projectId],
+ [isHydrating, isStreaming],
);
const removeSession = useCallback(
- async (targetStorageSessionId: string) => {
+ async (targetSessionId: string) => {
if (isHydrating || isStreaming) return;
try {
const nextActiveSessionId = await deleteChatSession(
- targetStorageSessionId,
- projectId,
+ targetSessionId,
);
const sessions = await listChatSessions();
setChatSessions(sessions);
- if (storageSessionIdRef.current !== targetStorageSessionId) {
+ if (sessionIdRef.current !== targetSessionId) {
return;
}
if (!nextActiveSessionId) {
hydrationNonceRef.current += 1;
titleUpdateNonceRef.current += 1;
- storageSessionIdRef.current = undefined;
sessionIdRef.current = undefined;
lastPersistedStateKeyRef.current = createPersistedStateKey({
- storageSessionId: undefined,
title: undefined,
isTitleManuallyEdited: false,
messages: [],
@@ -647,12 +633,11 @@ export const useAgentChatSession = ({
setIsHydrating(true);
const [nextState, sessionsAfterDelete] = await Promise.all([
- loadChatSessionById(nextActiveSessionId, projectId),
+ loadChatSessionById(nextActiveSessionId),
listChatSessions(),
]);
hydrationNonceRef.current += 1;
titleUpdateNonceRef.current += 1;
- storageSessionIdRef.current = nextState.storageSessionId;
sessionIdRef.current = nextState.sessionId;
lastPersistedStateKeyRef.current = createPersistedStateKey(nextState);
setBranchTransition(null);
@@ -668,7 +653,7 @@ export const useAgentChatSession = ({
setIsHydrating(false);
}
},
- [isHydrating, isStreaming, projectId],
+ [isHydrating, isStreaming],
);
const sendPrompt = useCallback(
@@ -679,22 +664,22 @@ export const useAgentChatSession = ({
);
const renameSession = useCallback(
- async (targetStorageSessionId: string, nextTitle: string) => {
+ async (targetSessionId: string, nextTitle: string) => {
const normalizedTitle = nextTitle.trim();
if (!normalizedTitle || isHydrating) return;
try {
- await updateChatSessionTitle(targetStorageSessionId, normalizedTitle, {
+ await updateChatSessionTitle(targetSessionId, normalizedTitle, {
isTitleManuallyEdited: true,
});
const sessions = await listChatSessions();
setChatSessions(sessions);
- if (storageSessionIdRef.current === targetStorageSessionId) {
+ if (sessionIdRef.current === targetSessionId) {
setSessionTitle(normalizedTitle);
setIsSessionTitleManuallyEdited(true);
lastPersistedStateKeyRef.current = createPersistedStateKey({
- storageSessionId: targetStorageSessionId,
+ sessionId: targetSessionId,
title: normalizedTitle,
isTitleManuallyEdited: true,
messages,
@@ -864,7 +849,7 @@ export const useAgentChatSession = ({
return {
messages,
chatSessions,
- activeStorageSessionId: storageSessionIdRef.current,
+ activeSessionId: sessionIdRef.current,
branchGroups,
branchTransition,
isHydrating,
diff --git a/src/lib/chatStream.test.ts b/src/lib/chatStream.test.ts
index 064ead6..79e400f 100644
--- a/src/lib/chatStream.test.ts
+++ b/src/lib/chatStream.test.ts
@@ -103,11 +103,11 @@ describe("streamAgentChat", () => {
});
});
- it("parses legacy tool_call arguments when params is empty", async () => {
+ it("parses tool_call arguments when params is empty", async () => {
apiFetch.mockResolvedValue({
ok: true,
body: makeStream([
- 'event: tool_call\ndata: {"conversationId":"agent-1e75dd01-29e","tool":"locate_features","params":{},"arguments":"{\\"ids\\":[\\"142902\\"],\\"feature_type\\":\\"junction\\"}"}\n\n',
+ 'event: tool_call\ndata: {"session_id":"agent-1e75dd01-29e","tool":"locate_features","params":{},"arguments":"{\\"ids\\":[\\"142902\\"],\\"feature_type\\":\\"junction\\"}"}\n\n',
'event: done\ndata: {"session_id":"agent-1e75dd01-29e"}\n\n',
]),
});
diff --git a/src/lib/chatStream.ts b/src/lib/chatStream.ts
index 9a6d981..4fd94d5 100644
--- a/src/lib/chatStream.ts
+++ b/src/lib/chatStream.ts
@@ -163,7 +163,6 @@ export const streamAgentChat = async ({
try {
const parsed = JSON.parse(data) as {
session_id?: string;
- conversationId?: string;
content?: string;
message?: string;
detail?: string;
@@ -223,7 +222,7 @@ export const streamAgentChat = async ({
} else if (event === "tool_call") {
onEvent({
type: "tool_call",
- sessionId: parsed.session_id ?? parsed.conversationId ?? "",
+ sessionId: parsed.session_id ?? "",
tool: parsed.tool ?? "",
params: resolveToolParams(parsed.params, parsed.arguments),
});