89 lines
3.0 KiB
Python
89 lines
3.0 KiB
Python
|
|
from typing import Any
|
||
|
|
import httpx
|
||
|
|
from app.core.config import settings
|
||
|
|
from app.core.logging import logger
|
||
|
|
|
||
|
|
|
||
|
|
class OpenCodeClient:
|
||
|
|
def __init__(self):
|
||
|
|
self.base_url = f"http://{settings.opencode_host}:{settings.opencode_port}"
|
||
|
|
self._client: httpx.AsyncClient | None = None
|
||
|
|
|
||
|
|
async def _get_client(self) -> httpx.AsyncClient:
|
||
|
|
if self._client is None:
|
||
|
|
headers = {}
|
||
|
|
if settings.opencode_password:
|
||
|
|
headers["Authorization"] = f"Bearer {settings.opencode_password}"
|
||
|
|
self._client = httpx.AsyncClient(
|
||
|
|
base_url=self.base_url,
|
||
|
|
headers=headers,
|
||
|
|
timeout=300.0,
|
||
|
|
)
|
||
|
|
return self._client
|
||
|
|
|
||
|
|
async def close(self):
|
||
|
|
if self._client:
|
||
|
|
await self._client.aclose()
|
||
|
|
self._client = None
|
||
|
|
|
||
|
|
async def health_check(self) -> dict[str, Any]:
|
||
|
|
client = await self._get_client()
|
||
|
|
resp = await client.get("/global/health")
|
||
|
|
resp.raise_for_status()
|
||
|
|
return resp.json()
|
||
|
|
|
||
|
|
async def create_session(self, title: str | None = None, parent_id: str | None = None) -> dict[str, Any]:
|
||
|
|
client = await self._get_client()
|
||
|
|
payload = {}
|
||
|
|
if title:
|
||
|
|
payload["title"] = title
|
||
|
|
if parent_id:
|
||
|
|
payload["parentID"] = parent_id
|
||
|
|
resp = await client.post("/session", json=payload)
|
||
|
|
resp.raise_for_status()
|
||
|
|
return resp.json()
|
||
|
|
|
||
|
|
async def get_session(self, session_id: str) -> dict[str, Any]:
|
||
|
|
client = await self._get_client()
|
||
|
|
resp = await client.get(f"/session/{session_id}")
|
||
|
|
resp.raise_for_status()
|
||
|
|
return resp.json()
|
||
|
|
|
||
|
|
async def delete_session(self, session_id: str) -> bool:
|
||
|
|
client = await self._get_client()
|
||
|
|
resp = await client.delete(f"/session/{session_id}")
|
||
|
|
resp.raise_for_status()
|
||
|
|
return resp.json()
|
||
|
|
|
||
|
|
async def send_message(self, session_id: str, text: str) -> dict[str, Any]:
|
||
|
|
client = await self._get_client()
|
||
|
|
payload = {
|
||
|
|
"parts": [{"type": "text", "text": text}]
|
||
|
|
}
|
||
|
|
resp = await client.post(f"/session/{session_id}/message", json=payload)
|
||
|
|
resp.raise_for_status()
|
||
|
|
return resp.json()
|
||
|
|
|
||
|
|
async def send_message_async(self, session_id: str, text: str) -> None:
|
||
|
|
client = await self._get_client()
|
||
|
|
payload = {
|
||
|
|
"parts": [{"type": "text", "text": text}]
|
||
|
|
}
|
||
|
|
resp = await client.post(f"/session/{session_id}/prompt_async", json=payload)
|
||
|
|
resp.raise_for_status()
|
||
|
|
|
||
|
|
async def abort_session(self, session_id: str) -> bool:
|
||
|
|
client = await self._get_client()
|
||
|
|
resp = await client.post(f"/session/{session_id}/abort")
|
||
|
|
resp.raise_for_status()
|
||
|
|
return resp.json()
|
||
|
|
|
||
|
|
async def get_session_status(self) -> dict[str, Any]:
|
||
|
|
client = await self._get_client()
|
||
|
|
resp = await client.get("/session/status")
|
||
|
|
resp.raise_for_status()
|
||
|
|
return resp.json()
|
||
|
|
|
||
|
|
|
||
|
|
opencode_client = OpenCodeClient()
|