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)}