修复ai
This commit is contained in:
+34
-14
@@ -55,10 +55,24 @@ def _use_openai() -> bool:
|
||||
return _ai_provider() in ("openai", "openai_compatible", "gateway")
|
||||
|
||||
|
||||
def _read_image_base64(image_path: str) -> Optional[str]:
|
||||
def _image_mime_for_path(path: str) -> str:
|
||||
ext = os.path.splitext(str(path or ""))[1].lower()
|
||||
if ext == ".png":
|
||||
return "image/png"
|
||||
if ext in (".jpg", ".jpeg"):
|
||||
return "image/jpeg"
|
||||
if ext == ".webp":
|
||||
return "image/webp"
|
||||
if ext == ".gif":
|
||||
return "image/gif"
|
||||
return "image/jpeg"
|
||||
|
||||
|
||||
def _read_image_base64(image_path: str) -> Optional[tuple]:
|
||||
try:
|
||||
with open(image_path, "rb") as f:
|
||||
return base64.b64encode(f.read()).decode("utf-8")
|
||||
b64 = base64.b64encode(f.read()).decode("utf-8")
|
||||
return b64, _image_mime_for_path(image_path)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
@@ -66,15 +80,15 @@ def _read_image_base64(image_path: str) -> Optional[str]:
|
||||
def _collect_images(
|
||||
image_paths: Optional[Sequence[str]] = None,
|
||||
images_b64: Optional[Sequence[str]] = None,
|
||||
) -> List[str]:
|
||||
out: List[str] = []
|
||||
) -> List[tuple]:
|
||||
out: List[tuple] = []
|
||||
for p in image_paths or []:
|
||||
b = _read_image_base64(p)
|
||||
if b:
|
||||
out.append(b)
|
||||
item = _read_image_base64(p)
|
||||
if item:
|
||||
out.append(item)
|
||||
for b in images_b64 or []:
|
||||
if b:
|
||||
out.append(str(b))
|
||||
out.append((str(b), "image/jpeg"))
|
||||
return out
|
||||
|
||||
|
||||
@@ -85,7 +99,7 @@ def _openai_chat_url() -> str:
|
||||
return f"{base}/chat/completions"
|
||||
|
||||
|
||||
def _generate_openai(prompt: str, images: List[str], temperature: float) -> str:
|
||||
def _generate_openai(prompt: str, images: List[tuple], temperature: float) -> str:
|
||||
api_key = _openai_api_key()
|
||||
if not api_key:
|
||||
return "AI 调用失败:未配置 OPENAI_API_KEY(请在当前实例目录 .env 中设置,修改后需重启服务)"
|
||||
@@ -95,11 +109,11 @@ def _generate_openai(prompt: str, images: List[str], temperature: float) -> str:
|
||||
}
|
||||
if images:
|
||||
content: List[dict] = [{"type": "text", "text": prompt}]
|
||||
for b64 in images:
|
||||
for b64, mime in images:
|
||||
content.append(
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {"url": f"data:image/jpeg;base64,{b64}"},
|
||||
"image_url": {"url": f"data:{mime};base64,{b64}"},
|
||||
}
|
||||
)
|
||||
messages = [{"role": "user", "content": content}]
|
||||
@@ -126,7 +140,7 @@ def _generate_openai(prompt: str, images: List[str], temperature: float) -> str:
|
||||
return (msg.get("content") or "").strip() or "AI 生成失败:空内容"
|
||||
|
||||
|
||||
def _generate_ollama(prompt: str, images: List[str], temperature: float) -> str:
|
||||
def _generate_ollama(prompt: str, images: List[tuple], temperature: float) -> str:
|
||||
payload = {
|
||||
"model": _ollama_model(),
|
||||
"prompt": prompt,
|
||||
@@ -134,7 +148,7 @@ def _generate_ollama(prompt: str, images: List[str], temperature: float) -> str:
|
||||
"options": {"temperature": temperature},
|
||||
}
|
||||
if images:
|
||||
payload["images"] = images
|
||||
payload["images"] = [b64 for b64, _mime in images]
|
||||
r = requests.post(_ollama_api(), json=payload, timeout=_ai_timeout_seconds())
|
||||
r.raise_for_status()
|
||||
return (r.json().get("response") or "").strip() or "AI 生成失败"
|
||||
@@ -167,6 +181,12 @@ def ai_generate(
|
||||
|
||||
|
||||
def ai_review(trades_text: str, period_title: str, image_paths=None) -> str:
|
||||
n_img = len(image_paths or [])
|
||||
attach_note = (
|
||||
f"【系统说明:已向模型附带 {n_img} 张复盘附图(自动K线或上传截图),请结合附图分析第5节。】\n\n"
|
||||
if n_img
|
||||
else "【系统说明:本次未附带复盘附图,第5节请写明「无附图,无法看图」;保存复盘记录时可勾选「自动生成K线图」。】\n\n"
|
||||
)
|
||||
prompt = f"""
|
||||
你是一位专业交易教练。下面是用户的{period_title}交易记录,请做简洁、可执行的复盘(中文)。
|
||||
|
||||
@@ -188,7 +208,7 @@ def ai_review(trades_text: str, period_title: str, image_paths=None) -> str:
|
||||
交易记录:
|
||||
{trades_text}
|
||||
""".strip()
|
||||
return ai_generate(prompt, image_paths=image_paths, temperature=0.2)
|
||||
return attach_note + ai_generate(prompt, image_paths=image_paths, temperature=0.2)
|
||||
|
||||
|
||||
def ai_short_advice(prompt_text: str) -> str:
|
||||
|
||||
Reference in New Issue
Block a user