PinkSky / server /mode_handlers.py
FreshPixels's picture
Update server/mode_handlers.py
e86a0e6 verified
Raw
History Blame Contribute Delete
5.68 kB
"""ะžะฑั€ะฐะฑะพั‚ั‡ะธะบะธ ั€ะตะถะธะผะพะฒ: Chat, Skill, Build"""
import threading
import logging
from datetime import datetime
from typing import Dict, Any
from .state import STATE
from .config import API_KEY, API_BASE
from .universal_agent import UniversalAgent
from .conductor_engine import ConductorEngine
from .skill_orchestrator import SkillOrchestrator
from .process_manager import PROCESS_MANAGER
from .notification_system import NOTIFICATIONS
from .helpers import parse_skill_args, build_skill_prompt, parse_build_args
from .telegram_utils import send_tg
from . import INTERNET_AGENT
from .interpreter_config import configure_interpreter_for_model
class RateLimiter:
def __init__(self):
self.user_requests = {}
self.max_requests = 5
self.time_window = 10 # seconds
self.logger = logging.getLogger(__name__)
def check_rate_limit(self, chat_id: str) -> bool:
now = datetime.now().timestamp()
requests = self.user_requests.get(chat_id, [])
# Remove old requests
requests = [t for t in requests if now - t < self.time_window]
if len(requests) >= self._get_limit(chat_id):
self.logger.warning(f"Rate limit exceeded for chat_id {chat_id}")
return False
requests.append(now)
self.user_requests[chat_id] = requests
return True
def _get_limit(self, chat_id: str) -> int:
# Allow higher limits for admin or premium users if needed
return self.max_requests
rate_limiter = RateLimiter()
logger = logging.getLogger(__name__)
def configure_interpreter_for_model(model_name: str):
"""Deprecated: Use from interpreter_config.py instead."""
return configure_interpreter_for_model(model_name, STATE, API_KEY, API_BASE)
def run_chat_mode(chat_id: str, text: str, file_context: str = "") -> str:
if not rate_limiter.check_rate_limit(chat_id):
send_tg(chat_id, "โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ\n โ”‚ โš ๏ธ ส€แด€แด›แด‡ สŸษชแดษชแด› โ”‚\n โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค\n โ”‚ Try again later โ˜• โ”‚\nโ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ")
return "Rate limited"
def chat_task():
STATE.cancel_flag = False
STATE.current_mode = "chat"
send_tg(
chat_id,
"โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ\n"
" โ”‚ ๐Ÿง  แด„แดษดแด…แดœแด„แด›แดส€ แด€แด„แด›ษชแด แด‡ โ”‚\n"
"โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค\n"
" โ”‚ Analyzing request โ”‚\n"
"โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ"
)
try:
conductor_engine = ConductorEngine(STATE)
result = conductor_engine.orchestrate(text + file_context, chat_id=chat_id)
if not STATE.cancel_flag:
send_tg(chat_id, result)
STATE.add_to_history("chat", "assistant", result)
except Exception as e:
if not STATE.cancel_flag:
send_tg(chat_id, f"โ–ธ โš ๏ธ แด„สœแด€แด› แด‡ส€ส€แดส€\n{str(e)[:500]}")
logger.error(f"Chat mode error for {chat_id}: {e}", exc_info=True)
t = threading.Thread(target=chat_task)
PROCESS_MANAGER.register_thread(t)
t.start()
return "โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ\n โ”‚ โ˜• แด„สœแด€แด› แดแดแด…แด‡ sแด›แด€ส€แด›แด‡แด… โ”‚\nโ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ"
def run_skill_mode(chat_id: str, text: str, file_context: str = "") -> str:
if not rate_limiter.check_rate_limit(chat_id):
send_tg(chat_id, "โ–ธ โš ๏ธ ส€แด€แด›แด‡ สŸษชแดษชแด›\nTry again later.")
return "Rate limited"
params, clean_text = parse_skill_args(text)
agents = params.get("agents", [])
use_internet = params.get("internet", False)
def skill_task():
STATE.cancel_flag = False
STATE.current_mode = "skill"
send_tg(
chat_id,
"โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ\n"
" โ”‚ ๐Ÿค– sแด‹ษชสŸสŸ แดแดแด…แด‡ โ”‚\n"
"โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค\n"
" โ”‚ Agents activated โ”‚\n"
"โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ"
)
if use_internet:
search_results = INTERNET_AGENT.search_web(clean_text[:200])
if search_results:
web_context = "\n\n๐ŸŒ ษชษดแด›แด‡ส€ษดแด‡แด› ส€แด‡sแดœสŸแด›s๏ผˆ๏ฝกโ—•โ€ฟโ—•๏ฝก๏ผ‰\n" + "\n".join(
f"โ–น {r['title'][:50]}... โ†’ {r['snippet'][:100]}..."
for r in search_results[:3]
)
file_context += web_context
try:
orchestrator = SkillOrchestrator(STATE)
result = orchestrator.execute_with_agents(chat_id, clean_text, file_context, agents)
if not STATE.cancel_flag:
send_tg(chat_id, result)
STATE.add_to_history("skill", "assistant", result)
except Exception as e:
if not STATE.cancel_flag:
send_tg(chat_id, f"โ–ธ โš ๏ธ sแด‹ษชสŸสŸ แด‡ส€ส€แดส€\n{str(e)[:500]}")
logger.error(f"Skill mode error for {chat_id}: {e}", exc_info=True)
t = threading.Thread(target=skill_task)
PROCESS_MANAGER.register_thread(t)
t.start()
return "โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ\n โ”‚ ๐Ÿงฉ sแด‹ษชสŸสŸ แดแดแด…แด‡ sแด›แด€ส€แด›แด‡แด… โ”‚\nโ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ"