Finish moving types

This commit is contained in:
mudler
2025-03-23 21:17:59 +01:00
committed by Ettore Di Giacinto
parent f0b8bfb4f4
commit 75a8d63e83
50 changed files with 568 additions and 467 deletions

View File

@@ -7,53 +7,15 @@ import (
"os"
"github.com/mudler/LocalAgent/core/action"
"github.com/mudler/LocalAgent/core/types"
"github.com/mudler/LocalAgent/pkg/xlog"
"github.com/sashabaranov/go-openai"
)
type ActionState struct {
ActionCurrentState
action.ActionResult
}
type ActionCurrentState struct {
Action Action
Params action.ActionParams
Reasoning string
}
// Actions is something the agent can do
type Action interface {
Run(ctx context.Context, action action.ActionParams) (action.ActionResult, error)
Definition() action.ActionDefinition
Plannable() bool
}
type Actions []Action
func (a Actions) ToTools() []openai.Tool {
tools := []openai.Tool{}
for _, action := range a {
tools = append(tools, openai.Tool{
Type: openai.ToolTypeFunction,
Function: action.Definition().ToFunctionDefinition(),
})
}
return tools
}
func (a Actions) Find(name string) Action {
for _, action := range a {
if action.Definition().Name.Is(name) {
return action
}
}
return nil
}
type decisionResult struct {
actionParams action.ActionParams
actionParams types.ActionParams
message string
actioName string
}
@@ -85,7 +47,7 @@ func (a *Agent) decision(
return &decisionResult{message: msg.Content}, nil
}
params := action.ActionParams{}
params := types.ActionParams{}
if err := params.Read(msg.ToolCalls[0].Function.Arguments); err != nil {
return nil, err
}
@@ -173,7 +135,7 @@ func (m Messages) IsLastMessageFromRole(role string) bool {
return m[len(m)-1].Role == role
}
func (a *Agent) generateParameters(ctx context.Context, pickTemplate string, act Action, c []openai.ChatCompletionMessage, reasoning string) (*decisionResult, error) {
func (a *Agent) generateParameters(ctx context.Context, pickTemplate string, act types.Action, c []openai.ChatCompletionMessage, reasoning string) (*decisionResult, error) {
stateHUD, err := renderTemplate(pickTemplate, a.prepareHUD(), a.availableActions(), reasoning)
if err != nil {
@@ -212,7 +174,7 @@ func (a *Agent) generateParameters(ctx context.Context, pickTemplate string, act
)
}
func (a *Agent) handlePlanning(ctx context.Context, job *Job, chosenAction Action, actionParams action.ActionParams, reasoning string, pickTemplate string) error {
func (a *Agent) handlePlanning(ctx context.Context, job *types.Job, chosenAction types.Action, actionParams types.ActionParams, reasoning string, pickTemplate string) error {
// Planning: run all the actions in sequence
if !chosenAction.Definition().Name.Is(action.PlanActionName) {
xlog.Debug("no plan action")
@@ -225,9 +187,17 @@ func (a *Agent) handlePlanning(ctx context.Context, job *Job, chosenAction Actio
return fmt.Errorf("error unmarshalling plan result: %w", err)
}
stateResult := ActionState{ActionCurrentState{chosenAction, actionParams, reasoning}, action.ActionResult{
Result: fmt.Sprintf("planning %s, subtasks: %+v", planResult.Goal, planResult.Subtasks),
}}
stateResult := types.ActionState{
ActionCurrentState: types.ActionCurrentState{
Job: job,
Action: chosenAction,
Params: actionParams,
Reasoning: reasoning,
},
ActionResult: types.ActionResult{
Result: fmt.Sprintf("planning %s, subtasks: %+v", planResult.Goal, planResult.Subtasks),
},
}
job.Result.SetResult(stateResult)
job.CallbackWithResult(stateResult)
@@ -258,8 +228,23 @@ func (a *Agent) handlePlanning(ctx context.Context, job *Job, chosenAction Actio
}
actionParams = params.actionParams
if !job.Callback(ActionCurrentState{subTaskAction, actionParams, subTaskReasoning}) {
job.Result.SetResult(ActionState{ActionCurrentState{chosenAction, actionParams, subTaskReasoning}, action.ActionResult{Result: "stopped by callback"}})
if !job.Callback(types.ActionCurrentState{
Job: job,
Action: subTaskAction,
Params: actionParams,
Reasoning: subTaskReasoning,
}) {
job.Result.SetResult(types.ActionState{
ActionCurrentState: types.ActionCurrentState{
Job: job,
Action: chosenAction,
Params: actionParams,
Reasoning: subTaskReasoning,
},
ActionResult: types.ActionResult{
Result: "stopped by callback",
},
})
job.Result.Conversation = a.currentConversation
job.Result.Finish(nil)
break
@@ -270,7 +255,15 @@ func (a *Agent) handlePlanning(ctx context.Context, job *Job, chosenAction Actio
return fmt.Errorf("error running action: %w", err)
}
stateResult := ActionState{ActionCurrentState{subTaskAction, actionParams, subTaskReasoning}, result}
stateResult := types.ActionState{
ActionCurrentState: types.ActionCurrentState{
Job: job,
Action: subTaskAction,
Params: actionParams,
Reasoning: subTaskReasoning,
},
ActionResult: result,
}
job.Result.SetResult(stateResult)
job.CallbackWithResult(stateResult)
xlog.Debug("[subtask] Action executed", "agent", a.Character.Name, "action", subTaskAction.Definition().Name, "result", result)
@@ -280,10 +273,10 @@ func (a *Agent) handlePlanning(ctx context.Context, job *Job, chosenAction Actio
return nil
}
func (a *Agent) availableActions() Actions {
func (a *Agent) availableActions() types.Actions {
// defaultActions := append(a.options.userActions, action.NewReply())
addPlanAction := func(actions Actions) Actions {
addPlanAction := func(actions types.Actions) types.Actions {
if !a.options.canPlan {
return actions
}
@@ -341,7 +334,7 @@ func (a *Agent) prepareHUD() (promptHUD *PromptHUD) {
}
// pickAction picks an action based on the conversation
func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.ChatCompletionMessage) (Action, action.ActionParams, string, error) {
func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.ChatCompletionMessage) (types.Action, types.ActionParams, string, error) {
c := messages
if !a.options.forceReasoning {
@@ -390,7 +383,7 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.
// and then use the reply to get the action
thought, err := a.decision(ctx,
c,
Actions{action.NewReasoning()}.ToTools(),
types.Actions{action.NewReasoning()}.ToTools(),
action.NewReasoning().Definition().Name)
if err != nil {
return nil, nil, "", err
@@ -421,7 +414,7 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.
Role: "system",
Content: "Given the assistant thought, pick the relevant action: " + reason,
}),
Actions{intentionsTools}.ToTools(),
types.Actions{intentionsTools}.ToTools(),
intentionsTools.Definition().Name)
if err != nil {
return nil, nil, "", fmt.Errorf("failed to get the action tool parameters: %v", err)

View File

@@ -10,6 +10,7 @@ import (
"github.com/mudler/LocalAgent/pkg/xlog"
"github.com/mudler/LocalAgent/core/action"
"github.com/mudler/LocalAgent/core/types"
"github.com/mudler/LocalAgent/pkg/llm"
"github.com/sashabaranov/go-openai"
)
@@ -25,21 +26,21 @@ type Agent struct {
options *options
Character Character
client *openai.Client
jobQueue chan *Job
actionContext *action.ActionContext
context *action.ActionContext
jobQueue chan *types.Job
actionContext *types.ActionContext
context *types.ActionContext
currentReasoning string
currentState *action.AgentInternalState
nextAction Action
nextActionParams *action.ActionParams
nextAction types.Action
nextActionParams *types.ActionParams
currentConversation Messages
selfEvaluationInProgress bool
pause bool
newConversations chan openai.ChatCompletionMessage
mcpActions Actions
mcpActions types.Actions
}
type RAGDB interface {
@@ -64,12 +65,12 @@ func New(opts ...Option) (*Agent, error) {
ctx, cancel := context.WithCancel(c)
a := &Agent{
jobQueue: make(chan *Job),
jobQueue: make(chan *types.Job),
options: options,
client: client,
Character: options.character,
currentState: &action.AgentInternalState{},
context: action.NewContext(ctx, cancel),
context: types.NewActionContext(ctx, cancel),
}
if a.options.statefile != "" {
@@ -130,18 +131,18 @@ func (a *Agent) ConversationChannel() chan openai.ChatCompletionMessage {
// Ask is a pre-emptive, blocking call that returns the response as soon as it's ready.
// It discards any other computation.
func (a *Agent) Ask(opts ...JobOption) *JobResult {
func (a *Agent) Ask(opts ...types.JobOption) *types.JobResult {
xlog.Debug("Agent Ask()", "agent", a.Character.Name, "model", a.options.LLMAPI.Model)
defer func() {
xlog.Debug("Agent has finished being asked", "agent", a.Character.Name)
}()
//a.StopAction()
j := NewJob(
j := types.NewJob(
append(
opts,
WithReasoningCallback(a.options.reasoningCallback),
WithResultCallback(a.options.resultCallback),
types.WithReasoningCallback(a.options.reasoningCallback),
types.WithResultCallback(a.options.resultCallback),
)...,
)
a.jobQueue <- j
@@ -224,12 +225,12 @@ func (a *Agent) Memory() RAGDB {
return a.options.ragdb
}
func (a *Agent) runAction(chosenAction Action, params action.ActionParams) (result action.ActionResult, err error) {
func (a *Agent) runAction(chosenAction types.Action, params types.ActionParams) (result types.ActionResult, err error) {
for _, act := range a.availableActions() {
if act.Definition().Name == chosenAction.Definition().Name {
res, err := act.Run(a.actionContext, params)
if err != nil {
return action.ActionResult{}, fmt.Errorf("error running action: %w", err)
return types.ActionResult{}, fmt.Errorf("error running action: %w", err)
}
result = res
@@ -244,7 +245,7 @@ func (a *Agent) runAction(chosenAction Action, params action.ActionParams) (resu
err = params.Unmarshal(&state)
if err != nil {
return action.ActionResult{}, fmt.Errorf("error unmarshalling state of the agent: %w", err)
return types.ActionResult{}, fmt.Errorf("error unmarshalling state of the agent: %w", err)
}
// update the current state with the one we just got from the action
a.currentState = &state
@@ -252,7 +253,7 @@ func (a *Agent) runAction(chosenAction Action, params action.ActionParams) (resu
// update the state file
if a.options.statefile != "" {
if err := a.SaveState(a.options.statefile); err != nil {
return action.ActionResult{}, err
return types.ActionResult{}, err
}
}
}
@@ -348,7 +349,7 @@ func extractImageContent(message openai.ChatCompletionMessage) (imageURL, text s
return
}
func (a *Agent) processUserInputs(job *Job, role string) {
func (a *Agent) processUserInputs(job *types.Job, role string) {
noNewMessage := job.Text == "" && job.Image == ""
onlyText := job.Text != "" && job.Image == ""
@@ -434,7 +435,7 @@ func (a *Agent) processUserInputs(job *Job, role string) {
}
}
func (a *Agent) consumeJob(job *Job, role string) {
func (a *Agent) consumeJob(job *types.Job, role string) {
a.Lock()
paused := a.pause
a.Unlock()
@@ -451,10 +452,10 @@ func (a *Agent) consumeJob(job *Job, role string) {
a.Lock()
// Set the action context
ctx, cancel := context.WithCancel(context.Background())
a.actionContext = action.NewContext(ctx, cancel)
a.actionContext = types.NewActionContext(ctx, cancel)
a.selfEvaluationInProgress = selfEvaluation
if len(job.conversationHistory) != 0 {
a.currentConversation = job.conversationHistory
if len(job.ConversationHistory) != 0 {
a.currentConversation = job.ConversationHistory
}
a.Unlock()
@@ -493,9 +494,9 @@ func (a *Agent) consumeJob(job *Job, role string) {
}
// choose an action first
var chosenAction Action
var chosenAction types.Action
var reasoning string
var actionParams action.ActionParams
var actionParams types.ActionParams
if a.nextAction != nil {
// if we are being re-evaluated, we already have the action
@@ -576,8 +577,19 @@ func (a *Agent) consumeJob(job *Job, role string) {
return
}
if !job.Callback(ActionCurrentState{chosenAction, actionParams, reasoning}) {
job.Result.SetResult(ActionState{ActionCurrentState{chosenAction, actionParams, reasoning}, action.ActionResult{Result: "stopped by callback"}})
if !job.Callback(types.ActionCurrentState{
Job: job,
Action: chosenAction,
Params: actionParams,
Reasoning: reasoning}) {
job.Result.SetResult(types.ActionState{
ActionCurrentState: types.ActionCurrentState{
Job: job,
Action: chosenAction,
Params: actionParams,
Reasoning: reasoning,
},
ActionResult: types.ActionResult{Result: "stopped by callback"}})
job.Result.Conversation = a.currentConversation
job.Result.Finish(nil)
return
@@ -622,7 +634,15 @@ func (a *Agent) consumeJob(job *Job, role string) {
result.Result = fmt.Sprintf("Error running tool: %v", err)
}
stateResult := ActionState{ActionCurrentState{chosenAction, actionParams, reasoning}, result}
stateResult := types.ActionState{
ActionCurrentState: types.ActionCurrentState{
Job: job,
Action: chosenAction,
Params: actionParams,
Reasoning: reasoning,
},
ActionResult: result,
}
job.Result.SetResult(stateResult)
job.CallbackWithResult(stateResult)
xlog.Debug("Action executed", "agent", a.Character.Name, "action", chosenAction.Definition().Name, "result", result)
@@ -781,7 +801,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
job.Result.Finish(nil)
}
func (a *Agent) addFunctionResultToConversation(chosenAction Action, actionParams action.ActionParams, result action.ActionResult) {
func (a *Agent) addFunctionResultToConversation(chosenAction types.Action, actionParams types.ActionParams, result types.ActionResult) {
// calling the function
a.currentConversation = append(a.currentConversation, openai.ChatCompletionMessage{
Role: "assistant",
@@ -847,10 +867,10 @@ func (a *Agent) periodicallyRun(timer *time.Timer) {
// - asking the agent to do something else based on the result
// whatNext := NewJob(WithText("Decide what to do based on the state"))
whatNext := NewJob(
WithText(innerMonologueTemplate),
WithReasoningCallback(a.options.reasoningCallback),
WithResultCallback(a.options.resultCallback),
whatNext := types.NewJob(
types.WithText(innerMonologueTemplate),
types.WithReasoningCallback(a.options.reasoningCallback),
types.WithResultCallback(a.options.resultCallback),
)
a.consumeJob(whatNext, SystemRole)
a.ResetConversation()
@@ -913,7 +933,7 @@ func (a *Agent) Run() error {
}
}
func (a *Agent) loop(timer *time.Timer, job *Job) {
func (a *Agent) loop(timer *time.Timer, job *types.Job) {
// Remember always to reset the timer - if we don't the agent will stop..
defer timer.Reset(a.options.periodicRuns)
// Consume the job and generate a response

View File

@@ -8,8 +8,8 @@ import (
"github.com/mudler/LocalAgent/pkg/xlog"
"github.com/mudler/LocalAgent/services/actions"
"github.com/mudler/LocalAgent/core/action"
. "github.com/mudler/LocalAgent/core/agent"
"github.com/mudler/LocalAgent/core/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/sashabaranov/go-openai/jsonschema"
@@ -19,14 +19,14 @@ const testActionResult = "In Boston it's 30C today, it's sunny, and humidity is
const testActionResult2 = "In milan it's very hot today, it is 45C and the humidity is at 200%"
const testActionResult3 = "In paris it's very cold today, it is 2C and the humidity is at 10%"
var _ Action = &TestAction{}
var _ types.Action = &TestAction{}
var debugOptions = []JobOption{
WithReasoningCallback(func(state ActionCurrentState) bool {
var debugOptions = []types.JobOption{
types.WithReasoningCallback(func(state types.ActionCurrentState) bool {
xlog.Info("Reasoning", state)
return true
}),
WithResultCallback(func(state ActionState) {
types.WithResultCallback(func(state types.ActionState) {
xlog.Info("Reasoning", state.Reasoning)
xlog.Info("Action", state.Action)
xlog.Info("Result", state.Result)
@@ -41,18 +41,18 @@ func (a *TestAction) Plannable() bool {
return true
}
func (a *TestAction) Run(c context.Context, p action.ActionParams) (action.ActionResult, error) {
func (a *TestAction) Run(c context.Context, p types.ActionParams) (types.ActionResult, error) {
for k, r := range a.response {
if strings.Contains(strings.ToLower(p.String()), strings.ToLower(k)) {
return action.ActionResult{Result: r}, nil
return types.ActionResult{Result: r}, nil
}
}
return action.ActionResult{Result: "No match"}, nil
return types.ActionResult{Result: "No match"}, nil
}
func (a *TestAction) Definition() action.ActionDefinition {
return action.ActionDefinition{
func (a *TestAction) Definition() types.ActionDefinition {
return types.ActionDefinition{
Name: "get_weather",
Description: "get current weather",
Properties: map[string]jsonschema.Definition{
@@ -74,8 +74,8 @@ type FakeStoreResultAction struct {
TestAction
}
func (a *FakeStoreResultAction) Definition() action.ActionDefinition {
return action.ActionDefinition{
func (a *FakeStoreResultAction) Definition() types.ActionDefinition {
return types.ActionDefinition{
Name: "store_results",
Description: "store results permanently. Use this tool after you have a result you want to keep.",
Properties: map[string]jsonschema.Definition{
@@ -93,8 +93,8 @@ type FakeInternetAction struct {
TestAction
}
func (a *FakeInternetAction) Definition() action.ActionDefinition {
return action.ActionDefinition{
func (a *FakeInternetAction) Definition() types.ActionDefinition {
return types.ActionDefinition{
Name: "search_internet",
Description: "search on internet",
Properties: map[string]jsonschema.Definition{
@@ -127,7 +127,7 @@ var _ = Describe("Agent test", func() {
res := agent.Ask(
append(debugOptions,
WithText("what's the weather in Boston and Milano? Use celsius units"),
types.WithText("what's the weather in Boston and Milano? Use celsius units"),
)...,
)
Expect(res.Error).ToNot(HaveOccurred())
@@ -142,7 +142,7 @@ var _ = Describe("Agent test", func() {
res = agent.Ask(
append(debugOptions,
WithText("Now I want to know the weather in Paris, always use celsius units"),
types.WithText("Now I want to know the weather in Paris, always use celsius units"),
)...)
for _, r := range res.State {
@@ -173,7 +173,7 @@ var _ = Describe("Agent test", func() {
defer agent.Stop()
res := agent.Ask(
append(debugOptions,
WithText("can you get the weather in boston? Use celsius units"))...,
types.WithText("can you get the weather in boston? Use celsius units"))...,
)
reasons := []string{}
for _, r := range res.State {
@@ -196,7 +196,7 @@ var _ = Describe("Agent test", func() {
defer agent.Stop()
result := agent.Ask(
WithText("Update your goals such as you want to learn to play the guitar"),
types.WithText("Update your goals such as you want to learn to play the guitar"),
)
fmt.Printf("%+v\n", result)
Expect(result.Error).ToNot(HaveOccurred())
@@ -221,7 +221,7 @@ var _ = Describe("Agent test", func() {
defer agent.Stop()
result := agent.Ask(
WithText("plan a trip to San Francisco from Venice, Italy"),
types.WithText("plan a trip to San Francisco from Venice, Italy"),
)
Expect(len(result.State)).To(BeNumerically(">", 1))

View File

@@ -1,133 +0,0 @@
package agent
import (
"sync"
"github.com/sashabaranov/go-openai"
)
// 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)
conversationHistory []openai.ChatCompletionMessage
}
// JobResult is the result of a job
type JobResult struct {
sync.Mutex
// The result of a job
State []ActionState
Conversation []openai.ChatCompletionMessage
Response string
Error error
ready chan bool
}
type JobOption func(*Job)
func WithConversationHistory(history []openai.ChatCompletionMessage) JobOption {
return func(j *Job) {
j.conversationHistory = history
}
}
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)
}
// SetResult sets the result of a job
func (j *JobResult) SetResponse(response string) {
j.Lock()
defer j.Unlock()
j.Response = response
}
// WaitResult waits for the result of a job
func (j *JobResult) WaitResult() *JobResult {
<-j.ready
j.Lock()
defer j.Unlock()
return j
}

View File

@@ -7,12 +7,12 @@ import (
mcp "github.com/metoro-io/mcp-golang"
"github.com/metoro-io/mcp-golang/transport/http"
"github.com/mudler/LocalAgent/core/action"
"github.com/mudler/LocalAgent/core/types"
"github.com/mudler/LocalAgent/pkg/xlog"
"github.com/sashabaranov/go-openai/jsonschema"
)
var _ Action = &mcpAction{}
var _ types.Action = &mcpAction{}
type MCPServer struct {
URL string `json:"url"`
@@ -30,11 +30,11 @@ func (a *mcpAction) Plannable() bool {
return true
}
func (m *mcpAction) Run(ctx context.Context, params action.ActionParams) (action.ActionResult, error) {
func (m *mcpAction) Run(ctx context.Context, params types.ActionParams) (types.ActionResult, error) {
resp, err := m.mcpClient.CallTool(ctx, m.toolName, params)
if err != nil {
xlog.Error("Failed to call tool", "error", err.Error())
return action.ActionResult{}, err
return types.ActionResult{}, err
}
xlog.Debug("MCP response", "response", resp)
@@ -51,12 +51,12 @@ func (m *mcpAction) Run(ctx context.Context, params action.ActionParams) (action
}
}
return action.ActionResult{
return types.ActionResult{
Result: textResult,
}, nil
}
func (m *mcpAction) Definition() action.ActionDefinition {
func (m *mcpAction) Definition() types.ActionDefinition {
props := map[string]jsonschema.Definition{}
dat, err := json.Marshal(m.inputSchema.Properties)
if err != nil {
@@ -64,8 +64,8 @@ func (m *mcpAction) Definition() action.ActionDefinition {
}
json.Unmarshal(dat, &props)
return action.ActionDefinition{
Name: action.ActionDefinitionName(m.toolName),
return types.ActionDefinition{
Name: types.ActionDefinitionName(m.toolName),
Description: m.toolDescription,
Required: m.inputSchema.Required,
//Properties: ,
@@ -84,7 +84,7 @@ func (a *Agent) initMCPActions() error {
a.mcpActions = nil
var err error
generatedActions := Actions{}
generatedActions := types.Actions{}
for _, mcpServer := range a.options.mcpServers {
transport := http.NewHTTPClientTransport("/mcp")

View File

@@ -4,6 +4,8 @@ import (
"context"
"strings"
"time"
"github.com/mudler/LocalAgent/core/types"
)
type Option func(*options) error
@@ -20,7 +22,7 @@ type options struct {
character Character
randomIdentityGuidance string
randomIdentity bool
userActions Actions
userActions types.Actions
enableHUD, standaloneJob, showCharacter, enableKB, enableSummaryMemory, enableLongTermMemory bool
canStopItself bool
@@ -41,8 +43,8 @@ type options struct {
systemPrompt string
// callbacks
reasoningCallback func(ActionCurrentState) bool
resultCallback func(ActionState)
reasoningCallback func(types.ActionCurrentState) bool
resultCallback func(types.ActionState)
conversationsPath string
@@ -262,14 +264,14 @@ func WithContext(ctx context.Context) Option {
}
}
func WithAgentReasoningCallback(cb func(ActionCurrentState) bool) Option {
func WithAgentReasoningCallback(cb func(types.ActionCurrentState) bool) Option {
return func(o *options) error {
o.reasoningCallback = cb
return nil
}
}
func WithAgentResultCallback(cb func(ActionState)) Option {
func WithAgentResultCallback(cb func(types.ActionState)) Option {
return func(o *options) error {
o.resultCallback = cb
return nil
@@ -310,7 +312,7 @@ func WithRandomIdentity(guidance ...string) Option {
}
}
func WithActions(actions ...Action) Option {
func WithActions(actions ...types.Action) Option {
return func(o *options) error {
o.userActions = actions
return nil

View File

@@ -5,11 +5,11 @@ import (
"html/template"
"time"
"github.com/mudler/LocalAgent/core/action"
"github.com/mudler/LocalAgent/core/types"
"github.com/sashabaranov/go-openai"
)
func renderTemplate(templ string, hud *PromptHUD, actions Actions, reasoning string) (string, error) {
func renderTemplate(templ string, hud *PromptHUD, actions types.Actions, reasoning string) (string, error) {
// prepare the prompt
prompt := bytes.NewBuffer([]byte{})
@@ -19,14 +19,14 @@ func renderTemplate(templ string, hud *PromptHUD, actions Actions, reasoning str
}
// Get all the actions definitions
definitions := []action.ActionDefinition{}
definitions := []types.ActionDefinition{}
for _, m := range actions {
definitions = append(definitions, m.Definition())
}
err = promptTemplate.Execute(prompt, struct {
HUD *PromptHUD
Actions []action.ActionDefinition
Actions []types.ActionDefinition
Reasoning string
Messages []openai.ChatCompletionMessage
Time string