MCPcopy
hub / github.com/docker/docker-agent / enforceMaxIterations

Method enforceMaxIterations

pkg/runtime/loop_steps.go:48–112  ·  view source on GitHub ↗

enforceMaxIterations runs at the top of every loop iteration. When the iteration count has reached the limit, it emits MaxIterationsReached and drives the appropriate exit/resume flow: - non-interactive sessions auto-stop with an assistant message, - interactive sessions block on r.resumeChan until

(
	ctx context.Context,
	sess *session.Session,
	a *agent.Agent,
	iteration int,
	runtimeMaxIterations int,
	events EventSink,
)

Source from the content-addressed store, hash-verified

46// tests that pump the resume channel and assert the resulting events
47// without standing up a full model + toolset pipeline.
48func (r *LocalRuntime) enforceMaxIterations(
49 ctx context.Context,
50 sess *session.Session,
51 a *agent.Agent,
52 iteration int,
53 runtimeMaxIterations int,
54 events EventSink,
55) (newMax int, decision iterationDecision) {
56 if runtimeMaxIterations <= 0 || iteration < runtimeMaxIterations {
57 return runtimeMaxIterations, iterationContinue
58 }
59
60 slog.DebugContext(ctx, "Maximum iterations reached",
61 "agent", a.Name(),
62 "iterations", iteration,
63 "max", runtimeMaxIterations,
64 )
65
66 events.Emit(MaxIterationsReached(runtimeMaxIterations))
67
68 maxIterMsg := fmt.Sprintf("Maximum iterations reached (%d)", runtimeMaxIterations)
69 r.notifyMaxIterations(ctx, a, sess.ID, maxIterMsg)
70 r.executeOnUserInputHooks(ctx, sess.ID, "max iterations reached")
71
72 stopMsg := fmt.Sprintf(
73 "Execution stopped after reaching the configured max_iterations limit (%d).",
74 runtimeMaxIterations,
75 )
76 appendStopMsg := func() {
77 addAgentMessage(sess, a, &chat.Message{
78 Role: chat.MessageRoleAssistant,
79 Content: stopMsg,
80 CreatedAt: r.now().Format(time.RFC3339),
81 }, events)
82 }
83
84 // In non-interactive mode (e.g. MCP server), auto-stop instead of
85 // blocking forever waiting for user input.
86 if sess.NonInteractive {
87 slog.DebugContext(ctx, "Auto-stopping after max iterations (non-interactive)", "agent", a.Name())
88 appendStopMsg()
89 return runtimeMaxIterations, iterationStop
90 }
91
92 // Wait for user decision (resume / reject)
93 select {
94 case req := <-r.resumeChan:
95 if req.Type == ResumeTypeApprove {
96 slog.DebugContext(ctx, "User chose to continue after max iterations", "agent", a.Name())
97 newMax := iteration + 10
98 r.executeOnSessionResumeHooks(ctx, a, sess.ID, runtimeMaxIterations, newMax)
99 return newMax, iterationContinue
100 }
101 slog.DebugContext(ctx, "User rejected continuation", "agent", a.Name())
102 appendStopMsg()
103 return runtimeMaxIterations, iterationStop
104
105 case <-ctx.Done():

Calls 8

notifyMaxIterationsMethod · 0.95
MaxIterationsReachedFunction · 0.85
addAgentMessageFunction · 0.85
nowMethod · 0.80
NameMethod · 0.65
EmitMethod · 0.65