logging: pt1

This commit is contained in:
Ettore Di Giacinto
2024-04-15 00:13:10 +02:00
parent ac8f6e94ff
commit f0bc2be678
14 changed files with 118 additions and 126 deletions

View File

@@ -3,6 +3,7 @@ package agent
import (
"context"
"fmt"
"log/slog"
"os"
"sync"
"time"
@@ -34,6 +35,7 @@ type Agent struct {
selfEvaluationInProgress bool
pause bool
logger *slog.Logger
newConversations chan openai.ChatCompletionMessage
}
@@ -74,12 +76,15 @@ func New(opts ...Option) (*Agent, error) {
}
}
if a.options.debugMode {
fmt.Println("=== Agent in Debug mode ===")
fmt.Println(a.Character.String())
fmt.Println(a.State().String())
fmt.Println("Permanent goal: ", a.options.permanentGoal)
}
var programLevel = new(slog.LevelVar) // Info by default
h := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: programLevel})
a.logger = slog.New(h)
programLevel.Set(a.options.logLevel)
a.logger.Info("Agent in Debug mode", "agent", a.Character.Name)
a.logger.Info("Character", "agent", a.Character.Name, "character", a.Character.String())
a.logger.Info("State", "agent", a.Character.Name, "state", a.State().String())
a.logger.Info("Permanent goal", "agent", a.Character.Name, "goal", a.options.permanentGoal)
return a, nil
}
@@ -107,7 +112,7 @@ func (a *Agent) ConversationChannel() chan openai.ChatCompletionMessage {
func (a *Agent) Ask(opts ...JobOption) *JobResult {
a.StopAction()
j := NewJob(append(opts, WithReasoningCallback(a.options.reasoningCallback), WithResultCallback(a.options.resultCallback))...)
// fmt.Println("Job created", text)
// slog.Info("Job created", text)
a.jobQueue <- j
return j.Result.WaitResult()
}
@@ -165,10 +170,7 @@ func (a *Agent) runAction(chosenAction Action, decisionResult *decisionResult) (
}
}
if a.options.debugMode {
fmt.Println("Action", chosenAction.Definition().Name)
fmt.Println("Result", result)
}
a.logger.Info("Running action", "action", chosenAction.Definition().Name, "agent", a.Character.Name)
if chosenAction.Definition().Name.Is(action.StateActionName) {
// We need to store the result in the state
@@ -198,9 +200,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
a.Unlock()
if paused {
if a.options.debugMode {
fmt.Println("Agent is paused, skipping job")
}
a.logger.Info("Agent is paused, skipping job", "agent", a.Character.Name)
job.Result.Finish(fmt.Errorf("agent is paused"))
return
}
@@ -270,9 +270,8 @@ func (a *Agent) consumeJob(job *Job, role string) {
if userMessage != "" {
results, err := a.options.ragdb.Search(userMessage, a.options.kbResults)
if err != nil {
if a.options.debugMode {
fmt.Println("Error finding similar strings inside KB:", err)
}
a.logger.Info("Error finding similar strings inside KB:", "error", err)
// job.Result.Finish(fmt.Errorf("error finding similar strings inside KB: %w", err))
// return
}
@@ -283,10 +282,8 @@ func (a *Agent) consumeJob(job *Job, role string) {
for _, r := range results {
formatResults += fmt.Sprintf("- %s \n", r)
}
if a.options.debugMode {
fmt.Println("Found similar strings in KB:")
fmt.Println(formatResults)
}
a.logger.Info("Found similar strings in KB", "agent", a.Character.Name, "results", formatResults)
// a.currentConversation = append(a.currentConversation,
// openai.ChatCompletionMessage{
// Role: "system",
@@ -341,9 +338,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
}
if chosenAction.Definition().Name.Is(action.StopActionName) {
if a.options.debugMode {
fmt.Println("LLM decided to stop")
}
a.logger.Info("LLM decided to stop")
job.Result.Finish(nil)
return
}
@@ -362,9 +357,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
return
}
if a.options.debugMode {
fmt.Println("===> Generating parameters for", chosenAction.Definition().Name)
}
a.logger.Info("===> Generating parameters for", "action", chosenAction.Definition().Name)
params, err := a.generateParameters(ctx, pickTemplate, chosenAction, a.currentConversation, reasoning)
if err != nil {
@@ -372,10 +365,8 @@ func (a *Agent) consumeJob(job *Job, role string) {
return
}
if a.options.debugMode {
fmt.Println("===> Generated parameters for", chosenAction.Definition().Name)
fmt.Println(params.actionParams.String())
}
a.logger.Info("===> Generated parameters for", "action", chosenAction.Definition().Name)
a.logger.Info(params.actionParams.String())
if params.actionParams == nil {
job.Result.Finish(fmt.Errorf("no parameters"))
@@ -549,9 +540,7 @@ func (a *Agent) consumeJob(job *Job, role string) {
// If we didn't got any message, we can use the response from the action
if chosenAction.Definition().Name.Is(action.ReplyActionName) && msg.Content == "" {
if a.options.debugMode {
fmt.Println("No output returned from conversation, using the action response as a reply.")
}
a.logger.Info("No output returned from conversation, using the action response as a reply.")
msg.Content = replyResponse.Message
}
@@ -570,9 +559,7 @@ func (a *Agent) periodicallyRun() {
// This would be a special action that would be picked up by the agent
// and would be used to contact the user.
if a.options.debugMode {
fmt.Println("START -- Periodically run is starting")
}
a.logger.Info("START -- Periodically run is starting")
if len(a.CurrentConversation()) != 0 {
// Here the LLM could decide to store some part of the conversation too in the memory
@@ -602,9 +589,8 @@ func (a *Agent) periodicallyRun() {
a.consumeJob(whatNext, SystemRole)
a.ResetConversation()
if a.options.debugMode {
fmt.Println("STOP -- Periodically run is done")
}
a.logger.Info("STOP -- Periodically run is done")
// Save results from state
// a.ResetConversation()

View File

@@ -2,6 +2,7 @@ package agent_test
import (
"fmt"
"log/slog"
"github.com/mudler/local-agent-framework/action"
. "github.com/mudler/local-agent-framework/agent"
@@ -18,13 +19,13 @@ var _ Action = &TestAction{}
var debugOptions = []JobOption{
WithReasoningCallback(func(state ActionCurrentState) bool {
fmt.Println("Reasoning", state)
slog.Info("Reasoning", state)
return true
}),
WithResultCallback(func(state ActionState) {
fmt.Println("Reasoning", state.Reasoning)
fmt.Println("Action", state.Action)
fmt.Println("Result", state.Result)
slog.Info("Reasoning", state.Reasoning)
slog.Info("Action", state.Action)
slog.Info("Result", state.Result)
}),
}
@@ -172,7 +173,6 @@ var _ = Describe("Agent test", func() {
WithLLMAPIURL(apiModel),
WithModel(testModel),
EnableHUD,
DebugMode,
// EnableStandaloneJob,
// WithRandomIdentity(),
WithPermanentGoal("I want to learn to play music"),
@@ -194,16 +194,15 @@ var _ = Describe("Agent test", func() {
WithLLMAPIURL(apiModel),
WithModel(testModel),
EnableHUD,
DebugMode,
EnableStandaloneJob,
WithAgentReasoningCallback(func(state ActionCurrentState) bool {
fmt.Println("Reasoning", state)
slog.Info("Reasoning", state)
return true
}),
WithAgentResultCallback(func(state ActionState) {
fmt.Println("Reasoning", state.Reasoning)
fmt.Println("Action", state.Action)
fmt.Println("Result", state.Result)
slog.Info("Reasoning", state.Reasoning)
slog.Info("Action", state.Action)
slog.Info("Result", state.Result)
}),
WithActions(
&FakeInternetAction{
@@ -230,14 +229,12 @@ var _ = Describe("Agent test", func() {
Expect(err).ToNot(HaveOccurred())
go agent.Run()
defer agent.Stop()
Eventually(func() string {
fmt.Println(agent.State())
return agent.State().Goal
}, "10m", "10s").Should(ContainSubstring("weather"), fmt.Sprint(agent.State()))
Eventually(func() string {
fmt.Println(agent.State())
return agent.State().String()
}, "10m", "10s").Should(ContainSubstring("store"), fmt.Sprint(agent.State()))

View File

@@ -2,6 +2,7 @@ package agent
import (
"context"
"log/slog"
"strings"
"time"
)
@@ -20,16 +21,17 @@ type options struct {
randomIdentity bool
userActions Actions
enableHUD, standaloneJob, showCharacter, enableKB bool
debugMode bool
canStopItself bool
initiateConversations bool
characterfile string
statefile string
context context.Context
permanentGoal string
periodicRuns time.Duration
kbResults int
ragdb RAGDB
logLevel slog.Level
canStopItself bool
initiateConversations bool
characterfile string
statefile string
context context.Context
permanentGoal string
periodicRuns time.Duration
kbResults int
ragdb RAGDB
prompts []PromptBlock
@@ -52,6 +54,7 @@ func defaultOptions() *options {
APIURL: "http://localhost:8080",
Model: "echidna",
},
logLevel: slog.LevelInfo,
character: Character{
Name: "John Doe",
Age: "",
@@ -88,6 +91,13 @@ var CanStopItself = func(o *options) error {
return nil
}
func LogLevel(level slog.Level) Option {
return func(o *options) error {
o.logLevel = level
return nil
}
}
func EnableKnowledgeBaseWithResults(results int) Option {
return func(o *options) error {
o.enableKB = true
@@ -101,11 +111,6 @@ var EnableInitiateConversations = func(o *options) error {
return nil
}
var DebugMode = func(o *options) error {
o.debugMode = true
return nil
}
// EnableStandaloneJob is an option to enable the agent
// to run jobs in the background automatically
var EnableStandaloneJob = func(o *options) error {