feat: rebuild as multi-user web agent

This commit is contained in:
wuyang
2026-07-26 06:52:12 +08:00
parent 45792c8fd5
commit 37f83eaac7
634 changed files with 5060 additions and 139619 deletions
+77
View File
@@ -0,0 +1,77 @@
from __future__ import annotations
from typing import Any
import httpx
from agent_platform.config import Settings
def completions_url(base_url: str) -> str:
base = base_url.rstrip("/")
if base.endswith("/v1"):
return f"{base}/chat/completions"
return f"{base}/v1/chat/completions"
class ModelProvider:
def __init__(self, settings: Settings, client: httpx.AsyncClient | None = None) -> None:
self.settings = settings
self.client = client or httpx.AsyncClient(
timeout=httpx.Timeout(settings.model_timeout_seconds),
limits=httpx.Limits(max_connections=50, max_keepalive_connections=20),
)
self._owns_client = client is None
@property
def headers(self) -> dict[str, str]:
return {
"Authorization": f"Bearer {self.settings.model_api_key}",
"Content-Type": "application/json",
}
async def close(self) -> None:
if self._owns_client:
await self.client.aclose()
async def complete(
self,
*,
model: str,
messages: list[dict[str, Any]],
tools: list[dict[str, Any]] | None = None,
temperature: float | None = None,
) -> dict[str, Any]:
payload: dict[str, Any] = {
"model": model,
"messages": messages,
"stream": False,
}
if tools:
payload["tools"] = tools
payload["tool_choice"] = "auto"
if temperature is not None:
payload["temperature"] = temperature
response = await self.client.post(
completions_url(self.settings.model_api_base_url),
headers=self.headers,
json=payload,
)
response.raise_for_status()
data = response.json()
if not data.get("choices"):
raise RuntimeError("Model provider returned no choices")
return data
async def forward(self, payload: dict[str, Any]) -> httpx.Response:
request = self.client.build_request(
"POST",
completions_url(self.settings.model_api_base_url),
headers=self.headers,
json=payload,
)
response = await self.client.send(request, stream=bool(payload.get("stream")))
if response.status_code >= 400:
await response.aread()
response.raise_for_status()
return response