in llm/go-server/cmd/server.go [72:158]
func (s *ChatServer) Chat(ctx context.Context, req *chat.ChatRequest, stream chat.ChatService_ChatServer) (err error) {
defer func() {
if r := recover(); r != nil {
log.Printf("panic in Chat: %v\n%s", r, debug.Stack())
err = fmt.Errorf("internal server error")
}
}()
if len(s.llms) == 0 {
return fmt.Errorf("no LLM models are initialized")
}
if len(req.Messages) == 0 {
log.Println("Request contains no messages")
return fmt.Errorf("empty messages in request")
}
modelName := req.Model
var llm *ollama.LLM
if modelName != "" {
var ok bool
llm, ok = s.llms[modelName]
if !ok {
return fmt.Errorf("requested model '%s' is not available", modelName)
}
} else {
for name, l := range s.llms {
modelName = name
llm = l
break
}
log.Printf("No model specified, using default model: %s", modelName)
}
var messages []llms.MessageContent
for _, msg := range req.Messages {
var msgType llms.ChatMessageType
switch msg.Role {
case "human":
msgType = llms.ChatMessageTypeHuman
case "ai":
msgType = llms.ChatMessageTypeAI
case "system":
msgType = llms.ChatMessageTypeSystem
}
messageContent := llms.MessageContent{
Role: msgType,
Parts: []llms.ContentPart{
llms.TextContent{Text: msg.Content},
},
}
if msg.Bin != nil && len(msg.Bin) != 0 {
decodeByte, err := base64.StdEncoding.DecodeString(string(msg.Bin))
if err != nil {
log.Printf("GenerateContent failed: %v\n", err)
return fmt.Errorf("GenerateContent failed: %v", err)
}
imgType := http.DetectContentType(decodeByte)
messageContent.Parts = append(messageContent.Parts, llms.BinaryPart(imgType, decodeByte))
}
messages = append(messages, messageContent)
}
_, err = llm.GenerateContent(
ctx,
messages,
llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
if chunk == nil {
return nil
}
return stream.Send(&chat.ChatResponse{
Content: string(chunk),
Model: modelName,
})
}),
)
if err != nil {
log.Printf("GenerateContent failed with model %s: %v\n", modelName, err)
return fmt.Errorf("GenerateContent failed with model %s: %v", modelName, err)
}
return nil
}