Files
wehub-resource-sync 1b8708893a
Security Scan / tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:12:26 +08:00

108 lines
2.6 KiB
Go

package functions
import (
"strings"
pb "github.com/mudler/LocalAI/pkg/grpc/proto"
"github.com/mudler/xlog"
)
// ToolCallsFromChatDeltas extracts tool calls from C++ autoparser chat deltas.
// Returns nil if no tool calls are present in the deltas.
func ToolCallsFromChatDeltas(deltas []*pb.ChatDelta) []FuncCallResults {
if len(deltas) == 0 {
xlog.Debug("[ChatDeltas] no chat deltas received from backend")
return nil
}
// Count what's in the deltas for logging
totalContentChunks := 0
totalReasoningChunks := 0
totalToolCallChunks := 0
for _, d := range deltas {
if d.Content != "" {
totalContentChunks++
}
if d.ReasoningContent != "" {
totalReasoningChunks++
}
totalToolCallChunks += len(d.ToolCalls)
}
xlog.Debug("[ChatDeltas] received deltas from backend",
"total_deltas", len(deltas),
"content_chunks", totalContentChunks,
"reasoning_chunks", totalReasoningChunks,
"tool_call_chunks", totalToolCallChunks,
)
type toolCallAccum struct {
Name string
Arguments string
ID string
}
byIndex := map[int32]*toolCallAccum{}
var maxIndex int32 = -1
for _, d := range deltas {
for _, tc := range d.ToolCalls {
acc, ok := byIndex[tc.Index]
if !ok {
acc = &toolCallAccum{}
byIndex[tc.Index] = acc
}
if tc.Name != "" {
acc.Name = tc.Name
}
if tc.Id != "" {
acc.ID = tc.Id
}
acc.Arguments += tc.Arguments
if tc.Index > maxIndex {
maxIndex = tc.Index
}
}
}
if len(byIndex) == 0 {
xlog.Debug("[ChatDeltas] deltas present but no tool calls found, falling back to text parsing")
return nil
}
results := make([]FuncCallResults, 0, len(byIndex))
for i := int32(0); i <= maxIndex; i++ {
if acc, ok := byIndex[i]; ok {
xlog.Debug("[ChatDeltas] extracted tool call",
"index", i,
"name", acc.Name,
"id", acc.ID,
"args_length", len(acc.Arguments),
)
results = append(results, FuncCallResults{
Name: acc.Name,
Arguments: acc.Arguments,
ID: acc.ID,
})
}
}
xlog.Debug("[ChatDeltas] using C++ autoparser tool calls, skipping Go-side parsing", "count", len(results))
return results
}
// ContentFromChatDeltas extracts accumulated content text from chat deltas.
func ContentFromChatDeltas(deltas []*pb.ChatDelta) string {
var sb strings.Builder
for _, d := range deltas {
sb.WriteString(d.Content)
}
return sb.String()
}
// ReasoningFromChatDeltas extracts accumulated reasoning text from chat deltas.
func ReasoningFromChatDeltas(deltas []*pb.ChatDelta) string {
var sb strings.Builder
for _, d := range deltas {
sb.WriteString(d.ReasoningContent)
}
return sb.String()
}