背景
OpenLess 当前已经支持热键录音、ASR、LLM 润色、文本插入、Selection Ask QA 面板。希望在此基础上新增一个“语音调用代码 Agent”的独立能力:
用户触发专用快捷键后,OpenLess 开始录音。
再次触发快捷键后结束录音,ASR 得到文本。
系统可按配置先用“语音润色大语言模型”整理语音转写内容。
后端把最终文本发送给 Claude Code 或开源 OpenCode Agent。
Agent 输出结果流式返回前端面板展示。
当前 OpenLess README 中说明产品主要负责文本整理,不负责回答问题、执行任务或分析项目。本功能会扩展为独立的 coding-agent 模式,应保持和普通听写、翻译、Selection Ask QA 分离,避免改变现有默认听写行为。
目标
新增一个独立功能:Voice Coding Agent。
默认行为:
默认关闭,需要用户在设置页开启。
使用独立快捷键,默认建议:
Windows/Linux: Ctrl+Shift+Enter
macOS: Cmd+Shift+Enter
第一次按下开始录音。
第二次按下停止录音并进入 ASR。
ASR 结果可先经过语音润色模型整理。
整理后的指令发送给 configured coding agent。
前端显示:
原始 ASR 文本
润色后的指令
Agent 当前状态
流式输出
错误、超时、取消状态
默认不自动插入文本到当前光标位置。
默认不允许 Agent 修改本地文件;权限模式默认为只读/计划模式。
用户可在高级设置中切换为更强权限模式。
非目标
不改变普通听写热键行为。
不改变 Selection Ask QA 的现有交互。
不把 Claude Code 输出默认插入到其他应用。
不默认启用 bypassPermissions。
不把 API key、access token、命令输出中的敏感字段写入前端事件、日志或历史记录。
调研结论
OpenLess 当前主处理路径已经具备热键录音、ASR、LLM 润色、历史保存、QA 面板流式回答能力,可复用大部分基础设施。
现有 Selection Ask QA 功能最接近目标:qa_hotkey 负责打开面板,主听写热键在面板可见时开始/结束 QA 录音,后端用 ASR 得到文本,再调用当前 LLM provider,前端通过 qa:state 接收流式回答。
当前 UserPreferences 已有 active_llm_provider、llm_thinking_enabled、qa_hotkey 等字段;凭据通过 OS vault 保存,LLM provider 支持 Ark、OpenAI-compatible、Gemini、Codex OAuth、custom 等。
官方 Claude Code 可通过 CLI 和 SDK 集成,关键参数包括 claude -p/--print、--output-format text|json|stream-json、--model、--fallback-model、--permission-mode、--allowedTools、--disallowedTools、--mcp-config。
官方 Claude Code 未定位为可 fork 的开源实现;开源优先方案应增加 opencode 适配器。OpenCode 是开源终端 coding agent,适合做二次开发优先落点,同时保留官方 claude-code-cli 适配器满足 Claude Code 用户。
相关 Issue 不构成重复:[insertion] 新增送出前文字處理 Hook #575 是“送出前文字处理 Hook”,[area] 无法现在大模型,也不知道哪个处于启用状态 #578 是模型选择状态问题;本需求是独立的语音触发代码 Agent 功能,但需要兼容 [insertion] 新增送出前文字處理 Hook #575 的文本处理扩展思路。
参考资料:
Claude Code / OpenCode 集成策略
Provider 抽象
新增后端 trait:
#[ async_trait]
pub trait CodingAgentProvider : Send + Sync {
async fn run (
& self ,
request : CodingAgentRequest ,
sink : CodingAgentEventSink ,
cancel : CancellationToken ,
) -> Result < CodingAgentResult , CodingAgentError > ;
}
核心类型:
pub struct CodingAgentRequest {
pub session_id : String ,
pub prompt : String ,
pub raw_transcript : String ,
pub polished_prompt : Option < String > ,
pub cwd : PathBuf ,
pub model : Option < String > ,
pub fallback_model : Option < String > ,
pub permission_mode : CodingAgentPermissionMode ,
pub allowed_tools : Vec < String > ,
pub disallowed_tools : Vec < String > ,
pub timeout_secs : u64 ,
pub extra_system_prompt : Option < String > ,
}
pub enum CodingAgentEvent {
Started { session_id : String } ,
TranscriptReady { text : String } ,
PromptReady { text : String } ,
Delta { text : String } ,
ToolEvent { name : String , status : String } ,
Completed { text : String } ,
Cancelled ,
Error { message : String } ,
}
Provider IDs:
claude-code-cli
opencode-cli
预留:claude-code-sdk
Claude Code CLI 适配器
新增 ClaudeCodeCliProvider:
默认可执行文件:claude
支持用户配置可执行文件路径。
使用非交互 print 模式:
claude -p
--output-format stream-json
--model <model>
--fallback-model <fallback_model>
--permission-mode <mode>
--add-dir <cwd> 如用户配置了额外目录
--mcp-config <path> 如用户配置 MCP
--append-system-prompt <prompt> 如配置了额外系统提示词
stdin 写入最终 prompt。
stdout 按行解析 stream-json。
stderr 独立收集,只在错误状态中返回摘要。
timeout 到期后 kill 子进程并发送 agent:error。
用户取消时 kill 子进程并发送 agent:cancelled。
子进程退出码非 0 时返回 CodingAgentError::ProcessExit。
默认权限:
permission_mode = CodingAgentPermissionMode :: Plan
timeout_secs = 300
allowed_tools = [ ]
disallowed_tools = [ ]
高级权限选项:
plan
default
acceptEdits
bypassPermissions
UI 中 bypassPermissions 必须放在高级区,附带明确风险文案,不能作为默认值。
OpenCode 适配器
新增 OpenCodeCliProvider:
provider id: opencode-cli
作为开源优先落点。
默认可执行文件:opencode
先实现同一 CodingAgentProvider trait。
命令参数由适配器内部封装,保持前端配置和 Claude Code 适配器一致:
cwd
model
permission_mode
timeout_secs
extra_system_prompt
若当前 OpenCode CLI 版本缺少稳定的非交互 stream 输出协议,先以实验 provider 暴露,并在 UI 中显示“experimental”。
后端实现
Preferences
在 UserPreferences 增加字段:
pub coding_agent_enabled: bool,
pub coding_agent_hotkey: Option <ShortcutBinding >,
pub coding_agent_provider: CodingAgentProviderId ,
pub coding_agent_workdir: Option <String >,
pub coding_agent_permission_mode: CodingAgentPermissionMode ,
pub coding_agent_model: Option <String >,
pub coding_agent_fallback_model: Option <String >,
pub coding_agent_timeout_secs: u64,
pub coding_agent_show_panel_on_start: bool,
pub coding_agent_save_history: bool,
pub coding_agent_use_voice_polish: bool,
pub voice_polish_model_mode: VoicePolishModelMode ,
pub voice_polish_provider_id: Option <String >,
pub voice_polish_thinking_enabled: bool,
默认值:
coding_agent_enabled = false
coding_agent_hotkey = CtrlOrCmd + Shift + Enter
coding_agent_provider = "claude-code-cli"
coding_agent_workdir = None
coding_agent_permission_mode = Plan
coding_agent_timeout_secs = 300
coding_agent_show_panel_on_start = true
coding_agent_save_history = true
coding_agent_use_voice_polish = true
voice_polish_model_mode = SystemDefault
voice_polish_provider_id = None
voice_polish_thinking_enabled = false
新增 enum:
pub enum VoicePolishModelMode {
SystemDefault ,
CustomProvider ,
}
pub enum CodingAgentPermissionMode {
Plan ,
Default ,
AcceptEdits ,
BypassPermissions ,
}
同步更新:
Rust defaults
serde rename
TypeScript UserPreferences
IPC mock settings
设置页初始值
所有 i18n locale key
语音润色模型配置层
新增“语音润色大语言模型”配置,不直接复用全局 active LLM 的写入命令,避免改变普通听写配置。
配置模式:
SystemDefault
读取现有 active LLM provider。
使用现有润色 prompt 和 style pack。
不新增凭据。
CustomProvider
使用独立 provider id:voice-polish-custom。
凭据仍写入 OS vault 的 LLM providers map。
保存字段:
displayName
apiKey
baseURL
model
temperature
extraHeaders
前端只显示 hasApiKey,不回传明文 key。
提供校验按钮,调用后端真实发起轻量模型请求。
新增后端命令:
get_voice_polish_model_config ( ) -> VoicePolishModelConfigWire
set_voice_polish_model_mode ( mode: VoicePolishModelMode )
set_voice_polish_provider_config ( config: VoicePolishProviderConfigWire )
validate_voice_polish_provider_config ( config: VoicePolishProviderConfigWire ) -> ProviderValidationResult
list_voice_polish_provider_models ( config: VoicePolishProviderConfigWire ) -> Vec <ModelInfo >
新增 provider factory:
fn build_voice_polish_provider (
prefs : & UserPreferences ,
vault : & CredentialsVault ,
) -> Result < Box < dyn LLMProvider > , ProviderError >
规则:
SystemDefault 走现有 ActiveLLMProvider。
CustomProvider 通过 provider id 精确读取 vault entry。
不修改 active_llm_provider。
不使用 ...storedSettings 展开旧字段。
保存 preferences 时仅写白名单字段。
Hotkey
新增 hotkey watcher 字段:
coding_agent_hotkey: Arc <Mutex <Option <ShortcutBinding >>>
新增命令:
get_coding_agent_hotkey_label( )
set_coding_agent_hotkey ( binding: Option <ShortcutBinding >)
更新冲突检测:
dictation hotkey
translation hotkey
selection ask hotkey
switch style hotkey
open app hotkey
coding agent hotkey
冲突时返回当前已有的快捷键名称。
Coordinator 状态机
新增状态:
pub enum CodingAgentPhase {
Idle ,
Recording ,
Transcribing ,
Polishing ,
AgentRunning ,
}
新增 session state:
pub struct CodingAgentSessionState {
pub session_id : String ,
pub phase : CodingAgentPhase ,
pub started_at : Instant ,
pub raw_transcript : Option < String > ,
pub polished_prompt : Option < String > ,
pub cancel_token : CancellationToken ,
}
快捷键处理:
Idle 且 feature enabled:
校验 workdir 已配置且存在。
校验 ASR provider 可用。
打开 Agent panel。
启动 recorder + ASR session。
phase -> Recording。
Recording:
stop recorder。
send last frame。
phase -> Transcribing。
等待 ASR final。
ASR final 为空:
coding_agent_use_voice_polish = true:
phase -> Polishing
调用 voice polish provider。
失败时按配置 fallback:
默认 fallback 到 raw transcript,并在 UI 显示 warning。
调用 coding agent:
phase -> AgentRunning
将 stream event 转成 Tauri event。
完成:
保存历史。
phase -> Idle
前端显示完成。
事件名建议:
coding-agent:state
coding-agent:level
coding-agent:dismiss
coding-agent:history
前端事件 payload:
type CodingAgentStateEvent =
| { kind : "phase" ; phase : CodingAgentPhase ; sessionId : string }
| { kind : "transcript" ; text : string ; sessionId : string }
| { kind : "prompt" ; text : string ; sessionId : string }
| { kind : "delta" ; text : string ; sessionId : string }
| { kind : "answer" ; text : string ; sessionId : string }
| { kind : "error" ; message : string ; sessionId : string }
| { kind : "cancelled" ; sessionId : string } ;
所有事件必须带 sessionId,前端丢弃旧 session 的延迟事件。
前端
新增页面/组件:
VoiceCodingAgentPanel.tsx
VoiceCodingAgentSettings.tsx
设置页新增分组:“语音调用代码 Agent”
provider 设置页新增分组:“语音润色大语言模型”
面板展示:
phase badge
raw ASR transcript collapsible block
polished prompt collapsible block
streaming markdown answer
stop button
copy answer button
copy prompt button
open settings button
error banner
设置项:
启用 Voice Coding Agent
快捷键录制器
Agent provider:Claude Code CLI / OpenCode CLI
Agent executable path
工作目录选择
model
fallback model
permission mode
timeout
是否先语音润色
语音润色模型模式:系统默认 / 自定义
自定义 base URL
自定义 model
自定义 API key
校验模型按钮
安全与错误处理
默认权限为 Plan。
未配置 workdir 时不启动 Agent,前端提示用户先选择项目目录。
未找到 claude 或 opencode 时显示安装提示。
API key 永不通过普通 state event 回传。
日志中屏蔽 bearer token、API key、account id。
子进程必须支持取消和 timeout。
快速连续按快捷键时只允许当前 session 生效。
ASR、润色、Agent 任一阶段失败都要恢复 phase 到 Idle。
旧 session 的 late event 必须被丢弃。
历史记录只保存用户允许保存的 raw transcript、polished prompt、answer、provider id、model、时间戳,不保存 secret。
测试计划
Rust:
preferences 默认值和 serde 兼容测试。
hotkey collision 测试,覆盖所有已有快捷键。
voice polish custom provider 精确读取 provider id,不修改 active LLM。
Claude Code CLI args 构造测试。
stream-json parser 测试。
timeout kill 子进程测试。
cancel kill 子进程测试。
session id guard 测试。
空 ASR 文本测试。
Agent process exit 非 0 测试。
Frontend:
UserPreferences 类型同步测试。
settings 初始渲染测试。
system default/custom voice polish 切换测试。
API key redacted 显示测试。
panel stream delta 合并测试。
stale session event 丢弃测试。
error banner 和 phase reset 测试。
手动验收:
普通听写热键仍可录音、润色、插入。
Selection Ask QA 仍可打开、录音、返回回答。
Voice Coding Agent 关闭时快捷键无动作。
Voice Coding Agent 启用但未配置 workdir 时给出设置提示。
使用系统默认语音润色模型能完成一次完整流程。
使用自定义强模型能完成一次完整流程。
Claude Code CLI 不存在时给出可理解错误。
Claude Code 输出能流式显示。
取消运行能终止子进程。
超时能终止子进程。
权限模式默认为计划/只读,不默认修改文件。
切换到 OpenCode provider 后能走同一 UI 与事件协议。
验收标准
用户可以在前端配置“语音润色大语言模型”,支持系统默认和自定义强模型。
用户可以配置 Voice Coding Agent 的快捷键、provider、模型、工作目录、权限模式。
触发快捷键后,ASR 内容能发送给 Claude Code CLI。
Claude Code 处理结果能返回前端并流式展示。
OpenCode provider 作为开源优先方案接入同一 provider trait。
功能不破坏普通听写、翻译、Selection Ask QA。
所有 secret 仍由 OS vault 保存,不进入前端事件和历史。
默认权限不会修改用户项目文件。
背景
OpenLess 当前已经支持热键录音、ASR、LLM 润色、文本插入、Selection Ask QA 面板。希望在此基础上新增一个“语音调用代码 Agent”的独立能力:
当前 OpenLess README 中说明产品主要负责文本整理,不负责回答问题、执行任务或分析项目。本功能会扩展为独立的 coding-agent 模式,应保持和普通听写、翻译、Selection Ask QA 分离,避免改变现有默认听写行为。
目标
新增一个独立功能:Voice Coding Agent。
默认行为:
Ctrl+Shift+EnterCmd+Shift+Enter非目标
bypassPermissions。调研结论
qa_hotkey负责打开面板,主听写热键在面板可见时开始/结束 QA 录音,后端用 ASR 得到文本,再调用当前 LLM provider,前端通过qa:state接收流式回答。UserPreferences已有active_llm_provider、llm_thinking_enabled、qa_hotkey等字段;凭据通过 OS vault 保存,LLM provider 支持 Ark、OpenAI-compatible、Gemini、Codex OAuth、custom 等。claude -p/--print、--output-format text|json|stream-json、--model、--fallback-model、--permission-mode、--allowedTools、--disallowedTools、--mcp-config。opencode适配器。OpenCode 是开源终端 coding agent,适合做二次开发优先落点,同时保留官方claude-code-cli适配器满足 Claude Code 用户。参考资料:
Claude Code / OpenCode 集成策略
Provider 抽象
新增后端 trait:
核心类型:
Provider IDs:
claude-code-cliopencode-cliclaude-code-sdkClaude Code CLI 适配器
新增
ClaudeCodeCliProvider:claudeclaude -p--output-format stream-json--model <model>--fallback-model <fallback_model>--permission-mode <mode>--add-dir <cwd>如用户配置了额外目录--mcp-config <path>如用户配置 MCP--append-system-prompt <prompt>如配置了额外系统提示词agent:error。agent:cancelled。CodingAgentError::ProcessExit。默认权限:
高级权限选项:
plandefaultacceptEditsbypassPermissionsUI 中
bypassPermissions必须放在高级区,附带明确风险文案,不能作为默认值。OpenCode 适配器
新增
OpenCodeCliProvider:opencode-cliopencodeCodingAgentProvidertrait。cwdmodelpermission_modetimeout_secsextra_system_prompt后端实现
Preferences
在
UserPreferences增加字段:默认值:
新增 enum:
同步更新:
UserPreferences语音润色模型配置层
新增“语音润色大语言模型”配置,不直接复用全局 active LLM 的写入命令,避免改变普通听写配置。
配置模式:
SystemDefaultCustomProvidervoice-polish-custom。displayNameapiKeybaseURLmodeltemperatureextraHeadershasApiKey,不回传明文 key。新增后端命令:
新增 provider factory:
规则:
SystemDefault走现有ActiveLLMProvider。CustomProvider通过 provider id 精确读取 vault entry。active_llm_provider。...storedSettings展开旧字段。Hotkey
新增 hotkey watcher 字段:
新增命令:
更新冲突检测:
冲突时返回当前已有的快捷键名称。
Coordinator 状态机
新增状态:
新增 session state:
快捷键处理:
Idle且 feature enabled:Recording。Recording:Transcribing。Idlecoding_agent_use_voice_polish = true:PolishingAgentRunningIdle事件名建议:
coding-agent:statecoding-agent:levelcoding-agent:dismisscoding-agent:history前端事件 payload:
所有事件必须带
sessionId,前端丢弃旧 session 的延迟事件。前端
新增页面/组件:
VoiceCodingAgentPanel.tsxVoiceCodingAgentSettings.tsx面板展示:
设置项:
安全与错误处理
Plan。claude或opencode时显示安装提示。Idle。测试计划
Rust:
Frontend:
UserPreferences类型同步测试。手动验收:
验收标准