Skip to content

ThinkWatch Core 0.83.0

Choose a tag to compare

@github-actions github-actions released this 25 Oct 05:51
· 10 commits to main since this release
96729cf

This release retries upstreams that fail for a moment before any answer content, including a single upstream, and lets routing rules set the reasoning effort, adapting when an upstream refuses one.

Upgrade notes

  • The control-plane protocol version goes from 52 to 54. The request store's schema is unchanged; nothing is cleared.
  • set.thinking in routing rules is removed and replaced by set.reasoning. A configuration that still has thinking: under a rule's set does not load: core starts in safe mode and the one-click repair removes the field. thinking: false corresponds to reasoning: off.
  • failover.wait_secs now limits queueing and retrying together. Its default (120 seconds) and range are unchanged; 0 turns both off.

Temporary upstream failures are retried. When every candidate has been tried and the last attempt failed temporarily before any answer content reached the client, the gateway backs off and tries again instead of passing the error on. With a single upstream, the request is sent to it again.

  • Temporary failures: statuses 500, 502, 503, 504 and 529, unless the body names a request error; in-stream errors with a listed code or type (server_error, api_error, overloaded_error, server_is_overloaded, slow_down, Gemini UNAVAILABLE / INTERNAL, Bedrock serviceUnavailableException / internalServerException); a connection that cannot be made or breaks before the response head; a stream that breaks, or ends after only its opening events, before content (new code gw.upstream.stream_ended_early).
  • Not retried: other statuses, unlisted in-stream errors, rate limits (they keep using the throttle queue), used-up quota, no balance, rejected credentials, a missing model, idle timeouts, and any failure after content. Failover to another candidate is unchanged.
  • Pauses are 2, 4 and 8 seconds, then 16 seconds each time, with up to 20% jitter either way. retry-after-ms, Retry-After or a retry delay in the body can lengthen a pause but not shorten it. Retrying stops when the next pause would end after the request's wait deadline; the last error is then handed over.
  • Each round retries the candidates that failed temporarily in the previous round. A conversation kept on an upstream (session affinity, encrypted history) retries only that upstream. Each retry is a normal hop: request hooks, content filtering, redaction and parameter rewrites run again. Token-counting requests are not retried.
  • The last candidate's streamed answer is held until its first content while the request can still wait, so an error at the start can be retried. After 15 seconds the client receives the response head and keep-alives as before. Whole answers from the last candidate are passed on as they arrive.
  • Hits in content written by plugins are reported once per client request, not once per attempt.
  • New event RequestRetrying (paired with RequestDequeued); AttemptView gains retry and backoff_ms.

Routing rules can set the reasoning effort. set.reasoning takes off or one of low, medium, high, xhigh, max.

  • A level changes the effort of requests that already have reasoning on. Requests without reasoning are left as they are; reasoning is never turned on.
  • off turns reasoning off: OpenAI Chat and Responses requests get none, and other formats lose the reasoning configuration together with the effort. Anthropic's output_config.effort and the GLM-style Chat thinking switch are now removed as well.
  • Rules apply per hop, so a rule with a provider_would_be condition changes only that upstream. Gemini budgets are capped at the model's limit.

Refused efforts are resent with one the upstream accepts. When an upstream answers 400 because of the effort level, the request is sent again once to the same upstream with a level it accepts (the ceiling, or the nearest level the error lists), or without the effort when the error names none.

  • After a successful resend the choice is remembered per upstream, model, format and level for 7 days (effort-memory.json in the data directory), so later requests are right the first time. Entries are dropped when the upstream's address, key or protocol changes, or when it is removed.
  • The resend does not count toward retries. Requests that set only a budget, and WebSocket turns, are not resent.
  • AttemptView.effort (asked, sent, reason: rule, rejected or remembered) records every change on the attempt chain.

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.83.0:

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

An installation made with the script switches to 0.83.0 with:

sudo twcore upgrade --version 0.83.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

  • Retry the last upstream after a temporary failure before any content by @fylorn in #373
  • Reasoning override in routing rules; resend an effort the upstream refuses by @fylorn in #374
  • 0.83.0 by @fylorn in #375

Full Changelog: v0.82.0...v0.83.0