Skip to content

feat: #2886 add tool_name and call_id properties to ToolCallItem and ToolCallOutputItem#2919

Draft
SuperMarioYL wants to merge 3 commits intoopenai:mainfrom
SuperMarioYL:feat/tool-call-item-convenience-props
Draft

feat: #2886 add tool_name and call_id properties to ToolCallItem and ToolCallOutputItem#2919
SuperMarioYL wants to merge 3 commits intoopenai:mainfrom
SuperMarioYL:feat/tool-call-item-convenience-props

Conversation

@SuperMarioYL
Copy link
Copy Markdown

Summary

ToolApprovalItem already exposes tool_name and call_id convenience properties, but ToolCallItem and ToolCallOutputItem force callers to write fragile getattr chains or a two-pass call_id join to correlate outputs back to their originating calls.

This PR adds the missing accessors:

  • ToolCallItem.tool_name — extracts .name / "name" from the raw item. Returns None for hosted tool types that carry no name field (e.g. computer-use, file-search).
  • ToolCallItem.call_id — extracts .call_id / .id / "call_id" / "id", mirroring the logic already in ToolApprovalItem._extract_call_id.
  • ToolCallOutputItem.call_id — extracts "call_id" from the raw dict payload, matching the call_id on the corresponding ToolCallItem so callers can join without a second pass.

Before this change, getting all outputs for a named tool required a verbose two-pass join:

# Before — manual join
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 None
        if call_id_to_name.get(call_id) == "my_tool":
            print(item.output)

After:

# After — direct property access
calls = {item.call_id: item.tool_name for item in result.new_items if isinstance(item, ToolCallItem)}
for item in result.new_items:
    if isinstance(item, ToolCallOutputItem) and calls.get(item.call_id) == "my_tool":
        print(item.output)

Test plan

Added 8 unit tests in tests/test_items_helpers.py covering:

  • tool_name from ResponseFunctionToolCall (typed object)
  • tool_name from a raw dict
  • tool_name returns None for ResponseComputerToolCall (no name field)
  • call_id from ResponseFunctionToolCall
  • call_id from a raw dict
  • ToolCallOutputItem.call_id from a dict payload
  • ToolCallOutputItem.call_id returns None when absent
  • End-to-end join of ToolCallItem + ToolCallOutputItem via call_id

Verified locally:

  • uv run pytest tests/test_items_helpers.py tests/test_run_internal_items.py — 53 passed
  • uv run make lint — all checks passed
  • uv run pyright src/agents/items.py — 0 errors

Issue number

Closes #2886

Checks

  • I've added new tests (if relevant)
  • I've added/updated the relevant documentation
  • I've run make lint and make format
  • I've made sure tests pass

… ToolCallOutputItem

ToolApprovalItem already exposed these accessors; ToolCallItem and
ToolCallOutputItem forced callers to write fragile getattr chains or
a two-pass call_id join to correlate outputs back to their originating
calls.

- ToolCallItem.tool_name  — extracts .name / "name" from the raw item
  (None for hosted tool types that carry no name field, such as
  computer-use or file-search).
- ToolCallItem.call_id   — extracts .call_id / .id / "call_id" / "id".
- ToolCallOutputItem.call_id — extracts "call_id" from the raw dict
  payload; matches the call_id on the corresponding ToolCallItem so
  callers can correlate outputs to calls without a manual join.

Tests cover function-call, dict-backed, and computer-call raw items,
plus the end-to-end join pattern that motivated the request.

Closes openai#2886
@github-actions github-actions bot added enhancement New feature or request feature:core labels Apr 17, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3d18198481

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/items.py Outdated
Comment on lines +422 to +424
if isinstance(self.raw_item, dict):
return self.raw_item.get("call_id")
return getattr(self.raw_item, "call_id", None)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Support id fallback in ToolCallOutputItem.call_id

ToolCallOutputItem.call_id only reads raw_item["call_id"], but the SDK already treats id as a fallback identifier for tool payloads (for example in extract_tool_call_id and output indexing logic), so id-only provider payloads are intentionally handled elsewhere. In that supported scenario, ToolCallItem.call_id resolves to id while ToolCallOutputItem.call_id resolves to None, which breaks the new convenience join path and contradicts the property’s stated correlation behavior.

Useful? React with 👍 / 👎.

@seratch seratch changed the title feat(items): add tool_name and call_id properties to ToolCallItem and ToolCallOutputItem feat: #2886 add tool_name and call_id properties to ToolCallItem and ToolCallOutputItem Apr 17, 2026
@seratch seratch marked this pull request as draft April 17, 2026 23:41
SuperMarioYL and others added 2 commits April 21, 2026 18:04
Use cast() in ToolCallOutputItem.call_id to fix return-value type
mismatch when getattr resolves to object | Any from the output type
union. Also replace raw dict literal in test with ActionScreenshot
to match the typed action parameter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request feature:core

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

1 participant