Guillem Arias
45c61bcbc1
feat(ai): add Anthropic batch ops + LLM cost ledger (2/5)
...
Implements auto_categorize, auto_detect_merchants, and
enhance_provider_merchants on Provider::Anthropic via forced tool calls,
plus the cost-ledger plumbing they need.
- Provider::Anthropic::AutoCategorizer, AutoMerchantDetector,
ProviderMerchantEnhancer each define a single output tool whose
input_schema mirrors the desired output, then force the model to call
it via tool_choice: { type: "tool", name: ..., disable_parallel_tool_use: true }.
Anthropic guarantees the tool_use.input matches the schema, so there
is no JSON parsing fragility, no <think> tag stripping, and no
json_object/json_schema fallback ladders.
- Concerns::UsageRecorder mirrors the OpenAI sibling but persists
cache_creation_input_tokens / cache_read_input_tokens to dedicated
columns instead of metadata.
- Migration adds cache_creation_tokens, cache_read_tokens (nullable
integers) to llm_usages. OpenAI rows leave them null.
- LlmUsage::PRICING gains Claude 4.x rows (opus-4-7 $15/$75, sonnet-4-6
$3/$15, haiku-4-5 $1/$5 per MTok). infer_provider returns "anthropic"
for claude-* via the existing exact/prefix lookup.
- Provider::Anthropic#chat_response now persists cache columns directly
rather than stashing them in metadata.
- 25-transaction batch cap mirrors the OpenAI provider so the cost
ledger sees the same shape regardless of which provider ran a batch.
Tests cover the forced-tool-call path, null/None normalization,
case-insensitive merchant matching, the missing-tool_use error path,
and Anthropic-specific pricing + provider inference on LlmUsage.
Stacked on #1983 (PR 1/5). 3/5 PDF + vision next.
2026-05-29 14:51:07 +02:00
..
2026-05-14 21:33:22 +02:00
2026-05-13 21:05:11 +02:00
2026-05-27 10:42:12 +02:00
2026-05-13 21:27:50 +02:00
2026-05-18 20:49:28 +02:00
2026-04-08 22:23:15 +02:00
2026-04-07 14:43:17 +02:00
2026-05-13 18:13:48 +02:00
2026-05-13 18:13:48 +02:00
2026-05-13 18:13:48 +02:00
2025-03-28 13:08:22 -04:00
2026-01-21 22:56:39 +01:00
2026-01-21 22:56:39 +01:00
2026-04-11 21:37:07 +02:00
2026-04-01 20:25:06 +02:00
2026-04-11 21:37:07 +02:00
2026-05-18 20:49:28 +02:00
2026-03-11 15:54:01 +01:00
2026-05-13 14:03:37 +02:00
2026-05-12 00:17:49 +02:00
2026-05-13 17:54:09 +02:00
2026-02-06 18:04:03 +01:00
2026-04-13 00:51:23 +02:00
2026-05-13 20:07:00 +02:00
2026-05-12 23:45:19 +02:00
2026-05-26 22:48:23 +02:00
2026-05-12 23:45:19 +02:00
2026-05-18 18:38:53 +02:00
2026-04-10 23:19:48 +02:00
2026-04-27 18:33:22 +02:00
2026-04-27 18:33:22 +02:00
2026-01-09 13:03:40 +01:00
2026-05-12 00:22:37 +02:00
2026-05-12 00:22:37 +02:00
2026-01-12 15:35:14 -05:00
2026-02-19 18:58:01 +01:00
2026-01-23 00:53:24 +01:00
2026-01-09 19:38:04 +01:00
2026-01-22 20:37:07 +01:00
2026-01-22 20:37:07 +01:00
2026-01-22 20:37:07 +01:00
2026-03-25 17:47:04 +01:00
2026-01-10 20:11:00 +01:00
2026-03-13 08:11:51 +01:00
2026-05-29 14:51:07 +02:00
2026-03-23 12:34:43 +01:00
2026-05-12 00:37:47 +02:00
2026-03-25 17:47:04 +01:00
2026-05-17 16:55:01 +02:00
2026-01-05 22:11:47 +01:00
2026-05-13 18:17:10 +02:00
2026-01-16 12:34:06 +01:00
2026-04-18 09:50:34 +02:00
2026-05-12 23:45:19 +02:00
2026-05-12 12:17:00 +02:00
2026-04-19 11:16:04 +02:00
2026-04-19 11:16:04 +02:00
2026-05-09 21:55:20 +02:00
2025-10-22 16:02:50 +02:00
2026-04-09 18:33:59 +02:00
2026-05-12 23:45:19 +02:00
2026-04-08 21:05:58 +02:00
2025-07-15 11:42:41 -04:00
2026-03-20 17:01:31 +01:00
2026-05-13 20:07:00 +02:00
2026-05-19 13:37:10 +02:00
2026-01-07 15:59:04 +01:00
2026-03-25 10:50:23 +01:00
2026-05-13 21:05:11 +02:00
2026-05-24 13:27:27 +02:00
2026-05-18 18:38:53 +02:00
2025-04-16 20:26:45 -05:00
2026-05-17 09:52:49 +02:00
2024-02-02 09:05:04 -06:00
2026-03-14 20:14:18 +01:00
2026-05-03 20:33:29 +02:00
2026-03-03 15:47:51 +01:00
2026-05-01 13:31:32 +02:00
2026-03-25 10:50:23 +01:00
2025-07-23 18:15:14 -04:00
2026-04-07 14:43:17 +02:00
2026-04-07 14:43:17 +02:00
2026-05-13 18:13:48 +02:00
2026-05-13 18:13:48 +02:00
2026-04-13 20:03:55 +02:00
2026-05-19 13:37:10 +02:00
2026-05-17 09:52:49 +02:00
2026-05-18 20:49:28 +02:00
2026-05-25 19:49:25 +02:00
2026-03-19 15:17:55 +01:00
2026-04-07 16:28:01 +02:00
2026-04-01 20:25:06 +02:00
2026-04-01 20:25:06 +02:00
2026-05-13 18:13:48 +02:00
2026-05-18 20:49:28 +02:00
2026-03-25 10:50:23 +01:00
2026-05-13 18:13:48 +02:00
2026-05-17 16:55:01 +02:00
2026-05-18 20:49:28 +02:00
2026-04-10 23:19:48 +02:00
2026-04-10 23:19:48 +02:00
2026-02-01 23:48:54 +01:00
2026-05-20 19:21:31 +02:00
2026-03-29 17:30:12 +02:00
2026-04-13 00:51:23 +02:00
2025-03-17 11:54:53 -04:00
2026-02-11 15:22:56 +01:00
2025-09-24 00:19:51 +02:00
2026-01-09 19:38:04 +01:00
2026-01-21 17:16:51 +01:00
2026-05-19 13:37:10 +02:00
2026-05-12 23:45:19 +02:00
2026-05-12 23:45:19 +02:00
2026-05-12 23:45:19 +02:00
2024-10-18 11:26:58 -05:00
2024-10-18 11:26:58 -05:00
2026-05-19 13:37:10 +02:00
2026-05-20 20:28:26 +02:00
2026-03-19 15:17:55 +01:00
2026-05-17 09:52:49 +02:00
2026-03-25 10:50:23 +01:00
2026-04-11 15:09:59 +02:00
2026-05-05 01:04:29 +02:00
2026-03-25 10:50:23 +01:00
2026-01-23 22:05:28 +01:00
2026-05-12 00:22:37 +02:00
2026-05-12 00:22:37 +02:00
2026-05-29 14:51:07 +02:00
2026-04-18 00:06:24 +02:00
2026-03-19 15:17:55 +01:00
2026-05-12 12:18:17 +02:00
2026-04-09 18:33:59 +02:00
2024-08-23 09:33:42 -04:00
2025-11-01 09:12:42 +01:00
2026-03-19 15:17:55 +01:00
2026-05-03 10:56:31 +02:00
2026-05-03 20:33:29 +02:00
2026-05-12 00:00:49 +02:00
2026-02-06 18:04:29 +01:00
2026-05-12 21:55:22 +02:00
2025-02-21 11:57:59 -05:00
2025-02-21 11:57:59 -05:00
2026-05-05 01:12:48 +02:00
2026-05-23 09:41:57 +02:00
2026-05-17 09:52:49 +02:00
2026-02-10 23:42:22 +01:00
2026-05-05 01:04:29 +02:00
2026-05-13 18:13:48 +02:00
2026-05-13 18:13:48 +02:00
2025-05-15 10:19:56 -04:00
2026-05-05 01:12:48 +02:00
2026-05-17 09:52:49 +02:00
2025-04-14 11:40:34 -04:00
2026-05-17 09:52:49 +02:00
2026-05-14 21:56:49 +02:00
2026-05-17 09:52:49 +02:00
2026-04-10 17:42:16 +02:00
2025-11-20 08:31:03 +01:00
2026-01-23 22:05:28 +01:00
2026-05-25 20:27:59 +02:00
2026-05-17 09:52:49 +02:00
2026-02-10 23:42:22 +01:00
2026-03-20 14:52:09 +01:00
2026-05-03 10:28:31 +02:00
2026-05-17 09:52:49 +02:00
2026-05-09 21:55:20 +02:00
2026-01-03 17:56:42 -05:00
2026-05-05 00:47:45 +02:00
2026-05-17 09:52:49 +02:00
2026-01-23 18:55:51 +01:00
2026-05-20 21:35:22 +02:00
2026-05-20 21:19:10 +02:00
2026-02-23 17:43:00 -05:00
2024-05-23 08:09:33 -04:00
2025-03-28 13:08:22 -04:00
2026-05-13 20:07:00 +02:00
2026-05-12 23:45:19 +02:00
2026-05-13 20:07:00 +02:00
2026-05-12 23:45:19 +02:00
2026-05-24 13:27:27 +02:00
2025-02-21 11:57:59 -05:00
2026-05-03 20:33:29 +02:00
2026-05-25 20:27:59 +02:00
2025-07-15 11:42:41 -04:00
2026-02-11 15:22:56 +01:00
2025-04-14 11:40:34 -04:00
2026-05-03 22:13:28 +02:00