新增: miniapp补齐4远程命令(approve/authorize_dir/continue_loop/stop_loop 对齐Phase3 §2.2)

This commit is contained in:
2026-06-22 02:53:13 +08:00
parent 5337c7d5e3
commit 8ccdce282c
2 changed files with 124 additions and 1 deletions

View File

@@ -24,6 +24,10 @@
* - stop(): 停止生成(stop Command → device invoke ai_chat_stop)
* - regenerate(): 重发最后一条 user 消息(重新 send_message)
* - switchConversation(id): 切换会话(switch Command → device 切 active)
* - approve(toolCallId, approved): 审批工具调用(approve Command → device invoke ai_approve)
* - authorizeDir(toolCallId, decision): 路径授权(authorize_dir Command → device invoke ai_authorize_dir)
* - continueLoop(convId): 继续循环(continue_loop Command → device invoke ai_continue_loop)
* - stopLoop(convId): 停止循环(stop_loop Command → device invoke ai_stop_loop)
*/
import { ref, reactive, computed } from 'vue'
@@ -428,6 +432,84 @@ function regenerate(): void {
send(lastUserText)
}
/**
* 审批工具调用(approve Command → relay → device invoke ai_approve)
*
* Phase3 §2.2 路由表:{cmd:"approve", args:{tool_call_id, approved}}
* 对应事件:AiApprovalRequired(挂起审批列表 pendingApprovals)。
*/
function approve(toolCallId: string, approved: boolean): void {
if (!toolCallId) return
const cmd: MiniCommand = {
cmd: 'approve',
args: {
tool_call_id: toolCallId,
approved,
},
}
wsClient.send(cmd)
// 乐观从挂起列表移除(对齐 AiApprovalResult 事件处理,避免 UI 卡 pending)
const idx = pendingApprovals.findIndex((p) => p.id === toolCallId)
if (idx >= 0) pendingApprovals.splice(idx, 1)
}
/**
* 路径授权(authorize_dir Command → relay → device invoke ai_authorize_dir)
*
* Phase3 §2.2 路由表:{cmd:"authorize_dir", args:{tool_call_id, decision}}
* 对应事件:AiDirAuthRequired(决策:'once'=本次 / 'always'=永久 / 'deny'=拒绝)。
*/
function authorizeDir(toolCallId: string, decision: 'once' | 'always' | 'deny'): void {
if (!toolCallId) return
const cmd: MiniCommand = {
cmd: 'authorize_dir',
args: {
tool_call_id: toolCallId,
decision,
},
}
wsClient.send(cmd)
}
/**
* 继续循环(continue_loop Command → relay → device invoke ai_continue_loop)
*
* Phase3 §2.2 路由表:{cmd:"continue_loop", args:{conversation_id}}
* 对应场景:AiMaxRoundsReached 达最大轮次暂停后,用户选「继续」再跑一轮。
*/
function continueLoop(conversationId?: string | null): void {
const convId = conversationId ?? activeConversationId.value
if (!convId) {
console.warn('[useAiChat] continue_loop 缺 conversation_id')
return
}
const cmd: MiniCommand = {
cmd: 'continue_loop',
args: { conversation_id: convId },
}
wsClient.send(cmd)
}
/**
* 停止循环(stop_loop Command → relay → device invoke ai_stop_loop)
*
* Phase3 §2.2 路由表:{cmd:"stop_loop", args:{conversation_id}}
* 对应场景:AiMaxRoundsReached 达最大轮次暂停后,用户选「停止」彻底终止。
* 与 stop 区别:stop 是中断流式生成,stop_loop 是停止多轮 agent 循环。
*/
function stopLoop(conversationId?: string | null): void {
const convId = conversationId ?? activeConversationId.value
if (!convId) {
console.warn('[useAiChat] stop_loop 缺 conversation_id')
return
}
const cmd: MiniCommand = {
cmd: 'stop_loop',
args: { conversation_id: convId },
}
wsClient.send(cmd)
}
/** 切换会话(switch Command → device 切 active_conversation_id) */
function switchConversation(convId: string): void {
activeConversationId.value = convId
@@ -484,6 +566,10 @@ export function useAiChat() {
regenerate,
switchConversation,
newConversation,
approve,
authorizeDir,
continueLoop,
stopLoop,
handleEvent,
friendlyError,
}