wip
This commit is contained in:
@@ -85,19 +85,28 @@ func (a *Agent) decision(
|
|||||||
return &decisionResult{actionParams: params}, nil
|
return &decisionResult{actionParams: params}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) generateParameters(ctx context.Context, action Action, conversation []openai.ChatCompletionMessage) (*decisionResult, error) {
|
func (a *Agent) generateParameters(ctx context.Context, pickTemplate string, act Action, c []openai.ChatCompletionMessage, reasoning string) (*decisionResult, error) {
|
||||||
|
conversation, _, _, err := a.prepareConversationParse(pickTemplate, c, false, reasoning)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return a.decision(ctx,
|
return a.decision(ctx,
|
||||||
conversation,
|
conversation,
|
||||||
a.systemActions().ToTools(),
|
a.systemActions().ToTools(),
|
||||||
action.Definition().Name)
|
act.Definition().Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) systemInternalActions() Actions {
|
||||||
|
if a.options.enableHUD {
|
||||||
|
return append(a.options.userActions, action.NewState())
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(a.options.userActions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) systemActions() Actions {
|
func (a *Agent) systemActions() Actions {
|
||||||
if a.options.enableHUD {
|
return append(a.systemInternalActions(), action.NewReply())
|
||||||
return append(a.options.userActions, action.NewReply(), action.NewState())
|
|
||||||
}
|
|
||||||
|
|
||||||
return append(a.options.userActions, action.NewReply())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) prepareHUD() PromptHUD {
|
func (a *Agent) prepareHUD() PromptHUD {
|
||||||
@@ -108,83 +117,73 @@ func (a *Agent) prepareHUD() PromptHUD {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const hudTemplate = `You have a character and your replies and actions might be influenced by it.
|
func (a *Agent) prepareConversationParse(templ string, messages []openai.ChatCompletionMessage, canReply bool, reasoning string) ([]openai.ChatCompletionMessage, Actions, []string, error) {
|
||||||
{{if .Character.Name}}Name: {{.Character.Name}}
|
|
||||||
{{end}}{{if .Character.Age}}Age: {{.Character.Age}}
|
|
||||||
{{end}}{{if .Character.Occupation}}Occupation: {{.Character.Occupation}}
|
|
||||||
{{end}}{{if .Character.Hobbies}}Hobbies: {{.Character.Hobbies}}
|
|
||||||
{{end}}{{if .Character.MusicTaste}}Music taste: {{.Character.MusicTaste}}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
This is your current state:
|
|
||||||
NowDoing: {{if .CurrentState.NowDoing}}{{.CurrentState.NowDoing}}{{else}}Nothing{{end}}
|
|
||||||
DoingNext: {{if .CurrentState.DoingNext}}{{.CurrentState.DoingNext}}{{else}}Nothing{{end}}
|
|
||||||
Your permanent goal is: {{if .PermanentGoal}}{{.PermanentGoal}}{{else}}Nothing{{end}}
|
|
||||||
Your current goal is: {{if .CurrentState.Goal}}{{.CurrentState.Goal}}{{else}}Nothing{{end}}
|
|
||||||
You have done: {{range .CurrentState.DoneHistory}}{{.}} {{end}}
|
|
||||||
You have a short memory with: {{range .CurrentState.Memories}}{{.}} {{end}}`
|
|
||||||
|
|
||||||
// pickAction picks an action based on the conversation
|
|
||||||
func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.ChatCompletionMessage) (Action, string, error) {
|
|
||||||
// prepare the prompt
|
// prepare the prompt
|
||||||
prompt := bytes.NewBuffer([]byte{})
|
prompt := bytes.NewBuffer([]byte{})
|
||||||
hud := bytes.NewBuffer([]byte{})
|
|
||||||
|
|
||||||
promptTemplate, err := template.New("pickAction").Parse(templ)
|
promptTemplate, err := template.New("pickAction").Parse(templ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, []Action{}, nil, err
|
||||||
}
|
}
|
||||||
hudTmpl, err := template.New("HUD").Parse(hudTemplate)
|
|
||||||
if err != nil {
|
actions := a.systemActions()
|
||||||
return nil, "", err
|
if !canReply {
|
||||||
|
actions = a.systemInternalActions()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all the actions definitions
|
// Get all the actions definitions
|
||||||
definitions := []action.ActionDefinition{}
|
definitions := []action.ActionDefinition{}
|
||||||
for _, m := range a.systemActions() {
|
for _, m := range actions {
|
||||||
definitions = append(definitions, m.Definition())
|
definitions = append(definitions, m.Definition())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var promptHUD *PromptHUD
|
||||||
|
if a.options.enableHUD {
|
||||||
|
h := a.prepareHUD()
|
||||||
|
promptHUD = &h
|
||||||
|
}
|
||||||
|
|
||||||
err = promptTemplate.Execute(prompt, struct {
|
err = promptTemplate.Execute(prompt, struct {
|
||||||
|
HUD *PromptHUD
|
||||||
Actions []action.ActionDefinition
|
Actions []action.ActionDefinition
|
||||||
|
Reasoning string
|
||||||
Messages []openai.ChatCompletionMessage
|
Messages []openai.ChatCompletionMessage
|
||||||
}{
|
}{
|
||||||
Actions: definitions,
|
Actions: definitions,
|
||||||
|
Reasoning: reasoning,
|
||||||
Messages: messages,
|
Messages: messages,
|
||||||
|
HUD: promptHUD,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, []Action{}, nil, err
|
||||||
}
|
|
||||||
|
|
||||||
err = hudTmpl.Execute(hud, a.prepareHUD())
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.options.debugMode {
|
if a.options.debugMode {
|
||||||
fmt.Println("=== HUD START ===", hud.String(), "=== HUD END ===")
|
|
||||||
fmt.Println("=== PROMPT START ===", prompt.String(), "=== PROMPT END ===")
|
fmt.Println("=== PROMPT START ===", prompt.String(), "=== PROMPT END ===")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all the available actions IDs
|
// Get all the available actions IDs
|
||||||
actionsID := []string{}
|
actionsID := []string{}
|
||||||
for _, m := range a.systemActions() {
|
for _, m := range actions {
|
||||||
actionsID = append(actionsID, m.Definition().Name.String())
|
actionsID = append(actionsID, m.Definition().Name.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
conversation := []openai.ChatCompletionMessage{}
|
conversation := []openai.ChatCompletionMessage{}
|
||||||
|
|
||||||
if a.options.enableHUD {
|
|
||||||
conversation = append(conversation, openai.ChatCompletionMessage{
|
|
||||||
Role: "system",
|
|
||||||
Content: hud.String(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
conversation = append(conversation, openai.ChatCompletionMessage{
|
conversation = append(conversation, openai.ChatCompletionMessage{
|
||||||
Role: "user",
|
Role: "user",
|
||||||
Content: prompt.String(),
|
Content: prompt.String(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return conversation, actions, actionsID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// pickAction picks an action based on the conversation
|
||||||
|
func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.ChatCompletionMessage, canReply bool) (Action, string, error) {
|
||||||
|
conversation, actions, actionsID, err := a.prepareConversationParse(templ, messages, canReply, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
// Get the LLM to think on what to do
|
// Get the LLM to think on what to do
|
||||||
thought, err := a.decision(ctx,
|
thought, err := a.decision(ctx,
|
||||||
conversation,
|
conversation,
|
||||||
@@ -234,7 +233,7 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the action
|
// Find the action
|
||||||
chosenAction := a.systemActions().Find(actionChoice.Tool)
|
chosenAction := actions.Find(actionChoice.Tool)
|
||||||
if chosenAction == nil {
|
if chosenAction == nil {
|
||||||
return nil, "", fmt.Errorf("no action found for intent:" + actionChoice.Tool)
|
return nil, "", fmt.Errorf("no action found for intent:" + actionChoice.Tool)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -13,33 +12,6 @@ import (
|
|||||||
"github.com/sashabaranov/go-openai"
|
"github.com/sashabaranov/go-openai"
|
||||||
)
|
)
|
||||||
|
|
||||||
const pickActionTemplate = `You can take any of the following tools:
|
|
||||||
|
|
||||||
{{range .Actions -}}
|
|
||||||
- {{.Name}}: {{.Description }}
|
|
||||||
{{ end }}
|
|
||||||
To answer back to the user, use the "reply" tool.
|
|
||||||
Given the text below, decide which action to take and explain the detailed reasoning behind it. For answering without picking a choice, reply with 'none'.
|
|
||||||
|
|
||||||
{{range .Messages -}}
|
|
||||||
{{.Role}}{{if .FunctionCall}}(tool_call){{.FunctionCall}}{{end}}: {{if .FunctionCall}}{{.FunctionCall}}{{else if .ToolCalls -}}{{range .ToolCalls -}}{{.Name}} called with {{.Arguments}}{{end}}{{ else }}{{.Content -}}{{end}}
|
|
||||||
{{end}}
|
|
||||||
`
|
|
||||||
|
|
||||||
const reEvalTemplate = `You can take any of the following tools:
|
|
||||||
|
|
||||||
{{range .Actions -}}
|
|
||||||
- {{.Name}}: {{.Description }}
|
|
||||||
{{ end }}
|
|
||||||
To answer back to the user, use the "reply" tool.
|
|
||||||
Given the text below, decide which action to take and explain the detailed reasoning behind it. For answering without picking a choice, reply with 'none'.
|
|
||||||
|
|
||||||
{{range .Messages -}}
|
|
||||||
{{.Role}}{{if .FunctionCall}}(tool_call){{.FunctionCall}}{{end}}: {{if .FunctionCall}}{{.FunctionCall}}{{else if .ToolCalls -}}{{range .ToolCalls -}}{{.Name}} called with {{.Arguments}}{{end}}{{ else }}{{.Content -}}{{end}}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
We already have called tools. Evaluate the current situation and decide if we need to execute other tools or answer back with a result.`
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
UserRole = "user"
|
UserRole = "user"
|
||||||
AssistantRole = "assistant"
|
AssistantRole = "assistant"
|
||||||
@@ -202,6 +174,7 @@ func (a *Agent) runAction(chosenAction Action, decisionResult *decisionResult) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) consumeJob(job *Job, role string) {
|
func (a *Agent) consumeJob(job *Job, role string) {
|
||||||
|
selfEvaluation := role == SystemRole
|
||||||
// Consume the job and generate a response
|
// Consume the job and generate a response
|
||||||
a.Lock()
|
a.Lock()
|
||||||
// Set the action context
|
// Set the action context
|
||||||
@@ -221,6 +194,17 @@ func (a *Agent) consumeJob(job *Job, role string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pickTemplate string
|
||||||
|
var reEvaluationTemplate string
|
||||||
|
|
||||||
|
if selfEvaluation {
|
||||||
|
pickTemplate = pickSelfTemplate
|
||||||
|
reEvaluationTemplate = reSelfEvalTemplate
|
||||||
|
} else {
|
||||||
|
pickTemplate = pickActionTemplate
|
||||||
|
reEvaluationTemplate = reEvalTemplate
|
||||||
|
}
|
||||||
|
|
||||||
// choose an action first
|
// choose an action first
|
||||||
var chosenAction Action
|
var chosenAction Action
|
||||||
var reasoning string
|
var reasoning string
|
||||||
@@ -234,7 +218,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
|
|||||||
a.nextAction = nil
|
a.nextAction = nil
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
chosenAction, reasoning, err = a.pickAction(ctx, pickActionTemplate, a.currentConversation)
|
chosenAction, reasoning, err = a.pickAction(ctx, pickTemplate, a.currentConversation, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
job.Result.Finish(err)
|
job.Result.Finish(err)
|
||||||
return
|
return
|
||||||
@@ -247,7 +231,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
params, err := a.generateParameters(ctx, chosenAction, a.currentConversation)
|
params, err := a.generateParameters(ctx, pickTemplate, chosenAction, a.currentConversation, reasoning)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
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
|
||||||
@@ -298,7 +282,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, reEvalTemplate, a.currentConversation)
|
followingAction, reasoning, err := a.pickAction(ctx, reEvaluationTemplate, a.currentConversation, !selfEvaluation)
|
||||||
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
|
||||||
@@ -344,6 +328,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) periodicallyRun() {
|
func (a *Agent) periodicallyRun() {
|
||||||
|
if len(a.CurrentConversation()) != 0 {
|
||||||
// Here the LLM could decide to store some part of the conversation too in the memory
|
// Here the LLM could decide to store some part of the conversation too in the memory
|
||||||
evaluateMemory := NewJob(
|
evaluateMemory := NewJob(
|
||||||
WithText(
|
WithText(
|
||||||
@@ -352,35 +337,39 @@ func (a *Agent) periodicallyRun() {
|
|||||||
a.consumeJob(evaluateMemory, SystemRole)
|
a.consumeJob(evaluateMemory, SystemRole)
|
||||||
|
|
||||||
a.ResetConversation()
|
a.ResetConversation()
|
||||||
|
}
|
||||||
|
|
||||||
// Here we go in a loop of
|
// Here we go in a loop of
|
||||||
// - asking the agent to do something
|
// - asking the agent to do something
|
||||||
// - evaluating the result
|
// - evaluating the result
|
||||||
// - asking the agent to do something else based on the result
|
// - asking the agent to do something else based on the result
|
||||||
|
|
||||||
whatNext := NewJob(WithText("What should I do next?"))
|
// whatNext := NewJob(WithText("Decide what to do based on the state"))
|
||||||
|
whatNext := NewJob(WithText("Decide what to based on the goal and the persistent goal."))
|
||||||
a.consumeJob(whatNext, SystemRole)
|
a.consumeJob(whatNext, SystemRole)
|
||||||
|
|
||||||
doWork := NewJob(WithText("Try to fullfill our goals automatically"))
|
// a.ResetConversation()
|
||||||
a.consumeJob(doWork, SystemRole)
|
|
||||||
|
|
||||||
results := []string{}
|
// doWork := NewJob(WithText("Select the tool to use based on your goal and the current state."))
|
||||||
for _, v := range doWork.Result.State {
|
// a.consumeJob(doWork, SystemRole)
|
||||||
results = append(results, v.Result)
|
|
||||||
}
|
|
||||||
|
|
||||||
a.ResetConversation()
|
// results := []string{}
|
||||||
|
// for _, v := range doWork.Result.State {
|
||||||
|
// results = append(results, v.Result)
|
||||||
|
// }
|
||||||
|
|
||||||
// Here the LLM could decide to do something based on the result of our automatic action
|
// a.ResetConversation()
|
||||||
evaluateAction := NewJob(
|
|
||||||
WithText(
|
|
||||||
`Evaluate the current situation and decide if we need to execute other tools (for instance to store results into permanent, or short memory).
|
|
||||||
We have done the following actions:
|
|
||||||
` + strings.Join(results, "\n"),
|
|
||||||
))
|
|
||||||
a.consumeJob(evaluateAction, SystemRole)
|
|
||||||
|
|
||||||
a.ResetConversation()
|
// // Here the LLM could decide to do something based on the result of our automatic action
|
||||||
|
// evaluateAction := NewJob(
|
||||||
|
// WithText(
|
||||||
|
// `Evaluate the current situation and decide if we need to execute other tools (for instance to store results into permanent, or short memory).
|
||||||
|
// We have done the following actions:
|
||||||
|
// ` + strings.Join(results, "\n"),
|
||||||
|
// ))
|
||||||
|
// a.consumeJob(evaluateAction, SystemRole)
|
||||||
|
|
||||||
|
// a.ResetConversation()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) Run() error {
|
func (a *Agent) Run() error {
|
||||||
|
|||||||
@@ -147,5 +147,32 @@ var _ = Describe("Agent test", func() {
|
|||||||
Expect(result.Error).ToNot(HaveOccurred())
|
Expect(result.Error).ToNot(HaveOccurred())
|
||||||
Expect(agent.State().Goal).To(ContainSubstring("guitar"), fmt.Sprint(agent.State()))
|
Expect(agent.State().Goal).To(ContainSubstring("guitar"), fmt.Sprint(agent.State()))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
FIt("it automatically performs things in the background", func() {
|
||||||
|
agent, err := New(
|
||||||
|
WithLLMAPIURL(apiModel),
|
||||||
|
WithModel(testModel),
|
||||||
|
EnableHUD,
|
||||||
|
DebugMode,
|
||||||
|
EnableStandaloneJob,
|
||||||
|
WithRandomIdentity(),
|
||||||
|
WithPermanentGoal("get the weather of all the cities in italy"),
|
||||||
|
)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
go agent.Run()
|
||||||
|
defer agent.Stop()
|
||||||
|
|
||||||
|
Eventually(func() string {
|
||||||
|
fmt.Println(agent.State())
|
||||||
|
return agent.State().NowDoing
|
||||||
|
}, "4m", "10s").Should(ContainSubstring("weather"), fmt.Sprint(agent.State()))
|
||||||
|
|
||||||
|
// result := agent.Ask(
|
||||||
|
// WithText("Update your goals such as you want to learn to play the guitar"),
|
||||||
|
// )
|
||||||
|
// fmt.Printf("%+v\n", result)
|
||||||
|
// Expect(result.Error).ToNot(HaveOccurred())
|
||||||
|
// Expect(agent.State().Goal).To(ContainSubstring("guitar"), fmt.Sprint(agent.State()))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
65
agent/templates.go
Normal file
65
agent/templates.go
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
const hud = `{{with .HUD }}You have a character and your replies and actions might be influenced by it.
|
||||||
|
{{if .Character.Name}}Name: {{.Character.Name}}
|
||||||
|
{{end}}{{if .Character.Age}}Age: {{.Character.Age}}
|
||||||
|
{{end}}{{if .Character.Occupation}}Occupation: {{.Character.Occupation}}
|
||||||
|
{{end}}{{if .Character.Hobbies}}Hobbies: {{.Character.Hobbies}}
|
||||||
|
{{end}}{{if .Character.MusicTaste}}Music taste: {{.Character.MusicTaste}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
This is your current state:
|
||||||
|
NowDoing: {{if .CurrentState.NowDoing}}{{.CurrentState.NowDoing}}{{else}}Nothing{{end}}
|
||||||
|
DoingNext: {{if .CurrentState.DoingNext}}{{.CurrentState.DoingNext}}{{else}}Nothing{{end}}
|
||||||
|
Your permanent goal is: {{if .PermanentGoal}}{{.PermanentGoal}}{{else}}Nothing{{end}}
|
||||||
|
Your current goal is: {{if .CurrentState.Goal}}{{.CurrentState.Goal}}{{else}}Nothing{{end}}
|
||||||
|
You have done: {{range .CurrentState.DoneHistory}}{{.}} {{end}}
|
||||||
|
You have a short memory with: {{range .CurrentState.Memories}}{{.}} {{end}}{{end}}`
|
||||||
|
|
||||||
|
const pickSelfTemplate = `
|
||||||
|
You can take any of the following tools:
|
||||||
|
|
||||||
|
{{range .Actions -}}
|
||||||
|
- {{.Name}}: {{.Description }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{if .Messages}}
|
||||||
|
Consider the text below, decide which action to take and explain the detailed reasoning behind it.
|
||||||
|
|
||||||
|
{{range .Messages -}}
|
||||||
|
{{.Role}}{{if .FunctionCall}}(tool_call){{.FunctionCall}}{{end}}: {{if .FunctionCall}}{{.FunctionCall}}{{else if .ToolCalls -}}{{range .ToolCalls -}}{{.Name}} called with {{.Arguments}}{{end}}{{ else }}{{.Content -}}{{end}}
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
Act like a smart AI agent having a character, the character and your state is defined in the message above.
|
||||||
|
You are now self-evaluating what to do next based on the state in the previous message.
|
||||||
|
For example, if the permanent goal is to "make a sandwich", you might want to "get the bread" first, and update the state afterwards by calling two tools in sequence.
|
||||||
|
You can update the short-term goal, the current action, the next action, the history of actions, and the memories.
|
||||||
|
You can't ask things to the user as you are thinking by yourself.
|
||||||
|
|
||||||
|
{{if .Reasoning}}Reasoning: {{.Reasoning}}{{end}}
|
||||||
|
` + hud
|
||||||
|
|
||||||
|
const reSelfEvalTemplate = pickSelfTemplate + `
|
||||||
|
|
||||||
|
We already have called other tools. Evaluate the current situation and decide if we need to execute other tools.`
|
||||||
|
|
||||||
|
const pickActionTemplate = hud + `
|
||||||
|
You can take any of the following tools:
|
||||||
|
|
||||||
|
{{range .Actions -}}
|
||||||
|
- {{.Name}}: {{.Description }}
|
||||||
|
{{ end }}
|
||||||
|
To answer back to the user, use the "reply" tool.
|
||||||
|
Given the text below, decide which action to take and explain the detailed reasoning behind it. For answering without picking a choice, reply with 'none'.
|
||||||
|
|
||||||
|
{{range .Messages -}}
|
||||||
|
{{.Role}}{{if .FunctionCall}}(tool_call){{.FunctionCall}}{{end}}: {{if .FunctionCall}}{{.FunctionCall}}{{else if .ToolCalls -}}{{range .ToolCalls -}}{{.Name}} called with {{.Arguments}}{{end}}{{ else }}{{.Content -}}{{end}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{if .Reasoning}}Reasoning: {{.Reasoning}}{{end}}
|
||||||
|
`
|
||||||
|
|
||||||
|
const reEvalTemplate = pickActionTemplate + `
|
||||||
|
|
||||||
|
We already have called other tools. Evaluate the current situation and decide if we need to execute other tools or answer back with a result.`
|
||||||
Reference in New Issue
Block a user