fix(chat): 运行期间权限切换使用pending机制,避免来回切换插入多余消息
- update_permission_mode / update_execution_mode 运行期间改用 queue 机制 - pending 值可被覆盖,最终若与当前相同则不通知 - 返回值直接返回 target_mode,前端立即更新 UI
This commit is contained in:
parent
ff7108738e
commit
ca4bf17639
@ -689,6 +689,44 @@ def update_permission_mode(terminal: WebTerminal, workspace: UserWorkspace, user
|
||||
"success": False,
|
||||
"error": "无效权限模式,仅支持 readonly / approval / auto_approval / unrestricted"
|
||||
}), 400
|
||||
|
||||
# 判断当前是否在对话运行期间
|
||||
is_running = False
|
||||
try:
|
||||
from .tasks import task_manager
|
||||
current_conv = getattr(getattr(terminal, "context_manager", None), "current_conversation_id", None)
|
||||
running_tasks = [
|
||||
r for r in task_manager.list_tasks(username) if r.status in {"pending", "running", "cancel_requested"}
|
||||
]
|
||||
if current_conv:
|
||||
running_tasks.sort(key=lambda r: 0 if r.conversation_id == current_conv else 1)
|
||||
is_running = bool(running_tasks)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if is_running:
|
||||
# 运行期间:使用 pending 机制延迟到工具循环中统一处理,
|
||||
# 避免「A→B→A」来回切换时中间值被覆盖后仍插入多余消息。
|
||||
try:
|
||||
terminal.queue_permission_mode_change(target_mode)
|
||||
except Exception as exc:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": str(exc),
|
||||
"message": "更新权限模式失败"
|
||||
}), 500
|
||||
status = terminal.get_status()
|
||||
socketio.emit('status_update', status, room=f"user_{username}")
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"mode": target_mode,
|
||||
"pending_mode": target_mode,
|
||||
"options": PERMISSION_MODE_OPTIONS,
|
||||
"conversation_id": getattr(terminal.context_manager, "current_conversation_id", None),
|
||||
"message": "权限模式将在当前工具执行完成后生效",
|
||||
})
|
||||
|
||||
# 空闲期间:直接生效
|
||||
previous_mode = terminal.get_permission_mode() if hasattr(terminal, "get_permission_mode") else None
|
||||
try:
|
||||
applied_mode = terminal.set_permission_mode(target_mode)
|
||||
@ -756,6 +794,42 @@ def update_execution_mode(terminal: WebTerminal, workspace: UserWorkspace, usern
|
||||
target_mode = str(data.get("mode") or "").strip().lower()
|
||||
if target_mode not in EXECUTION_MODE_OPTIONS:
|
||||
return jsonify({"success": False, "error": "无效执行环境,仅支持 sandbox / direct"}), 400
|
||||
|
||||
# 判断当前是否在对话运行期间
|
||||
is_running = False
|
||||
try:
|
||||
from .tasks import task_manager
|
||||
current_conv = getattr(getattr(terminal, "context_manager", None), "current_conversation_id", None)
|
||||
running_tasks = [
|
||||
r for r in task_manager.list_tasks(username) if r.status in {"pending", "running", "cancel_requested"}
|
||||
]
|
||||
if current_conv:
|
||||
running_tasks.sort(key=lambda r: 0 if r.conversation_id == current_conv else 1)
|
||||
is_running = bool(running_tasks)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if is_running:
|
||||
# 运行期间:使用 pending 机制延迟到工具循环中统一处理,
|
||||
# 避免「A→B→A」来回切换时中间值被覆盖后仍插入多余消息。
|
||||
try:
|
||||
terminal.queue_execution_mode_change(target_mode)
|
||||
except Exception as exc:
|
||||
return jsonify({"success": False, "error": str(exc), "message": "更新执行环境失败"}), 500
|
||||
status = terminal.get_status()
|
||||
socketio.emit('status_update', status, room=f"user_{username}")
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"state": {
|
||||
**(terminal.get_execution_mode_state() if hasattr(terminal, "get_execution_mode_state") else {"mode": target_mode}),
|
||||
"mode": target_mode,
|
||||
},
|
||||
"pending_mode": target_mode,
|
||||
"options": EXECUTION_MODE_OPTIONS,
|
||||
"message": "执行环境将在当前工具执行完成后生效",
|
||||
})
|
||||
|
||||
# 空闲期间:直接生效
|
||||
previous_mode = terminal.get_execution_mode() if hasattr(terminal, "get_execution_mode") else None
|
||||
try:
|
||||
state = terminal.set_execution_mode(target_mode)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user