zhaoqingang 1 an în urmă
părinte
comite
d961b5e929

+ 63 - 9
app/api/v2/chat.py

@@ -1,15 +1,69 @@
+import json
+import uuid
+
 from fastapi import Depends, APIRouter
 from fastapi import Depends, APIRouter
 from sqlalchemy.orm import Session
 from sqlalchemy.orm import Session
-from starlette.responses import StreamingResponse
-from app.api import get_current_user
-from app.models import UserModel
+from starlette.responses import StreamingResponse, Response
+from app.config.const import dialog_chat, advanced_chat, base_chat, agent_chat, workflow_chat, basic_chat, \
+    smart_message_error, http_400, http_500, http_200
 from app.models.base_model import get_db
 from app.models.base_model import get_db
-from app.models.v2.session_model import ChatDialogData
-from app.service.v2.chat import service_chat_dialog
+from app.models.v2.session_model import ChatData
+from app.service.v2.chat import service_chat_dialog, get_chat_info, service_chat_basic, \
+    service_chat_workflow, service_chat_parameters, service_chat_sessions
+
+chat_router_v2 = APIRouter()
+
+
+@chat_router_v2.post("/{chatId}/run")
+async def api_chat_dialog(chatId:str, dialog: ChatData, db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
+
+    chat_info = await get_chat_info(db, chatId)
+    if not chat_info:
+        error_msg = json.dumps({"message": smart_message_error, "error": "**ERROR**: parameter exception", "status": http_400})
+        return StreamingResponse(f"data: {error_msg}\n\n",
+                                 media_type="text/event-stream")
+    session_id = dialog.sessionId
+    if chat_info.mode == dialog_chat:
+        if not dialog.query:
+            error_msg = json.dumps(
+                {"message": smart_message_error, "error": "**ERROR**: question cannot be empty.", "status": http_400})
+            return StreamingResponse(f"data: {error_msg}\n\n",
+                                     media_type="text/event-stream")
+        if not session_id:
+            session = await service_chat_sessions(db, chatId, dialog.query)
+            if not session or session.get("code") != 0:
+                error_msg = json.dumps(
+                    {"message": smart_message_error, "error": "**ERROR**: chat agent error", "status": http_500})
+                return StreamingResponse(f"data: {error_msg}\n\n",
+                                         media_type="text/event-stream")
+            session_id = session.get("data", {}).get("id")
+        return StreamingResponse(service_chat_dialog(db, chatId ,dialog.query, session_id, 1, chat_info.mode), media_type="text/event-stream")
+    elif chat_info.mode == agent_chat or chat_info.mode == workflow_chat or chat_info.mode == advanced_chat or chat_info.mode == base_chat:
+        if not session_id:
+            session_id = str(uuid.uuid4()).replace("-", "")
+        return StreamingResponse(service_chat_workflow(db, chatId, dialog, session_id, 1, chat_info.mode),
+                                 media_type="text/event-stream")
+    elif chat_info.mode == basic_chat:
+        return StreamingResponse(service_chat_basic(db, chatId, dialog.question, dialog_chat.sessionId, 1),
+                                 media_type="text/event-stream")
+    else:
+        error_msg = json.dumps({"message": smart_message_error, "error": "**ERROR**: chat agent error", "status": http_500})
+        return StreamingResponse(f"data: {error_msg}\n\n",
+                                 media_type="text/event-stream")
 
 
-chat1_router = APIRouter()
 
 
+@chat_router_v2.get("/{chatId}/parameters")
+async def api_chat_parameters(chatId:str, db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
+    status_code = http_200
+    data = await service_chat_parameters(db, chatId, 1)
+    if not data:
+        status_code = http_400
+    return Response(json.dumps(data), media_type="application/json", status_code=status_code)
 
 
-@chat1_router.post("/chat_dialog")
-async def api_chat_dialog(dialog: ChatDialogData, db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
-    return StreamingResponse(service_chat_dialog(db, dialog.chatId ,dialog.question, dialog.sessionId, 1), media_type="text/event-stream")
+# @chat_router_v2.get("/{chatId}/parameters")
+# async def api_chat_parameters(chatId:str, db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
+#     status_code = http_200
+#     data = await service_chat_parameters(db, chatId, 1)
+#     if not data:
+#         status_code = http_400
+#     return Response(json.dumps(data), media_type="application/json", status_code=status_code)

+ 9 - 1
app/config/agent_base_url.py

@@ -1 +1,9 @@
-RG_CHAT_DIALOG= "/api/v1/chats/{}/completions"
+
+####------
+RG_CHAT_DIALOG= "/api/v1/chats/{}/completions"
+RG_CHAT_SESSIONS= "/api/v1/chats/{}/sessions"
+
+### ----------
+DF_CHAT_AGENT= "/v1/chat-messages"
+DF_CHAT_WORKFLOW= "/v1/workflows/run"
+DF_CHAT_PARAMETERS= "/v1/parameters"

+ 53 - 5
app/config/const.py

@@ -13,10 +13,10 @@ BISHENG = "bisheng_app"
 DIFY = "dify_app"
 DIFY = "dify_app"
 
 
 ### ---------------app type-----------------
 ### ---------------app type-----------------
-BASIC_ID = 3
-RAGFLOW_ID = 1
-BISHENG_ID = 2
-DIFY_ID = 4
+BASIC_TYPE = "3"
+RG_TYPE = "1"
+BS_TYPE = "2"
+DF_TYPE = "4"
 
 
 ###  ------------------status--------------------
 ###  ------------------status--------------------
 USER_STATSU_DELETE = "2"
 USER_STATSU_DELETE = "2"
@@ -41,4 +41,52 @@ RESOURCE_STATUS_OFF = "0"
 
 
 
 
 ###
 ###
-max_chunk_size  =5000
+max_chunk_size  =5000
+
+
+### ---------chat mode--------------
+dialog_chat = "agent-dialog"
+workflow_chat = "workflow"
+advanced_chat = "advanced-chat"
+agent_chat = "agent-chat"
+base_chat = "chat"
+basic_chat = "agent-basic"
+
+
+### ------------------------------
+rg_api_token = "6b8ee426c67511efb1510242ac1b0006"
+
+
+### ----------------evnet message value----------------------
+message_event = "message"
+message_agent_thought = "agent_thought"
+message_agent = "agent_message"
+message_end = "message_end"
+message_error = "error"
+message_file  = "message_file"
+message_tts  = "tts_message"
+message_tts_end  = "tts_message_end"
+message_replace  = "message_replace"
+message_ping = "ping"
+workflow_started = "workflow_started"
+node_started = "node_started"
+node_finished = "node_finished"
+workflow_finished = "workflow_finished"
+
+
+### --------------------smart output event message----------------------------------
+smart_message_cover = "message"
+smart_message_stream = "stream"
+smart_message_file = "message_file"
+smart_message_end = "message_end"
+smart_message_error = "error"
+smart_workflow_started = "workflow_started"
+smart_node_started = "node_started"
+smart_node_finished = "node_finished"
+smart_workflow_finished = "workflow_finished"
+
+
+### ---------------------------http status--------------------------------------
+http_200 = 200
+http_400 = 400
+http_500 = 500

+ 9 - 1
app/models/token_model.py

@@ -1,7 +1,7 @@
 from datetime import datetime
 from datetime import datetime
 from typing import Type
 from typing import Type
 
 
-from sqlalchemy import Column, Integer, DateTime, Text
+from sqlalchemy import Column, Integer, DateTime, Text, String
 from sqlalchemy.orm import Session
 from sqlalchemy.orm import Session
 
 
 from app.config.const import RAGFLOW
 from app.config.const import RAGFLOW
@@ -92,3 +92,11 @@ async def update_token(db: Session, user_id: int, access_token: str, token: dict
 
 
 
 
 
 
+class ApiTokenModel(Base):
+    __tablename__ = "chat_api_tokens"
+    id = Column(String(32), primary_key=True)
+    app_id = Column(String(32), index=True)
+    type = Column(String(16))
+    token = Column(String(255))
+    created_at = Column(DateTime, default=datetime.now())
+    last_used_at = Column(DateTime, default=datetime.now())

+ 15 - 7
app/models/v2/session_model.py

@@ -7,7 +7,7 @@ from typing import Optional, Type
 from pydantic import BaseModel
 from pydantic import BaseModel
 from sqlalchemy import Column, String, Integer, DateTime, JSON, TEXT, Index
 from sqlalchemy import Column, String, Integer, DateTime, JSON, TEXT, Index
 
 
-from Log import logger
+# from Log import logger
 from app.models.agent_model import AgentType
 from app.models.agent_model import AgentType
 from app.models.base_model import Base
 from app.models.base_model import Base
 
 
@@ -35,14 +35,17 @@ class ChatSessionModel(Base):
     reference = Column(TEXT)
     reference = Column(TEXT)
     conversation_id = Column(String(36), index=True)
     conversation_id = Column(String(36), index=True)
     event_type = Column(String(16))
     event_type = Column(String(16))
+    session_type = Column(String(16))
 
 
     # to_dict 方法
     # to_dict 方法
     def to_dict(self):
     def to_dict(self):
         return {
         return {
-            'id': self.id,
+            'session_id': self.id,
             'name': self.name,
             'name': self.name,
             'agent_type': self.agent_type,
             'agent_type': self.agent_type,
             'agent_id': self.agent_id,
             'agent_id': self.agent_id,
+            'event_type': self.event_type,
+            'session_type': self.session_type,
             'create_date': self.create_date.strftime("%Y-%m-%d %H:%M:%S"),
             'create_date': self.create_date.strftime("%Y-%m-%d %H:%M:%S"),
             'update_date': self.update_date.strftime("%Y-%m-%d %H:%M:%S"),
             'update_date': self.update_date.strftime("%Y-%m-%d %H:%M:%S"),
         }
         }
@@ -71,10 +74,12 @@ class ChatSessionModel(Base):
 
 
 
 
 
 
-class ChatDialogData(BaseModel):
+class ChatData(BaseModel):
     sessionId: Optional[str] = ""
     sessionId: Optional[str] = ""
-    question: str
-    chatId: str
+
+    class Config:
+        extra = 'allow'  # 允许其他动态字段
+
 
 
 
 
 class ChatSessionDao:
 class ChatSessionDao:
@@ -98,17 +103,20 @@ class ChatSessionDao:
         session = self.db.query(ChatSessionModel).filter_by(id=session_id).first()
         session = self.db.query(ChatSessionModel).filter_by(id=session_id).first()
         return session
         return session
 
 
-    async def update_session_by_id(self, session_id: str, session, message: dict) -> ChatSessionModel | None:
+    async def update_session_by_id(self, session_id: str, session, message: dict, conversation_id=None) -> ChatSessionModel | None:
+        print(message)
         if not session:
         if not session:
             session = await self.get_session_by_id(session_id)
             session = await self.get_session_by_id(session_id)
         if session:
         if session:
             try:
             try:
+                if conversation_id:
+                    session.conversation_id=conversation_id
                 session.add_message(message)
                 session.add_message(message)
                 session.update_date = current_time()
                 session.update_date = current_time()
                 self.db.commit()
                 self.db.commit()
                 self.db.refresh(session)
                 self.db.refresh(session)
             except Exception as e:
             except Exception as e:
-                logger.error(e)
+                # logger.error(e)
                 self.db.rollback()
                 self.db.rollback()
         return session
         return session
 
 

+ 75 - 0
app/service/v2/app_driver/chat_agent.py

@@ -0,0 +1,75 @@
+import json
+
+# from Log import logger
+from app.models.v2.session_model import ChatData
+from app.service.v2.app_driver.chat_base import ChatBase
+
+
+class ChatAgent(ChatBase):
+
+    async def chat_completions(self, url, data, headers):
+        complete_response = ""
+        async for line in self.http_stream(url, data, headers):
+            # logger.error(line)
+            if line.startswith("data:"):
+                complete_response = line.strip("data:").strip()
+            elif line.startswith("Error: "):
+                yield {"event": "error", "message": line}
+            else:
+                complete_response += line.strip()
+            try:
+                json_data = json.loads(complete_response)
+                # 处理 JSON 数据
+                # print(json_data)
+                complete_response = ""
+                yield json_data
+
+            except json.JSONDecodeError as e:
+                # logger.info("Invalid JSON data------------------")
+                print(e)
+
+    @staticmethod
+    async def request_data(query: str, conversation_id: str, user:str, chat_data: ChatData) -> dict:
+        inputs = []
+        files = []
+        if hasattr(chat_data,  "inputs"):
+            inputs = chat_data.inputs
+        if hasattr(chat_data,  "files"):
+            files = chat_data.files
+
+        return {
+            "inputs":inputs,
+            "query": query,
+            "response_mode": "streaming",
+            "conversation_id": conversation_id,
+            "user": user,
+            "files": files
+        }
+
+
+if __name__ == "__main__":
+    async def aa():
+        chat_id = "16954f6d-c1e6-4a0b-b371-363c28e8a48b"
+        token = "app-79ndndjNAFSV3qTuDAjDwuSO"
+        base_url = "http://192.168.20.116"
+        url = f"{base_url}/v1/chat-messages"
+        chat = ChatAgent()
+        data = {
+            "inputs":{},
+            "query": "你好,你能做什么?",
+            "response_mode": "streaming",
+            "conversation_id": "",
+            "user": "1",
+            "files": []
+        }
+        headers = {
+            'Content-Type': 'application/json',
+            'Authorization': f"Bearer {token}"
+        }
+        async for ans in chat.chat_completions(url, data, headers):
+            print(ans)
+
+
+    import asyncio
+
+    asyncio.run(aa())

+ 4 - 4
app/service/v2/app_driver/chat_base.py

@@ -22,19 +22,19 @@ class ChatBase:
     @staticmethod
     @staticmethod
     async def http_post(url, data, headers, timeout=300):
     async def http_post(url, data, headers, timeout=300):
         async with httpx.AsyncClient(timeout=timeout) as client:
         async with httpx.AsyncClient(timeout=timeout) as client:
-            response = client.post(url, json=data, headers=headers)
+            response = await client.post(url, json=data, headers=headers)
             return response
             return response
 
 
     @staticmethod
     @staticmethod
     async def http_get(url, params, headers, timeout=300):
     async def http_get(url, params, headers, timeout=300):
         async with httpx.AsyncClient(timeout=timeout) as client:
         async with httpx.AsyncClient(timeout=timeout) as client:
-            response = client.get(url, params=params, headers=headers)
+            response = await client.get(url, params=params, headers=headers)
             return response
             return response
 
 
     @staticmethod
     @staticmethod
     async def get_headers(token):
     async def get_headers(token):
-        headers = {
-            # 'Content-Type': 'application/json',
+        return {
+            'Content-Type': 'application/json',
             'Authorization': f'Bearer {token}'
             'Authorization': f'Bearer {token}'
         }
         }
 
 

+ 47 - 0
app/service/v2/app_driver/chat_data.py

@@ -0,0 +1,47 @@
+import json
+
+# from Log import logger
+from app.service.v2.app_driver.chat_base import ChatBase
+
+
+class ChatBaseApply(ChatBase):
+
+    async def chat_parameters(self, url, params, headers):
+
+        res = await self.http_get(url, params, headers)
+        if res.status_code == 200:
+            return res.json()
+        else:
+            return {}
+
+
+
+
+
+
+if __name__ == "__main__":
+    async def aa():
+        chat_id = "bcb56e4b-8f21-41f1-b22a-80335fe58345"
+        token = "app-9sbGzhtFuGIducdepzQgX06v"
+        base_url = "http://192.168.20.116"
+        url = f"{base_url}/v1/parameters"
+        chat = ChatBaseApply()
+        data = {
+            "question": "电网技术总结300字",
+            "stream": True,
+            "session_id": "9969c152cce411ef8a140242ac1b0002"
+        }
+        params = {
+            "user": "1"
+        }
+        headers = {
+            'Content-Type': 'application/json',
+            'Authorization': f"Bearer {token}"
+        }
+        ans = await chat.chat_parameters(url, params, headers)
+        print(ans)
+
+
+    import asyncio
+
+    asyncio.run(aa())

+ 18 - 13
app/service/v2/app_driver/chat_dialog.py

@@ -6,22 +6,10 @@ from app.service.v2.app_driver.chat_base import ChatBase
 
 
 class ChatDialog(ChatBase):
 class ChatDialog(ChatBase):
 
 
-
-    def __init__(self, token):
-        self.token = token
-
-
-    async def get_headers(self):
-        return {
-            'Content-Type': 'application/json',
-            'Authorization': f'Bearer {self.token}'
-        }
-
-
     async def chat_completions(self, url, data, headers):
     async def chat_completions(self, url, data, headers):
         complete_response = ""
         complete_response = ""
         async for line in self.http_stream(url, data, headers):
         async for line in self.http_stream(url, data, headers):
-            # logger.error(line)
+            print(line)
             if line.startswith("data:"):
             if line.startswith("data:"):
                 complete_response = line.strip("data:").strip()
                 complete_response = line.strip("data:").strip()
             else:
             else:
@@ -37,6 +25,23 @@ class ChatDialog(ChatBase):
                 logger.info("Invalid JSON data------------------")
                 logger.info("Invalid JSON data------------------")
                 # print(e)
                 # print(e)
 
 
+    async def chat_sessions(self, url, data, headers):
+
+        res = await self.http_post(url, data, headers)
+        if res.status_code == 200:
+            return res.json()
+        else:
+            return {}
+
+
+
+    @staticmethod
+    async def request_data(question, session_id=""):
+        return {
+            "question": question,
+            "stream": True,
+            "session_id": session_id
+        }
 
 
 
 
 
 

+ 0 - 0
app/service/v2/app_driver/chat_basic.py → app/service/v2/app_driver/chat_smart.py


+ 74 - 0
app/service/v2/app_driver/chat_workflow.py

@@ -0,0 +1,74 @@
+import json
+
+# from Log import logger
+from app.models.v2.session_model import ChatData
+from app.service.v2.app_driver.chat_base import ChatBase
+
+
+class ChatWorkflow(ChatBase):
+
+    async def chat_completions(self, url, data, headers):
+        complete_response = ""
+        async for line in self.http_stream(url, data, headers):
+            if line.startswith("data:"):
+                complete_response = line.strip("data:").strip()
+            elif line.startswith("Error: "):
+                yield {"event": "error", "message": line}
+            else:
+                complete_response += line.strip()
+            try:
+                json_data = json.loads(complete_response)
+                # 处理 JSON 数据
+                # print(json_data)
+                complete_response = ""
+                yield json_data
+
+            except json.JSONDecodeError as e:
+                # logger.info("Invalid JSON data------------------")
+                print(e)
+
+    @staticmethod
+    async def request_data(query: str, conversation_id: str, user:str, chat_data: ChatData) -> dict:
+        inputs = []
+        files = []
+        if hasattr(chat_data,  "inputs"):
+            inputs = chat_data.inputs
+        if hasattr(chat_data,  "files"):
+            files = chat_data.files
+
+        return {
+            "inputs":inputs,
+            "query": query,
+            "response_mode": "streaming",
+            "conversation_id": conversation_id,
+            "user": user,
+            "files": files
+        }
+
+
+if __name__ == "__main__":
+    async def aa():
+        chat_id = "16954f6d-c1e6-4a0b-b371-363c28e8a48b"
+        token = "app-79ndndjNAFSV3qTuDAjDwuSO"
+        base_url = "http://192.168.20.116"
+        url = f"{base_url}/v1/chat-messages"
+        chat = ChatAgent()
+        data = {
+            "inputs":{},
+            "query": "你好,你能做什么?",
+            "response_mode": "streaming",
+            "conversation_id": "",
+            "user": "1",
+            "files": []
+        }
+        headers = {
+            'Content-Type': 'application/json',
+            'Authorization': f"Bearer {token}"
+        }
+        async for ans in chat.chat_completions(url, data, headers):
+            print(ans)
+
+
+    import asyncio
+
+    asyncio.run(aa())

+ 196 - 40
app/service/v2/chat.py

@@ -1,70 +1,226 @@
 import json
 import json
 
 
 from Log import logger
 from Log import logger
-from app.config.agent_base_url import RG_CHAT_DIALOG
+from app.config.agent_base_url import RG_CHAT_DIALOG, DF_CHAT_AGENT, DF_CHAT_PARAMETERS, RG_CHAT_SESSIONS, \
+    DF_CHAT_WORKFLOW
 from app.config.config import settings
 from app.config.config import settings
-from app.config.const import max_chunk_size
-from app.models.v2.session_model import ChatSessionDao
+from app.config.const import *
+from app.models import DialogModel, ApiTokenModel
+from app.models.v2.session_model import ChatSessionDao, ChatData
+from app.service.v2.app_driver.chat_agent import ChatAgent
+from app.service.v2.app_driver.chat_data import ChatBaseApply
 from app.service.v2.app_driver.chat_dialog import ChatDialog
 from app.service.v2.app_driver.chat_dialog import ChatDialog
+from app.service.v2.app_driver.chat_workflow import ChatWorkflow
 
 
 
 
-async def service_chat_dialog(db, chat_id:str, question: str, session_id: str, user_id):
-    token = "ragflow-YzMzE1NDRjYzMyZjExZWY5ZjkxMDI0Mm"
-    url = settings.fwr_base_url+RG_CHAT_DIALOG.format(chat_id)
-    chat = ChatDialog(token)
-    request_data = {
-        "question": question,
-        "stream": True,
-        "session_id": session_id
-    }
-    headers = {
-        'Content-Type': 'application/json',
-        'Authorization': f"Bearer {token}"
-    }
+async def update_session_log(db, session_id: str, message: dict, conversation_id: str):
+    await ChatSessionDao(db).update_session_by_id(
+        session_id=session_id,
+        session=None,
+        message=message,
+        conversation_id=conversation_id
+    )
+
+
+async def add_session_log(db, session_id: str, question: str, chat_id: str, user_id, event_type: str,
+                          conversation_id: str):
     try:
     try:
-        await ChatSessionDao(db).update_or_insert_by_id(
+        session = await ChatSessionDao(db).update_or_insert_by_id(
             session_id=session_id,
             session_id=session_id,
             name=question[:255],
             name=question[:255],
             agent_id=chat_id,
             agent_id=chat_id,
             agent_type=1,
             agent_type=1,
             tenant_id=user_id,
             tenant_id=user_id,
             message={"role": "user", "content": question},
             message={"role": "user", "content": question},
-            conversation_id=session_id,
-            event_type="message"
+            conversation_id=conversation_id,
+            event_type=event_type
         )
         )
+        return session
     except Exception as e:
     except Exception as e:
         logger.error(e)
         logger.error(e)
+    return None
+
+
+async def get_chat_token(db, app_id):
+    app_token = db.query(ApiTokenModel).filter_by(app_id=app_id).first()
+    if app_token:
+        return app_token.token
+    return ""
+
+
+async def get_chat_info(db, chat_id: str):
+    return db.query(DialogModel).filter_by(id=chat_id, status=Dialog_STATSU_ON).first()
+
+
+async def get_chat_object(mode):
+    if mode == workflow_chat:
+        url = settings.dify_base_url + DF_CHAT_WORKFLOW
+        return ChatWorkflow(), url
+    else:
+        url = settings.dify_base_url + DF_CHAT_AGENT
+        return ChatAgent(), url
+
+
+async def service_chat_dialog(db, chat_id: str, question: str, session_id: str, user_id, mode: str):
+    conversation_id = ""
+    token = await get_chat_token(db, rg_api_token)
+    url = settings.fwr_base_url + RG_CHAT_DIALOG.format(chat_id)
+    chat = ChatDialog()
+    session = await add_session_log(db, session_id, question, chat_id, user_id, mode, session_id)
+    if session:
+        conversation_id = session.conversation_id
+    message = {"role": "assistant", "answer": "", "reference": {}}
     try:
     try:
-        message = {"role": "assistant","answer":"", "reference": {}}
-        async for ans in chat.chat_completions(url, request_data, headers):
+        async for ans in chat.chat_completions(url, await chat.request_data(question, conversation_id),
+                                               await chat.get_headers(token)):
+            data = {}
+            error = ""
+            status = http_200
             if ans.get("code", None) == 102:
             if ans.get("code", None) == 102:
-                error = ans.get("message", "请输入你的问题!")
-                data = {"answer":error}
-                event = "message"
+                error = ans.get("message", "error!")
+                status = http_400
+                event = smart_message_error
             else:
             else:
                 if isinstance(ans.get("data"), bool) and ans.get("data") is True:
                 if isinstance(ans.get("data"), bool) and ans.get("data") is True:
-                    data = {}
-                    event = "message_end"
+                    event = smart_message_end
                 else:
                 else:
                     data = ans.get("data", {})
                     data = ans.get("data", {})
-                    message = ans.get("data", {})
-                    event = "message"
-            message_str = "data: " + json.dumps({"event": event, "data": data}, ensure_ascii=False) + "\n\n"
+                    # conversation_id = data.get("session_id", "")
+                    if "session_id" in data:
+                        del data["session_id"]
+                    message = data
+                    event = smart_message_cover
+            message_str = "data: " + json.dumps(
+                {"event": event, "data": data, "error": error, "status": status, "session_id": session_id},
+                ensure_ascii=False) + "\n\n"
             for i in range(0, len(message_str), max_chunk_size):
             for i in range(0, len(message_str), max_chunk_size):
                 chunk = message_str[i:i + max_chunk_size]
                 chunk = message_str[i:i + max_chunk_size]
                 # print(chunk)
                 # print(chunk)
                 yield chunk  # 发送分块消息
                 yield chunk  # 发送分块消息
-        await ChatSessionDao(db).update_session_by_id(
-            session_id=session_id,
-            session=None,
-            message=message
-        )
     except Exception as e:
     except Exception as e:
+
         logger.error(e)
         logger.error(e)
-        yield "data: " + json.dumps({"message": "message",
-                                    "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
-                                   ensure_ascii=False) + "\n\n"
+        try:
+            yield "data: " + json.dumps({"message": smart_message_error,
+                                         "error": "**ERROR**: " + str(e), "status": http_500},
+                                        ensure_ascii=False) + "\n\n"
+        except:
+            ...
+    finally:
+        await update_session_log(db, session_id, message, conversation_id)
+
+
+async def service_chat_workflow(db, chat_id: str, chat_data: ChatData, session_id: str, user_id, mode: str):
+    conversation_id = ""
+    answer_event = ""
+    answer_agent = ""
+    message_id = ""
+    task_id = ""
+    error = ""
+    files = []
+    node_list = []
+    token = await get_chat_token(db, chat_id)
+
+    chat, url = await get_chat_object(mode)
+    if hasattr(chat_data, "query"):
+        query = chat_data.query
+    else:
+        query = "start new workflow"
+    session = await add_session_log(db, session_id, query, chat_id, user_id, mode, conversation_id)
+    if session:
+        conversation_id = session.conversation_id
+    try:
+        async for ans in chat.chat_completions(url,
+                                               await chat.request_data(query, conversation_id, str(user_id), chat_data),
+                                               await chat.get_headers(token)):
+            data = {}
+            status = http_200
+            conversation_id = ans.get("conversation_id")
+            task_id = ans.get("task_id")
+            if ans.get("event") == message_error:
+                error = ans.get("message", "参数异常!")
+                status = http_400
+                event = smart_message_error
+            elif ans.get("event") == message_agent:
+                data = {"answer": ans.get("answer", ""), "id": ans.get("message_id", "")}
+                answer_agent += ans.get("answer", "")
+                message_id = ans.get("message_id", "")
+                event = smart_message_stream
+            elif ans.get("event") == message_event:
+                data = {"answer": ans.get("answer", ""), "id": ans.get("message_id", "")}
+                answer_event += ans.get("answer", "")
+                message_id = ans.get("message_id", "")
+                event = smart_message_stream
+            elif ans.get("event") == message_file:
+                data = {"url": ans.get("url", ""), "id": ans.get("id", ""),
+                        "type": ans.get("type", "")}
+                files.append(data)
+                event = smart_message_file
+            elif ans.get("event") in [workflow_started, node_started, node_finished]:
+                data = ans.get("data", {})
+                data["inputs"] = []
+                data["outputs"] = []
+                data["process_data"] = ""
+                node_list.append(ans)
+                event = [smart_workflow_started, smart_node_started, smart_node_finished][
+                    [workflow_started, node_started, node_finished].index(ans.get("event"))]
+            elif ans.get("event") == workflow_finished:
+                data = ans.get("data", {})
+                event = smart_workflow_finished
+                node_list.append(ans)
+            elif ans.get("event") == message_end:
+                event = smart_message_end
+            else:
+                continue
+
+            yield "data: " + json.dumps(
+                {"event": event, "data": data, "error": error, "status": status, "task_id": task_id,
+                 "session_id": session_id},
+                ensure_ascii=False) + "\n\n"
+
+    except Exception as e:
+        logger.error(e)
+        try:
+            yield "data: " + json.dumps({"message": smart_message_error,
+                                         "error": "**ERROR**: " + str(e), "status": http_500},
+                                        ensure_ascii=False) + "\n\n"
+        except:
+            ...
+    finally:
+        await update_session_log(db, session_id, {"role": "assistant", "answer": answer_event or answer_agent,
+                                                  "node_list": node_list, "task_id": task_id, "id": message_id,
+                                                  "error": error}, conversation_id)
+
+
+async def service_chat_basic(db, chat_id: str, question: str, session_id: str, user_id):
+    ...
+
+
+async def service_chat_parameters(db, chat_id, user_id):
+    chat_info = db.query(DialogModel).filter_by(id=chat_id).first()
+    if not chat_info:
+        return {}
+    if chat_info.dialog_type == RG_TYPE:
+        return {"retriever_resource":
+            {
+                "enabled": True
+            }
+        }
+    elif chat_info.dialog_type == BASIC_TYPE:
+        ...
+    elif chat_info.dialog_type == DF_TYPE:
+        token = await get_chat_token(db, chat_id)
+        if not token:
+            return {}
+        url = settings.dify_base_url + DF_CHAT_PARAMETERS
+        chat = ChatBaseApply()
+        return await chat.chat_parameters(url, {"user": str(user_id)}, await chat.get_headers(token))
+
 
 
-        yield "data: " + json.dumps({"message": "message_end",
-                                    "data": {}},
-                                   ensure_ascii=False) + "\n\n"
+async def service_chat_sessions(db, chat_id, name):
+    token = await get_chat_token(db, rg_api_token)
+    if not token:
+        return {}
+    url = settings.fwr_base_url + RG_CHAT_SESSIONS.format(chat_id)
+    chat = ChatDialog()
+    return await chat.chat_sessions(url, {"name": name}, await chat.get_headers(token))

+ 2 - 2
main.py

@@ -15,7 +15,7 @@ from app.api.knowledge import knowledge_router
 from app.api.label import label_router
 from app.api.label import label_router
 from app.api.llm import llm_router
 from app.api.llm import llm_router
 from app.api.organization import dept_router
 from app.api.organization import dept_router
-from app.api.v2.chat import chat1_router
+from app.api.v2.chat import chat_router_v2
 from app.api.v2.public_api import public_api
 from app.api.v2.public_api import public_api
 from app.api.report import router as report_router
 from app.api.report import router as report_router
 from app.api.resource import menu_router
 from app.api.resource import menu_router
@@ -89,7 +89,7 @@ app.include_router(dialog_router, prefix='/api/dialog', tags=["dialog"])
 app.include_router(canvas_router, prefix='/api/canvas', tags=["canvas"])
 app.include_router(canvas_router, prefix='/api/canvas', tags=["canvas"])
 app.include_router(label_router, prefix='/api/label', tags=["label"])
 app.include_router(label_router, prefix='/api/label', tags=["label"])
 app.include_router(public_api, prefix='/v1/api', tags=["public_api"])
 app.include_router(public_api, prefix='/v1/api', tags=["public_api"])
-app.include_router(chat1_router, prefix='/v1/chat', tags=["chat1"])
+app.include_router(chat_router_v2, prefix='/v1/chat', tags=["chat1"])
 app.mount("/static", StaticFiles(directory="app/images"), name="static")
 app.mount("/static", StaticFiles(directory="app/images"), name="static")
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":