Skip to content

feat: recover from context overflow during agent steps#40

Open
MohamedAkbarally wants to merge 3 commits intofix/normalize-embedded-json-tool-args-flagfrom
feat/step-with-overflow-recovery
Open

feat: recover from context overflow during agent steps#40
MohamedAkbarally wants to merge 3 commits intofix/normalize-embedded-json-tool-args-flagfrom
feat/step-with-overflow-recovery

Conversation

@MohamedAkbarally
Copy link
Copy Markdown
Contributor

@MohamedAkbarally MohamedAkbarally commented Apr 6, 2026

Summary

  • catch ContextOverflowError in the agent loop and summarize once before retrying the same turn
  • allow existing client-side ContextOverflowError translations to trigger end-to-end overflow recovery

Retry the same turn after summarizing when the client reports a context overflow so agent runs can continue past provider context-window failures.

Made-with: Cursor
@MohamedAkbarally MohamedAkbarally changed the title fix: recover from context overflow during agent steps feat: recover from context overflow during agent steps Apr 6, 2026
Retry message summarization on a shorter history by preserving the newest assistant-led turn, and raise a clear ContextOverflowError when nothing remains to peel.

Made-with: Cursor
Copy link
Copy Markdown
Collaborator

@declanjackson declanjackson left a comment

Choose a reason for hiding this comment

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

LGTM - maybe we should quickly mention this logic in concepts.md?

Comment thread src/stirrup/core/agent.py
Comment on lines +1148 to +1150
task_context: list[ChatMessage] = list(
takewhile(lambda m: not isinstance(m, (AssistantMessage, SummaryMessage)), messages_to_summarize)
)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This can be out of the loop right?

Comment thread src/stirrup/core/agent.py Outdated
# UserMessage (not AssistantMessage) to avoid consecutive assistant messages which some providers reject
acknowledgement_msg = UserMessage(content="Got it, thanks!")
messages_to_summarize, latest_suffix = split_messages
preserved_tail = [*latest_suffix, *preserved_tail]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I wonder if we log every time we peel for observability? Or maybe just build in num messages peeled into the summarization logging

Reset token usage on assistant messages copied into post-summary trajectories so history snapshots do not double count preserved turns.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants