From 989a2421bae60e922d89924ddf6d0629e3a75815 Mon Sep 17 00:00:00 2001 From: mudler Date: Thu, 23 May 2024 18:58:53 +0200 Subject: [PATCH] Do not do two requests if reasoning is disabled Signed-off-by: mudler --- agent/actions.go | 27 ++++++++++++----------- agent/agent.go | 57 ++++++++++++++++++++++++++++-------------------- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/agent/actions.go b/agent/actions.go index 383243c..91d6ef6 100644 --- a/agent/actions.go +++ b/agent/actions.go @@ -192,7 +192,7 @@ func (a *Agent) prepareHUD() PromptHUD { } // pickAction picks an action based on the conversation -func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.ChatCompletionMessage) (Action, string, error) { +func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.ChatCompletionMessage) (Action, action.ActionParams, string, error) { c := messages if !a.options.forceReasoning { @@ -203,8 +203,9 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai. a.systemInternalActions().ToTools(), nil) if err != nil { - return nil, "", err + return nil, nil, "", err } + xlog.Debug(fmt.Sprintf("thought action Name: %v", thought.actioName)) xlog.Debug(fmt.Sprintf("thought message: %v", thought.message)) @@ -215,10 +216,10 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai. // LLM replied with an answer? //fmt.Errorf("no action found for intent:" + thought.actioName) - return nil, thought.message, nil + return nil, nil, thought.message, nil } xlog.Debug(fmt.Sprintf("chosenAction: %v", chosenAction.Definition().Name)) - return chosenAction, thought.message, nil + return chosenAction, thought.actionParams, thought.message, nil } var promptHUD *PromptHUD @@ -229,7 +230,7 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai. prompt, err := renderTemplate(templ, promptHUD, a.systemInternalActions(), "") if err != nil { - return nil, "", err + return nil, nil, "", err } // Get the LLM to think on what to do // and have a thought @@ -249,13 +250,13 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai. Actions{action.NewReasoning()}.ToTools(), action.NewReasoning().Definition().Name) if err != nil { - return nil, "", err + return nil, nil, "", err } reason := "" response := &action.ReasoningResponse{} if thought.actionParams != nil { if err := thought.actionParams.Unmarshal(response); err != nil { - return nil, "", err + return nil, nil, "", err } reason = response.Reasoning } @@ -280,29 +281,29 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai. Actions{intentionsTools}.ToTools(), intentionsTools.Definition().Name) if err != nil { - return nil, "", fmt.Errorf("failed to get the action tool parameters: %v", err) + return nil, nil, "", fmt.Errorf("failed to get the action tool parameters: %v", err) } actionChoice := action.IntentResponse{} if params.actionParams == nil { - return nil, params.message, nil + return nil, nil, params.message, nil } err = params.actionParams.Unmarshal(&actionChoice) if err != nil { - return nil, "", err + return nil, nil, "", err } if actionChoice.Tool == "" || actionChoice.Tool == "none" { - return nil, "", fmt.Errorf("no intent detected") + return nil, nil, "", fmt.Errorf("no intent detected") } // Find the action chosenAction := a.systemInternalActions().Find(actionChoice.Tool) if chosenAction == nil { - return nil, "", fmt.Errorf("no action found for intent:" + actionChoice.Tool) + return nil, nil, "", fmt.Errorf("no action found for intent:" + actionChoice.Tool) } - return chosenAction, actionChoice.Reasoning, nil + return chosenAction, nil, actionChoice.Reasoning, nil } diff --git a/agent/agent.go b/agent/agent.go index 23e5ff4..ca09245 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -33,6 +33,7 @@ type Agent struct { currentReasoning string currentState *action.StateResult nextAction Action + nextActionParams *action.ActionParams currentConversation Messages selfEvaluationInProgress bool pause bool @@ -182,10 +183,10 @@ func (a *Agent) Paused() bool { return a.pause } -func (a *Agent) runAction(chosenAction Action, decisionResult *decisionResult) (result string, err error) { +func (a *Agent) runAction(chosenAction Action, params action.ActionParams) (result string, err error) { for _, action := range a.systemInternalActions() { if action.Definition().Name == chosenAction.Definition().Name { - if result, err = action.Run(a.actionContext, decisionResult.actionParams); err != nil { + if result, err = action.Run(a.actionContext, params); err != nil { return "", fmt.Errorf("error running action: %w", err) } } @@ -197,7 +198,7 @@ func (a *Agent) runAction(chosenAction Action, decisionResult *decisionResult) ( // We need to store the result in the state state := action.StateResult{} - err = decisionResult.actionParams.Unmarshal(&state) + err = params.Unmarshal(&state) if err != nil { return "", fmt.Errorf("error unmarshalling state of the agent: %w", err) } @@ -350,17 +351,20 @@ func (a *Agent) consumeJob(job *Job, role string) { // choose an action first var chosenAction Action var reasoning string + var actionParams action.ActionParams - if a.currentReasoning != "" && a.nextAction != nil { + if a.nextAction != nil { // if we are being re-evaluated, we already have the action // and the reasoning. Consume it here and reset it chosenAction = a.nextAction reasoning = a.currentReasoning + actionParams = *a.nextActionParams a.currentReasoning = "" + a.nextActionParams = nil a.nextAction = nil } else { var err error - chosenAction, reasoning, err = a.pickAction(ctx, pickTemplate, a.currentConversation) + chosenAction, actionParams, reasoning, err = a.pickAction(ctx, pickTemplate, a.currentConversation) if err != nil { xlog.Error("Error picking action", "error", err) job.Result.Finish(err) @@ -391,16 +395,20 @@ func (a *Agent) consumeJob(job *Job, role string) { return } - xlog.Info("Generating parameters", - "agent", a.Character.Name, - "action", chosenAction.Definition().Name, - "reasoning", reasoning, - ) + // if we force a reasoning, we need to generate the parameters + if a.options.forceReasoning || actionParams == nil { + xlog.Info("Generating parameters", + "agent", a.Character.Name, + "action", chosenAction.Definition().Name, + "reasoning", reasoning, + ) - params, err := a.generateParameters(ctx, pickTemplate, chosenAction, a.currentConversation, reasoning) - if err != nil { - job.Result.Finish(fmt.Errorf("error generating action's parameters: %w", err)) - return + params, err := a.generateParameters(ctx, pickTemplate, chosenAction, a.currentConversation, reasoning) + if err != nil { + job.Result.Finish(fmt.Errorf("error generating action's parameters: %w", err)) + return + } + actionParams = params.actionParams } xlog.Info( @@ -408,16 +416,16 @@ func (a *Agent) consumeJob(job *Job, role string) { "agent", a.Character.Name, "action", chosenAction.Definition().Name, "reasoning", reasoning, - "params", params.actionParams.String(), + "params", actionParams.String(), ) - if params.actionParams == nil { + if actionParams == nil { job.Result.Finish(fmt.Errorf("no parameters")) return } - if !job.Callback(ActionCurrentState{chosenAction, params.actionParams, reasoning}) { - job.Result.SetResult(ActionState{ActionCurrentState{chosenAction, params.actionParams, reasoning}, "stopped by callback"}) + if !job.Callback(ActionCurrentState{chosenAction, actionParams, reasoning}) { + job.Result.SetResult(ActionState{ActionCurrentState{chosenAction, actionParams, reasoning}, "stopped by callback"}) job.Result.Finish(nil) return } @@ -426,7 +434,7 @@ func (a *Agent) consumeJob(job *Job, role string) { chosenAction.Definition().Name.Is(action.ConversationActionName) { message := action.ConversationActionResponse{} - if err := params.actionParams.Unmarshal(&message); err != nil { + if err := actionParams.Unmarshal(&message); err != nil { job.Result.Finish(fmt.Errorf("error unmarshalling conversation response: %w", err)) return } @@ -450,7 +458,7 @@ func (a *Agent) consumeJob(job *Job, role string) { // If we don't have to reply , run the action! if !chosenAction.Definition().Name.Is(action.ReplyActionName) { - result, err := a.runAction(chosenAction, params) + result, err := a.runAction(chosenAction, actionParams) if err != nil { //job.Result.Finish(fmt.Errorf("error running action: %w", err)) //return @@ -458,7 +466,7 @@ func (a *Agent) consumeJob(job *Job, role string) { result = fmt.Sprintf("Error running tool: %v", err) } - stateResult := ActionState{ActionCurrentState{chosenAction, params.actionParams, reasoning}, result} + stateResult := ActionState{ActionCurrentState{chosenAction, actionParams, reasoning}, result} job.Result.SetResult(stateResult) job.CallbackWithResult(stateResult) @@ -467,7 +475,7 @@ func (a *Agent) consumeJob(job *Job, role string) { Role: "assistant", FunctionCall: &openai.FunctionCall{ Name: chosenAction.Definition().Name.String(), - Arguments: params.actionParams.String(), + Arguments: actionParams.String(), }, }) @@ -484,7 +492,7 @@ func (a *Agent) consumeJob(job *Job, role string) { // given the result, we can now ask OpenAI to complete the conversation or // to continue using another tool given the result - followingAction, reasoning, err := a.pickAction(ctx, reEvaluationTemplate, a.currentConversation) + followingAction, followingParams, reasoning, err := a.pickAction(ctx, reEvaluationTemplate, a.currentConversation) if err != nil { job.Result.Finish(fmt.Errorf("error picking action: %w", err)) return @@ -498,6 +506,7 @@ func (a *Agent) consumeJob(job *Job, role string) { // call ourselves again a.currentReasoning = reasoning a.nextAction = followingAction + a.nextActionParams = &followingParams job.Text = "" a.consumeJob(job, role) return @@ -521,7 +530,7 @@ func (a *Agent) consumeJob(job *Job, role string) { // decode the response replyResponse := action.ReplyResponse{} - if err := params.actionParams.Unmarshal(&replyResponse); err != nil { + if err := actionParams.Unmarshal(&replyResponse); err != nil { job.Result.Finish(fmt.Errorf("error unmarshalling reply response: %w", err)) return }