Files
LocalAGI/agent/state.go
2024-04-21 15:39:38 +02:00

127 lines
2.8 KiB
Go

package agent
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"github.com/mudler/local-agent-framework/action"
"github.com/mudler/local-agent-framework/llm"
)
// PromptHUD contains
// all information that should be displayed to the LLM
// in the prompts
type PromptHUD struct {
Character Character `json:"character"`
CurrentState action.StateResult `json:"current_state"`
PermanentGoal string `json:"permanent_goal"`
ShowCharacter bool `json:"show_character"`
Time string `json:"time"`
}
type Character struct {
Name string `json:"name"`
Age any `json:"age"`
Occupation string `json:"job_occupation"`
Hobbies []string `json:"hobbies"`
MusicTaste []string `json:"favorites_music_genres"`
Sex string `json:"sex"`
}
func Load(path string) (*Character, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var c Character
err = json.Unmarshal(data, &c)
if err != nil {
return nil, err
}
return &c, nil
}
func (a *Agent) State() action.StateResult {
return *a.currentState
}
func (a *Agent) LoadState(path string) error {
data, err := os.ReadFile(path)
if err != nil {
return err
}
return json.Unmarshal(data, a.currentState)
}
func (a *Agent) LoadCharacter(path string) error {
data, err := os.ReadFile(path)
if err != nil {
return err
}
return json.Unmarshal(data, &a.Character)
}
func (a *Agent) SaveState(path string) error {
os.MkdirAll(filepath.Dir(path), 0755)
data, err := json.Marshal(a.currentState)
if err != nil {
return err
}
os.WriteFile(path, data, 0644)
return nil
}
func (a *Agent) SaveCharacter(path string) error {
os.MkdirAll(filepath.Dir(path), 0755)
data, err := json.Marshal(a.Character)
if err != nil {
return err
}
return os.WriteFile(path, data, 0644)
}
func (a *Agent) generateIdentity(guidance string) error {
if guidance == "" {
guidance = "Generate a random character for roleplaying."
}
err := llm.GenerateJSONFromStruct(a.context.Context, a.client, guidance, a.options.LLMAPI.Model, &a.options.character)
a.Character = a.options.character
if err != nil {
return fmt.Errorf("failed to generate JSON from structure: %v", err)
}
if !a.validCharacter() {
return fmt.Errorf("generated character is not valid ( guidance: %s ): %v", guidance, a.Character.String())
}
return nil
}
func (a *Agent) validCharacter() bool {
return a.Character.Name != "" &&
a.Character.Age != "" &&
a.Character.Occupation != "" &&
len(a.Character.Hobbies) != 0 &&
len(a.Character.MusicTaste) != 0
}
const fmtT = `=====================
Name: %s
Age: %s
Occupation: %s
Hobbies: %v
Music taste: %v
=====================`
func (c *Character) String() string {
return fmt.Sprintf(
fmtT,
c.Name,
c.Age,
c.Occupation,
c.Hobbies,
c.MusicTaste,
)
}