@nocobase/plugin-ai 2.3.0-alpha.1 → 2.3.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. package/dist/ai/docs/nocobase/ai-dev/watermark-plugin.md +2 -0
  2. package/dist/ai/docs/nocobase/ai-employees/block/ai-chat-box.md +133 -0
  3. package/dist/ai/docs/nocobase/ai-employees/knowledge-base/knowledge-base/documents.md +1 -1
  4. package/dist/ai/docs/nocobase/ai-employees/knowledge-base/knowledge-base/index.md +11 -7
  5. package/dist/ai/docs/nocobase/ai-employees/knowledge-base/knowledge-base/settings.md +12 -8
  6. package/dist/ai/docs/nocobase/ai-employees/knowledge-base/rag.md +43 -13
  7. package/dist/ai/docs/nocobase/ai-employees/knowledge-base/vector-database.md +3 -3
  8. package/dist/ai/docs/nocobase/ai-employees/workflow/nodes/knowledge/create-document.md +1 -1
  9. package/dist/ai/docs/nocobase/api/app/env.md +2 -0
  10. package/dist/ai/docs/nocobase/api/cli/api/resource/create.md +4 -3
  11. package/dist/ai/docs/nocobase/building-tips/ai-fill-js-block-form.md +1092 -0
  12. package/dist/ai/docs/nocobase/data-sources/calendar/calendar-collection.md +100 -3
  13. package/dist/ai/docs/nocobase/data-sources/collection-comment/index.md +92 -39
  14. package/dist/ai/docs/nocobase/data-sources/collection-sql/index.md +150 -29
  15. package/dist/ai/docs/nocobase/data-sources/collection-tree/index.md +93 -5
  16. package/dist/ai/docs/nocobase/data-sources/collection-view/index.md +226 -4
  17. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/advanced/china-region.md +122 -5
  18. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/advanced/collection-select.md +105 -4
  19. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/advanced/json.md +102 -4
  20. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/advanced/nano-id.md +104 -4
  21. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/advanced/snowflake-id.md +108 -4
  22. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/advanced/sort.md +3 -19
  23. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/advanced/uuid.md +104 -4
  24. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/associations/index.md +44 -8
  25. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/color.md +102 -4
  26. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/email.md +104 -4
  27. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/icon.md +102 -4
  28. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/input.md +112 -8
  29. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/integer.md +103 -4
  30. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/number.md +103 -4
  31. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/password.md +102 -4
  32. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/percent.md +104 -5
  33. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/phone.md +104 -4
  34. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/textarea.md +99 -8
  35. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/basic/url.md +103 -4
  36. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/choices/checkbox-group.md +105 -3
  37. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/choices/checkbox.md +102 -4
  38. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/choices/china-region.md +108 -5
  39. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/choices/multiple-select.md +103 -5
  40. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/choices/radio-group.md +106 -4
  41. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/choices/select.md +103 -5
  42. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/datetime/date.md +102 -4
  43. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/datetime/datetime-without-tz.md +103 -5
  44. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/datetime/datetime.md +103 -5
  45. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/datetime/index.md +53 -47
  46. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/datetime/time.md +102 -4
  47. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/datetime/unix-timestamp.md +103 -5
  48. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/geometric/circle.md +102 -4
  49. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/geometric/line.md +103 -5
  50. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/geometric/point.md +102 -4
  51. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/geometric/polygon.md +102 -4
  52. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/index.md +62 -16
  53. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/media/markdown.md +104 -4
  54. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/media/rich-text.md +105 -5
  55. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/system-info/created-at.md +105 -5
  56. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/system-info/created-by.md +103 -5
  57. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/system-info/space.md +100 -6
  58. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/system-info/table-oid.md +102 -4
  59. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/system-info/updated-at.md +104 -5
  60. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/system-info/updated-by.md +104 -6
  61. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection-fields/validation.md +68 -58
  62. package/dist/ai/docs/nocobase/data-sources/data-modeling/collection.md +32 -13
  63. package/dist/ai/docs/nocobase/data-sources/data-modeling/index.md +41 -33
  64. package/dist/ai/docs/nocobase/data-sources/data-source-external-mariadb/index.md +114 -6
  65. package/dist/ai/docs/nocobase/data-sources/data-source-external-mssql/index.md +117 -6
  66. package/dist/ai/docs/nocobase/data-sources/data-source-external-mysql/index.md +103 -6
  67. package/dist/ai/docs/nocobase/data-sources/data-source-external-nocobase/index.md +75 -73
  68. package/dist/ai/docs/nocobase/data-sources/data-source-external-oracle/index.md +129 -11
  69. package/dist/ai/docs/nocobase/data-sources/data-source-external-postgres/index.md +110 -6
  70. package/dist/ai/docs/nocobase/data-sources/data-source-kingbase/index.md +75 -49
  71. package/dist/ai/docs/nocobase/data-sources/data-source-main/general-collection.md +116 -15
  72. package/dist/ai/docs/nocobase/data-sources/data-source-main/index.md +92 -62
  73. package/dist/ai/docs/nocobase/data-sources/data-source-main/inheritance-collection.md +97 -10
  74. package/dist/ai/docs/nocobase/data-sources/data-source-manager/external-database.md +97 -58
  75. package/dist/ai/docs/nocobase/data-sources/data-source-manager/index.md +32 -24
  76. package/dist/ai/docs/nocobase/data-sources/data-source-rest-api/index.md +115 -153
  77. package/dist/ai/docs/nocobase/data-sources/external/clickhouse.md +124 -0
  78. package/dist/ai/docs/nocobase/data-sources/external/doris.md +130 -0
  79. package/dist/ai/docs/nocobase/data-sources/external/index.md +140 -0
  80. package/dist/ai/docs/nocobase/data-sources/external/kingbase.md +129 -0
  81. package/dist/ai/docs/nocobase/data-sources/external/mariadb.md +126 -0
  82. package/dist/ai/docs/nocobase/data-sources/external/mssql.md +129 -0
  83. package/dist/ai/docs/nocobase/data-sources/external/mysql.md +115 -0
  84. package/dist/ai/docs/nocobase/data-sources/external/nocobase.md +159 -0
  85. package/dist/ai/docs/nocobase/data-sources/external/oceanbase.md +126 -0
  86. package/dist/ai/docs/nocobase/data-sources/external/oracle.md +158 -0
  87. package/dist/ai/docs/nocobase/data-sources/external/postgresql.md +122 -0
  88. package/dist/ai/docs/nocobase/data-sources/external/rest-api.md +245 -0
  89. package/dist/ai/docs/nocobase/data-sources/field-attachment-url/index.md +100 -12
  90. package/dist/ai/docs/nocobase/data-sources/field-encryption/index.md +48 -47
  91. package/dist/ai/docs/nocobase/data-sources/field-formula/index.md +99 -5
  92. package/dist/ai/docs/nocobase/data-sources/field-markdown-vditor/index.md +105 -5
  93. package/dist/ai/docs/nocobase/data-sources/field-sequence/index.md +102 -5
  94. package/dist/ai/docs/nocobase/data-sources/field-signature/index.md +18 -16
  95. package/dist/ai/docs/nocobase/data-sources/field-sort/index.md +76 -73
  96. package/dist/ai/docs/nocobase/data-sources/file-manager/field-attachment.md +101 -7
  97. package/dist/ai/docs/nocobase/data-sources/file-manager/file-collection.md +101 -14
  98. package/dist/ai/docs/nocobase/data-sources/index.md +49 -33
  99. package/dist/ai/docs/nocobase/data-sources/main/index.md +130 -0
  100. package/dist/ai/docs/nocobase/data-sources/main/kingbase.md +147 -0
  101. package/dist/ai/docs/nocobase/data-sources/main/mariadb.md +59 -0
  102. package/dist/ai/docs/nocobase/data-sources/main/mysql.md +59 -0
  103. package/dist/ai/docs/nocobase/data-sources/main/oceanbase.md +62 -0
  104. package/dist/ai/docs/nocobase/data-sources/main/postgresql.md +61 -0
  105. package/dist/ai/docs/nocobase/file-manager/file-preview/index.md +44 -3
  106. package/dist/ai/docs/nocobase/file-manager/stable-url.md +1 -1
  107. package/dist/ai/docs/nocobase/file-manager/storage/aliyun-oss.md +100 -3
  108. package/dist/ai/docs/nocobase/file-manager/storage/index.md +76 -26
  109. package/dist/ai/docs/nocobase/file-manager/storage/local.md +4 -2
  110. package/dist/ai/docs/nocobase/file-manager/storage/s3-pro.md +58 -7
  111. package/dist/ai/docs/nocobase/get-started/installation/docker-nginx.mdx +4 -1
  112. package/dist/ai/docs/nocobase/get-started/installation/docker.mdx +2 -0
  113. package/dist/ai/docs/nocobase/get-started/installation/env.md +13 -1
  114. package/dist/ai/docs/nocobase/nocobase-cli/production/reverse-proxy/caddy.md +28 -5
  115. package/dist/ai/docs/nocobase/nocobase-cli/production/reverse-proxy/nginx.md +25 -0
  116. package/dist/ai/docs/nocobase/ops-management/migration-manager/built-in-tables.md +1 -2
  117. package/dist/ai/docs/nocobase/plugin-development/build.md +10 -4
  118. package/dist/ai/docs/nocobase/plugin-development/client/appendix/faq.md +1 -1
  119. package/dist/ai/docs/nocobase/plugin-development/client/examples/custom-action.md +2 -0
  120. package/dist/ai/docs/nocobase/plugin-development/client/examples/custom-block.md +2 -0
  121. package/dist/ai/docs/nocobase/plugin-development/client/examples/custom-field.md +2 -0
  122. package/dist/ai/docs/nocobase/plugin-development/client/examples/fullstack-plugin.md +2 -0
  123. package/dist/ai/docs/nocobase/plugin-development/client/examples/settings-page.md +2 -0
  124. package/dist/ai/docs/nocobase/plugin-development/common/i18n.md +3 -3
  125. package/dist/ai/docs/nocobase/plugin-development/server/cache.md +1 -1
  126. package/dist/ai/docs/nocobase/plugin-development/server/collections.md +0 -6
  127. package/dist/ai/docs/nocobase/plugin-development/server/command.md +2 -2
  128. package/dist/ai/docs/nocobase/plugin-development/server/context.md +2 -2
  129. package/dist/ai/docs/nocobase/plugin-development/server/i18n.md +4 -4
  130. package/dist/ai/docs/nocobase/plugin-development/write-your-first-plugin.md +91 -43
  131. package/dist/ai/docs/nocobase/runjs/context/ai.md +194 -4
  132. package/dist/ai/docs/nocobase/security/guide.md +17 -2
  133. package/dist/ai/docs/nocobase/users-permissions/sync/index.md +8 -1
  134. package/dist/ai/docs/nocobase/users-permissions/sync/sources/dingtalk.md +138 -0
  135. package/dist/ai/docs/nocobase/users-permissions/sync/sources/ldap.md +87 -0
  136. package/dist/ai/docs/nocobase/workflow/nodes/javascript.md +21 -1
  137. package/dist/ai/tools/executeFrontendTool.d.ts +10 -0
  138. package/dist/ai/tools/executeFrontendTool.js +86 -0
  139. package/dist/ai/tools/getSkill.js +1 -1
  140. package/dist/ai/tools/knowledge-base-retrieve.js +3 -1
  141. package/dist/ai/tools/loadFrontendTool.d.ts +10 -0
  142. package/dist/ai/tools/loadFrontendTool.js +99 -0
  143. package/dist/client/244.9421a13b1d5f28f6.js +10 -0
  144. package/dist/client/{525.203778500aca5d05.js → 525.94dd4136c1361477.js} +1 -1
  145. package/dist/client/681.6ffbc9329b9ac242.js +10 -0
  146. package/dist/client/705.1d735e63c25f66a8.js +10 -0
  147. package/dist/client/index.d.ts +1 -3
  148. package/dist/client/index.js +8 -8
  149. package/dist/client-v2/244.d0562f1f3a26531b.js +10 -0
  150. package/dist/client-v2/420.a5b929a5e7f330be.js +10 -0
  151. package/dist/client-v2/681.6890caa389564ff7.js +10 -0
  152. package/dist/client-v2/705.00c101bef403fb44.js +10 -0
  153. package/dist/client-v2/ai-employees/AIEmployeeShortcut.d.ts +2 -0
  154. package/dist/client-v2/ai-employees/AddContextButton.d.ts +2 -0
  155. package/dist/client-v2/ai-employees/chatbox/components/AIEmployeeSwitcher.d.ts +1 -0
  156. package/dist/client-v2/ai-employees/chatbox/components/ChatBoxUnreadBadge.d.ts +17 -0
  157. package/dist/client-v2/ai-employees/chatbox/components/Conversations.d.ts +9 -1
  158. package/dist/client-v2/ai-employees/chatbox/components/MessageRenderers.d.ts +1 -1
  159. package/dist/client-v2/ai-employees/chatbox/components/Messages.d.ts +5 -1
  160. package/dist/client-v2/ai-employees/chatbox/components/ModelSwitcher.d.ts +4 -0
  161. package/dist/client-v2/ai-employees/chatbox/components/Sender.d.ts +33 -1
  162. package/dist/client-v2/ai-employees/chatbox/components/index.d.ts +1 -0
  163. package/dist/client-v2/ai-employees/chatbox/hooks/reasoning-stream.d.ts +10 -0
  164. package/dist/client-v2/ai-employees/chatbox/hooks/useChat.d.ts +8 -5
  165. package/dist/client-v2/ai-employees/chatbox/hooks/useChatBoxActions.d.ts +3 -2
  166. package/dist/client-v2/ai-employees/chatbox/hooks/useChatBoxEffect.d.ts +2 -1
  167. package/dist/client-v2/ai-employees/chatbox/hooks/useChatConversationActions.d.ts +3 -2
  168. package/dist/client-v2/ai-employees/chatbox/hooks/useChatMessageActions.d.ts +4 -2
  169. package/dist/client-v2/ai-employees/chatbox/hooks/useToolCallActions.d.ts +3 -1
  170. package/dist/client-v2/ai-employees/chatbox/hooks/useUploadFiles.d.ts +13 -3
  171. package/dist/client-v2/ai-employees/chatbox/hooks/useWorkflowTasks.d.ts +3 -2
  172. package/dist/client-v2/ai-employees/chatbox/index.d.ts +17 -0
  173. package/dist/client-v2/ai-employees/chatbox/roles.d.ts +2 -153
  174. package/dist/client-v2/ai-employees/chatbox/stores/chat-box.d.ts +46 -33
  175. package/dist/client-v2/ai-employees/chatbox/stores/chat-conversations.d.ts +7 -7
  176. package/dist/client-v2/ai-employees/chatbox/stores/chat-messages.d.ts +23 -18
  177. package/dist/client-v2/ai-employees/chatbox/stores/chat-sender.d.ts +43 -0
  178. package/dist/client-v2/ai-employees/chatbox/stores/chat-tool-call.d.ts +6 -5
  179. package/dist/client-v2/ai-employees/chatbox/stores/chat-tools.d.ts +11 -5
  180. package/dist/client-v2/ai-employees/chatbox/stores/mounted-chat-boxes.d.ts +20 -0
  181. package/dist/client-v2/ai-employees/chatbox/stores/runtime.d.ts +43 -0
  182. package/dist/client-v2/ai-employees/chatbox/stores/workflow-tasks.d.ts +22 -10
  183. package/dist/client-v2/ai-employees/chatbox/upload.d.ts +19 -0
  184. package/dist/client-v2/ai-employees/chatbox/utils.d.ts +28 -4
  185. package/dist/client-v2/ai-employees/frontend-tools.d.ts +11 -0
  186. package/dist/client-v2/ai-employees/tools/SuggestionsOptionsCard.d.ts +1 -1
  187. package/dist/client-v2/ai-employees/tools/WorkflowTaskOutputCard.d.ts +1 -1
  188. package/dist/client-v2/ai-employees/types.d.ts +30 -0
  189. package/dist/client-v2/block/ai-chat-box/AIChatBoxBlockModel.d.ts +21 -0
  190. package/dist/client-v2/block/ai-chat-box/AIChatBoxCoreModel.d.ts +13 -0
  191. package/dist/client-v2/{ai-employees/chatbox/components/DebugPanel.d.ts → block/ai-chat-box/components/AIChatBoxCoreView.d.ts} +1 -1
  192. package/dist/client-v2/block/ai-chat-box/components/AIChatBoxView.d.ts +12 -0
  193. package/dist/client-v2/block/ai-chat-box/index.d.ts +14 -0
  194. package/dist/client-v2/block/ai-chat-box/settings.d.ts +12 -0
  195. package/dist/client-v2/block/ai-chat-box/sub-models.d.ts +26 -0
  196. package/dist/client-v2/block/ai-chat-box/types.d.ts +38 -0
  197. package/dist/client-v2/block/ai-chat-box/utils.d.ts +26 -0
  198. package/dist/client-v2/index.d.ts +3 -5
  199. package/dist/client-v2/index.js +3 -3
  200. package/dist/client-v2/llm-providers/forms.d.ts +2 -0
  201. package/dist/client-v2/llm-providers/index.d.ts +1 -0
  202. package/dist/client-v2/llm-services/model-select.d.ts +33 -0
  203. package/dist/client-v2/llm-services/utils.d.ts +1 -0
  204. package/dist/client-v2/manager/ai-manager.d.ts +10 -3
  205. package/dist/client-v2/manager/frontend-tool-registry.d.ts +30 -0
  206. package/dist/client-v2/models/ai-employees/AIEmployeeActionModel.d.ts +4 -1
  207. package/dist/client-v2/models/ai-employees/AIEmployeeShortcutModel.d.ts +8 -0
  208. package/dist/client-v2/pages/EmployeesPage.d.ts +15 -0
  209. package/dist/client-v2/pages/LLMServicesPage.d.ts +9 -4
  210. package/dist/client-v2/repositories/AIConfigRepository.d.ts +2 -0
  211. package/dist/client-v2/runjs/registerAIEmployeeRunJSFacade.d.ts +1 -0
  212. package/dist/client-v2/workflow/types.d.ts +1 -0
  213. package/dist/collections/ai-employees.d.ts +1 -0
  214. package/dist/collections/ai-employees.js +1 -0
  215. package/dist/common/ai-employee-validation.d.ts +17 -0
  216. package/dist/common/ai-employee-validation.js +67 -0
  217. package/dist/common/error-codes.d.ts +14 -0
  218. package/dist/common/error-codes.js +51 -0
  219. package/dist/common/frontend-tools.d.ts +26 -0
  220. package/dist/common/frontend-tools.js +57 -0
  221. package/dist/common/llm-service-models.d.ts +16 -0
  222. package/dist/common/llm-service-models.js +84 -0
  223. package/dist/externalVersion.js +19 -17
  224. package/dist/locale/de-DE.json +2 -1
  225. package/dist/locale/en-US.json +87 -5
  226. package/dist/locale/es-ES.json +2 -1
  227. package/dist/locale/fr-FR.json +2 -1
  228. package/dist/locale/hu-HU.json +2 -1
  229. package/dist/locale/id-ID.json +2 -1
  230. package/dist/locale/it-IT.json +2 -1
  231. package/dist/locale/ja-JP.json +2 -1
  232. package/dist/locale/ko-KR.json +2 -1
  233. package/dist/locale/nl-NL.json +2 -1
  234. package/dist/locale/pt-BR.json +2 -1
  235. package/dist/locale/ru-RU.json +2 -1
  236. package/dist/locale/tr-TR.json +2 -1
  237. package/dist/locale/uk-UA.json +2 -1
  238. package/dist/locale/vi-VN.json +2 -1
  239. package/dist/locale/zh-CN.json +87 -5
  240. package/dist/locale/zh-TW.json +2 -1
  241. package/dist/node_modules/@langchain/mistralai/package.json +1 -1
  242. package/dist/node_modules/@langchain/xai/package.json +1 -1
  243. package/dist/node_modules/fs-extra/package.json +1 -1
  244. package/dist/node_modules/jsonrepair/package.json +1 -1
  245. package/dist/node_modules/just-bash/package.json +1 -1
  246. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  247. package/dist/node_modules/openai/package.json +1 -1
  248. package/dist/node_modules/zod/package.json +1 -1
  249. package/dist/server/ai-employees/ai-conversations.d.ts +4 -1
  250. package/dist/server/ai-employees/ai-conversations.js +2 -0
  251. package/dist/server/ai-employees/ai-employee.d.ts +32 -2
  252. package/dist/server/ai-employees/ai-employee.js +375 -81
  253. package/dist/server/ai-employees/ai-knowledge-base.d.ts +21 -1
  254. package/dist/server/ai-employees/ai-knowledge-base.js +87 -12
  255. package/dist/server/ai-employees/middleware/conversation.js +28 -22
  256. package/dist/server/ai-employees/middleware/index.d.ts +1 -0
  257. package/dist/server/ai-employees/middleware/index.js +2 -0
  258. package/dist/server/ai-employees/middleware/tool-result-integrity.d.ts +22 -0
  259. package/dist/server/ai-employees/middleware/tool-result-integrity.js +211 -0
  260. package/dist/server/ai-employees/prompts.js +2 -2
  261. package/dist/server/ai-employees/reasoning-stream-state.d.ts +23 -0
  262. package/dist/server/ai-employees/reasoning-stream-state.js +63 -0
  263. package/dist/server/collections/ai-conversations.js +5 -0
  264. package/dist/server/document-loader/constants.js +1 -1
  265. package/dist/server/features/knowledge-base.d.ts +2 -0
  266. package/dist/server/frontend-tools.d.ts +25 -0
  267. package/dist/server/frontend-tools.js +171 -0
  268. package/dist/server/llm-providers/common/reasoning.js +18 -10
  269. package/dist/server/llm-providers/deepseek/index.d.ts +10 -0
  270. package/dist/server/llm-providers/deepseek/index.js +32 -0
  271. package/dist/server/llm-providers/deepseek/provider.d.ts +57 -0
  272. package/dist/server/llm-providers/deepseek/provider.js +320 -0
  273. package/dist/server/llm-providers/deepseek/reasoning.d.ts +83 -0
  274. package/dist/server/llm-providers/deepseek/reasoning.js +285 -0
  275. package/dist/server/llm-providers/mistral.d.ts +1 -1
  276. package/dist/server/llm-providers/provider.d.ts +1 -0
  277. package/dist/server/llm-providers/provider.js +3 -0
  278. package/dist/server/llm-providers/shengsuanyun.d.ts +29 -0
  279. package/dist/server/llm-providers/shengsuanyun.js +114 -0
  280. package/dist/server/manager/ai-chat-conversation.js +9 -0
  281. package/dist/server/manager/ai-context-datasource-manager.js +11 -2
  282. package/dist/server/manager/ai-feature-manager.js +1 -1
  283. package/dist/server/manager/ai-manager.d.ts +3 -0
  284. package/dist/server/manager/ai-manager.js +7 -2
  285. package/dist/server/manager/work-context-handler.js +10 -3
  286. package/dist/server/migrations/20260501000000-ai-employee-knowledge-base-retrieval-strategy.d.ts +14 -0
  287. package/dist/server/migrations/20260501000000-ai-employee-knowledge-base-retrieval-strategy.js +49 -0
  288. package/dist/server/plugin.d.ts +1 -0
  289. package/dist/server/plugin.js +31 -0
  290. package/dist/server/resource/aiConversations.d.ts +2 -0
  291. package/dist/server/resource/aiConversations.js +33 -3
  292. package/dist/server/resource/aiEmployees.d.ts +2 -0
  293. package/dist/server/resource/aiEmployees.js +96 -0
  294. package/dist/server/resource/aiWorkflowTasks.js +9 -1
  295. package/dist/server/resource/llmServices.d.ts +11 -0
  296. package/dist/server/resource/llmServices.js +85 -0
  297. package/dist/server/types/ai-chat-conversation.type.d.ts +1 -0
  298. package/dist/server/types/ai-message.type.d.ts +4 -0
  299. package/dist/server/types/knowledge-base.type.d.ts +8 -3
  300. package/dist/server/workflow/nodes/employee/files.d.ts +1 -1
  301. package/dist/server/workflow/nodes/employee/files.js +48 -1
  302. package/dist/server/workflow/nodes/employee/index.js +7 -2
  303. package/dist/server/workflow/nodes/employee/types.d.ts +1 -0
  304. package/dist/swagger/common.d.ts +143 -0
  305. package/dist/swagger/common.js +144 -0
  306. package/dist/swagger/employees.d.ts +301 -0
  307. package/dist/swagger/employees.js +131 -0
  308. package/dist/swagger/index.d.ts +1617 -0
  309. package/dist/swagger/index.js +62 -0
  310. package/dist/swagger/llm.d.ts +563 -0
  311. package/dist/swagger/llm.js +255 -0
  312. package/dist/swagger/schemas.d.ts +757 -0
  313. package/dist/swagger/schemas.js +392 -0
  314. package/package.json +2 -2
  315. package/dist/ai/docs/nocobase/ai-employees/knowledge-base/vector-store.md +0 -24
  316. package/dist/ai/docs/nocobase/data-sources/development/index.md +0 -6
  317. package/dist/client/372.40eb52905e3f3049.js +0 -10
  318. package/dist/client/681.399948c18d753667.js +0 -10
  319. package/dist/client/705.380279da896021fb.js +0 -10
  320. package/dist/client-v2/372.8cc3fde09c9bec77.js +0 -10
  321. package/dist/client-v2/406.341be51205c674e0.js +0 -10
  322. package/dist/client-v2/681.082f4f1c7b841983.js +0 -10
  323. package/dist/client-v2/705.1d10027ff8cfdf79.js +0 -10
  324. package/dist/client-v2/ai-employees/chatbox/stores/create-selectors.d.ts +0 -46
  325. package/dist/client-v2/ai-employees/chatbox/utils/normalizeTriggerTaskOptions.d.ts +0 -19
  326. package/dist/client-v2/debug-logger.d.ts +0 -52
  327. package/dist/server/llm-providers/deepseek.d.ts +0 -40
  328. package/dist/server/llm-providers/deepseek.js +0 -174
@@ -45,6 +45,7 @@ var import_utils = require("../utils");
45
45
  var import_prompts = require("./prompts");
46
46
  var import_lodash = __toESM(require("lodash"));
47
47
  var import_ai_chat_conversation = require("../manager/ai-chat-conversation");
48
+ var import_ai_knowledge_base = require("./ai-knowledge-base");
48
49
  var import_middleware = require("./middleware");
49
50
  var import_ai = require("@nocobase/ai");
50
51
  var import_checkpoints = require("./checkpoints");
@@ -56,12 +57,17 @@ var import_base = require("@langchain/core/callbacks/base");
56
57
  var import_shared = require("../../ai/tools/sub-agents/shared");
57
58
  var import_tool_call_sanitizer = require("./tool-call-sanitizer");
58
59
  var import_attachments = require("../attachments");
60
+ var import_frontend_tools = require("../../common/frontend-tools");
61
+ var import_frontend_tools2 = require("../frontend-tools");
62
+ var import_reasoning_stream_state = require("./reasoning-stream-state");
63
+ const ABORTED_TOOL_CALL_CONTENT = "The tool call was interrupted because the conversation was aborted.";
59
64
  class AIEmployee {
60
65
  sessionId;
61
66
  from = "main-agent";
62
67
  employee;
63
68
  aiChatConversation;
64
69
  skillSettings;
70
+ userMessageCount = 0;
65
71
  plugin;
66
72
  db;
67
73
  ctx;
@@ -73,6 +79,7 @@ class AIEmployee {
73
79
  tools;
74
80
  inWorkflow;
75
81
  streamCached;
82
+ static conversationPersistenceQueues = /* @__PURE__ */ new WeakMap();
76
83
  constructor({
77
84
  ctx,
78
85
  employee,
@@ -122,6 +129,9 @@ class AIEmployee {
122
129
  areToolsEnabled() {
123
130
  return this.chatSettings.enableTools !== false;
124
131
  }
132
+ getAIEmployeeRecord() {
133
+ return this.employee.toJSON();
134
+ }
125
135
  async getFormatMessages(userMessages) {
126
136
  const { provider } = await this.plugin.aiManager.getLLMService({
127
137
  ...this.model
@@ -204,6 +214,7 @@ class AIEmployee {
204
214
  const { provider, model, service } = await this.plugin.aiManager.getLLMService({
205
215
  ...this.model
206
216
  });
217
+ this.userMessageCount = (userMessages ?? []).filter((message) => message.role === "user").length;
207
218
  const { historyMessages, tools, resolvedTools, middleware, config, state } = await this.initSession({
208
219
  messageId,
209
220
  provider,
@@ -410,39 +421,52 @@ class AIEmployee {
410
421
  async processChatStream(stream, options) {
411
422
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
412
423
  const aiMessageIdMap = /* @__PURE__ */ new Map();
424
+ const persistedAIMessageIdMap = /* @__PURE__ */ new Map();
413
425
  const { signal, providerName, llmService, model, provider, responseMetadata, allowEmpty = false } = options;
414
- let isReasoning = false;
426
+ const reasoningState = new import_reasoning_stream_state.ReasoningStreamState();
427
+ const stopReasoning = async (conversation) => {
428
+ if (reasoningState.stop(conversation)) {
429
+ await this.protocol.with(conversation).stopReasoning();
430
+ }
431
+ };
432
+ const stopAllReasoning = async () => {
433
+ for (const conversation of reasoningState.drain()) {
434
+ await this.protocol.with(conversation).stopReasoning();
435
+ }
436
+ };
415
437
  let gathered;
416
- signal.addEventListener("abort", async () => {
417
- try {
418
- if ((gathered == null ? void 0 : gathered.type) === "ai") {
419
- const values = (0, import_utils2.convertAIMessage)({
420
- aiEmployee: this,
421
- providerName,
422
- provider,
423
- llmService,
424
- model,
425
- aiMessage: gathered
426
- });
427
- if (values) {
428
- values.metadata.interrupted = true;
429
- }
430
- await this.aiChatConversation.withTransaction(async (conversation, transaction) => {
431
- const result = await conversation.addMessages(values);
432
- });
433
- }
434
- } catch (e) {
435
- this.logger.error("Fail to save message after conversation abort", gathered);
436
- } finally {
437
- await this.aiConversationsRepo.update({
438
- values: { llmActiveState: "idle", read: true },
439
- filter: {
440
- sessionId: this.sessionId
438
+ let abortFinalization;
439
+ signal.addEventListener(
440
+ "abort",
441
+ () => {
442
+ abortFinalization = (async () => {
443
+ try {
444
+ await stopAllReasoning();
445
+ if ((gathered == null ? void 0 : gathered.type) === "ai") {
446
+ await this.finalizeAbortedAIMessage({
447
+ aiMessage: gathered,
448
+ providerName,
449
+ provider,
450
+ llmService,
451
+ model,
452
+ knownMessageId: persistedAIMessageIdMap.get(gathered.id)
453
+ });
454
+ }
455
+ } catch (e) {
456
+ this.logger.error("Fail to save message after conversation abort", gathered);
457
+ } finally {
458
+ await this.aiConversationsRepo.update({
459
+ values: { llmActiveState: "idle", read: true },
460
+ filter: {
461
+ sessionId: this.sessionId
462
+ }
463
+ });
464
+ await this.streamCached.clear();
441
465
  }
442
- });
443
- await this.streamCached.clear();
444
- }
445
- });
466
+ })();
467
+ },
468
+ { once: true }
469
+ );
446
470
  try {
447
471
  const aiEmployeeConversation = {
448
472
  sessionId: this.sessionId,
@@ -456,27 +480,27 @@ class AIEmployee {
456
480
  const { currentConversation } = metadata;
457
481
  if (chunk.type === "ai") {
458
482
  gathered = gathered !== void 0 ? (0, import_stream.concat)(gathered, chunk) : chunk;
459
- if (chunk.content) {
460
- if (isReasoning) {
461
- isReasoning = false;
462
- await this.protocol.with(currentConversation).stopReasoning();
463
- }
464
- const parsedContent = provider.parseResponseChunk(chunk.content);
465
- if (parsedContent) {
466
- await this.protocol.with(currentConversation).content(parsedContent);
467
- }
483
+ const reasoningContent = provider.parseReasoningContent(chunk);
484
+ if (reasoningContent) {
485
+ reasoningState.start(currentConversation);
486
+ await this.protocol.with(currentConversation).reasoning(reasoningContent);
487
+ }
488
+ const parsedContent = chunk.content ? provider.parseResponseChunk(chunk.content) : null;
489
+ if (parsedContent) {
490
+ await stopReasoning(currentConversation);
491
+ await this.protocol.with(currentConversation).content(parsedContent);
468
492
  }
469
493
  if ((_a = chunk.tool_call_chunks) == null ? void 0 : _a.length) {
494
+ await stopReasoning(currentConversation);
470
495
  await this.protocol.with(currentConversation).toolCallChunks(chunk.tool_call_chunks);
471
496
  }
472
497
  const webSearch = provider.parseWebSearchAction(chunk);
473
498
  if (webSearch == null ? void 0 : webSearch.length) {
499
+ await stopReasoning(currentConversation);
474
500
  await this.protocol.with(currentConversation).webSearch(webSearch);
475
501
  }
476
- const reasoningContent = provider.parseReasoningContent(chunk);
477
- if (reasoningContent) {
478
- isReasoning = true;
479
- await this.protocol.with(currentConversation).reasoning(reasoningContent);
502
+ if ((0, import_reasoning_stream_state.isReasoningFinishChunk)(chunk)) {
503
+ await stopReasoning(currentConversation);
480
504
  }
481
505
  }
482
506
  } else if (mode === "updates") {
@@ -505,6 +529,7 @@ class AIEmployee {
505
529
  if (chunks.action === "AfterAIMessageSaved") {
506
530
  await this.streamCached.skipped();
507
531
  aiMessageIdMap.set(currentConversation.sessionId, chunks.body.messageId);
532
+ persistedAIMessageIdMap.set(chunks.body.id, chunks.body.messageId);
508
533
  const data = responseMetadata.get(chunks.body.id);
509
534
  if (data) {
510
535
  const savedMessage = await this.aiMessagesModel.findOne({
@@ -532,6 +557,7 @@ class AIEmployee {
532
557
  }
533
558
  }
534
559
  } else if (chunks.action === "initToolCalls") {
560
+ await stopReasoning(currentConversation);
535
561
  await this.protocol.with(currentConversation).toolCalls(chunks.body);
536
562
  } else if (chunks.action === "beforeToolCall") {
537
563
  const toolsMap = await this.getToolsMap();
@@ -593,12 +619,14 @@ class AIEmployee {
593
619
  }
594
620
  }
595
621
  }
622
+ await stopAllReasoning();
596
623
  if (this.protocol.statistics.sent === 0 && !signal.aborted && !allowEmpty) {
597
624
  this.sendErrorResponse("Empty message");
598
625
  return;
599
626
  }
600
627
  await this.protocol.with(aiEmployeeConversation).endStream();
601
628
  } catch (err) {
629
+ await stopAllReasoning();
602
630
  this.ctx.log.error(err);
603
631
  if (err.name === "GraphRecursionError") {
604
632
  this.sendSpecificError({ name: err.name, message: err.message });
@@ -606,6 +634,7 @@ class AIEmployee {
606
634
  this.sendErrorResponse(provider.parseResponseError(err));
607
635
  }
608
636
  } finally {
637
+ await abortFinalization;
609
638
  if (this.from === "main-agent") {
610
639
  this.ctx.res.end();
611
640
  }
@@ -687,7 +716,7 @@ Field: ${field.name}, Title: ${(_a = field.options.uiSchema) == null ? void 0 :
687
716
  return message;
688
717
  }
689
718
  async getSystemPrompt(userMessages) {
690
- var _a, _b, _c, _d, _e, _f, _g;
719
+ var _a, _b, _c, _d, _e, _f, _g, _h;
691
720
  if (this.systemPromptMode === "none") {
692
721
  return "";
693
722
  }
@@ -695,9 +724,16 @@ Field: ${field.name}, Title: ${(_a = field.options.uiSchema) == null ? void 0 :
695
724
  if (this.systemPromptMode === "raw") {
696
725
  return about;
697
726
  }
727
+ const employee = this.getAIEmployeeRecord();
728
+ const knowledgeBaseManager = this.plugin.knowledgeBaseManager;
729
+ const knowledgeBaseEnabled = await knowledgeBaseManager.isEnabledKnowledgeBase(employee);
730
+ const roleNames = (0, import_ai_knowledge_base.getCurrentRoleNames)(this.ctx.state);
731
+ const hasAccessibleKnowledgeBase = knowledgeBaseEnabled ? await knowledgeBaseManager.hasAccessibleKnowledgeBase({ employee, roleNames }) : false;
732
+ const knowledgeBaseAccessDenied = knowledgeBaseEnabled && !hasAccessibleKnowledgeBase;
733
+ const knowledgeBaseOnDemand = knowledgeBaseEnabled && hasAccessibleKnowledgeBase && (0, import_ai_knowledge_base.normalizeKnowledgeBaseRetrievalStrategy)((_a = employee.knowledgeBase) == null ? void 0 : _a.retrievalStrategy) === "onDemand";
698
734
  const userConfig = await this.db.getRepository("usersAiEmployees").findOne({
699
735
  filter: {
700
- userId: ((_a = this.ctx.auth) == null ? void 0 : _a.user.id) ?? 0,
736
+ userId: ((_b = this.ctx.auth) == null ? void 0 : _b.user.id) ?? 0,
701
737
  aiEmployee: this.employee.username
702
738
  }
703
739
  });
@@ -722,17 +758,25 @@ ${workContextBackground.join("\n")}`;
722
758
  ${addSystemPrompt.map((it) => it.content).join("\n")}`;
723
759
  }
724
760
  let knowledgeBase;
725
- const { knowledgeBaseManager } = this.plugin;
726
- const employee = this.employee.toJSON();
727
- if (await knowledgeBaseManager.isEnabledKnowledgeBase(employee) && employee.knowledgeBasePrompt && (userMessages == null ? void 0 : userMessages.length)) {
761
+ if (knowledgeBaseEnabled && hasAccessibleKnowledgeBase && !knowledgeBaseOnDemand && (userMessages == null ? void 0 : userMessages.length)) {
728
762
  const lastUserMessage = userMessages.filter((x) => x.role === "user").at(-1);
729
763
  if (lastUserMessage) {
730
764
  knowledgeBase = await knowledgeBaseManager.retrievePrompt({
731
765
  employee,
732
- query: lastUserMessage.content.content
766
+ query: lastUserMessage.content.content,
767
+ roleNames
733
768
  });
734
769
  }
735
770
  }
771
+ const knowledgeBaseBackgroundPrompt = (0, import_ai_knowledge_base.getKnowledgeBaseBackgroundPrompt)({
772
+ accessDenied: knowledgeBaseAccessDenied,
773
+ onDemand: knowledgeBaseOnDemand,
774
+ preRetrieved: Boolean(knowledgeBase)
775
+ });
776
+ if (knowledgeBaseBackgroundPrompt) {
777
+ background = `${background}
778
+ ${knowledgeBaseBackgroundPrompt}`;
779
+ }
736
780
  const availableSkills = await this.getAvailableSkills();
737
781
  const availableAIEmployees = await this.getAvailableAIEmployees();
738
782
  const systemPrompt = (0, import_prompts.getSystemPrompt)({
@@ -746,8 +790,12 @@ ${addSystemPrompt.map((it) => it.content).join("\n")}`;
746
790
  personal: userConfig == null ? void 0 : userConfig.prompt,
747
791
  environment: {
748
792
  database: this.db.sequelize.getDialect(),
749
- locale: ((_c = (_b = this.ctx).getCurrentLocale) == null ? void 0 : _c.call(_b)) || "en-US",
750
- currentDateTime: getCurrentDateTimeForPrompt((_e = (_d = this.ctx).getCurrentLocale) == null ? void 0 : _e.call(_d), getCurrentTimezone(this.ctx)),
793
+ locale: ((_d = (_c = this.ctx).getCurrentLocale) == null ? void 0 : _d.call(_c)) || "en-US",
794
+ currentDateTime: getCurrentDateTimeForPrompt(
795
+ await this.aiChatConversation.getCreatedAt(),
796
+ (_f = (_e = this.ctx).getCurrentLocale) == null ? void 0 : _f.call(_e),
797
+ getCurrentTimezone(this.ctx)
798
+ ),
751
799
  timezone: getCurrentTimezone(this.ctx)
752
800
  },
753
801
  knowledgeBase,
@@ -755,7 +803,7 @@ ${addSystemPrompt.map((it) => it.content).join("\n")}`;
755
803
  availableAIEmployees,
756
804
  webSearch: this.webSearch
757
805
  });
758
- const { important } = ((_g = (_f = this.ctx.action) == null ? void 0 : _f.params) == null ? void 0 : _g.values) || {};
806
+ const { important } = ((_h = (_g = this.ctx.action) == null ? void 0 : _g.params) == null ? void 0 : _h.values) || {};
759
807
  if (important === "GraphRecursionError") {
760
808
  const importantPrompt = `<Important>You have already called tools multiple times and gathered sufficient information.
761
809
  First, provide a summary based on the existing information. Do not call additional tools.
@@ -766,14 +814,179 @@ If information is missing, clearly state it in the summary.</Important>`;
766
814
  }
767
815
  }
768
816
  // === Tool calls ===
817
+ async withLockedConversation(callback) {
818
+ const persistenceQueues = AIEmployee.conversationPersistenceQueues.get(this.db) ?? /* @__PURE__ */ new Map();
819
+ AIEmployee.conversationPersistenceQueues.set(this.db, persistenceQueues);
820
+ const previous = persistenceQueues.get(this.sessionId) ?? Promise.resolve();
821
+ let release;
822
+ const current = new Promise((resolve) => {
823
+ release = resolve;
824
+ });
825
+ persistenceQueues.set(this.sessionId, current);
826
+ await previous;
827
+ try {
828
+ for (let attempt = 0; attempt < 2; attempt++) {
829
+ try {
830
+ return await this.aiChatConversation.withTransaction(async (conversation, transaction) => {
831
+ const lockedConversation = await this.aiConversationsModel.findOne({
832
+ where: { sessionId: this.sessionId },
833
+ transaction,
834
+ lock: transaction.LOCK.UPDATE
835
+ });
836
+ if (!lockedConversation) {
837
+ throw new Error(`AI conversation ${this.sessionId} not found`);
838
+ }
839
+ return await callback(conversation, transaction);
840
+ });
841
+ } catch (error) {
842
+ if (!(error instanceof import_database.UniqueConstraintError) || attempt === 1) {
843
+ throw error;
844
+ }
845
+ }
846
+ }
847
+ throw new Error(`Failed to persist AI conversation ${this.sessionId}`);
848
+ } finally {
849
+ release();
850
+ if (persistenceQueues.get(this.sessionId) === current) {
851
+ persistenceQueues.delete(this.sessionId);
852
+ }
853
+ }
854
+ }
855
+ async findPersistedAIMessage(transaction, langChainMessageId, knownMessageId) {
856
+ var _a;
857
+ if (knownMessageId) {
858
+ const knownMessage = await this.aiMessagesModel.findOne({
859
+ where: { sessionId: this.sessionId, messageId: knownMessageId },
860
+ transaction
861
+ });
862
+ if (((_a = knownMessage == null ? void 0 : knownMessage.get("metadata")) == null ? void 0 : _a.id) === langChainMessageId) {
863
+ return knownMessage;
864
+ }
865
+ }
866
+ const messages = await this.aiMessagesModel.findAll({
867
+ where: { sessionId: this.sessionId, role: this.employee.username },
868
+ order: [["messageId", "DESC"]],
869
+ transaction
870
+ });
871
+ return messages.find((message) => {
872
+ var _a2;
873
+ return ((_a2 = message.get("metadata")) == null ? void 0 : _a2.id) === langChainMessageId;
874
+ });
875
+ }
876
+ async persistAIMessageInTransaction(conversation, transaction, options) {
877
+ const existingMessage = await this.findPersistedAIMessage(
878
+ transaction,
879
+ options.langChainMessageId,
880
+ options.knownMessageId
881
+ );
882
+ if (existingMessage) {
883
+ const message2 = existingMessage.toJSON();
884
+ const initializedToolCalls2 = await this.aiToolMessagesModel.findAll({
885
+ where: { sessionId: this.sessionId, messageId: message2.messageId },
886
+ transaction
887
+ });
888
+ return { message: message2, initializedToolCalls: initializedToolCalls2, created: false };
889
+ }
890
+ const message = await conversation.addMessages(options.values);
891
+ const initializedToolCalls = options.toolCalls.length ? await this.initToolCall(transaction, message.messageId, options.toolCalls) : [];
892
+ return { message, initializedToolCalls, created: true };
893
+ }
894
+ async persistAIMessage(options) {
895
+ return await this.withLockedConversation(async (conversation, transaction) => {
896
+ return await this.persistAIMessageInTransaction(conversation, transaction, options);
897
+ });
898
+ }
899
+ async finalizeAbortedAIMessage({
900
+ aiMessage,
901
+ providerName,
902
+ provider,
903
+ llmService,
904
+ model,
905
+ knownMessageId
906
+ }) {
907
+ const values = (0, import_utils2.convertAIMessage)({
908
+ aiEmployee: this,
909
+ providerName,
910
+ provider,
911
+ llmService,
912
+ model,
913
+ aiMessage
914
+ });
915
+ if (!values) {
916
+ return;
917
+ }
918
+ values.metadata = { ...values.metadata, interrupted: true };
919
+ const toolCalls = aiMessage.tool_calls ?? [];
920
+ return await this.withLockedConversation(async (conversation, transaction) => {
921
+ var _a;
922
+ const result = await this.persistAIMessageInTransaction(conversation, transaction, {
923
+ values,
924
+ langChainMessageId: aiMessage.id,
925
+ toolCalls,
926
+ knownMessageId
927
+ });
928
+ const unfinishedToolCalls = result.initializedToolCalls.map((toolCall) => toolCall.toJSON()).filter((toolCall) => toolCall.invokeStatus !== "confirmed");
929
+ if (!result.created && (!result.initializedToolCalls.length || unfinishedToolCalls.length) && !((_a = result.message.metadata) == null ? void 0 : _a.interrupted)) {
930
+ const metadata = { ...result.message.metadata, interrupted: true };
931
+ await this.aiMessagesModel.update(
932
+ { metadata },
933
+ { where: { sessionId: this.sessionId, messageId: result.message.messageId }, transaction }
934
+ );
935
+ result.message.metadata = metadata;
936
+ }
937
+ if (!unfinishedToolCalls.length) {
938
+ return result;
939
+ }
940
+ const persistedToolCalls = result.message.toolCalls ?? toolCalls;
941
+ const toolCallMap = new Map(persistedToolCalls.map((toolCall) => [toolCall.id, toolCall]));
942
+ const now = /* @__PURE__ */ new Date();
943
+ await conversation.addMessages(
944
+ unfinishedToolCalls.map((toolCall) => ({
945
+ role: "tool",
946
+ content: { type: "text", content: ABORTED_TOOL_CALL_CONTENT },
947
+ metadata: {
948
+ id: `aborted-tool:${aiMessage.id}:${toolCall.toolCallId}`,
949
+ model,
950
+ provider: providerName,
951
+ llmService,
952
+ messageId: result.message.messageId,
953
+ toolCallId: toolCall.toolCallId,
954
+ toolName: toolCall.toolName,
955
+ toolCall: toolCallMap.get(toolCall.toolCallId),
956
+ autoCall: toolCall.auto
957
+ }
958
+ }))
959
+ );
960
+ for (const toolCall of unfinishedToolCalls) {
961
+ await this.aiToolMessagesModel.update(
962
+ {
963
+ invokeStatus: "confirmed",
964
+ status: "error",
965
+ content: ABORTED_TOOL_CALL_CONTENT,
966
+ invokeStartTime: toolCall.invokeStartTime ?? now,
967
+ invokeEndTime: now
968
+ },
969
+ {
970
+ where: {
971
+ id: toolCall.id,
972
+ invokeStatus: { [import_database.Op.ne]: "confirmed" }
973
+ },
974
+ transaction
975
+ }
976
+ );
977
+ }
978
+ return result;
979
+ });
980
+ }
769
981
  async initToolCall(transaction, messageId, toolCalls) {
770
982
  const nowTime = /* @__PURE__ */ new Date();
771
983
  const toolMap = await this.getToolsMap();
984
+ const currentFrontendTools = toolCalls.some((toolCall) => toolCall.name === import_frontend_tools.EXECUTE_FRONTEND_TOOL_NAME) ? await (0, import_frontend_tools2.listCurrentFrontendTools)(this.ctx, this.sessionId) : [];
772
985
  return await this.aiToolMessagesRepo.create({
773
986
  values: toolCalls.map((toolCall) => {
774
987
  const toolsExisted = toolMap.has(toolCall.name);
775
988
  const tools = toolMap.get(toolCall.name);
776
- const auto = this.isAutoCall(tools);
989
+ const auto = toolCall.name === import_frontend_tools.EXECUTE_FRONTEND_TOOL_NAME ? toolsExisted && (0, import_frontend_tools2.shouldAutoExecuteFrontendTool)(currentFrontendTools, toolCall.args) : this.isAutoCall(tools);
777
990
  return {
778
991
  id: this.plugin.snowflake.generate(),
779
992
  sessionId: this.sessionId,
@@ -917,6 +1130,39 @@ If information is missing, clearly state it in the summary.</Important>`;
917
1130
  })).map((it) => it.toJSON());
918
1131
  return new Map(list.map((it) => [it.toolCallId, it]));
919
1132
  }
1133
+ async getToolCallResults(toolCallIds) {
1134
+ if (!toolCallIds.length) {
1135
+ return /* @__PURE__ */ new Map();
1136
+ }
1137
+ const list = (await this.aiToolMessagesModel.findAll({
1138
+ where: {
1139
+ sessionId: this.sessionId,
1140
+ toolCallId: {
1141
+ [import_database.Op.in]: toolCallIds
1142
+ }
1143
+ }
1144
+ })).map((item) => item.toJSON());
1145
+ const invokeStatusPriority = { confirmed: 2, done: 1 };
1146
+ const results = /* @__PURE__ */ new Map();
1147
+ for (const item of list) {
1148
+ if (item.invokeStatus !== "confirmed" && item.invokeStatus !== "done") {
1149
+ continue;
1150
+ }
1151
+ const existing = results.get(item.toolCallId);
1152
+ if (!existing) {
1153
+ results.set(item.toolCallId, item);
1154
+ continue;
1155
+ }
1156
+ const priority = invokeStatusPriority[item.invokeStatus];
1157
+ const existingPriority = invokeStatusPriority[existing.invokeStatus];
1158
+ const updatedAt = item.updatedAt ? new Date(item.updatedAt).getTime() : 0;
1159
+ const existingUpdatedAt = existing.updatedAt ? new Date(existing.updatedAt).getTime() : 0;
1160
+ if (priority > existingPriority || priority === existingPriority && updatedAt > existingUpdatedAt) {
1161
+ results.set(item.toolCallId, item);
1162
+ }
1163
+ }
1164
+ return results;
1165
+ }
920
1166
  async cancelToolCall() {
921
1167
  var _a;
922
1168
  let messageId;
@@ -1054,7 +1300,7 @@ If information is missing, clearly state it in the summary.</Important>`;
1054
1300
  });
1055
1301
  }
1056
1302
  async formatMessages({ messages, provider }) {
1057
- var _a, _b;
1303
+ var _a, _b, _c, _d;
1058
1304
  const formattedMessages = [];
1059
1305
  const workContextHandler = this.plugin.workContextHandler;
1060
1306
  const normalizedMessages = await this.normalizeMessageAttachments(messages);
@@ -1121,26 +1367,29 @@ If information is missing, clearly state it in the summary.</Important>`;
1121
1367
  }
1122
1368
  if (msg.role === "tool") {
1123
1369
  formattedMessages.push({
1370
+ id: (_a = msg.metadata) == null ? void 0 : _a.id,
1124
1371
  role: "tool",
1125
1372
  content,
1126
- tool_call_id: (_a = msg.metadata) == null ? void 0 : _a.toolCallId
1373
+ name: (_b = msg.metadata) == null ? void 0 : _b.toolName,
1374
+ tool_call_id: (_c = msg.metadata) == null ? void 0 : _c.toolCallId
1127
1375
  });
1128
1376
  continue;
1129
1377
  }
1378
+ const additionalKwargs = (0, import_tool_call_sanitizer.sanitizeAdditionalKwargsForToolCalls)((_d = msg.metadata) == null ? void 0 : _d.additional_kwargs, msg.toolCalls, {
1379
+ onDiscard: (info) => {
1380
+ var _a2;
1381
+ this.logger.warn("Discard malformed raw tool calls from AI message", {
1382
+ phase: "formatMessages",
1383
+ messageId: (_a2 = msg.metadata) == null ? void 0 : _a2.id,
1384
+ ...info
1385
+ });
1386
+ }
1387
+ }).additionalKwargs;
1130
1388
  formattedMessages.push({
1131
1389
  role: "assistant",
1132
1390
  content,
1133
1391
  tool_calls: msg.toolCalls,
1134
- additional_kwargs: (0, import_tool_call_sanitizer.sanitizeAdditionalKwargsForToolCalls)((_b = msg.metadata) == null ? void 0 : _b.additional_kwargs, msg.toolCalls, {
1135
- onDiscard: (info) => {
1136
- var _a2;
1137
- this.logger.warn("Discard malformed raw tool calls from AI message", {
1138
- phase: "formatMessages",
1139
- messageId: (_a2 = msg.metadata) == null ? void 0 : _a2.id,
1140
- ...info
1141
- });
1142
- }
1143
- }).additionalKwargs
1392
+ additional_kwargs: provider.prepareStoredAssistantAdditionalKwargs(additionalKwargs)
1144
1393
  });
1145
1394
  }
1146
1395
  return formattedMessages;
@@ -1185,12 +1434,32 @@ If information is missing, clearly state it in the summary.</Important>`;
1185
1434
  }
1186
1435
  return result;
1187
1436
  }
1437
+ async getKnowledgeBaseRetrieveTool() {
1438
+ const employee = this.getAIEmployeeRecord();
1439
+ const knowledgeBaseManager = this.plugin.knowledgeBaseManager;
1440
+ if (!await knowledgeBaseManager.isEnabledKnowledgeBase(employee)) {
1441
+ return void 0;
1442
+ }
1443
+ const hasAccessibleKnowledgeBase = await knowledgeBaseManager.hasAccessibleKnowledgeBase({
1444
+ employee,
1445
+ roleNames: (0, import_ai_knowledge_base.getCurrentRoleNames)(this.ctx.state)
1446
+ });
1447
+ if (!hasAccessibleKnowledgeBase) {
1448
+ return void 0;
1449
+ }
1450
+ return await this.toolsManager.getTools(import_ai.SYSTEM_TOOLS.KNOWLEDGE_BASE, { ctx: this.ctx });
1451
+ }
1188
1452
  async getAIEmployeeTools() {
1189
1453
  var _a;
1190
1454
  if (!this.areToolsEnabled()) {
1191
1455
  return [];
1192
1456
  }
1457
+ const currentFrontendTools = await (0, import_frontend_tools2.listCurrentFrontendTools)(this.ctx, this.sessionId);
1193
1458
  const tools = await this.listTools({ scope: "GENERAL" });
1459
+ const getSkill = await this.toolsManager.getTools(import_ai.SYSTEM_TOOLS.GET_SKILL, { ctx: this.ctx });
1460
+ if (getSkill) {
1461
+ tools.push(getSkill);
1462
+ }
1194
1463
  if (this.webSearch === true) {
1195
1464
  const subAgentWebSearch = await this.toolsManager.getTools(import_ai.SYSTEM_TOOLS.WEB_SEARCH, { ctx: this.ctx });
1196
1465
  tools.push(subAgentWebSearch);
@@ -1199,13 +1468,9 @@ If information is missing, clearly state it in the summary.</Important>`;
1199
1468
  const toolMap = await this.getToolsMap();
1200
1469
  const settingsTools = ((_a = this.employee.skillSettings) == null ? void 0 : _a.tools) ?? [];
1201
1470
  const employeeTools = [...settingsTools, ...this.tools];
1202
- if (await this.plugin.knowledgeBaseManager.isEnabledKnowledgeBase(this.employee.toJSON())) {
1203
- const knowledgeBaseRetrieveTool = await this.toolsManager.getTools(import_ai.SYSTEM_TOOLS.KNOWLEDGE_BASE, {
1204
- ctx: this.ctx
1205
- });
1206
- if (knowledgeBaseRetrieveTool) {
1207
- employeeTools.push({ name: import_ai.SYSTEM_TOOLS.KNOWLEDGE_BASE });
1208
- }
1471
+ const knowledgeBaseRetrieveTool = await this.getKnowledgeBaseRetrieveTool();
1472
+ if (knowledgeBaseRetrieveTool) {
1473
+ employeeTools.push({ name: import_ai.SYSTEM_TOOLS.KNOWLEDGE_BASE });
1209
1474
  }
1210
1475
  for (const toolSetting of employeeTools) {
1211
1476
  if (generalToolsNameSet.has(toolSetting.name)) {
@@ -1217,20 +1482,26 @@ If information is missing, clearly state it in the summary.</Important>`;
1217
1482
  }
1218
1483
  tools.push(tool);
1219
1484
  }
1220
- const systemTools = (0, import_ai.listSystemTools)();
1485
+ const systemTools = [...(0, import_ai.listSystemTools)(), import_frontend_tools.LOAD_FRONTEND_TOOL_NAME, import_frontend_tools.EXECUTE_FRONTEND_TOOL_NAME];
1221
1486
  if (!this.skillSettings) {
1222
- return tools;
1487
+ return (0, import_frontend_tools2.prepareToolsForFrontendConversation)(tools, currentFrontendTools);
1223
1488
  } else if (!this.skillSettings.toolsVersion) {
1224
1489
  const toolFilter = this.skillSettings.tools ?? [];
1225
- return tools.filter(
1226
- (t) => toolFilter.length === 0 || systemTools.includes(t.definition.name) || toolFilter.includes(t.definition.name)
1490
+ return (0, import_frontend_tools2.prepareToolsForFrontendConversation)(
1491
+ tools.filter(
1492
+ (t) => toolFilter.length === 0 || systemTools.includes(t.definition.name) || toolFilter.includes(t.definition.name)
1493
+ ),
1494
+ currentFrontendTools
1227
1495
  );
1228
1496
  } else {
1229
1497
  const toolFilter = this.skillSettings.tools;
1230
1498
  if (import_lodash.default.isArray(toolFilter)) {
1231
- return tools.filter((t) => systemTools.includes(t.definition.name) || toolFilter.includes(t.definition.name));
1499
+ return (0, import_frontend_tools2.prepareToolsForFrontendConversation)(
1500
+ tools.filter((t) => systemTools.includes(t.definition.name) || toolFilter.includes(t.definition.name)),
1501
+ currentFrontendTools
1502
+ );
1232
1503
  } else {
1233
- return tools;
1504
+ return (0, import_frontend_tools2.prepareToolsForFrontendConversation)(tools, currentFrontendTools);
1234
1505
  }
1235
1506
  }
1236
1507
  }
@@ -1272,6 +1543,9 @@ If information is missing, clearly state it in the summary.</Important>`;
1272
1543
  }
1273
1544
  const baseTools = await this.getAIEmployeeTools();
1274
1545
  const toolMap = await this.getToolsMap();
1546
+ for (const tool of baseTools) {
1547
+ toolMap.set(tool.definition.name, tool);
1548
+ }
1275
1549
  const availableSkills = await this.getAvailableSkills();
1276
1550
  const skillOwnedToolNames = new Set(availableSkills.flatMap((it) => it.tools ?? []));
1277
1551
  const baseToolNames = new Set(
@@ -1350,7 +1624,22 @@ If information is missing, clearly state it in the summary.</Important>`;
1350
1624
  (0, import_middleware.toolCallStatusMiddleware)(this),
1351
1625
  ...inWorkflow ? [(0, import_middleware.workflowHistoryMiddleware)(this, this.db)] : [],
1352
1626
  (0, import_middleware.conversationMiddleware)(this, { providerName, provider, llmService, model, messageId, agentThread }),
1353
- (0, import_middleware.toolCallSanitizerMiddleware)({ logger: this.logger })
1627
+ (0, import_middleware.toolCallSanitizerMiddleware)({ logger: this.logger }),
1628
+ (0, import_middleware.toolResultIntegrityMiddleware)({
1629
+ sessionId: this.sessionId,
1630
+ logger: this.logger,
1631
+ loadToolResults: async (toolCallIds) => {
1632
+ try {
1633
+ return await this.getToolCallResults(toolCallIds);
1634
+ } catch (error) {
1635
+ this.logger.warn("Failed to load persisted tool results before model call", {
1636
+ sessionId: this.sessionId,
1637
+ error
1638
+ });
1639
+ return /* @__PURE__ */ new Map();
1640
+ }
1641
+ }
1642
+ })
1354
1643
  ];
1355
1644
  }
1356
1645
  async getCurrentThread() {
@@ -1408,6 +1697,9 @@ If information is missing, clearly state it in the summary.</Important>`;
1408
1697
  get aiMessagesRepo() {
1409
1698
  return this.ctx.db.getRepository("aiMessages");
1410
1699
  }
1700
+ get aiConversationsModel() {
1701
+ return this.ctx.db.getModel("aiConversations");
1702
+ }
1411
1703
  get aiMessagesModel() {
1412
1704
  return this.ctx.db.getModel("aiMessages");
1413
1705
  }
@@ -1429,8 +1721,10 @@ function getCurrentTimezone(ctx) {
1429
1721
  }
1430
1722
  return typeof value === "string" ? value : void 0;
1431
1723
  }
1432
- function getCurrentDateTimeForPrompt(locale, timezone) {
1433
- const now = /* @__PURE__ */ new Date();
1724
+ function getCurrentDateTimeForPrompt(now, locale, timezone) {
1725
+ if (!now) {
1726
+ return void 0;
1727
+ }
1434
1728
  const normalizedLocale = locale || "en-US";
1435
1729
  try {
1436
1730
  const formatter = new Intl.DateTimeFormat(normalizedLocale, {