109 lines
3.2 KiB
Go
109 lines
3.2 KiB
Go
package agents
|
|
|
|
import (
|
|
"strings"
|
|
|
|
gollm "gitea.stevedudenhoeffer.com/steve/go-llm"
|
|
)
|
|
|
|
// TidBit is a small piece of information that the AI has learned.
|
|
type TidBit struct {
|
|
Info string `json:"info"`
|
|
Source string `json:"source"`
|
|
}
|
|
|
|
type Knowledge struct {
|
|
// OriginalQuestions are the questions that was asked first to the AI before any processing was done.
|
|
OriginalQuestions []string `json:"originalQuestions"`
|
|
|
|
// RemainingQuestions is the questions that are left to find answers for.
|
|
RemainingQuestions []string `json:"remainingQuestions"`
|
|
|
|
// NotesToSelf are notes that the AI has made for itself.
|
|
NotesToSelf []string `json:"notesToSelf"`
|
|
|
|
// CurrentObjectives are the objectives that the AI is currently working on.
|
|
CurrentObjectives []string `json:"currentObjectives"`
|
|
|
|
// Knowledge are the tidbits of information that the AI has learned.
|
|
Knowledge []TidBit `json:"knowledge"`
|
|
}
|
|
|
|
func (k Knowledge) ToSystemMessage() gollm.Message {
|
|
var sources = map[string][]string{}
|
|
|
|
for _, t := range k.Knowledge {
|
|
sources[t.Source] = append(sources[t.Source], t.Info)
|
|
}
|
|
|
|
var msg string
|
|
|
|
if len(k.OriginalQuestions) > 0 {
|
|
msg += "Original questions asked:\n - " + strings.Join(k.OriginalQuestions, "\n - ") + "\n"
|
|
}
|
|
|
|
if len(k.NotesToSelf) > 0 {
|
|
msg += "Notes to self:\n - " + strings.Join(k.NotesToSelf, "\n - ") + "\n"
|
|
}
|
|
|
|
if len(sources) > 0 {
|
|
msg += "Learned information:\n"
|
|
for source, info := range sources {
|
|
if source == "" {
|
|
source = "(unsourced)"
|
|
}
|
|
msg += " - From " + source + ":\n - " + strings.Join(info, "\n - ") + "\n"
|
|
}
|
|
}
|
|
|
|
if len(k.CurrentObjectives) > 0 {
|
|
msg += "Current objectives:\n - " + strings.Join(k.CurrentObjectives, "\n - ") + "\n"
|
|
}
|
|
|
|
if len(k.RemainingQuestions) > 0 {
|
|
msg += "Remaining questions:\n - " + strings.Join(k.RemainingQuestions, "\n - ") + "\n"
|
|
}
|
|
|
|
return gollm.Message{
|
|
Role: gollm.RoleSystem,
|
|
Text: msg,
|
|
}
|
|
}
|
|
|
|
// ToMessage converts the knowledge to a message that can be sent to the LLM.
|
|
func (k Knowledge) ToMessage() string {
|
|
var learned []string
|
|
for _, t := range k.Knowledge {
|
|
learned = append(learned, t.Info)
|
|
}
|
|
return "Original questions asked:\n" + strings.Join(k.OriginalQuestions, "\n") + "\n" +
|
|
"Learned information:\n" + strings.Join(learned, "\n") + "\n" +
|
|
"Remaining questions:\n" + strings.Join(k.RemainingQuestions, "\n")
|
|
}
|
|
|
|
// Absorb adds the knowledge from the other knowledge objects to this one.
|
|
// The OriginalQuestions returned will be from value of k's OriginalQuestions.
|
|
// If any absorbed knowledge has any "CurrentObjectives" set they will explicitly overwrite the current objectives in
|
|
// aggregate, all CurrentObjectives from all absorbed knowledge will be used.
|
|
// Any new Knowledge or NotesToSelf will be appended to the current Knowledge and NotesToSelf.
|
|
func (k Knowledge) Absorb(o ...Knowledge) Knowledge {
|
|
res := k
|
|
|
|
var newObjectives []string
|
|
|
|
for _, ok := range o {
|
|
if len(ok.CurrentObjectives) > 0 {
|
|
newObjectives = append(newObjectives, ok.CurrentObjectives...)
|
|
}
|
|
|
|
res.NotesToSelf = append(res.NotesToSelf, ok.NotesToSelf...)
|
|
res.Knowledge = append(res.Knowledge, ok.Knowledge...)
|
|
}
|
|
|
|
if len(newObjectives) > 0 {
|
|
res.CurrentObjectives = newObjectives
|
|
}
|
|
|
|
return res
|
|
}
|