Clouade did up to this point
This commit is contained in:
59
agent.go
Normal file
59
agent.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ToolExec func(ctx context.Context, name, argsJSON string) string
|
||||
|
||||
const maxAgentIterations = 50
|
||||
|
||||
// Agent is a stateless driver: given a message slice and tools, it advances
|
||||
// the conversation until the assistant replies with no tool calls.
|
||||
type Agent struct {
|
||||
Name string
|
||||
Client *Client
|
||||
SystemPrompt string
|
||||
Tools []Tool
|
||||
ToolExec ToolExec
|
||||
OnToolCall func(agent string, tc ToolCall, result string)
|
||||
}
|
||||
|
||||
// Run advances the given messages, returning the final assistant text and
|
||||
// the updated message slice (including tool calls + tool results).
|
||||
func (a *Agent) Run(ctx context.Context, messages []Message) (string, []Message, error) {
|
||||
for i := 0; i < maxAgentIterations; i++ {
|
||||
msg, err := a.Client.Chat(ctx, messages, a.Tools)
|
||||
if err != nil {
|
||||
return "", messages, err
|
||||
}
|
||||
messages = append(messages, msg)
|
||||
if len(msg.ToolCalls) == 0 {
|
||||
return msg.Content, messages, nil
|
||||
}
|
||||
for _, tc := range msg.ToolCalls {
|
||||
result := a.ToolExec(ctx, tc.Function.Name, tc.Function.Arguments)
|
||||
if a.OnToolCall != nil {
|
||||
a.OnToolCall(a.Name, tc, result)
|
||||
}
|
||||
messages = append(messages, Message{
|
||||
Role: "tool",
|
||||
ToolCallID: tc.ID,
|
||||
Name: tc.Function.Name,
|
||||
Content: result,
|
||||
})
|
||||
}
|
||||
}
|
||||
return "", messages, fmt.Errorf("%s: exceeded %d iterations without final reply", a.Name, maxAgentIterations)
|
||||
}
|
||||
|
||||
// Do is a one-shot helper: fresh conversation of system+user → final text.
|
||||
func (a *Agent) Do(ctx context.Context, userMsg string) (string, error) {
|
||||
messages := []Message{
|
||||
{Role: "system", Content: a.SystemPrompt},
|
||||
{Role: "user", Content: userMsg},
|
||||
}
|
||||
reply, _, err := a.Run(ctx, messages)
|
||||
return reply, err
|
||||
}
|
||||
Reference in New Issue
Block a user