Summary
The current alchemy-backed prompt caching path is incomplete:
- TinyAgent Python creates
cache_control on user text blocks.
- The in-repo Rust binding does not carry that field through.
session_id exists on Agent but is not forwarded into provider stream options.
This makes the documented explicit prompt-caching design incomplete on the alchemy path.
Why this issue exists
Observed behavior looked inconsistent:
- MiniMax probe returned
cache_read = 32 in .artifacts/runtime/minimax_cache_probe_2026-04-04.json
- OpenRouter
openai/gpt-4.1-mini returned cache_read = 0, cache_write = 0 in .artifacts/runtime/openrouter_gpt41mini_cache_probe_2026-04-04.json
The proof bundle in commit 70b32e8 shows that the difference is not explained by TinyAgent successfully forwarding explicit cache metadata today.
Proof
1. Python does generate cache_control
tinyagent/caching.py:22
.artifacts/runtime/openrouter_cache_debug_payload_2026-04-04.json
That runtime artifact shows:
python_context_has_cache_control = true
- user blocks include:
{
"type": "text",
"text": "Reply with exactly: turn one acknowledged.",
"cache_control": {
"type": "ephemeral"
}
}
2. Rust binding drops cache_control
rust/src/lib.rs:169 defines PyUserContentInput::Text with only text
rust/src/lib.rs:642 forwards only text and text_signature
3. session_id is not forwarded by TinyAgent
tinyagent/agent.py:294 stores _session_id
tinyagent/agent_types.py:286 SimpleStreamOptions has no session_id
tinyagent/agent_loop.py:195 builds provider options without session_id
tinyagent/alchemy_provider.py:313 forwards only api_key, temperature, and max_tokens
4. Vendored alchemy already has session_id support, but not cache_control modeling
vendor/alchemy-llm/src/types/options.rs:14 and :59 show session_id support exists in the vendored crate
vendor/alchemy-llm/src/types/content.rs:67 and vendor/alchemy-llm/src/types/message.rs:30 show no user-text cache_control field exists in the vendored message/content model
Ownership split
session_id forwarding: TinyAgent integration issue
cache_control forwarding: in-repo Rust binding + vendored alchemy-llm capability gap
Proof artifacts committed
.artifacts/research/2026-04-04_16-38-57_openrouter-cache-miss-proof.md
.artifacts/research/2026-04-04_16-48-17_caching-ownership-matrix.md
.artifacts/runtime/openrouter_cache_debug_payload_2026-04-04.json
.artifacts/runtime/openrouter_gpt41mini_cache_probe_2026-04-04.json
.artifacts/runtime/minimax_cache_probe_2026-04-04.json
examples/example_caching.py
Suggested next steps
- Add
session_id to TinyAgent SimpleStreamOptions and forward it through agent_loop.py and alchemy_provider.py.
- Extend the vendored
alchemy-llm user text/content model to represent cache_control.
- Extend
rust/src/lib.rs to deserialize and forward that field.
- Re-run
examples/example_caching.py against OpenRouter and MiniMax and compare telemetry before/after.
Summary
The current alchemy-backed prompt caching path is incomplete:
cache_controlon user text blocks.session_idexists onAgentbut is not forwarded into provider stream options.This makes the documented explicit prompt-caching design incomplete on the alchemy path.
Why this issue exists
Observed behavior looked inconsistent:
cache_read = 32in.artifacts/runtime/minimax_cache_probe_2026-04-04.jsonopenai/gpt-4.1-minireturnedcache_read = 0,cache_write = 0in.artifacts/runtime/openrouter_gpt41mini_cache_probe_2026-04-04.jsonThe proof bundle in commit
70b32e8shows that the difference is not explained by TinyAgent successfully forwarding explicit cache metadata today.Proof
1. Python does generate
cache_controltinyagent/caching.py:22.artifacts/runtime/openrouter_cache_debug_payload_2026-04-04.jsonThat runtime artifact shows:
python_context_has_cache_control = true{ "type": "text", "text": "Reply with exactly: turn one acknowledged.", "cache_control": { "type": "ephemeral" } }2. Rust binding drops
cache_controlrust/src/lib.rs:169definesPyUserContentInput::Textwith onlytextrust/src/lib.rs:642forwards onlytextandtext_signature3.
session_idis not forwarded by TinyAgenttinyagent/agent.py:294stores_session_idtinyagent/agent_types.py:286SimpleStreamOptionshas nosession_idtinyagent/agent_loop.py:195builds provider options withoutsession_idtinyagent/alchemy_provider.py:313forwards onlyapi_key,temperature, andmax_tokens4. Vendored alchemy already has
session_idsupport, but notcache_controlmodelingvendor/alchemy-llm/src/types/options.rs:14and:59showsession_idsupport exists in the vendored cratevendor/alchemy-llm/src/types/content.rs:67andvendor/alchemy-llm/src/types/message.rs:30show no user-textcache_controlfield exists in the vendored message/content modelOwnership split
session_idforwarding: TinyAgent integration issuecache_controlforwarding: in-repo Rust binding + vendoredalchemy-llmcapability gapProof artifacts committed
.artifacts/research/2026-04-04_16-38-57_openrouter-cache-miss-proof.md.artifacts/research/2026-04-04_16-48-17_caching-ownership-matrix.md.artifacts/runtime/openrouter_cache_debug_payload_2026-04-04.json.artifacts/runtime/openrouter_gpt41mini_cache_probe_2026-04-04.json.artifacts/runtime/minimax_cache_probe_2026-04-04.jsonexamples/example_caching.pySuggested next steps
session_idto TinyAgentSimpleStreamOptionsand forward it throughagent_loop.pyandalchemy_provider.py.alchemy-llmuser text/content model to representcache_control.rust/src/lib.rsto deserialize and forward that field.examples/example_caching.pyagainst OpenRouter and MiniMax and compare telemetry before/after.