"""HTTP chat proxy helpers for opt-in Telegram agent routing.""" from __future__ import annotations from typing import Any def build_chat_proxy_payload( *, message: str, source: str, agent: str, chat_id: int | None = None, message_id: int | None = None, username: str | None = None, ) -> dict[str, Any]: """Build the no-secret payload sent from Telegram to an agent HTTP chat route.""" metadata = { "source": source, "agent": agent, "chat_id": chat_id, "message_id": message_id, "username": username, } return { "message": message, "metadata": {k: v for k, v in metadata.items() if v is not None}, } def extract_chat_proxy_reply(payload: dict[str, Any]) -> str | None: """Extract a reply from supported Living IP Leo chat response shapes.""" if not isinstance(payload, dict): return None direct_reply = payload.get("reply") if isinstance(direct_reply, str) and direct_reply.strip(): return direct_reply.strip() decision = payload.get("decision") if isinstance(decision, dict): decision_reply = decision.get("reply") if isinstance(decision_reply, str) and decision_reply.strip(): return decision_reply.strip() llm = payload.get("llm") if isinstance(llm, dict): llm_reply = llm.get("reply") if isinstance(llm_reply, str) and llm_reply.strip(): return llm_reply.strip() llm_decision = llm.get("decision") if isinstance(llm_decision, dict): llm_decision_reply = llm_decision.get("reply") if isinstance(llm_decision_reply, str) and llm_decision_reply.strip(): return llm_decision_reply.strip() return None async def post_chat_proxy( *, url: str, payload: dict[str, Any], timeout_seconds: int = 30, ) -> tuple[int, dict[str, Any], str | None]: """POST to an agent HTTP chat route and return status, JSON body, and reply.""" import aiohttp async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=timeout_seconds)) as session: async with session.post( url, json=payload, headers={ "Accept": "application/json", "Content-Type": "application/json", "X-LivingIP-Source": "telegram-agent-proxy", }, ) as resp: data = await resp.json(content_type=None) return resp.status, data, extract_chat_proxy_reply(data)