Files
LocalAGI/agent/actions.go
2024-01-21 16:12:34 +01:00

98 lines
2.0 KiB
Go

package agent
import (
"context"
"fmt"
"github.com/mudler/local-agent-framework/llm"
)
type ActionContext struct {
context.Context
cancelFunc context.CancelFunc
}
// Actions is something the agent can do
type Action interface {
Description() string
ID() string
Run(map[string]string) error
}
var ErrContextCanceled = fmt.Errorf("context canceled")
func (a *Agent) Stop() {
a.context.cancelFunc()
}
func (a *Agent) Run() error {
// The agent run does two things:
// picks up requests from a queue
// and generates a response/perform actions
// It is also preemptive.
// That is, it can interrupt the current action
// if another one comes in.
// If there is no action, periodically evaluate if it has to do something on its own.
// Expose a REST API to interact with the agent to ask it things
for {
select {
case job := <-a.jobQueue:
// Consume the job and generate a response
a.consumeJob(job)
case <-a.context.Done():
// Agent has been canceled, return error
return ErrContextCanceled
}
}
}
// StopAction stops the current action
// if any. Can be called before adding a new job.
func (a *Agent) StopAction() {
if a.actionContext != nil {
a.actionContext.cancelFunc()
}
}
func (a *Agent) consumeJob(job *Job) {
// Consume the job and generate a response
// Implement your logic here
// Set the action context
ctx, cancel := context.WithCancel(context.Background())
a.actionContext = &ActionContext{
Context: ctx,
cancelFunc: cancel,
}
if job.Image != "" {
// TODO: Use llava to explain the image content
}
if job.Text == "" {
fmt.Println("no text!")
return
}
decision := struct {
Action string `json:"action"`
}{
Action: "generate_identity",
}
llm.GenerateJSON(ctx, a.client, a.options.LLMAPI.Model,
"decide which action to take give the",
&decision)
// perform the action (if any)
// or reply with a result
// if there is an action...
job.Result.SetResult("I don't know how to do that yet.")
}