mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-16 04:18:17 +08:00
fix(plans): parent delegated-step child conversations so they don't leak into the conversation list
This commit is contained in:
parent
eca4229751
commit
2664b26763
@ -30,10 +30,13 @@ import vip.mate.planning.service.PlanningService;
|
|||||||
import vip.mate.agent.context.ChatOrigin;
|
import vip.mate.agent.context.ChatOrigin;
|
||||||
import vip.mate.skill.runtime.SkillCatalogRenderer;
|
import vip.mate.skill.runtime.SkillCatalogRenderer;
|
||||||
import vip.mate.tool.builtin.DelegateAgentTool;
|
import vip.mate.tool.builtin.DelegateAgentTool;
|
||||||
|
import vip.mate.tool.builtin.DelegationContext;
|
||||||
|
import vip.mate.tool.builtin.ToolExecutionContext;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 步骤执行节点
|
* 步骤执行节点
|
||||||
@ -221,7 +224,7 @@ public class StepExecutionNode implements NodeAction {
|
|||||||
if (delegateAgentTool != null && assignedAgentId != null
|
if (delegateAgentTool != null && assignedAgentId != null
|
||||||
&& !assignedAgentId.equals(parseLongOrNull(agentId))) {
|
&& !assignedAgentId.equals(parseLongOrNull(agentId))) {
|
||||||
return executeDelegatedStep(accessor, stepIndex, step, planId, assignedAgentId,
|
return executeDelegatedStep(accessor, stepIndex, step, planId, assignedAgentId,
|
||||||
chatOrigin, events, iterationEventsOn);
|
conversationId, chatOrigin, events, iterationEventsOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iterationEventsOn) {
|
if (iterationEventsOn) {
|
||||||
@ -658,7 +661,7 @@ public class StepExecutionNode implements NodeAction {
|
|||||||
*/
|
*/
|
||||||
private Map<String, Object> executeDelegatedStep(
|
private Map<String, Object> executeDelegatedStep(
|
||||||
PlanStateAccessor accessor, int stepIndex, String step, Long planId,
|
PlanStateAccessor accessor, int stepIndex, String step, Long planId,
|
||||||
Long assignedAgentId, ChatOrigin chatOrigin,
|
Long assignedAgentId, String conversationId, ChatOrigin chatOrigin,
|
||||||
List<GraphEventPublisher.GraphEvent> events, boolean iterationEventsOn) {
|
List<GraphEventPublisher.GraphEvent> events, boolean iterationEventsOn) {
|
||||||
|
|
||||||
if (iterationEventsOn) {
|
if (iterationEventsOn) {
|
||||||
@ -672,12 +675,28 @@ public class StepExecutionNode implements NodeAction {
|
|||||||
|
|
||||||
log.info("[StepExecution] Delegating step {} to agent {}", stepIndex + 1, assignedAgentId);
|
log.info("[StepExecution] Delegating step {} to agent {}", stepIndex + 1, assignedAgentId);
|
||||||
|
|
||||||
|
// Seed the delegation context with the plan's REAL conversation id (from
|
||||||
|
// graph state) so the delegated child conversation is parented to it and
|
||||||
|
// stays hidden from the user's conversation list. The ChatOrigin in the
|
||||||
|
// plan-execute path carries no conversationId, so delegateByAgentId can't
|
||||||
|
// derive the parent on its own — we provide it here.
|
||||||
|
boolean seeded = false;
|
||||||
|
if (conversationId != null && !conversationId.isBlank()
|
||||||
|
&& DelegationContext.parentConversationId() == null
|
||||||
|
&& ToolExecutionContext.conversationId() == null) {
|
||||||
|
DelegationContext.enter(conversationId, Set.of(), conversationId, null, 0);
|
||||||
|
seeded = true;
|
||||||
|
}
|
||||||
String result;
|
String result;
|
||||||
try {
|
try {
|
||||||
result = delegateAgentTool.delegateByAgentId(assignedAgentId, step, chatOrigin);
|
result = delegateAgentTool.delegateByAgentId(assignedAgentId, step, chatOrigin);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[StepExecution] Delegated step {} threw: {}", stepIndex, e.getMessage(), e);
|
log.error("[StepExecution] Delegated step {} threw: {}", stepIndex, e.getMessage(), e);
|
||||||
result = "[错误] 委派执行异常:" + e.getMessage();
|
result = "[错误] 委派执行异常:" + e.getMessage();
|
||||||
|
} finally {
|
||||||
|
if (seeded) {
|
||||||
|
DelegationContext.exit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String finalResult = result != null ? result : "";
|
String finalResult = result != null ? result : "";
|
||||||
|
|||||||
@ -340,8 +340,30 @@ public class DelegateAgentTool {
|
|||||||
if (target == null || !Boolean.TRUE.equals(target.getEnabled())) {
|
if (target == null || !Boolean.TRUE.equals(target.getEnabled())) {
|
||||||
return "[错误] 未找到 id=" + agentId + " 的已启用 Agent。";
|
return "[错误] 未找到 id=" + agentId + " 的已启用 Agent。";
|
||||||
}
|
}
|
||||||
ToolContext ctx = (parentOrigin != null ? parentOrigin : ChatOrigin.EMPTY).toToolContext();
|
ChatOrigin origin = parentOrigin != null ? parentOrigin : ChatOrigin.EMPTY;
|
||||||
return delegateToAgent(target.getName(), task, false, ctx);
|
ToolContext ctx = origin.toToolContext();
|
||||||
|
// A graph-node-initiated delegation (e.g. a plan step) runs outside any
|
||||||
|
// tool-execution / delegation context, so resolveParentConversationId()
|
||||||
|
// would return null and the child conversation would be created with a
|
||||||
|
// null parent — leaking it into the user's top-level conversation list
|
||||||
|
// (the list filters on parentConversationId IS NULL). Seed a depth-0
|
||||||
|
// delegation frame carrying the parent conversation id from the
|
||||||
|
// ChatOrigin so the child is correctly parented and hidden, mirroring how
|
||||||
|
// a tool-initiated delegation gets its conv id from ToolExecutionContext.
|
||||||
|
String parentConvId = origin.conversationId();
|
||||||
|
boolean seedContext = parentConvId != null && !parentConvId.isBlank()
|
||||||
|
&& ToolExecutionContext.conversationId() == null
|
||||||
|
&& DelegationContext.parentConversationId() == null;
|
||||||
|
if (seedContext) {
|
||||||
|
DelegationContext.enter(parentConvId, Set.of(), parentConvId, null, 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return delegateToAgent(target.getName(), task, false, ctx);
|
||||||
|
} finally {
|
||||||
|
if (seedContext) {
|
||||||
|
DelegationContext.exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Parallel delegation ====================
|
// ==================== Parallel delegation ====================
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user