Skip to content

ThinkWatch Core 0.67.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 13:29
· 18 commits to main since this release
e7c0233

This release stops requests from hanging on an upstream that answers and then goes quiet, lets a running request or a whole session be aborted, and makes Codex work through routes that convert its requests to another format: its tools, history, compactions and mid-conversation instructions now all arrive. Requests converted for Claude now use prompt caching. Signing in to a ChatGPT account on another device works again.

Upgrade notes

  • The control-plane protocol version (CONTROL_API_VERSION) goes from 42 to 43. ThinkWatch Lite connects only to a core with the same protocol version: ThinkWatch Lite 2026.10.10 includes 0.66.0 (protocol 42) and does not connect to 0.67.0. A server used with it stays on 0.66.0 until the app is updated to a release that includes 0.67.0; sudo twcore upgrade --version 0.66.0 --restart switches a server back.
  • The request store's schema goes to 26: the request history and stored payloads are cleared on the first start. Recorded attempts could hold an outcome that no longer exists.
  • failover.next_on_slow_start and failover.stream_start_wait_secs are removed. A configuration that still has either fails to load and core starts in safe mode; the safe-mode repair offers to delete them. The new failover.idle_timeout_secs (default 300) replaces them.
  • Requests converted for Claude are cached. Prompt-cache writes are billed at the provider's cache-write rate (25% above input for Anthropic) and reads at its cache-read rate (a tenth of input), and both are recorded and priced from the price table. Clients that mark their own breakpoints, such as Claude Code, are unchanged.
  • Changed in the protocol:
    • New endpoints POST /request/{id}/abort and POST /sessions/{id}/abort (→ Aborted { requests }).
    • Attempts gain the outcomes idle_timeout (with the time waited) and aborted; a request aborted by the user is recorded with the failure source aborted.
    • FailoverView gains idle_timeout_secs and loses next_on_slow_start and stream_start_wait_secs; the slow_start outcome is gone.
  • Message codes, compared with 0.66.0:
    • New: gw.upstream.idle_timeout, gw.upstream.idle_timeout_mid_stream, gw.request.aborted, control.request_not_running, control.session_not_running.
    • Removed: gw.slow_start, config.slow_start_too_short.

No response. An upstream that accepts a request and then sends nothing used to keep it forever: there is deliberately no overall timeout, and the only check, moving on when a stream was slow to start, was off by default and never applied to the last upstream. Now, when failover.idle_timeout_secs (300 seconds by default, 30 to 3600) pass without any content — text, reasoning or a tool call; keep-alive pings do not count — the gateway gives up on that upstream. Before anything has reached the client, the request moves to the next upstream and the silent one counts as a failure for its pause; when none is left, the client gets a timeout error in its own format instead of waiting. After content has started, the answer ends with an error event the client understands. A whole (non-streamed) answer counts the same time until it arrives. A streamed answer is held for at most 15 seconds; after that the client receives its response headers and keep-alive comments, so it does not give up while the gateway is still able to move to the next upstream.

Abort. A running request, or every running request of a session, can be aborted from the control plane. The upstream call is dropped at once, the client gets an error, the request is recorded as aborted by the user, and the upstream is not set aside.

Codex through converted routes.

  • For some models Codex sends no top-level tools and declares every tool in an additional_tools input item. Those items were dropped, so a route converting to Anthropic, Chat, Gemini or Bedrock sent no tools at all, and Codex reported that it could not read files or run commands. Every tool now arrives, and tool calls come back to Codex under the names and kinds it declared.
  • Local shell calls, tool search, mid-session reasoning-effort changes and agent messages in the history are converted instead of dropped. text.verbosity reaches GPT-5 and later models on Chat upstreams.
  • Compacting a long session works on converted routes: the upstream writes a handoff summary, Codex receives it as its compaction, and later requests carry it back. OpenAI's own encrypted compactions still cannot be read by other upstreams and are refused clearly.
  • Developer messages that arrive in the middle of a conversation stay where they are instead of joining the system prompt, so the system prompt stays the same from turn to turn and caching keeps working.

Prompt caching for Claude. A request converted for Claude from a client that marks no cache breakpoints — Codex, Chat and Gemini clients — now gets them on the tools, the system prompt and the last two user turns, so each turn reads what the previous one cached. This applies to Anthropic-format upstreams and to Claude models on Bedrock.

ChatGPT account on another device. OpenAI's device-code answer now gives its polling interval as text ("5"), which stopped the sign-in with "could not be read". Numbers written as text are now accepted there and in the other sign-in answers that carry durations.

Downloads

Platform Binary Archive for server installation
Linux, x86_64 twcore-x86_64-unknown-linux-gnu twcore-x86_64-unknown-linux-gnu.tar.gz
Linux, aarch64 twcore-aarch64-unknown-linux-gnu twcore-aarch64-unknown-linux-gnu.tar.gz
macOS, Apple silicon twcore-aarch64-apple-darwin —
Windows, x64 twcore-x86_64-pc-windows-msvc.exe —
Windows, ARM64 twcore-aarch64-pc-windows-msvc.exe —

Each file is published with a .sha256 file beside it. A Linux archive contains twcore, the systemd unit twcore.service and LICENSE. ThinkWatch Lite includes its own copy of twcore; the files here are for running core separately, such as on a server.

Server installation

On Linux (x86_64 or aarch64), the install script sets up twcore as a systemd service. This installs 0.67.0:

curl -fsSL https://raw.githubusercontent.com/ThinkWatchProject/ThinkWatch-Core/main/scripts/install.sh | sudo sh -s -- --version 0.67.0

An installation made with the script switches to 0.67.0 with:

sudo twcore upgrade --version 0.67.0 --restart

Configuration, the remote control port and connecting ThinkWatch Lite are described in docs/server.md.

Verifying a download

A .sha256 file holds the SHA-256 of the file followed by its name. With both files in the current directory, on Linux:

sha256sum -c twcore-x86_64-unknown-linux-gnu.tar.gz.sha256

On macOS:

shasum -a 256 -c twcore-aarch64-apple-darwin.sha256

On Windows, in PowerShell, the following prints True when the binary matches:

(Get-FileHash .\twcore-x86_64-pc-windows-msvc.exe).Hash -eq (Get-Content .\twcore-x86_64-pc-windows-msvc.exe.sha256).Split()[0]

The install script and twcore upgrade check the SHA-256 themselves.

What's Changed

  • ChatGPT login: read the device code's interval as a number or a numeric string by @fylorn in #302
  • Idle timeout with automatic failover, and manual abort of requests and sessions (protocol 43) by @fylorn in #303
  • Responses conversion: keep the tools Codex declares in input, and every item it sends by @fylorn in #304
  • Codex compaction on converted routes; mid-conversation developer messages stay in place by @fylorn in #305
  • Mark prompt-cache breakpoints for Claude when the client marked none by @fylorn in #306
  • chore: v0.67.0 by @fylorn in #307

Full Changelog: v0.66.0...v0.67.0