feat(llm): adopt Anthropic prompt caching + per-purpose spend tagging across CMOAgent
Summary
Vendor-radar adoption of two Anthropic SDK features already shipped (since Aug 2024) that CMOAgent wasn't using:
-
Prompt caching via
cache_control={"type":"ephemeral"}on the 4 static + large system prompts (digest, weekly_reset, operator-plan, experiment-proposal). After the first call within the 5-min TTL, input tokens on that block are billed at offline% of normal cost. -
Per-purpose spend tagging via
metadata=cmo_metadata("<purpose>")on every LLM call site (previously missing on weekly_reset, learning/propose, pitch_analyzer, watcher). Lets LiteLLMspend_per_tagand PMC's/api/mc/llm-spenddashboard attribute cost per code path.
Also corrects a misleading comment in llm_client.py that claimed LiteLLM auto-injected cache_control at the proxy layer — it does not; the client must add it.
Changes
-
New helper
cached_system(prompt: str)insrc/agents/gaming_cmo/llm_client.pythat wraps a system string in the Anthropic prompt-caching block form. -
Caching applied in:
digest.py,weekly_reset.py,agent.py(operator-plan + experiment-proposal paths). -
Tagging added in:
weekly_reset.py,agent.py(both paths),learning/propose.py,pitch_analyzer.py,watcher.py. -
Floor bump
anthropic>=0.40.0→anthropic>=0.50.0(lockfile already 0.95.0). -
7 new unit tests in
tests/test_llm_client.pycovering helper shape, validation, metadata invariants, and an integration assertion ondigest.generate_daily_digest.
Test plan
-
uv run pytest -q→ 398 passed in 6.32s (baseline 391, +7 new) -
uv sync --extra devresolves anthropic 0.95.0 cleanly -
Post-merge: verify on a real digest run that response.usage.cache_creation_input_tokens/cache_read_input_tokensare non-zero (confirms LiteLLM forwardscache_controland Anthropic bills the discount).
Follow-ups (out of scope, noted in commit bodies)
-
analyst.py:331still constructsanthropic.Anthropicinline (already tagged); migrating toget_anthropic_client()requires relaxing the module-singleton to accept per-call overrides. - Bigger radar items (Citations API for analyst, native web_search for watcher, memory tool for learning loop) deferred — require a product decision, not autopilot work.