新增: miniapp补齐4远程命令(approve/authorize_dir/continue_loop/stop_loop 对齐Phase3 §2.2)
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user