AI model calls
When your app calls a language model, elcapture recognises it and adds an AI model call section to the Summary: the model, the token counts, and an estimated cost in dollars. It works whether the response is streamed or not.
What it shows
| Field | From the response |
|---|---|
| Model | The model name the API returned, and which provider it matched. |
| Input tokens | Prompt tokens sent to the model. |
| Cached input | Prompt tokens served from the provider's cache (shown when present), priced lower. |
| Cache writes | Tokens written to the cache (shown when present), priced higher. |
| Output tokens | Tokens the model generated. |
| Estimated cost | Token counts times the model's price. An estimate to spot expensive calls, not a billing record. |
What it understands
Anthropic's Messages API (api.anthropic.com), OpenAI's chat completions and responses APIs (api.openai.com), Google Gemini (generativelanguage / aiplatform.googleapis.com), and OpenAI-compatible endpoints — anything serving /chat/completions, /v1/responses or /v1/messages. For streamed responses it reads the token counts out of the event stream, taking the highest counts seen.
Prices
elcapture ships a built-in price table (US dollars per million tokens, input / output), covering current Claude and Gemini models. When a model isn't in the table it still shows the token counts and tells you to add a price. To set your own, create llm-prices.json in the app's data folder (~/Library/Application Support/elcapture); elcapture matches by the longest model-name prefix, so claude-sonnet covers every dated variant.
Why it helps
The bill is a sum of individual calls, and usually a few are doing the damage — a prompt that ships the whole context every turn, a retry loop, a cache that isn't hitting. With the cost on each request, the expensive one is easy to find. Filter to model calls and sort by cost to see them together.