diff --git a/backend/main/xiaozhi-server/core/providers/llm/antaf/__init__.py b/backend/main/xiaozhi-server/core/providers/llm/antaf/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/main/xiaozhi-server/core/providers/llm/antaf/antaf.py b/backend/main/xiaozhi-server/core/providers/llm/antaf/antaf.py new file mode 100644 index 0000000..bb13fdc --- /dev/null +++ b/backend/main/xiaozhi-server/core/providers/llm/antaf/antaf.py @@ -0,0 +1,66 @@ +import requests +from config.logger import setup_logging +from core.providers.llm.base import LLMProviderBase + +TAG = __name__ +logger = setup_logging() + + +class LLMProvider(LLMProviderBase): + """ + 蚂蚁阿福 LLM Provider + 通过 Frida HTTP Bridge (port 18900) 对接蚂蚁阿福 App 的文字对话 API。 + Bridge 运行在手机上,通过 adb forward 或网络暴露 SSE 流式接口。 + """ + + def __init__(self, config): + self.bridge_url = config.get("bridge_url", "http://127.0.0.1:18900") + self.timeout = config.get("timeout", 60) + logger.bind(tag=TAG).info( + f"AntafLLM 初始化: bridge={self.bridge_url}, timeout={self.timeout}s" + ) + + def response(self, session_id, dialogue, **kwargs): + # 提取最后一条用户消息 + query = "" + for msg in reversed(dialogue): + if msg.get("role") == "user": + query = msg.get("content", "") + break + + if not query: + logger.bind(tag=TAG).warning("对话中没有用户消息") + yield "抱歉,我没有收到您的问题。" + return + + logger.bind(tag=TAG).info(f"AntafLLM 请求: {query[:50]}...") + + try: + url = f"{self.bridge_url}/chat" + resp = requests.get( + url, + params={"q": query}, + stream=True, + timeout=self.timeout, + ) + resp.encoding = "utf-8" + + for line in resp.iter_lines(decode_unicode=True): + if not line: + continue + if line.startswith("data: "): + data = line[6:] + if data == "[DONE]": + break + if data and len(data.strip()) > 0: + yield data + + except requests.exceptions.ConnectionError: + logger.bind(tag=TAG).error("无法连接蚂蚁阿福 Bridge,请检查手机和 Frida 状态") + yield "抱歉,蚂蚁阿福服务暂时不可用。" + except requests.exceptions.Timeout: + logger.bind(tag=TAG).error(f"蚂蚁阿福 Bridge 超时 ({self.timeout}s)") + yield "抱歉,回答超时了。" + except Exception as e: + logger.bind(tag=TAG).error(f"AntafLLM 异常: {e}") + yield "抱歉,发生了错误。"