Files
goclaw/cmd/gateway_consumer_delivery_test.go

181 lines
7.0 KiB
Go

package cmd
import (
"context"
"encoding/json"
"testing"
"github.com/google/uuid"
"github.com/nextlevelbuilder/goclaw/internal/agent"
"github.com/nextlevelbuilder/goclaw/internal/bus"
"github.com/nextlevelbuilder/goclaw/internal/channels"
"github.com/nextlevelbuilder/goclaw/internal/providers"
"github.com/nextlevelbuilder/goclaw/internal/store"
)
func TestBuildDeliveryRuntimeUsesResolvedDeliveryProviderModels(t *testing.T) {
tenantID := uuid.New()
ctx := store.WithTenantID(context.Background(), tenantID)
reg := providers.NewRegistry(store.TenantIDFromContext)
reg.RegisterForTenant(tenantID, deliveryRuntimeTestProvider{name: "channel-provider", model: "channel-default"})
reg.RegisterForTenant(tenantID, deliveryRuntimeTestProvider{name: "progress-provider", model: "progress-default"})
runtime := buildDeliveryRuntime(ctx, &ConsumerDeps{ProviderReg: reg}, deliveryRuntimeTestAgent{
id: "agent",
uuid: uuid.New(),
model: "agent-model",
providerName: "agent-provider",
provider: deliveryRuntimeTestProvider{name: "agent-provider", model: "agent-default"},
}, channels.ResolvedChatBehavior{
Enabled: true,
QuickAck: channels.ResolvedQuickAckConfig{
Enabled: true,
Mode: channels.QuickAckModeSidecar,
Provider: "channel-provider",
Model: "channel-model",
},
IntermediateReplies: channels.ResolvedIntermediateRepliesConfig{
Enabled: true,
Mode: channels.IntermediateModeSidecar,
Provider: "progress-provider",
Model: "progress-model",
},
}, bus.InboundMessage{
TenantID: tenantID,
Content: "kiểm tra giúp tôi",
Metadata: map[string]string{"locale": "vi"},
}, "user-1", "dm", "telegram", "agent")
quick, ok := runtime.QuickAckGenerator.(channels.ProviderDeliveryMessageGenerator)
if !ok {
t.Fatalf("QuickAckGenerator = %T, want ProviderDeliveryMessageGenerator", runtime.QuickAckGenerator)
}
if quick.ProviderName != "channel-provider" || quick.Model != "channel-model" {
t.Fatalf("quick provider/model = %q/%q, want channel-provider/channel-model", quick.ProviderName, quick.Model)
}
progress, ok := runtime.ProgressGenerator.(channels.ProviderDeliveryMessageGenerator)
if !ok {
t.Fatalf("ProgressGenerator = %T, want ProviderDeliveryMessageGenerator", runtime.ProgressGenerator)
}
if progress.ProviderName != "progress-provider" || progress.Model != "progress-model" {
t.Fatalf("progress provider/model = %q/%q, want progress-provider/progress-model", progress.ProviderName, progress.Model)
}
}
func TestBuildDeliveryRuntimeFallsBackToAgentProviderModelWhenUnset(t *testing.T) {
tenantID := uuid.New()
agentProvider := deliveryRuntimeTestProvider{name: "agent-provider", model: "agent-default"}
runtime := buildDeliveryRuntime(context.Background(), &ConsumerDeps{}, deliveryRuntimeTestAgent{
id: "agent",
uuid: uuid.New(),
model: "agent-model",
providerName: "agent-provider",
provider: agentProvider,
}, channels.ResolvedChatBehavior{
Enabled: true,
QuickAck: channels.ResolvedQuickAckConfig{
Enabled: true,
Mode: channels.QuickAckModeSidecar,
},
IntermediateReplies: channels.ResolvedIntermediateRepliesConfig{
Enabled: true,
Mode: channels.IntermediateModeSidecar,
},
}, bus.InboundMessage{TenantID: tenantID}, "user-1", "dm", "telegram", "agent")
quick, ok := runtime.QuickAckGenerator.(channels.ProviderDeliveryMessageGenerator)
if !ok {
t.Fatalf("QuickAckGenerator = %T, want ProviderDeliveryMessageGenerator", runtime.QuickAckGenerator)
}
if quick.ProviderName != "agent-provider" || quick.Model != "agent-model" {
t.Fatalf("quick provider/model = %q/%q, want agent-provider/agent-model", quick.ProviderName, quick.Model)
}
progress, ok := runtime.ProgressGenerator.(channels.ProviderDeliveryMessageGenerator)
if !ok {
t.Fatalf("ProgressGenerator = %T, want ProviderDeliveryMessageGenerator", runtime.ProgressGenerator)
}
if progress.ProviderName != "agent-provider" || progress.Model != "agent-model" {
t.Fatalf("progress provider/model = %q/%q, want agent-provider/agent-model", progress.ProviderName, progress.Model)
}
}
func TestBuildDeliveryRuntimeIncludesAgentPersonaBrief(t *testing.T) {
agent := deliveryRuntimePersonaTestAgent{
deliveryRuntimeTestAgent: deliveryRuntimeTestAgent{
id: "agent",
uuid: uuid.New(),
model: "agent-model",
providerName: "agent-provider",
provider: deliveryRuntimeTestProvider{name: "agent-provider", model: "agent-default"},
},
personaByUserID: map[string]string{
"raw-user": "wrong persona",
"resolved-user": "Style: concise, warm",
},
}
runtime := buildDeliveryRuntime(context.Background(), &ConsumerDeps{}, deliveryRuntimePersonaTestAgent{
deliveryRuntimeTestAgent: agent.deliveryRuntimeTestAgent,
personaByUserID: agent.personaByUserID,
}, channels.ResolvedChatBehavior{
Enabled: true,
QuickAck: channels.ResolvedQuickAckConfig{
Enabled: true,
Mode: channels.QuickAckModeSidecar,
},
IntermediateReplies: channels.ResolvedIntermediateRepliesConfig{
Enabled: true,
Mode: channels.IntermediateModeSidecar,
},
}, bus.InboundMessage{UserID: "raw-user"}, "resolved-user", "dm", "telegram", "agent")
if runtime.PersonaBrief != "Style: concise, warm" {
t.Fatalf("runtime persona brief = %q, want agent persona", runtime.PersonaBrief)
}
}
type deliveryRuntimeTestAgent struct {
id string
uuid uuid.UUID
otherConfig json.RawMessage
model string
providerName string
provider providers.Provider
}
func (a deliveryRuntimeTestAgent) ID() string { return a.id }
func (a deliveryRuntimeTestAgent) UUID() uuid.UUID { return a.uuid }
func (a deliveryRuntimeTestAgent) OtherConfig() json.RawMessage { return a.otherConfig }
func (a deliveryRuntimeTestAgent) Run(context.Context, agent.RunRequest) (*agent.RunResult, error) {
return nil, nil
}
func (a deliveryRuntimeTestAgent) IsRunning() bool { return true }
func (a deliveryRuntimeTestAgent) Model() string { return a.model }
func (a deliveryRuntimeTestAgent) ProviderName() string { return a.providerName }
func (a deliveryRuntimeTestAgent) Provider() providers.Provider { return a.provider }
type deliveryRuntimePersonaTestAgent struct {
deliveryRuntimeTestAgent
personaByUserID map[string]string
}
func (a deliveryRuntimePersonaTestAgent) DeliveryPersonaBrief(_ context.Context, userID string) string {
return a.personaByUserID[userID]
}
type deliveryRuntimeTestProvider struct {
name string
model string
}
func (p deliveryRuntimeTestProvider) Chat(context.Context, providers.ChatRequest) (*providers.ChatResponse, error) {
return &providers.ChatResponse{}, nil
}
func (p deliveryRuntimeTestProvider) ChatStream(context.Context, providers.ChatRequest, func(providers.StreamChunk)) (*providers.ChatResponse, error) {
return &providers.ChatResponse{}, nil
}
func (p deliveryRuntimeTestProvider) DefaultModel() string { return p.model }
func (p deliveryRuntimeTestProvider) Name() string { return p.name }