Skip to content

Conversation

@zzstoatzz
Copy link
Collaborator

summary

fixes infinite loop and "multiple endturn tools" warning when using allow_fail=True

root cause

  • when a task has allow_fail=True, it creates two endturn tools: MarkTaskSuccessful and MarkTaskFailed
  • previous code (agent.py:186) set output_type=type(None) when >1 endturn tool detected
  • this caused the agent to not validate its output as an EndTurn, leading to infinite loop with repeated "Multiple EndTurn tools detected" warnings

solution

  • use Union[Tool1, Tool2] as output_type when multiple endturn tools exist
  • this allows pydantic_ai to properly validate the agent's response as one of the union types
  • the model can now choose between marking the task successful or failed

testing

  • added 3 new tests in tests/basic/tasks/test_tasks.py::TestAllowFail:
    • test that tasks with allow_fail complete without infinite loop (regression test)
    • test that allow_fail creates both MarkTaskSuccessful and MarkTaskFailed tools
    • test that multiple EndTurn tools result in Union output type
  • manually tested with repros - tasks can now properly succeed OR fail
  • 61/62 existing tests pass (1 failure due to API connection issue, not our change)

related

🤖 Generated with Claude Code

zzstoatzz and others added 2 commits September 29, 2025 14:46
fixes infinite loop and "multiple endturn tools" warning when using allow_fail=True

**root cause**
- when a task has allow_fail=True, it creates two endturn tools: MarkTaskSuccessful and MarkTaskFailed
- previous code (line 186) set output_type=type(None) when >1 endturn tool detected
- this caused the agent to not validate its output as an EndTurn, leading to infinite loop

**solution**
- use Union[Tool1, Tool2] as output_type when multiple endturn tools exist
- this allows pydantic_ai to properly validate the agent's response as one of the union types
- the model can now choose between marking the task successful or failed

**testing**
- tested with allow_fail=True - tasks can now properly succeed OR fail
- no more infinite loops
- no more "multiple endturn tools" warnings
- 58/59 existing tests pass (1 failure due to API connection issue, not our change)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- test that tasks with allow_fail complete without infinite loop
- test that allow_fail creates both MarkTaskSuccessful and MarkTaskFailed tools
- test that multiple EndTurn tools result in Union output type

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions bot added the tests label Sep 29, 2025
@zzstoatzz zzstoatzz marked this pull request as ready for review September 29, 2025 19:51
Copilot AI review requested due to automatic review settings September 29, 2025 19:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes an infinite loop issue that occurred when using tasks with allow_fail=True, which creates multiple EndTurn tools. The solution replaces the previous workaround of setting output_type=type(None) with a proper Union type that allows the model to choose between success and failure tools.

  • Replaced type(None) with Union[Tool1, Tool2] for multiple EndTurn tools to enable proper validation
  • Removed the warning about multiple EndTurn tools since this is now properly handled
  • Added comprehensive test coverage for the allow_fail functionality

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/marvin/agents/agent.py Updated logic to use Union type for multiple EndTurn tools instead of type(None)
tests/basic/tasks/test_tasks.py Added new test class with 3 tests covering allow_fail functionality and regression testing
Comments suppressed due to low confidence (1)

tests/basic/tasks/test_tasks.py:1

  • The test accesses private attribute _output_type and doesn't verify the Union contains the expected tool types. Consider using public APIs if available, and assert that the Union contains the specific MarkTaskSuccessful and MarkTaskFailed tool types.
import enum

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@zzstoatzz zzstoatzz added the fix Pull requests that fix bugs label Sep 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Pull requests that fix bugs tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants