mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
234 lines
5.6 KiB
Go
234 lines
5.6 KiB
Go
package routing
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/sipeed/picoclaw/pkg/bus"
|
|
"github.com/sipeed/picoclaw/pkg/config"
|
|
)
|
|
|
|
func testConfig(agents []config.AgentConfig) *config.Config {
|
|
return &config.Config{
|
|
Agents: config.AgentsConfig{
|
|
Defaults: config.AgentDefaults{
|
|
Workspace: "/tmp/picoclaw-test",
|
|
ModelName: "gpt-4",
|
|
},
|
|
List: agents,
|
|
},
|
|
Session: config.SessionConfig{
|
|
Dimensions: []string{"sender"},
|
|
},
|
|
}
|
|
}
|
|
|
|
func TestResolveRoute_DefaultAgent_NoBindings(t *testing.T) {
|
|
cfg := testConfig(nil)
|
|
r := NewRouteResolver(cfg)
|
|
|
|
route := r.ResolveRoute(bus.InboundContext{
|
|
Channel: "telegram",
|
|
ChatType: "direct",
|
|
SenderID: "user1",
|
|
})
|
|
|
|
if route.AgentID != DefaultAgentID {
|
|
t.Errorf("AgentID = %q, want %q", route.AgentID, DefaultAgentID)
|
|
}
|
|
if route.MatchedBy != "default" {
|
|
t.Errorf("MatchedBy = %q, want 'default'", route.MatchedBy)
|
|
}
|
|
if len(route.SessionPolicy.Dimensions) != 1 || route.SessionPolicy.Dimensions[0] != "sender" {
|
|
t.Errorf("SessionPolicy.Dimensions = %v, want [sender]", route.SessionPolicy.Dimensions)
|
|
}
|
|
if route.SessionPolicy.IdentityLinks != nil {
|
|
t.Errorf("SessionPolicy.IdentityLinks = %v, want nil", route.SessionPolicy.IdentityLinks)
|
|
}
|
|
}
|
|
|
|
func TestResolveRoute_UsesNormalizedInboundContextFields(t *testing.T) {
|
|
cfg := testConfig([]config.AgentConfig{{ID: "sales", Default: true}})
|
|
r := NewRouteResolver(cfg)
|
|
|
|
route := r.ResolveRoute(bus.InboundContext{
|
|
Channel: "Telegram",
|
|
Account: "Bot2",
|
|
ChatType: "direct",
|
|
SenderID: "user123",
|
|
})
|
|
|
|
if route.AgentID != "sales" {
|
|
t.Errorf("AgentID = %q, want 'sales'", route.AgentID)
|
|
}
|
|
if route.Channel != "telegram" {
|
|
t.Errorf("Channel = %q, want 'telegram'", route.Channel)
|
|
}
|
|
if route.AccountID != "bot2" {
|
|
t.Errorf("AccountID = %q, want 'bot2'", route.AccountID)
|
|
}
|
|
if route.MatchedBy != "default" {
|
|
t.Errorf("MatchedBy = %q, want 'default'", route.MatchedBy)
|
|
}
|
|
}
|
|
|
|
func TestResolveRoute_DispatchFirstMatchWins(t *testing.T) {
|
|
cfg := testConfig([]config.AgentConfig{
|
|
{ID: "main", Default: true},
|
|
{ID: "support"},
|
|
{ID: "sales"},
|
|
})
|
|
cfg.Agents.Dispatch = &config.DispatchConfig{
|
|
Rules: []config.DispatchRule{
|
|
{
|
|
Name: "support-group",
|
|
Agent: "support",
|
|
When: config.DispatchSelector{
|
|
Channel: "telegram",
|
|
Chat: "group:-100123",
|
|
},
|
|
},
|
|
{
|
|
Name: "vip-in-group",
|
|
Agent: "sales",
|
|
When: config.DispatchSelector{
|
|
Channel: "telegram",
|
|
Chat: "group:-100123",
|
|
Sender: "12345",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
r := NewRouteResolver(cfg)
|
|
|
|
route := r.ResolveRoute(bus.InboundContext{
|
|
Channel: "telegram",
|
|
ChatID: "-100123",
|
|
ChatType: "group",
|
|
SenderID: "12345",
|
|
})
|
|
|
|
if route.AgentID != "support" {
|
|
t.Fatalf("AgentID = %q, want support", route.AgentID)
|
|
}
|
|
if route.MatchedBy != "dispatch.rule:support-group" {
|
|
t.Fatalf("MatchedBy = %q, want dispatch.rule:support-group", route.MatchedBy)
|
|
}
|
|
}
|
|
|
|
func TestResolveRoute_DispatchOverridesSessionDimensions(t *testing.T) {
|
|
cfg := testConfig([]config.AgentConfig{
|
|
{ID: "main", Default: true},
|
|
{ID: "support"},
|
|
})
|
|
cfg.Session.Dimensions = []string{"chat"}
|
|
cfg.Agents.Dispatch = &config.DispatchConfig{
|
|
Rules: []config.DispatchRule{
|
|
{
|
|
Name: "support-dm",
|
|
Agent: "support",
|
|
When: config.DispatchSelector{
|
|
Channel: "telegram",
|
|
Chat: "direct:user-1",
|
|
},
|
|
SessionDimensions: []string{"chat", "sender"},
|
|
},
|
|
},
|
|
}
|
|
r := NewRouteResolver(cfg)
|
|
|
|
route := r.ResolveRoute(bus.InboundContext{
|
|
Channel: "telegram",
|
|
ChatID: "user-1",
|
|
ChatType: "direct",
|
|
SenderID: "user-1",
|
|
})
|
|
|
|
if route.AgentID != "support" {
|
|
t.Fatalf("AgentID = %q, want support", route.AgentID)
|
|
}
|
|
if got := route.SessionPolicy.Dimensions; len(got) != 2 || got[0] != "chat" || got[1] != "sender" {
|
|
t.Fatalf("SessionPolicy.Dimensions = %v, want [chat sender]", got)
|
|
}
|
|
}
|
|
|
|
func TestResolveRoute_DispatchMentionedRule(t *testing.T) {
|
|
cfg := testConfig([]config.AgentConfig{
|
|
{ID: "main", Default: true},
|
|
{ID: "support"},
|
|
})
|
|
mentioned := true
|
|
cfg.Agents.Dispatch = &config.DispatchConfig{
|
|
Rules: []config.DispatchRule{
|
|
{
|
|
Name: "slack-mentions",
|
|
Agent: "support",
|
|
When: config.DispatchSelector{
|
|
Channel: "slack",
|
|
Space: "workspace:t001",
|
|
Mentioned: &mentioned,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
r := NewRouteResolver(cfg)
|
|
|
|
route := r.ResolveRoute(bus.InboundContext{
|
|
Channel: "slack",
|
|
ChatID: "C123",
|
|
ChatType: "channel",
|
|
SpaceID: "T001",
|
|
SpaceType: "workspace",
|
|
SenderID: "U123",
|
|
Mentioned: true,
|
|
})
|
|
|
|
if route.AgentID != "support" {
|
|
t.Fatalf("AgentID = %q, want support", route.AgentID)
|
|
}
|
|
}
|
|
|
|
func TestResolveRoute_InvalidAgentFallsToDefault(t *testing.T) {
|
|
agents := []config.AgentConfig{
|
|
{ID: "main", Default: true},
|
|
}
|
|
cfg := testConfig(agents)
|
|
r := NewRouteResolver(cfg)
|
|
|
|
route := r.ResolveRoute(bus.InboundContext{Channel: "telegram"})
|
|
|
|
if route.AgentID != "main" {
|
|
t.Errorf("AgentID = %q, want 'main' (invalid agent should fall to default)", route.AgentID)
|
|
}
|
|
}
|
|
|
|
func TestResolveRoute_DefaultAgentSelection(t *testing.T) {
|
|
agents := []config.AgentConfig{
|
|
{ID: "alpha"},
|
|
{ID: "beta", Default: true},
|
|
{ID: "gamma"},
|
|
}
|
|
cfg := testConfig(agents)
|
|
r := NewRouteResolver(cfg)
|
|
|
|
route := r.ResolveRoute(bus.InboundContext{Channel: "cli"})
|
|
|
|
if route.AgentID != "beta" {
|
|
t.Errorf("AgentID = %q, want 'beta' (marked as default)", route.AgentID)
|
|
}
|
|
}
|
|
|
|
func TestResolveRoute_NoDefaultUsesFirst(t *testing.T) {
|
|
agents := []config.AgentConfig{
|
|
{ID: "alpha"},
|
|
{ID: "beta"},
|
|
}
|
|
cfg := testConfig(agents)
|
|
r := NewRouteResolver(cfg)
|
|
|
|
route := r.ResolveRoute(bus.InboundContext{Channel: "cli"})
|
|
|
|
if route.AgentID != "alpha" {
|
|
t.Errorf("AgentID = %q, want 'alpha' (first in list)", route.AgentID)
|
|
}
|
|
}
|