@@ -88,6 +88,14 @@ func mapResponsesRequestToChatCompletions(original []byte) ([]byte, error) {
8888 mapped ["max_tokens" ] = v
8989 }
9090
91+ // Map tools and tool_choice if present
92+ if v , ok := req ["tools" ]; ok {
93+ mapped ["tools" ] = v
94+ }
95+ if v , ok := req ["tool_choice" ]; ok {
96+ mapped ["tool_choice" ] = v
97+ }
98+
9199 return json .Marshal (mapped )
92100}
93101
@@ -117,23 +125,75 @@ func mapChatCompletionToResponses(chatCompletionJSON []byte) ([]byte, error) {
117125 return nil , err
118126 }
119127
120- content := ""
121- stopReason := "stop"
122- if len (parsed .Choices ) > 0 {
123- content = parsed .Choices [0 ].Message .Content
124- if parsed .Choices [0 ].FinishReason != "" {
125- stopReason = parsed .Choices [0 ].FinishReason
128+ // Also parse generically to inspect tool calls
129+ var generic map [string ]interface {}
130+ _ = json .Unmarshal (chatCompletionJSON , & generic )
131+
132+ var output []map [string ]interface {}
133+ if len (parsed .Choices ) > 0 && parsed .Choices [0 ].Message .Content != "" {
134+ output = append (output , map [string ]interface {}{
135+ "type" : "message" ,
136+ "role" : "assistant" ,
137+ "content" : parsed .Choices [0 ].Message .Content ,
138+ })
139+ }
140+
141+ // Modern tool_calls
142+ if chs , ok := generic ["choices" ].([]interface {}); ok && len (chs ) > 0 {
143+ if ch , ok := chs [0 ].(map [string ]interface {}); ok {
144+ if msg , ok := ch ["message" ].(map [string ]interface {}); ok {
145+ if tcs , ok := msg ["tool_calls" ].([]interface {}); ok {
146+ for _ , tci := range tcs {
147+ if tc , ok := tci .(map [string ]interface {}); ok {
148+ name := ""
149+ args := ""
150+ if fn , ok := tc ["function" ].(map [string ]interface {}); ok {
151+ if n , ok := fn ["name" ].(string ); ok {
152+ name = n
153+ }
154+ if a , ok := fn ["arguments" ].(string ); ok {
155+ args = a
156+ }
157+ }
158+ output = append (output , map [string ]interface {}{
159+ "type" : "tool_call" ,
160+ "tool_name" : name ,
161+ "arguments" : args ,
162+ })
163+ }
164+ }
165+ }
166+ // Legacy function_call
167+ if fc , ok := msg ["function_call" ].(map [string ]interface {}); ok {
168+ name := ""
169+ args := ""
170+ if n , ok := fc ["name" ].(string ); ok {
171+ name = n
172+ }
173+ if a , ok := fc ["arguments" ].(string ); ok {
174+ args = a
175+ }
176+ output = append (output , map [string ]interface {}{
177+ "type" : "tool_call" ,
178+ "tool_name" : name ,
179+ "arguments" : args ,
180+ })
181+ }
182+ }
126183 }
127184 }
128185
186+ stopReason := "stop"
187+ if len (parsed .Choices ) > 0 && parsed .Choices [0 ].FinishReason != "" {
188+ stopReason = parsed .Choices [0 ].FinishReason
189+ }
190+
129191 out := map [string ]interface {}{
130- "id" : parsed .ID ,
131- "object" : "response" ,
132- "created" : parsed .Created ,
133- "model" : parsed .Model ,
134- "output" : []map [string ]interface {}{
135- {"type" : "message" , "role" : "assistant" , "content" : content },
136- },
192+ "id" : parsed .ID ,
193+ "object" : "response" ,
194+ "created" : parsed .Created ,
195+ "model" : parsed .Model ,
196+ "output" : output ,
137197 "stop_reason" : stopReason ,
138198 "usage" : map [string ]int {
139199 "input_tokens" : parsed .Usage .PromptTokens ,
@@ -160,9 +220,10 @@ func translateSSEChunkToResponses(chunk []byte) ([][]byte, bool) {
160220 created , _ := parsed ["created" ].(float64 )
161221 // Emit a created event only once per stream (handled by caller)
162222
163- // Extract content delta and finish_reason
223+ // Extract content delta, tool call deltas, and finish_reason
164224 var deltaText string
165225 var finish string
226+ var toolEvents [][]byte
166227 if arr , ok := parsed ["choices" ].([]interface {}); ok && len (arr ) > 0 {
167228 if ch , ok := arr [0 ].(map [string ]interface {}); ok {
168229 if fr , ok := ch ["finish_reason" ].(string ); ok && fr != "" {
@@ -172,11 +233,45 @@ func translateSSEChunkToResponses(chunk []byte) ([][]byte, bool) {
172233 if c , ok := d ["content" ].(string ); ok {
173234 deltaText = c
174235 }
236+ if tcs , ok := d ["tool_calls" ].([]interface {}); ok {
237+ for _ , tci := range tcs {
238+ if tc , ok := tci .(map [string ]interface {}); ok {
239+ ev := map [string ]interface {}{"type" : "response.tool_calls.delta" }
240+ if idx , ok := tc ["index" ].(float64 ); ok {
241+ ev ["index" ] = int (idx )
242+ }
243+ if fn , ok := tc ["function" ].(map [string ]interface {}); ok {
244+ if n , ok := fn ["name" ].(string ); ok && n != "" {
245+ ev ["name" ] = n
246+ }
247+ if a , ok := fn ["arguments" ].(string ); ok && a != "" {
248+ ev ["arguments_delta" ] = a
249+ }
250+ }
251+ b , _ := json .Marshal (ev )
252+ toolEvents = append (toolEvents , b )
253+ }
254+ }
255+ }
256+ if fc , ok := d ["function_call" ].(map [string ]interface {}); ok {
257+ ev := map [string ]interface {}{"type" : "response.tool_calls.delta" }
258+ if n , ok := fc ["name" ].(string ); ok && n != "" {
259+ ev ["name" ] = n
260+ }
261+ if a , ok := fc ["arguments" ].(string ); ok && a != "" {
262+ ev ["arguments_delta" ] = a
263+ }
264+ b , _ := json .Marshal (ev )
265+ toolEvents = append (toolEvents , b )
266+ }
175267 }
176268 }
177269 }
178270
179271 var events [][]byte
272+ if len (toolEvents ) > 0 {
273+ events = append (events , toolEvents ... )
274+ }
180275 if deltaText != "" {
181276 ev := map [string ]interface {}{
182277 "type" : "response.output_text.delta" ,
0 commit comments