From 3b1bf7da6771bd1d6852d3dcc1f906d5ae5c95d1 Mon Sep 17 00:00:00 2001
From: zhaoqingang <zhaoqg0118@163.com>
Date: 星期三, 12 三月 2025 13:49:12 +0800
Subject: [PATCH] 增加内容优化
---
app/config/env_conf/default_agent_conf.json | 91 +++++++++++++++
app/service/v2/chat.py | 48 +++++--
app/init_config/init_run_data.py | 12 -
app/service/files.py | 28 ++++
app/service/v2/mindmap.py | 1
app/config/const.py | 14 +
app/task/sync_account_token.py | 2
app/service/v2/app_driver/chat_agent.py | 5
app/api/files.py | 25 +++
app/service/v2/initialize_data.py | 63 ++++++++++
app/models/v2/chat.py | 35 +++--
11 files changed, 276 insertions(+), 48 deletions(-)
diff --git a/app/api/files.py b/app/api/files.py
index 0592b4b..7107025 100644
--- a/app/api/files.py
+++ b/app/api/files.py
@@ -1,4 +1,5 @@
import io
+import time
from typing import Optional, List
import requests
@@ -19,7 +20,7 @@
from app.models.user_model import UserModel
from app.service.basic import BasicService
from app.service.bisheng import BishengService
-from app.service.files import read_file
+from app.service.files import read_file, service_chat_message, generate_word_document
from app.service.v2.api_token import DfTokenDao
from app.service.difyService import DifyService
from app.service.ragflow import RagflowService
@@ -242,4 +243,24 @@
break
yield data
- return StreamingResponse(generate(), media_type="application/octet-stream")
\ No newline at end of file
+ return StreamingResponse(generate(), media_type="application/octet-stream")
+
+
+@router.get("/message/{message_id}/download", response_model=Response)
+async def chat_message_generate_docx(message_id: str, db=Depends(get_db)):
+ title, content = await service_chat_message(db, message_id)
+ if title:
+ print(title)
+ # 鍒涘缓 Word 鏂囨。
+ doc = await generate_word_document(title, content)
+
+ # 淇濆瓨鍒板唴瀛樼紦鍐插尯
+ buffer = io.BytesIO()
+ doc.save(buffer)
+ buffer.seek(0)
+ # print(2323232)
+ # 杩斿洖鏂囦欢娴�
+ return StreamingResponse(buffer,
+ media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ headers={"Content-Disposition": f"attachment; filename={int(time.time()*1000)}.docx"})
+ raise HTTPException(status_code=400, detail="Failed to generate Word document")
diff --git a/app/config/const.py b/app/config/const.py
index a173fe6..9c369f7 100644
--- a/app/config/const.py
+++ b/app/config/const.py
@@ -1,5 +1,5 @@
-### ----------dify------api token
+### ----------df------api token
DOCUMENT_TO_CLEANING = "document_to_cleaning"
DOCUMENT_TO_REPORT = "document_to_report"
IMAGE_TO_TEXT = "image_and_text_conversion"
@@ -62,6 +62,7 @@
agent_chat = "agent-chat"
base_chat = "chat"
basic_chat = "agent-basic"
+complex_chat = "complex-chat"
### ------------------------------
@@ -118,5 +119,12 @@
complex_dialog_chat = 1 # 鏂囨。鍜屽熀纭�瀵硅瘽
complex_network_chat = 2 # 鑱旂綉瀵硅瘽
complex_knowledge_chat = 3 # 鐭ヨ瘑搴撳璇�
-# complex_deep_chat = 4
-complex_mindmap_chat = 5
\ No newline at end of file
+complex_deep_chat = 6
+complex_mindmap_chat = 5 # 鎬濈淮瀵煎浘
+complex_content_optimization_chat = 4 # 鍐呭浼樺寲
+complex_clean_chat = 7 # 娓呮礂
+complex_title_chat = 8 # 灏忔爣棰�
+complex_report_chat = 9 # 鎶ュ憡
+
+### --------------------------------basic develop agent---------------------------------------------------
+basic_report_talk ="basic_report_talk"
\ No newline at end of file
diff --git a/app/config/env_conf/default_agent_conf.json b/app/config/env_conf/default_agent_conf.json
index b58a3a6..a37e185 100644
--- a/app/config/env_conf/default_agent_conf.json
+++ b/app/config/env_conf/default_agent_conf.json
@@ -139,5 +139,94 @@
"mode": "agent-basic"
}
],
- "bs": []
+ "complex": [
+ {
+ "id": "c703ad73-faed-4fab-b00c-717766ad71dd",
+ "name": "鐭ヨ瘑搴撲笓瀹�",
+ "description": "鐭ヨ瘑搴撲笓瀹�",
+ "icon": "intellFrame4",
+ "chat_mode": 3,
+ "parameters": {
+ },
+ "dialogType": "4",
+ "mode": "complex-chat"
+ },
+ {
+ "id": "ad127cb5-a1ef-49a3-82ed-6467a670fd10",
+ "name": "鏂囨。鍒嗘瀽涓撳",
+ "description": "鏂囨。鍒嗘瀽涓撳",
+ "icon": "intellFrame4",
+ "chat_mode": 1,
+ "parameters": {
+ },
+ "dialogType": "4",
+ "mode": "complex-chat"
+ },
+ {
+ "id": "c6a9fda3-bfb8-40ef-9510-545766c7d6a0",
+ "name": "鑱旂綉鎼滅储涓撳",
+ "description": "鑱旂綉鎼滅储涓撳",
+ "icon": "intellFrame4",
+ "chat_mode": 2,
+ "parameters": {
+ },
+ "dialogType": "4",
+ "mode": "complex-chat"
+ },
+ {
+ "id": "1974a79d-35bf-446d-95ed-0724380ea65a",
+ "name": "璇浼樺寲涓撳",
+ "description": "璇浼樺寲涓撳",
+ "icon": "intellFrame4",
+ "chat_mode": 4,
+ "parameters": {
+ },
+ "dialogType": "4",
+ "mode": "complex-chat"
+ },
+ {
+ "id": "8c6b05e7-da35-4aa4-8874-32b5bba93e7a",
+ "name": "鎬濈淮瀵煎浘涓撳",
+ "description": "鎬濈淮瀵煎浘涓撳",
+ "icon": "intellFrame4",
+ "chat_mode": 5,
+ "parameters": {
+ },
+ "dialogType": "4",
+ "mode": "complex-chat"
+ },
+ {
+ "id": "8c6b05e7-da35-4aa4-8874-32b5bba93111",
+ "name": "娓呮礂宸ヤ綔娴�",
+ "description": "娓呮礂宸ヤ綔娴�",
+ "icon": "intellFrame4",
+ "chat_mode": 7,
+ "parameters": {
+ },
+ "dialogType": "4",
+ "mode": "complex-chat"
+ },
+ {
+ "id": "8c6b05e7-da35-4aa4-8874-32b5bba93222",
+ "name": "灏忔爣棰樺伐浣滄祦",
+ "description": "灏忔爣棰樺伐浣滄祦",
+ "icon": "intellFrame4",
+ "chat_mode": 8,
+ "parameters": {
+ },
+ "dialogType": "4",
+ "mode": "complex-chat"
+ },
+ {
+ "id": "8c6b05e7-da35-4aa4-8874-32b5bba9333",
+ "name": "鎶ュ憡鐢熸垚宸ヤ綔娴�",
+ "description": "鎶ュ憡鐢熸垚宸ヤ綔娴�",
+ "icon": "intellFrame4",
+ "chat_mode": 9,
+ "parameters": {
+ },
+ "dialogType": "4",
+ "mode": "complex-chat"
+ }
+ ]
}
\ No newline at end of file
diff --git a/app/init_config/init_run_data.py b/app/init_config/init_run_data.py
index db095fb..c0ff67e 100644
--- a/app/init_config/init_run_data.py
+++ b/app/init_config/init_run_data.py
@@ -1,6 +1,6 @@
from app.models.base_model import SessionLocal
from app.service.v2.initialize_data import dialog_menu_sync, default_group_sync, default_role_sync, \
- basic_agent_sync, admin_account_sync, sync_rg_api_token
+ basic_agent_sync, admin_account_sync, sync_rg_api_token, sync_complex_api_token
from app.task.sync_account_token import sync_token
@@ -10,17 +10,15 @@
await dialog_menu_sync(db) # 灏忔暟
await default_group_sync(db) # 榛樿缁�
await default_role_sync(db) # 榛樿瑙掕壊
- # await app_register_sync(db) # 娉ㄥ唽鐨勫簲鐢�
await basic_agent_sync(db) # 寮�鍙戠殑agent
- await admin_account_sync(db) #
- await sync_rg_api_token(db) #
- await sync_token() # 鍚姩鍚屾token浠诲姟
+ await admin_account_sync(db) # 绠$悊鍛樿处鍙�
+ await sync_rg_api_token(db) # rg token
+ await sync_token() # 璐﹀彿token鐧诲綍
+ await sync_complex_api_token(db) # 璐﹀彿token鐧诲綍
except Exception as e:
print(e)
finally:
db.close()
- # await default_role_sync(db) # 椤甸潰璧勬簮閰嶇疆淇℃伅
- # await default_role_sync(db) # 榛樿鐨勮鑹茶祫婧�
diff --git a/app/models/v2/chat.py b/app/models/v2/chat.py
index 86d7ea4..e41edcf 100644
--- a/app/models/v2/chat.py
+++ b/app/models/v2/chat.py
@@ -26,6 +26,7 @@
query: str
chatMode: Optional[int] = 1 # 1= 鏅�氬璇濓紝2=鑱旂綉锛�3=鐭ヨ瘑搴�,4=娣卞害
isDeep: Optional[int] = 1 # 1= 鏅��, 2=娣卞害
+ optimizeType: Optional[str] = "" # 浼樺寲绫诲瀷锛氭鼎鑹诧紝鎵╁啓锛岀缉鍐欙紝璋冩暣璇皵锛岃嚜瀹氫箟
knowledgeId: Optional[list] = []
files: Optional[list] = []
@@ -38,6 +39,7 @@
"knowledgeId": self.knowledgeId,
"files": self.files,
"isDeep": self.isDeep,
+ "optimizeType": self.optimizeType,
}
@@ -173,15 +175,19 @@
}
def log_to_json(self):
- return {
- 'id': self.id,
- 'name': self.name,
- 'agent_type': self.agent_type,
- 'chat_id': self.agent_id,
- 'create_date': self.create_date.strftime("%Y-%m-%d %H:%M:%S"),
- 'update_date': self.update_date.strftime("%Y-%m-%d %H:%M:%S"),
- 'message': json.loads(self.message)
- }
+ if self.message_type == 1:
+ return {
+ 'id': self.id,
+ 'role': "user",
+ 'content': self.content,
+ }
+ else:
+ return {
+ 'id': self.id,
+ 'role': "assistant",
+ 'answer': self.content,
+ 'node_list': json.loads(self.node_data) if self.node_data else [],
+ }
class ComplexChatSessionDao:
@@ -238,12 +244,11 @@
self.db.delete(session)
self.db.commit()
- async def get_session_list(self, user_id: int, agent_id: str, keyword:str, page: int, page_size: int) -> any:
- query = self.db.query(ComplexChatSessionModel).filter(ComplexChatSessionModel.tenant_id==user_id)
- if agent_id:
- query = query.filter(ComplexChatSessionModel.agent_id==agent_id)
+ async def get_session_list(self, session_id: int, keyword:str="", page: int=1, page_size: int=100) -> any:
+ query = self.db.query(ComplexChatSessionModel).filter(ComplexChatSessionModel.session_id==session_id)
+
if keyword:
- query = query.filter(ComplexChatSessionModel.name.like('%{}%'.format(keyword)))
+ query = query.filter(ComplexChatSessionModel.content.like('%{}%'.format(keyword)))
total = query.count()
- session_list = query.order_by(ComplexChatSessionModel.update_date.desc()).offset((page-1)*page_size).limit(page_size).all()
+ session_list = query.order_by(ComplexChatSessionModel.create_date.desc()).offset((page-1)*page_size).limit(page_size).all()
return total, session_list
\ No newline at end of file
diff --git a/app/service/files.py b/app/service/files.py
index ad0e93e..69f21ed 100644
--- a/app/service/files.py
+++ b/app/service/files.py
@@ -1,8 +1,11 @@
+import json
+
import fitz
import io
from docx import Document
from dashscope import get_tokenizer # dashscope鐗堟湰 >= 1.14.0
+from app.models import ComplexChatSessionDao
from app.service.auth import decode_access_token
@@ -52,4 +55,27 @@
'.docx'):
text = await read_word(file)
- return await get_str_token(text)
\ No newline at end of file
+ return await get_str_token(text)
+
+
+async def service_chat_message(db, message_id: str):
+ message = await ComplexChatSessionDao(db).get_session_by_id(message_id)
+ content = ""
+ title = ""
+ if message:
+ content = message.content
+ title= json.loads(message.query).get("query")
+ return title, content
+
+
+async def generate_word_document(title, content):
+ doc = Document()
+ # 娣诲姞鏍囬
+ doc.add_heading(title, level=1)
+
+ # 灏嗗唴瀹规寜娈佃惤鍒嗗壊骞跺啓鍏ユ枃妗�
+ for paragraph in content.split('\n'):
+ # print("--------------:", paragraph)
+ doc.add_paragraph(paragraph)
+
+ return doc
\ No newline at end of file
diff --git a/app/service/v2/app_driver/chat_agent.py b/app/service/v2/app_driver/chat_agent.py
index 5fa0bfa..a9d1790 100644
--- a/app/service/v2/app_driver/chat_agent.py
+++ b/app/service/v2/app_driver/chat_agent.py
@@ -1,5 +1,6 @@
import json
+from Log import logger
# from Log import logger
from app.models.v2.session_model import ChatData
from app.service.v2.app_driver.chat_base import ChatBase
@@ -26,8 +27,8 @@
yield json_data
except json.JSONDecodeError as e:
- # logger.info("Invalid JSON data------------------")
- print(e)
+ logger.info("Invalid JSON data------------------")
+ # print(e)
@staticmethod
async def request_data(query: str, conversation_id: str, user:str, chat_data: ChatData) -> dict:
diff --git a/app/service/v2/chat.py b/app/service/v2/chat.py
index 83ea02a..0942681 100644
--- a/app/service/v2/chat.py
+++ b/app/service/v2/chat.py
@@ -1,6 +1,7 @@
import asyncio
import io
import json
+import time
import uuid
import fitz
@@ -11,7 +12,8 @@
DF_CHAT_WORKFLOW, DF_UPLOAD_FILE, RG_ORIGINAL_URL
from app.config.config import settings
from app.config.const import *
-from app.models import DialogModel, ApiTokenModel, UserTokenModel, ComplexChatSessionDao, ChatDataRequest
+from app.models import DialogModel, ApiTokenModel, UserTokenModel, ComplexChatSessionDao, ChatDataRequest, \
+ ComplexChatDao
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
@@ -90,7 +92,7 @@
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, 1)
+ session = await add_session_log(db, session_id, question, chat_id, user_id, mode, session_id, RG_TYPE)
if session:
conversation_id = session.conversation_id
message = {"role": "assistant", "answer": "", "reference": {}}
@@ -173,7 +175,7 @@
else:
query = "start new conversation"
session = await add_session_log(db, session_id, query if query else "start new conversation", chat_id, user_id,
- mode, conversation_id, 3)
+ mode, conversation_id, DF_TYPE)
if session:
conversation_id = session.conversation_id
try:
@@ -251,8 +253,15 @@
"error": error}, conversation_id)
+
+
async def service_chat_basic(db, chat_id: str, chat_data: ChatData, session_id: str, user_id, mode: str):
- ...
+
+ if chat_id == basic_report_talk:
+ complex_chat = await ComplexChatDao(db).get_complex_chat_by_mode(chat_data.report_mode)
+ if complex_chat:
+ ...
+
async def service_chat_parameters(db, chat_id, user_id):
@@ -285,7 +294,15 @@
async def service_chat_session_log(db, session_id):
session_log = await ChatSessionDao(db).get_session_by_id(session_id)
- return json.dumps(session_log.log_to_json() if session_log else {})
+ if not session_log:
+ return {}
+ log_info =session_log.log_to_json()
+ if session_log.event_type == complex_chat:
+
+ total, message_list = await ComplexChatSessionDao(db).get_session_list(session_id)
+ log_info["message"] = [message.log_to_json() for message in message_list[::-1]]
+
+ return json.dumps(log_info)
async def service_chat_upload(db, chat_id, file, user_id):
@@ -470,23 +487,28 @@
error = ""
files = []
node_list = []
+ conversation_id = ""
token = await get_chat_token(db, chat_id)
chat, url = await get_chat_object(mode)
- conversation_id, message = await add_complex_log(db, str(uuid.uuid4()),chat_id, chat_request.sessionId, chat_request.chatMode, chat_request.query, user_id, mode, DF_TYPE, 1, query_data=chat_request.to_dict())
- if not message:
- yield "data: " + json.dumps({"message": smart_message_error,
- "error": "\n**ERROR**: 鍒涘缓浼氳瘽澶辫触锛�", "status": http_500},
- ensure_ascii=False) + "\n\n"
- return
+ if chat_request.chatMode != complex_content_optimization_chat:
+ await add_session_log(db, chat_request.sessionId, chat_request.query if chat_request.query else "鏈懡鍚嶄細璇�", chat_id, user_id,
+ mode, "", DF_TYPE)
+ conversation_id, message = await add_complex_log(db, str(uuid.uuid4()),chat_id, chat_request.sessionId, chat_request.chatMode, chat_request.query, user_id, mode, DF_TYPE, 1, query_data=chat_request.to_dict())
+ if not message:
+ yield "data: " + json.dumps({"message": smart_message_error,
+ "error": "\n**ERROR**: 鍒涘缓浼氳瘽澶辫触锛�", "status": http_500},
+ ensure_ascii=False) + "\n\n"
+ return
inputs = {"is_deep": chat_request.isDeep}
if chat_request.chatMode == complex_knowledge_chat:
inputs["query_json"] = json.dumps({"query": chat_request.query, "dataset_ids": chat_request.knowledgeId})
-
+ elif chat_request.chatMode == complex_content_optimization_chat:
+ inputs["type"] = chat_request.optimizeType
try:
async for ans in chat.chat_completions(url,
await chat.complex_request_data(chat_request.query, conversation_id, str(user_id), files=chat_request.files, inputs=inputs),
await chat.get_headers(token)):
- print(ans)
+ # print(ans)
data = {}
status = http_200
conversation_id = ans.get("conversation_id")
diff --git a/app/service/v2/initialize_data.py b/app/service/v2/initialize_data.py
index 1f05cab..eacdefa 100644
--- a/app/service/v2/initialize_data.py
+++ b/app/service/v2/initialize_data.py
@@ -7,12 +7,12 @@
from Log import logger
-from app.config.agent_base_url import RG_APP_TOKEN_LIST, RG_APP_NEW_TOKEN
+from app.config.agent_base_url import RG_APP_TOKEN_LIST, RG_APP_NEW_TOKEN, DF_CHAT_API_KEY
# from app.api import pwd_context
from app.config.const import DIFY, ENV_CONF_PATH, RAGFLOW, smart_server, chat_server, workflow_server, TMP_DICT, \
rg_api_token
from app.models import MenuCapacityModel, WebMenuModel, GroupModel, RoleModel, DialogModel, UserModel, UserAppModel, \
- cipher_suite, UserTokenModel, ApiTokenModel
+ cipher_suite, UserTokenModel, ApiTokenModel, ComplexChatModel
from app.service.auth import UserAppDao
from app.service.bisheng import BishengService
from app.service.difyService import DifyService
@@ -21,6 +21,7 @@
from app.service.v2.app_driver.chat_data import ChatBaseApply
from app.service.v2.app_register import AppRegisterDao
from app.config.config import settings
+from app.service.v2.chat import get_app_token
from app.utils.password_handle import generate_password, password_encrypted, password_decrypted
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@@ -131,10 +132,12 @@
async def basic_agent_sync(db):
agent_list = []
+ complex_list = []
with open(os.path.join(ENV_CONF_PATH, "default_agent_conf.json"), 'r', encoding='utf-8') as file:
# 鍔犺浇JSON鏁版嵁
agent_dict = json.load(file)
agent_list = agent_dict.get("basic", [])
+ complex_list = agent_dict.get("complex", [])
user = db.query(UserModel).filter_by(permission="admin").first()
for agent in agent_list:
dialog = db.query(DialogModel).filter(DialogModel.id == agent["id"]).first()
@@ -152,6 +155,30 @@
try:
dialog = DialogModel(id=agent["id"], name=agent["name"], description=agent["description"],
icon=agent["icon"], tenant_id=user.id if user else "", dialog_type=agent["dialogType"], mode=agent["mode"],parameters = json.dumps(agent["parameters"]))
+ db.add(dialog)
+ db.commit()
+ db.refresh(dialog)
+ except Exception as e:
+ print(e)
+ db.rollback()
+
+ for agent in complex_list:
+ dialog = db.query(ComplexChatModel).filter(ComplexChatModel.id == agent["id"]).first()
+ if dialog:
+ try:
+ dialog.name = agent["name"]
+ dialog.description = agent["description"]
+ dialog.icon = agent["icon"]
+ dialog.mode = agent["mode"]
+ dialog.chat_mode = agent["chat_mode"]
+ # dialog.parameters = json.dumps(agent["parameters"])
+ db.commit()
+ except Exception as e:
+ logger.error(e)
+ else:
+ try:
+ dialog = ComplexChatModel(id=agent["id"], name=agent["name"], description=agent["description"],
+ icon=agent["icon"], tenant_id=user.id if user else "", dialog_type=agent["dialogType"], mode=agent["mode"],chat_mode = agent["chat_mode"])
db.add(dialog)
db.commit()
db.refresh(dialog)
@@ -353,4 +380,36 @@
except Exception as e:
print(e)
+ db.rollback()
+
+
+
+async def sync_complex_api_token(db):
+ token = ""
+ try:
+ complex_list = db.query(ComplexChatModel).all()
+ for i in complex_list:
+ user_token = db.query(ApiTokenModel).filter(ApiTokenModel.app_id == i.id).first()
+ if not user_token:
+ chat = ChatBaseApply()
+ url = settings.dify_base_url + DF_CHAT_API_KEY.format(i.id)
+ access_token = await get_app_token(db, workflow_server)
+ param = await chat.chat_get(url, {}, await chat.get_headers(access_token))
+ if param and param.get("data"):
+ token = param.get("data", [{}])[0].get("token")
+ token_id = param.get("data", [{}])[0].get("id")
+ # dialog.parameters = json.dumps(param)
+ else:
+ param = await chat.chat_post(url, {}, await chat.get_headers(access_token))
+ if param:
+ token = param.get("token")
+ token_id = param.get("id")
+
+ if token:
+ db.add(ApiTokenModel(id=token_id, app_id=i.id, type="app", token=token))
+ db.commit()
+ print("df_api_token: 鏇存柊鎴愬姛锛�")
+
+ except Exception as e:
+ print(e)
db.rollback()
\ No newline at end of file
diff --git a/app/service/v2/mindmap.py b/app/service/v2/mindmap.py
index 79620f5..f6e576c 100644
--- a/app/service/v2/mindmap.py
+++ b/app/service/v2/mindmap.py
@@ -75,7 +75,6 @@
url = settings.dify_base_url + DF_CHAT_AGENT
chat_request = json.loads(session.query)
if session.mindmap:
-
inputs = {"is_deep": chat_request.get("isDeep", 1)}
if session.chat_mode == complex_knowledge_chat:
inputs["query_json"] = json.dumps(
diff --git a/app/task/sync_account_token.py b/app/task/sync_account_token.py
index 55e0082..55b1893 100644
--- a/app/task/sync_account_token.py
+++ b/app/task/sync_account_token.py
@@ -38,7 +38,7 @@
async def sync_token_chat(token_id, url, data, is_crypt, ping_url, token):
db = SessionLocal()
# pdb = PostgresqlSessionLocal()
- current_time = datetime.now() - timedelta(hours=12)
+ current_time = datetime.now() - timedelta(hours=24)
try:
user_token = db.query(UserTokenModel).filter(UserTokenModel.id == token_id).first()
chat = ChatBaseApply()
--
Gitblit v1.8.0