Skip to content

Commit fe9f06e

Browse files
Narrow agent tool fallback to current-run items
Co-authored-by: Codex <noreply@openai.com>
1 parent 052339a commit fe9f06e

2 files changed

Lines changed: 113 additions & 12 deletions

File tree

src/agents/agent.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -855,18 +855,25 @@ async def dispatch_stream_events() -> None:
855855
):
856856
return run_result.final_output
857857

858-
from .items import ItemHelpers
859-
860-
text_output = ItemHelpers.text_message_outputs(run_result.new_items)
861-
if text_output:
862-
return text_output
863-
864-
for item in reversed(run_result.to_input_list()):
865-
if item.get("type") != "function_call_output":
866-
continue
867-
output = item.get("output")
868-
if isinstance(output, str) and output:
869-
return output
858+
from .items import ItemHelpers, MessageOutputItem, ToolCallOutputItem
859+
860+
latest_tool_output: str | None = None
861+
for item in reversed(run_result.new_items):
862+
if isinstance(item, MessageOutputItem):
863+
text_output = ItemHelpers.text_message_output(item)
864+
if text_output:
865+
return text_output
866+
867+
if (
868+
latest_tool_output is None
869+
and isinstance(item, ToolCallOutputItem)
870+
and isinstance(item.output, str)
871+
and item.output
872+
):
873+
latest_tool_output = item.output
874+
875+
if latest_tool_output is not None:
876+
return latest_tool_output
870877

871878
return run_result.final_output
872879

tests/test_agent_as_tool.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
Session,
3131
SessionSettings,
3232
ToolApprovalItem,
33+
ToolCallOutputItem,
3334
TResponseInputItem,
3435
Usage,
3536
tool_namespace,
@@ -407,6 +408,99 @@ async def extractor(result) -> str:
407408
assert output == "custom output"
408409

409410

411+
@pytest.mark.asyncio
412+
async def test_agent_as_tool_fallback_uses_current_run_items_only(
413+
monkeypatch: pytest.MonkeyPatch,
414+
) -> None:
415+
agent = Agent(name="summarizer")
416+
417+
message = ResponseOutputMessage(
418+
id="msg_current",
419+
role="assistant",
420+
status="completed",
421+
type="message",
422+
content=[
423+
ResponseOutputText(
424+
annotations=[],
425+
text="Current run summary",
426+
type="output_text",
427+
logprobs=[],
428+
)
429+
],
430+
)
431+
432+
class DummyResult:
433+
def __init__(self) -> None:
434+
self.final_output = ""
435+
self.new_items = [
436+
ToolCallOutputItem(
437+
agent=agent,
438+
raw_item={
439+
"call_id": "call_current",
440+
"output": "Current tool output",
441+
"type": "function_call_output",
442+
},
443+
output="Current tool output",
444+
),
445+
MessageOutputItem(agent=agent, raw_item=message),
446+
]
447+
448+
def to_input_list(self) -> list[dict[str, Any]]:
449+
return [
450+
{
451+
"call_id": "call_old",
452+
"output": "Old output from prior history",
453+
"type": "function_call_output",
454+
}
455+
]
456+
457+
run_result = DummyResult()
458+
459+
async def fake_run(
460+
cls,
461+
starting_agent,
462+
input,
463+
*,
464+
context,
465+
max_turns,
466+
hooks,
467+
run_config,
468+
previous_response_id,
469+
conversation_id,
470+
session,
471+
):
472+
del (
473+
cls,
474+
starting_agent,
475+
input,
476+
context,
477+
max_turns,
478+
hooks,
479+
run_config,
480+
previous_response_id,
481+
conversation_id,
482+
session,
483+
)
484+
return run_result
485+
486+
monkeypatch.setattr(Runner, "run", classmethod(fake_run))
487+
488+
tool = agent.as_tool(
489+
tool_name="summary_tool",
490+
tool_description="Summarize current run output",
491+
)
492+
tool_context = ToolContext(
493+
context=None,
494+
tool_name="summary_tool",
495+
tool_call_id="call_1",
496+
tool_arguments='{"input": "hello"}',
497+
)
498+
499+
output = await tool.on_invoke_tool(tool_context, '{"input": "hello"}')
500+
501+
assert output == "Current run summary"
502+
503+
410504
@pytest.mark.asyncio
411505
async def test_agent_as_tool_extractor_can_access_agent_tool_invocation(
412506
monkeypatch: pytest.MonkeyPatch,

0 commit comments

Comments
 (0)