Skip to content

🦌 Generate graceful summary when maxSteps exhausted mid-tool-call#49

Merged
masudahiroto merged 7 commits intomainfrom
deer/fix-graceful-summary-on-max-steps
Apr 6, 2026
Merged

🦌 Generate graceful summary when maxSteps exhausted mid-tool-call#49
masudahiroto merged 7 commits intomainfrom
deer/fix-graceful-summary-on-max-steps

Conversation

@masudahiroto
Copy link
Copy Markdown
Contributor

@masudahiroto masudahiroto commented Apr 1, 2026

Summary

When an agent exhausts its maxSteps limit while still mid-tool-call chain, it previously ended abruptly without producing a final text response. This change adds a graceful summary step: after the last allowed step, if the final step ended with tool calls (meaning the model never got to produce a text response), an extra step is run with tools stripped and a prompt injected asking the model to summarize its progress.

Changes

  • AISDKAgent.ts: Added lastStepHadToolCalls tracking to RunContext; extended the step loop by one iteration to allow a graceful summary step; introduced applyGracefulSummaryOverrides() to strip tools and inject a summary prompt on the extra step; refactored streamText call to use a shared stepConfig object for cleaner metadata/tools management.
  • AISDKAgent.maxSteps.test.ts: Added createToolThenTextMockModel helper for testing the graceful summary path; updated existing call-count assertions to account for the extra summary step; added new tests verifying that a text message is emitted after maxSteps when last step had tool calls, and that no extra call is made when the run completes normally without tool calls.

Created by deer — review carefully.

…ll chain

When the for loop exhausts maxSteps while still processing tool calls,
make one final streamText call without tools so the model can summarize
its progress, instead of silently stopping mid-execution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The graceful summary call (triggered when maxSteps is exhausted) was
missing the experimental_telemetry option, so Langfuse did not record it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

// Graceful finish: if maxSteps was exhausted while still in a tool-call chain,
// make one final streamText call without tools so the model can summarize progress.
if (lastStepHadToolCalls) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same feedback as #50

It would be nice to try and keep this file a bit cleaner and cover edge cases with functions such that the main logic can be simplified into a function call which handles the edge case if it exists, or no-ops if it doesn't.

@masudahiroto masudahiroto changed the title 🦌 Fix: generate graceful summary when maxSteps exhausted mid-tool-call 🦌 Generate graceful summary when maxSteps exhausted mid-tool-call Apr 1, 2026

// Graceful finish: if maxSteps was exhausted while still in a tool-call chain,
// make one final streamText call without tools so the model can summarize progress.
const gracefulSummary = await generateGracefulSummaryIfNeeded({
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function needs so many arguments :(
it implies a really tight coupling
can we simplify somehow? maybe some of the decision making has to move back into AISDKAgent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you. This function has many arguments and its structure is not ideal. I'll consider how we can solve this. Thank you for your review 🙇

Copy link
Copy Markdown
Contributor Author

@masudahiroto masudahiroto Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mm-zacharydavison I refactored the graceful summary step.

It is now integrated into the main agent loop. The loop iterates one extra time beyond maxSteps, and the last iteration (stepIteration === this.maxSteps) is treated as the graceful summary step, where the messages, tools, and metadata are overridden specifically for summarization. Some minor refactoring of AISDKAgent is also included.

@masudahiroto
Copy link
Copy Markdown
Contributor Author

sorry but i will merge #53 first. please wait a minutes to fix merge conflicts

Resolve conflicts in AISDKAgent.ts by applying graceful summary
feature (lastStepHadToolCalls, applyGracefulSummaryOverrides,
stepConfig) onto main's refactored structure (RunContext, StepContext,
executeStepLoop, processStreamChunk).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@masudahiroto
Copy link
Copy Markdown
Contributor Author

I fixed the merge conflict caused by refactoring of AISDKAgent. Please re-review it. I apologize for requesting many reviews.

@masudahiroto masudahiroto merged commit 1e82ba3 into main Apr 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants