mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-18 02:14:43 +00:00
fix(spawn): resolve parent agent from context in managed mode (#4)
In managed mode, multiple agents share a single tool registry. The spawn and subagent tools were constructed with a hardcoded parentID of "default", which does not exist as an agent in managed mode deployments. This caused subagent announces to fail with "agent default not found" when any non-default agent (e.g. a secondary agent) tried to spawn a subagent. Fix: add ctxAgentKey to tool context keys (same pattern as channel/chatID), inject the calling agent's key from the loop, and read it in spawn/subagent tools with a fallback to the construction-time default for backward compatibility with standalone mode.
This commit is contained in:
1 parent
406f83160e
commit
0105bab2d5
4 files changed
+30
-2
No files matched your search
@@ -434,6 +434,9 @@ func (l *Loop) runLoop(ctx context.Context, req RunRequest) (*RunResult, error)
|
||||
}
|
||||
}
|
||||
|
||||
// Inject agent key into context for tool-level resolution (managed mode: multiple agents share tool registry)
|
||||
ctx = tools.WithToolAgentKey(ctx, l.id)
|
||||
|
||||
// Security: truncate oversized user messages gracefully (feed truncation notice into LLM)
|
||||
maxChars := l.maxMessageChars
|
||||
if maxChars <= 0 {
|
||||
|
||||
@@ -20,6 +20,7 @@ const (
|
||||
ctxSandboxKey toolContextKey = "tool_sandbox_key"
|
||||
ctxAsyncCB toolContextKey = "tool_async_cb"
|
||||
ctxWorkspace toolContextKey = "tool_workspace"
|
||||
ctxAgentKey toolContextKey = "tool_agent_key"
|
||||
)
|
||||
|
||||
func WithToolChannel(ctx context.Context, channel string) context.Context {
|
||||
@@ -76,6 +77,18 @@ func ToolWorkspaceFromCtx(ctx context.Context) string {
|
||||
return v
|
||||
}
|
||||
|
||||
// WithToolAgentKey injects the calling agent's key into context.
|
||||
// In managed mode multiple agents share a single tool registry; the agent key
|
||||
// lets tools like spawn/subagent identify which agent is the parent.
|
||||
func WithToolAgentKey(ctx context.Context, key string) context.Context {
|
||||
return context.WithValue(ctx, ctxAgentKey, key)
|
||||
}
|
||||
|
||||
func ToolAgentKeyFromCtx(ctx context.Context) string {
|
||||
v, _ := ctx.Value(ctxAgentKey).(string)
|
||||
return v
|
||||
}
|
||||
|
||||
// --- Vision / ImageGen config (per-agent overrides) ---
|
||||
|
||||
const (
|
||||
|
||||
@@ -61,7 +61,13 @@ func (t *SpawnTool) Execute(ctx context.Context, args map[string]interface{}) *R
|
||||
peerKind := ToolPeerKindFromCtx(ctx)
|
||||
callback := ToolAsyncCBFromCtx(ctx)
|
||||
|
||||
msg, err := t.manager.Spawn(ctx, t.parentID, t.depth, task, label, modelOverride,
|
||||
// Resolve parent agent from ctx (managed mode) with fallback to construction-time default
|
||||
parentID := ToolAgentKeyFromCtx(ctx)
|
||||
if parentID == "" {
|
||||
parentID = t.parentID
|
||||
}
|
||||
|
||||
msg, err := t.manager.Spawn(ctx, parentID, t.depth, task, label, modelOverride,
|
||||
channel, chatID, peerKind, callback)
|
||||
if err != nil {
|
||||
return ErrorResult(err.Error())
|
||||
|
||||
@@ -148,7 +148,13 @@ func (t *SubagentTool) executeRun(ctx context.Context, args map[string]interface
|
||||
channel := ToolChannelFromCtx(ctx)
|
||||
chatID := ToolChatIDFromCtx(ctx)
|
||||
|
||||
result, iterations, err := t.manager.RunSync(ctx, t.parentID, t.depth, task, label,
|
||||
// Resolve parent agent from ctx (managed mode) with fallback to construction-time default
|
||||
parentID := ToolAgentKeyFromCtx(ctx)
|
||||
if parentID == "" {
|
||||
parentID = t.parentID
|
||||
}
|
||||
|
||||
result, iterations, err := t.manager.RunSync(ctx, parentID, t.depth, task, label,
|
||||
channel, chatID)
|
||||
if err != nil {
|
||||
return ErrorResult(fmt.Sprintf("Subagent '%s' failed: %v", label, err))
|
||||
|
||||
Reference in new issue
Block a user