This commit is contained in:
2026-04-21 23:38:29 +08:00
commit d5444cdb35
15 changed files with 1236 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
import asyncio
import base64
from typing import Callable
from openai import AsyncOpenAI
from .config import AICfg
class AIClient:
def __init__(self, cfg: AICfg):
kwargs: dict = {"api_key": cfg.api_key or "sk-no-key"}
if cfg.base_url:
kwargs["base_url"] = cfg.base_url
self._client = AsyncOpenAI(**kwargs)
self._cfg = cfg
async def analyze(self, image_path: str, on_chunk: Callable[[str], None]) -> None:
with open(image_path, "rb") as f:
img_b64 = base64.b64encode(f.read()).decode()
data_url = f"data:image/png;base64,{img_b64}"
stream = await self._client.chat.completions.create(
model=self._cfg.model,
max_tokens=self._cfg.max_tokens,
stream=True,
messages=[
{"role": "system", "content": self._cfg.system_prompt},
{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": data_url}},
{"type": "text", "text": "请分析截图中的题目,给出答案和解析。"},
],
},
],
)
async for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
on_chunk(delta)
def analyze_sync(self, image_path: str, on_chunk: Callable[[str], None]) -> None:
asyncio.run(self.analyze(image_path, on_chunk))