Enha: address template issues
This commit is contained in:
87
bot.go
87
bot.go
@@ -67,6 +67,80 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
// cleanNullMessages removes messages with null or empty content to prevent API issues
|
||||
func cleanNullMessages(messages []models.RoleMsg) []models.RoleMsg {
|
||||
cleaned := make([]models.RoleMsg, 0, len(messages))
|
||||
for _, msg := range messages {
|
||||
// Include message if it has content or if it's a tool response (which might have tool_call_id)
|
||||
if msg.HasContent() || msg.ToolCallID != "" {
|
||||
cleaned = append(cleaned, msg)
|
||||
}
|
||||
}
|
||||
return consolidateConsecutiveAssistantMessages(cleaned)
|
||||
}
|
||||
|
||||
// consolidateConsecutiveAssistantMessages merges consecutive assistant messages into a single message
|
||||
func consolidateConsecutiveAssistantMessages(messages []models.RoleMsg) []models.RoleMsg {
|
||||
if len(messages) == 0 {
|
||||
return messages
|
||||
}
|
||||
|
||||
consolidated := make([]models.RoleMsg, 0, len(messages))
|
||||
currentAssistantMsg := models.RoleMsg{}
|
||||
isBuildingAssistantMsg := false
|
||||
|
||||
for i := 0; i < len(messages); i++ {
|
||||
msg := messages[i]
|
||||
|
||||
if msg.Role == cfg.AssistantRole || msg.Role == cfg.WriteNextMsgAsCompletionAgent {
|
||||
// If this is an assistant message, start or continue building
|
||||
if !isBuildingAssistantMsg {
|
||||
// Start accumulating assistant message
|
||||
currentAssistantMsg = msg.Copy()
|
||||
isBuildingAssistantMsg = true
|
||||
} else {
|
||||
// Continue accumulating - append content to the current assistant message
|
||||
if currentAssistantMsg.IsContentParts() || msg.IsContentParts() {
|
||||
// Handle structured content
|
||||
if !currentAssistantMsg.IsContentParts() {
|
||||
// Convert existing content to content parts
|
||||
currentAssistantMsg = models.NewMultimodalMsg(currentAssistantMsg.Role, []interface{}{models.TextContentPart{Type: "text", Text: currentAssistantMsg.Content}})
|
||||
currentAssistantMsg.ToolCallID = msg.ToolCallID
|
||||
}
|
||||
if msg.IsContentParts() {
|
||||
currentAssistantMsg.ContentParts = append(currentAssistantMsg.ContentParts, msg.GetContentParts()...)
|
||||
} else if msg.Content != "" {
|
||||
currentAssistantMsg.AddTextPart(msg.Content)
|
||||
}
|
||||
} else {
|
||||
// Simple string content
|
||||
if currentAssistantMsg.Content != "" {
|
||||
currentAssistantMsg.Content += "\n" + msg.Content
|
||||
} else {
|
||||
currentAssistantMsg.Content = msg.Content
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This is not an assistant message
|
||||
// If we were building an assistant message, add it to the result
|
||||
if isBuildingAssistantMsg {
|
||||
consolidated = append(consolidated, currentAssistantMsg)
|
||||
isBuildingAssistantMsg = false
|
||||
}
|
||||
// Add the non-assistant message
|
||||
consolidated = append(consolidated, msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Don't forget the last assistant message if we were building one
|
||||
if isBuildingAssistantMsg {
|
||||
consolidated = append(consolidated, currentAssistantMsg)
|
||||
}
|
||||
|
||||
return consolidated
|
||||
}
|
||||
|
||||
// GetLogLevel returns the current log level as a string
|
||||
func GetLogLevel() string {
|
||||
level := logLevel.Level()
|
||||
@@ -481,6 +555,10 @@ out:
|
||||
Role: botPersona, Content: respText.String(),
|
||||
})
|
||||
}
|
||||
|
||||
// Clean null/empty messages to prevent API issues with endpoints like llama.cpp jinja template
|
||||
cleanChatBody()
|
||||
|
||||
colorText()
|
||||
updateStatusLine()
|
||||
// bot msg is done;
|
||||
@@ -492,6 +570,15 @@ out:
|
||||
findCall(respText.String(), toolResp.String(), tv)
|
||||
}
|
||||
|
||||
// cleanChatBody removes messages with null or empty content to prevent API issues
|
||||
func cleanChatBody() {
|
||||
if chatBody != nil && chatBody.Messages != nil {
|
||||
originalLen := len(chatBody.Messages)
|
||||
chatBody.Messages = cleanNullMessages(chatBody.Messages)
|
||||
logger.Debug("cleaned chat body", "original_len", originalLen, "new_len", len(chatBody.Messages))
|
||||
}
|
||||
}
|
||||
|
||||
func findCall(msg, toolCall string, tv *tview.TextView) {
|
||||
fc := &models.FuncCall{}
|
||||
if toolCall != "" {
|
||||
|
||||
4
llm.go
4
llm.go
@@ -236,6 +236,8 @@ func (op LCPChat) FormMsg(msg, role string, resume bool) (io.Reader, error) {
|
||||
bodyCopy.Messages[i] = msg
|
||||
}
|
||||
}
|
||||
// Clean null/empty messages to prevent API issues
|
||||
bodyCopy.Messages = cleanNullMessages(bodyCopy.Messages)
|
||||
req := models.OpenAIReq{
|
||||
ChatBody: bodyCopy,
|
||||
Tools: nil,
|
||||
@@ -385,6 +387,8 @@ func (ds DeepSeekerChat) FormMsg(msg, role string, resume bool) (io.Reader, erro
|
||||
bodyCopy.Messages[i] = msg
|
||||
}
|
||||
}
|
||||
// Clean null/empty messages to prevent API issues
|
||||
bodyCopy.Messages = cleanNullMessages(bodyCopy.Messages)
|
||||
dsBody := models.NewDSChatReq(*bodyCopy)
|
||||
data, err := json.Marshal(dsBody)
|
||||
if err != nil {
|
||||
|
||||
@@ -230,6 +230,38 @@ func NewMultimodalMsg(role string, contentParts []interface{}) RoleMsg {
|
||||
}
|
||||
}
|
||||
|
||||
// HasContent returns true if the message has either string content or structured content parts
|
||||
func (m RoleMsg) HasContent() bool {
|
||||
if m.Content != "" {
|
||||
return true
|
||||
}
|
||||
if m.hasContentParts && len(m.ContentParts) > 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsContentParts returns true if the message uses structured content parts
|
||||
func (m RoleMsg) IsContentParts() bool {
|
||||
return m.hasContentParts
|
||||
}
|
||||
|
||||
// GetContentParts returns the content parts of the message
|
||||
func (m RoleMsg) GetContentParts() []interface{} {
|
||||
return m.ContentParts
|
||||
}
|
||||
|
||||
// Copy creates a copy of the RoleMsg with all fields
|
||||
func (m RoleMsg) Copy() RoleMsg {
|
||||
return RoleMsg{
|
||||
Role: m.Role,
|
||||
Content: m.Content,
|
||||
ContentParts: m.ContentParts,
|
||||
ToolCallID: m.ToolCallID,
|
||||
hasContentParts: m.hasContentParts,
|
||||
}
|
||||
}
|
||||
|
||||
// AddTextPart adds a text content part to the message
|
||||
func (m *RoleMsg) AddTextPart(text string) {
|
||||
if !m.hasContentParts {
|
||||
|
||||
Reference in New Issue
Block a user