feat: initial XCClaw基础架构
- 基于 FastAPI 的 Web API 服务 - OpenCode API 客户端封装 - 会话管理器(同步/异步任务执行) - APScheduler 定时任务调度 - 完整的 REST API 端点
This commit is contained in:
88
app/services/opencode_client.py
Normal file
88
app/services/opencode_client.py
Normal file
@@ -0,0 +1,88 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user