@@ -4,6 +4,7 @@ import { Anthropic } from "@anthropic-ai/sdk"
44import OpenAI from "openai"
55
66import { convertToOpenAiMessages } from "../openai-format"
7+ import { normalizeMistralToolCallId } from "../mistral-format"
78
89describe ( "convertToOpenAiMessages" , ( ) => {
910 it ( "should convert simple text messages" , ( ) => {
@@ -70,7 +71,7 @@ describe("convertToOpenAiMessages", () => {
7071 } )
7172 } )
7273
73- it ( "should handle assistant messages with tool use" , ( ) => {
74+ it ( "should handle assistant messages with tool use (no normalization without normalizeToolCallId) " , ( ) => {
7475 const anthropicMessages : Anthropic . Messages . MessageParam [ ] = [
7576 {
7677 role : "assistant" ,
@@ -97,7 +98,7 @@ describe("convertToOpenAiMessages", () => {
9798 expect ( assistantMessage . content ) . toBe ( "Let me check the weather." )
9899 expect ( assistantMessage . tool_calls ) . toHaveLength ( 1 )
99100 expect ( assistantMessage . tool_calls ! [ 0 ] ) . toEqual ( {
100- id : "weather-123" ,
101+ id : "weather-123" , // Not normalized without normalizeToolCallId function
101102 type : "function" ,
102103 function : {
103104 name : "get_weather" ,
@@ -106,7 +107,7 @@ describe("convertToOpenAiMessages", () => {
106107 } )
107108 } )
108109
109- it ( "should handle user messages with tool results" , ( ) => {
110+ it ( "should handle user messages with tool results (no normalization without normalizeToolCallId) " , ( ) => {
110111 const anthropicMessages : Anthropic . Messages . MessageParam [ ] = [
111112 {
112113 role : "user" ,
@@ -125,7 +126,102 @@ describe("convertToOpenAiMessages", () => {
125126
126127 const toolMessage = openAiMessages [ 0 ] as OpenAI . Chat . ChatCompletionToolMessageParam
127128 expect ( toolMessage . role ) . toBe ( "tool" )
128- expect ( toolMessage . tool_call_id ) . toBe ( "weather-123" )
129+ expect ( toolMessage . tool_call_id ) . toBe ( "weather-123" ) // Not normalized without normalizeToolCallId function
129130 expect ( toolMessage . content ) . toBe ( "Current temperature in London: 20°C" )
130131 } )
132+
133+ it ( "should normalize tool call IDs when normalizeToolCallId function is provided" , ( ) => {
134+ const anthropicMessages : Anthropic . Messages . MessageParam [ ] = [
135+ {
136+ role : "assistant" ,
137+ content : [
138+ {
139+ type : "tool_use" ,
140+ id : "call_5019f900a247472bacde0b82" ,
141+ name : "read_file" ,
142+ input : { path : "test.ts" } ,
143+ } ,
144+ ] ,
145+ } ,
146+ {
147+ role : "user" ,
148+ content : [
149+ {
150+ type : "tool_result" ,
151+ tool_use_id : "call_5019f900a247472bacde0b82" ,
152+ content : "file contents" ,
153+ } ,
154+ ] ,
155+ } ,
156+ ]
157+
158+ // With normalizeToolCallId function - should normalize
159+ const openAiMessages = convertToOpenAiMessages ( anthropicMessages , {
160+ normalizeToolCallId : normalizeMistralToolCallId ,
161+ } )
162+
163+ const assistantMessage = openAiMessages [ 0 ] as OpenAI . Chat . ChatCompletionAssistantMessageParam
164+ expect ( assistantMessage . tool_calls ! [ 0 ] . id ) . toBe ( normalizeMistralToolCallId ( "call_5019f900a247472bacde0b82" ) )
165+
166+ const toolMessage = openAiMessages [ 1 ] as OpenAI . Chat . ChatCompletionToolMessageParam
167+ expect ( toolMessage . tool_call_id ) . toBe ( normalizeMistralToolCallId ( "call_5019f900a247472bacde0b82" ) )
168+ } )
169+
170+ it ( "should not normalize tool call IDs when normalizeToolCallId function is not provided" , ( ) => {
171+ const anthropicMessages : Anthropic . Messages . MessageParam [ ] = [
172+ {
173+ role : "assistant" ,
174+ content : [
175+ {
176+ type : "tool_use" ,
177+ id : "call_5019f900a247472bacde0b82" ,
178+ name : "read_file" ,
179+ input : { path : "test.ts" } ,
180+ } ,
181+ ] ,
182+ } ,
183+ {
184+ role : "user" ,
185+ content : [
186+ {
187+ type : "tool_result" ,
188+ tool_use_id : "call_5019f900a247472bacde0b82" ,
189+ content : "file contents" ,
190+ } ,
191+ ] ,
192+ } ,
193+ ]
194+
195+ // Without normalizeToolCallId function - should NOT normalize
196+ const openAiMessages = convertToOpenAiMessages ( anthropicMessages , { } )
197+
198+ const assistantMessage = openAiMessages [ 0 ] as OpenAI . Chat . ChatCompletionAssistantMessageParam
199+ expect ( assistantMessage . tool_calls ! [ 0 ] . id ) . toBe ( "call_5019f900a247472bacde0b82" )
200+
201+ const toolMessage = openAiMessages [ 1 ] as OpenAI . Chat . ChatCompletionToolMessageParam
202+ expect ( toolMessage . tool_call_id ) . toBe ( "call_5019f900a247472bacde0b82" )
203+ } )
204+
205+ it ( "should use custom normalization function when provided" , ( ) => {
206+ const anthropicMessages : Anthropic . Messages . MessageParam [ ] = [
207+ {
208+ role : "assistant" ,
209+ content : [
210+ {
211+ type : "tool_use" ,
212+ id : "toolu_123" ,
213+ name : "test_tool" ,
214+ input : { } ,
215+ } ,
216+ ] ,
217+ } ,
218+ ]
219+
220+ // Custom normalization function that prefixes with "custom_"
221+ const customNormalizer = ( id : string ) => `custom_${ id } `
222+ const openAiMessages = convertToOpenAiMessages ( anthropicMessages , { normalizeToolCallId : customNormalizer } )
223+
224+ const assistantMessage = openAiMessages [ 0 ] as OpenAI . Chat . ChatCompletionAssistantMessageParam
225+ expect ( assistantMessage . tool_calls ! [ 0 ] . id ) . toBe ( "custom_toolu_123" )
226+ } )
131227} )
0 commit comments