feat: track conversations inside connectors (#92)

* switch to observer pattern

Signed-off-by: mudler <mudler@localai.io>

* keep conversation history in telegram and slack

* generalize with conversation tracker

---------

Signed-off-by: mudler <mudler@localai.io>
This commit is contained in:
Ettore Di Giacinto
2025-03-25 16:31:03 +01:00
committed by GitHub
parent 53c1554d55
commit d0cfc4c317
8 changed files with 422 additions and 92 deletions

View File

@@ -0,0 +1,75 @@
package connectors
import (
"fmt"
"sync"
"time"
"github.com/mudler/LocalAgent/pkg/xlog"
"github.com/sashabaranov/go-openai"
)
type TrackerKey interface{ ~int | ~int64 | ~string }
type ConversationTracker[K TrackerKey] struct {
convMutex sync.Mutex
currentconversation map[K][]openai.ChatCompletionMessage
lastMessageTime map[K]time.Time
lastMessageDuration time.Duration
}
func NewConversationTracker[K TrackerKey](lastMessageDuration time.Duration) *ConversationTracker[K] {
return &ConversationTracker[K]{
lastMessageDuration: lastMessageDuration,
currentconversation: map[K][]openai.ChatCompletionMessage{},
lastMessageTime: map[K]time.Time{},
}
}
func (c *ConversationTracker[K]) GetConversation(key K) []openai.ChatCompletionMessage {
// Lock the conversation mutex to update the conversation history
c.convMutex.Lock()
defer c.convMutex.Unlock()
// Clear up the conversation if the last message was sent more than lastMessageDuration ago
currentConv := []openai.ChatCompletionMessage{}
lastMessageTime := c.lastMessageTime[key]
if lastMessageTime.IsZero() {
lastMessageTime = time.Now()
}
if lastMessageTime.Add(c.lastMessageDuration).Before(time.Now()) {
currentConv = []openai.ChatCompletionMessage{}
c.lastMessageTime[key] = time.Now()
xlog.Debug("Conversation history does not exist for", "key", fmt.Sprintf("%v", key))
} else {
xlog.Debug("Conversation history exists for", "key", fmt.Sprintf("%v", key))
currentConv = append(currentConv, c.currentconversation[key]...)
}
// cleanup other conversations if older
for k := range c.currentconversation {
lastMessage, exists := c.lastMessageTime[k]
if !exists {
delete(c.currentconversation, k)
delete(c.lastMessageTime, k)
continue
}
if lastMessage.Add(c.lastMessageDuration).Before(time.Now()) {
xlog.Debug("Cleaning up conversation for", k)
delete(c.currentconversation, k)
delete(c.lastMessageTime, k)
}
}
return currentConv
}
func (c *ConversationTracker[K]) AddMessage(key K, message openai.ChatCompletionMessage) {
// Lock the conversation mutex to update the conversation history
c.convMutex.Lock()
defer c.convMutex.Unlock()
c.currentconversation[key] = append(c.currentconversation[key], message)
c.lastMessageTime[key] = time.Now()
}