diff --git a/README.md b/README.md
index 818dce7..210b612 100644
--- a/README.md
+++ b/README.md
@@ -170,7 +170,7 @@ SayIt/
| 语音识别 | Qwen3-ASR + vLLM / 豆包 ASR / 千问 ASR / sherpa-onnx |
| AI 润色 | DeepSeek / 通义千问 / Azure OpenAI / Ollama |
| 部署 | Docker Compose、NVIDIA Container Toolkit |
-| 开发 | 整个项目使用 Claude Opus 4.6 开发 |
+| 开发 | 整个项目使用 Claude Opus 开发 |
## 开发
@@ -195,6 +195,18 @@ cd backend && uvicorn app.main:app --port 8000
前置要求:Python 3.10+、NVIDIA GPU + CUDA
+## 交流反馈
+
+有任何问题、建议或想法,欢迎扫码加入用户反馈微信群,一起交流:
+
+
+
+

+
+*微信扫码加入 SayIt 用户反馈群*
+
+
+
## 贡献
欢迎提交 Bug 报告和功能建议!请阅读 [贡献指南](./CONTRIBUTING.md)。
diff --git a/client/package.json b/client/package.json
index f31ce0d..bc12fb3 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
{
"name": "sayit-tauri",
- "version": "0.0.5",
+ "version": "0.0.7",
"description": "SayIt - Voice to Text Desktop App (Tauri)",
"type": "module",
"scripts": {
diff --git a/client/src-tauri/Cargo.lock b/client/src-tauri/Cargo.lock
index 9610a19..a0cb3fa 100644
--- a/client/src-tauri/Cargo.lock
+++ b/client/src-tauri/Cargo.lock
@@ -3763,7 +3763,7 @@ dependencies = [
[[package]]
name = "sayit"
-version = "0.0.5"
+version = "0.0.7"
dependencies = [
"base64 0.22.1",
"bzip2",
diff --git a/client/src-tauri/Cargo.toml b/client/src-tauri/Cargo.toml
index ab3879a..72f67ba 100644
--- a/client/src-tauri/Cargo.toml
+++ b/client/src-tauri/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "sayit"
-version = "0.0.5"
+version = "0.0.7"
authors = ["Liu Qianglong", "Claude"]
edition = "2021"
diff --git a/client/src-tauri/src/commands/system.rs b/client/src-tauri/src/commands/system.rs
index 8fa435b..6339e1b 100644
--- a/client/src-tauri/src/commands/system.rs
+++ b/client/src-tauri/src/commands/system.rs
@@ -246,7 +246,11 @@ pub fn check_for_updates() -> Result {
/// 下载更新安装包到临时目录
#[tauri::command]
pub async fn download_update(url: String) -> Result {
- let client = reqwest::Client::new();
+ // 必须带 User-Agent:生产环境 AWS WAF 的 NoUserAgent_HEADER 规则会拦截无 UA 的请求(403)
+ let client = reqwest::Client::builder()
+ .user_agent(concat!("SayIt/", env!("CARGO_PKG_VERSION")))
+ .build()
+ .map_err(|e| format!("初始化下载客户端失败: {}", e))?;
let resp = client
.get(&url)
.timeout(std::time::Duration::from_secs(300))
diff --git a/client/src-tauri/src/main.rs b/client/src-tauri/src/main.rs
index f242419..93248d3 100644
--- a/client/src-tauri/src/main.rs
+++ b/client/src-tauri/src/main.rs
@@ -178,11 +178,21 @@ fn main() {
hook.start(app.handle(), &ptt_str, &hf_str);
// 设置窗口图标(用 ICO 文件,包含多尺寸帧,Windows 自动选最合适的)
+ // 并根据启动方式决定是否显示主窗口:
+ // 开机自启会带 --minimized 参数 → 保持隐藏,静默停留在托盘
+ // 用户手动打开则正常显示(窗口配置为 visible:false,需显式 show)
+ let launched_minimized = std::env::args().any(|arg| arg == "--minimized");
if let Some(main_window) = app.get_webview_window("main") {
let ico_bytes = include_bytes!("../icons/icon.ico");
if let Ok(icon) = tauri::image::Image::from_bytes(ico_bytes) {
let _ = main_window.set_icon(icon);
}
+ if !launched_minimized {
+ let _ = main_window.show();
+ let _ = main_window.set_focus();
+ } else {
+ log::info!("Launched with --minimized, staying hidden in tray");
+ }
}
// 系统托盘图标
@@ -261,14 +271,26 @@ fn main() {
{
use tauri_plugin_autostart::ManagerExt;
let storage: tauri::State = app.state();
+ let autostart = app.autolaunch();
let already_set = storage.get("autoLaunchInitialized", None);
if already_set.is_null() || already_set.as_str() == Some("") {
- // 首次运行,注册开机自启并标记
- let autostart = app.autolaunch();
+ // 首次运行,注册开机自启并标记(新注册已带 --minimized 参数)
let _ = autostart.enable();
let flag = serde_json::json!("true");
let _ = storage.set("autoLaunchInitialized", &flag);
+ let _ = storage.set("autoLaunchArgsMigrated", &flag);
log::info!("Auto-launch enabled on first run");
+ } else {
+ // 老用户迁移:旧自启项不带 --minimized 参数,重新注册一次以写入新参数
+ let migrated = storage.get("autoLaunchArgsMigrated", None);
+ if migrated.as_str() != Some("true") {
+ if autostart.is_enabled().unwrap_or(false) {
+ let _ = autostart.disable();
+ let _ = autostart.enable();
+ log::info!("Auto-launch re-registered with --minimized arg");
+ }
+ let _ = storage.set("autoLaunchArgsMigrated", &serde_json::json!("true"));
+ }
}
}
@@ -284,7 +306,7 @@ fn main() {
// .plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_autostart::init(
tauri_plugin_autostart::MacosLauncher::LaunchAgent,
- None,
+ Some(vec!["--minimized"]),
))
.invoke_handler(tauri::generate_handler![
// Store
diff --git a/client/src-tauri/tauri.conf.json b/client/src-tauri/tauri.conf.json
index 9e5120d..b4fe411 100644
--- a/client/src-tauri/tauri.conf.json
+++ b/client/src-tauri/tauri.conf.json
@@ -1,6 +1,6 @@
{
"productName": "SayIt",
- "version": "0.0.5",
+ "version": "0.0.7",
"identifier": "com.sayit.app",
"build": {
"frontendDist": "../dist",
@@ -20,7 +20,7 @@
"minHeight": 600,
"decorations": false,
"center": true,
- "visible": true
+ "visible": false
}
],
"security": {
diff --git a/client/src/services/defaults.ts b/client/src/services/defaults.ts
index 3a4c504..a462a87 100644
--- a/client/src/services/defaults.ts
+++ b/client/src/services/defaults.ts
@@ -22,7 +22,7 @@ export const DEFAULTS: Record = {
selectedMic: '', // 设备 ID,空字符串 = 系统默认
// ── AI 校对 ──
- aiEnabled: false, // 是否开启 AI 校对。可选: true | false
+ aiEnabled: true, // 是否开启 AI 校对。可选: true | false
aiPromptAppend: '', // 全局附加 prompt
// ── AI 供应商 ──
diff --git a/client/src/services/personalization/defaults.ts b/client/src/services/personalization/defaults.ts
index 36b2291..cfd2b8a 100644
--- a/client/src/services/personalization/defaults.ts
+++ b/client/src/services/personalization/defaults.ts
@@ -6,7 +6,7 @@ export const BUILTIN_APP_RULES: AppPromptRule[] = [
appId: 'teams',
name: 'Teams',
builtin: true,
- enabled: true,
+ enabled: false,
priority: 100,
presetId: 'intent',
promptAppend: '适合即时协作聊天。优先输出可以直接发送的短消息,语气自然、清晰、简洁,避免邮件腔。',
@@ -20,7 +20,7 @@ export const BUILTIN_APP_RULES: AppPromptRule[] = [
appId: 'outlook',
name: 'Outlook',
builtin: true,
- enabled: true,
+ enabled: false,
priority: 95,
presetId: 'intent',
promptAppend: '适合工作邮件草稿。语气正式、完整,必要时自然分段,但不要编造收件人、称呼或任何事实。',
@@ -34,7 +34,7 @@ export const BUILTIN_APP_RULES: AppPromptRule[] = [
appId: 'kiro',
name: 'Kiro',
builtin: true,
- enabled: true,
+ enabled: false,
priority: 90,
presetId: 'faithful',
promptAppend: '面向开发工具输入。保留代码、命令、文件名、路径、英文标识符和 Markdown 结构,不要把技术词改写成普通中文。',
@@ -48,7 +48,7 @@ export const BUILTIN_APP_RULES: AppPromptRule[] = [
appId: 'vscode',
name: 'VSCode',
builtin: true,
- enabled: true,
+ enabled: false,
priority: 85,
presetId: 'faithful',
promptAppend: '面向 VSCode 编辑区。保留代码、命令、文件名、API、英文术语和 Markdown 结构,不要过度润色技术内容。',
@@ -62,7 +62,7 @@ export const BUILTIN_APP_RULES: AppPromptRule[] = [
appId: 'cursor',
name: 'Cursor',
builtin: true,
- enabled: true,
+ enabled: false,
priority: 80,
presetId: 'faithful',
promptAppend: '面向 Cursor 编辑区。保留代码、命令、路径、技术名词和英文标识符,不要擅自解释或补全技术内容。',
@@ -76,7 +76,7 @@ export const BUILTIN_APP_RULES: AppPromptRule[] = [
appId: 'notepad',
name: '记事本',
builtin: true,
- enabled: true,
+ enabled: false,
priority: 70,
presetId: 'intent',
promptAppend: '面向 Windows 记事本,适合随手记录的纯文本。输出纯文本,不要使用 Markdown 标记或特殊格式符号。',
diff --git a/client/src/services/personalization/store.ts b/client/src/services/personalization/store.ts
index 2722e26..63372bd 100644
--- a/client/src/services/personalization/store.ts
+++ b/client/src/services/personalization/store.ts
@@ -39,7 +39,7 @@ function normalizeAppPromptRule(raw: unknown, fallback?: AppPromptRule): AppProm
appId,
name,
builtin: value.builtin === true || fallback?.builtin === true,
- enabled: typeof value.enabled === 'boolean' ? value.enabled : fallback?.enabled ?? true,
+ enabled: typeof value.enabled === 'boolean' ? value.enabled : fallback?.enabled ?? false,
priority,
presetId: String(value.presetId ?? fallback?.presetId ?? '').trim() || undefined,
promptAppend: String(value.promptAppend ?? fallback?.promptAppend ?? '').trim(),
diff --git a/docs/SayIt AI 服务提供商.md b/docs/SayIt AI 服务提供商.md
deleted file mode 100644
index 235880d..0000000
--- a/docs/SayIt AI 服务提供商.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# SayIt AI 润色供应商
-
-SayIt 有两个核心功能:语音转文本(ASR)和 AI 文本润色。ASR 部分可以参考 [豆包语音识别凭证获取](豆包ASR凭据获取.md) 和 [阿里云千问语音识别](aliyun.md)。
-
-AI 润色功能可以去除口癖词(嗯、啊、那个)、修正语音识别错误、自动分段排版等,都可以通过 Prompt 自定义控制。
-
-SayIt 已对接国内常用的 AI 服务商(通义千问、DeepSeek、豆包等),同时支持 OpenAI 兼容格式,可以接入其他供应商或第三方中转。
-
-## 1. 最佳实践
-
-**推荐 DeepSeek deepseek-v4-flash 作为默认选择。** 质量最好、价格极低、速度可接受。
-
-DeepSeek V4 Flash(2026 年 4 月发布)是 284B 参数的 MoE 模型,13B 激活参数,支持 1M 上下文。关闭思考模式后速度接近旧版 deepseek-chat,但质量明显更好,价格还更便宜(输入 1 元/百万 Token,输出 2 元/百万 Token)。
-
-如果对延迟极度敏感(需要 <500ms),可以用通义千问 qwen3.6-flash,速度最快但质量略逊。
-
-| 供应商 | 模型 | 短文本 | 长文本 | 每月成本 |
-| --------------| -------------------| -----------| ------------| ----------|
-| **DeepSeek** | deepseek-v4-flash | **803ms** | **2089ms** | ~1.5 元 |
-| 通义千问 | qwen3.6-flash | 393ms | 1308ms | ~3.8 元 |
-
-> 月成本按每天 100 次、每次约 100 字估算。V4 Flash 默认开启 thinking,会导致延迟飙升到 2~7 秒。SayIt 已在代码中自动关闭思考模式,无需用户手动配置。
-
-## 2. 如何选择AI模型
-
-- **速度**:总耗时由 TTFT(Time To First Token,首个字生成时间)和 TPS(每秒 Token 数)决定。语音转写场景下,总耗时超过 1~2 秒会有明显等待感。
-- **质量**:能否准确执行 Prompt 指令——去口癖、识别自我修正、格式化列表、纠正专有名词大小写等。
-- **价格**:V4 Flash 的自动 prompt 缓存机制让重复 system prompt 的场景成本极低。
-
-## 3. 实测数据
-
-以下数据是 2026 年 5 月实测的,使用非流式请求(和 SayIt 实际调用方式一致),每条用例跑了 3 次取中位数。
-
-### 速度
-
-| 供应商 | 模型 | 短文本 | 中等文本 | 长文本(~200字) |
-| ----------| -------------------------------| --------| ----------| ------------------|
-| DeepSeek | deepseek-v4-flash(关闭思考) | 803ms | 971ms | 2089ms |
-| 通义千问 | qwen3.6-flash | 393ms | 489ms | 1308ms |
-
-
-### 质量
-
-两家都能正确去口癖、识别列表结构、纠正专有名词大小写(DeepSeek、ChatGPT、OpenAI 等)。V4 Flash 在专有名词纠正和格式化方面更稳定,输出更简洁。
-
-
-## 4. 关于豆包
-
-豆包的语音识别(ASR)是目前中文场景下最好的,SayIt 推荐使用豆包 ASR。但豆包的 AI 文本模型(lite 和 mini 都测了)延迟极不稳定,中长文本经常超过 10 秒,不适合语音转写的润色场景。建议 ASR 用豆包,AI 润色用 DeepSeek 或通义千问。
-
-## 5. 价格参考
-
-| 供应商 | 模型 | 输入(百万Token) | 输出(百万Token) |
-| ----------| ----------------------| -------------------| -------------------|
-| DeepSeek | deepseek-v4-flash | 1 元 | 2 元 |
-| 通义千问 | qwen3.6-flash | 1.8 元 | 10.8 元 |
-| 豆包 | doubao-seed-2-0-mini | 0.2 元 | 2 元 |
-
-
-
-## 6. 配置指南
-
-> 建议直接使用官方 API。第三方中转站延迟普遍更高。
-
-### DeepSeek(推荐)
-
-- API 地址:`https://api.deepseek.com`
-- 模型:`deepseek-v4-flash`
-- 获取 API Key:[platform.deepseek.com](https://platform.deepseek.com/api_keys)
-- **注意**:SayIt 会自动在请求中添加 `thinking: {type: "disabled"}` 关闭思考模式以降低延迟
-
-
-### 通义千问
-
-- API 地址:`https://dashscope.aliyuncs.com/compatible-mode`
-- 模型:`qwen3.6-flash`
-- 获取 API Key:[百炼平台](https://bailian.console.aliyun.com/?spm=a2c4g.11186623.0.0.60905ec6iyaRqr&tab=model#/api-key)
-
-
-### 豆包(火山方舟)
-- API 地址:`https://ark.cn-beijing.volces.com/api/v3`
-- 模型:`doubao-seed-2-0-mini-260215`
-
\ No newline at end of file
diff --git a/docs/SayIt ASR 服务提供商.md b/docs/SayIt ASR 服务提供商.md
deleted file mode 100644
index e5ea29f..0000000
--- a/docs/SayIt ASR 服务提供商.md
+++ /dev/null
@@ -1,95 +0,0 @@
-# SayIt ASR 语音识别配置
-
-SayIt 支持三种语音识别模式:
-
-- **云端 API**:调用云服务商的语音识别接口,准确率最高,适合大多数个人用户
-- **本地推理**:使用本地模型离线识别,不需要网络,但准确率和速度不如云端
-- **服务器模式**:自己部署后端服务,适合团队或有定制需求的场景
-
-对个人用户来说,**云端 API 是最推荐的方式**,下面主要介绍这个。
-
-## 1. 最佳实践
-
-中文语音识别准确率最高的是**豆包流式语音识别 2.0**(Seed-ASR-2.0),其次是阿里的**千问 ASR**(qwen3-asr-flash)。
-
-SayIt 对豆包和千问 ASR 都做了流式优化——按住说话时,音频会实时发送给服务端,松手后只需要等待最后一小段音频的处理时间,通常几百毫秒就能拿到结果。
-
-另外 SayIt 还支持**千问 3.5 Omni** 多模态模型,这类模型原生支持音频输入、文本输出,可以在转录的同时执行 Prompt 指令(比如去口癖、翻译等),相当于 ASR + AI 润色一步到位。
-
-| 供应商 | 模型 | 特点 | 价格 |
-| --------------| --------------------------| --------------------------| -------------------------|
-| **豆包** | Seed-ASR-2.0 | 中文准确率最高,推荐首选 | 1.00 元/小时 |
-| **阿里千问** | qwen3-asr-flash-realtime | 流式识别,速度极快 | 1.19 元/小时 |
-| **阿里千问** | qwen3.5-omni-flash | ASR + AI 一步到位 | 按 Token 计费(见下方) |
-
-
-## 2. 使用豆包语音识别
-
-SayIt 支持使用字节跳动「豆包流式语音识别模型 2.0」作为语音识别引擎。豆包 ASR 是目前中文语音识别准确率最高的模型,推荐使用。
-
-1. 注册 / 登录火山引擎
-
-打开[火山引擎语音服务控制台](https://console.volcengine.com/speech/service/10038),用手机号注册或登录即可。已有账号的直接登录,没有账号会引导你先注册。
-[图片]
-
-
-2. 完成实名认证
-
-火山引擎的 API 服务需要先做实名认证,没认证的话后面创建应用会卡住。进入[实名认证页面](https://console.volcengine.com/user/authentication/detail/),按页面提示走完就行。
-[图片]
-
-
-3. 创建应用并获取 APP ID
-
-进入[应用管理页面](https://console.volcengine.com/speech/app1),点击「创建应用」。填写应用名称和简介(随便写就行),关键一步:一定要勾选「豆包流式语音识别模型 2.0 小时版」,不然后面用不了。
-[图片]
-
-
-4. 获取APP ID 和 Access Token
-
-进入 [API 服务中心页面](https://console.volcengine.com/speech/service/10038),点击「豆包流式语音识别模型2.0」(配图是旧版界面)。页面上会显示你的 APP ID,鼠标放到 Access Token 上面,点击小眼睛图标,可以看到 Access Token 信息。
-[图片]
-
-记录下来这两个信息填到 SayIt 软件中。选择 语音引擎 - 云 API 模式 - 选择ASR供应商为豆包 ASR,填写凭证信息后可以保存测试。
-[图片]
-
-
-豆包开通试用后,半年内有 20 小时的[免费额度](https://www.volcengine.com/docs/6561/1359369?lang=zh)。超出免费额度后,按量计费:豆包流式语音识别模型 2.0 — 1 元/小时。[后付费价格详情](https://www.volcengine.com/docs/6561/1359370?lang=zh)
-
-
-## 3. 阿里千问 ASR
-
-阿里百炼平台提供了两个语音识别模型,都可以在 SayIt 中使用。
-
-**qwen3-asr-flash / qwen3-asr-flash-realtime**
-
-纯语音识别模型,中文准确率仅次于豆包。有两个版本:
-- **qwen3-asr-flash**:非流式,录完再发,速度也很快
-- **qwen3-asr-flash-realtime**:流式,边录边发,松手后几乎立刻出结果,体验极佳
-
-两者准确率一样,推荐使用流式版本。适合搭配独立的 AI 润色供应商使用(比如通义千问或 DeepSeek 做文本校对)。
-
-**qwen3.5-omni-flash**
-
-多模态模型,可以直接接收音频输入并输出文本。和普通 ASR + AI 润色的两步流程不同,Omni 模型一步完成,可以在 System Prompt 中直接控制输出格式(比如去口癖、翻译、列表排版等)。
-
-适合不想分别配置 ASR 和 AI 润色的用户,配置更简单。
-
-**配置方式**
-
-在 SayIt 设置中选择千问 ASR 系列,需要填写 API Key。
-
-- 获取 API Key:[阿里百炼平台](https://bailian.console.aliyun.com/cn-beijing?tab=model#/api-key)
-
-## 4. 价格
-
-下面是各个模型按需使用的价格参考。
-
-| 模型 | 价格 | 免费额度 |
-| ---------------------------------------| -----------------| ------------------------|
-| 豆包 Seed-ASR-2.0 | 1.00 元/小时 | 20 小时(半年内) |
-| 千问 qwen3-asr-flash(非流式) | 0.79 元/小时 | 10 小时(90天内) |
-| 千问 qwen3-asr-flash-realtime(流式) | 1.19 元/小时 | 10 小时(90天内) |
-| 千问 qwen3.5-omni-flash | 约 2.3 元/小时* | 100 万 Token(90天内) |
-
-*Omni 按 Token 计费(每秒音频 ≈ 25 token),2.3 元为粗略估算。详见[千问价格文档](https://help.aliyun.com/zh/model-studio/model-pricing#95f0464a10q5c)。
diff --git a/docs/images/readme/SayIt 用户反馈微信群.jpg b/docs/images/readme/SayIt 用户反馈微信群.jpg
new file mode 100644
index 0000000..0006eb9
Binary files /dev/null and b/docs/images/readme/SayIt 用户反馈微信群.jpg differ
diff --git a/docs/images/readme/screenshot-home.png b/docs/images/readme/screenshot-home.png
index 2970d93..6c64d46 100644
Binary files a/docs/images/readme/screenshot-home.png and b/docs/images/readme/screenshot-home.png differ