diff --git a/src/clean_agent_preview.py b/src/clean_agent_preview.py index 5ee0607c8..d4c157696 100644 --- a/src/clean_agent_preview.py +++ b/src/clean_agent_preview.py @@ -4393,10 +4393,11 @@ async def stream_preview(*, endpoint_url, model, messages, headers, turn_contrac retrievals=successful_web_retrievals, search_limit=2, ) - round_max_tokens = ( - min(request_max_tokens, 4096) - if artifact_body_handoff_target else request_max_tokens - ) + # Thinking providers can consume several thousand tokens before + # emitting the requested body. Reusing the configured output + # budget avoids a reasoning-only response that leaves the + # required artifact unwritten. + round_max_tokens = request_max_tokens request = {'model': model, 'messages': request_messages, 'temperature': temperature, 'max_tokens': round_max_tokens, 'stream': True, 'stream_options': {'include_usage': True}, diff --git a/tests/test_clean_agent_preview.py b/tests/test_clean_agent_preview.py index 5e9fd539b..6ca600135 100644 --- a/tests/test_clean_agent_preview.py +++ b/tests/test_clean_agent_preview.py @@ -613,7 +613,7 @@ async def test_repeated_off_contract_calls_recover_via_required_artifact_body(mo 'completion_requirements': { 'required_artifacts': ['/workspace/output.html'], }, - }, max_rounds=5, + }, max_tokens=8192, max_rounds=5, )] assert [block.tool_type for block in executed] == ['write_file'] @@ -622,6 +622,8 @@ async def test_repeated_off_contract_calls_recover_via_required_artifact_body(mo if message.get('role') == 'assistant' and message.get('tool_calls') ) assert prior_tool_turn['reasoning_content'] == 'reasoning-one' + assert requests[2]['max_tokens'] == 8192 + assert requests[3]['max_tokens'] == 8192 assert executed[0].content == ( '/workspace/output.html\nRecovered' )