Files
promptkit/internal/domain/exchange.go

61 lines
1.6 KiB
Go

package domain
// Exchange is an immutable logical conversation ending in an assistant message.
type Exchange struct {
parent *Exchange
runID string
parentRunID string
messages []RenderedMessage
count int
}
// CaptureExchange creates a new exchange without modifying its parent.
func CaptureExchange(parent *Exchange, runID string, messages []RenderedMessage, output string) *Exchange {
turn := make([]RenderedMessage, len(messages)+1)
copyRenderedMessages(turn, messages)
turn[len(messages)] = RenderedMessage{Role: RoleAssistant, Content: output}
exchange := &Exchange{parent: parent, runID: runID, messages: turn, count: len(turn)}
if parent != nil {
exchange.parentRunID = parent.runID
exchange.count += parent.count
}
return exchange
}
// RunID returns the identity of the run that produced this exchange.
func (e *Exchange) RunID() string {
if e == nil {
return ""
}
return e.runID
}
// ParentRunID returns the immediate source run identity, if present.
func (e *Exchange) ParentRunID() string {
if e == nil {
return ""
}
return e.parentRunID
}
// MessageCount returns the number of messages in the logical history.
func (e *Exchange) MessageCount() int {
if e == nil {
return 0
}
return e.count
}
// Messages returns a detached copy of the complete logical history.
func (e *Exchange) Messages() []RenderedMessage {
if e == nil {
return nil
}
messages := make([]RenderedMessage, e.count)
for current := e; current != nil; current = current.parent {
start := current.count - len(current.messages)
copyRenderedMessages(messages[start:current.count], current.messages)
}
return messages
}