diff --git a/cmd/olliesrv/internal/agent/agent_config.go b/cmd/olliesrv/internal/agent/agent_config.go index 49405e5..1db0dd6 100644 --- a/cmd/olliesrv/internal/agent/agent_config.go +++ b/cmd/olliesrv/internal/agent/agent_config.go @@ -30,8 +30,6 @@ type AgentConfig struct { Tools *bool `json:"tools,omitempty"` AutoLoad []string `json:"autoLoad,omitempty"` - // MaxSteps caps the number of tool-call rounds per turn. 0 means unlimited. - MaxSteps int `json:"maxSteps,omitempty"` CompactionModel string `json:"compactionModel,omitempty"` // SystemPrompt overrides the embedded system prompt with a file path. SystemPrompt string `json:"systemPrompt,omitempty"` diff --git a/cmd/olliesrv/internal/agent/loop.go b/cmd/olliesrv/internal/agent/loop.go index ec4843d..09c57b2 100644 --- a/cmd/olliesrv/internal/agent/loop.go +++ b/cmd/olliesrv/internal/agent/loop.go @@ -162,59 +162,31 @@ func (ag *Agent) run(ctx context.Context) error { } } - msg := backend.Message{ID: responseID, Role: "assistant", Content: content, Reasoning: reasoning, ToolCalls: toolCalls} - results, interrupted := ag.execToolCalls(ctx, toolCalls) + msg := backend.Message{ID: responseID, Role: "assistant", Content: content, Reasoning: reasoning, ToolCalls: toolCalls} + results, interrupted := ag.execToolCalls(ctx, toolCalls) - h.update(msg, results) - ag.save() + h.update(msg, results) + ag.save() - if interrupted { - return ctx.Err() - } - if len(toolCalls) == 0 { - break - } - - if abort := ag.trackErrors(ctx, results, &errs, step); abort != nil { - return abort - } - - // Reset step counter when an action-oriented tool succeeds. - if rt.ToolMeta != nil { - for _, r := range results { - if !r.IsError && rt.ToolMeta[r.Name].ResetsCounter { - step = 0 - break - } + if interrupted { + return ctx.Err() } - } - - // Step budget warnings. - if rt.MaxSteps > 0 { - halfBudget := rt.MaxSteps / 2 - if step == halfBudget { - h.update(backend.Message{ - Role: "user", - Content: fmt.Sprintf("\nYou have used %d/%d research steps without taking action. Consider making progress — write code, edit files, or run commands. Action tools reset this counter.\n", step, rt.MaxSteps), - }, nil) - } else if step >= rt.MaxSteps-1 { - ag.emit(Event{Role: "maxsteps", Content: fmt.Sprintf("%d", step+1)}) - h.update(backend.Message{ - Role: "user", - Content: fmt.Sprintf("\nStep budget exhausted (%d/%d steps used). Stop calling tools. Summarize what you have done and what remains, then stop.\n", step+1, rt.MaxSteps), - }, nil) + if len(toolCalls) == 0 { break } - } - _, compactErr := ag.autoCompact(ctx) - if compactErr != nil { - ag.emit(Event{Role: "error", Content: compactErr.Error()}) - break - } + if abort := ag.trackErrors(ctx, results, &errs, step); abort != nil { + return abort + } - step++ - } + _, compactErr := ag.autoCompact(ctx) + if compactErr != nil { + ag.emit(Event{Role: "error", Content: compactErr.Error()}) + break + } + + step++ + } return nil } diff --git a/cmd/olliesrv/internal/agent/runtime.go b/cmd/olliesrv/internal/agent/runtime.go index 31408ba..4273238 100644 --- a/cmd/olliesrv/internal/agent/runtime.go +++ b/cmd/olliesrv/internal/agent/runtime.go @@ -145,7 +145,6 @@ type Runtime struct { ToolMeta map[string]protocol.ToolInfo Exec toolExecutor GenParams backend.GenerationParams - MaxSteps int CompactionModel string UserPrompt string // resolved user prompts, prepended to each turn's input Messages []string @@ -179,7 +178,6 @@ func BuildRuntime(cfg *AgentConfig, srv *toolclient.ToolsrvConn, cwd string, env var agentPrompt string var userPrompt string var genParams backend.GenerationParams - var maxSteps int if cfg != nil { if resolved, err := resolvePrompt(cfg.Prompt, cwd, env); err != nil { fmt.Fprintf(os.Stderr, "resolve prompt: %v\n", err) @@ -192,7 +190,6 @@ func BuildRuntime(cfg *AgentConfig, srv *toolclient.ToolsrvConn, cwd string, env userPrompt = resolved } genParams = cfg.GenerationParams - maxSteps = cfg.MaxSteps } genParams.CWD = cwd @@ -235,7 +232,6 @@ func BuildRuntime(cfg *AgentConfig, srv *toolclient.ToolsrvConn, cwd string, env Exec: exec, Preamble: preamble, GenParams: genParams, - MaxSteps: maxSteps, CompactionModel: compactionModel, UserPrompt: userPrompt, Messages: messages, diff --git a/data/agents/default.json b/data/agents/default.json index 5b9226d..a7c8340 100644 --- a/data/agents/default.json +++ b/data/agents/default.json @@ -27,7 +27,6 @@ "lsp_rename", "lsp_completion" ], - "maxSteps": 25, "temperature": 0.5, "maxTokens": 16384 } diff --git a/data/agents/driver.json b/data/agents/driver.json index 2a4aed7..d9ac71a 100644 --- a/data/agents/driver.json +++ b/data/agents/driver.json @@ -41,7 +41,6 @@ ], "backend": "openrouter", "model": "deepseek/deepseek-v4-flash", - "maxSteps": 25, "temperature": 0.4, "maxTokens": 16384 } diff --git a/data/agents/explorer.json b/data/agents/explorer.json index e414f8a..b21354d 100644 --- a/data/agents/explorer.json +++ b/data/agents/explorer.json @@ -26,7 +26,6 @@ "code_rewrite", "code_dependencies" ], - "maxSteps": 40, "temperature": 0.3, "maxTokens": 16384 } diff --git a/data/agents/librarian.json b/data/agents/librarian.json index 4c63696..ea2ce51 100644 --- a/data/agents/librarian.json +++ b/data/agents/librarian.json @@ -15,7 +15,6 @@ "memory_recall", "memory_remember" ], - "maxSteps": 20, "temperature": 0.3, "maxTokens": 16384 } diff --git a/data/agents/navigator.json b/data/agents/navigator.json index 77ccac5..a15a471 100644 --- a/data/agents/navigator.json +++ b/data/agents/navigator.json @@ -28,6 +28,5 @@ "code_dependencies" ], "temperature": 0.3, - "maxTokens": 8192, - "maxSteps": 30 + "maxTokens": 8192 } diff --git a/data/agents/observer.json b/data/agents/observer.json index 4061125..632c063 100644 --- a/data/agents/observer.json +++ b/data/agents/observer.json @@ -23,7 +23,6 @@ "lsp_rename", "lsp_completion" ], - "maxSteps": 5, "temperature": 0.3, "maxTokens": 4096 } diff --git a/data/agents/taskmanager.json b/data/agents/taskmanager.json index 68c6c0c..e4961e5 100644 --- a/data/agents/taskmanager.json +++ b/data/agents/taskmanager.json @@ -17,7 +17,6 @@ "memory_recall", "memory_remember" ], - "maxSteps": 20, "temperature": 0.3, "maxTokens": 8192 } diff --git a/data/agents/theo.json b/data/agents/theo.json index 5541d3c..6cf29ec 100644 --- a/data/agents/theo.json +++ b/data/agents/theo.json @@ -17,7 +17,6 @@ "file_grep", "file_write" ], - "maxSteps": 30, "temperature": 0.3, "maxTokens": 8192 } diff --git a/data/tools/file_edit.meta b/data/tools/file_edit.meta index e4d9746..887db8f 100644 --- a/data/tools/file_edit.meta +++ b/data/tools/file_edit.meta @@ -1,7 +1,6 @@ { "description": "Replace text in a file. Has fuzzy matching (whitespace/indent flexible).", "outputFormat": "diff", - "resetsCounter": true, "prompt": "## file_edit\n\nReplace text in a file. Has fuzzy matching (whitespace/indent flexible).\n\n**Args**: `path`, `old_string`, `new_string` (required); `replace_all` (optional)\n\n```\nfile_edit(path=\"\", old_string=\"old text\", new_string=\"new text\")\nfile_edit(path=\"\", old_string=\"old text\", new_string=\"new text\", replace_all=\"true\")\n```\n\n**Constraints**: Absolute paths only. Errors if `old_string` matches multiple locations \u2014 add surrounding context to disambiguate, or use `replace_all=true`.", "args": { "type": "object", diff --git a/data/tools/file_write.meta b/data/tools/file_write.meta index eec8140..40fda31 100644 --- a/data/tools/file_write.meta +++ b/data/tools/file_write.meta @@ -1,7 +1,6 @@ { "description": "Create or overwrite a file. Produces a unified diff.", "outputFormat": "diff", - "resetsCounter": true, "prompt": "## file_write\n\nCreate or overwrite a file. Produces a unified diff.\n\n**Args**: `[path, content]`\n\n```\nfile_write(path=\"\", content=\"file content here\")\n```\n\n**Constraints**: Absolute paths only. Parent directory must exist.", "args": { "type": "object", diff --git a/data/tools/shell.meta b/data/tools/shell.meta index d9f61dc..f49df35 100644 --- a/data/tools/shell.meta +++ b/data/tools/shell.meta @@ -1,6 +1,5 @@ { "description": "Execute a single bash command in a sandboxed environment.", - "resetsCounter": true, "prompt": "Execute a single bash command in a sandboxed environment.\n\nUsage: {\"cmd\": \"your command here\"}\n\nSandbox prevents dangerous operations. Use for computation, builds, scripting.\ntimeout applies to each call (default: 30s). A non-zero exit is an error.", "args": { "type": "object", diff --git a/toolsrv/metadata/meta.go b/toolsrv/metadata/meta.go index a9c8f3c..0d45afc 100644 --- a/toolsrv/metadata/meta.go +++ b/toolsrv/metadata/meta.go @@ -19,7 +19,6 @@ type MetaFile struct { Scope string `json:"scope,omitempty"` OutputFormat string `json:"outputFormat,omitempty"` Cmd string `json:"cmd,omitempty"` - ResetsCounter bool `json:"resetsCounter,omitempty"` Variants []Variant `json:"variants,omitempty"` } @@ -35,7 +34,6 @@ type Variant struct { Scope string `json:"scope,omitempty"` OutputFormat string `json:"outputFormat,omitempty"` Cmd string `json:"cmd,omitempty"` - ResetsCounter bool `json:"resetsCounter,omitempty"` } // LoadMetaFile reads and parses a .meta sidecar file for the given tool name. @@ -86,9 +84,6 @@ func (m *MetaFile) Resolve() *MetaFile { if v.Scope != "" { resolved.Scope = v.Scope } - if v.ResetsCounter { - resolved.ResetsCounter = true - } if v.Cmd != "" { resolved.Cmd = v.Cmd } @@ -184,7 +179,6 @@ func ToolInfoFromMeta(name string, m *MetaFile) protocol.ToolInfo { Tier: tier, Scope: resolved.Scope, OutputFormat: resolved.OutputFormat, - ResetsCounter: resolved.ResetsCounter, } } diff --git a/toolsrv/protocol/types.go b/toolsrv/protocol/types.go index ab60247..f9d7fec 100644 --- a/toolsrv/protocol/types.go +++ b/toolsrv/protocol/types.go @@ -5,15 +5,14 @@ import "encoding/json" // ToolInfo describes a tool provided by a server. type ToolInfo struct { - Server string - Name string - Description string - InputSchema json.RawMessage - Prompt string - Tier string - Scope string - OutputFormat string - ResetsCounter bool + Server string + Name string + Description string + InputSchema json.RawMessage + Prompt string + Tier string + Scope string + OutputFormat string } // ToolResult is the structured result from a tool execution.