init
This commit is contained in:
@@ -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))
|
||||
Reference in New Issue
Block a user