diff --git a/agent/agent.go b/agent/agent.go index 29b00a1..8bd42a6 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -59,12 +59,6 @@ func New(opts ...Option) (*Agent, error) { context: action.NewContext(ctx, cancel), } - if a.options.randomIdentity { - if err = a.generateIdentity(a.options.randomIdentityGuidance); err != nil { - return a, fmt.Errorf("failed to generate identity: %v", err) - } - } - if a.options.statefile != "" { if _, err := os.Stat(a.options.statefile); err == nil { if err = a.LoadState(a.options.statefile); err != nil { @@ -73,20 +67,6 @@ func New(opts ...Option) (*Agent, error) { } } - if a.options.characterfile != "" { - if _, err := os.Stat(a.options.characterfile); err == nil { - // if there is a file, load the character back - if err = a.LoadCharacter(a.options.characterfile); err != nil { - return a, fmt.Errorf("failed to load character: %v", err) - } - } else { - // otherwise save it for next time - if err = a.SaveCharacter(a.options.characterfile); err != nil { - return a, fmt.Errorf("failed to save character: %v", err) - } - } - } - if a.options.debugMode { fmt.Println("=== Agent in Debug mode ===") fmt.Println(a.Character.String()) @@ -520,11 +500,44 @@ func (a *Agent) periodicallyRun() { // a.ResetConversation() } +func (a *Agent) prepareIdentity() error { + + if a.options.characterfile != "" { + if _, err := os.Stat(a.options.characterfile); err == nil { + // if there is a file, load the character back + if err = a.LoadCharacter(a.options.characterfile); err != nil { + return fmt.Errorf("failed to load character: %v", err) + } + } else { + if a.options.randomIdentity { + if err = a.generateIdentity(a.options.randomIdentityGuidance); err != nil { + return fmt.Errorf("failed to generate identity: %v", err) + } + } + + // otherwise save it for next time + if err = a.SaveCharacter(a.options.characterfile); err != nil { + return fmt.Errorf("failed to save character: %v", err) + } + } + } else { + if err := a.generateIdentity(a.options.randomIdentityGuidance); err != nil { + return fmt.Errorf("failed to generate identity: %v", err) + } + } + + return nil +} + func (a *Agent) Run() error { // The agent run does two things: // picks up requests from a queue // and generates a response/perform actions + if err := a.prepareIdentity(); err != nil { + return fmt.Errorf("failed to prepare identity: %v", err) + } + // It is also preemptive. // That is, it can interrupt the current action // if another one comes in. diff --git a/example/webui/agentpool.go b/example/webui/agentpool.go index 8bb0a6f..90bc788 100644 --- a/example/webui/agentpool.go +++ b/example/webui/agentpool.go @@ -19,17 +19,17 @@ type ConnectorConfig struct { type ActionsConfig string type AgentConfig struct { - Connector []ConnectorConfig `json:"connector"` - Actions []ActionsConfig `json:"actions"` + Connector []ConnectorConfig `json:"connector" form:"connector" ` + Actions []ActionsConfig `json:"actions" form:"actions"` // This is what needs to be part of ActionsConfig - Model string `json:"model"` - Name string `json:"name"` - HUD bool `json:"hud"` - Debug bool `json:"debug"` - StandaloneJob bool `json:"standalone_job"` - RandomIdentity bool `json:"random_identity"` - IdentityGuidance string `json:"identity_guidance"` - PeriodicRuns string `json:"periodic_runs"` + Model string `json:"model" form:"model"` + Name string `json:"name" form:"name"` + HUD bool `json:"hud" form:"hud"` + Debug bool `json:"debug" form:"debug"` + StandaloneJob bool `json:"standalone_job" form:"standalone_job"` + RandomIdentity bool `json:"random_identity" form:"random_identity"` + IdentityGuidance string `json:"identity_guidance" form:"identity_guidance"` + PeriodicRuns string `json:"periodic_runs" form:"periodic_runs"` } type AgentPool struct { @@ -104,13 +104,17 @@ func (a *AgentPool) List() []string { return agents } +var AvailableActions = []string{"search"} + func (a *AgentConfig) availableActions() []Action { actions := []Action{} + if len(a.Actions) == 0 { // Return search as default return []Action{external.NewSearch(3)} } for _, action := range a.Actions { + fmt.Println("Set Action", action) switch action { case "search": actions = append(actions, external.NewSearch(3)) @@ -134,6 +138,10 @@ func (a *AgentPool) startAgentWithConfig(name string, config *AgentConfig) error fmt.Println("API URL", a.apiURL) actions := config.availableActions() + + stateFile, characterFile := a.stateFiles(name) + + fmt.Println("Actions", actions) opts := []Option{ WithModel(model), WithLLMAPIURL(a.apiURL), @@ -141,8 +149,8 @@ func (a *AgentPool) startAgentWithConfig(name string, config *AgentConfig) error WithActions( actions..., ), - WithStateFile(filepath.Join(a.pooldir, fmt.Sprintf("%s.state.json", name))), - WithCharacterFile(filepath.Join(a.pooldir, fmt.Sprintf("%s.character.json", name))), + WithStateFile(stateFile), + WithCharacterFile(characterFile), WithAgentReasoningCallback(func(state ActionCurrentState) bool { fmt.Println("Reasoning", state.Reasoning) manager.Send( @@ -201,7 +209,7 @@ func (a *AgentPool) startAgentWithConfig(name string, config *AgentConfig) error go func() { if err := agent.Run(); err != nil { - panic(err) + fmt.Println("Agent stop: ", err.Error()) } }() @@ -253,7 +261,21 @@ func (a *AgentPool) Start(name string) error { return fmt.Errorf("agent %s not found", name) } +func (a *AgentPool) stateFiles(name string) (string, string) { + stateFile := filepath.Join(a.pooldir, fmt.Sprintf("%s.state.json", name)) + characterFile := filepath.Join(a.pooldir, fmt.Sprintf("%s.character.json", name)) + + return stateFile, characterFile +} + func (a *AgentPool) Remove(name string) error { + + // Cleanup character and state + stateFile, characterFile := a.stateFiles(name) + + os.Remove(stateFile) + os.Remove(characterFile) + a.Stop(name) delete(a.agents, name) delete(a.pool, name) diff --git a/example/webui/create.html b/example/webui/create.html index 1e1fef8..fed8dba 100644 --- a/example/webui/create.html +++ b/example/webui/create.html @@ -4,25 +4,38 @@