Files
notarius/internal/modules/dnd/shared/prompt_inputs.go

94 lines
2.7 KiB
Go

package shared
import (
"bytes"
"fmt"
"sort"
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
)
func PromptInputs(sourceInput contracts.LLMInputMaterial, references contracts.ReferenceSet) contracts.LLMInputSet {
partySlot := references.Slots["party"]
if len(partySlot.Items) == 0 {
partySlot = references.Slots["roster"]
}
return contracts.LLMInputSet{
"transcript": TranscriptPromptMaterial(sourceInput),
"players": ReferencePromptMaterial("players", references.Slots["players"]),
"party": ReferencePromptMaterial("party", partySlot),
"glossary": ReferencePromptMaterial("glossary", references.Slots["glossary"]),
}
}
func TranscriptPromptMaterial(material contracts.LLMInputMaterial) contracts.LLMInputMaterial {
out := material.Clone()
out.Name = "transcript"
return out
}
func ReferencePromptMaterial(name string, slot contracts.ResolvedReferenceSlot) contracts.LLMInputMaterial {
body := ReferencePromptInput(slot)
digest := ""
originURI := ""
if len(slot.Items) == 1 {
digest = slot.Items[0].Digest
originURI = slot.Items[0].Origin.URI
}
return contracts.NewLLMInputMaterial(name, "text/plain", body, digest, originURI)
}
func ReferencePromptInput(slot contracts.ResolvedReferenceSlot) []byte {
if len(slot.Items) == 0 {
return []byte(" ")
}
items := append([]contracts.ReferenceItem(nil), slot.Items...)
sort.SliceStable(items, func(i, j int) bool {
if items[i].Origin.URI != items[j].Origin.URI {
return items[i].Origin.URI < items[j].Origin.URI
}
if items[i].Digest != items[j].Digest {
return items[i].Digest < items[j].Digest
}
if comparison := bytes.Compare(items[i].Content, items[j].Content); comparison != 0 {
return comparison < 0
}
if items[i].Origin.Type != items[j].Origin.Type {
return items[i].Origin.Type < items[j].Origin.Type
}
if items[i].MediaType != items[j].MediaType {
return items[i].MediaType < items[j].MediaType
}
return items[i].SizeBytes < items[j].SizeBytes
})
if len(items) == 1 {
return append([]byte(nil), items[0].Content...)
}
var b bytes.Buffer
for i, item := range items {
if i > 0 {
b.WriteString("\n\n")
}
fmt.Fprintf(&b, "Reference %d\n", i+1)
if item.Origin.Type != "" {
fmt.Fprintf(&b, "Origin-Type: %s\n", item.Origin.Type)
}
if item.Origin.URI != "" {
fmt.Fprintf(&b, "Origin-URI: %s\n", item.Origin.URI)
}
if item.Digest != "" {
fmt.Fprintf(&b, "Digest: %s\n", item.Digest)
}
if item.MediaType != "" {
fmt.Fprintf(&b, "Media-Type: %s\n", item.MediaType)
}
if item.SizeBytes > 0 {
fmt.Fprintf(&b, "Size-Bytes: %d\n", item.SizeBytes)
}
b.WriteString("\n")
b.Write(item.Content)
}
return b.Bytes()
}