Files
microdao-daarion/gateway-bot/contradiction_detector.py
Apple ef3473db21 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>
2026-02-09 08:46:46 -08:00

107 lines
3.6 KiB
Python

"""
DAARION Platform - Contradiction Detector
Prevents agent from contradicting user corrections
"""
import re
from typing import Optional, Tuple
# Patterns that indicate user correction
CORRECTION_PATTERNS = [
r"це\s+всього\s+(\d+)",
r"тільки\s+(\d+)\s+частин",
r"(\d+)\s+поки\s+немає",
r"(\d+)\s+частин\s+всього",
r"всього\s+(\d+)",
r"поки\s+(\d+)",
r"немає\s+(\d+)",
r"(\d+)\s+частини\s+тільки"
]
# Patterns that indicate agent is contradicting
CONTRADICTION_PATTERNS = [
r"чекаю\s+(\d+)\s+частину",
r"чекаю\s+(\d+)\s+частину",
r"чекаю\s+продовження",
r"чекаю\s+наступну"
]
def detect_correction(user_message: str) -> Optional[int]:
"""
Detect if user message contains a correction about number of parts.
Returns:
Number of parts mentioned, or None if no correction detected
"""
user_lower = user_message.lower()
for pattern in CORRECTION_PATTERNS:
match = re.search(pattern, user_lower)
if match:
try:
num = int(match.group(1))
return num
except (ValueError, IndexError):
continue
return None
def check_contradiction(agent_response: str, user_correction: Optional[int]) -> Tuple[bool, Optional[str]]:
"""
Check if agent response contradicts user correction.
Returns:
(is_contradiction, error_message)
"""
if user_correction is None:
return False, None
response_lower = agent_response.lower()
# Check for contradiction patterns
for pattern in CONTRADICTION_PATTERNS:
match = re.search(pattern, response_lower)
if match:
# Extract number from agent response
try:
agent_num = int(match.group(1)) if match.groups() else None
# If agent mentions a number higher than user correction, it's a contradiction
if agent_num and agent_num > user_correction:
return True, f"Користувач сказав 'всього {user_correction}', але агент каже 'чекаю {agent_num} частину'"
except (ValueError, IndexError):
# Pattern matched but no number - still check for "продовження"
if "продовження" in response_lower or "наступну" in response_lower:
return True, f"Користувач сказав 'всього {user_correction}', але агент каже 'чекаю продовження'"
return False, None
def filter_contradiction(response: str, user_correction: Optional[int]) -> str:
"""
Filter out contradiction from response.
Returns:
Filtered response
"""
if user_correction is None:
return response
# Remove contradiction phrases
filtered = response
# Remove "чекаю N частину" where N > user_correction
pattern = re.compile(r"чекаю\s+\d+\s+частину", re.IGNORECASE)
filtered = pattern.sub("", filtered)
# Remove "чекаю продовження" if user said "всього N"
if "продовження" in filtered.lower() or "наступну" in filtered.lower():
filtered = re.sub(r"чекаю\s+продовження", "", filtered, flags=re.IGNORECASE)
filtered = re.sub(r"чекаю\s+наступну", "", filtered, flags=re.IGNORECASE)
# Clean up extra spaces
filtered = re.sub(r"\s+", " ", filtered).strip()
return filtered