fix(wechat-bot): ①对话时间统一北京时间 ②媒体内联发送(微信直看图片/视频) ③媒体生成计入Token驾驶舱 ④清空技能市场
This commit is contained in:
1 parent
7739f17594
commit
da89a27bca
3 files changed
+166
-42
No files matched your search
@@ -14,7 +14,9 @@ IM Bot 真实 LLM 调用。
|
||||
"""
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import re as _re
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from typing import Optional
|
||||
from urllib.parse import urlparse as _urlparse
|
||||
|
||||
@@ -22,7 +24,9 @@ import httpx
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..capability_registry import resolve_auto_model
|
||||
from ..models import AIModel, ModelProvider
|
||||
from ..models import AIModel, ModelProvider, TokenUsageLog, gen_uuid
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# 香港出网代理(实测对 AGNES 延迟更低,2026-07-15 用户实测),与 chat.py 同值。
|
||||
@@ -65,7 +69,37 @@ def _run_async(coro):
|
||||
return asyncio.run(coro)
|
||||
|
||||
|
||||
def _call_real_llm(db: Session, user=None, prompt: str = "", platform: str = "im", user_id: str = None) -> str:
|
||||
def _log_media_usage(db: Session, user_id: str, ai_model, media_type: str, prompt: str):
|
||||
"""IM Bot 媒体生成记账:把图片/视频消耗写入 TokenUsageLog,供驾驶舱统计。
|
||||
|
||||
此前 IM Bot 路径完全不写 TokenUsageLog,导致微信生成的图片/视频在驾驶舱里“查无此项”。
|
||||
媒体 API 不返回 token 用量,这里用与 chat.py _generate_media_task 一致的估算。
|
||||
"""
|
||||
if not user_id or not ai_model:
|
||||
return
|
||||
try:
|
||||
base = 1200 if media_type == "video" else 400
|
||||
est = base + (len(prompt or "") // 4)
|
||||
db.add(TokenUsageLog(
|
||||
id=gen_uuid(),
|
||||
user_id=user_id,
|
||||
model_id=ai_model.id,
|
||||
model_name=ai_model.name,
|
||||
prompt_tokens=est,
|
||||
completion_tokens=0,
|
||||
total_tokens=est,
|
||||
created_at=datetime.now(timezone(timedelta(hours=8))).replace(tzinfo=None),
|
||||
))
|
||||
db.commit()
|
||||
except Exception as e:
|
||||
try:
|
||||
db.rollback()
|
||||
except Exception:
|
||||
pass
|
||||
logger.warning(f"[im_llm] 媒体 Token 记账失败(忽略): {e}")
|
||||
|
||||
|
||||
def _call_real_llm(db: Session, user=None, prompt: str = "", platform: str = "im", user_id: str = None) -> "str | dict":
|
||||
"""调用七虎AI 生成回复,供 IM Bot 复用。支持媒体意图路由与已安装技能自动发现。"""
|
||||
try:
|
||||
from app.api.chat import (
|
||||
@@ -88,19 +122,22 @@ def _call_real_llm(db: Session, user=None, prompt: str = "", platform: str = "im
|
||||
# 绝不直接把原始异常(如 "Server disconnected")甩给用户
|
||||
result = "⚠️ 媒体生成暂时失败(连接或服务波动),请稍后重试。"
|
||||
if result:
|
||||
# IM 不渲染 HTML,把 <img>/<video> 还原为纯文本链接返回
|
||||
# 媒体生成成功:返回结构化对象,交由 im_bot_user 在微信内联发送图片/视频
|
||||
s = result.strip()
|
||||
if s.startswith("<img") or s.startswith("<video"):
|
||||
m = _re.search(r'src="([^"]+)"', s)
|
||||
url = m.group(1) if m else ""
|
||||
label = "图片" if s.startswith("<img") else "视频"
|
||||
return f"已为你生成{label}:{url}" if url else "(生成完成,但未能提取媒体地址)"
|
||||
media_type = "image" if s.startswith("<img") else "video"
|
||||
if not url:
|
||||
return "(生成完成,但未能提取媒体地址)"
|
||||
# IM Bot 路径此前完全不记账 → 补写媒体消耗,驾驶舱才看得到图片/视频数据
|
||||
_log_media_usage(db, user_id, ai_model, media_type, prompt)
|
||||
return {"__media__": True, "media_type": media_type, "url": url}
|
||||
# 媒体生成失败:_generate_media 已返回友好中文(如限频/队列繁忙),
|
||||
# 直接透传,绝不把原始提示词/标签/JSON 透传给用户
|
||||
if s.startswith("⚠️") or s.startswith("(媒体"):
|
||||
return s
|
||||
return "(媒体生成未能返回有效内容,请重试)"
|
||||
return result
|
||||
|
||||
# ===== 2) 文本回复 + 技能自动发现(Issue 8)=====
|
||||
ai_model = resolve_auto_model("text", db)
|
||||
|
||||
Reference in new issue
Block a user