mirror of
https://github.com/patriceckhart/zot.git
synced 2026-06-27 05:46:34 +02:00
100 lines
2.8 KiB
Go
100 lines
2.8 KiB
Go
package tools
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/patriceckhart/zot/packages/agent/swarm"
|
|
"github.com/patriceckhart/zot/packages/provider"
|
|
)
|
|
|
|
type noopSwarmRunner struct{}
|
|
|
|
func (noopSwarmRunner) Run(context.Context, swarm.Sink) error { return nil }
|
|
|
|
func newTestSwarm(t *testing.T) *swarm.Swarm {
|
|
t.Helper()
|
|
root := t.TempDir()
|
|
return swarm.New(swarm.Config{
|
|
Root: filepath.Join(root, "swarm"),
|
|
RepoRoot: root,
|
|
NewRunner: func(*swarm.Agent) swarm.Runner {
|
|
return noopSwarmRunner{}
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestSwarmSpawnInheritsHostModelAndProviderWhenOmitted(t *testing.T) {
|
|
tool := &SwarmSpawnTool{
|
|
Swarm: newTestSwarm(t),
|
|
Enabled: func() bool { return true },
|
|
DefaultModel: func() string { return "gpt-5" },
|
|
DefaultProvider: func() string { return "openai-codex" },
|
|
}
|
|
|
|
res, err := tool.Execute(context.Background(), json.RawMessage(`{"task":"research docs"}`), nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if res.IsError {
|
|
t.Fatalf("unexpected tool error: %s", textResult(res.Content))
|
|
}
|
|
details, ok := res.Details.(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("details type = %T, want map[string]any", res.Details)
|
|
}
|
|
if got := details["model"]; got != "gpt-5" {
|
|
t.Fatalf("model detail = %v, want gpt-5", got)
|
|
}
|
|
if got := details["provider"]; got != "openai-codex" {
|
|
t.Fatalf("provider detail = %v, want openai-codex", got)
|
|
}
|
|
text := textResult(res.Content)
|
|
if !strings.Contains(text, "model: gpt-5") || !strings.Contains(text, "provider: openai-codex") {
|
|
t.Fatalf("result text missing inherited model/provider:\n%s", text)
|
|
}
|
|
|
|
agents := tool.Swarm.List()
|
|
if len(agents) != 1 {
|
|
t.Fatalf("spawned agents = %d, want 1", len(agents))
|
|
}
|
|
if agents[0].Model != "gpt-5" || agents[0].Provider != "openai-codex" {
|
|
t.Fatalf("agent model/provider = %q/%q, want gpt-5/openai-codex", agents[0].Model, agents[0].Provider)
|
|
}
|
|
}
|
|
|
|
func TestSwarmSpawnRejectsPartialModelProviderOverride(t *testing.T) {
|
|
tool := &SwarmSpawnTool{
|
|
Swarm: newTestSwarm(t),
|
|
Enabled: func() bool { return true },
|
|
DefaultModel: func() string { return "gpt-5" },
|
|
DefaultProvider: func() string { return "openai-codex" },
|
|
}
|
|
|
|
res, err := tool.Execute(context.Background(), json.RawMessage(`{"task":"research docs","provider":"openai"}`), nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !res.IsError {
|
|
t.Fatalf("expected partial override to fail")
|
|
}
|
|
if got := textResult(res.Content); !strings.Contains(got, "omit both model/provider") {
|
|
t.Fatalf("error text = %q", got)
|
|
}
|
|
if got := len(tool.Swarm.List()); got != 0 {
|
|
t.Fatalf("spawned agents = %d, want 0", got)
|
|
}
|
|
}
|
|
|
|
func textResult(content []provider.Content) string {
|
|
if len(content) == 0 {
|
|
return ""
|
|
}
|
|
if tb, ok := content[0].(provider.TextBlock); ok {
|
|
return tb.Text
|
|
}
|
|
return ""
|
|
}
|