99 lines
1.8 KiB
Go
99 lines
1.8 KiB
Go
package thread
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.wntrmute.dev/kyle/goutils/die"
|
|
)
|
|
|
|
const timeFormat = "2006-01-02 15:04"
|
|
|
|
type Message struct {
|
|
ID string `json:"id"`
|
|
ThreadID string `json:"thread_id"`
|
|
Role string `json:"role"`
|
|
Status string `json:"status"`
|
|
Created int64 `json:"created"`
|
|
Updated int64 `json:"updated"`
|
|
Object string `json:"object"`
|
|
Content []struct {
|
|
Type string `json:"type"`
|
|
Text struct {
|
|
Value string `json:"value"`
|
|
Annotations []any `json:"annotations"`
|
|
} `json:"text"`
|
|
} `json:"content"`
|
|
}
|
|
|
|
func (m *Message) Date() time.Time {
|
|
return time.Unix(m.Created/1000, 0)
|
|
}
|
|
|
|
func (m *Message) Header() string {
|
|
role := m.Role
|
|
switch role {
|
|
case "user":
|
|
role = strings.ToTitle(os.Getenv("USER"))
|
|
case "assistant":
|
|
role = "LLM"
|
|
default:
|
|
// nothing
|
|
}
|
|
return fmt.Sprintf("[%s] **%s**\n", m.Date().Format(timeFormat), m.Role)
|
|
}
|
|
|
|
func (m *Message) Body() string {
|
|
content := []string{}
|
|
|
|
for _, contentItem := range m.Content {
|
|
// TODO: handle different content types
|
|
if contentItem.Type != "text" {
|
|
continue
|
|
}
|
|
|
|
if contentItem.Text.Annotations != nil {
|
|
log.Print("warning: annotation in content not supported")
|
|
}
|
|
|
|
content = append(content, contentItem.Text.Value)
|
|
}
|
|
|
|
return strings.Join(content, "\n\n")
|
|
}
|
|
|
|
func LoadMessages(path string) ([]*Message, error) {
|
|
messagesPath := filepath.Join(path, "messages.jsonl")
|
|
|
|
file, err := os.Open(messagesPath)
|
|
die.If(err)
|
|
defer file.Close()
|
|
|
|
jsonParser := json.NewDecoder(file)
|
|
var messages []*Message
|
|
|
|
for err == nil {
|
|
var message Message
|
|
err = jsonParser.Decode(&message)
|
|
if err == nil {
|
|
messages = append(messages, &message)
|
|
}
|
|
}
|
|
|
|
if err != io.EOF {
|
|
return nil, err
|
|
}
|
|
|
|
return messages, nil
|
|
}
|
|
|
|
func (m *Message) String() string {
|
|
return m.Header() + m.Body() + "\n"
|
|
}
|