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.21",
"version": "2026.10.22",
"type": "module",
"packageManager": "pnpm@11.13.0",
"scripts": {
Expand Down
18 changes: 18 additions & 0 deletions release-notes/2026.10.22.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
**Upgrade notes:**
- The bundled core is now 0.75.0. The control-plane protocol stays at 48, so remote servers on core 0.74.0 keep working.
- Nothing is cleared; the request history, stored payloads and settings carry over.
- Plugins: changes a hook makes to the request or tool call it receives now take effect without returning it. Before, they were dropped unless the hook returned the object. The two built-in plugins are updated unless their code was edited.

**Security:**
- The dangerous-command check now looks at every choice of a streamed Chat Completions answer and every candidate of a Gemini answer, not only the first. An upstream could otherwise get a tool call past the check by placing it in a second choice, or by spreading its arguments across two choices.
- In a streamed answer with several choices, placeholders are restored in each choice separately; the choices could get mixed before.

**Plugins:**
- Plugins have a global `tw` with helpers for common edits: `tw.appendSystem`, `tw.texts`, `tw.toolCalls`, `tw.mapStrings`, `tw.replace`, `tw.streamReplace`, `tw.lines` and `tw.pairs`. `tw.streamReplace` replaces text in streamed answers, including a match that spans two pieces of the stream. The template for a new plugin uses them. See the Plugins page of the documentation.
- A stream-mode plugin that held back text and cut a placeholder in two left the placeholder in the answer instead of the original value. This is fixed.
- A stream-mode plugin that failed and was skipped could lose or reorder the text it was holding. This is fixed.
- In answers with several choices, plugins keep each choice apart, and every choice of a non-streamed answer goes through them.
- A stream-mode plugin that only holds text back, without changing it, is no longer recorded as having changed the answer.

**Other:**
- rustls 0.23.46 (RUSTSEC-2026-0346 to -0349).
48 changes: 24 additions & 24 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.21"
version = "2026.10.22"
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.74.0" }
tw-types = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" }
tw-yaml = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" }
tw-guard = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" }
tw-watch = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" }
tw-link = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" }
tw-api = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" }
tw-types = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" }
tw-yaml = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" }
tw-guard = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" }
tw-watch = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" }
tw-link = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.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.21",
"version": "2026.10.22",
"identifier": "app.thinkwatch.lite",
"build": {
"beforeDevCommand": "pnpm dev",
Expand Down
18 changes: 7 additions & 11 deletions src/plugins/Editor.i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,11 @@ export const editorText = messages(
' settings: { note: { type: "string", label: "附加内容", value: "" } },',
"};",
"",
"// 请求发往上游之前调用:req.system 为系统提示词,ctx.settings 为设置项的值。",
"// 返回修改后的 req;返回 undefined 表示不修改。",
"// 请求发往上游之前调用:修改 req 即生效,ctx.settings 为设置项的值。",
"// tw 提供常用的改写函数,例如 tw.appendSystem 在系统提示词末尾附加一段文字。",
"export function onRequest(req, ctx) {",
' const note = String(ctx.settings.note ?? "").trim();',
' if (note === "" || req.system.includes(note)) return undefined;',
' req.system = req.system ? req.system + "\\n\\n" + note : note;',
" return req;",
' if (note !== "") tw.appendSystem(req, note);',
"}",
]),

Expand Down Expand Up @@ -117,14 +115,12 @@ export const editorText = messages(
' settings: { note: { type: "string", label: "Note", value: "" } },',
"};",
"",
"// Runs before a request goes to the upstream: req.system is the system prompt, and",
"// ctx.settings holds the values of the settings. Return the changed req, or undefined",
"// to leave the request unchanged.",
"// Runs before a request goes to the upstream: changes to req take effect, and",
"// ctx.settings holds the values of the settings. tw provides common edits, such as",
"// tw.appendSystem, which adds text to the end of the system prompt.",
"export function onRequest(req, ctx) {",
' const note = String(ctx.settings.note ?? "").trim();',
' if (note === "" || req.system.includes(note)) return undefined;',
' req.system = req.system ? req.system + "\\n\\n" + note : note;',
" return req;",
' if (note !== "") tw.appendSystem(req, note);',
"}",
]),

Expand Down
Loading