@@ -11,6 +11,106 @@ target.
1111
1212## [ Unreleased]
1313
14+ ## [ 3.3.0] — 2026-10-09
15+
16+ Requests converted for Claude now use prompt caching, and Codex works
17+ through routes that convert its requests to another format: its tools,
18+ its history and its compactions arrive. A Responses request that only
19+ OpenAI can read — one that continues a conversation kept on OpenAI's
20+ servers, or carries a compaction OpenAI wrote — now goes to a route that
21+ speaks Responses instead of being refused. The thinkwatch-core crates move
22+ from v0.65.0 to v0.67.1.
23+
24+ ### Read before upgrading
25+
26+ - ** Converted requests to Claude are cached, and billed as cache traffic.**
27+ A request converted for an Anthropic-format upstream, or for a Claude
28+ model on Bedrock that AWS lists for prompt caching (Claude 3.5 Sonnet v2,
29+ Claude 3.7 Sonnet, and Claude 4.5 and later), from a client that marks no
30+ cache breakpoints — Codex, Chat and Gemini clients, and an Anthropic
31+ client whose request goes to Bedrock without ` cache_control ` — now gets
32+ them at the end of the tools, the system prompt and the last two user
33+ turns, with the 5-minute lifetime.
34+ - The upstream bills the prefix a request writes at its cache-write rate
35+ (1.25× input at Anthropic) and what the next turns read back at its
36+ cache-read rate (0.1×). ThinkWatch prices and counts them the same
37+ way: cost, budgets and ` tokens ` rate limits weigh a cache write by the
38+ model's ` cache_write_weight ` and a read by its ` cache_read_weight ` ,
39+ 1.25× and 0.1× its input weight when unset. Set them on the model to
40+ match what your upstream charges.
41+ - A conversation of several turns costs less. A one-off request with a
42+ long prompt costs up to a quarter more on its input.
43+ - Prompt token counts (` input_tokens ` on the log rows, quotas) include
44+ cached input in full, as before.
45+ - Requests that mark their own breakpoints, such as Claude Code's, and
46+ requests forwarded in their own format are unchanged.
47+ - An upstream that refuses the added breakpoints — a ` 400 ` that names
48+ ` cache_control ` , ` cachePoint ` or prompt caching, as an
49+ Anthropic-compatible endpoint that does not know them answers — gets
50+ the request once more without them, and later requests to it for that
51+ model leave them out from the start. Each instance remembers this
52+ until a provider or model is changed or it restarts. Breakpoints a
53+ client marked itself are never taken out, and the probes that check a
54+ route's API format go without breakpoints.
55+ - ** Rolling back with Codex sessions.** A Codex session that compacted
56+ through a converted route on 3.3.0 carries a compaction that 3.2.1
57+ refuses, so after a rollback, or on a 3.2.1 instance during the rollout,
58+ it cannot continue and needs a new session.
59+
60+ Nothing else needs action: no setting, schema, API route or Redis key
61+ changes.
62+
63+ ### Fixed
64+
65+ - ** Responses requests that only OpenAI can read.** A Responses request
66+ that continues a conversation kept on OpenAI's servers
67+ (` previous_response_id ` , ` conversation ` , ` prompt ` , ` background ` ), points
68+ at a stored item (` item_reference ` ) or carries a compaction OpenAI wrote
69+ was refused with ` 400 ` , even on a route that speaks Responses and would
70+ have forwarded it as sent: every request was decoded for its usage
71+ estimate, and one that could not be decoded was refused. Codex sends such
72+ a compaction in every request after compacting a session through an
73+ OpenAI upstream, so the session could not go on; and a WebSocket turn
74+ naming a response other than the connection's last one, meant to go
75+ upstream as sent, was refused too. These requests now go to the model's
76+ routes that speak Responses, and only a model with none refuses them,
77+ with the reason. Their input estimate counts the request's text.
78+
79+ ### Changed
80+
81+ - thinkwatch-core crates (tw-bedrock, tw-breaker, tw-dialect, tw-guard)
82+ v0.65.0 → v0.67.1. Only tw-dialect, the format conversion, changes:
83+ - ** Prompt caching for Claude** on converted requests (see Read before
84+ upgrading).
85+ - ** Codex tools.** For some models Codex declares every tool in an
86+ ` additional_tools ` input item and sends no top-level ` tools ` . Those
87+ items were dropped, so a route converting to Anthropic, Chat, Gemini
88+ or Bedrock sent no tools and Codex could not read files or run
89+ commands. Every tool now arrives, and tool calls come back under the
90+ names and kinds Codex declared. Local shell calls, tool search,
91+ reasoning-effort changes and agent messages in the history are
92+ converted instead of dropped.
93+ - ** Codex compaction on converted routes.** Codex compacts a long
94+ session through a provider named ` OpenAI ` by asking for exactly one
95+ compaction item, which a converted route could not give, so compacting
96+ failed. The upstream now writes a handoff summary, Codex receives it as
97+ its compaction, and later requests carry it back. The summary request
98+ is billed like any other. The summary travels in the item's
99+ ` encrypted_content ` (` tw1.c.… ` ) base64-encoded, not encrypted; with
100+ ` audit.body_redact_pii ` on, captured bodies have it redacted like the
101+ rest of the body. OpenAI's own compactions still cannot be read by an
102+ upstream of another format, and are refused saying so.
103+ - ** System messages in mid-conversation stay in place.** A ` system ` or
104+ ` developer ` message after the conversation has started was added to
105+ the system prompt on a converted route. It now stays where it was
106+ given: a developer message for a Responses upstream, and a user turn
107+ wrapped in ` <system-reminder> ` for Anthropic, Chat, Gemini and Bedrock
108+ upstreams. The system prompt stays the same from one turn to the next,
109+ which is what keeps the prompt cache working.
110+ - ** ` verbosity ` ** (Chat) and ** ` text.verbosity ` ** (Responses) carry
111+ across the conversion to GPT-5 and later models. Other models still
112+ leave it out.
113+
14114## [ 3.2.1] — 2026-10-09
15115
16116The Helm chart and the Compose file now pull the published images: they
@@ -1469,7 +1569,8 @@ unreleased builds should: stop the gateway, run `db/schema.sql`
14691569against PostgreSQL, restart against this tag. The schema is
14701570idempotent end-to-end, so the apply is safe to repeat.
14711571
1472- [ Unreleased ] : https://github.com/ThinkWatchProject/ThinkWatch/compare/v3.2.1...HEAD
1572+ [ Unreleased ] : https://github.com/ThinkWatchProject/ThinkWatch/compare/v3.3.0...HEAD
1573+ [ 3.3.0 ] : https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v3.3.0
14731574[ 3.2.1 ] : https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v3.2.1
14741575[ 3.2.0 ] : https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v3.2.0
14751576[ 3.1.0 ] : https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v3.1.0
0 commit comments