fetch_agent.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. from pickle import PROTO
  2. from typing import Dict, List, Tuple
  3. from sqlalchemy import create_engine, Column, String, Integer, Text
  4. from sqlalchemy.exc import IntegrityError
  5. from sqlalchemy.orm import sessionmaker
  6. from app.config.config import settings
  7. from app.config.const import RAGFLOW, BISHENG, DIFY
  8. from app.models import KnowledgeModel
  9. from app.models.dialog_model import DialogModel
  10. from app.models.user_model import UserAppModel
  11. from app.models.agent_model import AgentModel
  12. from app.models.base_model import SessionLocal, Base
  13. from app.service.v2.app_register import AppRegisterDao
  14. # 创建数据库引擎和会话工厂
  15. engine_bisheng = create_engine(settings.sgb_db_url)
  16. engine_ragflow = create_engine(settings.fwr_db_url)
  17. engine_dify = create_engine(settings.dify_database_url)
  18. SessionBisheng = sessionmaker(autocommit=False, autoflush=False, bind=engine_bisheng)
  19. SessionRagflow = sessionmaker(autocommit=False, autoflush=False, bind=engine_ragflow)
  20. SessionDify = sessionmaker(autocommit=False, autoflush=False, bind=engine_dify)
  21. class Flow(Base):
  22. __tablename__ = 'flow'
  23. id = Column(String(255), primary_key=True)
  24. name = Column(String(255), nullable=False)
  25. status = Column(Integer, nullable=False)
  26. description = Column(String(255), nullable=False)
  27. user_id = Column(Integer, nullable=False)
  28. class Dialog(Base):
  29. __tablename__ = 'dialog'
  30. id = Column(String(255), primary_key=True)
  31. name = Column(String(255), nullable=False)
  32. status = Column(String(1), nullable=False)
  33. description = Column(String(255), nullable=False)
  34. tenant_id = Column(String(36), nullable=False)
  35. class DfApps(Base):
  36. __tablename__ = 'apps'
  37. id = Column(String(36), primary_key=True)
  38. name = Column(String(255), nullable=False)
  39. status = Column(String(16), nullable=False)
  40. description = Column(Text, nullable=False)
  41. tenant_id = Column(String(36), nullable=False)
  42. mode = Column(String(36), nullable=False)
  43. class RgKnowledge(Base):
  44. __tablename__ = 'knowledgebase'
  45. id = Column(String(36), primary_key=True) # id
  46. name = Column(String(128)) # 名称
  47. permission = Column(String(32), default="me")
  48. tenant_id = Column(String(32)) # 创建人id
  49. description = Column(Text) # 说明
  50. status = Column(String(1)) # 状态
  51. doc_num = Column(Integer) # 文档
  52. class RgUserTenant(Base):
  53. __tablename__ = 'user_tenant'
  54. id = Column(String(36), primary_key=True) # id
  55. tenant_id = Column(String(32)) # 名称
  56. user_id = Column(String(32))
  57. role = Column(String(32)) # 创建人id
  58. # 解析名字
  59. def parse_names(names_str: str) -> List[str]:
  60. return [name.strip() for name in names_str.split(',')]
  61. BISHENG_NAMES_TO_SYNC = parse_names(settings.fetch_sgb_agent)
  62. RAGFLOW_NAMES_TO_SYNC = parse_names(settings.fetch_fwr_agent)
  63. def get_data_from_bisheng(names: List[str]) -> List[Tuple]:
  64. db = SessionBisheng()
  65. try:
  66. if names:
  67. query = db.query(Flow.id, Flow.name) \
  68. .filter(Flow.status == 2, Flow.name.in_(names))
  69. else:
  70. query = db.query(Flow.id, Flow.name) \
  71. .filter(Flow.status == 2)
  72. results = query.all()
  73. print(f"Executing query: {query}")
  74. # 格式化id为UUID
  75. formatted_results = [(format_uuid(row[0]), row[1]) for row in results]
  76. return formatted_results
  77. finally:
  78. db.close()
  79. def format_uuid(uuid_str: str) -> str:
  80. # 确保输入字符串长度为32
  81. if len(uuid_str) != 32:
  82. raise ValueError("Input string must be 32 characters long")
  83. # 插入连字符
  84. formatted_uuid = f"{uuid_str[:8]}-{uuid_str[8:12]}-{uuid_str[12:16]}-{uuid_str[16:20]}-{uuid_str[20:]}"
  85. return formatted_uuid
  86. def get_data_from_ragflow(names: List[str]) -> List[Tuple]:
  87. db = SessionRagflow()
  88. try:
  89. if names:
  90. query = db.query(Dialog.id, Dialog.name) \
  91. .filter(Dialog.status == 1, Dialog.name.in_(names))
  92. else:
  93. query = db.query(Dialog.id, Dialog.name) \
  94. .filter(Dialog.status == 1)
  95. results = query.all()
  96. print(f"Executing query: {query}")
  97. return results
  98. finally:
  99. db.close()
  100. def update_ids_in_local(data: List[Tuple]):
  101. db = SessionLocal()
  102. try:
  103. for row in data:
  104. name = row[1]
  105. new_id = row[0]
  106. existing_agent = db.query(AgentModel).filter_by(name=name).first()
  107. if existing_agent:
  108. existing_agent.id = new_id
  109. db.add(existing_agent)
  110. db.commit()
  111. except IntegrityError:
  112. db.rollback()
  113. raise
  114. finally:
  115. db.close()
  116. def initialize_agents():
  117. db = SessionLocal()
  118. try:
  119. count = db.query(AgentModel).count()
  120. if count > 0:
  121. result = db.query(AgentModel).delete()
  122. db.commit() # 提交事务
  123. initial_agents = [
  124. # ('80ee430a-e396-48c4-a12c-7c7cdf5eda51', 1, '报告生成', 'DIFY', 'report'),
  125. ('basic_excel_merge', 2, '报表合并', 'BASIC', 'excelMerge'),
  126. ('7638f00638a24c21a68ec6c49b304a35', 4, '文档智能', 'DIFY', 'documentIa'),
  127. ('da3451da89d911efb9490242ac190006', 3, '知识问答', 'RAGFLOW', 'knowledgeQA'),
  128. ('e96eb7a589db11ef87d20242ac190006', 5, '智能问答', 'RAGFLOW', 'chat'),
  129. ('basic_excel_talk', 6, '智能数据', 'BASIC', 'excelTalk'),
  130. ('basic_question_talk', 7, '出题组卷', 'BASIC', 'questionTalk'),
  131. ('9d75142a-66eb-4e23-b7d4-03efe4584915', 8, '小数绘图', 'DIFY', 'imageTalk'),
  132. ('basic_paper_talk', 9, '文档出卷', 'BASIC', 'paperTalk'),
  133. ('basic_report_clean', 10, '文档报告', 'DIFY', 'reportWorkflow')
  134. ]
  135. for agent in initial_agents:
  136. agent_id = format_uuid(agent[0]) if len(agent[0]) == 32 else agent[0]
  137. db.add(AgentModel(id=agent_id, sort=agent[1], name=agent[2], agent_type=agent[3], type=agent[4]))
  138. db.commit()
  139. print("Initial agents inserted successfully")
  140. except IntegrityError:
  141. db.rollback()
  142. raise
  143. finally:
  144. db.close()
  145. def sync_agents():
  146. try:
  147. # bisheng_data = get_data_from_bisheng(BISHENG_NAMES_TO_SYNC)
  148. ragflow_data = get_data_from_ragflow(RAGFLOW_NAMES_TO_SYNC)
  149. # update_ids_in_local(bisheng_data)
  150. update_ids_in_local(ragflow_data)
  151. print("Agents synchronized successfully")
  152. except Exception as e:
  153. print(f"Failed to sync agents: {str(e)}")
  154. def update_ids_in_local(data: List[Tuple]):
  155. db = SessionLocal()
  156. try:
  157. for row in data:
  158. name = row[1]
  159. new_id = row[0]
  160. existing_agent = db.query(AgentModel).filter_by(name=name).first()
  161. if existing_agent:
  162. existing_agent.id = new_id
  163. db.add(existing_agent)
  164. db.commit()
  165. except IntegrityError:
  166. db.rollback()
  167. raise
  168. finally:
  169. db.close()
  170. def get_rag_user_id(db, tenant_id, app_type):
  171. user = db.query(UserAppModel).filter(UserAppModel.app_type==app_type, UserAppModel.app_id==tenant_id).first()
  172. if user:
  173. return user.user_id
  174. return tenant_id
  175. def get_data_from_bisheng_v2(names: List[str]) -> List[Dict]:
  176. db = SessionBisheng()
  177. try:
  178. if names:
  179. query = db.query(Flow.id, Flow.name, Flow.description, Flow.status, Flow.user_id) \
  180. .filter(Flow.name.in_(names), Flow.status=="1")
  181. else:
  182. query = db.query(Flow.id, Flow.name, Flow.description, Flow.status, Flow.user_id).filter(Flow.status=="1")
  183. results = query.all()
  184. # print(f"Executing query: {query}")
  185. # 格式化id为UUID
  186. formatted_results = [{"id":row[0], "name": row[1], "description": row[2], "status": row[3], "user_id": str(row[4]), "mode": "agent-dialog"} for row in results]
  187. return formatted_results
  188. finally:
  189. db.close()
  190. def get_data_from_ragflow_v2(names: List[str]) -> List[Dict]:
  191. db = SessionRagflow()
  192. try:
  193. if names:
  194. query = db.query(Dialog.id, Dialog.name, Dialog.description, Dialog.status, Dialog.tenant_id) \
  195. .filter( Dialog.name.in_(names), Dialog.status == "1")
  196. else:
  197. query = db.query(Dialog.id, Dialog.name, Dialog.description, Dialog.status, Dialog.tenant_id).filter( Dialog.status == "1")
  198. results = query.all()
  199. formatted_results = [
  200. {"id": row[0], "name": row[1], "description": row[2], "status": "1" if row[3] == "1" else "2",
  201. "user_id": str(row[4]), "mode": "agent-dialog"} for row in results]
  202. return formatted_results
  203. finally:
  204. db.close()
  205. def get_data_from_dify_v2(names: List[str]) -> List[Dict]:
  206. db = SessionDify()
  207. try:
  208. if names:
  209. query = db.query(DfApps.id, DfApps.name, DfApps.description, DfApps.status, DfApps.tenant_id, DfApps.mode) \
  210. .filter( DfApps.name.in_(names))
  211. else:
  212. query = db.query(DfApps.id, DfApps.name, DfApps.description, DfApps.status, DfApps.tenant_id, DfApps.mode)
  213. results = query.all()
  214. formatted_results = [
  215. {"id": str(row[0]), "name": row[1], "description": row[2], "status": "1",
  216. "user_id": str(row[4]), "mode": row[5]} for row in results]
  217. return formatted_results
  218. finally:
  219. db.close()
  220. def update_ids_in_local_v2(data: List[Dict], dialog_type:str):
  221. db = SessionLocal()
  222. agent_id_list = []
  223. type_dict = {"1": RAGFLOW,"2": BISHENG,"4": DIFY}
  224. try:
  225. for row in data:
  226. agent_id_list.append(row["id"])
  227. existing_agent = db.query(DialogModel).filter_by(id=row["id"]).first()
  228. if existing_agent:
  229. existing_agent.name = row["name"]
  230. existing_agent.description = row["description"]
  231. # existing_agent.status = row["status"]
  232. existing_agent.mode = row["mode"]
  233. # existing_agent.tenant_id = get_rag_user_id(db, row["user_id"], type_dict[dialog_type])
  234. else:
  235. existing = DialogModel(id=row["id"], status=row["status"], name=row["name"], description=row["description"], tenant_id=get_rag_user_id(db, row["user_id"], type_dict[dialog_type]), dialog_type=dialog_type, mode=row["mode"])
  236. db.add(existing)
  237. db.commit()
  238. for dialog in db.query(DialogModel).filter_by(dialog_type=dialog_type).all():
  239. if dialog.id not in agent_id_list:
  240. # print(dialog.id)
  241. db.query(DialogModel).filter_by(id=dialog.id).update({"status": "2"})
  242. db.commit()
  243. except IntegrityError:
  244. db.rollback()
  245. raise
  246. finally:
  247. db.close()
  248. def get_data_from_ragflow_knowledge():
  249. db = SessionRagflow()
  250. try:
  251. results = db.query(RgKnowledge.id, RgKnowledge.name, RgKnowledge.description, RgKnowledge.status, RgKnowledge.tenant_id, RgKnowledge.doc_num, RgKnowledge.permission).all()
  252. formatted_results = [
  253. {"id": row[0], "name": row[1], "description": row[2], "status": str(row[3]),
  254. "user_id": str(row[4]), "doc_num": row[5], "permission": row[6]} for row in results]
  255. return formatted_results
  256. finally:
  257. db.close()
  258. def sync_agents_v2():
  259. db = SessionLocal()
  260. try:
  261. app_register = AppRegisterDao(db).get_apps()
  262. for app in app_register:
  263. if app["id"] == RAGFLOW:
  264. ragflow_data = get_data_from_ragflow_v2([])
  265. if ragflow_data:
  266. update_ids_in_local_v2(ragflow_data, "1")
  267. elif app["id"] == BISHENG:
  268. bisheng_data = get_data_from_bisheng_v2([])
  269. if bisheng_data:
  270. update_ids_in_local_v2(bisheng_data, "2")
  271. elif app["id"] == DIFY:
  272. dify_data = get_data_from_dify_v2([])
  273. if dify_data:
  274. update_ids_in_local_v2(dify_data, "4")
  275. print("v2 Agents synchronized successfully")
  276. except Exception as e:
  277. print(f"v2 Failed to sync agents: {str(e)}")
  278. finally:
  279. db.close()
  280. def update_ids_in_local_knowledge(data, klg_type):
  281. type_dict = {"1": RAGFLOW, "2": BISHENG, "4": DIFY}
  282. db = SessionLocal()
  283. agent_id_list = []
  284. try:
  285. for row in data:
  286. agent_id_list.append(row["id"])
  287. existing_agent = db.query(KnowledgeModel).filter_by(id=row["id"]).first()
  288. if existing_agent:
  289. existing_agent.name = row["name"]
  290. existing_agent.description = row["description"]
  291. # existing_agent.tenant_id = get_rag_user_id(db, row["user_id"], type_dict[klg_type])
  292. existing_agent.permission = row["permission"]
  293. existing_agent.documents = row["doc_num"]
  294. existing_agent.status = row["status"]
  295. else:
  296. existing = KnowledgeModel(id=row["id"], name=row["name"], description=row["description"],
  297. tenant_id=get_rag_user_id(db, row["user_id"], type_dict[klg_type]),status=row["status"],
  298. knowledge_type=1, permission=row["permission"], documents=row["doc_num"])
  299. db.add(existing)
  300. db.commit()
  301. for dialog in db.query(KnowledgeModel).filter_by(knowledge_type=klg_type).all():
  302. if dialog.id not in agent_id_list:
  303. db.query(KnowledgeModel).filter_by(id=dialog.id).delete()
  304. db.commit()
  305. except IntegrityError:
  306. db.rollback()
  307. raise
  308. finally:
  309. db.close()
  310. def get_one_from_ragflow_knowledge(klg_id):
  311. db = SessionRagflow()
  312. try:
  313. row = db.query(RgKnowledge.id, RgKnowledge.name, RgKnowledge.description, RgKnowledge.status, RgKnowledge.tenant_id, RgKnowledge.doc_num, RgKnowledge.permission).filter(RgKnowledge.id==klg_id).first()
  314. return {"id": row[0], "name": row[1], "description": row[2], "status": str(row[3]),
  315. "user_id": str(row[4]), "doc_num": row[5], "permission": row[6]} if row else {}
  316. finally:
  317. db.close()
  318. def sync_knowledge():
  319. db = SessionLocal()
  320. try:
  321. app_register = AppRegisterDao(db).get_apps()
  322. for app in app_register:
  323. if app["id"] == RAGFLOW:
  324. ragflow_data = get_data_from_ragflow_knowledge()
  325. if ragflow_data:
  326. update_ids_in_local_knowledge(ragflow_data, "1")
  327. # elif app["id"] == BISHENG:
  328. # bisheng_data = get_data_from_bisheng_v2([])
  329. # update_ids_in_local_v2(bisheng_data, "2")
  330. # elif app["id"] == DIFY:
  331. # dify_data = get_data_from_dify_v2([])
  332. # update_ids_in_local_v2(dify_data, "4")
  333. print("sync knowledge successfully")
  334. except Exception as e:
  335. print(f"Failed to sync knowledge: {str(e)}")
  336. finally:
  337. db.close()
  338. def update_ragflow_user_tenant(user_id: str):
  339. db = SessionRagflow()
  340. try:
  341. if user_id:
  342. db.query(RgUserTenant).filter( RgUserTenant.user_id==user_id, RgUserTenant.role=="invite").update({"role": "normal"})
  343. db.query(RgUserTenant).filter( RgUserTenant.tenant_id==user_id, RgUserTenant.role=="invite").update({"role": "normal"})
  344. else:
  345. db.query(RgUserTenant).filter(RgUserTenant.role=="invite").update({"role": "normal"})
  346. db.commit()
  347. finally:
  348. db.close()
  349. if __name__ == "__main__":
  350. # a = get_data_from_dify_v2([])
  351. # print(a)
  352. update_ragflow_user_tenant("")