Do not do two requests if reasoning is disabled

Signed-off-by: mudler <mudler@localai.io>
This commit is contained in:
mudler
2024-05-23 18:58:53 +02:00
parent 3f9b454276
commit 989a2421ba
2 changed files with 47 additions and 37 deletions

View File

@@ -192,7 +192,7 @@ func (a *Agent) prepareHUD() PromptHUD {
} }
// pickAction picks an action based on the conversation // 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 c := messages
if !a.options.forceReasoning { if !a.options.forceReasoning {
@@ -203,8 +203,9 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.
a.systemInternalActions().ToTools(), a.systemInternalActions().ToTools(),
nil) nil)
if err != 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 action Name: %v", thought.actioName))
xlog.Debug(fmt.Sprintf("thought message: %v", thought.message)) 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? // LLM replied with an answer?
//fmt.Errorf("no action found for intent:" + thought.actioName) //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)) xlog.Debug(fmt.Sprintf("chosenAction: %v", chosenAction.Definition().Name))
return chosenAction, thought.message, nil return chosenAction, thought.actionParams, thought.message, nil
} }
var promptHUD *PromptHUD 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(), "") prompt, err := renderTemplate(templ, promptHUD, a.systemInternalActions(), "")
if err != nil { if err != nil {
return nil, "", err return nil, nil, "", err
} }
// Get the LLM to think on what to do // Get the LLM to think on what to do
// and have a thought // and have a thought
@@ -249,13 +250,13 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.
Actions{action.NewReasoning()}.ToTools(), Actions{action.NewReasoning()}.ToTools(),
action.NewReasoning().Definition().Name) action.NewReasoning().Definition().Name)
if err != nil { if err != nil {
return nil, "", err return nil, nil, "", err
} }
reason := "" reason := ""
response := &action.ReasoningResponse{} response := &action.ReasoningResponse{}
if thought.actionParams != nil { if thought.actionParams != nil {
if err := thought.actionParams.Unmarshal(response); err != nil { if err := thought.actionParams.Unmarshal(response); err != nil {
return nil, "", err return nil, nil, "", err
} }
reason = response.Reasoning reason = response.Reasoning
} }
@@ -280,29 +281,29 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.
Actions{intentionsTools}.ToTools(), Actions{intentionsTools}.ToTools(),
intentionsTools.Definition().Name) intentionsTools.Definition().Name)
if err != nil { 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{} actionChoice := action.IntentResponse{}
if params.actionParams == nil { if params.actionParams == nil {
return nil, params.message, nil return nil, nil, params.message, nil
} }
err = params.actionParams.Unmarshal(&actionChoice) err = params.actionParams.Unmarshal(&actionChoice)
if err != nil { if err != nil {
return nil, "", err return nil, nil, "", err
} }
if actionChoice.Tool == "" || actionChoice.Tool == "none" { if actionChoice.Tool == "" || actionChoice.Tool == "none" {
return nil, "", fmt.Errorf("no intent detected") return nil, nil, "", fmt.Errorf("no intent detected")
} }
// Find the action // Find the action
chosenAction := a.systemInternalActions().Find(actionChoice.Tool) chosenAction := a.systemInternalActions().Find(actionChoice.Tool)
if chosenAction == nil { 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
} }

View File

@@ -33,6 +33,7 @@ type Agent struct {
currentReasoning string currentReasoning string
currentState *action.StateResult currentState *action.StateResult
nextAction Action nextAction Action
nextActionParams *action.ActionParams
currentConversation Messages currentConversation Messages
selfEvaluationInProgress bool selfEvaluationInProgress bool
pause bool pause bool
@@ -182,10 +183,10 @@ func (a *Agent) Paused() bool {
return a.pause 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() { for _, action := range a.systemInternalActions() {
if action.Definition().Name == chosenAction.Definition().Name { 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) 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 // We need to store the result in the state
state := action.StateResult{} state := action.StateResult{}
err = decisionResult.actionParams.Unmarshal(&state) err = params.Unmarshal(&state)
if err != nil { if err != nil {
return "", fmt.Errorf("error unmarshalling state of the agent: %w", err) 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 // choose an action first
var chosenAction Action var chosenAction Action
var reasoning string 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 // if we are being re-evaluated, we already have the action
// and the reasoning. Consume it here and reset it // and the reasoning. Consume it here and reset it
chosenAction = a.nextAction chosenAction = a.nextAction
reasoning = a.currentReasoning reasoning = a.currentReasoning
actionParams = *a.nextActionParams
a.currentReasoning = "" a.currentReasoning = ""
a.nextActionParams = nil
a.nextAction = nil a.nextAction = nil
} else { } else {
var err error 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 { if err != nil {
xlog.Error("Error picking action", "error", err) xlog.Error("Error picking action", "error", err)
job.Result.Finish(err) job.Result.Finish(err)
@@ -391,6 +395,8 @@ func (a *Agent) consumeJob(job *Job, role string) {
return return
} }
// if we force a reasoning, we need to generate the parameters
if a.options.forceReasoning || actionParams == nil {
xlog.Info("Generating parameters", xlog.Info("Generating parameters",
"agent", a.Character.Name, "agent", a.Character.Name,
"action", chosenAction.Definition().Name, "action", chosenAction.Definition().Name,
@@ -402,22 +408,24 @@ func (a *Agent) consumeJob(job *Job, role string) {
job.Result.Finish(fmt.Errorf("error generating action's parameters: %w", err)) job.Result.Finish(fmt.Errorf("error generating action's parameters: %w", err))
return return
} }
actionParams = params.actionParams
}
xlog.Info( xlog.Info(
"Generated parameters", "Generated parameters",
"agent", a.Character.Name, "agent", a.Character.Name,
"action", chosenAction.Definition().Name, "action", chosenAction.Definition().Name,
"reasoning", reasoning, "reasoning", reasoning,
"params", params.actionParams.String(), "params", actionParams.String(),
) )
if params.actionParams == nil { if actionParams == nil {
job.Result.Finish(fmt.Errorf("no parameters")) job.Result.Finish(fmt.Errorf("no parameters"))
return return
} }
if !job.Callback(ActionCurrentState{chosenAction, params.actionParams, reasoning}) { if !job.Callback(ActionCurrentState{chosenAction, actionParams, reasoning}) {
job.Result.SetResult(ActionState{ActionCurrentState{chosenAction, params.actionParams, reasoning}, "stopped by callback"}) job.Result.SetResult(ActionState{ActionCurrentState{chosenAction, actionParams, reasoning}, "stopped by callback"})
job.Result.Finish(nil) job.Result.Finish(nil)
return return
} }
@@ -426,7 +434,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
chosenAction.Definition().Name.Is(action.ConversationActionName) { chosenAction.Definition().Name.Is(action.ConversationActionName) {
message := action.ConversationActionResponse{} 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)) job.Result.Finish(fmt.Errorf("error unmarshalling conversation response: %w", err))
return return
} }
@@ -450,7 +458,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
// If we don't have to reply , run the action! // If we don't have to reply , run the action!
if !chosenAction.Definition().Name.Is(action.ReplyActionName) { if !chosenAction.Definition().Name.Is(action.ReplyActionName) {
result, err := a.runAction(chosenAction, params) result, err := a.runAction(chosenAction, actionParams)
if err != nil { if err != nil {
//job.Result.Finish(fmt.Errorf("error running action: %w", err)) //job.Result.Finish(fmt.Errorf("error running action: %w", err))
//return //return
@@ -458,7 +466,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
result = fmt.Sprintf("Error running tool: %v", err) 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.Result.SetResult(stateResult)
job.CallbackWithResult(stateResult) job.CallbackWithResult(stateResult)
@@ -467,7 +475,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
Role: "assistant", Role: "assistant",
FunctionCall: &openai.FunctionCall{ FunctionCall: &openai.FunctionCall{
Name: chosenAction.Definition().Name.String(), 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 // given the result, we can now ask OpenAI to complete the conversation or
// to continue using another tool given the result // 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 { if err != nil {
job.Result.Finish(fmt.Errorf("error picking action: %w", err)) job.Result.Finish(fmt.Errorf("error picking action: %w", err))
return return
@@ -498,6 +506,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
// call ourselves again // call ourselves again
a.currentReasoning = reasoning a.currentReasoning = reasoning
a.nextAction = followingAction a.nextAction = followingAction
a.nextActionParams = &followingParams
job.Text = "" job.Text = ""
a.consumeJob(job, role) a.consumeJob(job, role)
return return
@@ -521,7 +530,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
// decode the response // decode the response
replyResponse := action.ReplyResponse{} 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)) job.Result.Finish(fmt.Errorf("error unmarshalling reply response: %w", err))
return return
} }