fix(spend_tracking): re-key the create calls that mint a response id too

Interaction, video, container, code, MCP tool and A2A calls are charged per call and keyed on
the id the provider minted for that call, the same shape as a chat completion, so a reused id
would drop their rows as well. List them with the inference calls.
This commit is contained in:
Yucheng He 2026-09-15 13:05:18 -07:00
parent abd8c08315
commit 101845007f
2 changed files with 35 additions and 5 deletions

View file

@ -7268,15 +7268,35 @@ _RESPONSE_ID_KEYED_SPEND_LOG_CALL_TYPES: Final = frozenset(
CallTypes.aocr.value,
CallTypes.vector_store_search.value,
CallTypes.avector_store_search.value,
CallTypes.create_interaction.value,
CallTypes.acreate_interaction.value,
CallTypes.create_video.value,
CallTypes.acreate_video.value,
CallTypes.video_remix.value,
CallTypes.avideo_remix.value,
CallTypes.video_edit.value,
CallTypes.avideo_edit.value,
CallTypes.video_extension.value,
CallTypes.avideo_extension.value,
CallTypes.create_container.value,
CallTypes.acreate_container.value,
CallTypes.run_code.value,
CallTypes.arun_code.value,
CallTypes.code_interpreter_tool.value,
CallTypes.acode_interpreter_tool.value,
CallTypes.call_mcp_tool.value,
CallTypes.send_message.value,
CallTypes.asend_message.value,
CallTypes.pass_through.value,
CallTypes.llm_passthrough_route.value,
CallTypes.allm_passthrough_route.value,
}
)
"""The inference calls, whose provider mints a response id per call: a stored row with the same
``request_id`` is another request the provider gave the same id. Every other call type (object
creates, reads, polls and management calls, batch cost claims) is keyed on the id of the object
it addressed, and a second row for one of those collapses on purpose."""
"""The inference and create calls, whose provider mints a response id per call: a stored row
with the same ``request_id`` is another request the provider gave the same id. Every other call
type (object reads, polls, cancels, lists and deletes, batch cost claims) is keyed on the id of the
object it addressed, and a second row for one of those collapses on purpose. Realtime and
Responses websocket sessions carry no provider id and are keyed on the call id already."""
def _is_transient_spend_log_write_error(e: Exception) -> bool:

View file

@ -987,7 +987,17 @@ async def test_update_spend_logs_rekeys_the_rows_a_reused_provider_response_id_w
@pytest.mark.asyncio
@pytest.mark.parametrize(
"call_type",
["acompletion", "atext_completion", "aembedding", "aresponses", "aanthropic_messages", "allm_passthrough_route"],
[
"acompletion",
"atext_completion",
"aembedding",
"aresponses",
"aanthropic_messages",
"acreate_interaction",
"acreate_video",
"call_mcp_tool",
"allm_passthrough_route",
],
)
async def test_update_spend_logs_rekeys_every_inference_call_type(
mock_prisma_client: MagicMock, make_spend_log_row: SpendLogRowFactory, call_type: str