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.10.27",
"version": "2026.10.28",
"type": "module",
"packageManager": "pnpm@11.13.0",
"scripts": {
Expand Down
11 changes: 11 additions & 0 deletions release-notes/2026.10.28.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
**Upgrade notes:**
- The bundled core is now 0.81.0. The control-plane protocol stays at 51, so a remote server running core 0.80.0 still connects; the behavior described below needs 0.81.0 on the side that runs the gateway.
- Nothing is cleared; the request history, stored payloads and settings carry over.

**Conversations with encrypted history stay on their upstream:**
- OpenAI Responses upstreams, such as a ChatGPT account, hand clients encrypted history that only the same account can read. Codex sends it back every turn. Before, moving Codex's route to another upstream made a conversation under way fail on every turn.
- Such a conversation now goes back to the upstream that encrypted its history, even after its route changes. The request details show this under Conversation.
- If that upstream was removed, or another upstream is asked to read the history, the request fails with a message that explains why and suggests routing the conversation back or starting a new one.

**Routing:**
- In the route table's rule list, the letter tile shown for an upstream without a logo lines up with the text.
30 changes: 15 additions & 15 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.10.27"
version = "2026.10.28"
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.80.0" }
tw-types = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.80.0" }
tw-yaml = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.80.0" }
tw-guard = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.80.0" }
tw-watch = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.80.0" }
tw-link = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.80.0" }
tw-api = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.81.0" }
tw-types = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.81.0" }
tw-yaml = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.81.0" }
tw-guard = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.81.0" }
tw-watch = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.81.0" }
tw-link = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.81.0" }

[lib]
name = "thinkwatch_lite_lib"
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.10.27",
"version": "2026.10.28",
"identifier": "app.thinkwatch.lite",
"build": {
"beforeDevCommand": "pnpm dev",
Expand Down
2 changes: 1 addition & 1 deletion src/generated/tw-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5487,7 +5487,7 @@ gateway_reachable: Array<string>, };
/**
* 留在上次回答这段对话的那一家的理由。
*/
export type Stay = "turn" | "cache";
export type Stay = "turn" | "cache" | "sealed";

/**
* 观测这一层在不在记。
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/core.zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@
"gw.wait.mixed": "等待期间没有可处理此请求的上游恢复可用。因 429 暂停:{rate_limited!names}。达到按分钟或小时计的用量上限:{window_full!names}。当天、当周或当月的用量上限已用完:{used_up!names}。达到并发上限:{busy!names}。请稍后重试。",
"gw.route.upstream_missing": "配置中不存在「{upstream}」。",
"gw.route.selected_upstream_missing": "规则「{rule}」选中的上游「{upstream}」在配置中不存在。",
"gw.route.sealed_upstream_gone": "此对话的历史由上游「{upstream}」加密,该上游已不在配置中,其他上游无法读取。请开始新的对话。",
"gw.route.all_selected_disabled": "路由选中的上游均已停用:{detail}",
"gw.route.protocol_mismatch": "{path} 只能由 {wanted} 格式的上游处理,而上游「{upstream}」是 {got} 格式。",
"gw.count_tokens.bedrock_upstream": "无法通过 AWS Bedrock 上游「{upstream}」计算 token 数。",
Expand All @@ -498,6 +499,7 @@
"gw.upstream.forward_failed": "转发失败:{detail}",
"gw.upstream.body_broken": "回答接收途中与上游的连接断开:{detail}",
"gw.upstream.rate_limited": "上游「{upstream}」触发限流。",
"gw.upstream.sealed_elsewhere": "上游「{upstream}」无法读取此对话中加密的历史:历史由另一个上游加密,只有该上游能够读取。请将此对话改回原来的上游,或开始新的对话。上游返回:{message}",
"gw.upstream.paused": "上游「{upstream}」返回 429(限流),已暂停发送,约 {secs} 秒后恢复。",
"gw.upstream.window_full": "上游「{upstream}」已达到一条按分钟或小时计的用量上限,约 {secs} 秒后空出额度。",
"gw.upstream.period_used_up": "上游「{upstream}」当天、当周或当月的一条用量上限已用完,将于 {resets} 重置。",
Expand Down
2 changes: 2 additions & 0 deletions src/traffic/drawer/RequestDrawer.i18n.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export const requestDrawerText = messages(
heldRoute: "沿用本轮开头的路由决定",
stayedTurn: "同一轮内留在上次回答的上游",
stayedCache: "上次回答的缓存仍有效,留在该上游",
stayedSealed: "对话带有该上游加密的内容,只能送回该上游",
/** 选定上游之后才判断、拒绝了此请求的规则 */
deniedBy: "拒绝规则",
/** 规则写的拒绝理由,或者选中的上游为何都无法服务 */
Expand Down Expand Up @@ -275,6 +276,7 @@ export const requestDrawerText = messages(
heldRoute: "Kept the route decided at the start of this turn",
stayedTurn: "Stayed with the upstream that answered earlier in this turn",
stayedCache: "Stayed with the upstream that answered last, while its cache is warm",
stayedSealed: "Sent back to the upstream that encrypted content in this conversation",
deniedBy: "Denied by",
reason: "Reason",
attempts: "Attempts",
Expand Down
1 change: 1 addition & 0 deletions src/traffic/drawer/Routing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export function Routing({ r, plugins, running }: { r: HistoryRow; plugins: Plugi
{f.continuity.heldRoute && <span>{t.heldRoute}</span>}
{f.continuity.stayed === "turn" && <span>{t.stayedTurn}</span>}
{f.continuity.stayed === "cache" && <span>{t.stayedCache}</span>}
{f.continuity.stayed === "sealed" && <span>{t.stayedSealed}</span>}
</span>
}
/>
Expand Down
Loading