import json import urllib.request import urllib.error import logging from pr.config import DEFAULT_TEMPERATURE, DEFAULT_MAX_TOKENS 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)}