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>
306 lines
8.5 KiB
Python
306 lines
8.5 KiB
Python
"""
|
||
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
|
||
import os
|
||
|
||
# Add gateway-bot to path
|
||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'gateway-bot'))
|
||
|
||
from behavior_policy import (
|
||
analyze_message,
|
||
should_respond,
|
||
detect_agent_mention,
|
||
detect_broadcast_intent,
|
||
detect_question,
|
||
detect_imperative,
|
||
detect_url,
|
||
detect_explicit_request,
|
||
detect_short_note,
|
||
detect_media_question,
|
||
)
|
||
|
||
|
||
# ===== Broadcast Detection =====
|
||
|
||
class TestBroadcastDetection:
|
||
def test_time_pattern(self):
|
||
assert detect_broadcast_intent("20:00 10.02 Deployed")
|
||
|
||
def test_emoji_start(self):
|
||
assert detect_broadcast_intent("\u26a1 Оновлення системи")
|
||
|
||
def test_announcement_word(self):
|
||
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("Допоможи з налаштуванням")
|
||
|
||
|
||
# ===== Imperative Detection =====
|
||
|
||
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("Просто повідомлення")
|
||
|
||
|
||
# ===== Explicit Request Detection (Gateway level) =====
|
||
|
||
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("Просто текст без питання")
|
||
|
||
|
||
# ===== Question Detection =====
|
||
|
||
class TestQuestionDetection:
|
||
def test_with_question_mark(self):
|
||
assert detect_question("Що це таке?")
|
||
|
||
def test_without_question_mark(self):
|
||
assert not detect_question("Що нового в проекті")
|
||
|
||
|
||
# ===== Mention Detection =====
|
||
|
||
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="123",
|
||
user_id="456",
|
||
is_private_chat=True,
|
||
)
|
||
assert decision.should_respond
|
||
assert decision.reason == "private_chat"
|
||
|
||
|
||
# ===== SOWA: Mentioned + Request =====
|
||
|
||
class TestSOWAMentionedWithRequest:
|
||
def test_mentioned_with_request(self):
|
||
decision = analyze_message(
|
||
text="@Helion що змінилось у v2.0?",
|
||
agent_id="helion",
|
||
chat_id="-100123",
|
||
user_id="456",
|
||
is_private_chat=False,
|
||
payload_explicit_request=True,
|
||
)
|
||
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="-100123",
|
||
user_id="456",
|
||
is_private_chat=False,
|
||
)
|
||
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="-100123",
|
||
user_id="456",
|
||
has_media=True,
|
||
is_private_chat=False,
|
||
payload_explicit_request=False,
|
||
)
|
||
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="@Helion що на фото?",
|
||
agent_id="helion",
|
||
chat_id="-100123",
|
||
user_id="456",
|
||
has_media=True,
|
||
media_caption="@Helion що на фото?",
|
||
is_private_chat=False,
|
||
payload_explicit_request=True,
|
||
)
|
||
assert decision.should_respond
|
||
assert decision.reason == "mentioned_with_request"
|
||
|
||
|
||
# ===== v2.1: Bare Mention in Public = NO_OUTPUT =====
|
||
|
||
class TestSOWABareMentionPublicNoResponse:
|
||
def test_bare_mention_public(self):
|
||
resp, reason = should_respond(
|
||
text="@Helion",
|
||
agent_id="helion",
|
||
chat_id="-100123",
|
||
user_id="456",
|
||
is_private_chat=False,
|
||
payload_explicit_request=False,
|
||
)
|
||
assert not resp
|
||
assert reason == "bare_mention_public_topic"
|
||
|
||
|
||
# ===== v2.1: Bare Mention in DM = Responds =====
|
||
|
||
class TestSOWABareMentionDMResponds:
|
||
def test_bare_mention_dm(self):
|
||
resp, reason = should_respond(
|
||
text="@Helion",
|
||
agent_id="helion",
|
||
chat_id="123",
|
||
user_id="456",
|
||
is_private_chat=True,
|
||
payload_explicit_request=False,
|
||
)
|
||
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="-100123",
|
||
user_id="456",
|
||
is_private_chat=False,
|
||
payload_explicit_request=False,
|
||
)
|
||
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="-100123",
|
||
user_id="456",
|
||
is_private_chat=False,
|
||
is_reply_to_agent=True,
|
||
)
|
||
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__":
|
||
pytest.main([__file__, "-v"])
|