Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "thinkwatch-lite",
"private": true,
"description": "Desktop app for a local AI API gateway on macOS, Windows and Linux",
"version": "2026.9.26",
"version": "2026.10.0",
"type": "module",
"packageManager": "pnpm@11.13.0",
"scripts": {
Expand Down
47 changes: 47 additions & 0 deletions release-notes/2026.10.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
**Upgrade notes:**
- The bundled core is now 0.57.1, which speaks control-plane protocol 31. A remote server has to run core 0.57.x too: this version does not connect to 0.56.x, and 2026.9.26 and earlier do not connect to 0.57.x.
- **Request history is cleared** on the first start, as the request store is rebuilt. Configuration, keys and upstreams are kept.
- Two redaction rules are on by default: Chinese resident ID numbers and bank card numbers. In Observe, the factory mode, they are only recorded; in Enforce they are replaced before a request leaves. Either can be switched off on the Security page.
- Routing rules on input tokens now use the gateway's token-count estimate: one token per CJK character and 1,600 per image or file, with thinking left out. A request with many images can now cross a size threshold it used to stay under.

**Searching the whole history:**
- The Traffic page used to search only the latest 2,000 requests it had loaded. A search or filter now also runs over every stored request, newest first. The footer says how far back the search has got, and **Search further** goes back another page.
- The toggle inside the search box also searches content. It covers what each request newly sent (the last user turn, tool results included) and its answer (text and tool calls), for requests whose payloads are still kept.
- Each content match shows an excerpt under the request, with credentials masked.

**Upstream check-up:**
- **Upstreams › Check-up** compares each upstream with the others over 24 hours, 7 days, 30 days or a custom range:
- requests and failure rate;
- whether the model named in its answers matches the one sent, with the pairs that differ;
- the input it reports, as a multiple of the local estimate, against other upstreams serving the same model;
- the share of input read from the prompt cache in follow-up turns, against those upstreams too;
- median time to first token and generation speed.
- Every figure comes with its sample size. A deviation is marked only when both sides have enough samples:
- input: a gap of 25% or more, and only on the upstream further from the local estimate;
- cache: other upstreams read at least 30% from the cache and this one less than half of that.

**ID and bank card numbers:**
- Outbound redaction now also replaces Chinese resident ID numbers and bank card numbers. A number counts only when its structure and check digit are valid:
- an ID number needs a region code, a real birth date and a valid check character;
- a card number needs the prefix and length of UnionPay, Visa, Mastercard, American Express, JCB, Discover or Diners Club, and must pass the Luhn check.
- Placeholders say what was there, such as `<<TW_ID_NUMBER_1>>`, and the security log shows only the last four characters.

**More clients:**
- The Clients page now connects Pi, oh-my-pi, Grok Build, Qwen Code and Hermes Agent:
- **Pi and oh-my-pi** get a provider of their own with the models the key can use. Their default model stays as it is, and ThinkWatch models are chosen in `/model`.
- **Grok Build** gets one model entry per gateway model, each with its own key, so the xAI session token is never sent to the gateway. One of them becomes the default model. Remote campaigns, which can change the default model, are turned off while it is connected.
- **Qwen Code** 0.19.3 or later gets a provider of its own in the OpenAI format, and the change applies after a restart.
- **Hermes Agent**: its default profile is pointed at the gateway, and other profiles keep their own configuration.
- **DeepSeek Harness** counts as installed when only its desktop app is. Models used through a DeepSeek account in the desktop app still go to DeepSeek directly, which the plan now says.
- The MCP page lists the servers of the five new clients without writing to them. Skills in the shared `~/.agents/skills` folder appear under a shared folder, and Cursor's hooks are scanned too.
- Codex stopped reading `OPENAI_BASE_URL` in April 2026, so a shell that still exports it is no longer reported as overriding the connection.

**Getting started:**
- Until the first request reaches an upstream, the Overview page shows a checklist: add an upstream, connect a client, send a first request.
- Other pages show a hint for the next step where it applies. A hint can be hidden, and **Settings › General** shows the hidden ones again.

**Requests other than POST:**
- These now get a 404 from the gateway itself. Hermes Agent sends such GETs when it starts, to tell whether a server is Ollama or LM Studio.
- They used to be sent to an upstream as empty POSTs and recorded as failed requests.

The [Features](https://thinkwat.ch/docs/lite/features) page describes each of these in full.
4 changes: 0 additions & 4 deletions scripts/shots/mock/clients.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,10 +419,6 @@ function clientsNow(): DetectedClient[] {
"adopt.cost.hermes_agent.restart",
"Hermes Agent sessions that are already open keep their provider until they are restarted; the messaging gateway picks up the change with the next message.",
),
msg(
"adopt.cost.hermes_agent.probes",
"Hermes Agent checks whether the gateway is a local model server such as LM Studio or Ollama; those checks appear in Traffic as failed requests.",
),
],
}),
];
Expand Down
46 changes: 23 additions & 23 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "thinkwatch-lite"
version = "2026.9.26"
version = "2026.10.0"
edition = "2024"
# **这个数决定依赖能升到哪一版。**edition 2024 的解析器只挑声明的 Rust
# 版本编得动的依赖:写 1.85 的时候,`cargo update` 一直停在旧的 time 和
Expand All @@ -26,12 +26,12 @@ license = "MIT"
# twcore 二进制必须和这里编译进去的协议镜像来自同一个 core 版本 —— 打包脚本正是
# 从 tw-api 锁到的 tag 去取二进制的(见 scripts/fetch-core.sh)。
[workspace.dependencies]
tw-api = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.0" }
tw-types = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.0" }
tw-yaml = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.0" }
tw-guard = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.0" }
tw-watch = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.0" }
tw-link = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.0" }
tw-api = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.1" }
tw-types = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.1" }
tw-yaml = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.1" }
tw-guard = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.1" }
tw-watch = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.1" }
tw-link = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.57.1" }

[lib]
name = "thinkwatch_lite_lib"
Expand Down
7 changes: 2 additions & 5 deletions src-tauri/crates/tw-adopt/src/clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,11 +666,8 @@ pub fn adoptable() -> Vec<Client> {
code!("adopt.cost.hermes_agent.restart"),
"Hermes Agent sessions that are already open keep their provider until they are restarted; the messaging gateway picks up the change with the next message.",
),
// 指向本机的地址,它会挨个问几个本地模型服务的路径,网关把这些请求转给上游
(
code!("adopt.cost.hermes_agent.probes"),
"Hermes Agent checks whether the gateway is a local model server such as LM Studio or Ollama; those checks appear in Traffic as failed requests.",
),
// 它起来时还会拿 GET 问几个本机模型服务的路径(`/api/tags`、`/version` …),看网关
// 是不是 Ollama、LM Studio:core 0.57.1 起网关就地回 404,不转发、不记录,用不着说
],
verified: Verified::FieldsOnly,
marker: &[crate::paths::HERMES_DIR],
Expand Down
1 change: 0 additions & 1 deletion src-tauri/msg-codes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ adopt.cost.dsh.web_search
adopt.cost.grok_build.builtin_models
adopt.cost.grok_build.campaigns
adopt.cost.grok_build.helper_models
adopt.cost.hermes_agent.probes
adopt.cost.hermes_agent.restart
adopt.cost.omp.default_model
adopt.cost.opencode.restart
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "ThinkWatch Lite",
"version": "2026.9.26",
"version": "2026.10.0",
"identifier": "app.thinkwatch.lite",
"build": {
"beforeDevCommand": "pnpm dev",
Expand Down
2 changes: 1 addition & 1 deletion src/i18n/core.zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@
"gw.convert.tool_unsendable": "请求要求使用工具 {tool},但无法按上游「{upstream}」的格式发送。网页搜索这类服务端工具只能由所属的服务商执行。",
"gw.convert.tools_unsendable": "请求要求调用工具,但其中的工具都无法按上游「{upstream}」的格式发送。网页搜索这类服务端工具只能由所属的服务商执行。",
"gw.files.unsupported": "网关不托管文件,图片和文档请直接放在请求中发送。",
"gw.method.not_forwarded": "{method} {path} 不是 API 调用。网关只向上游转发 POST 请求。",
"gw.request.body_too_large": "请求体大小为 {size} 字节,超过上限 {max} 字节。",
"gw.upstream.timeout": "上游响应超时。",
"gw.upstream.unreachable": "无法连接上游 {url},请检查接口地址、网络和代理设置。",
Expand Down Expand Up @@ -663,7 +664,6 @@
"adopt.cost.qwen_code.other_models": "为快速回复、视觉、上下文压缩等任务单独设置的模型仍使用各自的提供方。",
"adopt.cost.qwen_code.proxy": "Qwen Code 使用代理时,需将网关地址加入 NO_PROXY,否则发往网关的请求也会经过代理。",
"adopt.cost.hermes_agent.restart": "已打开的 Hermes Agent 会话在重新启动前仍使用原来的提供方;消息网关从下一条消息起使用新配置。",
"adopt.cost.hermes_agent.probes": "Hermes Agent 会检测网关是否为 LM Studio、Ollama 等本机模型服务,这些检测请求会以失败请求的形式出现在流量中。",
"// ── adopt.diag:接管为什么没生效 ────────────────────────────────": "",
"adopt.diag.not_running": "{client} 当前未运行",
"adopt.diag.not_running.detail": "下次启动时将读取新配置。",
Expand Down
Loading