package agent import ( "sync" ) // Job is a request to the agent to do something type Job struct { // The job is a request to the agent to do something // It can be a question, a command, or a request to do something // The agent will try to do it, and return a response Text string Image string // base64 encoded image Result *JobResult reasoningCallback func(ActionCurrentState) bool resultCallback func(ActionState) } // JobResult is the result of a job type JobResult struct { sync.Mutex // The result of a job State []ActionState Error error ready chan bool } type JobOption func(*Job) func WithReasoningCallback(f func(ActionCurrentState) bool) JobOption { return func(r *Job) { r.reasoningCallback = f } } func WithResultCallback(f func(ActionState)) JobOption { return func(r *Job) { r.resultCallback = f } } // NewJobResult creates a new job result func NewJobResult() *JobResult { r := &JobResult{ ready: make(chan bool), } return r } func (j *Job) Callback(stateResult ActionCurrentState) bool { if j.reasoningCallback == nil { return true } return j.reasoningCallback(stateResult) } func (j *Job) CallbackWithResult(stateResult ActionState) { if j.resultCallback == nil { return } j.resultCallback(stateResult) } func WithImage(image string) JobOption { return func(j *Job) { j.Image = image } } func WithText(text string) JobOption { return func(j *Job) { j.Text = text } } // NewJob creates a new job // It is a request to the agent to do something // It has a JobResult to get the result asynchronously // To wait for a Job result, use JobResult.WaitResult() func NewJob(opts ...JobOption) *Job { j := &Job{ Result: NewJobResult(), } for _, o := range opts { o(j) } return j } // SetResult sets the result of a job func (j *JobResult) SetResult(text ActionState) { j.Lock() defer j.Unlock() j.State = append(j.State, text) } // SetResult sets the result of a job func (j *JobResult) Finish(e error) { j.Lock() defer j.Unlock() j.Error = e close(j.ready) } // WaitResult waits for the result of a job func (j *JobResult) WaitResult() []ActionState { <-j.ready j.Lock() defer j.Unlock() return j.State }