🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

feat: record all tool call types - #26855

Merged
dannykopping merged 2 commits into
mainfrom
dk/record-all-tool-types
Jul 6, 2026
Merged

feat: record all tool call types#26855
dannykopping merged 2 commits into
mainfrom
dk/record-all-tool-types

Conversation

@dannykopping

@dannykopping dannykopping commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

The Responses interceptor previously recorded only function_call and custom_tool_call output items, so interceptions that did real work via built-in tools (web_search_call, computer_call, shell_call, mcp_call, etc.) recorded no tool usage at all.

recordNonInjectedToolUsage now whitelists every tool-call output type and records it, with the tool name falling back to the item type when none is set.

ToolUsageRecord also gains an ItemID field so the two distinct Responses identifiers are captured without conflation (addresses review feedback on coder/aibridge#273):

  • ItemID: the output item's unique id (always present).
  • ToolCallID: the call_id correlation id (empty for hosted tools the provider runs server-side).

Tests

  • Extends TestRecordToolUsage with cases for the new hosted/agentic tool types.
  • Adds blocking and streaming web_search fixtures (scrubbed of credentials and identifying metadata) plus TestResponsesOutputMatchesUpstream cases asserting a hosted tool records with an empty ToolCallID and a populated ItemID.

Linear: AIGOV-96


This PR was produced by opencode (agent) using the anthropic/claude-opus-4-8 model, under human direction and review.

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@dannykopping dannykopping changed the title feat(aibridge/intercept/responses): record all tool call types feat: record all tool call types Jun 30, 2026
@dannykopping
dannykopping force-pushed the dk/record-all-tool-types branch 2 times, most recently from f2e690f to a876e19 Compare June 30, 2026 12:12
@dannykopping
dannykopping requested a review from SasSwart June 30, 2026 12:15
@dannykopping
dannykopping marked this pull request as ready for review June 30, 2026 12:16
@dannykopping
dannykopping requested a review from pawbana July 2, 2026 15:57
Previously the responses interceptor only recorded function_call and
custom_tool_call output items, so interceptions that did real work via
built-in tools (web_search_call, computer_call, shell_call, mcp_call,
etc.) showed no tool usage at all.

recordNonInjectedToolUsage now whitelists every tool-call output type
and records it. The tool name falls back to the item type when no
explicit name is set (built-in tools usually have none).

ToolUsageRecord gains a separate ItemID field so the two distinct
Responses identifiers are captured without conflation:
- ItemID: the output item's unique id (always present).
- ToolCallID: the call_id correlation id (empty for hosted tools the
  provider executes internally).
Adds blocking and streaming web_search.txtar fixtures (derived from a
real gpt-5.4 Responses payload, scrubbed of credentials and identifying
metadata) and TestResponsesOutputMatchesUpstream cases for both paths.

Each case validates a hosted tool call: web_search_call is recorded,
its ToolCallID is empty (the provider runs it server-side, so there is
no call_id), and ItemID captures the output item's id.
@dannykopping
dannykopping force-pushed the dk/record-all-tool-types branch from a876e19 to 3c594fa Compare July 6, 2026 06:55
@dannykopping
dannykopping merged commit 08a6359 into main Jul 6, 2026
25 of 26 checks passed

Copy link
Copy Markdown
Contributor Author

Merge activity

@dannykopping
dannykopping deleted the dk/record-all-tool-types branch July 6, 2026 07:10
dannykopping added a commit that referenced this pull request Jul 6, 2026
## Summary

Plumbs the Responses output item id (added as `ToolUsageRecord.ItemID` in #26855) through to the database, captured independently of the `provider_tool_call_id` correlation key. Hosted tools (`web_search_call`, etc.) only have an item id; agentic tools have both.

`provider_item_id` is specific to the OpenAI Responses API; it stays empty for chat completions and Anthropic messages, which have no separate item id.

## Changes

- Migration `000534`: nullable `provider_item_id` column on `aibridge_tool_usages`.
- Proto: `item_id` field 11 on `RecordToolUsageRequest`.
- Server handler: persists `provider_item_id` and adds it to structured logging.
- Translator: maps `ToolUsageRecord.ItemID` to the proto field.

## Tests

- `TestRecordToolUsageProviderItemID`: real-database round-trip asserting `provider_item_id` persists for both hosted and agentic tools, independently of `provider_tool_call_id`.

Stacked on #26855. Linear: AIGOV-96

---

_This PR was produced by opencode (agent) using the_ _`anthropic/claude-opus-4-8`_ _model, under human direction and review._
jaaydenh added a commit that referenced this pull request Jul 7, 2026
Resolve conflicts from main:

- Drop UpdateChatStatusPreserveUpdatedAt (query, dbauthz wrapper, and its
  generated code): main removed it in #26980 (remove chat chain mode). Keep
  the branch's UpdateChatSummary.
- Renumber chat_summary migration 000538 -> 000540 to avoid colliding with
  main's new 000538_chat_shared_notification and 000539_ai_provider_icons.
  Verified the chats_expanded recreation matches main's latest view plus the
  two summary columns (up), and the down migration restores main's view.
- querier_test.go: drop ProviderResponseID from InsertChatMessagesParams in
  TestUpdateChatSummary; main's #26855/#26856 refactor removed that field.
- Regenerated queries.sql.go/querier.go/dbmock/querymetrics/audit-logs/apidoc/
  types from the merged sources (picks up main's ai_providers Icon, etc.).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants