fix(chatpb): Update AddFile to support nested chat entries
- The AddFile function now correctly parses both the old flat log format and the new format where chats are grouped by topic. - It flattens the new structure by iterating through the 'Entries' of a chat group and appending them to the main chat list. - This allows the application to transparently load both old and new log files.
This commit is contained in:
parent
80090152a1
commit
3b6b85200d
88
helpers.go
88
helpers.go
|
@ -48,6 +48,14 @@ func UnmarshalChatsTEXT(data []byte) (*Chats, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (all *Chats) AddFile(filename string) error {
|
func (all *Chats) AddFile(filename string) error {
|
||||||
|
// Nil checks for safety.
|
||||||
|
if all == nil {
|
||||||
|
return fmt.Errorf("cannot call AddFile on a nil *Chats object")
|
||||||
|
}
|
||||||
|
if all.Chats == nil {
|
||||||
|
all.Chats = make([]*Chat, 0)
|
||||||
|
}
|
||||||
|
|
||||||
data, err := os.ReadFile(filename)
|
data, err := os.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error reading file %s: %v", filename, err)
|
log.Fatalf("Error reading file %s: %v", filename, err)
|
||||||
|
@ -60,17 +68,74 @@ func (all *Chats) AddFile(filename string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, chat := range logData.GetChats() {
|
// Iterate through the top-level messages from the source file.
|
||||||
// make a copy
|
for _, chatGroup := range logData.GetChats() {
|
||||||
newc := proto.Clone(chat).(*Chat)
|
if len(chatGroup.GetEntries()) > 0 {
|
||||||
|
// NEW FORMAT: This is a group, process its entries.
|
||||||
|
for _, entry := range chatGroup.GetEntries() {
|
||||||
|
// Convert the ChatEntry into a new Chat object for the flat list.
|
||||||
|
newChat := convertEntryToChat(entry, filename)
|
||||||
|
if newChat != nil {
|
||||||
|
newChat.VerifyUuid()
|
||||||
|
all.AppendByUuid(newChat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// OLD FORMAT: This is a single, flat Chat message.
|
||||||
|
// We still process it to handle its external content file correctly.
|
||||||
|
newChat := convertChatToChat(chatGroup, filename)
|
||||||
|
if newChat != nil {
|
||||||
|
newChat.VerifyUuid()
|
||||||
|
all.AppendByUuid(newChat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertChatToChat handles an old-style Chat message. It creates a clean
|
||||||
|
// copy and resolves its external content file.
|
||||||
|
func convertChatToChat(chat *Chat, filename string) *Chat {
|
||||||
|
if chat == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manually create a ChatEntry from the Chat fields to reuse the logic.
|
||||||
|
entry := &ChatEntry{
|
||||||
|
From: chat.GetFrom(),
|
||||||
|
Ctime: chat.GetCtime(),
|
||||||
|
Content: chat.GetContent(),
|
||||||
|
Table: chat.GetTable(),
|
||||||
|
ToolCalls: chat.GetToolCalls(),
|
||||||
|
ContentFile: chat.GetContentFile(),
|
||||||
|
Uuid: chat.GetUuid(),
|
||||||
|
Snippets: chat.GetSnippets(),
|
||||||
|
}
|
||||||
|
return convertEntryToChat(entry, filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertEntryToChat creates a new Chat object from a ChatEntry's data
|
||||||
|
// and resolves its external content file.
|
||||||
|
func convertEntryToChat(entry *ChatEntry, filename string) *Chat {
|
||||||
|
if entry == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new Chat object and copy the fields.
|
||||||
|
newChat := &Chat{
|
||||||
|
From: entry.GetFrom(),
|
||||||
|
Ctime: entry.GetCtime(),
|
||||||
|
Table: entry.GetTable(),
|
||||||
|
ToolCalls: entry.GetToolCalls(),
|
||||||
|
Snippets: entry.GetSnippets(),
|
||||||
|
Uuid: entry.GetUuid(),
|
||||||
|
}
|
||||||
|
|
||||||
// Handle content: prefer content_file, fallback to content.
|
// Handle content: prefer content_file, fallback to content.
|
||||||
var content string
|
var content string
|
||||||
if contentFile := chat.GetContentFile(); contentFile != "" {
|
if contentFile := entry.GetContentFile(); contentFile != "" {
|
||||||
// Construct the full path relative to the log file's directory.
|
|
||||||
logDir := filepath.Dir(filename)
|
logDir := filepath.Dir(filename)
|
||||||
contentPath := filepath.Join(logDir, contentFile)
|
contentPath := filepath.Join(logDir, contentFile)
|
||||||
|
|
||||||
contentBytes, err := os.ReadFile(contentPath)
|
contentBytes, err := os.ReadFile(contentPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
content = fmt.Sprintf("--- ERROR: Could not read content file %s: %v ---", contentPath, err)
|
content = fmt.Sprintf("--- ERROR: Could not read content file %s: %v ---", contentPath, err)
|
||||||
|
@ -78,16 +143,13 @@ func (all *Chats) AddFile(filename string) error {
|
||||||
content = string(contentBytes)
|
content = string(contentBytes)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback for older log formats.
|
content = entry.GetContent()
|
||||||
content = chat.GetContent()
|
|
||||||
}
|
}
|
||||||
newc.Content = content
|
newChat.Content = content
|
||||||
newc.VerifyUuid()
|
|
||||||
all.AppendNew(newc)
|
return newChat
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (chats *Chats) VerifyUuids() bool {
|
func (chats *Chats) VerifyUuids() bool {
|
||||||
var changed bool
|
var changed bool
|
||||||
|
|
Loading…
Reference in New Issue