| | |
| | | import io |
| | | import time |
| | | from typing import Optional, List |
| | | |
| | | import requests |
| | |
| | | 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 |
| | |
| | | yield data |
| | | |
| | | 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") |
| | |
| | | |
| | | ### ----------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" |
| | |
| | | agent_chat = "agent-chat" |
| | | base_chat = "chat" |
| | | basic_chat = "agent-basic" |
| | | complex_chat = "complex-chat" |
| | | |
| | | |
| | | ### ------------------------------ |
| | |
| | | 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" |
| | |
| | | "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" |
| | | } |
| | | ] |
| | | } |
| | |
| | | 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 |
| | | |
| | | |
| | |
| | | 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) # 默认的角色资源 |
| | | |
| | | |
| | |
| | | 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] = [] |
| | | |
| | |
| | | "knowledgeId": self.knowledgeId, |
| | | "files": self.files, |
| | | "isDeep": self.isDeep, |
| | | "optimizeType": self.optimizeType, |
| | | } |
| | | |
| | | |
| | |
| | | } |
| | | |
| | | def log_to_json(self): |
| | | if self.message_type == 1: |
| | | 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) |
| | | '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 [], |
| | | } |
| | | |
| | | |
| | |
| | | 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 |
| | |
| | | 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 |
| | | |
| | | |
| | |
| | | text = await read_word(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 |
| | |
| | | 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 |
| | |
| | | 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: |
| | |
| | | import asyncio |
| | | import io |
| | | import json |
| | | import time |
| | | import uuid |
| | | |
| | | import fitz |
| | |
| | | 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 |
| | |
| | | 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": {}} |
| | |
| | | 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: |
| | |
| | | "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): |
| | |
| | | |
| | | 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): |
| | |
| | | error = "" |
| | | files = [] |
| | | node_list = [] |
| | | conversation_id = "" |
| | | token = await get_chat_token(db, chat_id) |
| | | chat, url = await get_chat_object(mode) |
| | | 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, |
| | |
| | | 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") |
| | |
| | | |
| | | |
| | | 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 |
| | |
| | | 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") |
| | |
| | | |
| | | 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() |
| | |
| | | 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) |
| | |
| | | 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() |
| | |
| | | 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( |
| | |
| | | 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() |