- compaction automatique du contexte LLM quand la taille atteint le seuil (contexte max - taille de réponse max), par résumé de l'historique ancien - filtre textuel (?q=) et pagination (20/page) de l'historique des conversations - correctif ORM : offset de pagination en base 0 - suppression d'une conversation : messages associés supprimés, session en cours annulée, popup de confirmation (ConfirmDialog) - titres de conversation nettoyés du markdown - styles des listes markdown, variante danger du bouton - go.mod/go.sum : dépendances go-rod et stealth manquantes du commit précédent
136 lines
3.7 KiB
Go
136 lines
3.7 KiB
Go
package turso
|
|
|
|
import (
|
|
"database/sql"
|
|
"log"
|
|
"strings"
|
|
|
|
"trankilou.fr/lassistanoque/backend/internal/adapter/database/orm"
|
|
"trankilou.fr/lassistanoque/backend/internal/domain"
|
|
)
|
|
|
|
type TursoChatRepository struct {
|
|
db *sql.DB
|
|
chatTable orm.Table[domain.Chat]
|
|
messageTable orm.Table[domain.Message]
|
|
}
|
|
|
|
func NewTursoChatRepository(db *sql.DB) *TursoChatRepository {
|
|
dialect := orm.NewSqliteDialect()
|
|
chatTable, err := orm.NewTable[domain.Chat](db, dialect, "chats")
|
|
messageTable, err := orm.NewTable[domain.Message](db, dialect, "chat_messages")
|
|
if err != nil {
|
|
log.Fatalf("error creating lasebuche agent table")
|
|
}
|
|
|
|
return &TursoChatRepository{
|
|
db: db,
|
|
chatTable: chatTable,
|
|
messageTable: messageTable,
|
|
}
|
|
}
|
|
|
|
func (r *TursoChatRepository) ListChats(userID string, teamID string, page int, query string) ([]*domain.Chat, error) {
|
|
where := "team_id=$1 and team_id in (select team_id from user_teams where user_id=$2)"
|
|
args := []any{teamID, userID}
|
|
if query != "" {
|
|
// % et _ sont des jokers LIKE : on les neutralise
|
|
escaped := strings.ReplaceAll(query, `\`, `\\`)
|
|
escaped = strings.ReplaceAll(escaped, `%`, `\%`)
|
|
escaped = strings.ReplaceAll(escaped, `_`, `\_`)
|
|
where += " and title like $3 escape '\\'"
|
|
args = append(args, "%"+escaped+"%")
|
|
}
|
|
return r.chatTable.Select(
|
|
orm.WithWhere(where, args...),
|
|
orm.WithOrder("_date_created desc"),
|
|
orm.WithPagination(page, 20),
|
|
)
|
|
}
|
|
|
|
func (r *TursoChatRepository) ListChatsWithUnfreshTitles(teamID string) ([]*domain.Chat, error) {
|
|
return r.chatTable.Select(
|
|
orm.WithWhere(
|
|
"team_id=$1 and fresh_title=0",
|
|
teamID,
|
|
),
|
|
)
|
|
}
|
|
|
|
func (r *TursoChatRepository) GetChat(userID string, teamID string, id string) (*domain.Chat, error) {
|
|
return r.chatTable.SelectOne(
|
|
"id=$1 and team_id=$2 and team_id in (select team_id from user_teams where user_id=$3)",
|
|
id,
|
|
teamID,
|
|
userID,
|
|
)
|
|
}
|
|
|
|
func (r *TursoChatRepository) CreateChat(userID string, chat *domain.Chat) (*domain.Chat, error) {
|
|
return r.chatTable.Insert(chat)
|
|
}
|
|
|
|
func (r *TursoChatRepository) UpdateChat(userID string, chat *domain.Chat) (*domain.Chat, error) {
|
|
return r.chatTable.Update(chat)
|
|
}
|
|
|
|
func (r *TursoChatRepository) DeleteChat(userID string, teamID string, id string) error {
|
|
// les messages n'ont pas de clé étrangère cascade : suppression explicite
|
|
err := r.messageTable.DeleteWhere(
|
|
"chat_id=$1 and team_id=$2 and team_id in (select team_id from user_teams where user_id=$3)",
|
|
id,
|
|
teamID,
|
|
userID,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return r.chatTable.DeleteWhere(
|
|
"id=$1 and team_id=$2 and team_id in (select team_id from user_teams where user_id=$3)",
|
|
id,
|
|
teamID,
|
|
userID,
|
|
)
|
|
}
|
|
|
|
func (r *TursoChatRepository) GetChatMessages(userID string, teamID string, chatID string, withToolCallResponses bool) ([]*domain.Message, error) {
|
|
var messages []*domain.Message
|
|
var err error
|
|
if !withToolCallResponses {
|
|
messages, err = r.messageTable.Select(
|
|
orm.WithWhere(
|
|
`chat_id=$1
|
|
and team_id=$2
|
|
and team_id in (select team_id from user_teams where user_id=$3)
|
|
and (tool_call_id='' or tool_call_id is null)`,
|
|
chatID,
|
|
teamID,
|
|
userID,
|
|
),
|
|
orm.WithOrder("_date_created asc"),
|
|
)
|
|
} else {
|
|
messages, err = r.messageTable.Select(
|
|
orm.WithWhere(
|
|
"chat_id=$1 and team_id=$2 and team_id in (select team_id from user_teams where user_id=$3)",
|
|
chatID,
|
|
teamID,
|
|
userID,
|
|
),
|
|
orm.WithOrder("_date_created asc"),
|
|
)
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, m := range messages {
|
|
m.Json2toolCall()
|
|
}
|
|
return messages, nil
|
|
}
|
|
|
|
func (r *TursoChatRepository) CreateChatMessage(userID string, message *domain.Message) (*domain.Message, error) {
|
|
message.ToolCall2Json()
|
|
return r.messageTable.Insert(message)
|
|
}
|