diff --git a/oxygent/oxy/llms/http_llm.py b/oxygent/oxy/llms/http_llm.py index 4ed0ff8..e8aefce 100644 --- a/oxygent/oxy/llms/http_llm.py +++ b/oxygent/oxy/llms/http_llm.py @@ -13,6 +13,8 @@ from ...config import Config from ...schemas import OxyRequest, OxyResponse, OxyState from .remote_llm import RemoteLLM +from pydantic import Field +from typing import Callable logger = logging.getLogger(__name__) @@ -24,6 +26,26 @@ class HttpLLM(RemoteLLM): with remote LLM APIs over HTTP. It handles API authentication, request formatting, and response parsing for OpenAI-compatible APIs. """ + llm_request_modifier: Callable = Field( + lambda url, headers, payload: (url, headers, payload), exclude=True, description="Modifier function to modify request params before sending." + ) + + def _before_request_hook(self, url: str, headers: dict, payload: dict) -> tuple[str, dict, dict]: + """Hook function to modify request URL, headers, and payload before sending. + + This method can be overridden by subclasses or set dynamically to modify + the request parameters before sending to the LLM API. + + Args: + url: The request URL + headers: The request headers + payload: The request payload + + Returns: + Tuple of (modified_url, modified_headers, modified_payload) + """ + url, headers, payload = self.llm_request_modifier(url, headers, payload) + return url, headers, payload async def _execute(self, oxy_request: OxyRequest) -> OxyResponse: """Execute an HTTP request to the remote LLM API. @@ -103,6 +125,9 @@ async def _execute(self, oxy_request: OxyRequest) -> OxyResponse: if payload.get("stream", False) and (use_openai or not is_gemini): result_parts: list[str] = [] async with httpx.AsyncClient(timeout=None) as client: + # Apply before request hook + url, headers, payload = self._before_request_hook(url, headers, payload) + async with client.stream( "POST", url, headers=headers, json=payload ) as resp: @@ -144,6 +169,9 @@ async def _execute(self, oxy_request: OxyRequest) -> OxyResponse: return OxyResponse(state=OxyState.COMPLETED, output=result) async with httpx.AsyncClient(timeout=self.timeout) as client: + # Apply before request hook + url, headers, payload = self._before_request_hook(url, headers, payload) + http_response = await client.post(url, headers=headers, json=payload) http_response.raise_for_status() data = http_response.json()