zhaoqingang
2025-03-12 3b1bf7da6771bd1d6852d3dcc1f906d5ae5c95d1
增加内容优化
11个文件已修改
324 ■■■■ 已修改文件
app/api/files.py 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/config/const.py 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/config/env_conf/default_agent_conf.json 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/init_config/init_run_data.py 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/models/v2/chat.py 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/service/files.py 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/service/v2/app_driver/chat_agent.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/service/v2/chat.py 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/service/v2/initialize_data.py 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/service/v2/mindmap.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/task/sync_account_token.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
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")
    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")
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
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"
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"
    }
  ]
}
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)  # 默认的角色资源
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
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)
    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
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:
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")
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()
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(
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()