























@@ -693,7 +693,27 @@ describe("convertToOllamaMessages", () => {
693693expect(result[0].role).toBe("assistant");
694694expect(result[0].content).toBe("Let me check.");
695695expect(result[0].tool_calls).toEqual([
696-{ function: { name: "bash", arguments: { command: "ls" } } },
696+{ id: "call_1", function: { name: "bash", arguments: { command: "ls" } } },
697+]);
698+});
699+700+it("preserves assistant tool-call ids before Ollama replay", () => {
701+const messages = [
702+{
703+role: "assistant",
704+content: [
705+{
706+type: "toolCall",
707+id: "fc_ollama_123",
708+name: "bash",
709+arguments: { command: "pwd" },
710+},
711+],
712+},
713+];
714+const result = convertToOllamaMessages(messages);
715+expect(result[0].tool_calls).toEqual([
716+{ id: "fc_ollama_123", function: { name: "bash", arguments: { command: "pwd" } } },
697717]);
698718});
699719@@ -709,8 +729,8 @@ describe("convertToOllamaMessages", () => {
709729];
710730const result = convertToOllamaMessages(messages);
711731expect(result[0].tool_calls).toEqual([
712-{ function: { name: "exec", arguments: { command: "pwd" } } },
713-{ function: { name: "read", arguments: { path: "README.md" } } },
732+{ id: "call_1", function: { name: "exec", arguments: { command: "pwd" } } },
733+{ id: "call_2", function: { name: "read", arguments: { path: "README.md" } } },
714734]);
715735});
716736@@ -729,9 +749,9 @@ describe("convertToOllamaMessages", () => {
729749availableToolNames: new Set(["tool_a", "tools_invoke_test", "function-run"]),
730750});
731751expect(result[0].tool_calls).toEqual([
732-{ function: { name: "tool_a", arguments: { value: 1 } } },
733-{ function: { name: "tools_invoke_test", arguments: { value: 2 } } },
734-{ function: { name: "function-run", arguments: { value: 3 } } },
752+{ id: "call_1", function: { name: "tool_a", arguments: { value: 1 } } },
753+{ id: "call_2", function: { name: "tools_invoke_test", arguments: { value: 2 } } },
754+{ id: "call_3", function: { name: "function-run", arguments: { value: 3 } } },
735755]);
736756});
737757@@ -750,9 +770,9 @@ describe("convertToOllamaMessages", () => {
750770availableToolNames: new Set(["exec", "read"]),
751771});
752772expect(result[0].tool_calls).toEqual([
753-{ function: { name: "exec", arguments: { command: "pwd" } } },
754-{ function: { name: "read", arguments: { path: "." } } },
755-{ function: { name: "tool_missing", arguments: {} } },
773+{ id: "call_1", function: { name: "exec", arguments: { command: "pwd" } } },
774+{ id: "call_2", function: { name: "read", arguments: { path: "." } } },
775+{ id: "call_3", function: { name: "tool_missing", arguments: {} } },
756776]);
757777});
758778@@ -770,10 +790,10 @@ describe("convertToOllamaMessages", () => {
770790];
771791const result = convertToOllamaMessages(messages);
772792expect(result[0].tool_calls).toEqual([
773-{ function: { name: "functionshell", arguments: {} } },
774-{ function: { name: "tooling", arguments: {} } },
775-{ function: { name: "tools", arguments: {} } },
776-{ function: { name: "tool_a", arguments: {} } },
793+{ id: "call_1", function: { name: "functionshell", arguments: {} } },
794+{ id: "call_2", function: { name: "tooling", arguments: {} } },
795+{ id: "call_3", function: { name: "tools", arguments: {} } },
796+{ id: "call_4", function: { name: "tool_a", arguments: {} } },
777797]);
778798});
779799@@ -795,7 +815,7 @@ describe("convertToOllamaMessages", () => {
795815];
796816const result = convertToOllamaMessages(messages);
797817expect(result[0].tool_calls).toEqual([
798-{ function: { name: "Read", arguments: { file_path: "/tmp/test.txt" } } },
818+{ id: "call_2", function: { name: "Read", arguments: { file_path: "/tmp/test.txt" } } },
799819]);
800820});
801821@@ -810,7 +830,7 @@ describe("convertToOllamaMessages", () => {
810830];
811831const result = convertToOllamaMessages(messages);
812832expect(result[0].tool_calls).toEqual([
813-{ function: { name: "exec", arguments: { command: "echo hello" } } },
833+{ id: "toolu_1", function: { name: "exec", arguments: { command: "echo hello" } } },
814834]);
815835});
816836@@ -831,6 +851,7 @@ describe("convertToOllamaMessages", () => {
831851const result = convertToOllamaMessages(messages);
832852expect(result[0].tool_calls).toEqual([
833853{
854+id: "call_3",
834855function: {
835856name: "read",
836857arguments: {
@@ -981,6 +1002,47 @@ describe("buildAssistantMessage", () => {
9811002expect(toolCall.id).toMatch(/^ollama_call_[0-9a-f-]{36}$/);
9821003});
98310041005+it("preserves Ollama response tool-call ids", () => {
1006+const response = {
1007+model: "gemini-3-flash-preview:cloud",
1008+created_at: "2026-01-01T00:00:00Z",
1009+message: {
1010+role: "assistant" as const,
1011+content: "",
1012+tool_calls: [
1013+{ id: "fc_ollama_real_1", function: { name: "bash", arguments: { command: "pwd" } } },
1014+],
1015+},
1016+done: true,
1017+};
1018+const result = buildAssistantMessage(response, modelInfo);
1019+expectToolCallContent(result.content[0], { name: "bash", arguments: { command: "pwd" } });
1020+expect((result.content[0] as { id?: string }).id).toBe("fc_ollama_real_1");
1021+});
1022+1023+it("preserves parallel Ollama response tool-call ids independently", () => {
1024+const response = {
1025+model: "gemini-3-flash-preview:cloud",
1026+created_at: "2026-01-01T00:00:00Z",
1027+message: {
1028+role: "assistant" as const,
1029+content: "",
1030+tool_calls: [
1031+{ id: "fc_ollama_real_1", function: { name: "read", arguments: { path: "a.txt" } } },
1032+{ id: "fc_ollama_real_2", function: { name: "exec", arguments: { command: "date" } } },
1033+],
1034+},
1035+done: true,
1036+};
1037+const result = buildAssistantMessage(response, modelInfo);
1038+expect(result.content.map((part) => (part as { id?: string }).id)).toEqual([
1039+"fc_ollama_real_1",
1040+"fc_ollama_real_2",
1041+]);
1042+expectToolCallContent(result.content[0], { name: "read", arguments: { path: "a.txt" } });
1043+expectToolCallContent(result.content[1], { name: "exec", arguments: { command: "date" } });
1044+});
1045+9841046it("normalizes provider-prefixed tool-call names in Ollama responses", () => {
9851047const response = {
9861048model: "qwen3:32b",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。