import json
|
from config.logger import setup_logging
|
import requests
|
from core.providers.llm.base import LLMProviderBase
|
from core.providers.llm.system_prompt import get_system_prompt_for_function
|
from core.utils.util import check_model_key
|
|
TAG = __name__
|
logger = setup_logging()
|
|
|
class LLMProvider(LLMProviderBase):
|
def __init__(self, config):
|
self.api_key = config["api_key"]
|
self.mode = config.get("mode", "chat-messages")
|
self.base_url = config.get("base_url", "https://api.dify.ai/v1").rstrip("/")
|
self.session_conversation_map = {} # 存储session_id和conversation_id的映射
|
model_key_msg = check_model_key("DifyLLM", self.api_key)
|
if model_key_msg:
|
logger.bind(tag=TAG).error(model_key_msg)
|
|
def response(self, session_id, dialogue, **kwargs):
|
# 取最后一条用户消息
|
last_msg = next(m for m in reversed(dialogue) if m["role"] == "user")
|
conversation_id = self.session_conversation_map.get(session_id)
|
|
# 发起流式请求
|
if self.mode == "chat-messages":
|
request_json = {
|
"query": last_msg["content"],
|
"response_mode": "streaming",
|
"user": session_id,
|
"inputs": {},
|
"conversation_id": conversation_id,
|
}
|
elif self.mode == "workflows/run":
|
request_json = {
|
"inputs": {"query": last_msg["content"]},
|
"response_mode": "streaming",
|
"user": session_id,
|
}
|
elif self.mode == "completion-messages":
|
request_json = {
|
"inputs": {"query": last_msg["content"]},
|
"response_mode": "streaming",
|
"user": session_id,
|
}
|
|
with requests.post(
|
f"{self.base_url}/{self.mode}",
|
headers={"Authorization": f"Bearer {self.api_key}"},
|
json=request_json,
|
stream=True,
|
) as r:
|
if self.mode == "chat-messages":
|
for line in r.iter_lines():
|
if line.startswith(b"data: "):
|
event = json.loads(line[6:])
|
# 如果没有找到conversation_id,则获取此次conversation_id
|
if not conversation_id:
|
conversation_id = event.get("conversation_id")
|
self.session_conversation_map[session_id] = (
|
conversation_id # 更新映射
|
)
|
# 过滤 message_replace 事件,此事件会全量推一次
|
if event.get("event") != "message_replace" and event.get(
|
"answer"
|
):
|
yield event["answer"]
|
elif self.mode == "workflows/run":
|
for line in r.iter_lines():
|
if line.startswith(b"data: "):
|
event = json.loads(line[6:])
|
if event.get("event") == "workflow_finished":
|
if event["data"]["status"] == "succeeded":
|
yield event["data"]["outputs"]["answer"]
|
else:
|
yield "【服务响应异常】"
|
elif self.mode == "completion-messages":
|
for line in r.iter_lines():
|
if line.startswith(b"data: "):
|
event = json.loads(line[6:])
|
# 过滤 message_replace 事件,此事件会全量推一次
|
if event.get("event") != "message_replace" and event.get(
|
"answer"
|
):
|
yield event["answer"]
|
|
def response_with_functions(self, session_id, dialogue, functions=None):
|
if len(dialogue) == 2 and functions is not None and len(functions) > 0:
|
# 第一次调用llm, 取最后一条用户消息,附加tool提示词
|
last_msg = dialogue[-1]["content"]
|
function_str = json.dumps(functions, ensure_ascii=False)
|
modify_msg = get_system_prompt_for_function(function_str) + last_msg
|
dialogue[-1]["content"] = modify_msg
|
|
# 如果最后一个是 role="tool",附加到user上
|
if len(dialogue) > 1 and dialogue[-1]["role"] == "tool":
|
assistant_msg = "\ntool call result: " + dialogue[-1]["content"] + "\n\n"
|
while len(dialogue) > 1:
|
if dialogue[-1]["role"] == "user":
|
dialogue[-1]["content"] = assistant_msg + dialogue[-1]["content"]
|
break
|
dialogue.pop()
|
|
for token in self.response(session_id, dialogue):
|
yield token, None
|