Skip to content

feat: add session resume support and loop resilience#17

Merged
axeldelafosse merged 3 commits intomainfrom
feat/session-resume-and-loop-resilience
Feb 25, 2026
Merged

feat: add session resume support and loop resilience#17
axeldelafosse merged 3 commits intomainfrom
feat/session-resume-and-loop-resilience

Conversation

@axeldelafosse
Copy link
Copy Markdown
Owner

Summary

  • add --session <id> and wire session/thread resume IDs through the loop runner for both Claude and Codex
  • surface current session/thread IDs in loop iteration logs and print resume hints when agent runs fail
  • make loop iterations more resilient by continuing after non-zero exits/runtime errors and supporting configurable cooldowns between iterations

Transport + Review Reliability

  • Claude SDK server: detect background Task tool calls, drain background workers before continuing, and add internals for timeout/poll tuning in tests
  • Codex app-server: support resuming an existing thread and ignore foreign subagent turn/error notifications so parent turns are not failed by unrelated events
  • review parsing: prefer clean parsed output when explicit review signals are present and ignore noisy transport frames in combined output

Tests

  • add tests/loop/claude-sdk-server.test.ts for immediate completion, background drain/continue flow, non-Task behavior, and timeout behavior
  • add a Codex app-server regression test for foreign subagent turn notifications
  • update loop tests to assert non-zero exits no longer abort the run loop
  • add review-run coverage for transport-noise scenarios

Validation

  • bun run check
  • bun test

Add --session support to resume Claude/Codex conversations and surface resume hints from the latest session/thread IDs. Improve loop stability by continuing after agent runtime failures and non-zero exits, with per-iteration cooldown support. Harden transport handling by draining Claude background Task workers before continuation and ignoring foreign subagent events in Codex app-server responses. Tighten review signal parsing to prefer clean parsed output when transport noise is present. Extend tests across main loop behavior, Claude SDK background draining, Codex subagent filtering, and review parsing.
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @axeldelafosse, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the robustness and usability of the agent loop runner. By introducing session resume capabilities, users can seamlessly pick up agent work where they left off, improving workflow continuity. The added loop resilience ensures that temporary agent failures or non-zero exits do not halt the entire process, making long-running tasks more stable. Furthermore, targeted improvements to both Claude SDK and Codex app-server interactions, along with smarter review parsing, contribute to a more reliable and predictable agent execution environment.

Highlights

  • Session Resume Support: Introduced a new --session <id> command-line argument to allow resuming previous agent sessions or threads for both Claude and Codex. Current session/thread IDs are now surfaced in loop iteration logs, and resume hints are printed when agent runs fail.
  • Loop Resilience Improvements: Enhanced the loop runner to continue iterations even after non-zero exits or runtime errors from agents, preventing premature termination. Configurable cooldowns between iterations have also been added for better stability.
  • Claude SDK Server Enhancements: Implemented detection and draining of background Task tool calls before continuing, ensuring all background work is completed. Internal mechanisms for timeout and child process polling have been added for tuning and testing.
  • Codex App-Server Refinements: Enabled the Codex app-server to support resuming an existing thread. It now also ignores foreign subagent turn/error notifications, preventing unrelated events from failing parent turns.
  • Review Parsing Reliability: Improved review parsing logic to prefer clean parsed output when explicit review signals are present, effectively ignoring noisy transport frames that might appear in combined output.
Changelog
  • src/loop/args.ts
    • Added parsing for the new --session command-line argument to capture a session ID.
  • src/loop/claude-sdk-server.ts
    • Introduced spawnSync and ServeFn types for internal use and testing.
    • Expanded TurnState interface with backgroundTaskSeen and drainingBackground flags to manage background processes.
    • Added constants for background task continuation messages and default child process polling intervals.
    • Implemented countChildProcesses function to track active child processes for background task draining.
    • Exposed internal functions (setServeFn, setSpawnFn, setCountChildProcessesFn, setChildPollIntervalMs, setWaitTimeoutMs) for testing and tuning.
    • Added lastSessionId and resumeId fields to ClaudeSdkClient to manage session state.
    • Implemented getLastSessionId and setResumeId methods for session management.
    • Modified start method to include --resume argument when spawning the Claude SDK child process if a resumeId is set.
    • Updated createServer to use serveFn for testability.
    • Added logic to store and log the sessionId upon initialization.
    • Implemented background task draining logic within handleMessage to wait for child processes to complete before continuing.
    • Added sendUserMessage helper function for sending user messages to the Claude SDK.
    • Updated runTurnExclusive to use configurable waitTimeoutMs and initialize new TurnState with background task flags.
    • Modified startClaudeSdk to accept an optional resumeSessionId for resuming sessions.
    • Exported getLastClaudeSessionId to retrieve the last active Claude session ID.
  • src/loop/codex-app-server.ts
    • Added lastThreadId field to AppServerClient for tracking the last active thread.
    • Implemented getLastThreadId method to retrieve the last active Codex thread ID.
    • Modified runTurn to accept an optional resumeThreadId parameter.
    • Updated ensureThread to support resuming an existing thread if resumeThreadId is provided, otherwise starts a new one.
    • Ensured lastThreadId is updated when a new thread is started or resumed.
    • Simplified findTurnState logic to directly return the turn state if found.
    • Enhanced handleError and handleTurnCompleted to ignore notifications for unknown or foreign turnIds, preventing unrelated subagent events from failing the parent turn.
    • Modified runCodexTurn to pass the resumeThreadId to the underlying runTurn method.
    • Exported getLastCodexThreadId to retrieve the last active Codex thread ID.
  • src/loop/constants.ts
    • Updated the HELP text to include the new --session <id> option.
    • Added session to the VALUE_FLAGS mapping for argument parsing.
  • src/loop/main.ts
    • Introduced ITERATION_COOLDOWN_MS for configurable delays between loop iterations.
    • Added sleep and iterationCooldown utility functions.
    • Implemented lastSession to retrieve the last session/thread ID based on the agent.
    • Added logSessionHint to provide resume instructions upon agent failure.
    • Introduced logIterationHeader to display current iteration and session ID in logs.
    • Created tryRunAgent to wrap agent execution, catching errors and logging hints without aborting the loop.
    • Modified runIterations to incorporate iterationCooldown, logIterationHeader, and tryRunAgent for improved resilience and logging. Agent non-zero exits now log an error and continue the loop instead of throwing.
  • src/loop/review.ts
    • Introduced cleanOutputText to remove carriage returns and trim whitespace from text.
    • Added hasExplicitSignal to check for explicit review signals in output.
    • Refactored cleanOutput to prioritize parsed output over combined output if explicit review signals are present in the parsed output, effectively filtering out transport noise.
  • src/loop/runner.ts
    • Updated LegacyAgentRunner type to include an optional sessionId parameter.
    • Modified runnerState.runLegacyAgent to pass the sessionId parameter.
    • Adjusted buildCommand to conditionally include --resume <sessionId> argument for Claude agents.
    • Updated runCodexAgent and runClaudeAgent to accept and pass an optional sessionId.
    • Modified the main runAgent function to extract sessionId from opts and pass it to the specific agent runners, then unset it from opts.
  • src/loop/types.ts
    • Extended ValueFlag type to include session for argument parsing.
    • Added an optional sessionId property to the Options interface.
  • tests/loop/claude-sdk-server.test.ts
    • Added a new test file to cover Claude SDK server functionality.
    • Included tests for immediate resolution when no background tasks are detected.
    • Added tests for draining background Task workers and sending continuation messages.
    • Verified that non-Task tools with run_in_background do not trigger drain mode.
    • Confirmed that timeouts correctly reject even when background workers are present.
  • tests/loop/codex-app-server.test.ts
    • Added a regression test to ensure runCodexTurn correctly ignores foreign subagent turn notifications.
  • tests/loop/main.test.ts
    • Set LOOP_COOLDOWN_MS to '0' in test environment for consistent test execution.
    • Updated tests to assert that runLoop now continues iterations after non-zero agent exits, rather than throwing an error.
  • tests/loop/review-run.test.ts
    • Added a test to confirm runReview ignores transport noise in combined output when the parsed output contains a final pass signal.
Activity
  • Added tests/loop/claude-sdk-server.test.ts to cover new Claude SDK server features, including background task draining and timeout behavior.
  • Added a regression test in tests/loop/codex-app-server.test.ts to validate the handling of foreign subagent turn notifications.
  • Updated existing loop tests to confirm that non-zero agent exits no longer abort the run loop, reflecting the new resilience features.
  • Included review-run coverage for scenarios involving transport noise in combined output.
  • Validated changes by running bun run check and bun test.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces significant enhancements, including session resume capabilities for both Claude and Codex agents via a --session flag, and improved resilience for the main execution loop. The loop now gracefully handles non-zero exit codes and runtime errors by continuing to the next iteration, and includes a configurable cooldown period. The Claude SDK server is now more robust, with logic to detect and wait for background tasks to complete before proceeding. The Codex app-server is also improved to support thread resumption and to ignore notifications from unrelated sub-agents, preventing them from failing the parent turn. The changes are well-tested, with new unit tests covering the complex new behaviors in the Claude SDK server, a regression test for the Codex app-server, and updates to existing tests to assert the new loop resilience. My feedback includes a suggestion for more robust parsing of an environment variable and another to improve code clarity with a comment.

Comment thread src/loop/main.ts Outdated
Comment thread src/loop/runner.ts Outdated
Move iteration helpers (cooldown, session logging, tryRunAgent,
formatFollowUp) from main.ts into iteration.ts to bring main.ts back
under the 100-line limit. Pass sessionId as an explicit parameter to
runAgent instead of mutating opts. Rename src/loop.ts to src/cli.ts to
reduce confusion with the src/loop/ directory.
@axeldelafosse axeldelafosse merged commit 67afeb0 into main Feb 25, 2026
2 checks passed
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.

1 participant