Skip to content

Commit 069370f

Browse files
committed
feat(items): add tool call convenience accessors
1 parent 4977f35 commit 069370f

2 files changed

Lines changed: 68 additions & 10 deletions

File tree

src/agents/items.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -364,17 +364,25 @@ class ToolCallItem(RunItemBase[Any]):
364364

365365
@property
366366
def tool_name(self) -> str | None:
367-
"""Return the tool name from the raw item, if available."""
367+
"""Return the tool name from the raw item when available."""
368368
if isinstance(self.raw_item, dict):
369-
return self.raw_item.get("name")
370-
return getattr(self.raw_item, "name", None)
369+
candidate = self.raw_item.get("name") or self.raw_item.get("tool_name")
370+
else:
371+
candidate = getattr(self.raw_item, "name", None) or getattr(
372+
self.raw_item, "tool_name", None
373+
)
374+
return str(candidate) if candidate is not None else None
371375

372376
@property
373377
def call_id(self) -> str | None:
374-
"""Return the call identifier from the raw item, if available."""
378+
"""Return the call identifier from the raw item when available."""
375379
if isinstance(self.raw_item, dict):
376-
return self.raw_item.get("call_id") or self.raw_item.get("id")
377-
return getattr(self.raw_item, "call_id", None) or getattr(self.raw_item, "id", None)
380+
candidate = self.raw_item.get("call_id") or self.raw_item.get("id")
381+
else:
382+
candidate = getattr(self.raw_item, "call_id", None) or getattr(
383+
self.raw_item, "id", None
384+
)
385+
return str(candidate) if candidate is not None else None
378386

379387

380388
ToolCallOutputTypes: TypeAlias = (
@@ -405,11 +413,14 @@ class ToolCallOutputItem(RunItemBase[Any]):
405413

406414
@property
407415
def call_id(self) -> str | None:
408-
"""Return the call identifier from the raw item, if available."""
416+
"""Return the call identifier from the raw item when available."""
409417
if isinstance(self.raw_item, dict):
410-
cid = self.raw_item.get("call_id") or self.raw_item.get("id")
411-
return str(cid) if cid is not None else None
412-
return getattr(self.raw_item, "call_id", None) or getattr(self.raw_item, "id", None)
418+
candidate = self.raw_item.get("call_id") or self.raw_item.get("id")
419+
else:
420+
candidate = getattr(self.raw_item, "call_id", None) or getattr(
421+
self.raw_item, "id", None
422+
)
423+
return str(candidate) if candidate is not None else None
413424

414425
def to_input_item(self) -> TResponseInputItem:
415426
"""Converts the tool output into an input item for the next model turn.

tests/test_run_internal_items.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from agents.items import (
1616
ReasoningItem,
1717
ToolCallItem,
18+
ToolCallOutputItem,
1819
ToolSearchCallItem,
1920
ToolSearchOutputItem,
2021
TResponseInputItem,
@@ -550,6 +551,52 @@ def test_run_item_to_input_item_omits_tool_call_metadata() -> None:
550551
assert "title" not in result_dict
551552

552553

554+
def test_tool_call_item_exposes_convenience_properties_for_typed_raw_items() -> None:
555+
agent = Agent(name="A")
556+
item = ToolCallItem(
557+
agent=agent,
558+
raw_item=ResponseFunctionToolCall(
559+
id="fc_123",
560+
call_id="call_123",
561+
name="lookup_account",
562+
arguments="{}",
563+
type="function_call",
564+
status="completed",
565+
),
566+
)
567+
568+
assert item.tool_name == "lookup_account"
569+
assert item.call_id == "call_123"
570+
571+
572+
def test_tool_call_item_exposes_convenience_properties_for_dict_raw_items() -> None:
573+
agent = Agent(name="A")
574+
item = ToolCallItem(
575+
agent=agent,
576+
raw_item={
577+
"id": "fc_456",
578+
"call_id": "call_456",
579+
"name": "lookup_account",
580+
"arguments": "{}",
581+
"type": "function_call",
582+
},
583+
)
584+
585+
assert item.tool_name == "lookup_account"
586+
assert item.call_id == "call_456"
587+
588+
589+
def test_tool_call_output_item_exposes_call_id_for_dict_raw_items() -> None:
590+
agent = Agent(name="A")
591+
item = ToolCallOutputItem(
592+
agent=agent,
593+
raw_item={"type": "function_call_output", "call_id": "call_456", "output": "ok"},
594+
output="ok",
595+
)
596+
597+
assert item.call_id == "call_456"
598+
599+
553600
def test_normalize_input_items_for_api_strips_internal_tool_call_metadata() -> None:
554601
item = cast(
555602
TResponseInputItem,

0 commit comments

Comments
 (0)