helion: deepseek-first, on-demand CrewAI, local subagent profiles, concise post-synthesis
This commit is contained in:
@@ -469,6 +469,18 @@ SENPAI_CONFIG = load_agent_config(
|
||||
default_prompt="Ти — Гордон Сенпай (Gordon Senpai), радник з ринків капіталу та цифрових активів. Допомагаєш з трейдингом, ризик-менеджментом, аналізом ринків.",
|
||||
)
|
||||
|
||||
# 1OK Configuration
|
||||
ONEOK_CONFIG = load_agent_config(
|
||||
agent_id="oneok",
|
||||
name=os.getenv("ONEOK_NAME", "1OK"),
|
||||
prompt_path=os.getenv(
|
||||
"ONEOK_PROMPT_PATH",
|
||||
str(Path(__file__).parent / "oneok_prompt.txt"),
|
||||
),
|
||||
telegram_token_env="ONEOK_TELEGRAM_BOT_TOKEN",
|
||||
default_prompt="Ти — 1OK, асистент віконного майстра. Допомагаєш з кваліфікацією ліда, підготовкою заміру та формуванням комерційної пропозиції.",
|
||||
)
|
||||
|
||||
# SOUL / Athena Configuration
|
||||
SOUL_CONFIG = load_agent_config(
|
||||
agent_id="soul",
|
||||
@@ -517,6 +529,7 @@ AGENT_REGISTRY: Dict[str, AgentConfig] = {
|
||||
"clan": CLAN_CONFIG,
|
||||
"eonarch": EONARCH_CONFIG,
|
||||
"senpai": SENPAI_CONFIG,
|
||||
"oneok": ONEOK_CONFIG,
|
||||
"soul": SOUL_CONFIG,
|
||||
"yaromir": YAROMIR_CONFIG,
|
||||
"sofiia": SOFIIA_CONFIG,
|
||||
@@ -707,6 +720,11 @@ async def eonarch_telegram_webhook(update: TelegramUpdate):
|
||||
async def senpai_telegram_webhook(update: TelegramUpdate):
|
||||
return await handle_telegram_webhook(SENPAI_CONFIG, update)
|
||||
|
||||
# 1OK webhook endpoint
|
||||
@router.post("/oneok/telegram/webhook")
|
||||
async def oneok_telegram_webhook(update: TelegramUpdate):
|
||||
return await handle_telegram_webhook(ONEOK_CONFIG, update)
|
||||
|
||||
|
||||
# SOUL / Athena webhook endpoint
|
||||
@router.post("/soul/telegram/webhook")
|
||||
@@ -897,50 +915,6 @@ def _resolve_stt_upload_url() -> str:
|
||||
# Helper Functions
|
||||
# ========================================
|
||||
|
||||
async def send_telegram_message(chat_id: str, text: str, bot_token: Optional[str] = None) -> bool:
|
||||
"""
|
||||
Відправити повідомлення в Telegram.
|
||||
|
||||
Args:
|
||||
chat_id: ID чату
|
||||
text: Текст повідомлення
|
||||
bot_token: Telegram bot token (якщо None, використовується TELEGRAM_BOT_TOKEN)
|
||||
|
||||
Returns:
|
||||
True якщо успішно, False інакше
|
||||
"""
|
||||
try:
|
||||
token = bot_token or os.getenv("TELEGRAM_BOT_TOKEN")
|
||||
if not token:
|
||||
logger.error("TELEGRAM_BOT_TOKEN not set")
|
||||
return False
|
||||
|
||||
# Strip <think>...</think> tags (DeepSeek reasoning leak)
|
||||
import re
|
||||
text = re.sub(r'<think>.*?</think>', '', text, flags=re.DOTALL)
|
||||
text = re.sub(r'<think>.*$', '', text, flags=re.DOTALL) # unclosed tag
|
||||
# Strip any DSML/XML-like markup
|
||||
text = re.sub(r'</?(?:function_calls|invoke|parameter)[^>]*>', '', text)
|
||||
text = text.strip()
|
||||
if not text:
|
||||
text = "..."
|
||||
|
||||
url = f"https://api.telegram.org/bot{token}/sendMessage"
|
||||
payload = {
|
||||
"chat_id": chat_id,
|
||||
"text": text,
|
||||
"parse_mode": "Markdown"
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.post(url, json=payload, timeout=10.0)
|
||||
response.raise_for_status()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to send Telegram message: {e}")
|
||||
return False
|
||||
|
||||
|
||||
async def get_telegram_file_path(file_id: str, bot_token: Optional[str] = None) -> Optional[str]:
|
||||
"""
|
||||
Отримати шлях до файлу з Telegram API.
|
||||
@@ -2491,7 +2465,11 @@ async def handle_telegram_webhook(
|
||||
+ "\n(Не потрібно щоразу представлятися по імені або писати шаблонне: 'чим можу допомогти'.)"
|
||||
)
|
||||
|
||||
if needs_complex_reasoning:
|
||||
# Helion policy: DeepSeek-first primary response path.
|
||||
if agent_config.agent_id == "helion":
|
||||
router_request["metadata"]["provider"] = "cloud_deepseek"
|
||||
router_request["metadata"]["reason"] = "helion_primary_deepseek"
|
||||
elif needs_complex_reasoning:
|
||||
router_request["metadata"]["provider"] = "cloud_deepseek"
|
||||
router_request["metadata"]["reason"] = "auto_complex"
|
||||
|
||||
@@ -3546,27 +3524,52 @@ async def _artifact_job_done(job_id: str, note: str) -> None:
|
||||
raise HTTPException(status_code=502, detail=f"Job done error: {resp.text[:200]}")
|
||||
|
||||
|
||||
async def send_telegram_message(chat_id: str, text: str, bot_token: str = None):
|
||||
"""Send message to Telegram chat"""
|
||||
async def send_telegram_message(chat_id: str, text: str, bot_token: Optional[str] = None) -> bool:
|
||||
"""Send message to Telegram chat with explicit error diagnostics."""
|
||||
telegram_token = bot_token or os.getenv("TELEGRAM_BOT_TOKEN")
|
||||
if not telegram_token:
|
||||
logger.error("TELEGRAM_BOT_TOKEN not set")
|
||||
return
|
||||
|
||||
return False
|
||||
|
||||
# Defensive cleanup for occasional reasoning/markup leaks.
|
||||
import re
|
||||
safe_text = re.sub(r'<think>.*?</think>', '', text or "", flags=re.DOTALL)
|
||||
safe_text = re.sub(r'<think>.*$', '', safe_text, flags=re.DOTALL)
|
||||
safe_text = safe_text.strip() or "..."
|
||||
|
||||
token_id = telegram_token.split(":", 1)[0] if ":" in telegram_token else "unknown"
|
||||
url = f"https://api.telegram.org/bot{telegram_token}/sendMessage"
|
||||
payload = {
|
||||
"chat_id": chat_id,
|
||||
"text": text,
|
||||
# "parse_mode": "Markdown", # Removed to prevent 400 errors
|
||||
"chat_id": str(chat_id),
|
||||
"text": safe_text,
|
||||
"disable_web_page_preview": True,
|
||||
}
|
||||
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.post(url, json=payload, timeout=10.0)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Telegram message sent to chat {chat_id}")
|
||||
response = await client.post(url, json=payload, timeout=15.0)
|
||||
|
||||
if response.status_code >= 400:
|
||||
err_desc = response.text[:300]
|
||||
try:
|
||||
body = response.json()
|
||||
err_desc = body.get("description") or err_desc
|
||||
except Exception:
|
||||
pass
|
||||
logger.error(
|
||||
"Telegram sendMessage failed: bot_id=%s chat_id=%s status=%s desc=%s",
|
||||
token_id,
|
||||
chat_id,
|
||||
response.status_code,
|
||||
err_desc,
|
||||
)
|
||||
return False
|
||||
|
||||
logger.info("Telegram message sent: bot_id=%s chat_id=%s", token_id, chat_id)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending Telegram message: {e}")
|
||||
logger.error("Telegram sendMessage exception: bot_id=%s chat_id=%s error=%s", token_id, chat_id, e)
|
||||
return False
|
||||
|
||||
|
||||
# ========================================
|
||||
|
||||
@@ -25,6 +25,7 @@ GATEWAY_MAX_TOKENS_CONCISE = int(os.getenv("GATEWAY_MAX_TOKENS_CONCISE", "220"))
|
||||
GATEWAY_MAX_TOKENS_TRAINING = int(os.getenv("GATEWAY_MAX_TOKENS_TRAINING", "900"))
|
||||
GATEWAY_TEMPERATURE_DEFAULT = float(os.getenv("GATEWAY_TEMPERATURE_DEFAULT", "0.4"))
|
||||
GATEWAY_MAX_TOKENS_SENPAI_DEFAULT = int(os.getenv("GATEWAY_MAX_TOKENS_SENPAI_DEFAULT", "320"))
|
||||
GATEWAY_MAX_TOKENS_HELION_DEFAULT = int(os.getenv("GATEWAY_MAX_TOKENS_HELION_DEFAULT", "240"))
|
||||
GATEWAY_MAX_TOKENS_DETAILED = int(os.getenv("GATEWAY_MAX_TOKENS_DETAILED", "900"))
|
||||
|
||||
|
||||
@@ -87,6 +88,8 @@ async def send_to_router(body: Dict[str, Any]) -> Dict[str, Any]:
|
||||
# Senpai tends to over-verbose responses in Telegram; use lower default unless user asked details.
|
||||
if agent_id == "senpai":
|
||||
max_tokens = GATEWAY_MAX_TOKENS_SENPAI_DEFAULT
|
||||
elif agent_id == "helion":
|
||||
max_tokens = min(max_tokens, GATEWAY_MAX_TOKENS_HELION_DEFAULT)
|
||||
|
||||
if metadata.get("is_training_group"):
|
||||
max_tokens = GATEWAY_MAX_TOKENS_TRAINING
|
||||
|
||||
Reference in New Issue
Block a user