Add default conversation title
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"code.chimeric.al/chimerical/odidere/internal/db"
|
||||
"code.chimeric.al/chimerical/odidere/internal/llm"
|
||||
)
|
||||
|
||||
// MaxTitleLength is the maximum length of a conversation title in
|
||||
// Unicode code points.
|
||||
const MaxTitleLength = 256
|
||||
|
||||
// deriveTitle returns a title from the first line of text that
|
||||
// contains non-whitespace characters. It replaces runs of
|
||||
// whitespace on that line with single spaces and truncates to
|
||||
// MaxTitleLength runes. It returns "" if text has no
|
||||
// non-whitespace characters.
|
||||
func deriveTitle(text string) string {
|
||||
for line := range strings.SplitSeq(text, "\n") {
|
||||
title := strings.Join(strings.Fields(line), " ")
|
||||
if title == "" {
|
||||
continue
|
||||
}
|
||||
if utf8.RuneCountInString(title) <= MaxTitleLength {
|
||||
return title
|
||||
}
|
||||
runes := []rune(title)
|
||||
return string(runes[:MaxTitleLength])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// setTitle derives a title from msg and sets the conversation
|
||||
// title if the conversation has no title yet. It does nothing if
|
||||
// msg has no non-whitespace text or if the conversation already
|
||||
// has a title.
|
||||
func (c *Conversation) setTitle(
|
||||
ctx context.Context,
|
||||
msg llm.Message,
|
||||
) error {
|
||||
title := deriveTitle(msg.Text())
|
||||
if title == "" {
|
||||
return nil
|
||||
}
|
||||
_, err := c.dbw.UpdateConversationTitleIfUnset(
|
||||
ctx,
|
||||
db.UpdateConversationTitleIfUnsetParams{
|
||||
Id: c.id,
|
||||
Title: title,
|
||||
},
|
||||
)
|
||||
// sql.ErrNoRows means the conversation already has a title (or
|
||||
// does not exist).
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("update conversation title: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user