# Fix potential infinite tool call loop by resetting tool_choice after tool execution ## Summary This PR fixes an issue where setting `tool_choice` to "required" or a specific function name could cause models to get stuck in an infinite tool call loop. When `tool_choice` is set to force tool usage, this setting persists across model invocations. This PR automatically resets `tool_choice` to "auto" after tool execution, allowing the model to decide whether to make additional tool calls in subsequent turns. Unlike using `tool_use_behavior="stop_on_first_tool"`, this approach lets the model continue processing tool results while preventing forced repeated tool calls. ## Test plan - Added tests to verify tool_choice reset behavior for both agent and run_config settings - Added integration test to verify the solution prevents infinite loops - All tests pass ## Checks - [x] I've added new tests for the fix - [x] I've updated the relevant documentation (added comment in code) - [x] I've run `make lint` and `make format` - [x] I've made sure tests pass |
||
|---|---|---|
| .. | ||
| tracing | ||
| voice | ||
| __init__.py | ||
| conftest.py | ||
| fake_model.py | ||
| README.md | ||
| test_agent_config.py | ||
| test_agent_hooks.py | ||
| test_agent_runner.py | ||
| test_agent_runner_streamed.py | ||
| test_agent_tracing.py | ||
| test_computer_action.py | ||
| test_config.py | ||
| test_doc_parsing.py | ||
| test_extension_filters.py | ||
| test_function_schema.py | ||
| test_function_tool.py | ||
| test_function_tool_decorator.py | ||
| test_global_hooks.py | ||
| test_guardrails.py | ||
| test_handoff_tool.py | ||
| test_items_helpers.py | ||
| test_max_turns.py | ||
| test_openai_chatcompletions.py | ||
| test_openai_chatcompletions_converter.py | ||
| test_openai_chatcompletions_stream.py | ||
| test_openai_responses_converter.py | ||
| test_output_tool.py | ||
| test_pretty_print.py | ||
| test_responses.py | ||
| test_responses_tracing.py | ||
| test_result_cast.py | ||
| test_run_config.py | ||
| test_run_step_execution.py | ||
| test_run_step_processing.py | ||
| test_strict_schema.py | ||
| test_tool_choice_reset.py | ||
| test_tool_converter.py | ||
| test_tool_use_behavior.py | ||
| test_trace_processor.py | ||
| test_tracing.py | ||
| test_tracing_errors.py | ||
| test_tracing_errors_streamed.py | ||
| testing_processor.py | ||
Tests
Before running any tests, make sure you have uv installed (and ideally run make sync after).
Running tests
make tests
Snapshots
We use inline-snapshots for some tests. If your code adds new snapshot tests or breaks existing ones, you can fix/create them. After fixing/creating snapshots, run make tests again to verify the tests pass.
Fixing snapshots
make snapshots-fix
Creating snapshots
make snapshots-update