Compare commits
No commits in common. "aa50a72d86d7c4d486653b0bab23747bead17c3d" and "944cef05877a7c141622c09bca4944ed34fe1db6" have entirely different histories.
aa50a72d86
...
944cef0587
@ -433,27 +433,15 @@ def update_work_mode(terminal: WebTerminal, workspace: UserWorkspace, username:
|
|||||||
"error": tr("chat_permission.invalid_work_mode")
|
"error": tr("chat_permission.invalid_work_mode")
|
||||||
}), 400
|
}), 400
|
||||||
|
|
||||||
# 请求显式携带的 conversation_id(query > body,与 with_terminal 路由同优先级)。
|
|
||||||
# 判定必须基于请求而非 terminal.context_manager.current_conversation_id:
|
|
||||||
# /new 页面不带 cid 时路由到工作区级 terminal,其焦点残留为「最近对话」
|
|
||||||
# (_ensure_conversation 自动加载最近对话恢复焦点),按残留焦点判定会把
|
|
||||||
# 最近对话误判为「本对话」,其运行中会误拦 /new 页面切换(新对话默认模式
|
|
||||||
# 与任何运行中对话无关)。
|
|
||||||
req_conv_id = (request.args.get("conversation_id") or "").strip() or None
|
|
||||||
if not req_conv_id and isinstance(data, dict):
|
|
||||||
req_conv_id = (data.get("conversation_id") or "").strip() or None
|
|
||||||
|
|
||||||
# 运行中拒绝切换(无 pending 队列——运行模式不存在「工具结果后插入」的路径)。
|
# 运行中拒绝切换(无 pending 队列——运行模式不存在「工具结果后插入」的路径)。
|
||||||
# 运行模式是对话级状态,只检测本对话是否有运行中任务;其他对话运行不影响;
|
# 运行模式是对话级状态,只检测本对话是否有运行中任务;其他对话运行不影响。
|
||||||
# /new 页面(无 cid)不检查,直接放行。
|
try:
|
||||||
if req_conv_id:
|
from server.tasks import task_manager
|
||||||
try:
|
current_conv = getattr(getattr(terminal, "context_manager", None), "current_conversation_id", None)
|
||||||
from server.tasks import task_manager
|
if current_conv:
|
||||||
req_conv_norm = req_conv_id.removeprefix("conv_")
|
|
||||||
conv_running = [
|
conv_running = [
|
||||||
r for r in task_manager.list_tasks(username)
|
r for r in task_manager.list_tasks(username)
|
||||||
if r.status in {"pending", "running", "cancel_requested"}
|
if r.status in {"pending", "running", "cancel_requested"} and r.conversation_id == current_conv
|
||||||
and (r.conversation_id or "").removeprefix("conv_") == req_conv_norm
|
|
||||||
]
|
]
|
||||||
if conv_running:
|
if conv_running:
|
||||||
return jsonify({
|
return jsonify({
|
||||||
@ -461,19 +449,12 @@ def update_work_mode(terminal: WebTerminal, workspace: UserWorkspace, username:
|
|||||||
"error": tr("chat_permission.work_mode_running_refused"),
|
"error": tr("chat_permission.work_mode_running_refused"),
|
||||||
"message": tr("chat_permission.work_mode_running_refused"),
|
"message": tr("chat_permission.work_mode_running_refused"),
|
||||||
}), 409
|
}), 409
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
previous_permission = terminal.get_permission_mode() if hasattr(terminal, "get_permission_mode") else None
|
previous_permission = terminal.get_permission_mode() if hasattr(terminal, "get_permission_mode") else None
|
||||||
try:
|
try:
|
||||||
if req_conv_id:
|
result = terminal.switch_work_mode(target_mode)
|
||||||
# 对话内切换:持久化到该对话 metadata(对话级唯一真相)
|
|
||||||
result = terminal.switch_work_mode(target_mode, conversation_id=req_conv_id)
|
|
||||||
else:
|
|
||||||
# /new 页面:仅设工作区级内存态(新对话继承冻结读 terminal 当前值),
|
|
||||||
# persist=False 避免误写工作区 terminal 残留焦点对话的 metadata
|
|
||||||
# (与 _sync_workspace_terminal_mode 同策略)。
|
|
||||||
result = terminal.switch_work_mode(target_mode, persist=False)
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": False,
|
"success": False,
|
||||||
|
|||||||
@ -161,52 +161,41 @@ export const resourceMethods = {
|
|||||||
this.modelSet(status.model_key);
|
this.modelSet(status.model_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 运行模式四件套(work_mode/permission_mode/execution_mode/network_permission)
|
if (status && typeof status.permission_mode === 'string') {
|
||||||
// 来源隔离:status_update 是用户级房间广播,工作区级 / 其他对话 / 其他标签页
|
this.currentPermissionMode = status.permission_mode;
|
||||||
// 的 terminal 触发时都会携带它自己的模式值;不做隔离时别的 terminal 的快照会
|
}
|
||||||
// 覆盖当前对话的显示(plan 锁对话的 UI 会被误解锁,点击切换又被后端 500 拒绝)。
|
// 运行模式(work_mode):terminal 快照权威。对话加载后 load.ts 会再调
|
||||||
// 仅当快照对应当前查看的对话(含双空:/new 页面 ↔ 工作区级 terminal)才应用;
|
// fetchWorkMode 以对话 metadata 为准修正一次,两者一致,不会跳变。
|
||||||
// 对话权威值由 load.ts 进入对话时的对话级 fetch(fetchWorkMode 等)保证。
|
if (status && typeof status.work_mode === 'string') {
|
||||||
const statusConvIdRaw = status?.conversation?.current_id;
|
this.currentWorkMode = status.work_mode;
|
||||||
const statusConvId = typeof statusConvIdRaw === 'string' ? statusConvIdRaw : '';
|
}
|
||||||
const modeSourceMatches = hasConversation ? statusConvId === convId : !statusConvId;
|
const pendingModes = status?.pending_runtime_modes || {};
|
||||||
if (modeSourceMatches) {
|
if (typeof pendingModes.permission_mode === 'string') {
|
||||||
if (status && typeof status.permission_mode === 'string') {
|
this.pendingPermissionMode = pendingModes.permission_mode;
|
||||||
this.currentPermissionMode = status.permission_mode;
|
} else {
|
||||||
}
|
this.pendingPermissionMode = '';
|
||||||
if (status && typeof status.work_mode === 'string') {
|
}
|
||||||
this.currentWorkMode = status.work_mode;
|
if (status?.execution_mode && typeof status.execution_mode === 'object') {
|
||||||
}
|
if (typeof status.execution_mode.mode === 'string') {
|
||||||
const pendingModes = status?.pending_runtime_modes || {};
|
this.currentExecutionMode = status.execution_mode.mode;
|
||||||
if (typeof pendingModes.permission_mode === 'string') {
|
|
||||||
this.pendingPermissionMode = pendingModes.permission_mode;
|
|
||||||
} else {
|
|
||||||
this.pendingPermissionMode = '';
|
|
||||||
}
|
|
||||||
if (status?.execution_mode && typeof status.execution_mode === 'object') {
|
|
||||||
if (typeof status.execution_mode.mode === 'string') {
|
|
||||||
this.currentExecutionMode = status.execution_mode.mode;
|
|
||||||
}
|
|
||||||
this.executionModeEnabled =
|
|
||||||
typeof status.execution_mode_enabled === 'boolean' ? status.execution_mode_enabled : true;
|
|
||||||
}
|
|
||||||
if (typeof status.network_permission === 'string') {
|
|
||||||
this.currentNetworkPermission = status.network_permission;
|
|
||||||
}
|
|
||||||
this.networkPermissionEnabled =
|
|
||||||
typeof status.network_permission_enabled === 'boolean'
|
|
||||||
? status.network_permission_enabled
|
|
||||||
: false;
|
|
||||||
if (typeof pendingModes.network_permission === 'string') {
|
|
||||||
this.pendingNetworkPermission = pendingModes.network_permission;
|
|
||||||
} else {
|
|
||||||
this.pendingNetworkPermission = '';
|
|
||||||
}
|
|
||||||
if (typeof pendingModes.execution_mode === 'string') {
|
|
||||||
this.pendingExecutionMode = pendingModes.execution_mode;
|
|
||||||
} else {
|
|
||||||
this.pendingExecutionMode = '';
|
|
||||||
}
|
}
|
||||||
|
this.executionModeEnabled =
|
||||||
|
typeof status.execution_mode_enabled === 'boolean' ? status.execution_mode_enabled : true;
|
||||||
|
}
|
||||||
|
if (typeof status.network_permission === 'string') {
|
||||||
|
this.currentNetworkPermission = status.network_permission;
|
||||||
|
}
|
||||||
|
this.networkPermissionEnabled =
|
||||||
|
typeof status.network_permission_enabled === 'boolean' ? status.network_permission_enabled : false;
|
||||||
|
if (typeof pendingModes.network_permission === 'string') {
|
||||||
|
this.pendingNetworkPermission = pendingModes.network_permission;
|
||||||
|
} else {
|
||||||
|
this.pendingNetworkPermission = '';
|
||||||
|
}
|
||||||
|
if (typeof pendingModes.execution_mode === 'string') {
|
||||||
|
this.pendingExecutionMode = pendingModes.execution_mode;
|
||||||
|
} else {
|
||||||
|
this.pendingExecutionMode = '';
|
||||||
}
|
}
|
||||||
// has_images/has_videos 遵循与上面模型/运行模式相同的权威规则:
|
// has_images/has_videos 遵循与上面模型/运行模式相同的权威规则:
|
||||||
// 有打开对话时才从 status 同步;空对话/显式新建路由(/new)上 status 里的值
|
// 有打开对话时才从 status 同步;空对话/显式新建路由(/new)上 status 里的值
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user