knowledge.py 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. from django.utils.translation import gettext_lazy as _
  2. from drf_spectacular.utils import extend_schema
  3. from rest_framework.parsers import MultiPartParser
  4. from rest_framework.request import Request
  5. from rest_framework.views import APIView
  6. from common.auth import TokenAuth
  7. from common.auth.authentication import has_permissions, check_batch_permissions, get_is_permissions
  8. from common.constants.permission_constants import PermissionConstants, RoleConstants, ViewPermission, CompareConstants
  9. from common.log.log import log
  10. from common import result
  11. from knowledge.api.knowledge import KnowledgeBaseCreateAPI, KnowledgeWebCreateAPI, KnowledgeTreeReadAPI, \
  12. KnowledgeEditAPI, KnowledgeReadAPI, KnowledgePageAPI, SyncWebAPI, GenerateRelatedAPI, HitTestAPI, EmbeddingAPI, \
  13. GetModelAPI, KnowledgeExportAPI, KnowledgeBatchOperateAPI, KnowledgeImportAPI
  14. from knowledge.models import KnowledgeScope, Knowledge, Document, Paragraph
  15. from knowledge.serializers.common import get_knowledge_operation_object
  16. from knowledge.serializers.knowledge import KnowledgeSerializer, KnowledgeBatchOperateSerializer
  17. from models_provider.serializers.model_serializer import ModelSerializer
  18. from tools.api.tool import GetInternalToolAPI
  19. from django.db.models import QuerySet, Count, Sum
  20. def get_knowledge_operation_object_batch(knowledge_id_list):
  21. knowledge_model_list = QuerySet(model=Knowledge).filter(id__in=knowledge_id_list)
  22. if knowledge_model_list is not None:
  23. return {
  24. "name": f'[{",".join([app.name for app in knowledge_model_list])}]',
  25. 'knowledge_list': [{'name': app.name} for app in knowledge_model_list]
  26. }
  27. return {}
  28. class KnowledgeView(APIView):
  29. authentication_classes = [TokenAuth]
  30. @extend_schema(
  31. methods=['GET'],
  32. description=_('Get knowledge by folder'),
  33. summary=_('Get knowledge by folder'),
  34. operation_id=_('Get knowledge by folder'), # type: ignore
  35. parameters=KnowledgeTreeReadAPI.get_parameters(),
  36. responses=KnowledgeTreeReadAPI.get_response(),
  37. tags=[_('Knowledge Base')] # type: ignore
  38. )
  39. @has_permissions(
  40. PermissionConstants.KNOWLEDGE_READ.get_workspace_permission(),
  41. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
  42. )
  43. def get(self, request: Request, workspace_id: str):
  44. return result.success(KnowledgeSerializer.Query(
  45. data={
  46. 'workspace_id': workspace_id,
  47. 'folder_id': request.query_params.get('folder_id'),
  48. 'name': request.query_params.get('name'),
  49. 'desc': request.query_params.get("desc"),
  50. 'scope': KnowledgeScope.WORKSPACE,
  51. 'user_id': request.user.id
  52. }
  53. ).list())
  54. class Operate(APIView):
  55. authentication_classes = [TokenAuth]
  56. @extend_schema(
  57. methods=['PUT'],
  58. description=_('Edit knowledge'),
  59. summary=_('Edit knowledge'),
  60. operation_id=_('Edit knowledge'), # type: ignore
  61. parameters=KnowledgeEditAPI.get_parameters(),
  62. request=KnowledgeEditAPI.get_request(),
  63. responses=KnowledgeEditAPI.get_response(),
  64. tags=[_('Knowledge Base')] # type: ignore
  65. )
  66. @has_permissions(
  67. PermissionConstants.KNOWLEDGE_EDIT.get_workspace_knowledge_permission(),
  68. PermissionConstants.KNOWLEDGE_EDIT.get_workspace_permission_workspace_manage_role(),
  69. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  70. ViewPermission([RoleConstants.USER.get_workspace_role()],
  71. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  72. )
  73. @log(
  74. menu='Knowledge Base', operate="Modify knowledge base information",
  75. get_operation_object=lambda r, keywords: get_knowledge_operation_object(keywords.get('knowledge_id')),
  76. )
  77. def put(self, request: Request, workspace_id: str, knowledge_id: str):
  78. return result.success(KnowledgeSerializer.Operate(
  79. data={'user_id': request.user.id, 'workspace_id': workspace_id, 'knowledge_id': knowledge_id}
  80. ).edit(request.data))
  81. @extend_schema(
  82. methods=['DELETE'],
  83. description=_('Delete knowledge'),
  84. summary=_('Delete knowledge'),
  85. operation_id=_('Delete knowledge'), # type: ignore
  86. parameters=KnowledgeBaseCreateAPI.get_parameters(),
  87. request=KnowledgeBaseCreateAPI.get_request(),
  88. responses=KnowledgeBaseCreateAPI.get_response(),
  89. tags=[_('Knowledge Base')] # type: ignore
  90. )
  91. @has_permissions(
  92. PermissionConstants.KNOWLEDGE_DELETE.get_workspace_knowledge_permission(),
  93. PermissionConstants.KNOWLEDGE_DELETE.get_workspace_permission_workspace_manage_role(),
  94. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  95. ViewPermission([RoleConstants.USER.get_workspace_role()],
  96. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  97. )
  98. @log(
  99. menu='Knowledge Base', operate="Delete knowledge base",
  100. get_operation_object=lambda r, keywords: get_knowledge_operation_object(keywords.get('knowledge_id')),
  101. )
  102. def delete(self, request: Request, workspace_id: str, knowledge_id: str):
  103. return result.success(KnowledgeSerializer.Operate(
  104. data={'user_id': request.user.id, 'workspace_id': workspace_id, 'knowledge_id': knowledge_id}
  105. ).delete())
  106. @extend_schema(
  107. methods=['GET'],
  108. description=_('Get knowledge'),
  109. summary=_('Get knowledge'),
  110. operation_id=_('Get knowledge'), # type: ignore
  111. parameters=KnowledgeReadAPI.get_parameters(),
  112. responses=KnowledgeReadAPI.get_response(),
  113. tags=[_('Knowledge Base')] # type: ignore
  114. )
  115. @has_permissions(
  116. PermissionConstants.KNOWLEDGE_READ.get_workspace_knowledge_permission(),
  117. PermissionConstants.KNOWLEDGE_READ.get_workspace_permission_workspace_manage_role(),
  118. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  119. ViewPermission([RoleConstants.USER.get_workspace_role()],
  120. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  121. )
  122. def get(self, request: Request, workspace_id: str, knowledge_id: str):
  123. return result.success(KnowledgeSerializer.Operate(
  124. data={'user_id': request.user.id, 'workspace_id': workspace_id, 'knowledge_id': knowledge_id}
  125. ).one())
  126. class BatchDelete(APIView):
  127. authentication_classes = [TokenAuth]
  128. @extend_schema(
  129. methods=['PUT'],
  130. description=_("Batch delete knowledge"),
  131. summary=_("Batch delete knowledge"),
  132. operation_id=_("Batch delete knowledge"),
  133. parameters=KnowledgeBatchOperateAPI.get_parameters(),
  134. request=KnowledgeBatchOperateAPI.get_request(),
  135. responses=result.DefaultResultSerializer,
  136. tags=[_('Knowledge Base')]
  137. )
  138. @has_permissions(PermissionConstants.KNOWLEDGE_BATCH_DELETE.get_workspace_permission(),
  139. RoleConstants.USER.get_workspace_role(),
  140. RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
  141. )
  142. def put(self, request: Request, workspace_id: str):
  143. id_list = request.data.get('id_list', [])
  144. permitted_ids = check_batch_permissions(
  145. request, id_list, 'knowledge_id',
  146. (PermissionConstants.KNOWLEDGE_DELETE.get_workspace_knowledge_permission(),
  147. PermissionConstants.KNOWLEDGE_DELETE.get_workspace_permission_workspace_manage_role(),
  148. ViewPermission([RoleConstants.USER.get_workspace_role()],
  149. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()],
  150. CompareConstants.AND),
  151. RoleConstants.WORKSPACE_MANAGE.get_workspace_role()), workspace_id=workspace_id
  152. )
  153. @log(menu='Knowledge Base', operate='Batch delete knowledge',
  154. get_operation_object=lambda r, k: get_knowledge_operation_object_batch(permitted_ids))
  155. def inner(view, r, **kwargs):
  156. return KnowledgeBatchOperateSerializer(
  157. data={'workspace_id': workspace_id, 'user_id': request.user.id}
  158. ).batch_delete({'id_list': permitted_ids})
  159. return result.success(inner(self, request, workspace_id=workspace_id))
  160. class BatchMove(APIView):
  161. authentication_classes = [TokenAuth]
  162. @extend_schema(
  163. methods=['PUT'],
  164. description=_("Batch move knowledge"),
  165. summary=_("Batch move knowledge"),
  166. operation_id=_("Batch move knowledge"),
  167. parameters=KnowledgeBatchOperateAPI.get_parameters(),
  168. request=KnowledgeBatchOperateAPI.get_move_request(),
  169. responses=result.DefaultResultSerializer,
  170. tags=[_('Knowledge Base')]
  171. )
  172. @has_permissions(PermissionConstants.KNOWLEDGE_BATCH_MOVE.get_workspace_permission(),
  173. RoleConstants.USER.get_workspace_role(),
  174. RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
  175. )
  176. def put(self, request: Request, workspace_id: str):
  177. id_list = request.data.get('id_list', [])
  178. permitted_ids = check_batch_permissions(
  179. request, id_list, 'knowledge_id',
  180. (PermissionConstants.KNOWLEDGE_EDIT.get_workspace_knowledge_permission(),
  181. PermissionConstants.KNOWLEDGE_EDIT.get_workspace_permission_workspace_manage_role(),
  182. ViewPermission([RoleConstants.USER.get_workspace_role()],
  183. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()],
  184. CompareConstants.AND),
  185. RoleConstants.WORKSPACE_MANAGE.get_workspace_role()),
  186. workspace_id=workspace_id
  187. )
  188. @log(menu='Knowledge Base', operate='Batch move knowledge',
  189. get_operation_object=lambda r, k: get_knowledge_operation_object_batch(permitted_ids))
  190. def inner(view, r, **kwargs):
  191. return KnowledgeBatchOperateSerializer(
  192. data={'workspace_id': workspace_id, 'user_id': request.user.id}
  193. ).batch_move({'id_list': permitted_ids, 'folder_id': request.data.get('folder_id')})
  194. return result.success(inner(self, request, workspace_id=workspace_id))
  195. class Page(APIView):
  196. authentication_classes = [TokenAuth]
  197. @extend_schema(
  198. methods=['GET'],
  199. description=_('Get the knowledge base paginated list'),
  200. summary=_('Get the knowledge base paginated list'),
  201. operation_id=_('Get the knowledge base paginated list'), # type: ignore
  202. parameters=KnowledgePageAPI.get_parameters(),
  203. responses=KnowledgePageAPI.get_response(),
  204. tags=[_('Knowledge Base')] # type: ignore
  205. )
  206. @has_permissions(
  207. PermissionConstants.KNOWLEDGE_READ.get_workspace_permission(),
  208. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
  209. )
  210. def get(self, request: Request, workspace_id: str, current_page: int, page_size: int):
  211. return result.success(KnowledgeSerializer.Query(
  212. data={
  213. 'workspace_id': workspace_id,
  214. 'folder_id': request.query_params.get('folder_id'),
  215. 'name': request.query_params.get('name'),
  216. 'desc': request.query_params.get("desc"),
  217. 'scope': KnowledgeScope.WORKSPACE,
  218. 'user_id': request.user.id,
  219. 'create_user': request.query_params.get('create_user'),
  220. }
  221. ).page(current_page, page_size))
  222. class SyncWeb(APIView):
  223. authentication_classes = [TokenAuth]
  224. @extend_schema(
  225. methods=['PUT'],
  226. summary=_("Synchronize the knowledge base of the website"),
  227. description=_("Synchronize the knowledge base of the website"),
  228. operation_id=_("Synchronize the knowledge base of the website"), # type: ignore
  229. parameters=SyncWebAPI.get_parameters(),
  230. request=SyncWebAPI.get_request(),
  231. responses=SyncWebAPI.get_response(),
  232. tags=[_('Knowledge Base')] # type: ignore
  233. )
  234. @has_permissions(
  235. PermissionConstants.KNOWLEDGE_SYNC.get_workspace_knowledge_permission(),
  236. PermissionConstants.KNOWLEDGE_SYNC.get_workspace_permission_workspace_manage_role(),
  237. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  238. ViewPermission([RoleConstants.USER.get_workspace_role()],
  239. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  240. )
  241. @log(
  242. menu='Knowledge Base', operate="Synchronize the knowledge base of the website",
  243. get_operation_object=lambda r, keywords: get_knowledge_operation_object(keywords.get('knowledge_id')),
  244. )
  245. def put(self, request: Request, workspace_id: str, knowledge_id: str):
  246. return result.success(KnowledgeSerializer.SyncWeb(
  247. data={
  248. 'workspace_id': workspace_id,
  249. 'sync_type': request.query_params.get('sync_type'),
  250. 'knowledge_id': knowledge_id,
  251. 'user_id': str(request.user.id)
  252. }
  253. ).sync())
  254. class HitTest(APIView):
  255. authentication_classes = [TokenAuth]
  256. @extend_schema(
  257. methods=['POST'],
  258. summary=_('Hit test list'),
  259. description=_('Hit test list'),
  260. operation_id=_('Hit test list'), # type: ignore
  261. parameters=HitTestAPI.get_parameters(),
  262. request=HitTestAPI.get_request(),
  263. responses=HitTestAPI.get_response(),
  264. tags=[_('Knowledge Base')] # type: ignore
  265. )
  266. @has_permissions(
  267. PermissionConstants.KNOWLEDGE_HIT_TEST.get_workspace_knowledge_permission(),
  268. PermissionConstants.KNOWLEDGE_HIT_TEST.get_workspace_permission_workspace_manage_role(),
  269. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  270. ViewPermission([RoleConstants.USER.get_workspace_role()],
  271. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  272. )
  273. def post(self, request: Request, workspace_id: str, knowledge_id: str):
  274. return result.success(KnowledgeSerializer.HitTest(
  275. data={
  276. 'workspace_id': workspace_id,
  277. 'knowledge_id': knowledge_id,
  278. 'user_id': request.user.id,
  279. "query_text": request.data.get("query_text"),
  280. "top_number": request.data.get("top_number"),
  281. 'similarity': request.data.get('similarity'),
  282. 'search_mode': request.data.get('search_mode')
  283. }
  284. ).hit_test())
  285. class StoreKnowledge(APIView):
  286. authentication_classes = [TokenAuth]
  287. @extend_schema(
  288. methods=['GET'],
  289. description=_("Get Appstore tools"),
  290. summary=_("Get Appstore tools"),
  291. operation_id=_("Get Appstore tools"), # type: ignore
  292. responses=GetInternalToolAPI.get_response(),
  293. tags=[_("Tool")] # type: ignore
  294. )
  295. def get(self, request: Request):
  296. return result.success(KnowledgeSerializer.StoreKnowledge(data={
  297. 'user_id': request.user.id,
  298. 'name': request.query_params.get('name', ''),
  299. }).get_appstore_templates())
  300. class Embedding(APIView):
  301. authentication_classes = [TokenAuth]
  302. @extend_schema(
  303. methods=['PUT'],
  304. summary=_('Re-vectorize'),
  305. description=_('Re-vectorize'),
  306. operation_id=_('Re-vectorize'), # type: ignore
  307. parameters=EmbeddingAPI.get_parameters(),
  308. request=EmbeddingAPI.get_request(),
  309. responses=EmbeddingAPI.get_response(),
  310. tags=[_('Knowledge Base')] # type: ignore
  311. )
  312. @has_permissions(
  313. PermissionConstants.KNOWLEDGE_VECTOR.get_workspace_knowledge_permission(),
  314. PermissionConstants.KNOWLEDGE_VECTOR.get_workspace_permission_workspace_manage_role(),
  315. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  316. ViewPermission([RoleConstants.USER.get_workspace_role()],
  317. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  318. )
  319. @log(
  320. menu='Knowledge Base', operate='Re-vectorize',
  321. get_operation_object=lambda r, k: get_knowledge_operation_object(k.get('knowledge_id')),
  322. )
  323. def put(self, request: Request, workspace_id: str, knowledge_id: str):
  324. return result.success(KnowledgeSerializer.Operate(
  325. data={'knowledge_id': knowledge_id, 'workspace_id': workspace_id, 'user_id': request.user.id}
  326. ).embedding())
  327. class Export(APIView):
  328. authentication_classes = [TokenAuth]
  329. @extend_schema(
  330. summary=_('Export knowledge base'),
  331. operation_id=_('Export knowledge base'), # type: ignore
  332. parameters=KnowledgeExportAPI.get_parameters(),
  333. responses=KnowledgeExportAPI.get_response(),
  334. tags=[_('Knowledge Base')] # type: ignore
  335. )
  336. @has_permissions(
  337. PermissionConstants.KNOWLEDGE_EXPORT.get_workspace_knowledge_permission(),
  338. PermissionConstants.KNOWLEDGE_EXPORT.get_workspace_permission_workspace_manage_role(),
  339. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  340. ViewPermission([RoleConstants.USER.get_workspace_role()],
  341. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  342. )
  343. @log(
  344. menu='Knowledge Base', operate="Export knowledge base",
  345. get_operation_object=lambda r, keywords: get_knowledge_operation_object(keywords.get('knowledge_id')),
  346. )
  347. def get(self, request: Request, workspace_id: str, knowledge_id: str):
  348. return KnowledgeSerializer.Operate(data={
  349. 'workspace_id': workspace_id, 'knowledge_id': knowledge_id, 'user_id': request.user.id
  350. }).export_excel()
  351. class ExportZip(APIView):
  352. authentication_classes = [TokenAuth]
  353. @extend_schema(
  354. summary=_('Export knowledge base containing images'),
  355. operation_id=_('Export knowledge base containing images'), # type: ignore
  356. parameters=KnowledgeExportAPI.get_parameters(),
  357. responses=KnowledgeExportAPI.get_response(),
  358. tags=[_('Knowledge Base')] # type: ignore
  359. )
  360. @has_permissions(
  361. PermissionConstants.KNOWLEDGE_EXPORT.get_workspace_knowledge_permission(),
  362. PermissionConstants.KNOWLEDGE_EXPORT.get_workspace_permission_workspace_manage_role(),
  363. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  364. ViewPermission([RoleConstants.USER.get_workspace_role()],
  365. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  366. )
  367. @log(
  368. menu='Knowledge Base', operate="Export knowledge base containing images",
  369. get_operation_object=lambda r, keywords: get_knowledge_operation_object(keywords.get('knowledge_id')),
  370. )
  371. def get(self, request: Request, workspace_id: str, knowledge_id: str):
  372. return KnowledgeSerializer.Operate(data={
  373. 'workspace_id': workspace_id, 'knowledge_id': knowledge_id, 'user_id': request.user.id
  374. }).export_zip()
  375. class ExportKnowledge(APIView):
  376. authentication_classes = [TokenAuth]
  377. @extend_schema(
  378. summary=_('Export knowledge bundle'),
  379. operation_id=_('Export knowledge bundle'), # type: ignore
  380. parameters=KnowledgeExportAPI.get_parameters(),
  381. responses=KnowledgeExportAPI.get_response(),
  382. tags=[_('Knowledge Base')] # type: ignore
  383. )
  384. @has_permissions(
  385. PermissionConstants.KNOWLEDGE_EXPORT.get_workspace_knowledge_permission(),
  386. PermissionConstants.KNOWLEDGE_EXPORT.get_workspace_permission_workspace_manage_role(),
  387. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  388. ViewPermission([RoleConstants.USER.get_workspace_role()],
  389. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  390. )
  391. @log(
  392. menu='Knowledge Base', operate="Export knowledge bundle",
  393. get_operation_object=lambda r, keywords: get_knowledge_operation_object(keywords.get('knowledge_id')),
  394. )
  395. def get(self, request: Request, workspace_id: str, knowledge_id: str):
  396. return KnowledgeSerializer.Operate(data={
  397. 'workspace_id': workspace_id, 'knowledge_id': knowledge_id, 'user_id': request.user.id
  398. }).export_knowledge()
  399. class ImportKnowledge(APIView):
  400. authentication_classes = [TokenAuth]
  401. parser_classes = [MultiPartParser]
  402. @extend_schema(
  403. methods=['POST'],
  404. description=_('Import knowledge bundle'),
  405. summary=_('Import knowledge bundle'),
  406. operation_id=_('Import knowledge bundle'),
  407. parameters=KnowledgeImportAPI.get_parameters(),
  408. request=KnowledgeImportAPI.get_request(),
  409. responses=KnowledgeImportAPI.get_response(),
  410. tags=[_('Knowledge Base')]
  411. )
  412. @has_permissions(
  413. PermissionConstants.KNOWLEDGE_CREATE.get_workspace_permission(),
  414. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  415. RoleConstants.USER.get_workspace_role()
  416. )
  417. @log(
  418. menu='Knowledge Base', operate="Import knowledge bundle",
  419. )
  420. def post(self, request: Request, workspace_id: str):
  421. is_import_tool = get_is_permissions(request, workspace_id=workspace_id)(
  422. PermissionConstants.TOOL_IMPORT.get_workspace_permission(),
  423. PermissionConstants.TOOL_IMPORT.get_workspace_permission_workspace_manage_role(),
  424. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
  425. )
  426. return result.success(
  427. KnowledgeSerializer.ImportKnowledge(
  428. data={'workspace_id': workspace_id, 'user_id': request.user.id, 'folder_id': request.data.get('folder_id',workspace_id)}
  429. ).import_knowledge(request.FILES.get('file'), is_import_tool)
  430. )
  431. class GenerateRelated(APIView):
  432. authentication_classes = [TokenAuth]
  433. @extend_schema(
  434. methods=['PUT'],
  435. summary=_('Generate related'),
  436. description=_('Generate related'),
  437. operation_id=_('Generate related'), # type: ignore
  438. parameters=GenerateRelatedAPI.get_parameters(),
  439. request=GenerateRelatedAPI.get_request(),
  440. responses=GenerateRelatedAPI.get_response(),
  441. tags=[_('Knowledge Base')] # type: ignore
  442. )
  443. @has_permissions(
  444. PermissionConstants.KNOWLEDGE_GENERATE.get_workspace_knowledge_permission(),
  445. PermissionConstants.KNOWLEDGE_GENERATE.get_workspace_permission_workspace_manage_role(),
  446. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  447. ViewPermission([RoleConstants.USER.get_workspace_role()],
  448. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  449. )
  450. @log(
  451. menu='document', operate='Generate related documents',
  452. get_operation_object=lambda r, k: get_knowledge_operation_object(k.get('knowledge_id')),
  453. )
  454. def put(self, request: Request, workspace_id: str, knowledge_id: str):
  455. return result.success(KnowledgeSerializer.Operate(
  456. data={'knowledge_id': knowledge_id, 'workspace_id': workspace_id, 'user_id': request.user.id}
  457. ).generate_related(request.data))
  458. class Model(APIView):
  459. authentication_classes = [TokenAuth]
  460. @extend_schema(
  461. methods=['GET'],
  462. summary=_('Get model for knowledge base'),
  463. description=_('Get model for knowledge base'),
  464. operation_id=_('Get model for knowledge base'), # type: ignore
  465. parameters=GetModelAPI.get_parameters(),
  466. responses=GetModelAPI.get_response(),
  467. tags=[_('Knowledge Base')] # type: ignore
  468. )
  469. @has_permissions(
  470. PermissionConstants.KNOWLEDGE_EDIT.get_workspace_permission(),
  471. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
  472. )
  473. def get(self, request: Request, workspace_id: str):
  474. return result.success(ModelSerializer.Query(
  475. data={
  476. 'workspace_id': workspace_id,
  477. 'model_type': 'LLM'
  478. }
  479. ).list(workspace_id, True))
  480. class EmbeddingModel(APIView):
  481. authentication_classes = [TokenAuth]
  482. @has_permissions(
  483. PermissionConstants.KNOWLEDGE_EDIT.get_workspace_permission(),
  484. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
  485. )
  486. def get(self, request: Request, workspace_id: str):
  487. return result.success(ModelSerializer.Query(
  488. data={
  489. 'workspace_id': workspace_id,
  490. 'model_type': 'EMBEDDING'
  491. }
  492. ).list(workspace_id, True))
  493. class TransformWorkflow(APIView):
  494. authentication_classes = [TokenAuth]
  495. @has_permissions(
  496. PermissionConstants.KNOWLEDGE_EDIT.get_workspace_knowledge_permission(),
  497. PermissionConstants.KNOWLEDGE_EDIT.get_workspace_permission_workspace_manage_role(),
  498. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  499. ViewPermission([RoleConstants.USER.get_workspace_role()],
  500. [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], CompareConstants.AND),
  501. )
  502. @log(
  503. menu='Knowledge Base', operate="Modify knowledge base information",
  504. get_operation_object=lambda r, keywords: get_knowledge_operation_object(keywords.get('knowledge_id')),
  505. )
  506. def post(self, request: Request, workspace_id: str, knowledge_id: str):
  507. return result.success(KnowledgeSerializer.TransformWorkflow(
  508. data={'user_id': request.user.id, 'workspace_id': workspace_id, 'knowledge_id': knowledge_id}
  509. ).transform(request.data))
  510. class Tags(APIView):
  511. authentication_classes = [TokenAuth]
  512. @extend_schema(
  513. methods=['GET'],
  514. description=_('Get all tags of knowledge base'),
  515. summary=_('Get all tags of knowledge base'),
  516. operation_id=_('Get all tags of knowledge base'), # type: ignore
  517. parameters=KnowledgeReadAPI.get_parameters(),
  518. responses=KnowledgeReadAPI.get_response(),
  519. tags=[_('Knowledge Base')] # type: ignore
  520. )
  521. @has_permissions(
  522. PermissionConstants.KNOWLEDGE_READ.get_workspace_permission(),
  523. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
  524. )
  525. def get(self, request: Request, workspace_id: str):
  526. return result.success(KnowledgeSerializer.Tags(data={
  527. 'user_id': request.user.id,
  528. 'workspace_id': workspace_id,
  529. 'knowledge_ids': request.query_params.getlist('knowledge_ids[]')
  530. }).list())
  531. class Statistics(APIView):
  532. """知识库用量统计"""
  533. authentication_classes = [TokenAuth]
  534. @extend_schema(
  535. methods=['GET'],
  536. description=_("Get knowledge base usage statistics"),
  537. summary=_("Get knowledge base usage statistics"),
  538. operation_id=_("Get knowledge base usage statistics"),
  539. tags=[_('Knowledge Base')]
  540. )
  541. @has_permissions(
  542. PermissionConstants.KNOWLEDGE_READ.get_workspace_permission(),
  543. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
  544. RoleConstants.USER.get_workspace_role()
  545. )
  546. def get(self, request: Request, workspace_id: str, knowledge_id: str):
  547. doc_count = Document.objects.filter(knowledge_id=knowledge_id).count()
  548. para_stats = Paragraph.objects.filter(knowledge_id=knowledge_id).aggregate(
  549. total_count=Count('id'),
  550. total_hit=Sum('hit_num')
  551. )
  552. return result.success({
  553. 'document_count': doc_count,
  554. 'paragraph_count': para_stats['total_count'] or 0,
  555. 'total_hit_count': para_stats['total_hit'] or 0
  556. })
  557. class KnowledgeBaseView(APIView):
  558. authentication_classes = [TokenAuth]
  559. @extend_schema(
  560. methods=['POST'],
  561. description=_('Create base knowledge'),
  562. summary=_('Create base knowledge'),
  563. operation_id=_('Create base knowledge'), # type: ignore
  564. parameters=KnowledgeBaseCreateAPI.get_parameters(),
  565. request=KnowledgeBaseCreateAPI.get_request(),
  566. responses=KnowledgeBaseCreateAPI.get_response(),
  567. tags=[_('Knowledge Base')] # type: ignore
  568. )
  569. @has_permissions(
  570. PermissionConstants.KNOWLEDGE_CREATE.get_workspace_permission(),
  571. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
  572. )
  573. @log(
  574. menu='knowledge Base', operate='Create base knowledge',
  575. get_operation_object=lambda r, k: {'name': r.data.get('name'), 'desc': r.data.get('desc')},
  576. )
  577. def post(self, request: Request, workspace_id: str):
  578. return result.success(KnowledgeSerializer.Create(
  579. data={'user_id': request.user.id, 'workspace_id': workspace_id}
  580. ).save_base(request.data))
  581. class KnowledgeWebView(APIView):
  582. authentication_classes = [TokenAuth]
  583. @extend_schema(
  584. methods=['POST'],
  585. description=_('Create web knowledge'),
  586. summary=_('Create web knowledge'),
  587. operation_id=_('Create web knowledge'), # type: ignore
  588. parameters=KnowledgeWebCreateAPI.get_parameters(),
  589. request=KnowledgeWebCreateAPI.get_request(),
  590. responses=KnowledgeWebCreateAPI.get_response(),
  591. tags=[_('Knowledge Base')] # type: ignore
  592. )
  593. @has_permissions(
  594. PermissionConstants.KNOWLEDGE_CREATE.get_workspace_permission(),
  595. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
  596. )
  597. @log(
  598. menu='Knowledge Base', operate="Create a web site knowledge base",
  599. get_operation_object=lambda r, k: {'name': r.data.get('name'), 'desc': r.data.get('desc'),
  600. 'first_list': r.FILES.getlist('file'),
  601. 'meta': {'source_url': r.data.get('source_url'),
  602. 'selector': r.data.get('selector'),
  603. 'embedding_model_id': r.data.get('embedding_model_id')}}
  604. ,
  605. )
  606. def post(self, request: Request, workspace_id: str):
  607. return result.success(KnowledgeSerializer.Create(
  608. data={'user_id': request.user.id, 'workspace_id': workspace_id}
  609. ).save_web(request.data))