88 lines
4.1 KiB
Bash
Executable File
88 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Handy 全局语音:ALT+1 = option+1,SenseVoice 中文模型 + 卡若AI 回廊洗字(ASR 纠错库)
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
HANDY_PASTE_SCRIPT="${SCRIPT_DIR}/handy_paste_karuo_asr.sh"
|
||
SETTINGS="$HOME/Library/Application Support/com.pais.handy/settings_store.json"
|
||
MODELS_DIR="$HOME/Library/Application Support/com.pais.handy/models"
|
||
PARAKEET_DIR="${MODELS_DIR}/parakeet-tdt-0.6b-v3-int8"
|
||
PARAKEET_OFF="${MODELS_DIR}/_disabled_parakeet-tdt-0.6b-v3-int8"
|
||
|
||
if [[ ! -f "$SETTINGS" ]]; then
|
||
echo "请先启动一次 Handy 以生成配置:open -a Handy" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# 写前解锁(勿 uchg 锁定:Tauri Store 启动时要 merge 写回,锁死会导致进程一直用旧内存配置)
|
||
chflags nouchg "$SETTINGS" 2>/dev/null || true
|
||
|
||
python3 << PY
|
||
import json
|
||
from pathlib import Path
|
||
p = Path("$SETTINGS")
|
||
d = json.loads(p.read_text())
|
||
s = d["settings"]
|
||
# 日志显示你实际按的是 ⌘1;与 Cursor 习惯一致(原需求 ALT+1=⌥1 见 option+shift 备用)
|
||
s["bindings"]["transcribe"]["current_binding"] = "command_left+1"
|
||
s["bindings"]["transcribe"]["name"] = "语音转写"
|
||
s["bindings"]["transcribe"]["description"] = "将语音转为简体中文并粘贴(含卡若纠错)。"
|
||
s["bindings"]["transcribe_with_post_process"]["current_binding"] = "option+shift+1"
|
||
s["bindings"]["transcribe_with_post_process"]["name"] = "转写并润色"
|
||
s["bindings"]["transcribe_with_post_process"]["description"] = "转写后走 AI 润色(默认关闭,避免英文润色)。"
|
||
s["bindings"]["cancel"]["name"] = "取消录音"
|
||
s["bindings"]["cancel"]["description"] = "取消当前录音。"
|
||
s["push_to_talk"] = True
|
||
s["app_language"] = "zh-Hans"
|
||
s["selected_language"] = "zh-Hans"
|
||
s["translate_to_english"] = False
|
||
s["post_process_enabled"] = False
|
||
s["post_process_selected_prompt_id"] = None
|
||
s["ort_accelerator"] = "coreml"
|
||
s["whisper_accelerator"] = "coreml"
|
||
s["mute_while_recording"] = False
|
||
# macOS:external_script 会使 Handy 启动时整表回滚为 auto+ctrl_v(v0.8.3 实测)
|
||
s["paste_method"] = "ctrl_v"
|
||
s["external_script_path"] = None
|
||
# 仅中文模型 SenseVoice;禁止回退英文 Parakeet
|
||
from pathlib import Path
|
||
models = Path.home() / "Library/Application Support/com.pais.handy/models"
|
||
sv = models / "sense-voice-int8"
|
||
if not sv.is_dir():
|
||
raise SystemExit("缺少 sense-voice-int8 中文模型,请先下载后再运行本脚本")
|
||
s["selected_model"] = "sense-voice-int8"
|
||
# 默认后处理提示改为中文(即使未开启润色,避免误开时出现英文 prompt)
|
||
for pr in s.get("post_process_prompts") or []:
|
||
if pr.get("id") == "default_improve_transcriptions":
|
||
pr["name"] = "润色转写(中文)"
|
||
pr["prompt"] = (
|
||
"请仅输出润色后的简体中文转写,不要翻译成英文:\n"
|
||
"1. 修正错别字、标点\n"
|
||
"2. 口语数字可改为阿拉伯数字\n"
|
||
"3. 去掉嗯啊等语气词\n"
|
||
"4. 保持原意与语序,不要改写结构\n\n"
|
||
"转写原文:\n\${output}"
|
||
)
|
||
p.write_text(json.dumps(d, indent=2, ensure_ascii=False) + "\n")
|
||
print("OK: 纯中文 zh-Hans + sense-voice-int8 + 卡若ASR纠错")
|
||
PY
|
||
|
||
chmod +x "${HANDY_PASTE_SCRIPT}"
|
||
|
||
# 禁用英文 Parakeet 模型目录,避免 UI 误选后仍输出英文
|
||
if [[ -d "$PARAKEET_DIR" && ! -d "$PARAKEET_OFF" ]]; then
|
||
mv "$PARAKEET_DIR" "$PARAKEET_OFF"
|
||
echo "已禁用 parakeet 模型目录(仅保留 sense-voice-int8)"
|
||
fi
|
||
|
||
killall -9 handy 2>/dev/null || true
|
||
killall -9 Handy 2>/dev/null || true
|
||
sleep 2
|
||
open -a Handy
|
||
echo "已重启 Handy。请按住 ⌘1 说中文(已对齐你实际按键)。"
|
||
echo "勿在 Handy 设置改模型/语言;若被改回请再跑 handy_force_chinese.sh"
|
||
if [[ ! -f "$HOME/Library/Application Support/com.pais.handy/models/sense-voice-int8/model.int8.onnx" ]]; then
|
||
echo "未检测到 SenseVoice:在 Handy → 模型 中下载 sense-voice-int8,或运行:"
|
||
echo " curl -fL -o /tmp/sv.tgz https://blob.handy.computer/sense-voice-int8.tar.gz && tar -xzf /tmp/sv.tgz -C \"$HOME/Library/Application Support/com.pais.handy/models\""
|
||
fi
|