Fixed
- Prompt caching now hits. The system prompt began with Home Assistant's
Current time is HH:MM:SSline, which changed the first bytes of every request and invalidated the provider's exact-prefix cache on every turn: Anthropic reportedcache_creationof the whole prompt andcache_read: 0on each call. The prompt is now rendered as a stable prefix (your instructions, timezone, PIN and YAML-mode guidance, the tool-error rule, the exposed-entity context) followed by a volatile tail (date/time, retrieved memories, the running summary). For Anthropic the stable prefix carries an explicitcache_controlbreakpoint, alongside the client's existing automatic last-block breakpoint, so the prefix is written once and read back on every later call that binds the same tools; the same ordering lets OpenAI's and Gemini's implicit caching match the prefix too. Every other provider, including non-Anthropic fallback-chain members, receives a single plain string with no Anthropic-only field, so the key never reaches an API that rejects unknown content fields; the only change for them is that the date/time line, memories and summary now end the prompt instead of opening it. Two related per-turn sources of cache misses were closed at the same time: inside a tool loop the memory search fell back to a recency listing that differed from the semantic result of the first call, so the<memories>block changed between the call that requested a tool and the call that answered (memories are now retrieved once per turn and reused by every model call in it, which also removes the extra embedding call per tool round), and retrieved tools were bound in relevance order, so the same tool set arrived in a different order on different turns (they are now bound in name order; the tool array is the head of the cached prefix). Note that the cache is a hierarchytools → system → messages: a turn whose retrieved tool set differs from the previous turn's still cannot read the previous prefix. (#617) - When the agent has no tools at all, the system prompt no longer collapses to just the exposed-entity context: an operator-precedence slip made the whole instruction block conditional on tools rather than only the tool-error rule.