Skip to content

Commit 5b86130

Browse files
committed
feat(items): add tool call convenience accessors
1 parent 2cf2c09 commit 5b86130

2 files changed

Lines changed: 80 additions & 0 deletions

File tree

src/agents/items.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,28 @@ class ToolCallItem(RunItemBase[Any]):
362362
tool_origin: ToolOrigin | None = None
363363
"""Optional metadata describing the source of a function-tool-backed item."""
364364

365+
@property
366+
def tool_name(self) -> str | None:
367+
"""Return the tool name from the raw item when available."""
368+
if isinstance(self.raw_item, dict):
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
375+
376+
@property
377+
def call_id(self) -> str | None:
378+
"""Return the call identifier from the raw item when available."""
379+
if isinstance(self.raw_item, dict):
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
386+
365387

366388
ToolCallOutputTypes: TypeAlias = (
367389
FunctionCallOutput
@@ -389,6 +411,17 @@ class ToolCallOutputItem(RunItemBase[Any]):
389411
tool_origin: ToolOrigin | None = None
390412
"""Optional metadata describing the source of a function-tool-backed item."""
391413

414+
@property
415+
def call_id(self) -> str | None:
416+
"""Return the call identifier from the raw item when available."""
417+
if isinstance(self.raw_item, dict):
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
424+
392425
def to_input_item(self) -> TResponseInputItem:
393426
"""Converts the tool output into an input item for the next model turn.
394427

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,
@@ -489,6 +490,52 @@ def test_run_item_to_input_item_omits_tool_call_metadata() -> None:
489490
assert "title" not in result_dict
490491

491492

493+
def test_tool_call_item_exposes_convenience_properties_for_typed_raw_items() -> None:
494+
agent = Agent(name="A")
495+
item = ToolCallItem(
496+
agent=agent,
497+
raw_item=ResponseFunctionToolCall(
498+
id="fc_123",
499+
call_id="call_123",
500+
name="lookup_account",
501+
arguments="{}",
502+
type="function_call",
503+
status="completed",
504+
),
505+
)
506+
507+
assert item.tool_name == "lookup_account"
508+
assert item.call_id == "call_123"
509+
510+
511+
def test_tool_call_item_exposes_convenience_properties_for_dict_raw_items() -> None:
512+
agent = Agent(name="A")
513+
item = ToolCallItem(
514+
agent=agent,
515+
raw_item={
516+
"id": "fc_456",
517+
"call_id": "call_456",
518+
"name": "lookup_account",
519+
"arguments": "{}",
520+
"type": "function_call",
521+
},
522+
)
523+
524+
assert item.tool_name == "lookup_account"
525+
assert item.call_id == "call_456"
526+
527+
528+
def test_tool_call_output_item_exposes_call_id_for_dict_raw_items() -> None:
529+
agent = Agent(name="A")
530+
item = ToolCallOutputItem(
531+
agent=agent,
532+
raw_item={"type": "function_call_output", "call_id": "call_456", "output": "ok"},
533+
output="ok",
534+
)
535+
536+
assert item.call_id == "call_456"
537+
538+
492539
def test_normalize_input_items_for_api_strips_internal_tool_call_metadata() -> None:
493540
item = cast(
494541
TResponseInputItem,

0 commit comments

Comments
 (0)