refactor: switch from async to sync http client

feat: bump version to 1.13.0
docs: update changelog with release notes
This commit is contained in:
retoor 2025-11-07 18:17:58 +01:00
parent a2468b7d5b
commit 6509ccc5d3
3 changed files with 30 additions and 27 deletions

View File

@ -9,6 +9,14 @@
## Version 1.12.0 - 2025-11-07
This release introduces new agent capabilities like communication, autonomous detection, and plugin support. Users can now interact with the agent in new ways and benefit from improved performance and more robust testing.
**Changes:** 4 files, 15 lines
**Languages:** Markdown (8 lines), Other (2 lines), Python (3 lines), TOML (2 lines)
## Version 1.11.0 - 2025-11-07
This release introduces agent communication, autonomous detection, and plugin support, enabling more complex and flexible workflows. Interactive modes and a new agent execution tool have also been added, alongside performance improvements and dependency updates.

View File

@ -1,4 +1,3 @@
import asyncio
import json
import logging
import socket
@ -10,11 +9,11 @@ from typing import Dict, Any, Optional
logger = logging.getLogger("pr")
class AsyncHTTPClient:
class SyncHTTPClient:
def __init__(self):
self.session_headers = {}
async def request(
def request(
self,
method: str,
url: str,
@ -23,9 +22,7 @@ class AsyncHTTPClient:
json_data: Optional[Dict[str, Any]] = None,
timeout: float = 30.0,
) -> Dict[str, Any]:
"""Make an async HTTP request using urllib in a thread executor with retry logic."""
loop = asyncio.get_event_loop()
"""Make a sync HTTP request using urllib with retry logic."""
# Prepare headers
request_headers = {**self.session_headers}
if headers:
@ -46,22 +43,20 @@ class AsyncHTTPClient:
while True:
attempt += 1
try:
# Execute in thread pool
response = await loop.run_in_executor(
None, lambda: urllib.request.urlopen(req, timeout=timeout)
)
response_data = await loop.run_in_executor(None, response.read)
response_text = response_data.decode("utf-8")
# Execute request
with urllib.request.urlopen(req, timeout=timeout) as response:
response_data = response.read()
response_text = response_data.decode("utf-8")
return {
"status": response.status,
"headers": dict(response.headers),
"text": response_text,
"json": lambda: json.loads(response_text) if response_text else None,
}
return {
"status": response.status,
"headers": dict(response.headers),
"text": response_text,
"json": lambda: json.loads(response_text) if response_text else None,
}
except urllib.error.HTTPError as e:
error_body = await loop.run_in_executor(None, e.read)
error_body = e.read()
error_text = error_body.decode("utf-8")
return {
"status": e.code,
@ -86,7 +81,7 @@ class AsyncHTTPClient:
)
# Exponential backoff starting at 1 second
await asyncio.sleep(attempt)
time.sleep(attempt)
except Exception as e:
error_msg = str(e)
# For other exceptions, check if they might be timeout-related
@ -106,17 +101,17 @@ class AsyncHTTPClient:
)
# Exponential backoff starting at 1 second
await asyncio.sleep(attempt)
time.sleep(attempt)
else:
# Non-timeout errors should not be retried
return {"error": True, "exception": error_msg}
async def get(
def get(
self, url: str, headers: Optional[Dict[str, str]] = None, timeout: float = 30.0
) -> Dict[str, Any]:
return await self.request("GET", url, headers=headers, timeout=timeout)
return self.request("GET", url, headers=headers, timeout=timeout)
async def post(
def post(
self,
url: str,
headers: Optional[Dict[str, str]] = None,
@ -124,7 +119,7 @@ class AsyncHTTPClient:
json_data: Optional[Dict[str, Any]] = None,
timeout: float = 30.0,
) -> Dict[str, Any]:
return await self.request(
return self.request(
"POST", url, headers=headers, data=data, json_data=json_data, timeout=timeout
)
@ -133,4 +128,4 @@ class AsyncHTTPClient:
# Global client instance
http_client = AsyncHTTPClient()
http_client = SyncHTTPClient()

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "rp"
version = "1.11.0"
version = "1.12.0"
description = "R python edition. The ultimate autonomous AI CLI."
readme = "README.md"
requires-python = ">=3.12"