diff --git a/internal/persona/persona.go b/internal/persona/persona.go index 4af029e..d3928bb 100644 --- a/internal/persona/persona.go +++ b/internal/persona/persona.go @@ -64,7 +64,8 @@ func (f Facts) Block(now time.Time) string { ruWeekdays[int(now.Weekday())], now.Day(), ruMonths[int(now.Month())-1], now.Year(), now.Hour(), now.Minute())) - b.WriteString("Умеешь: " + strings.Join(f.can(), "; ") + ". Больше ничего — если просят другое, скажи прямо, что не умеешь.\n") + b.WriteString("Умеешь: " + strings.Join(f.can(), "; ") + + ". Других ДЕЙСТВИЙ не умеешь — если просят такое, скажи прямо.\n") if s := strings.TrimSpace(f.Static); s != "" { b.WriteString(s + "\n") @@ -83,6 +84,11 @@ func (f Facts) Block(now time.Time) string { // perform is worse than one she never mentions. func (f Facts) can() []string { c := []string{ + // Talking comes first, and the closing line says "действий" rather than + // "ничего", because this same block sits in front of the chat and + // general-knowledge prompts. A flat "you can do nothing else" would + // tell her to refuse the exact thing those two prompts are for. + "разговаривать и отвечать на вопросы", "ставить напоминания", "записывать заметки и факты и отвечать по ним", "смотреть календарь", diff --git a/internal/router/knowledge.go b/internal/router/knowledge.go index 6a16e4b..d425e95 100644 --- a/internal/router/knowledge.go +++ b/internal/router/knowledge.go @@ -3,5 +3,8 @@ package router // KnowledgePrompt returns the system prompt for general knowledge questions // that the phraser uses when no notes match the query. func KnowledgePrompt() string { - return `Ты — Мавена, персональный ассистент. Ответь кратко из своих знаний. Если не знаешь — скажи "не знаю". Не выдумывай. Respond ONLY with valid JSON: {"response": "...", "mood": "neutral"}.` + // No self-introduction here: the shared persona block already says who she + // is, and this line used to disagree with it — a different name ("Мавена") + // and a masculine noun ("ассистент") in front of a feminine persona. + return `Ответь кратко из своих знаний. Если не знаешь — скажи "не знаю". Не выдумывай. Respond ONLY with valid JSON: {"response": "...", "mood": "neutral"}.` } diff --git a/internal/router/knowledge_test.go b/internal/router/knowledge_test.go index 2c38fde..e84cc75 100644 --- a/internal/router/knowledge_test.go +++ b/internal/router/knowledge_test.go @@ -11,10 +11,18 @@ func TestKnowledgePrompt(t *testing.T) { t.Fatal("KnowledgePrompt returned empty string") } // Must contain key instructions - checks := []string{"Мавена", "не знаю", "не выдумывай"} + checks := []string{"не знаю", "не выдумывай"} for _, c := range checks { if !strings.Contains(strings.ToLower(prompt), strings.ToLower(c)) { t.Errorf("KnowledgePrompt should mention %q", c) } } + // Who she is comes from the shared persona block now. This prompt used to + // say it too, with a different name and a masculine noun, which is the + // drift the block exists to stop. + for _, w := range []string{"Мавена", "ассистент"} { + if strings.Contains(prompt, w) { + t.Errorf("KnowledgePrompt should not introduce her (%q) — the persona block does", w) + } + } }