@@ -10,6 +10,7 @@ import (
1010 "github.com/mudler/LocalAI/core/backend"
1111 "github.com/mudler/LocalAI/core/config"
1212 mcpTools "github.com/mudler/LocalAI/core/http/endpoints/mcp"
13+ openaiEndpoint "github.com/mudler/LocalAI/core/http/endpoints/openai"
1314 "github.com/mudler/LocalAI/core/http/middleware"
1415 "github.com/mudler/LocalAI/core/schema"
1516 "github.com/mudler/LocalAI/core/templates"
@@ -197,54 +198,25 @@ func handleAnthropicNonStream(c echo.Context, id string, input *schema.Anthropic
197198 xlog .Debug ("Anthropic MCP re-templating" , "iteration" , mcpIteration , "prompt_len" , len (predInput ))
198199 }
199200
200- images := [] string {}
201- for _ , m := range openAIReq .Messages {
202- images = append ( images , m . StringImages ... )
203- }
201+ // Populate openAIReq fields for ComputeChoices
202+ openAIReq .Tools = convertFuncsToOpenAITools ( funcs )
203+ openAIReq . ToolsChoice = input . ToolChoice
204+ openAIReq . Metadata = input . Metadata
204205
205- toolsJSON := ""
206- if len (funcs ) > 0 {
207- openAITools := make ([]functions.Tool , len (funcs ))
208- for i , f := range funcs {
209- openAITools [i ] = functions.Tool {Type : "function" , Function : f }
210- }
211- if toolsBytes , err := json .Marshal (openAITools ); err == nil {
212- toolsJSON = string (toolsBytes )
213- }
214- }
215- toolChoiceJSON := ""
216- if input .ToolChoice != nil {
217- if toolChoiceBytes , err := json .Marshal (input .ToolChoice ); err == nil {
218- toolChoiceJSON = string (toolChoiceBytes )
219- }
206+ var result string
207+ cb := func (s string , c * []schema.Choice ) {
208+ result = s
220209 }
221-
222- predFunc , err := backend .ModelInference (
223- input .Context , predInput , openAIReq .Messages , images , nil , nil , ml , cfg , cl , appConfig , nil , toolsJSON , toolChoiceJSON , nil , nil , nil , input .Metadata )
210+ choices , tokenUsage , chatDeltas , err := openaiEndpoint .ComputeChoices (openAIReq , predInput , cfg , cl , appConfig , ml , cb , nil )
224211 if err != nil {
225212 xlog .Error ("Anthropic model inference failed" , "error" , err )
226213 return sendAnthropicError (c , 500 , "api_error" , fmt .Sprintf ("model inference failed: %v" , err ))
227214 }
228-
229- const maxEmptyRetries = 5
230- var prediction backend.LLMResponse
231- var result string
232- for attempt := 0 ; attempt <= maxEmptyRetries ; attempt ++ {
233- prediction , err = predFunc ()
234- if err != nil {
235- xlog .Error ("Anthropic prediction failed" , "error" , err )
236- return sendAnthropicError (c , 500 , "api_error" , fmt .Sprintf ("prediction failed: %v" , err ))
237- }
238- result = backend .Finetune (* cfg , predInput , prediction .Response )
239- if result != "" || ! shouldUseFn {
240- break
241- }
242- xlog .Warn ("Anthropic: retrying prediction due to empty backend response" , "attempt" , attempt + 1 , "maxRetries" , maxEmptyRetries )
243- }
215+ _ = choices
244216
245217 // Try pre-parsed tool calls from C++ autoparser first, fall back to text parsing
246218 var toolCalls []functions.FuncCallResults
247- if deltaToolCalls := functions .ToolCallsFromChatDeltas (prediction . ChatDeltas ); len (deltaToolCalls ) > 0 {
219+ if deltaToolCalls := functions .ToolCallsFromChatDeltas (chatDeltas ); len (deltaToolCalls ) > 0 {
248220 xlog .Debug ("[ChatDeltas] Anthropic: using pre-parsed tool calls" , "count" , len (deltaToolCalls ))
249221 toolCalls = deltaToolCalls
250222 } else {
@@ -350,8 +322,8 @@ func handleAnthropicNonStream(c echo.Context, id string, input *schema.Anthropic
350322 StopReason : & stopReason ,
351323 Content : contentBlocks ,
352324 Usage : schema.AnthropicUsage {
353- InputTokens : prediction . Usage .Prompt ,
354- OutputTokens : prediction . Usage .Completion ,
325+ InputTokens : tokenUsage .Prompt ,
326+ OutputTokens : tokenUsage .Completion ,
355327 },
356328 }
357329
@@ -397,12 +369,6 @@ func handleAnthropicStream(c echo.Context, id string, input *schema.AnthropicReq
397369 xlog .Debug ("Anthropic MCP stream re-templating" , "iteration" , mcpIteration )
398370 }
399371
400- openAIMessages := openAIReq .Messages
401- images := []string {}
402- for _ , m := range openAIMessages {
403- images = append (images , m .StringImages ... )
404- }
405-
406372 // Track accumulated content for tool call detection
407373 accumulatedContent := ""
408374 currentBlockIndex := 0
@@ -481,38 +447,19 @@ func handleAnthropicStream(c echo.Context, id string, input *schema.AnthropicReq
481447 return true
482448 }
483449
484- toolsJSON := ""
485- if len (funcs ) > 0 {
486- openAITools := make ([]functions.Tool , len (funcs ))
487- for i , f := range funcs {
488- openAITools [i ] = functions.Tool {Type : "function" , Function : f }
489- }
490- if toolsBytes , err := json .Marshal (openAITools ); err == nil {
491- toolsJSON = string (toolsBytes )
492- }
493- }
494- toolChoiceJSON := ""
495- if input .ToolChoice != nil {
496- if toolChoiceBytes , err := json .Marshal (input .ToolChoice ); err == nil {
497- toolChoiceJSON = string (toolChoiceBytes )
498- }
499- }
450+ // Populate openAIReq fields for ComputeChoices
451+ openAIReq .Tools = convertFuncsToOpenAITools (funcs )
452+ openAIReq .ToolsChoice = input .ToolChoice
453+ openAIReq .Metadata = input .Metadata
500454
501- predFunc , err := backend .ModelInference (
502- input .Context , predInput , openAIMessages , images , nil , nil , ml , cfg , cl , appConfig , tokenCallback , toolsJSON , toolChoiceJSON , nil , nil , nil , input .Metadata )
455+ _ , tokenUsage , chatDeltas , err := openaiEndpoint .ComputeChoices (openAIReq , predInput , cfg , cl , appConfig , ml , func (s string , c * []schema.Choice ) {}, tokenCallback )
503456 if err != nil {
504457 xlog .Error ("Anthropic stream model inference failed" , "error" , err )
505458 return sendAnthropicError (c , 500 , "api_error" , fmt .Sprintf ("model inference failed: %v" , err ))
506459 }
507460
508- prediction , err := predFunc ()
509- if err != nil {
510- xlog .Error ("Anthropic stream prediction failed" , "error" , err )
511- return sendAnthropicError (c , 500 , "api_error" , fmt .Sprintf ("prediction failed: %v" , err ))
512- }
513-
514461 // Also check chat deltas for tool calls
515- if deltaToolCalls := functions .ToolCallsFromChatDeltas (prediction . ChatDeltas ); len (deltaToolCalls ) > 0 && len (collectedToolCalls ) == 0 {
462+ if deltaToolCalls := functions .ToolCallsFromChatDeltas (chatDeltas ); len (deltaToolCalls ) > 0 && len (collectedToolCalls ) == 0 {
516463 collectedToolCalls = deltaToolCalls
517464 }
518465
@@ -595,7 +542,7 @@ func handleAnthropicStream(c echo.Context, id string, input *schema.AnthropicReq
595542 StopReason : & stopReason ,
596543 },
597544 Usage : & schema.AnthropicUsage {
598- OutputTokens : prediction . Usage .Completion ,
545+ OutputTokens : tokenUsage .Completion ,
599546 },
600547 })
601548
@@ -613,6 +560,14 @@ func handleAnthropicStream(c echo.Context, id string, input *schema.AnthropicReq
613560 return nil
614561}
615562
563+ func convertFuncsToOpenAITools (funcs functions.Functions ) []functions.Tool {
564+ tools := make ([]functions.Tool , len (funcs ))
565+ for i , f := range funcs {
566+ tools [i ] = functions.Tool {Type : "function" , Function : f }
567+ }
568+ return tools
569+ }
570+
616571func sendAnthropicSSE (c echo.Context , event schema.AnthropicStreamEvent ) {
617572 data , err := json .Marshal (event )
618573 if err != nil {
0 commit comments