Skip to content

Add convenience properties (tool_name, call_id) to ToolCallItem and ToolCallOutputItem #2886

@DanielCufino

Description

@DanielCufino

Please read this first

Describe the feature

ToolApprovalItem exposes convenience properties (tool_name, call_id) for inspecting tool calls without reaching into raw_item. ToolCallItem and ToolCallOutputItem lack equivalent accessors, forcing users to write getattr chains and isinstance checks for basic operations like "get all outputs for tool X."

# ToolApprovalItem — has accessors
approval.tool_name   # "my_tool"
approval.call_id     # "call_abc"

# ToolCallItem — manual raw_item access
getattr(item.raw_item, "name", None)
getattr(item.raw_item, "call_id", None)

# ToolCallOutputItem — no tool name at all
# raw_item is a FunctionCallOutput TypedDict with call_id but no name.
# Must correlate back to the ToolCallItem via call_id.

A common post-run task is "get tool outputs by name." Today this requires a two-pass call_id join through new_items:

call_id_to_name = {}
for item in result.new_items:
    if isinstance(item, ToolCallItem):
        name = getattr(item.raw_item, "name", None)
        call_id = getattr(item.raw_item, "call_id", None)
        if name and call_id:
            call_id_to_name[call_id] = name

for item in result.new_items:
    if isinstance(item, ToolCallOutputItem):
        call_id = item.raw_item.get("call_id") if isinstance(item.raw_item, dict) else getattr(item.raw_item, "call_id", None)
        name = call_id_to_name.get(call_id)
        if name == "my_tool":
            print(item.output)

Proposed changes:

  1. Add tool_name and call_id properties to ToolCallItem (mirroring ToolApprovalItem)
  2. Add a call_id property to ToolCallOutputItem

All changes are additive and backward-compatible. PR at #2887.

Limitation: ToolCallOutputItem still can't expose tool_name as a property because FunctionCallOutput (its raw_item type) doesn't carry the tool name — only the call_id. Fully eliminating the join would require the runner to pass the tool name through at construction time, similar to how ToolApprovalItem receives tool_name as a constructor argument. That's a deeper change that the maintainers may want to consider separately.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions