mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-27 01:22:18 +00:00
fix(interactions): drop the stored request context once a settlement row is settled
This commit is contained in:
parent
a2ba6e01d1
commit
ae71e91b3b
2 changed files with 14 additions and 7 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import asyncio
|
||||
import os
|
||||
import socket
|
||||
from collections.abc import Awaitable, Sequence
|
||||
from collections.abc import Awaitable, Mapping, Sequence
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
from typing import TYPE_CHECKING, Final, Protocol
|
||||
|
|
@ -69,6 +69,7 @@ class _Claim(TypedDict):
|
|||
class _Outcome(TypedDict):
|
||||
settled_at: ReadOnly[datetime]
|
||||
outcome: ReadOnly[SettlementOutcome]
|
||||
create_context: ReadOnly[object]
|
||||
|
||||
|
||||
class _SettlementTableActions(Protocol):
|
||||
|
|
@ -85,6 +86,12 @@ def _settlement_table(prisma_client: "PrismaClient") -> _SettlementTableActions:
|
|||
return BackgroundInteractionSettlementRepository(prisma_client).table
|
||||
|
||||
|
||||
def _json(data: Mapping[str, object]) -> object:
|
||||
from prisma import Json # noqa: PLC0415 # local import: prisma may be ungenerated at module load in some tools
|
||||
|
||||
return Json(data)
|
||||
|
||||
|
||||
def _pending_rows(rows: Sequence[_SettlementRow]) -> tuple[PendingBackgroundInteraction, ...]:
|
||||
return tuple(pending for row in rows for pending in _pending_row(row))
|
||||
|
||||
|
|
@ -114,13 +121,11 @@ class PrismaBackgroundSettlementStore:
|
|||
claimed_by: str
|
||||
|
||||
async def register(self, pending: PendingBackgroundInteraction) -> None:
|
||||
from prisma import Json # noqa: PLC0415 # local import: prisma may be ungenerated at module load in some tools
|
||||
|
||||
await self.table.create(
|
||||
data=_NewSettlementRow(
|
||||
interaction_id=pending.interaction_id,
|
||||
custom_llm_provider=pending.custom_llm_provider,
|
||||
create_context=Json(pending.create_context.model_dump(mode="json")),
|
||||
create_context=_json(pending.create_context.model_dump(mode="json")),
|
||||
created_at=pending.created_at,
|
||||
)
|
||||
)
|
||||
|
|
@ -144,7 +149,7 @@ class PrismaBackgroundSettlementStore:
|
|||
|
||||
async def record_outcome(self, interaction_id: str, outcome: SettlementOutcome) -> None:
|
||||
await self.table.update_many(
|
||||
data=_Outcome(settled_at=datetime.now(timezone.utc), outcome=outcome),
|
||||
data=_Outcome(settled_at=datetime.now(timezone.utc), outcome=outcome, create_context=_json({})),
|
||||
where=_RowKey(interaction_id=interaction_id),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class _FakeSettlementTable:
|
|||
matched = self._matching(where)
|
||||
for row in matched:
|
||||
for column, value in data.items():
|
||||
setattr(row, column, value)
|
||||
setattr(row, column, getattr(value, "data", value) if column == "create_context" else value)
|
||||
return len(matched)
|
||||
|
||||
def _matching(self, where) -> list:
|
||||
|
|
@ -184,11 +184,12 @@ async def test_unclaimed_skips_claimed_and_unreadable_rows():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_record_outcome_keeps_the_audit_trail_on_the_row():
|
||||
async def test_record_outcome_keeps_the_audit_trail_and_drops_the_stored_request_context():
|
||||
table = _FakeSettlementTable()
|
||||
store = PrismaBackgroundSettlementStore(table=table, claimed_by="replica-a:1")
|
||||
await store.register(_pending("interactions/bg-1"))
|
||||
assert await store.claim("interactions/bg-1")
|
||||
assert table.rows["interactions/bg-1"].create_context
|
||||
|
||||
await store.record_outcome("interactions/bg-1", "billed")
|
||||
|
||||
|
|
@ -196,6 +197,7 @@ async def test_record_outcome_keeps_the_audit_trail_on_the_row():
|
|||
assert row.outcome == "billed"
|
||||
assert row.settled_at is not None
|
||||
assert row.claimed_at <= row.settled_at
|
||||
assert row.create_context == {}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue