"""Bounded, non-redirecting HTTP. No SDK retries or environment credential discovery.""" import asyncio import math import aiohttp from ..protocol import DecisionError, loads async def post(session, connection, path, payload): try: async with session.post( connection.base_url + path, json=payload, headers={"Authorization": "Bearer " + connection.key}, allow_redirects=False, timeout=aiohttp.ClientTimeout(total=45), ) as response: if response.status != 200: raise DecisionError(f"upstream_http_{response.status}", 502) # read(n) may return a partial chunk: accumulate with an explicit byte bound. data = bytearray() async for chunk in response.content.iter_chunked(16384): data.extend(chunk) if len(data) > 262144: raise DecisionError("upstream_response_too_large", 502) try: result = loads(data.decode("utf-8")) except UnicodeError as exc: raise DecisionError("invalid_upstream_encoding", 502) from exc if not isinstance(result, dict): raise DecisionError("invalid_upstream_response", 502) return result except TimeoutError as exc: raise DecisionError("upstream_timeout", 504) from exc except (aiohttp.ClientError, OSError) as exc: raise DecisionError("upstream_transport_error", 502) from exc except asyncio.CancelledError: raise def usage(result): """Only real numeric counters, no inferred price, upstream strings or raw body.""" raw = result.get("usage", {}) if not isinstance(raw, dict): return {} return { k: v for k, v in raw.items() if k in ( "input_tokens", "output_tokens", "total_tokens", "prompt_tokens", "completion_tokens", "cost", ) and type(v) in (int, float) and math.isfinite(v) and 0 <= v <= 1e9 }