test(agent): assert child turn uses target agent model

Replace generic mockProvider with modelRecordingProvider that captures
the model parameter passed to Chat(). After delegation from alpha to
beta, assert the recorded model is "model-beta" — proving the child
turn actually ran with the target agent's configuration, not the
caller's.

Also add wiring tests:
- TestDelegateToolNotRegistered_SingleAgent: single-agent has no
  delegate in its tool registry
- TestDelegateToolRegistered_MultiAgent: both agents in a two-agent
  setup have the delegate tool

Ref: #2148
This commit is contained in:
xiaoen
2026-04-15 22:27:05 +08:00
parent 6ee66123f2
commit a34120b821
+68 -12
View File
@@ -2071,9 +2071,36 @@ func TestSubTurn_IndependentContext(t *testing.T) {
// ====================== TargetAgentID Tests ======================
// modelRecordingProvider captures the model passed to Chat for test assertions.
type modelRecordingProvider struct {
mu sync.Mutex
lastModel string
}
func (rp *modelRecordingProvider) Chat(
_ context.Context,
_ []providers.Message,
_ []providers.ToolDefinition,
model string,
_ map[string]any,
) (*providers.LLMResponse, error) {
rp.mu.Lock()
rp.lastModel = model
rp.mu.Unlock()
return &providers.LLMResponse{Content: "Mock response"}, nil
}
func (rp *modelRecordingProvider) GetDefaultModel() string { return "mock-model" }
func (rp *modelRecordingProvider) getLastModel() string {
rp.mu.Lock()
defer rp.mu.Unlock()
return rp.lastModel
}
// newMultiAgentLoop creates an AgentLoop with two named agents for testing
// cross-agent delegation via TargetAgentID.
func newMultiAgentLoop(t *testing.T) (*AgentLoop, func()) {
func newMultiAgentLoop(t *testing.T, provider providers.LLMProvider) (*AgentLoop, func()) {
t.Helper()
tmpDir, err := os.MkdirTemp("", "multiagent-test-*")
if err != nil {
@@ -2109,24 +2136,20 @@ func newMultiAgentLoop(t *testing.T) (*AgentLoop, func()) {
}
msgBus := bus.NewMessageBus()
provider := &mockProvider{}
al := NewAgentLoop(cfg, msgBus, provider)
return al, func() { os.RemoveAll(tmpDir) }
}
func TestSpawnSubTurn_TargetAgentID_UsesTargetAgent(t *testing.T) {
al, cleanup := newMultiAgentLoop(t)
rp := &modelRecordingProvider{}
al, cleanup := newMultiAgentLoop(t, rp)
defer cleanup()
alphaAgent, ok := al.registry.GetAgent("alpha")
if !ok {
t.Fatal("alpha agent not in registry")
}
betaAgent, ok := al.registry.GetAgent("beta")
if !ok {
t.Fatal("beta agent not in registry")
}
// Parent is alpha, target is beta
parent := &turnState{
@@ -2151,14 +2174,16 @@ func TestSpawnSubTurn_TargetAgentID_UsesTargetAgent(t *testing.T) {
t.Fatal("expected non-nil result")
}
// Verify the two agents have distinct models (test setup sanity check)
if alphaAgent.Model == betaAgent.Model {
t.Fatal("test setup error: alpha and beta should have different models")
// The recording provider captures the model passed to Chat().
// If TargetAgentID works correctly, the child turn should have
// used beta's model, not alpha's.
if got := rp.getLastModel(); got != "model-beta" {
t.Errorf("child turn used model %q, want %q", got, "model-beta")
}
}
func TestSpawnSubTurn_TargetAgentID_NotFound(t *testing.T) {
al, cleanup := newMultiAgentLoop(t)
al, cleanup := newMultiAgentLoop(t, &mockProvider{})
defer cleanup()
alphaAgent, _ := al.registry.GetAgent("alpha")
@@ -2187,7 +2212,7 @@ func TestSpawnSubTurn_TargetAgentID_NotFound(t *testing.T) {
}
func TestSpawnSubTurn_TargetAgentID_EmptyModelAccepted(t *testing.T) {
al, cleanup := newMultiAgentLoop(t)
al, cleanup := newMultiAgentLoop(t, &mockProvider{})
defer cleanup()
alphaAgent, _ := al.registry.GetAgent("alpha")
@@ -2215,3 +2240,34 @@ func TestSpawnSubTurn_TargetAgentID_EmptyModelAccepted(t *testing.T) {
t.Fatal("expected non-nil result")
}
}
func TestDelegateToolNotRegistered_SingleAgent(t *testing.T) {
// Single-agent setup: delegate should not be registered
al, _, _, provider, cleanup := newTestAgentLoop(t)
_ = provider
defer cleanup()
agent := al.registry.GetDefaultAgent()
if agent == nil {
t.Fatal("default agent should exist")
}
if _, has := agent.Tools.Get("delegate"); has {
t.Error("delegate tool should not be registered in single-agent setup")
}
}
func TestDelegateToolRegistered_MultiAgent(t *testing.T) {
al, cleanup := newMultiAgentLoop(t, &mockProvider{})
defer cleanup()
// Both agents should have the delegate tool
for _, id := range []string{"alpha", "beta"} {
agent, ok := al.registry.GetAgent(id)
if !ok {
t.Fatalf("agent %q not found", id)
}
if _, has := agent.Tools.Get("delegate"); !has {
t.Errorf("agent %q should have delegate tool in multi-agent setup", id)
}
}
}