LocalAI / core /schema /message.go
AbdulElahGwaith's picture
Upload folder using huggingface_hub
0f07ba7 verified
package schema
import (
"encoding/json"
"github.com/mudler/xlog"
"github.com/mudler/LocalAI/pkg/grpc/proto"
)
type Message struct {
// The message role
Role string `json:"role,omitempty" yaml:"role"`
// The message name (used for tools calls)
Name string `json:"name,omitempty" yaml:"name"`
// The message content
Content interface{} `json:"content" yaml:"content"`
StringContent string `json:"string_content,omitempty" yaml:"string_content,omitempty"`
StringImages []string `json:"string_images,omitempty" yaml:"string_images,omitempty"`
StringVideos []string `json:"string_videos,omitempty" yaml:"string_videos,omitempty"`
StringAudios []string `json:"string_audios,omitempty" yaml:"string_audios,omitempty"`
// A result of a function call
FunctionCall interface{} `json:"function_call,omitempty" yaml:"function_call,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty" yaml:"tool_call,omitempty"`
// Reasoning content extracted from <thinking>...</thinking> tags
Reasoning *string `json:"reasoning,omitempty" yaml:"reasoning,omitempty"`
}
type ToolCall struct {
Index int `json:"index"`
ID string `json:"id"`
Type string `json:"type"`
FunctionCall FunctionCall `json:"function"`
}
type FunctionCall struct {
Name string `json:"name,omitempty"`
Arguments string `json:"arguments"`
}
type Messages []Message
// MessagesToProto converts schema.Message slice to proto.Message slice
// It handles content conversion, tool_calls serialization, and optional fields
func (messages Messages) ToProto() []*proto.Message {
protoMessages := make([]*proto.Message, len(messages))
for i, message := range messages {
protoMessages[i] = &proto.Message{
Role: message.Role,
Name: message.Name, // needed by function calls
}
switch ct := message.Content.(type) {
case string:
protoMessages[i].Content = ct
case []interface{}:
// If using the tokenizer template, in case of multimodal we want to keep the multimodal content as and return only strings here
data, _ := json.Marshal(ct)
resultData := []struct {
Text string `json:"text"`
}{}
json.Unmarshal(data, &resultData)
for _, r := range resultData {
protoMessages[i].Content += r.Text
}
}
// Serialize tool_calls to JSON string if present
if len(message.ToolCalls) > 0 {
toolCallsJSON, err := json.Marshal(message.ToolCalls)
if err != nil {
xlog.Warn("failed to marshal tool_calls to JSON", "error", err)
} else {
protoMessages[i].ToolCalls = string(toolCallsJSON)
}
}
// Note: tool_call_id is not in schema.Message yet
// Reasoning field is now available in schema.Message but not yet in proto.Message
}
return protoMessages
}