Skip to content

Alchemy prompt-caching path drops cache_control and does not forward session_id #37

@larock22

Description

@larock22

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

  1. Add session_id to TinyAgent SimpleStreamOptions and forward it through agent_loop.py and alchemy_provider.py.
  2. Extend the vendored alchemy-llm user text/content model to represent cache_control.
  3. Extend rust/src/lib.rs to deserialize and forward that field.
  4. Re-run examples/example_caching.py against OpenRouter and MiniMax and compare telemetry before/after.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions