import json import logging import urllib.error import urllib.request from pr.config import DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE from pr.core.context import auto_slim_messages logger = logging.getLogger("pr") def call_api( messages, model, api_url, api_key, use_tools, tools_definition, verbose=False ): try: messages = auto_slim_messages(messages, verbose=verbose) logger.debug(f"=== API CALL START ===") logger.debug(f"Model: {model}") logger.debug(f"API URL: {api_url}") logger.debug(f"Use tools: {use_tools}") logger.debug(f"Message count: {len(messages)}") headers = { "Content-Type": "application/json", } if api_key: headers["Authorization"] = f"Bearer {api_key}" data = { "model": model, "messages": messages, "temperature": DEFAULT_TEMPERATURE, "max_tokens": DEFAULT_MAX_TOKENS, } if "gpt-5" in model: del data["temperature"] del data["max_tokens"] logger.debug("GPT-5 detected: removed temperature and max_tokens") if use_tools: data["tools"] = tools_definition data["tool_choice"] = "auto" logger.debug(f"Tool calling enabled with {len(tools_definition)} tools") request_json = json.dumps(data) logger.debug(f"Request payload size: {len(request_json)} bytes") req = urllib.request.Request( api_url, data=request_json.encode("utf-8"), headers=headers, method="POST" ) logger.debug("Sending HTTP request...") with urllib.request.urlopen(req) as response: response_data = response.read().decode("utf-8") logger.debug(f"Response received: {len(response_data)} bytes") result = json.loads(response_data) if "usage" in result: logger.debug(f"Token usage: {result['usage']}") if "choices" in result and result["choices"]: choice = result["choices"][0] if "message" in choice: msg = choice["message"] logger.debug(f"Response role: {msg.get('role', 'N/A')}") if "content" in msg and msg["content"]: logger.debug( f"Response content length: {len(msg['content'])} chars" ) if "tool_calls" in msg: logger.debug( f"Response contains {len(msg['tool_calls'])} tool call(s)" ) logger.debug("=== API CALL END ===") return result except urllib.error.HTTPError as e: error_body = e.read().decode("utf-8") logger.error(f"API HTTP Error: {e.code} - {error_body}") logger.debug("=== API CALL FAILED ===") return {"error": f"API Error: {e.code}", "message": error_body} except Exception as e: logger.error(f"API call failed: {e}") logger.debug("=== API CALL FAILED ===") return {"error": str(e)} def list_models(model_list_url, api_key): try: req = urllib.request.Request(model_list_url) if api_key: req.add_header("Authorization", f"Bearer {api_key}") with urllib.request.urlopen(req) as response: data = json.loads(response.read().decode("utf-8")) return data.get("data", []) except Exception as e: return {"error": str(e)}