Repository navigation
v1.4.2 — Agentic loop polish + Anthropic prompt caching
What's new
A pile of agent-loop UX and cost fixes that came out of multi-hour SQL/data sessions with Opus 4.7. If you're using Mason for anything tool-heavy, this is worth updating to.
Prompt caching for Claude models — big cost win
Tool schemas are the heaviest static portion of every turn (~16K tokens for ~80 tools). Mason now marks cache_control: ephemeral on the last tool and last system message, so Anthropic caches the entire static prefix for 5 minutes. Subsequent turns within the cache window read at ~10% of input cost — typically 80–90% savings on the static prefix every turn.
Verify it's working in DevTools console after a few turns:
[CHAT] Usage (streamed) — input: 31000, output: 230, cache_created: 0, cache_read: 26017
cache_read climbing turn-over-turn = caching engaged.
OpenAI/GPT models automatic-cache prefixes >1024 tokens, no opt-in needed. Gemini/Meta/Qwen have no standard caching path yet.
Agent loop UX
- Agent iteration budget raised 10 → 40. Polling patterns (waiting on a job run, multi-step SQL builds) used to silently hit the cap and return to idle with no explanation. Now the budget fits real workflows.
- Clear stop message when the loop exhausts. No more "looks like a hang" mystery — the chat surfaces
Agent loop hit the 40-step budget — send "continue" to keep going. - Building bricks stay visible during tool execution and below streaming text. Previously the indicator vanished when "Calling tool: X" appeared, and again once content started streaming — users assumed Mason had frozen during slow MCP calls or model pauses.
- Empty-response detection. If Opus 4.7 burns its token budget on extended thinking and returns no visible content, Mason now shows a clear hint instead of silently rendering an empty bubble.
Chat reliability
max_tokens4096 → 16384. Gives Opus 4.7 extended-thinking headroom before output, and reduces tool-call argument truncation.trimHistorydrops orphan tool results. Anthropic was rejecting whole requests when our message trimming cut between an assistant-with-tool_calls and its result. Now any tool-result message whosetool_call_idisn't matched is pruned.- Tool-call argument sanitization. Empty or malformed JSON in
function.arguments(from truncation or providers that emit no args for no-param tools) now normalizes to{}so the conversation doesn't wedge.
Full changelog: v1.4.1...v1.4.2