From 29d4d3fc0960cda33b6ecc44d0afd1b2f5673533 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 3 Sep 2025 17:01:18 +0530 Subject: [PATCH] Store provider and model details --- src/calibre/ai/__init__.py | 11 +++++++++-- src/calibre/ai/open_router/backend.py | 10 ++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/calibre/ai/__init__.py b/src/calibre/ai/__init__.py index fb710aae98..e0bd316bdb 100644 --- a/src/calibre/ai/__init__.py +++ b/src/calibre/ai/__init__.py @@ -37,11 +37,18 @@ class ChatResponse(NamedTuple): content: str = '' reasoning: str = '' type: ChatMessageType = ChatMessageType.assistant - cost: float = 0 - currency: str = 'USD' + exception: Exception | None = None error_details: str = '' # can be traceback or error message from HTTP response + # This metadata will typically be present in the last response from a + # streaming chat session. + has_metadata: bool = False + cost: float = 0 + currency: str = 'USD' + provider: str = '' + model: str = '' + class NoFreeModels(Exception): pass diff --git a/src/calibre/ai/open_router/backend.py b/src/calibre/ai/open_router/backend.py index d5442bb60f..e33d5bdb1f 100644 --- a/src/calibre/ai/open_router/backend.py +++ b/src/calibre/ai/open_router/backend.py @@ -310,7 +310,10 @@ def text_chat_implementation(messages: Iterable[ChatMessage]) -> Iterator[ChatRe if c or r: yield ChatResponse(content=c, reasoning=r, type=ChatMessageType(role)) if u := data.get('usage'): - yield ChatResponse(cost=float(u['cost'] or 0)) + yield ChatResponse( + cost=float(u['cost'] or 0), currency=_('credits'), provider=data.get('provider') or '', + model=data.get('model') or '', has_metadata=True, + ) with opener().open(rq) as response: if response.status != http.HTTPStatus.OK: @@ -350,9 +353,8 @@ def develop(): raise SystemExit(str(x.exception)) if x.content: print(end=x.content, flush=True) - if x.cost: - print(f'Cost: {x.cost}') - print() + if x.has_metadata: + print(f'\nCost: {x.cost} {x.currency} Provider: {x.provider} Model: {x.model}') if __name__ == '__main__':