fix(sub-agent): 修复传统模式 terminate 后子智能体仍继续调用工具的问题
- _call_model 中硬取消时直接抛出 CancelledError,避免返回半成品 tool_calls - 软停止时仍优雅 break,后续由 _run_loop 丢弃半成品并进入 idle - 保持 _mark_task_done 不覆盖 terminated 状态 - 侧边栏当前对话运行态标记修复保留
This commit is contained in:
parent
0aa37b83ee
commit
571ed6c81f
@ -301,6 +301,17 @@ class SubAgentStateMixin:
|
||||
task = self.tasks.get(task_id)
|
||||
if not task:
|
||||
return
|
||||
# 如果 terminate_sub_agent 已把任务标为 terminated,下渗异步任务自然结束时
|
||||
# 不要被“已完成/fulfilled覆盖为failed”值覆盖,否则 task 被碰成 failed 但实际上
|
||||
# 用户手动终止已发生,状态语义错误且“successful=false”。
|
||||
existing_status = task.get("status")
|
||||
if existing_status in TERMINAL_STATUSES.union({"terminated"}):
|
||||
ma_debug(
|
||||
"mark_task_done_skip_already_terminal",
|
||||
task_id=task_id,
|
||||
existing_status=existing_status,
|
||||
)
|
||||
return
|
||||
status = "completed" if success else "failed"
|
||||
ma_debug(
|
||||
"mark_task_done",
|
||||
|
||||
@ -540,8 +540,12 @@ class SubAgentTask:
|
||||
usage = None
|
||||
|
||||
async for chunk in client.chat(self.messages, tools=tools, stream=True):
|
||||
if self._cancelled:
|
||||
if self._soft_stop:
|
||||
# 软停止:优雅中断当前模型调用,后续由 _run_loop 丢弃半成品并进入 idle
|
||||
break
|
||||
if self._cancelled:
|
||||
# 硬取消:立即抛出 CancelledError,确保不会返回半成品的 tool_calls 继续执行
|
||||
raise asyncio.CancelledError()
|
||||
if chunk.get("error"):
|
||||
raise RuntimeError(f"API 调用失败: {chunk.get('error')}")
|
||||
choice = (chunk.get("choices") or [{}])[0]
|
||||
|
||||
@ -63,6 +63,8 @@
|
||||
:icon-style="iconStyle"
|
||||
:format-time="formatTime"
|
||||
:running-tasks="runningWorkspaceTasks"
|
||||
:current-task-in-progress="taskInProgress"
|
||||
:current-conversation-id="currentConversationId"
|
||||
:current-workspace-id="currentHostWorkspaceId"
|
||||
:display-mode="chatDisplayMode"
|
||||
:display-mode-disabled="displayModeSwitchDisabled"
|
||||
@ -765,6 +767,8 @@
|
||||
:icon-style="iconStyle"
|
||||
:format-time="formatTime"
|
||||
:running-tasks="runningWorkspaceTasks"
|
||||
:current-task-in-progress="taskInProgress"
|
||||
:current-conversation-id="currentConversationId"
|
||||
:current-workspace-id="currentHostWorkspaceId"
|
||||
:display-mode="chatDisplayMode"
|
||||
:display-mode-disabled="displayModeSwitchDisabled"
|
||||
|
||||
@ -547,6 +547,9 @@ const props = withDefaults(
|
||||
hostWorkspaceEnabled?: boolean;
|
||||
groupByWorkspace?: boolean;
|
||||
versioningHostMode?: boolean;
|
||||
/** 当前会话是否仍在运行(用于标记当前正在查看的对话也显示运行中转圈) */
|
||||
currentTaskInProgress?: boolean;
|
||||
currentConversationId?: string;
|
||||
}>(),
|
||||
{
|
||||
showCollapseButton: true,
|
||||
@ -559,7 +562,9 @@ const props = withDefaults(
|
||||
workspaceKind: 'workspace',
|
||||
hostWorkspaceEnabled: false,
|
||||
groupByWorkspace: false,
|
||||
versioningHostMode: false
|
||||
versioningHostMode: false,
|
||||
currentTaskInProgress: false,
|
||||
currentConversationId: ''
|
||||
}
|
||||
);
|
||||
|
||||
@ -890,8 +895,15 @@ const completedConversationIds = computed(
|
||||
.filter(Boolean)
|
||||
)
|
||||
);
|
||||
const isConversationActive = (conversationId: string) =>
|
||||
activeConversationIds.value.has(String(conversationId || ''));
|
||||
const isConversationActive = (conversationId: string) => {
|
||||
if (activeConversationIds.value.has(String(conversationId || ''))) return true;
|
||||
// 后端 runningTasks 库只跟踪跨工作的任务(当前会话排除了),
|
||||
// 所以当前会话的运行态要单独用 currentTaskInProgress 标记。
|
||||
if (props.currentTaskInProgress && String(conversationId || '') === String(props.currentConversationId || '')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const isConversationCompleted = (conversationId: string) =>
|
||||
completedConversationIds.value.has(String(conversationId || ''));
|
||||
const isWorkspaceRunning = (workspaceId: string) =>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user