fix: honor model override for sync subagents (#1423)

This commit is contained in:
Zezae Oh authored and GitHub committed 2026-07-11 11:54:18 +07:00
1 parent 0d588e05c1
commit 2a6872ac84
3 files changed
+52 -2

No files matched your search

+2 -1
View File
@@ -127,7 +127,7 @@ func (sm *SubagentManager) RunSync(
ctx context.Context,
parentID string,
depth int,
task, label string,
task, label, modelOverride string,
channel, chatID string,
) (string, int, error) {
cfg := sm.effectiveConfig(ctx)
@@ -160,6 +160,7 @@ func (sm *SubagentManager) RunSync(
Label: label,
Status: "running",
Depth: depth + 1,
Model: modelOverride,
OriginChannel: channel,
OriginChatID: chatID,
OriginLocalKey: ToolLocalKeyFromCtx(ctx),
+48
View File
@@ -0,0 +1,48 @@
package tools
import (
"context"
"testing"
"github.com/google/uuid"
"github.com/nextlevelbuilder/goclaw/internal/providers"
"github.com/nextlevelbuilder/goclaw/internal/store"
)
type recordingSubagentProvider struct {
model string
}
func (p *recordingSubagentProvider) Name() string { return "recording" }
func (p *recordingSubagentProvider) DefaultModel() string { return "provider-default" }
func (p *recordingSubagentProvider) Chat(_ context.Context, req providers.ChatRequest) (*providers.ChatResponse, error) {
p.model = req.Model
return &providers.ChatResponse{Content: "done", FinishReason: "stop"}, nil
}
func (p *recordingSubagentProvider) ChatStream(ctx context.Context, req providers.ChatRequest, _ func(providers.StreamChunk)) (*providers.ChatResponse, error) {
return p.Chat(ctx, req)
}
func TestRunSyncHonorsPerTaskModelOverride(t *testing.T) {
provider := &recordingSubagentProvider{}
manager := NewSubagentManager(provider, nil, "manager-default", nil, NewRegistry, SubagentConfig{
MaxConcurrent: 4,
MaxSpawnDepth: 3,
MaxChildrenPerAgent: 8,
Model: "configured-model",
})
ctx := store.WithTenantID(context.Background(), uuid.New())
ctx = WithParentModel(ctx, "parent-model")
result, _, err := manager.RunSync(ctx, "parent", 0, "test task", "test", "requested-model", "test", "chat")
if err != nil {
t.Fatalf("RunSync() error = %v", err)
}
if result != "done" {
t.Fatalf("RunSync() result = %q, want %q", result, "done")
}
if provider.model != "requested-model" {
t.Fatalf("provider model = %q, want per-task override %q", provider.model, "requested-model")
}
}
+2 -1
View File
@@ -153,6 +153,7 @@ After all spawn tool calls in this turn are complete, briefly tell the user what
// executeSubagentSync runs a sync self-clone.
func (t *SpawnTool) executeSubagentSync(ctx context.Context, args map[string]any, task string) *Result {
label, _ := args["label"].(string)
modelOverride, _ := args["model"].(string)
if label == "" {
label = truncate(task, 50)
}
@@ -165,7 +166,7 @@ func (t *SpawnTool) executeSubagentSync(ctx context.Context, args map[string]any
parentID = t.parentID
}
result, iterations, err := t.subagentMgr.RunSync(ctx, parentID, t.depth, task, label,
result, iterations, err := t.subagentMgr.RunSync(ctx, parentID, t.depth, task, label, modelOverride,
channel, chatID)
if err != nil {
return ErrorResult(fmt.Sprintf("Subagent '%s' failed: %v", label, err))