"""HTTP client for the Nous inference chat completions API.""" from __future__ import annotations import os import httpx _DEFAULT_UA = "osint-dashboard-news-summarizer" _DEFAULT_BASE = "https://inference-api.nousresearch.com/v1" _JSON_SYSTEM = ( "You are an OSINT executive briefer. Reply with a single complete JSON object. " "Never truncate mid-sentence. If you run out of room, drop the lowest-priority item." ) def chat(prompt, *, api_key, model, base_url, json_mode=False) -> str: resolved = (base_url or os.environ.get("NOUS_BASE_URL", _DEFAULT_BASE)).rstrip("/") url = f"{resolved}/chat/completions" headers = { "Authorization": f"Bearer {api_key}", "User-Agent": os.environ.get("OSINT_USER_AGENT") or _DEFAULT_UA, } max_tokens = 8192 if json_mode else 4096 timeout = 120.0 if json_mode else 60.0 messages = [{"role": "user", "content": prompt}] if json_mode: messages = [ {"role": "system", "content": _JSON_SYSTEM}, {"role": "user", "content": prompt}, ] payload = { "model": model, "messages": messages, "temperature": 0.2, "max_tokens": max_tokens, } if json_mode: payload["response_format"] = {"type": "json_object"} last_content = "" try: for attempt in range(2): with httpx.Client(timeout=timeout) as client: resp = client.post(url, headers=headers, json=payload) if resp.status_code == 401 or resp.status_code >= 500: return "" data = resp.json() choice = (data.get("choices") or [{}])[0] last_content = (choice.get("message") or {}).get("content") or "" finish = choice.get("finish_reason") if finish == "length" and attempt == 0: payload["max_tokens"] = min(int(payload["max_tokens"]) * 2, 16384) continue return last_content return last_content except Exception: return ""