diff --git a/pkg/agent/commands.go b/pkg/agent/commands.go index f8b40a6..45f5558 100644 --- a/pkg/agent/commands.go +++ b/pkg/agent/commands.go @@ -7,6 +7,7 @@ import ( "os" "os/exec" "slices" + "strconv" "strings" "ollie/pkg/config" @@ -130,6 +131,28 @@ func (s *agent) handleCommand(ctx context.Context, input string, handler EventHa handler(infoEvent("switched model to: " + args[0])) }, + "/maxsteps": func(args []string) { + if len(args) == 0 { + if s.cfg.MaxSteps == 0 { + handler(infoEvent("maxsteps: unlimited")) + } else { + handler(infoEvent(fmt.Sprintf("maxsteps: %d", s.cfg.MaxSteps))) + } + return + } + n, err := strconv.Atoi(args[0]) + if err != nil || n < 0 { + handler(infoEvent("error: maxsteps requires a non-negative integer (0 = unlimited)")) + return + } + s.cfg.MaxSteps = n + if n == 0 { + handler(infoEvent("maxsteps: unlimited")) + } else { + handler(infoEvent(fmt.Sprintf("maxsteps: %d", n))) + } + }, + "/agents": func(args []string) { seen := make(map[string]bool) found := false @@ -190,6 +213,7 @@ func (s *agent) handleCommand(ctx context.Context, input string, handler EventHa s.cfg.Tools = env.tools s.cfg.Exec = env.exec s.cfg.GenerationParams = env.genParams + s.cfg.MaxSteps = env.maxSteps s.agentName = name s.session = nil s.sessionID = NewSessionID() @@ -374,6 +398,7 @@ func (s *agent) handleCommand(ctx context.Context, input string, handler EventHa " /backend [type] - show current backend, or switch to ", " /model [name] - show current model, or switch to ", " /models - list available models", + " /maxsteps [n] - show or set max tool-call steps (0 = unlimited)", " /skills - list available skills", " /tools - list available tools", " /cwd [path] - show or change working directory", diff --git a/pkg/agent/core.go b/pkg/agent/core.go index fb82793..04c51be 100644 --- a/pkg/agent/core.go +++ b/pkg/agent/core.go @@ -198,6 +198,9 @@ type AgentCoreConfig struct { NewDispatcher func() tools.Dispatcher NewBackend func(string) (backend.Backend, error) // if nil, defaults to backend.NewWithName Log *olog.Logger // if nil, logging is disabled + // MaxSteps overrides the agent JSON maxSteps when non-zero. + // 0 means use the value from the agent config (or unlimited if absent). + MaxSteps int } // agent is the Core implementation. It owns all agent and session state @@ -323,6 +326,12 @@ func NewAgentCore(cfg AgentCoreConfig) Core { GenerationParams: cfg.Env.genParams, MaxSteps: cfg.Env.maxSteps, } + // A non-zero MaxSteps in AgentCoreConfig takes precedence over the + // value loaded from the agent JSON, allowing callers to impose a + // per-session limit at construction time (e.g. via a CLI flag). + if cfg.MaxSteps > 0 { + run.MaxSteps = cfg.MaxSteps + } if cfg.SessionID != "" { os.MkdirAll(filepath.Join(ollieTmpDir(), cfg.SessionID), 0700) //nolint:errcheck }