remove maxSteps and ResetsCounter entirely
The step budget mechanism is gone. Agents run until they finish, are interrupted by the user, or (for sub-agents) hit the timeout. No replacement. The human is the kill switch.
This commit is contained in:
parent
da0ee4456f
commit
74ba5ae7ac
|
|
@ -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"`
|
||||
|
|
|
|||
|
|
@ -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("<system-step-budget-warning>\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</system-step-budget-warning>", 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("<system-step-budget-stop>\nStep budget exhausted (%d/%d steps used). Stop calling tools. Summarize what you have done and what remains, then stop.\n</system-step-budget-stop>", 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
"lsp_rename",
|
||||
"lsp_completion"
|
||||
],
|
||||
"maxSteps": 25,
|
||||
"temperature": 0.5,
|
||||
"maxTokens": 16384
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
],
|
||||
"backend": "openrouter",
|
||||
"model": "deepseek/deepseek-v4-flash",
|
||||
"maxSteps": 25,
|
||||
"temperature": 0.4,
|
||||
"maxTokens": 16384
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
"code_rewrite",
|
||||
"code_dependencies"
|
||||
],
|
||||
"maxSteps": 40,
|
||||
"temperature": 0.3,
|
||||
"maxTokens": 16384
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
"memory_recall",
|
||||
"memory_remember"
|
||||
],
|
||||
"maxSteps": 20,
|
||||
"temperature": 0.3,
|
||||
"maxTokens": 16384
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,5 @@
|
|||
"code_dependencies"
|
||||
],
|
||||
"temperature": 0.3,
|
||||
"maxTokens": 8192,
|
||||
"maxSteps": 30
|
||||
"maxTokens": 8192
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
"lsp_rename",
|
||||
"lsp_completion"
|
||||
],
|
||||
"maxSteps": 5,
|
||||
"temperature": 0.3,
|
||||
"maxTokens": 4096
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
"memory_recall",
|
||||
"memory_remember"
|
||||
],
|
||||
"maxSteps": 20,
|
||||
"temperature": 0.3,
|
||||
"maxTokens": 8192
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
"file_grep",
|
||||
"file_write"
|
||||
],
|
||||
"maxSteps": 30,
|
||||
"temperature": 0.3,
|
||||
"maxTokens": 8192
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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=\"<ABSOLUTE_PATH_FROM_PWD>\", old_string=\"old text\", new_string=\"new text\")\nfile_edit(path=\"<ABSOLUTE_PATH_FROM_PWD>\", 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",
|
||||
|
|
|
|||
|
|
@ -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=\"<ABSOLUTE_PATH_FROM_PWD>\", content=\"file content here\")\n```\n\n**Constraints**: Absolute paths only. Parent directory must exist.",
|
||||
"args": {
|
||||
"type": "object",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue