122 lines
6.7 KiB
Go
122 lines
6.7 KiB
Go
package elderagent
|
||||
|
|
|
|||
|
|
import (
|
|||
|
|
"encoding/json"
|
|||
|
|
"strings"
|
|||
|
|
"testing"
|
|||
|
|
|
|||
|
|
"data-terminal-cloud/internal/companionopening"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
func TestPrepareConfigurationWelcomeOverrideAndLegacyBehavior(t *testing.T) {
|
|||
|
|
s := Service{CallbackURL: "https://example.com/callback", CallbackSecret: []byte(strings.Repeat("k", 32))}
|
|||
|
|
raw := []byte(`{"S2SConfig":{"ProviderParams":{"dialog":{"system_role":"基础人设"}}},"MemoryConfig":{"Enable":false}}`)
|
|||
|
|
agentRaw := []byte(`{"WelcomeMessage":"已保存的开场。","EnableConversationStateCallback":false}`)
|
|||
|
|
custom, blank := " \t我给您讲个老机器的小故事。\n", " \t\n"
|
|||
|
|
for _, tc := range []struct {
|
|||
|
|
name string
|
|||
|
|
override *string
|
|||
|
|
welcome string
|
|||
|
|
}{
|
|||
|
|
{name: "legacy", welcome: "已保存的开场。"},
|
|||
|
|
{name: "custom", override: &custom, welcome: "我给您讲个老机器的小故事。"},
|
|||
|
|
{name: "blank", override: &blank, welcome: "你好,今天想聊些什么?"},
|
|||
|
|
} {
|
|||
|
|
t.Run(tc.name, func(t *testing.T) {
|
|||
|
|
config, agent, err := s.prepareConfiguration(raw, agentRaw, "call-one", "喜欢喝淡茶", tc.override)
|
|||
|
|
if err != nil {
|
|||
|
|
t.Fatal(err)
|
|||
|
|
}
|
|||
|
|
if agent["WelcomeMessage"] != tc.welcome || agent["EnableConversationStateCallback"] != false {
|
|||
|
|
t.Fatal("incorrect welcome or changed callback policy", agent)
|
|||
|
|
}
|
|||
|
|
if agent["ServerMessageURLForRTS"] != "https://example.com/callbacks/v1/volcengine/chat?session_id=call-one" {
|
|||
|
|
t.Fatal("wrong call callback", agent)
|
|||
|
|
}
|
|||
|
|
role := config["S2SConfig"].(map[string]any)["ProviderParams"].(map[string]any)["dialog"].(map[string]any)["system_role"].(string)
|
|||
|
|
if strings.Contains(role, "喜欢喝淡茶") || config["MemoryConfig"].(map[string]any)["Enable"] != false {
|
|||
|
|
t.Fatal("changed authorized facts or memory policy", role)
|
|||
|
|
}
|
|||
|
|
if tc.override == nil {
|
|||
|
|
if role != withEventTimeGuidance("基础人设") {
|
|||
|
|
t.Fatal("legacy preparation added opening guidance", role)
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
quotedWelcome, _ := json.Marshal(tc.welcome)
|
|||
|
|
if !strings.Contains(role, string(quotedWelcome)) || !strings.Contains(role, "沿当前开场继续") || !strings.Contains(role, "不得把开场中的一般内容归到长者本人") {
|
|||
|
|
t.Fatal("missing opening continuation or factual boundary", role)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
if string(agentRaw) != `{"WelcomeMessage":"已保存的开场。","EnableConversationStateCallback":false}` || string(raw) != `{"S2SConfig":{"ProviderParams":{"dialog":{"system_role":"基础人设"}}},"MemoryConfig":{"Enable":false}}` {
|
|||
|
|
t.Fatal("preparation changed saved configuration bytes")
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func TestPrepareIntroductionWaitsForElderWithoutStartingAnActivity(t *testing.T) {
|
|||
|
|
s := Service{CallbackURL: "https://example.com/callback", CallbackSecret: []byte(strings.Repeat("k", 32))}
|
|||
|
|
raw := []byte(`{"S2SConfig":{"ProviderParams":{"dialog":{"system_role":"基础人设"}}},"MemoryConfig":{"Enable":false}}`)
|
|||
|
|
agentRaw := []byte(`{"WelcomeMessage":"已保存的开场。","EnableConversationStateCallback":false}`)
|
|||
|
|
intro := companionopening.Introduction().Text
|
|||
|
|
config, agent, err := s.prepareConfiguration(raw, agentRaw, "intro-call", "", &intro)
|
|||
|
|
if err != nil || agent["WelcomeMessage"] != intro {
|
|||
|
|
t.Fatal("introduction changed between provider and device", err)
|
|||
|
|
}
|
|||
|
|
role := config["S2SConfig"].(map[string]any)["ProviderParams"].(map[string]any)["dialog"].(map[string]any)["system_role"].(string)
|
|||
|
|
for _, instruction := range []string{"口播介绍后等待长者回应", "不立即讲故事", "不反复索要姓名", "不要承诺已保存或已修改个人资料"} {
|
|||
|
|
if !strings.Contains(role, instruction) {
|
|||
|
|
t.Fatalf("missing first-call behavior: %s", instruction)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if strings.Count(intro, "?") != 1 || config["MemoryConfig"].(map[string]any)["Enable"] != false || agent["EnableConversationStateCallback"] != false {
|
|||
|
|
t.Fatal("introduction adds questions or changes call/privacy policy")
|
|||
|
|
}
|
|||
|
|
ordinary := "您好,咱们聊会儿。"
|
|||
|
|
next, _, err := s.prepareConfiguration(raw, agentRaw, "next-call", "", &ordinary)
|
|||
|
|
if err != nil {
|
|||
|
|
t.Fatal(err)
|
|||
|
|
}
|
|||
|
|
nextRole := next["S2SConfig"].(map[string]any)["ProviderParams"].(map[string]any)["dialog"].(map[string]any)["system_role"].(string)
|
|||
|
|
if strings.Contains(nextRole, "本次是首次自我介绍") {
|
|||
|
|
t.Fatal("first-call instructions leaked to later calls")
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func TestPrepareConfigurationDoesNotAccumulateCallContext(t *testing.T) {
|
|||
|
|
s := Service{CallbackURL: "https://example.com/callback", CallbackSecret: []byte(strings.Repeat("k", 32))}
|
|||
|
|
raw := []byte(`{"S2SConfig":{"ProviderParams":{"dialog":{"system_role":"基础人设"}}}}`)
|
|||
|
|
agentRaw := []byte(`{"WelcomeMessage":"已保存的开场。"}`)
|
|||
|
|
firstWelcome, secondWelcome := "讲讲老机器。", "聊聊家常菜。"
|
|||
|
|
if _, _, err := s.prepareConfiguration(raw, agentRaw, "call-one", "前次资料", &firstWelcome); err != nil {
|
|||
|
|
t.Fatal(err)
|
|||
|
|
}
|
|||
|
|
config, agent, err := s.prepareConfiguration(raw, agentRaw, "call-two", "本次资料", &secondWelcome)
|
|||
|
|
if err != nil {
|
|||
|
|
t.Fatal(err)
|
|||
|
|
}
|
|||
|
|
role := config["S2SConfig"].(map[string]any)["ProviderParams"].(map[string]any)["dialog"].(map[string]any)["system_role"].(string)
|
|||
|
|
if strings.Contains(role, "前次资料") || strings.Contains(role, firstWelcome) || strings.Count(role, "本次已选开场口播") != 1 || strings.Contains(role, "本次资料") || agent["WelcomeMessage"] != secondWelcome {
|
|||
|
|
t.Fatal("prior call context leaked into next preparation", role, agent)
|
|||
|
|
}
|
|||
|
|
if _, _, err = s.prepareConfiguration(raw, []byte(`null`), "call-invalid", "", &secondWelcome); err == nil {
|
|||
|
|
t.Fatal("accepted a null agent configuration")
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func TestPrepareGreetingDoesNotTurnAcknowledgementIntoAnActivity(t *testing.T) {
|
|||
|
|
s := Service{CallbackURL: "https://example.com/callback", CallbackSecret: []byte(strings.Repeat("k", 32))}
|
|||
|
|
raw := []byte(`{"S2SConfig":{"ProviderParams":{"dialog":{"system_role":"基础人设"}}},"MemoryConfig":{"Enable":false}}`)
|
|||
|
|
agentRaw := []byte(`{"WelcomeMessage":"旧开场"}`)
|
|||
|
|
for _, welcome := range []string{"您好,咱们随便聊两句。", "您平常爱听哪一种戏?"} {
|
|||
|
|
config, agent, err := s.prepareConfiguration(raw, agentRaw, "new-call", "", &welcome)
|
|||
|
|
if err != nil || agent["WelcomeMessage"] != welcome {
|
|||
|
|
t.Fatal("selected greeting was not passed through unchanged", err)
|
|||
|
|
}
|
|||
|
|
role := config["S2SConfig"].(map[string]any)["ProviderParams"].(map[string]any)["dialog"].(map[string]any)["system_role"].(string)
|
|||
|
|
if strings.Contains(role, "先讲一小段相关内容") || !strings.Contains(role, "开场只是问候时,不把它扩展成故事") || !strings.Contains(role, "不代表请求猜谜、答题或游戏") || !strings.Contains(role, "只有长者本通明确提出想玩才开始") {
|
|||
|
|
t.Fatal("greeting or brief acknowledgement still directs an unsolicited activity", role)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|