Skip to content

Commit e8662bd

Browse files
committed
fix(agent): honor ACP iteration limits
1 parent 1aaea01 commit e8662bd

4 files changed

Lines changed: 61 additions & 2 deletions

File tree

internal/agent/agent.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,35 @@ import (
1414
"github.com/cnjack/jcode/internal/toolpolicy"
1515
)
1616

17-
const maxIterations = 1000
17+
const defaultMaxIterations = 1000
18+
19+
type agentOptions struct {
20+
maxIterations int
21+
}
22+
23+
// AgentOption configures one ChatModelAgent without changing the defaults used by
24+
// existing transports.
25+
type AgentOption func(*agentOptions)
26+
27+
// WithMaxIterations bounds the model/tool loop for the constructed agent.
28+
// Non-positive values retain the default for backward compatibility.
29+
func WithMaxIterations(limit int) AgentOption {
30+
return func(options *agentOptions) {
31+
if limit > 0 {
32+
options.maxIterations = limit
33+
}
34+
}
35+
}
36+
37+
func resolveAgentOptions(options ...AgentOption) agentOptions {
38+
resolved := agentOptions{maxIterations: defaultMaxIterations}
39+
for _, apply := range options {
40+
if apply != nil {
41+
apply(&resolved)
42+
}
43+
}
44+
return resolved
45+
}
1846

1947
type ApprovalFunc func(ctx context.Context, toolName, toolArgs string) (bool, error)
2048

@@ -47,10 +75,12 @@ func NewAgent(
4775
approvalFunc ApprovalFunc,
4876
middlewares []adk.ChatModelAgentMiddleware,
4977
handlers []adk.ChatModelAgentMiddleware,
78+
options ...AgentOption,
5079
) (*adk.ChatModelAgent, error) {
5180
return newAgent(
5281
ctx, chatmodel, tools, nil, toolDisclosureGroups{},
5382
instruction, approvalFunc, middlewares, handlers,
83+
options...,
5484
)
5585
}
5686

@@ -64,7 +94,9 @@ func newAgent(
6494
approvalFunc ApprovalFunc,
6595
middlewares []adk.ChatModelAgentMiddleware,
6696
handlers []adk.ChatModelAgentMiddleware,
97+
options ...AgentOption,
6798
) (*adk.ChatModelAgent, error) {
99+
resolvedOptions := resolveAgentOptions(options...)
68100
// Handler order is outermost → innermost: tracing middlewares first, then the
69101
// tool-search middleware, then the caller's state-rewriting handlers, and
70102
// finally the hook + approval + safe-tool-error stack. Tool search must inspect
@@ -138,7 +170,7 @@ func newAgent(
138170
Tools: append([]tool.BaseTool(nil), directTools...),
139171
},
140172
},
141-
MaxIterations: maxIterations,
173+
MaxIterations: resolvedOptions.maxIterations,
142174
Handlers: enhanced,
143175
ModelRetryConfig: &adk.ModelRetryConfig{
144176
MaxRetries: 5,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package agent
2+
3+
import "testing"
4+
5+
func TestResolveAgentOptionsMaxIterations(t *testing.T) {
6+
tests := []struct {
7+
name string
8+
options []AgentOption
9+
want int
10+
}{
11+
{name: "default", want: defaultMaxIterations},
12+
{name: "explicit limit", options: []AgentOption{WithMaxIterations(40)}, want: 40},
13+
{name: "non-positive limit keeps default", options: []AgentOption{WithMaxIterations(0)}, want: defaultMaxIterations},
14+
}
15+
16+
for _, tt := range tests {
17+
t.Run(tt.name, func(t *testing.T) {
18+
if got := resolveAgentOptions(tt.options...).maxIterations; got != tt.want {
19+
t.Fatalf("max iterations = %d, want %d", got, tt.want)
20+
}
21+
})
22+
}
23+
}

internal/agent/toolsearch_agent.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func NewAgentWithToolPlan(
3333
approvalFunc ApprovalFunc,
3434
middlewares []adk.ChatModelAgentMiddleware,
3535
handlers []adk.ChatModelAgentMiddleware,
36+
options ...AgentOption,
3637
) (*adk.ChatModelAgent, error) {
3738
direct, deferred, disclosureGroups, err := executableToolsFromPlan(ctx, plan)
3839
if err != nil {
@@ -44,6 +45,7 @@ func NewAgentWithToolPlan(
4445
return newAgent(
4546
ctx, chatmodel, direct, deferred, disclosureGroups,
4647
instruction, approvalFunc, middlewares, handlers,
48+
options...,
4749
)
4850
}
4951

internal/command/acp.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,7 @@ func (a *acpAgent) buildAgentSession(
824824
return agent.NewAgent(
825825
agentCtx, chatModel, staticTools, sysPrompt,
826826
approvalState.RequestApproval, nil, handlers,
827+
agent.WithMaxIterations(cfg.MaxIterations),
827828
)
828829
}
829830
toolMode := agent.ToolModeNormal
@@ -839,6 +840,7 @@ func (a *acpAgent) buildAgentSession(
839840
return agent.NewAgentWithToolPlan(
840841
agentCtx, chatModel, toolPlan, sysPrompt,
841842
approvalState.RequestApproval, nil, handlers,
843+
agent.WithMaxIterations(cfg.MaxIterations),
842844
)
843845
}
844846
newSessionAgent := func(

0 commit comments

Comments
 (0)