flowent 0.0.7 → 0.0.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 (387) hide show
  1. package/README.md +0 -3
  2. package/backend/README.md +0 -3
  3. package/backend/pyproject.toml +2 -8
  4. package/backend/src/flowent/__init__.py +6 -2
  5. package/backend/src/flowent/__pycache__/__init__.cpython-313.pyc +0 -0
  6. package/backend/src/flowent/__pycache__/agent.cpython-313.pyc +0 -0
  7. package/backend/src/flowent/__pycache__/context.cpython-313.pyc +0 -0
  8. package/backend/src/flowent/__pycache__/llm.cpython-313.pyc +0 -0
  9. package/backend/src/flowent/__pycache__/logging.cpython-313.pyc +0 -0
  10. package/backend/src/flowent/__pycache__/main.cpython-313.pyc +0 -0
  11. package/backend/src/flowent/__pycache__/patch.cpython-313.pyc +0 -0
  12. package/backend/src/flowent/__pycache__/paths.cpython-313.pyc +0 -0
  13. package/backend/src/flowent/__pycache__/sandbox.cpython-313.pyc +0 -0
  14. package/backend/src/flowent/__pycache__/storage.cpython-313.pyc +0 -0
  15. package/backend/src/flowent/__pycache__/tools.cpython-313.pyc +0 -0
  16. package/backend/src/flowent/agent.py +213 -3173
  17. package/backend/src/flowent/cli.py +19 -24
  18. package/backend/src/flowent/context.py +127 -0
  19. package/backend/src/flowent/llm.py +256 -0
  20. package/backend/src/flowent/logging.py +170 -129
  21. package/backend/src/flowent/main.py +321 -70
  22. package/backend/src/flowent/patch.py +182 -0
  23. package/backend/src/flowent/paths.py +11 -0
  24. package/backend/src/flowent/sandbox.py +214 -40
  25. package/backend/src/flowent/static/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  26. package/backend/src/flowent/static/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  27. package/backend/src/flowent/static/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  28. package/backend/src/flowent/static/assets/index-C76K95ty.js +81 -0
  29. package/backend/src/flowent/static/assets/index-iUMNKvlU.css +2 -0
  30. package/backend/src/flowent/static/flowent.png +0 -0
  31. package/backend/src/flowent/static/index.html +5 -25
  32. package/backend/src/flowent/storage.py +302 -0
  33. package/backend/src/flowent/tools.py +376 -0
  34. package/backend/tests/__pycache__/test_agent_tools.cpython-313-pytest-9.0.3.pyc +0 -0
  35. package/backend/tests/__pycache__/test_health.cpython-313-pytest-9.0.3.pyc +0 -0
  36. package/backend/tests/__pycache__/test_llm_providers.cpython-313-pytest-9.0.3.pyc +0 -0
  37. package/backend/tests/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
  38. package/backend/tests/__pycache__/test_persistence.cpython-313-pytest-9.0.3.pyc +0 -0
  39. package/backend/tests/__pycache__/test_workspace_chat.cpython-313-pytest-9.0.3.pyc +0 -0
  40. package/backend/tests/test_agent_tools.py +477 -0
  41. package/backend/tests/test_health.py +12 -0
  42. package/backend/tests/test_llm_providers.py +113 -0
  43. package/backend/tests/test_logging.py +182 -0
  44. package/backend/tests/test_persistence.py +125 -0
  45. package/backend/tests/test_workspace_chat.py +578 -0
  46. package/backend/uv.lock +803 -99
  47. package/dist/frontend/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  48. package/dist/frontend/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  49. package/dist/frontend/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  50. package/dist/frontend/assets/index-C76K95ty.js +81 -0
  51. package/dist/frontend/assets/index-iUMNKvlU.css +2 -0
  52. package/dist/frontend/flowent.png +0 -0
  53. package/dist/frontend/index.html +5 -25
  54. package/package.json +1 -2
  55. package/backend/src/flowent/__pycache__/_version.cpython-313.pyc +0 -0
  56. package/backend/src/flowent/__pycache__/access.cpython-313.pyc +0 -0
  57. package/backend/src/flowent/__pycache__/assistant_commands.cpython-313.pyc +0 -0
  58. package/backend/src/flowent/__pycache__/cli.cpython-313.pyc +0 -0
  59. package/backend/src/flowent/__pycache__/config.cpython-313.pyc +0 -0
  60. package/backend/src/flowent/__pycache__/events.cpython-313.pyc +0 -0
  61. package/backend/src/flowent/__pycache__/graph_runtime.cpython-313.pyc +0 -0
  62. package/backend/src/flowent/__pycache__/graph_service.cpython-313.pyc +0 -0
  63. package/backend/src/flowent/__pycache__/image_assets.cpython-313.pyc +0 -0
  64. package/backend/src/flowent/__pycache__/model_metadata.cpython-313.pyc +0 -0
  65. package/backend/src/flowent/__pycache__/network.cpython-313.pyc +0 -0
  66. package/backend/src/flowent/__pycache__/observability_service.cpython-313.pyc +0 -0
  67. package/backend/src/flowent/__pycache__/registry.cpython-313.pyc +0 -0
  68. package/backend/src/flowent/__pycache__/role_management.cpython-313.pyc +0 -0
  69. package/backend/src/flowent/__pycache__/runtime.cpython-313.pyc +0 -0
  70. package/backend/src/flowent/__pycache__/security.cpython-313.pyc +0 -0
  71. package/backend/src/flowent/__pycache__/settings.cpython-313.pyc +0 -0
  72. package/backend/src/flowent/__pycache__/settings_management.cpython-313.pyc +0 -0
  73. package/backend/src/flowent/__pycache__/state_db.cpython-313.pyc +0 -0
  74. package/backend/src/flowent/__pycache__/workspace_store.cpython-313.pyc +0 -0
  75. package/backend/src/flowent/access.py +0 -247
  76. package/backend/src/flowent/assistant_commands.py +0 -115
  77. package/backend/src/flowent/channels/__init__.py +0 -3
  78. package/backend/src/flowent/channels/__pycache__/__init__.cpython-313.pyc +0 -0
  79. package/backend/src/flowent/channels/__pycache__/telegram.cpython-313.pyc +0 -0
  80. package/backend/src/flowent/channels/telegram.py +0 -615
  81. package/backend/src/flowent/config.py +0 -14
  82. package/backend/src/flowent/dev.py +0 -3
  83. package/backend/src/flowent/events.py +0 -157
  84. package/backend/src/flowent/graph_runtime.py +0 -60
  85. package/backend/src/flowent/graph_service.py +0 -2401
  86. package/backend/src/flowent/image_assets.py +0 -356
  87. package/backend/src/flowent/model_metadata.py +0 -102
  88. package/backend/src/flowent/models/__init__.py +0 -125
  89. package/backend/src/flowent/models/__pycache__/__init__.cpython-313.pyc +0 -0
  90. package/backend/src/flowent/models/__pycache__/agent.cpython-313.pyc +0 -0
  91. package/backend/src/flowent/models/__pycache__/base.cpython-313.pyc +0 -0
  92. package/backend/src/flowent/models/__pycache__/blueprint.cpython-313.pyc +0 -0
  93. package/backend/src/flowent/models/__pycache__/content.cpython-313.pyc +0 -0
  94. package/backend/src/flowent/models/__pycache__/delta.cpython-313.pyc +0 -0
  95. package/backend/src/flowent/models/__pycache__/event.cpython-313.pyc +0 -0
  96. package/backend/src/flowent/models/__pycache__/graph.cpython-313.pyc +0 -0
  97. package/backend/src/flowent/models/__pycache__/history.cpython-313.pyc +0 -0
  98. package/backend/src/flowent/models/__pycache__/llm.cpython-313.pyc +0 -0
  99. package/backend/src/flowent/models/__pycache__/message.cpython-313.pyc +0 -0
  100. package/backend/src/flowent/models/__pycache__/tab.cpython-313.pyc +0 -0
  101. package/backend/src/flowent/models/__pycache__/todo.cpython-313.pyc +0 -0
  102. package/backend/src/flowent/models/agent.py +0 -34
  103. package/backend/src/flowent/models/base.py +0 -24
  104. package/backend/src/flowent/models/blueprint.py +0 -176
  105. package/backend/src/flowent/models/content.py +0 -164
  106. package/backend/src/flowent/models/delta.py +0 -44
  107. package/backend/src/flowent/models/event.py +0 -51
  108. package/backend/src/flowent/models/graph.py +0 -472
  109. package/backend/src/flowent/models/history.py +0 -272
  110. package/backend/src/flowent/models/llm.py +0 -62
  111. package/backend/src/flowent/models/message.py +0 -33
  112. package/backend/src/flowent/models/tab.py +0 -85
  113. package/backend/src/flowent/models/todo.py +0 -10
  114. package/backend/src/flowent/network.py +0 -146
  115. package/backend/src/flowent/observability_service.py +0 -218
  116. package/backend/src/flowent/prompts/__init__.py +0 -67
  117. package/backend/src/flowent/prompts/__pycache__/__init__.cpython-313.pyc +0 -0
  118. package/backend/src/flowent/prompts/__pycache__/common.cpython-313.pyc +0 -0
  119. package/backend/src/flowent/prompts/__pycache__/steward.cpython-313.pyc +0 -0
  120. package/backend/src/flowent/prompts/common.py +0 -250
  121. package/backend/src/flowent/prompts/steward.py +0 -64
  122. package/backend/src/flowent/providers/__init__.py +0 -23
  123. package/backend/src/flowent/providers/__pycache__/__init__.cpython-313.pyc +0 -0
  124. package/backend/src/flowent/providers/__pycache__/anthropic.cpython-313.pyc +0 -0
  125. package/backend/src/flowent/providers/__pycache__/base_url.cpython-313.pyc +0 -0
  126. package/backend/src/flowent/providers/__pycache__/configuration.cpython-313.pyc +0 -0
  127. package/backend/src/flowent/providers/__pycache__/content.cpython-313.pyc +0 -0
  128. package/backend/src/flowent/providers/__pycache__/errors.cpython-313.pyc +0 -0
  129. package/backend/src/flowent/providers/__pycache__/gateway.cpython-313.pyc +0 -0
  130. package/backend/src/flowent/providers/__pycache__/headers.cpython-313.pyc +0 -0
  131. package/backend/src/flowent/providers/__pycache__/management.cpython-313.pyc +0 -0
  132. package/backend/src/flowent/providers/__pycache__/openai.cpython-313.pyc +0 -0
  133. package/backend/src/flowent/providers/__pycache__/openai_responses.cpython-313.pyc +0 -0
  134. package/backend/src/flowent/providers/__pycache__/registry.cpython-313.pyc +0 -0
  135. package/backend/src/flowent/providers/__pycache__/sse.cpython-313.pyc +0 -0
  136. package/backend/src/flowent/providers/__pycache__/thinking.cpython-313.pyc +0 -0
  137. package/backend/src/flowent/providers/anthropic.py +0 -468
  138. package/backend/src/flowent/providers/base_url.py +0 -60
  139. package/backend/src/flowent/providers/configuration.py +0 -189
  140. package/backend/src/flowent/providers/content.py +0 -122
  141. package/backend/src/flowent/providers/errors.py +0 -223
  142. package/backend/src/flowent/providers/gateway.py +0 -169
  143. package/backend/src/flowent/providers/gemini.py +0 -447
  144. package/backend/src/flowent/providers/headers.py +0 -20
  145. package/backend/src/flowent/providers/management.py +0 -96
  146. package/backend/src/flowent/providers/ollama.py +0 -293
  147. package/backend/src/flowent/providers/openai.py +0 -422
  148. package/backend/src/flowent/providers/openai_responses.py +0 -655
  149. package/backend/src/flowent/providers/registry.py +0 -144
  150. package/backend/src/flowent/providers/sse.py +0 -31
  151. package/backend/src/flowent/providers/thinking.py +0 -79
  152. package/backend/src/flowent/registry.py +0 -73
  153. package/backend/src/flowent/role_management.py +0 -270
  154. package/backend/src/flowent/routes/__init__.py +0 -26
  155. package/backend/src/flowent/routes/__pycache__/__init__.cpython-313.pyc +0 -0
  156. package/backend/src/flowent/routes/__pycache__/access.cpython-313.pyc +0 -0
  157. package/backend/src/flowent/routes/__pycache__/assistant.cpython-313.pyc +0 -0
  158. package/backend/src/flowent/routes/__pycache__/image_assets.cpython-313.pyc +0 -0
  159. package/backend/src/flowent/routes/__pycache__/meta.cpython-313.pyc +0 -0
  160. package/backend/src/flowent/routes/__pycache__/nodes.cpython-313.pyc +0 -0
  161. package/backend/src/flowent/routes/__pycache__/prompts.cpython-313.pyc +0 -0
  162. package/backend/src/flowent/routes/__pycache__/providers_route.cpython-313.pyc +0 -0
  163. package/backend/src/flowent/routes/__pycache__/roles.cpython-313.pyc +0 -0
  164. package/backend/src/flowent/routes/__pycache__/settings.cpython-313.pyc +0 -0
  165. package/backend/src/flowent/routes/__pycache__/tabs.cpython-313.pyc +0 -0
  166. package/backend/src/flowent/routes/__pycache__/ws.cpython-313.pyc +0 -0
  167. package/backend/src/flowent/routes/access.py +0 -48
  168. package/backend/src/flowent/routes/assistant.py +0 -158
  169. package/backend/src/flowent/routes/image_assets.py +0 -33
  170. package/backend/src/flowent/routes/meta.py +0 -28
  171. package/backend/src/flowent/routes/nodes.py +0 -423
  172. package/backend/src/flowent/routes/prompts.py +0 -46
  173. package/backend/src/flowent/routes/providers_route.py +0 -365
  174. package/backend/src/flowent/routes/roles.py +0 -207
  175. package/backend/src/flowent/routes/settings.py +0 -379
  176. package/backend/src/flowent/routes/tabs.py +0 -298
  177. package/backend/src/flowent/routes/ws.py +0 -33
  178. package/backend/src/flowent/runtime.py +0 -160
  179. package/backend/src/flowent/security.py +0 -37
  180. package/backend/src/flowent/settings.py +0 -2112
  181. package/backend/src/flowent/settings_management.py +0 -394
  182. package/backend/src/flowent/state_db.py +0 -108
  183. package/backend/src/flowent/static/assets/AssistantPage-BW7XAd9I.js +0 -1
  184. package/backend/src/flowent/static/assets/ChannelsPage-tCJHgt6m.js +0 -1
  185. package/backend/src/flowent/static/assets/PageScaffold-f6g2l7XN.js +0 -1
  186. package/backend/src/flowent/static/assets/PromptsPage-C3Sxn2D7.js +0 -1
  187. package/backend/src/flowent/static/assets/ProvidersPage-BfmdXmNt.js +0 -3
  188. package/backend/src/flowent/static/assets/RolesPage-DET8wO4r.js +0 -1
  189. package/backend/src/flowent/static/assets/SettingsPage-D-g3deMm.js +0 -3
  190. package/backend/src/flowent/static/assets/ToolsPage-CDmtE2g4.js +0 -1
  191. package/backend/src/flowent/static/assets/WorkspacePage-AZsJ0sD0.js +0 -3
  192. package/backend/src/flowent/static/assets/WorkspacePanels-CteCjolX.js +0 -1
  193. package/backend/src/flowent/static/assets/alert-dialog-Duorp_S-.js +0 -1
  194. package/backend/src/flowent/static/assets/dialog-C3ixjGjN.js +0 -1
  195. package/backend/src/flowent/static/assets/elk-worker.min-C9JGDOE-.js +0 -6312
  196. package/backend/src/flowent/static/assets/graph-vendor-CHpVij2M.css +0 -1
  197. package/backend/src/flowent/static/assets/graph-vendor-DRq_-6fV.js +0 -7
  198. package/backend/src/flowent/static/assets/index--o_0fv0N.css +0 -1
  199. package/backend/src/flowent/static/assets/index-C9HuekJm.js +0 -10
  200. package/backend/src/flowent/static/assets/layout.worker-jMHqAFbP.js +0 -24
  201. package/backend/src/flowent/static/assets/markdown-vendor-C9RtvaJh.js +0 -29
  202. package/backend/src/flowent/static/assets/modelParams-DmnF2hwR.js +0 -1
  203. package/backend/src/flowent/static/assets/providerTypes-DT3Ahwl_.js +0 -1
  204. package/backend/src/flowent/static/assets/react-vendor-mEs_JJxa.js +0 -9
  205. package/backend/src/flowent/static/assets/roles-CuRT_chR.js +0 -1
  206. package/backend/src/flowent/static/assets/rolldown-runtime-BYbx6iT9.js +0 -1
  207. package/backend/src/flowent/static/assets/select-DCfeNu-F.js +0 -1
  208. package/backend/src/flowent/static/assets/surface-pWwG5ogx.js +0 -1
  209. package/backend/src/flowent/static/assets/ui-vendor-C5pJa8N7.js +0 -51
  210. package/backend/src/flowent/static/assets/useAppRoute-FgSHBKhV.js +0 -1
  211. package/backend/src/flowent/static/favicon.svg +0 -4
  212. package/backend/src/flowent/tools/__init__.py +0 -176
  213. package/backend/src/flowent/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  214. package/backend/src/flowent/tools/__pycache__/connect.cpython-313.pyc +0 -0
  215. package/backend/src/flowent/tools/__pycache__/contacts.cpython-313.pyc +0 -0
  216. package/backend/src/flowent/tools/__pycache__/create_agent.cpython-313.pyc +0 -0
  217. package/backend/src/flowent/tools/__pycache__/create_tab.cpython-313.pyc +0 -0
  218. package/backend/src/flowent/tools/__pycache__/delete_tab.cpython-313.pyc +0 -0
  219. package/backend/src/flowent/tools/__pycache__/edit.cpython-313.pyc +0 -0
  220. package/backend/src/flowent/tools/__pycache__/exec.cpython-313.pyc +0 -0
  221. package/backend/src/flowent/tools/__pycache__/fetch.cpython-313.pyc +0 -0
  222. package/backend/src/flowent/tools/__pycache__/idle.cpython-313.pyc +0 -0
  223. package/backend/src/flowent/tools/__pycache__/list_roles.cpython-313.pyc +0 -0
  224. package/backend/src/flowent/tools/__pycache__/list_tabs.cpython-313.pyc +0 -0
  225. package/backend/src/flowent/tools/__pycache__/list_tools.cpython-313.pyc +0 -0
  226. package/backend/src/flowent/tools/__pycache__/manage_prompts.cpython-313.pyc +0 -0
  227. package/backend/src/flowent/tools/__pycache__/manage_providers.cpython-313.pyc +0 -0
  228. package/backend/src/flowent/tools/__pycache__/manage_roles.cpython-313.pyc +0 -0
  229. package/backend/src/flowent/tools/__pycache__/manage_settings.cpython-313.pyc +0 -0
  230. package/backend/src/flowent/tools/__pycache__/read.cpython-313.pyc +0 -0
  231. package/backend/src/flowent/tools/__pycache__/send.cpython-313.pyc +0 -0
  232. package/backend/src/flowent/tools/__pycache__/set_permissions.cpython-313.pyc +0 -0
  233. package/backend/src/flowent/tools/__pycache__/sleep.cpython-313.pyc +0 -0
  234. package/backend/src/flowent/tools/__pycache__/todo.cpython-313.pyc +0 -0
  235. package/backend/src/flowent/tools/connect.py +0 -100
  236. package/backend/src/flowent/tools/contacts.py +0 -22
  237. package/backend/src/flowent/tools/create_agent.py +0 -191
  238. package/backend/src/flowent/tools/create_tab.py +0 -61
  239. package/backend/src/flowent/tools/delete_tab.py +0 -39
  240. package/backend/src/flowent/tools/edit.py +0 -142
  241. package/backend/src/flowent/tools/exec.py +0 -118
  242. package/backend/src/flowent/tools/fetch.py +0 -85
  243. package/backend/src/flowent/tools/idle.py +0 -27
  244. package/backend/src/flowent/tools/list_roles.py +0 -68
  245. package/backend/src/flowent/tools/list_tabs.py +0 -100
  246. package/backend/src/flowent/tools/list_tools.py +0 -28
  247. package/backend/src/flowent/tools/manage_prompts.py +0 -102
  248. package/backend/src/flowent/tools/manage_providers.py +0 -220
  249. package/backend/src/flowent/tools/manage_roles.py +0 -275
  250. package/backend/src/flowent/tools/manage_settings.py +0 -326
  251. package/backend/src/flowent/tools/read.py +0 -152
  252. package/backend/src/flowent/tools/send.py +0 -68
  253. package/backend/src/flowent/tools/set_permissions.py +0 -99
  254. package/backend/src/flowent/tools/sleep.py +0 -41
  255. package/backend/src/flowent/tools/todo.py +0 -51
  256. package/backend/src/flowent/workspace_store.py +0 -479
  257. package/backend/tests/__init__.py +0 -0
  258. package/backend/tests/__pycache__/__init__.cpython-313.pyc +0 -0
  259. package/backend/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  260. package/backend/tests/conftest.py +0 -6
  261. package/backend/tests/integration/api/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  262. package/backend/tests/integration/api/__pycache__/test_access_api.cpython-313-pytest-9.0.3.pyc +0 -0
  263. package/backend/tests/integration/api/__pycache__/test_assistant_api.cpython-313-pytest-9.0.3.pyc +0 -0
  264. package/backend/tests/integration/api/__pycache__/test_frontend_mounting.cpython-313-pytest-9.0.3.pyc +0 -0
  265. package/backend/tests/integration/api/__pycache__/test_meta_api.cpython-313-pytest-9.0.3.pyc +0 -0
  266. package/backend/tests/integration/api/__pycache__/test_nodes_api.cpython-313-pytest-9.0.3.pyc +0 -0
  267. package/backend/tests/integration/api/__pycache__/test_prompts_api.cpython-313-pytest-9.0.3.pyc +0 -0
  268. package/backend/tests/integration/api/__pycache__/test_roles_api.cpython-313-pytest-9.0.3.pyc +0 -0
  269. package/backend/tests/integration/api/__pycache__/test_tabs_api.cpython-313-pytest-9.0.3.pyc +0 -0
  270. package/backend/tests/integration/api/conftest.py +0 -29
  271. package/backend/tests/integration/api/test_access_api.py +0 -182
  272. package/backend/tests/integration/api/test_assistant_api.py +0 -422
  273. package/backend/tests/integration/api/test_frontend_mounting.py +0 -61
  274. package/backend/tests/integration/api/test_meta_api.py +0 -32
  275. package/backend/tests/integration/api/test_nodes_api.py +0 -787
  276. package/backend/tests/integration/api/test_prompts_api.py +0 -47
  277. package/backend/tests/integration/api/test_roles_api.py +0 -228
  278. package/backend/tests/integration/api/test_tabs_api.py +0 -688
  279. package/backend/tests/unit/__pycache__/test_access.cpython-313-pytest-9.0.3.pyc +0 -0
  280. package/backend/tests/unit/__pycache__/test_cli.cpython-313-pytest-9.0.3.pyc +0 -0
  281. package/backend/tests/unit/__pycache__/test_graph_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  282. package/backend/tests/unit/__pycache__/test_network.cpython-313-pytest-9.0.3.pyc +0 -0
  283. package/backend/tests/unit/__pycache__/test_state_sqlite_storage.cpython-313-pytest-9.0.3.pyc +0 -0
  284. package/backend/tests/unit/__pycache__/test_workspace_store.cpython-313-pytest-9.0.3.pyc +0 -0
  285. package/backend/tests/unit/agent/__pycache__/test_agent_public_api.cpython-313-pytest-9.0.3.pyc +0 -0
  286. package/backend/tests/unit/agent/__pycache__/test_agent_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  287. package/backend/tests/unit/agent/test_agent_public_api.py +0 -822
  288. package/backend/tests/unit/agent/test_agent_runtime.py +0 -3088
  289. package/backend/tests/unit/channels/__pycache__/test_telegram_channel.cpython-313-pytest-9.0.3.pyc +0 -0
  290. package/backend/tests/unit/channels/test_telegram_channel.py +0 -552
  291. package/backend/tests/unit/logging/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
  292. package/backend/tests/unit/logging/test_logging.py +0 -132
  293. package/backend/tests/unit/prompts/__pycache__/test_prompts.cpython-313-pytest-9.0.3.pyc +0 -0
  294. package/backend/tests/unit/prompts/test_prompts.py +0 -570
  295. package/backend/tests/unit/providers/__pycache__/test_anthropic_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  296. package/backend/tests/unit/providers/__pycache__/test_errors.cpython-313-pytest-9.0.3.pyc +0 -0
  297. package/backend/tests/unit/providers/__pycache__/test_extract_delta_parts.cpython-313-pytest-9.0.3.pyc +0 -0
  298. package/backend/tests/unit/providers/__pycache__/test_openai_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  299. package/backend/tests/unit/providers/__pycache__/test_openai_responses.cpython-313-pytest-9.0.3.pyc +0 -0
  300. package/backend/tests/unit/providers/__pycache__/test_provider_gateway.cpython-313-pytest-9.0.3.pyc +0 -0
  301. package/backend/tests/unit/providers/__pycache__/test_think_tag_parser.cpython-313-pytest-9.0.3.pyc +0 -0
  302. package/backend/tests/unit/providers/test_anthropic_provider.py +0 -185
  303. package/backend/tests/unit/providers/test_errors.py +0 -68
  304. package/backend/tests/unit/providers/test_extract_delta_parts.py +0 -22
  305. package/backend/tests/unit/providers/test_openai_provider.py +0 -139
  306. package/backend/tests/unit/providers/test_openai_responses.py +0 -402
  307. package/backend/tests/unit/providers/test_provider_gateway.py +0 -359
  308. package/backend/tests/unit/providers/test_think_tag_parser.py +0 -36
  309. package/backend/tests/unit/routes/__pycache__/test_prompts_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  310. package/backend/tests/unit/routes/__pycache__/test_providers_route.cpython-313-pytest-9.0.3.pyc +0 -0
  311. package/backend/tests/unit/routes/__pycache__/test_roles_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  312. package/backend/tests/unit/routes/__pycache__/test_settings_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  313. package/backend/tests/unit/routes/test_prompts_routes.py +0 -82
  314. package/backend/tests/unit/routes/test_providers_route.py +0 -370
  315. package/backend/tests/unit/routes/test_roles_routes.py +0 -539
  316. package/backend/tests/unit/routes/test_settings_routes.py +0 -1123
  317. package/backend/tests/unit/runtime/__pycache__/test_bootstrap_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  318. package/backend/tests/unit/runtime/test_bootstrap_runtime.py +0 -1002
  319. package/backend/tests/unit/sandbox/__pycache__/test_sandbox_tools.cpython-313-pytest-9.0.3.pyc +0 -0
  320. package/backend/tests/unit/sandbox/test_sandbox_tools.py +0 -78
  321. package/backend/tests/unit/security/__pycache__/test_security.cpython-313-pytest-9.0.3.pyc +0 -0
  322. package/backend/tests/unit/security/test_security.py +0 -124
  323. package/backend/tests/unit/settings/__pycache__/test_settings_roles.cpython-313-pytest-9.0.3.pyc +0 -0
  324. package/backend/tests/unit/settings/test_settings_roles.py +0 -703
  325. package/backend/tests/unit/test_access.py +0 -45
  326. package/backend/tests/unit/test_cli.py +0 -102
  327. package/backend/tests/unit/test_graph_runtime.py +0 -72
  328. package/backend/tests/unit/test_network.py +0 -51
  329. package/backend/tests/unit/test_state_sqlite_storage.py +0 -87
  330. package/backend/tests/unit/test_workspace_store.py +0 -228
  331. package/backend/tests/unit/tools/__pycache__/test_connect_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  332. package/backend/tests/unit/tools/__pycache__/test_create_agent_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  333. package/backend/tests/unit/tools/__pycache__/test_delete_tab_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  334. package/backend/tests/unit/tools/__pycache__/test_edit_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  335. package/backend/tests/unit/tools/__pycache__/test_exec_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  336. package/backend/tests/unit/tools/__pycache__/test_fetch_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  337. package/backend/tests/unit/tools/__pycache__/test_manage_prompts_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  338. package/backend/tests/unit/tools/__pycache__/test_manage_providers_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  339. package/backend/tests/unit/tools/__pycache__/test_manage_roles_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  340. package/backend/tests/unit/tools/__pycache__/test_manage_settings_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  341. package/backend/tests/unit/tools/__pycache__/test_read_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  342. package/backend/tests/unit/tools/__pycache__/test_set_permissions_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  343. package/backend/tests/unit/tools/__pycache__/test_todo_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  344. package/backend/tests/unit/tools/__pycache__/test_tool_registry.cpython-313-pytest-9.0.3.pyc +0 -0
  345. package/backend/tests/unit/tools/test_connect_tool.py +0 -228
  346. package/backend/tests/unit/tools/test_create_agent_tool.py +0 -404
  347. package/backend/tests/unit/tools/test_delete_tab_tool.py +0 -116
  348. package/backend/tests/unit/tools/test_edit_tool.py +0 -115
  349. package/backend/tests/unit/tools/test_exec_tool.py +0 -81
  350. package/backend/tests/unit/tools/test_fetch_tool.py +0 -65
  351. package/backend/tests/unit/tools/test_manage_prompts_tool.py +0 -92
  352. package/backend/tests/unit/tools/test_manage_providers_tool.py +0 -460
  353. package/backend/tests/unit/tools/test_manage_roles_tool.py +0 -411
  354. package/backend/tests/unit/tools/test_manage_settings_tool.py +0 -611
  355. package/backend/tests/unit/tools/test_read_tool.py +0 -33
  356. package/backend/tests/unit/tools/test_set_permissions_tool.py +0 -595
  357. package/backend/tests/unit/tools/test_todo_tool.py +0 -37
  358. package/backend/tests/unit/tools/test_tool_registry.py +0 -199
  359. package/dist/frontend/assets/AssistantPage-BW7XAd9I.js +0 -1
  360. package/dist/frontend/assets/ChannelsPage-tCJHgt6m.js +0 -1
  361. package/dist/frontend/assets/PageScaffold-f6g2l7XN.js +0 -1
  362. package/dist/frontend/assets/PromptsPage-C3Sxn2D7.js +0 -1
  363. package/dist/frontend/assets/ProvidersPage-BfmdXmNt.js +0 -3
  364. package/dist/frontend/assets/RolesPage-DET8wO4r.js +0 -1
  365. package/dist/frontend/assets/SettingsPage-D-g3deMm.js +0 -3
  366. package/dist/frontend/assets/ToolsPage-CDmtE2g4.js +0 -1
  367. package/dist/frontend/assets/WorkspacePage-AZsJ0sD0.js +0 -3
  368. package/dist/frontend/assets/WorkspacePanels-CteCjolX.js +0 -1
  369. package/dist/frontend/assets/alert-dialog-Duorp_S-.js +0 -1
  370. package/dist/frontend/assets/dialog-C3ixjGjN.js +0 -1
  371. package/dist/frontend/assets/elk-worker.min-C9JGDOE-.js +0 -6312
  372. package/dist/frontend/assets/graph-vendor-CHpVij2M.css +0 -1
  373. package/dist/frontend/assets/graph-vendor-DRq_-6fV.js +0 -7
  374. package/dist/frontend/assets/index--o_0fv0N.css +0 -1
  375. package/dist/frontend/assets/index-C9HuekJm.js +0 -10
  376. package/dist/frontend/assets/layout.worker-jMHqAFbP.js +0 -24
  377. package/dist/frontend/assets/markdown-vendor-C9RtvaJh.js +0 -29
  378. package/dist/frontend/assets/modelParams-DmnF2hwR.js +0 -1
  379. package/dist/frontend/assets/providerTypes-DT3Ahwl_.js +0 -1
  380. package/dist/frontend/assets/react-vendor-mEs_JJxa.js +0 -9
  381. package/dist/frontend/assets/roles-CuRT_chR.js +0 -1
  382. package/dist/frontend/assets/rolldown-runtime-BYbx6iT9.js +0 -1
  383. package/dist/frontend/assets/select-DCfeNu-F.js +0 -1
  384. package/dist/frontend/assets/surface-pWwG5ogx.js +0 -1
  385. package/dist/frontend/assets/ui-vendor-C5pJa8N7.js +0 -51
  386. package/dist/frontend/assets/useAppRoute-FgSHBKhV.js +0 -1
  387. package/dist/frontend/favicon.svg +0 -4
@@ -1,144 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from enum import StrEnum
4
- from typing import Protocol
5
-
6
- from flowent.providers import LLMProvider
7
- from flowent.providers.base_url import resolve_provider_base_url
8
-
9
-
10
- class ProviderType(StrEnum):
11
- OPENAI_COMPATIBLE = "openai_compatible"
12
- OPENAI_RESPONSES = "openai_responses"
13
- ANTHROPIC = "anthropic"
14
- GEMINI = "gemini"
15
-
16
-
17
- class ProviderFactory(Protocol):
18
- def __call__(
19
- self,
20
- *,
21
- provider_name: str,
22
- api_base_url: str,
23
- api_key: str,
24
- headers: dict[str, str],
25
- model: str,
26
- request_timeout_seconds: float,
27
- ) -> LLMProvider: ...
28
-
29
-
30
- def _build_openai_compatible_provider(
31
- *,
32
- provider_name: str,
33
- api_base_url: str,
34
- api_key: str,
35
- headers: dict[str, str],
36
- model: str,
37
- request_timeout_seconds: float,
38
- ) -> LLMProvider:
39
- from flowent.providers.openai import OpenAIProvider
40
-
41
- return OpenAIProvider(
42
- provider_name=provider_name,
43
- api_base_url=api_base_url,
44
- api_key=api_key,
45
- headers=headers,
46
- model=model,
47
- request_timeout_seconds=request_timeout_seconds,
48
- )
49
-
50
-
51
- def _build_openai_responses_provider(
52
- *,
53
- provider_name: str,
54
- api_base_url: str,
55
- api_key: str,
56
- headers: dict[str, str],
57
- model: str,
58
- request_timeout_seconds: float,
59
- ) -> LLMProvider:
60
- from flowent.providers.openai_responses import OpenAIResponsesProvider
61
-
62
- return OpenAIResponsesProvider(
63
- provider_name=provider_name,
64
- api_base_url=api_base_url,
65
- api_key=api_key,
66
- headers=headers,
67
- model=model,
68
- request_timeout_seconds=request_timeout_seconds,
69
- )
70
-
71
-
72
- def _build_anthropic_provider(
73
- *,
74
- provider_name: str,
75
- api_base_url: str,
76
- api_key: str,
77
- headers: dict[str, str],
78
- model: str,
79
- request_timeout_seconds: float,
80
- ) -> LLMProvider:
81
- from flowent.providers.anthropic import AnthropicProvider
82
-
83
- return AnthropicProvider(
84
- provider_name=provider_name,
85
- api_base_url=api_base_url,
86
- api_key=api_key,
87
- headers=headers,
88
- model=model,
89
- request_timeout_seconds=request_timeout_seconds,
90
- )
91
-
92
-
93
- def _build_gemini_provider(
94
- *,
95
- provider_name: str,
96
- api_base_url: str,
97
- api_key: str,
98
- headers: dict[str, str],
99
- model: str,
100
- request_timeout_seconds: float,
101
- ) -> LLMProvider:
102
- from flowent.providers.gemini import GeminiProvider
103
-
104
- return GeminiProvider(
105
- provider_name=provider_name,
106
- api_base_url=api_base_url,
107
- api_key=api_key,
108
- headers=headers,
109
- model=model,
110
- request_timeout_seconds=request_timeout_seconds,
111
- )
112
-
113
-
114
- PROVIDER_FACTORIES: dict[ProviderType, ProviderFactory] = {
115
- ProviderType.OPENAI_COMPATIBLE: _build_openai_compatible_provider,
116
- ProviderType.OPENAI_RESPONSES: _build_openai_responses_provider,
117
- ProviderType.ANTHROPIC: _build_anthropic_provider,
118
- ProviderType.GEMINI: _build_gemini_provider,
119
- }
120
-
121
-
122
- def create_provider(
123
- provider_type: str,
124
- base_url: str,
125
- api_key: str = "",
126
- headers: dict[str, str] | None = None,
127
- model: str = "",
128
- provider_name: str = "",
129
- request_timeout_seconds: float = 120.0,
130
- ) -> LLMProvider:
131
- try:
132
- normalized_type = ProviderType(provider_type.lower())
133
- except ValueError as exc:
134
- raise ValueError(f"Unknown provider type: {provider_type}") from exc
135
-
136
- resolved_base_url = resolve_provider_base_url(normalized_type, base_url)
137
- return PROVIDER_FACTORIES[normalized_type](
138
- provider_name=provider_name,
139
- api_base_url=resolved_base_url,
140
- api_key=api_key,
141
- headers=headers or {},
142
- model=model,
143
- request_timeout_seconds=request_timeout_seconds,
144
- )
@@ -1,31 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import json
4
- from collections.abc import Iterator
5
- from typing import Any
6
-
7
- from flowent.network import iter_response_lines
8
-
9
-
10
- def iter_sse_data(response: Any) -> Iterator[str]:
11
- for line in iter_response_lines(response):
12
- if not line or line.startswith(":"):
13
- continue
14
- if not line.startswith("data: "):
15
- continue
16
- yield line[6:]
17
-
18
-
19
- def iter_sse_json(
20
- response: Any,
21
- done_token: str | None = None,
22
- ) -> Iterator[dict[str, Any]]:
23
- for payload in iter_sse_data(response):
24
- if done_token is not None and payload.strip() == done_token:
25
- break
26
- try:
27
- parsed = json.loads(payload)
28
- except json.JSONDecodeError:
29
- continue
30
- if isinstance(parsed, dict):
31
- yield parsed
@@ -1,79 +0,0 @@
1
- from __future__ import annotations
2
-
3
-
4
- class ThinkTagParser:
5
- OPEN_TAG = "<think>"
6
- CLOSE_TAG = "</think>"
7
-
8
- def __init__(self) -> None:
9
- self._inside = False
10
- self._pending = ""
11
- self._skip_newlines = False
12
-
13
- def feed(self, text: str) -> list[tuple[str, str]]:
14
- if self._skip_newlines:
15
- text = text.lstrip("\n")
16
- if not text:
17
- return []
18
- self._skip_newlines = False
19
- self._pending += text
20
- return self._drain()
21
-
22
- def flush(self) -> list[tuple[str, str]]:
23
- if not self._pending:
24
- return []
25
- chunk_type = "thinking" if self._inside else "content"
26
- result = [(chunk_type, self._pending)]
27
- self._pending = ""
28
- return result
29
-
30
- def _drain(self) -> list[tuple[str, str]]:
31
- results: list[tuple[str, str]] = []
32
- while self._pending:
33
- tag = self.CLOSE_TAG if self._inside else self.OPEN_TAG
34
- idx = self._pending.find(tag)
35
- if idx >= 0:
36
- before = self._pending[:idx]
37
- if before:
38
- chunk_type = "thinking" if self._inside else "content"
39
- results.append((chunk_type, before))
40
- self._pending = self._pending[idx + len(tag) :]
41
- self._inside = not self._inside
42
- self._pending = self._pending.lstrip("\n")
43
- if not self._pending:
44
- self._skip_newlines = True
45
- continue
46
-
47
- for n in range(min(len(tag) - 1, len(self._pending)), 0, -1):
48
- if self._pending.endswith(tag[:n]):
49
- safe = self._pending[:-n]
50
- if safe:
51
- chunk_type = "thinking" if self._inside else "content"
52
- results.append((chunk_type, safe))
53
- self._pending = self._pending[-n:]
54
- return results
55
-
56
- chunk_type = "thinking" if self._inside else "content"
57
- results.append((chunk_type, self._pending))
58
- self._pending = ""
59
-
60
- return results
61
-
62
-
63
- def split_thinking_content(text: str) -> tuple[str, str]:
64
- parser = ThinkTagParser()
65
- chunks = parser.feed(text)
66
- chunks.extend(parser.flush())
67
-
68
- content_parts: list[str] = []
69
- thinking_parts: list[str] = []
70
-
71
- for chunk_type, chunk_text in chunks:
72
- if not chunk_text:
73
- continue
74
- if chunk_type == "thinking":
75
- thinking_parts.append(chunk_text)
76
- else:
77
- content_parts.append(chunk_text)
78
-
79
- return "".join(content_parts), "".join(thinking_parts)
@@ -1,73 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import threading
4
- from typing import TYPE_CHECKING
5
-
6
- from loguru import logger
7
-
8
- from flowent.models import NodeType
9
-
10
- if TYPE_CHECKING:
11
- from flowent.agent import Agent
12
-
13
-
14
- class AgentRegistry:
15
- def __init__(self) -> None:
16
- self._agents: dict[str, Agent] = {}
17
- self._lock = threading.Lock()
18
-
19
- def register(self, agent: Agent) -> None:
20
- with self._lock:
21
- self._agents[agent.uuid] = agent
22
- logger.info(
23
- "Node registered: {} (type={})",
24
- agent.uuid[:8],
25
- agent.config.node_type.value,
26
- )
27
-
28
- def unregister(self, agent_id: str) -> None:
29
- with self._lock:
30
- removed = self._agents.pop(agent_id, None)
31
- if removed:
32
- logger.info("Node unregistered: {}", agent_id[:8])
33
-
34
- def get(self, agent_id: str) -> Agent | None:
35
- with self._lock:
36
- return self._agents.get(agent_id)
37
-
38
- def get_assistant(self) -> Agent | None:
39
- with self._lock:
40
- for agent in self._agents.values():
41
- if agent.node_type == NodeType.ASSISTANT:
42
- return agent
43
- return None
44
-
45
- def find_by_name(self, name: str) -> Agent | None:
46
- with self._lock:
47
- matches = [a for a in self._agents.values() if a.config.name == name]
48
- if len(matches) == 1:
49
- return matches[0]
50
- return None
51
-
52
- def find_by_uuid_prefix(self, prefix: str) -> Agent | None:
53
- with self._lock:
54
- matches = [
55
- agent
56
- for agent_id, agent in self._agents.items()
57
- if agent_id.startswith(prefix)
58
- ]
59
- if len(matches) == 1:
60
- return matches[0]
61
- return None
62
-
63
- def get_all(self) -> list[Agent]:
64
- with self._lock:
65
- return list(self._agents.values())
66
-
67
- def reset(self) -> None:
68
- with self._lock:
69
- self._agents.clear()
70
- logger.debug("Registry reset")
71
-
72
-
73
- registry = AgentRegistry()
@@ -1,270 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from flowent.settings import (
4
- ModelParams,
5
- RoleConfig,
6
- RoleModelConfig,
7
- Settings,
8
- build_model_params_from_mapping,
9
- clear_role_references,
10
- find_provider,
11
- is_builtin_role_name,
12
- normalize_tool_names,
13
- rename_role_references,
14
- validate_role_tool_config,
15
- )
16
-
17
-
18
- class RoleConflictError(ValueError):
19
- pass
20
-
21
-
22
- def find_role_by_name(roles: list[RoleConfig], role_name: str) -> RoleConfig | None:
23
- for role in roles:
24
- if role.name == role_name:
25
- return role
26
- return None
27
-
28
-
29
- def require_role_name(value: str) -> str:
30
- name = value.strip()
31
- if not name:
32
- raise ValueError("Role name is required")
33
- return name
34
-
35
-
36
- def require_role_description(value: str) -> str:
37
- description = value.strip()
38
- if not description:
39
- raise ValueError("Role description is required")
40
- return description
41
-
42
-
43
- def normalize_optional_role_name(value: str | None) -> str | None:
44
- if value is None:
45
- return None
46
- return require_role_name(value)
47
-
48
-
49
- def normalize_optional_role_description(value: str | None) -> str | None:
50
- if value is None:
51
- return None
52
- return require_role_description(value)
53
-
54
-
55
- def ensure_role_name_available(
56
- roles: list[RoleConfig],
57
- role_name: str,
58
- *,
59
- current_name: str | None = None,
60
- ) -> None:
61
- if any(role.name == role_name and role.name != current_name for role in roles):
62
- raise RoleConflictError(f"Role '{role_name}' already exists")
63
-
64
-
65
- def resolve_role_tool_config(
66
- current: RoleConfig | None,
67
- included_tools: list[str] | None,
68
- excluded_tools: list[str] | None,
69
- ) -> tuple[list[str], list[str]]:
70
- from flowent.tools import is_assistant_only_tool_name
71
-
72
- next_included = normalize_tool_names(
73
- included_tools
74
- if included_tools is not None
75
- else current.included_tools
76
- if current
77
- else []
78
- )
79
- if included_tools is not None:
80
- next_included = [
81
- tool_name
82
- for tool_name in next_included
83
- if not tool_name.startswith("mcp__")
84
- and not is_assistant_only_tool_name(tool_name)
85
- ]
86
- next_excluded = normalize_tool_names(
87
- excluded_tools
88
- if excluded_tools is not None
89
- else current.excluded_tools
90
- if current
91
- else []
92
- )
93
- if excluded_tools is not None:
94
- next_excluded = [
95
- tool_name
96
- for tool_name in next_excluded
97
- if not tool_name.startswith("mcp__")
98
- ]
99
- validate_role_tool_config(next_included, next_excluded)
100
- return next_included, next_excluded
101
-
102
-
103
- def resolve_role_model(
104
- requested: object,
105
- *,
106
- settings: Settings,
107
- current: RoleModelConfig | None,
108
- provided: bool,
109
- invalid_type_error: str,
110
- missing_provider_id_error: str,
111
- missing_model_error: str,
112
- ) -> RoleModelConfig | None:
113
- if not provided:
114
- return current
115
- if requested is None:
116
- return None
117
-
118
- extracted = _extract_role_model_fields(requested)
119
- if extracted is None:
120
- raise ValueError(invalid_type_error)
121
-
122
- provider_id_value, model_value = extracted
123
- if not isinstance(provider_id_value, str) or not provider_id_value.strip():
124
- raise ValueError(missing_provider_id_error)
125
- if not isinstance(model_value, str) or not model_value.strip():
126
- raise ValueError(missing_model_error)
127
-
128
- provider_id = provider_id_value.strip()
129
- model = model_value.strip()
130
- if find_provider(settings, provider_id) is None:
131
- raise ValueError(f"Provider '{provider_id}' not found")
132
-
133
- return RoleModelConfig(provider_id=provider_id, model=model)
134
-
135
-
136
- def resolve_role_model_params(
137
- requested: object,
138
- *,
139
- current: ModelParams | None,
140
- provided: bool,
141
- ) -> ModelParams | None:
142
- if not provided:
143
- return current
144
- return build_model_params_from_mapping(requested)
145
-
146
-
147
- def validate_builtin_role_update(
148
- role: RoleConfig,
149
- *,
150
- next_name: str | None,
151
- next_description: str | None,
152
- next_system_prompt: str | None,
153
- next_included_tools: list[str],
154
- next_excluded_tools: list[str],
155
- ) -> None:
156
- if not is_builtin_role_name(role.name):
157
- return
158
- if next_name is not None and next_name != role.name:
159
- raise ValueError(f"Cannot rename built-in role '{role.name}'")
160
- if next_description is not None and next_description != role.description:
161
- raise ValueError(
162
- f"Cannot modify built-in role '{role.name}' fields other than "
163
- "model or model_params"
164
- )
165
- if next_system_prompt is not None and next_system_prompt != role.system_prompt:
166
- raise ValueError(
167
- f"Cannot modify built-in role '{role.name}' fields other than "
168
- "model or model_params"
169
- )
170
- if (
171
- next_included_tools != role.included_tools
172
- or next_excluded_tools != role.excluded_tools
173
- ):
174
- raise ValueError(
175
- f"Cannot modify built-in role '{role.name}' fields other than "
176
- "model or model_params"
177
- )
178
-
179
-
180
- def build_role_config(
181
- *,
182
- name: str,
183
- description: str,
184
- system_prompt: str,
185
- model: RoleModelConfig | None,
186
- model_params: ModelParams | None,
187
- included_tools: list[str],
188
- excluded_tools: list[str],
189
- ) -> RoleConfig:
190
- return RoleConfig(
191
- name=name,
192
- description=description,
193
- system_prompt=system_prompt,
194
- model=model,
195
- model_params=model_params,
196
- included_tools=included_tools,
197
- excluded_tools=excluded_tools,
198
- )
199
-
200
-
201
- def apply_role_update(
202
- *,
203
- settings: Settings,
204
- role: RoleConfig,
205
- next_name: str | None,
206
- next_description: str | None,
207
- next_system_prompt: str | None,
208
- next_model: RoleModelConfig | None,
209
- update_model: bool,
210
- next_model_params: ModelParams | None,
211
- update_model_params: bool,
212
- next_included_tools: list[str],
213
- next_excluded_tools: list[str],
214
- ) -> RoleConfig:
215
- previous_name = role.name
216
- if next_name is not None:
217
- role.name = next_name
218
- rename_role_references(settings, previous_name, role.name)
219
- if next_description is not None:
220
- role.description = next_description
221
- if next_system_prompt is not None:
222
- role.system_prompt = next_system_prompt
223
- if update_model:
224
- role.model = next_model
225
- if update_model_params:
226
- role.model_params = next_model_params
227
- role.included_tools = next_included_tools
228
- role.excluded_tools = next_excluded_tools
229
- return role
230
-
231
-
232
- def remove_role(settings: Settings, role: RoleConfig) -> None:
233
- settings.roles = [existing for existing in settings.roles if existing is not role]
234
- clear_role_references(settings, role.name)
235
-
236
-
237
- def sync_running_system_roles() -> None:
238
- from flowent.graph_service import sync_assistant_role, sync_tab_leaders
239
-
240
- sync_assistant_role(reason="assistant role updated")
241
- sync_tab_leaders(reason="leader role updated")
242
-
243
-
244
- def _extract_role_model_fields(requested: object) -> tuple[object, object] | None:
245
- if isinstance(requested, dict):
246
- return requested.get("provider_id"), requested.get("model")
247
- provider_id = getattr(requested, "provider_id", None)
248
- model = getattr(requested, "model", None)
249
- if provider_id is None and model is None:
250
- return None
251
- return provider_id, model
252
-
253
-
254
- __all__ = [
255
- "RoleConflictError",
256
- "apply_role_update",
257
- "build_role_config",
258
- "ensure_role_name_available",
259
- "find_role_by_name",
260
- "normalize_optional_role_description",
261
- "normalize_optional_role_name",
262
- "remove_role",
263
- "require_role_description",
264
- "require_role_name",
265
- "resolve_role_model",
266
- "resolve_role_model_params",
267
- "resolve_role_tool_config",
268
- "sync_running_system_roles",
269
- "validate_builtin_role_update",
270
- ]
@@ -1,26 +0,0 @@
1
- from fastapi import APIRouter
2
-
3
- from flowent.routes.access import router as access_router
4
- from flowent.routes.assistant import router as assistant_router
5
- from flowent.routes.image_assets import router as image_assets_router
6
- from flowent.routes.meta import router as meta_router
7
- from flowent.routes.nodes import router as nodes_router
8
- from flowent.routes.prompts import router as prompts_router
9
- from flowent.routes.providers_route import router as providers_router
10
- from flowent.routes.roles import router as roles_router
11
- from flowent.routes.settings import router as settings_router
12
- from flowent.routes.tabs import router as tabs_router
13
- from flowent.routes.ws import router as ws_router
14
-
15
- router = APIRouter()
16
- router.include_router(access_router)
17
- router.include_router(nodes_router)
18
- router.include_router(assistant_router)
19
- router.include_router(image_assets_router)
20
- router.include_router(roles_router)
21
- router.include_router(providers_router)
22
- router.include_router(prompts_router)
23
- router.include_router(settings_router)
24
- router.include_router(tabs_router)
25
- router.include_router(meta_router)
26
- router.include_router(ws_router)