mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-11-27 20:50:25 +08:00
Created an interface in aiusechat for the backend providers. Use that interface throughout the usechat code. Isolate the backend implementations to only the new file usechat-backend.go.
85 lines
2.3 KiB
Go
85 lines
2.3 KiB
Go
// Copyright 2025, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package aiusechat
|
|
|
|
import (
|
|
"github.com/wavetermdev/waveterm/pkg/aiusechat/uctypes"
|
|
)
|
|
|
|
// CombineConsecutiveSameRoleMessages combines consecutive UIMessages with the same role
|
|
// by appending their Parts together. This is useful for APIs like OpenAI that may split
|
|
// assistant messages into separate messages (e.g., one for text and one for tool calls).
|
|
func CombineConsecutiveSameRoleMessages(uiChat *uctypes.UIChat) *uctypes.UIChat {
|
|
if uiChat == nil || len(uiChat.Messages) == 0 {
|
|
return uiChat
|
|
}
|
|
|
|
combined := make([]uctypes.UIMessage, 0, len(uiChat.Messages))
|
|
var current *uctypes.UIMessage
|
|
|
|
for i := range uiChat.Messages {
|
|
msg := &uiChat.Messages[i]
|
|
|
|
if current == nil {
|
|
// First message - start a new combined message
|
|
current = &uctypes.UIMessage{
|
|
ID: msg.ID,
|
|
Role: msg.Role,
|
|
Metadata: msg.Metadata,
|
|
Parts: make([]uctypes.UIMessagePart, len(msg.Parts)),
|
|
}
|
|
copy(current.Parts, msg.Parts)
|
|
continue
|
|
}
|
|
|
|
if current.Role == msg.Role {
|
|
// Same role - append parts to current message
|
|
current.Parts = append(current.Parts, msg.Parts...)
|
|
} else {
|
|
// Different role - save current and start new
|
|
combined = append(combined, *current)
|
|
current = &uctypes.UIMessage{
|
|
ID: msg.ID,
|
|
Role: msg.Role,
|
|
Metadata: msg.Metadata,
|
|
Parts: make([]uctypes.UIMessagePart, len(msg.Parts)),
|
|
}
|
|
copy(current.Parts, msg.Parts)
|
|
}
|
|
}
|
|
|
|
// Don't forget the last message
|
|
if current != nil {
|
|
combined = append(combined, *current)
|
|
}
|
|
|
|
return &uctypes.UIChat{
|
|
ChatId: uiChat.ChatId,
|
|
APIType: uiChat.APIType,
|
|
Model: uiChat.Model,
|
|
APIVersion: uiChat.APIVersion,
|
|
Messages: combined,
|
|
}
|
|
}
|
|
|
|
|
|
// ConvertAIChatToUIChat converts an AIChat to a UIChat by routing to the appropriate
|
|
// provider-specific converter based on APIType, then combining consecutive same-role messages.
|
|
func ConvertAIChatToUIChat(aiChat *uctypes.AIChat) (*uctypes.UIChat, error) {
|
|
if aiChat == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
backend, err := GetBackendByAPIType(aiChat.APIType)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
uiChat, err := backend.ConvertAIChatToUIChat(*aiChat)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return CombineConsecutiveSameRoleMessages(uiChat), nil
|
|
}
|