snapshot: NODE1 production state 2026-02-09
Complete snapshot of /opt/microdao-daarion/ from NODE1 (144.76.224.179).
This represents the actual running production code that has diverged
significantly from the previous main branch.
Key changes from old main:
- Gateway (http_api.py): expanded from ~40KB to 164KB with full agent support
- Router: new /v1/agents/{id}/infer endpoint with vision + DeepSeek routing
- Behavior Policy: SOWA v2.2 (3-level: FULL/ACK/SILENT)
- Agent Registry: config/agent_registry.yml as single source of truth
- 13 agents configured (was 3)
- Memory service integration
- CrewAI teams and roles
Excluded from snapshot: venv/, .env, data/, backups, .tgz archives
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,446 +1,304 @@
|
||||
"""
|
||||
Tests for Behavior Policy v1: Silent-by-default + Short-first + Media-no-comment
|
||||
Tests for Behavior Policy v2.1
|
||||
Aligned with Global System Prompt v2.1 — FINAL
|
||||
|
||||
Tests cover:
|
||||
- Broadcast detection
|
||||
- Imperative/explicit request detection
|
||||
- Mention detection
|
||||
- SOWA: DM always responds
|
||||
- SOWA: Mentioned + explicit_request -> responds
|
||||
- SOWA: Broadcast without mention -> NO_OUTPUT
|
||||
- SOWA: Media/link without request -> NO_OUTPUT
|
||||
- SOWA: Media + mention -> responds
|
||||
- SOWA: Bare mention in public -> NO_OUTPUT (v2.1 anti-spam)
|
||||
- SOWA: Bare mention in DM -> responds
|
||||
- SOWA: Question without mention in topic -> NO_OUTPUT
|
||||
- URL detection
|
||||
- Reply to agent
|
||||
"""
|
||||
import pytest
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
# Add gateway-bot to path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "gateway-bot"))
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'gateway-bot'))
|
||||
|
||||
from behavior_policy import (
|
||||
detect_agent_mention,
|
||||
detect_any_agent_mention,
|
||||
detect_command,
|
||||
detect_question,
|
||||
detect_imperative,
|
||||
detect_broadcast_intent,
|
||||
detect_short_note,
|
||||
detect_media_question,
|
||||
analyze_message,
|
||||
should_respond,
|
||||
is_no_output_response,
|
||||
NO_OUTPUT,
|
||||
TRAINING_GROUP_IDS,
|
||||
detect_agent_mention,
|
||||
detect_broadcast_intent,
|
||||
detect_question,
|
||||
detect_imperative,
|
||||
detect_url,
|
||||
detect_explicit_request,
|
||||
detect_short_note,
|
||||
detect_media_question,
|
||||
)
|
||||
|
||||
|
||||
# ========================================
|
||||
# Unit Tests: detect_agent_mention
|
||||
# ========================================
|
||||
# ===== Broadcast Detection =====
|
||||
|
||||
class TestDetectAgentMention:
|
||||
def test_helion_mention_exact(self):
|
||||
assert detect_agent_mention("Helion, що ти думаєш?", "helion") is True
|
||||
|
||||
def test_helion_mention_lowercase(self):
|
||||
assert detect_agent_mention("helion допоможи", "helion") is True
|
||||
|
||||
def test_helion_mention_ukrainian(self):
|
||||
assert detect_agent_mention("Хеліон, як справи?", "helion") is True
|
||||
|
||||
def test_helion_mention_at(self):
|
||||
assert detect_agent_mention("@energyunionBot глянь", "helion") is True
|
||||
|
||||
def test_helion_no_mention(self):
|
||||
assert detect_agent_mention("Привіт всім", "helion") is False
|
||||
|
||||
def test_daarwizz_mention(self):
|
||||
assert detect_agent_mention("@DAARWIZZBot поясни", "daarwizz") is True
|
||||
|
||||
def test_daarwizz_no_mention(self):
|
||||
assert detect_agent_mention("Helion допоможи", "daarwizz") is False
|
||||
|
||||
|
||||
class TestDetectAnyAgentMention:
|
||||
def test_helion_detected(self):
|
||||
assert detect_any_agent_mention("Helion, скажи") == "helion"
|
||||
|
||||
def test_daarwizz_detected(self):
|
||||
assert detect_any_agent_mention("@DAARWIZZBot допоможи") == "daarwizz"
|
||||
|
||||
def test_no_agent(self):
|
||||
assert detect_any_agent_mention("Привіт всім") is None
|
||||
|
||||
|
||||
# ========================================
|
||||
# Unit Tests: detect_command
|
||||
# ========================================
|
||||
|
||||
class TestDetectCommand:
|
||||
def test_ask_command(self):
|
||||
assert detect_command("/ask що таке DAO?") is True
|
||||
|
||||
def test_helion_command(self):
|
||||
assert detect_command("/helion покажи") is True
|
||||
|
||||
def test_brand_command(self):
|
||||
assert detect_command("/бренд_інтейк https://example.com") is True
|
||||
|
||||
def test_no_command(self):
|
||||
assert detect_command("Привіт, як справи?") is False
|
||||
|
||||
def test_slash_in_middle(self):
|
||||
assert detect_command("Дивись https://example.com/path") is False
|
||||
|
||||
|
||||
# ========================================
|
||||
# Unit Tests: detect_question
|
||||
# ========================================
|
||||
|
||||
class TestDetectQuestion:
|
||||
def test_question_mark(self):
|
||||
assert detect_question("Що це таке?") is True
|
||||
|
||||
def test_question_word_start(self):
|
||||
assert detect_question("Як це працює") is True
|
||||
|
||||
def test_question_word_чому(self):
|
||||
assert detect_question("Чому так") is True
|
||||
|
||||
def test_english_question(self):
|
||||
assert detect_question("What is this?") is True
|
||||
|
||||
def test_no_question(self):
|
||||
assert detect_question("Добре") is False
|
||||
|
||||
def test_statement(self):
|
||||
assert detect_question("Я згоден з цим") is False
|
||||
|
||||
|
||||
# ========================================
|
||||
# Unit Tests: detect_imperative
|
||||
# ========================================
|
||||
|
||||
class TestDetectImperative:
|
||||
def test_поясни(self):
|
||||
assert detect_imperative("Поясни мені це") is True
|
||||
|
||||
def test_зроби(self):
|
||||
assert detect_imperative("Зроби аналіз") is True
|
||||
|
||||
def test_допоможи(self):
|
||||
assert detect_imperative("Допоможи з цим") is True
|
||||
|
||||
def test_after_mention(self):
|
||||
assert detect_imperative("@Helion поясни") is True
|
||||
|
||||
def test_no_imperative(self):
|
||||
assert detect_imperative("Привіт") is False
|
||||
|
||||
|
||||
# ========================================
|
||||
# Unit Tests: detect_broadcast_intent
|
||||
# ========================================
|
||||
|
||||
class TestDetectBroadcastIntent:
|
||||
class TestBroadcastDetection:
|
||||
def test_time_pattern(self):
|
||||
assert detect_broadcast_intent("20:00 Вебінар") is True
|
||||
|
||||
def test_time_date_pattern(self):
|
||||
assert detect_broadcast_intent("14.30 10.02 Зустріч") is True
|
||||
|
||||
assert detect_broadcast_intent("20:00 10.02 Deployed")
|
||||
|
||||
def test_emoji_start(self):
|
||||
assert detect_broadcast_intent("✅ Завершено") is True
|
||||
|
||||
def test_url_only(self):
|
||||
assert detect_broadcast_intent("https://example.com") is True
|
||||
|
||||
assert detect_broadcast_intent("\u26a1 Оновлення системи")
|
||||
|
||||
def test_announcement_word(self):
|
||||
assert detect_broadcast_intent("Анонс: новий реліз") is True
|
||||
|
||||
def test_normal_message(self):
|
||||
assert detect_broadcast_intent("Привіт, як справи?") is False
|
||||
assert detect_broadcast_intent("увага всім! нова версія")
|
||||
|
||||
def test_url_only(self):
|
||||
assert detect_broadcast_intent("https://example.com")
|
||||
|
||||
def test_normal_message_not_broadcast(self):
|
||||
assert not detect_broadcast_intent("Допоможи з налаштуванням")
|
||||
|
||||
|
||||
# ========================================
|
||||
# Unit Tests: detect_short_note
|
||||
# ========================================
|
||||
# ===== Imperative Detection =====
|
||||
|
||||
class TestDetectShortNote:
|
||||
def test_checkmark_only(self):
|
||||
assert detect_short_note("✅") is True
|
||||
|
||||
def test_time_checkmark(self):
|
||||
assert detect_short_note("20:00 ✅") is True
|
||||
|
||||
def test_ok(self):
|
||||
assert detect_short_note("ok") is True
|
||||
|
||||
def test_plus(self):
|
||||
assert detect_short_note("+") is True
|
||||
|
||||
def test_normal_message(self):
|
||||
assert detect_short_note("Привіт, як справи?") is False
|
||||
|
||||
def test_empty(self):
|
||||
assert detect_short_note("") is True
|
||||
class TestImperativeDetection:
|
||||
def test_ua_imperative(self):
|
||||
assert detect_imperative("Допоможи з налаштуванням")
|
||||
|
||||
def test_ua_analyze(self):
|
||||
assert detect_imperative("Проаналізуй логи")
|
||||
|
||||
def test_en_fix(self):
|
||||
assert detect_imperative("Fix this bug")
|
||||
|
||||
def test_en_explain(self):
|
||||
assert detect_imperative("Explain how it works")
|
||||
|
||||
def test_no_imperative(self):
|
||||
assert not detect_imperative("Просто повідомлення")
|
||||
|
||||
|
||||
# ========================================
|
||||
# Unit Tests: detect_media_question
|
||||
# ========================================
|
||||
# ===== Explicit Request Detection (Gateway level) =====
|
||||
|
||||
class TestDetectMediaQuestion:
|
||||
def test_question_in_caption(self):
|
||||
assert detect_media_question("Що на цьому фото?") is True
|
||||
|
||||
def test_imperative_in_caption(self):
|
||||
assert detect_media_question("Опиши це зображення") is True
|
||||
|
||||
def test_no_question(self):
|
||||
assert detect_media_question("") is False
|
||||
|
||||
def test_just_hashtag(self):
|
||||
assert detect_media_question("#photo") is False
|
||||
class TestExplicitRequestDetection:
|
||||
def test_imperative_triggers(self):
|
||||
assert detect_explicit_request("Допоможи з налаштуванням")
|
||||
|
||||
def test_question_with_mention(self):
|
||||
assert detect_explicit_request("Що це?", mentioned_agents=['helion'])
|
||||
|
||||
def test_question_in_dm(self):
|
||||
assert detect_explicit_request("Що це?", is_dm=True)
|
||||
|
||||
def test_question_without_context(self):
|
||||
assert not detect_explicit_request("Що це?")
|
||||
|
||||
def test_no_question_no_imperative(self):
|
||||
assert not detect_explicit_request("Просто текст без питання")
|
||||
|
||||
|
||||
# ========================================
|
||||
# Unit Tests: is_no_output_response
|
||||
# ========================================
|
||||
# ===== Question Detection =====
|
||||
|
||||
class TestIsNoOutputResponse:
|
||||
def test_empty_string(self):
|
||||
assert is_no_output_response("") is True
|
||||
|
||||
def test_whitespace(self):
|
||||
assert is_no_output_response(" ") is True
|
||||
|
||||
def test_no_output_marker(self):
|
||||
assert is_no_output_response("__NO_OUTPUT__") is True
|
||||
|
||||
def test_no_output_lowercase(self):
|
||||
assert is_no_output_response("no_output") is True
|
||||
|
||||
def test_normal_response(self):
|
||||
assert is_no_output_response("Ось моя відповідь") is False
|
||||
|
||||
def test_dots_only(self):
|
||||
assert is_no_output_response("...") is True
|
||||
class TestQuestionDetection:
|
||||
def test_with_question_mark(self):
|
||||
assert detect_question("Що це таке?")
|
||||
|
||||
def test_without_question_mark(self):
|
||||
assert not detect_question("Що нового в проекті")
|
||||
|
||||
|
||||
# ========================================
|
||||
# Integration Tests: analyze_message / should_respond
|
||||
# ========================================
|
||||
# ===== Mention Detection =====
|
||||
|
||||
class TestAnalyzeMessage:
|
||||
"""Test main decision logic"""
|
||||
|
||||
def test_training_group_always_respond(self):
|
||||
decision = analyze_message(
|
||||
text="Привіт всім",
|
||||
agent_id="helion",
|
||||
chat_id="-1003556680911", # Training group
|
||||
)
|
||||
assert decision.should_respond is True
|
||||
assert decision.reason == "training_group"
|
||||
|
||||
def test_private_chat_always_respond(self):
|
||||
class TestMentionDetection:
|
||||
def test_helion_at_mention(self):
|
||||
assert detect_agent_mention("@Helion що на постері?", "helion")
|
||||
|
||||
def test_helion_name(self):
|
||||
assert detect_agent_mention("Helion, допоможи", "helion")
|
||||
|
||||
def test_ua_name(self):
|
||||
assert detect_agent_mention("хеліон, що скажеш?", "helion")
|
||||
|
||||
def test_no_mention(self):
|
||||
assert not detect_agent_mention("Хто знає відповідь?", "helion")
|
||||
|
||||
|
||||
# ===== URL Detection =====
|
||||
|
||||
class TestURLDetection:
|
||||
def test_https(self):
|
||||
assert detect_url("Check https://example.com")
|
||||
|
||||
def test_www(self):
|
||||
assert detect_url("Visit www.github.com")
|
||||
|
||||
def test_telegram(self):
|
||||
assert detect_url("Join t.me/channel")
|
||||
|
||||
def test_telegram_me(self):
|
||||
assert detect_url("Link: telegram.me/bot")
|
||||
|
||||
def test_no_link(self):
|
||||
assert not detect_url("No link here")
|
||||
|
||||
|
||||
# ===== SOWA: DM Always Responds =====
|
||||
|
||||
class TestSOWADMAlwaysResponds:
|
||||
def test_dm_responds(self):
|
||||
decision = analyze_message(
|
||||
text="Привіт",
|
||||
agent_id="helion",
|
||||
chat_id="123456",
|
||||
chat_id="123",
|
||||
user_id="456",
|
||||
is_private_chat=True,
|
||||
)
|
||||
assert decision.should_respond is True
|
||||
assert decision.should_respond
|
||||
assert decision.reason == "private_chat"
|
||||
|
||||
def test_direct_mention_respond(self):
|
||||
|
||||
|
||||
# ===== SOWA: Mentioned + Request =====
|
||||
|
||||
class TestSOWAMentionedWithRequest:
|
||||
def test_mentioned_with_request(self):
|
||||
decision = analyze_message(
|
||||
text="Helion, що думаєш?",
|
||||
text="@Helion що змінилось у v2.0?",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
chat_id="-100123",
|
||||
user_id="456",
|
||||
is_private_chat=False,
|
||||
payload_explicit_request=True,
|
||||
)
|
||||
assert decision.should_respond is True
|
||||
assert decision.reason == "direct_mention"
|
||||
|
||||
def test_command_respond(self):
|
||||
decision = analyze_message(
|
||||
text="/helion допоможи",
|
||||
assert decision.should_respond
|
||||
assert decision.reason == "mentioned_with_request"
|
||||
|
||||
|
||||
# ===== SOWA: Broadcast Without Mention =====
|
||||
|
||||
class TestSOWABroadcastNoMention:
|
||||
def test_broadcast_no_mention(self):
|
||||
resp, reason = should_respond(
|
||||
text="\u26a1 Оновлення: релізимо v2.0",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
chat_id="-100123",
|
||||
user_id="456",
|
||||
is_private_chat=False,
|
||||
)
|
||||
assert decision.should_respond is True
|
||||
assert decision.reason == "command"
|
||||
|
||||
def test_broadcast_no_mention_silent(self):
|
||||
decision = analyze_message(
|
||||
text="20:00 Вебінар Energy Union",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
)
|
||||
assert decision.should_respond is False
|
||||
assert decision.reason == "broadcast_no_mention"
|
||||
|
||||
def test_short_note_silent(self):
|
||||
decision = analyze_message(
|
||||
text="20:00 10.02 ✅",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
)
|
||||
assert decision.should_respond is False
|
||||
assert "short_note" in decision.reason or "broadcast" in decision.reason
|
||||
|
||||
def test_media_no_question_silent(self):
|
||||
decision = analyze_message(
|
||||
assert not resp
|
||||
assert reason == "broadcast_not_directed"
|
||||
|
||||
|
||||
# ===== SOWA: Media Without Request =====
|
||||
|
||||
class TestSOWAMediaWithoutRequest:
|
||||
def test_media_no_request(self):
|
||||
resp, reason = should_respond(
|
||||
text="",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
chat_id="-100123",
|
||||
user_id="456",
|
||||
has_media=True,
|
||||
media_caption="",
|
||||
is_private_chat=False,
|
||||
payload_explicit_request=False,
|
||||
)
|
||||
assert decision.should_respond is False
|
||||
assert decision.reason == "media_no_question"
|
||||
|
||||
def test_media_with_question_respond(self):
|
||||
assert not resp
|
||||
assert reason == "media_or_link_without_request"
|
||||
|
||||
|
||||
# ===== SOWA: Media + Mention =====
|
||||
|
||||
class TestSOWAMediaWithMention:
|
||||
def test_media_with_mention(self):
|
||||
decision = analyze_message(
|
||||
text="",
|
||||
text="@Helion що на фото?",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
chat_id="-100123",
|
||||
user_id="456",
|
||||
has_media=True,
|
||||
media_caption="Що на цьому фото?",
|
||||
media_caption="@Helion що на фото?",
|
||||
is_private_chat=False,
|
||||
payload_explicit_request=True,
|
||||
)
|
||||
assert decision.should_respond is True
|
||||
assert decision.reason == "media_with_question"
|
||||
|
||||
def test_question_no_mention_silent(self):
|
||||
"""General question without mention = don't respond in groups"""
|
||||
decision = analyze_message(
|
||||
text="Як це працює?",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
)
|
||||
assert decision.should_respond is False
|
||||
assert decision.reason == "question_no_mention"
|
||||
|
||||
def test_addressed_to_other_agent(self):
|
||||
decision = analyze_message(
|
||||
text="@DAARWIZZBot поясни DAO",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
)
|
||||
assert decision.should_respond is False
|
||||
assert "other_agent" in decision.reason
|
||||
assert decision.should_respond
|
||||
assert decision.reason == "mentioned_with_request"
|
||||
|
||||
|
||||
# ========================================
|
||||
# E2E Test Cases (from requirements)
|
||||
# ========================================
|
||||
# ===== v2.1: Bare Mention in Public = NO_OUTPUT =====
|
||||
|
||||
class TestE2ECases:
|
||||
"""
|
||||
Test cases from the requirements document.
|
||||
"""
|
||||
|
||||
def test_case_1_poster_no_question(self):
|
||||
"""Case 1: Постер у каналі без питання → (нічого)"""
|
||||
respond, reason = should_respond(
|
||||
text="",
|
||||
class TestSOWABareMentionPublicNoResponse:
|
||||
def test_bare_mention_public(self):
|
||||
resp, reason = should_respond(
|
||||
text="@Helion",
|
||||
agent_id="helion",
|
||||
chat_id="channel123",
|
||||
has_media=True,
|
||||
media_caption="",
|
||||
chat_id="-100123",
|
||||
user_id="456",
|
||||
is_private_chat=False,
|
||||
payload_explicit_request=False,
|
||||
)
|
||||
assert respond is False
|
||||
assert reason == "media_no_question"
|
||||
|
||||
def test_case_2_timing_no_question(self):
|
||||
"""Case 2: Таймінг без питання → (нічого)"""
|
||||
respond, reason = should_respond(
|
||||
text="20:00 10.02 ✅",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
)
|
||||
assert respond is False
|
||||
# Either short_note or broadcast pattern matches
|
||||
|
||||
def test_case_3_direct_request_with_photo(self):
|
||||
"""Case 3: @Helion що на цьому постері? коротко + image → respond"""
|
||||
respond, reason = should_respond(
|
||||
text="",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
has_media=True,
|
||||
media_caption="@Helion що на цьому постері? коротко",
|
||||
)
|
||||
# Should respond because there's a question in caption
|
||||
assert respond is True
|
||||
assert reason == "media_with_question"
|
||||
|
||||
def test_case_4_link_no_question(self):
|
||||
"""Case 4: Посилання без питання → (нічого)"""
|
||||
respond, reason = should_respond(
|
||||
text="https://t.me/energyunionofficial/123",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
has_media=True, # Link treated as media
|
||||
media_caption="https://t.me/energyunionofficial/123",
|
||||
)
|
||||
assert respond is False
|
||||
assert reason == "media_no_question"
|
||||
|
||||
def test_case_5_link_with_question(self):
|
||||
"""Case 5: @DAARWIZZ глянь посилання і скажи 3 тези + link → respond"""
|
||||
respond, reason = should_respond(
|
||||
text="@DAARWIZZBot глянь посилання і скажи 3 тези https://example.com",
|
||||
agent_id="daarwizz",
|
||||
chat_id="group123",
|
||||
has_media=True,
|
||||
media_caption="@DAARWIZZBot глянь посилання і скажи 3 тези https://example.com",
|
||||
)
|
||||
# Should respond because there's a direct mention + question
|
||||
assert respond is True
|
||||
assert reason == "media_with_question"
|
||||
assert not resp
|
||||
assert reason == "bare_mention_public_topic"
|
||||
|
||||
|
||||
# ========================================
|
||||
# Edge Cases
|
||||
# ========================================
|
||||
# ===== v2.1: Bare Mention in DM = Responds =====
|
||||
|
||||
class TestEdgeCases:
|
||||
def test_empty_text(self):
|
||||
respond, reason = should_respond(
|
||||
text="",
|
||||
class TestSOWABareMentionDMResponds:
|
||||
def test_bare_mention_dm(self):
|
||||
resp, reason = should_respond(
|
||||
text="@Helion",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
chat_id="123",
|
||||
user_id="456",
|
||||
is_private_chat=True,
|
||||
payload_explicit_request=False,
|
||||
)
|
||||
assert respond is False
|
||||
|
||||
def test_none_text(self):
|
||||
respond, reason = should_respond(
|
||||
text=None,
|
||||
assert resp
|
||||
assert reason == "private_chat"
|
||||
|
||||
|
||||
# ===== SOWA: Question Without Mention in Topic =====
|
||||
|
||||
class TestSOWAQuestionWithoutMentionInTopic:
|
||||
def test_question_no_mention_topic(self):
|
||||
resp, reason = should_respond(
|
||||
text="Хто знає чому падає сервер?",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
chat_id="-100123",
|
||||
user_id="456",
|
||||
is_private_chat=False,
|
||||
payload_explicit_request=False,
|
||||
)
|
||||
assert respond is False
|
||||
|
||||
def test_mixed_agents_mention(self):
|
||||
"""When multiple agents mentioned, each should handle their own"""
|
||||
# Helion should respond to Helion mention
|
||||
respond_helion, _ = should_respond(
|
||||
text="Helion та DAARWIZZ, допоможіть",
|
||||
assert not resp
|
||||
assert reason == "not_directed_to_agent"
|
||||
|
||||
|
||||
# ===== SOWA: Reply to Agent =====
|
||||
|
||||
class TestSOWAReplyToAgent:
|
||||
def test_reply_to_agent(self):
|
||||
resp, reason = should_respond(
|
||||
text="А що з цим робити?",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
chat_id="-100123",
|
||||
user_id="456",
|
||||
is_private_chat=False,
|
||||
is_reply_to_agent=True,
|
||||
)
|
||||
assert respond_helion is True
|
||||
|
||||
# DAARWIZZ should also respond
|
||||
respond_daarwizz, _ = should_respond(
|
||||
text="Helion та DAARWIZZ, допоможіть",
|
||||
agent_id="daarwizz",
|
||||
chat_id="group123",
|
||||
)
|
||||
assert respond_daarwizz is True
|
||||
|
||||
def test_question_to_specific_agent(self):
|
||||
"""Question directed to another agent"""
|
||||
respond, reason = should_respond(
|
||||
text="@greenfoodliveBot як справи?",
|
||||
agent_id="helion",
|
||||
chat_id="group123",
|
||||
)
|
||||
assert respond is False
|
||||
assert "other_agent" in reason
|
||||
assert resp
|
||||
assert reason == "reply_to_agent"
|
||||
|
||||
|
||||
# ===== Short Notes =====
|
||||
|
||||
class TestShortNotes:
|
||||
def test_checkmark(self):
|
||||
assert detect_short_note("\u2705")
|
||||
|
||||
def test_ok(self):
|
||||
assert detect_short_note("ok")
|
||||
|
||||
def test_plus(self):
|
||||
assert detect_short_note("+")
|
||||
|
||||
def test_normal_message(self):
|
||||
assert not detect_short_note("Це нормальне повідомлення")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user