flowent 0.0.7 → 0.0.10

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 (386) 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/__pycache__/__init__.cpython-313.pyc +0 -0
  5. package/backend/src/flowent/__pycache__/agent.cpython-313.pyc +0 -0
  6. package/backend/src/flowent/__pycache__/cli.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 +364 -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 +449 -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__/config.cpython-313.pyc +0 -0
  59. package/backend/src/flowent/__pycache__/events.cpython-313.pyc +0 -0
  60. package/backend/src/flowent/__pycache__/graph_runtime.cpython-313.pyc +0 -0
  61. package/backend/src/flowent/__pycache__/graph_service.cpython-313.pyc +0 -0
  62. package/backend/src/flowent/__pycache__/image_assets.cpython-313.pyc +0 -0
  63. package/backend/src/flowent/__pycache__/model_metadata.cpython-313.pyc +0 -0
  64. package/backend/src/flowent/__pycache__/network.cpython-313.pyc +0 -0
  65. package/backend/src/flowent/__pycache__/observability_service.cpython-313.pyc +0 -0
  66. package/backend/src/flowent/__pycache__/registry.cpython-313.pyc +0 -0
  67. package/backend/src/flowent/__pycache__/role_management.cpython-313.pyc +0 -0
  68. package/backend/src/flowent/__pycache__/runtime.cpython-313.pyc +0 -0
  69. package/backend/src/flowent/__pycache__/security.cpython-313.pyc +0 -0
  70. package/backend/src/flowent/__pycache__/settings.cpython-313.pyc +0 -0
  71. package/backend/src/flowent/__pycache__/settings_management.cpython-313.pyc +0 -0
  72. package/backend/src/flowent/__pycache__/state_db.cpython-313.pyc +0 -0
  73. package/backend/src/flowent/__pycache__/workspace_store.cpython-313.pyc +0 -0
  74. package/backend/src/flowent/access.py +0 -247
  75. package/backend/src/flowent/assistant_commands.py +0 -115
  76. package/backend/src/flowent/channels/__init__.py +0 -3
  77. package/backend/src/flowent/channels/__pycache__/__init__.cpython-313.pyc +0 -0
  78. package/backend/src/flowent/channels/__pycache__/telegram.cpython-313.pyc +0 -0
  79. package/backend/src/flowent/channels/telegram.py +0 -615
  80. package/backend/src/flowent/config.py +0 -14
  81. package/backend/src/flowent/dev.py +0 -3
  82. package/backend/src/flowent/events.py +0 -157
  83. package/backend/src/flowent/graph_runtime.py +0 -60
  84. package/backend/src/flowent/graph_service.py +0 -2401
  85. package/backend/src/flowent/image_assets.py +0 -356
  86. package/backend/src/flowent/model_metadata.py +0 -102
  87. package/backend/src/flowent/models/__init__.py +0 -125
  88. package/backend/src/flowent/models/__pycache__/__init__.cpython-313.pyc +0 -0
  89. package/backend/src/flowent/models/__pycache__/agent.cpython-313.pyc +0 -0
  90. package/backend/src/flowent/models/__pycache__/base.cpython-313.pyc +0 -0
  91. package/backend/src/flowent/models/__pycache__/blueprint.cpython-313.pyc +0 -0
  92. package/backend/src/flowent/models/__pycache__/content.cpython-313.pyc +0 -0
  93. package/backend/src/flowent/models/__pycache__/delta.cpython-313.pyc +0 -0
  94. package/backend/src/flowent/models/__pycache__/event.cpython-313.pyc +0 -0
  95. package/backend/src/flowent/models/__pycache__/graph.cpython-313.pyc +0 -0
  96. package/backend/src/flowent/models/__pycache__/history.cpython-313.pyc +0 -0
  97. package/backend/src/flowent/models/__pycache__/llm.cpython-313.pyc +0 -0
  98. package/backend/src/flowent/models/__pycache__/message.cpython-313.pyc +0 -0
  99. package/backend/src/flowent/models/__pycache__/tab.cpython-313.pyc +0 -0
  100. package/backend/src/flowent/models/__pycache__/todo.cpython-313.pyc +0 -0
  101. package/backend/src/flowent/models/agent.py +0 -34
  102. package/backend/src/flowent/models/base.py +0 -24
  103. package/backend/src/flowent/models/blueprint.py +0 -176
  104. package/backend/src/flowent/models/content.py +0 -164
  105. package/backend/src/flowent/models/delta.py +0 -44
  106. package/backend/src/flowent/models/event.py +0 -51
  107. package/backend/src/flowent/models/graph.py +0 -472
  108. package/backend/src/flowent/models/history.py +0 -272
  109. package/backend/src/flowent/models/llm.py +0 -62
  110. package/backend/src/flowent/models/message.py +0 -33
  111. package/backend/src/flowent/models/tab.py +0 -85
  112. package/backend/src/flowent/models/todo.py +0 -10
  113. package/backend/src/flowent/network.py +0 -146
  114. package/backend/src/flowent/observability_service.py +0 -218
  115. package/backend/src/flowent/prompts/__init__.py +0 -67
  116. package/backend/src/flowent/prompts/__pycache__/__init__.cpython-313.pyc +0 -0
  117. package/backend/src/flowent/prompts/__pycache__/common.cpython-313.pyc +0 -0
  118. package/backend/src/flowent/prompts/__pycache__/steward.cpython-313.pyc +0 -0
  119. package/backend/src/flowent/prompts/common.py +0 -250
  120. package/backend/src/flowent/prompts/steward.py +0 -64
  121. package/backend/src/flowent/providers/__init__.py +0 -23
  122. package/backend/src/flowent/providers/__pycache__/__init__.cpython-313.pyc +0 -0
  123. package/backend/src/flowent/providers/__pycache__/anthropic.cpython-313.pyc +0 -0
  124. package/backend/src/flowent/providers/__pycache__/base_url.cpython-313.pyc +0 -0
  125. package/backend/src/flowent/providers/__pycache__/configuration.cpython-313.pyc +0 -0
  126. package/backend/src/flowent/providers/__pycache__/content.cpython-313.pyc +0 -0
  127. package/backend/src/flowent/providers/__pycache__/errors.cpython-313.pyc +0 -0
  128. package/backend/src/flowent/providers/__pycache__/gateway.cpython-313.pyc +0 -0
  129. package/backend/src/flowent/providers/__pycache__/headers.cpython-313.pyc +0 -0
  130. package/backend/src/flowent/providers/__pycache__/management.cpython-313.pyc +0 -0
  131. package/backend/src/flowent/providers/__pycache__/openai.cpython-313.pyc +0 -0
  132. package/backend/src/flowent/providers/__pycache__/openai_responses.cpython-313.pyc +0 -0
  133. package/backend/src/flowent/providers/__pycache__/registry.cpython-313.pyc +0 -0
  134. package/backend/src/flowent/providers/__pycache__/sse.cpython-313.pyc +0 -0
  135. package/backend/src/flowent/providers/__pycache__/thinking.cpython-313.pyc +0 -0
  136. package/backend/src/flowent/providers/anthropic.py +0 -468
  137. package/backend/src/flowent/providers/base_url.py +0 -60
  138. package/backend/src/flowent/providers/configuration.py +0 -189
  139. package/backend/src/flowent/providers/content.py +0 -122
  140. package/backend/src/flowent/providers/errors.py +0 -223
  141. package/backend/src/flowent/providers/gateway.py +0 -169
  142. package/backend/src/flowent/providers/gemini.py +0 -447
  143. package/backend/src/flowent/providers/headers.py +0 -20
  144. package/backend/src/flowent/providers/management.py +0 -96
  145. package/backend/src/flowent/providers/ollama.py +0 -293
  146. package/backend/src/flowent/providers/openai.py +0 -422
  147. package/backend/src/flowent/providers/openai_responses.py +0 -655
  148. package/backend/src/flowent/providers/registry.py +0 -144
  149. package/backend/src/flowent/providers/sse.py +0 -31
  150. package/backend/src/flowent/providers/thinking.py +0 -79
  151. package/backend/src/flowent/registry.py +0 -73
  152. package/backend/src/flowent/role_management.py +0 -270
  153. package/backend/src/flowent/routes/__init__.py +0 -26
  154. package/backend/src/flowent/routes/__pycache__/__init__.cpython-313.pyc +0 -0
  155. package/backend/src/flowent/routes/__pycache__/access.cpython-313.pyc +0 -0
  156. package/backend/src/flowent/routes/__pycache__/assistant.cpython-313.pyc +0 -0
  157. package/backend/src/flowent/routes/__pycache__/image_assets.cpython-313.pyc +0 -0
  158. package/backend/src/flowent/routes/__pycache__/meta.cpython-313.pyc +0 -0
  159. package/backend/src/flowent/routes/__pycache__/nodes.cpython-313.pyc +0 -0
  160. package/backend/src/flowent/routes/__pycache__/prompts.cpython-313.pyc +0 -0
  161. package/backend/src/flowent/routes/__pycache__/providers_route.cpython-313.pyc +0 -0
  162. package/backend/src/flowent/routes/__pycache__/roles.cpython-313.pyc +0 -0
  163. package/backend/src/flowent/routes/__pycache__/settings.cpython-313.pyc +0 -0
  164. package/backend/src/flowent/routes/__pycache__/tabs.cpython-313.pyc +0 -0
  165. package/backend/src/flowent/routes/__pycache__/ws.cpython-313.pyc +0 -0
  166. package/backend/src/flowent/routes/access.py +0 -48
  167. package/backend/src/flowent/routes/assistant.py +0 -158
  168. package/backend/src/flowent/routes/image_assets.py +0 -33
  169. package/backend/src/flowent/routes/meta.py +0 -28
  170. package/backend/src/flowent/routes/nodes.py +0 -423
  171. package/backend/src/flowent/routes/prompts.py +0 -46
  172. package/backend/src/flowent/routes/providers_route.py +0 -365
  173. package/backend/src/flowent/routes/roles.py +0 -207
  174. package/backend/src/flowent/routes/settings.py +0 -379
  175. package/backend/src/flowent/routes/tabs.py +0 -298
  176. package/backend/src/flowent/routes/ws.py +0 -33
  177. package/backend/src/flowent/runtime.py +0 -160
  178. package/backend/src/flowent/security.py +0 -37
  179. package/backend/src/flowent/settings.py +0 -2112
  180. package/backend/src/flowent/settings_management.py +0 -394
  181. package/backend/src/flowent/state_db.py +0 -108
  182. package/backend/src/flowent/static/assets/AssistantPage-BW7XAd9I.js +0 -1
  183. package/backend/src/flowent/static/assets/ChannelsPage-tCJHgt6m.js +0 -1
  184. package/backend/src/flowent/static/assets/PageScaffold-f6g2l7XN.js +0 -1
  185. package/backend/src/flowent/static/assets/PromptsPage-C3Sxn2D7.js +0 -1
  186. package/backend/src/flowent/static/assets/ProvidersPage-BfmdXmNt.js +0 -3
  187. package/backend/src/flowent/static/assets/RolesPage-DET8wO4r.js +0 -1
  188. package/backend/src/flowent/static/assets/SettingsPage-D-g3deMm.js +0 -3
  189. package/backend/src/flowent/static/assets/ToolsPage-CDmtE2g4.js +0 -1
  190. package/backend/src/flowent/static/assets/WorkspacePage-AZsJ0sD0.js +0 -3
  191. package/backend/src/flowent/static/assets/WorkspacePanels-CteCjolX.js +0 -1
  192. package/backend/src/flowent/static/assets/alert-dialog-Duorp_S-.js +0 -1
  193. package/backend/src/flowent/static/assets/dialog-C3ixjGjN.js +0 -1
  194. package/backend/src/flowent/static/assets/elk-worker.min-C9JGDOE-.js +0 -6312
  195. package/backend/src/flowent/static/assets/graph-vendor-CHpVij2M.css +0 -1
  196. package/backend/src/flowent/static/assets/graph-vendor-DRq_-6fV.js +0 -7
  197. package/backend/src/flowent/static/assets/index--o_0fv0N.css +0 -1
  198. package/backend/src/flowent/static/assets/index-C9HuekJm.js +0 -10
  199. package/backend/src/flowent/static/assets/layout.worker-jMHqAFbP.js +0 -24
  200. package/backend/src/flowent/static/assets/markdown-vendor-C9RtvaJh.js +0 -29
  201. package/backend/src/flowent/static/assets/modelParams-DmnF2hwR.js +0 -1
  202. package/backend/src/flowent/static/assets/providerTypes-DT3Ahwl_.js +0 -1
  203. package/backend/src/flowent/static/assets/react-vendor-mEs_JJxa.js +0 -9
  204. package/backend/src/flowent/static/assets/roles-CuRT_chR.js +0 -1
  205. package/backend/src/flowent/static/assets/rolldown-runtime-BYbx6iT9.js +0 -1
  206. package/backend/src/flowent/static/assets/select-DCfeNu-F.js +0 -1
  207. package/backend/src/flowent/static/assets/surface-pWwG5ogx.js +0 -1
  208. package/backend/src/flowent/static/assets/ui-vendor-C5pJa8N7.js +0 -51
  209. package/backend/src/flowent/static/assets/useAppRoute-FgSHBKhV.js +0 -1
  210. package/backend/src/flowent/static/favicon.svg +0 -4
  211. package/backend/src/flowent/tools/__init__.py +0 -176
  212. package/backend/src/flowent/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  213. package/backend/src/flowent/tools/__pycache__/connect.cpython-313.pyc +0 -0
  214. package/backend/src/flowent/tools/__pycache__/contacts.cpython-313.pyc +0 -0
  215. package/backend/src/flowent/tools/__pycache__/create_agent.cpython-313.pyc +0 -0
  216. package/backend/src/flowent/tools/__pycache__/create_tab.cpython-313.pyc +0 -0
  217. package/backend/src/flowent/tools/__pycache__/delete_tab.cpython-313.pyc +0 -0
  218. package/backend/src/flowent/tools/__pycache__/edit.cpython-313.pyc +0 -0
  219. package/backend/src/flowent/tools/__pycache__/exec.cpython-313.pyc +0 -0
  220. package/backend/src/flowent/tools/__pycache__/fetch.cpython-313.pyc +0 -0
  221. package/backend/src/flowent/tools/__pycache__/idle.cpython-313.pyc +0 -0
  222. package/backend/src/flowent/tools/__pycache__/list_roles.cpython-313.pyc +0 -0
  223. package/backend/src/flowent/tools/__pycache__/list_tabs.cpython-313.pyc +0 -0
  224. package/backend/src/flowent/tools/__pycache__/list_tools.cpython-313.pyc +0 -0
  225. package/backend/src/flowent/tools/__pycache__/manage_prompts.cpython-313.pyc +0 -0
  226. package/backend/src/flowent/tools/__pycache__/manage_providers.cpython-313.pyc +0 -0
  227. package/backend/src/flowent/tools/__pycache__/manage_roles.cpython-313.pyc +0 -0
  228. package/backend/src/flowent/tools/__pycache__/manage_settings.cpython-313.pyc +0 -0
  229. package/backend/src/flowent/tools/__pycache__/read.cpython-313.pyc +0 -0
  230. package/backend/src/flowent/tools/__pycache__/send.cpython-313.pyc +0 -0
  231. package/backend/src/flowent/tools/__pycache__/set_permissions.cpython-313.pyc +0 -0
  232. package/backend/src/flowent/tools/__pycache__/sleep.cpython-313.pyc +0 -0
  233. package/backend/src/flowent/tools/__pycache__/todo.cpython-313.pyc +0 -0
  234. package/backend/src/flowent/tools/connect.py +0 -100
  235. package/backend/src/flowent/tools/contacts.py +0 -22
  236. package/backend/src/flowent/tools/create_agent.py +0 -191
  237. package/backend/src/flowent/tools/create_tab.py +0 -61
  238. package/backend/src/flowent/tools/delete_tab.py +0 -39
  239. package/backend/src/flowent/tools/edit.py +0 -142
  240. package/backend/src/flowent/tools/exec.py +0 -118
  241. package/backend/src/flowent/tools/fetch.py +0 -85
  242. package/backend/src/flowent/tools/idle.py +0 -27
  243. package/backend/src/flowent/tools/list_roles.py +0 -68
  244. package/backend/src/flowent/tools/list_tabs.py +0 -100
  245. package/backend/src/flowent/tools/list_tools.py +0 -28
  246. package/backend/src/flowent/tools/manage_prompts.py +0 -102
  247. package/backend/src/flowent/tools/manage_providers.py +0 -220
  248. package/backend/src/flowent/tools/manage_roles.py +0 -275
  249. package/backend/src/flowent/tools/manage_settings.py +0 -326
  250. package/backend/src/flowent/tools/read.py +0 -152
  251. package/backend/src/flowent/tools/send.py +0 -68
  252. package/backend/src/flowent/tools/set_permissions.py +0 -99
  253. package/backend/src/flowent/tools/sleep.py +0 -41
  254. package/backend/src/flowent/tools/todo.py +0 -51
  255. package/backend/src/flowent/workspace_store.py +0 -479
  256. package/backend/tests/__init__.py +0 -0
  257. package/backend/tests/__pycache__/__init__.cpython-313.pyc +0 -0
  258. package/backend/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  259. package/backend/tests/conftest.py +0 -6
  260. package/backend/tests/integration/api/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  261. package/backend/tests/integration/api/__pycache__/test_access_api.cpython-313-pytest-9.0.3.pyc +0 -0
  262. package/backend/tests/integration/api/__pycache__/test_assistant_api.cpython-313-pytest-9.0.3.pyc +0 -0
  263. package/backend/tests/integration/api/__pycache__/test_frontend_mounting.cpython-313-pytest-9.0.3.pyc +0 -0
  264. package/backend/tests/integration/api/__pycache__/test_meta_api.cpython-313-pytest-9.0.3.pyc +0 -0
  265. package/backend/tests/integration/api/__pycache__/test_nodes_api.cpython-313-pytest-9.0.3.pyc +0 -0
  266. package/backend/tests/integration/api/__pycache__/test_prompts_api.cpython-313-pytest-9.0.3.pyc +0 -0
  267. package/backend/tests/integration/api/__pycache__/test_roles_api.cpython-313-pytest-9.0.3.pyc +0 -0
  268. package/backend/tests/integration/api/__pycache__/test_tabs_api.cpython-313-pytest-9.0.3.pyc +0 -0
  269. package/backend/tests/integration/api/conftest.py +0 -29
  270. package/backend/tests/integration/api/test_access_api.py +0 -182
  271. package/backend/tests/integration/api/test_assistant_api.py +0 -422
  272. package/backend/tests/integration/api/test_frontend_mounting.py +0 -61
  273. package/backend/tests/integration/api/test_meta_api.py +0 -32
  274. package/backend/tests/integration/api/test_nodes_api.py +0 -787
  275. package/backend/tests/integration/api/test_prompts_api.py +0 -47
  276. package/backend/tests/integration/api/test_roles_api.py +0 -228
  277. package/backend/tests/integration/api/test_tabs_api.py +0 -688
  278. package/backend/tests/unit/__pycache__/test_access.cpython-313-pytest-9.0.3.pyc +0 -0
  279. package/backend/tests/unit/__pycache__/test_cli.cpython-313-pytest-9.0.3.pyc +0 -0
  280. package/backend/tests/unit/__pycache__/test_graph_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  281. package/backend/tests/unit/__pycache__/test_network.cpython-313-pytest-9.0.3.pyc +0 -0
  282. package/backend/tests/unit/__pycache__/test_state_sqlite_storage.cpython-313-pytest-9.0.3.pyc +0 -0
  283. package/backend/tests/unit/__pycache__/test_workspace_store.cpython-313-pytest-9.0.3.pyc +0 -0
  284. package/backend/tests/unit/agent/__pycache__/test_agent_public_api.cpython-313-pytest-9.0.3.pyc +0 -0
  285. package/backend/tests/unit/agent/__pycache__/test_agent_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  286. package/backend/tests/unit/agent/test_agent_public_api.py +0 -822
  287. package/backend/tests/unit/agent/test_agent_runtime.py +0 -3088
  288. package/backend/tests/unit/channels/__pycache__/test_telegram_channel.cpython-313-pytest-9.0.3.pyc +0 -0
  289. package/backend/tests/unit/channels/test_telegram_channel.py +0 -552
  290. package/backend/tests/unit/logging/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
  291. package/backend/tests/unit/logging/test_logging.py +0 -132
  292. package/backend/tests/unit/prompts/__pycache__/test_prompts.cpython-313-pytest-9.0.3.pyc +0 -0
  293. package/backend/tests/unit/prompts/test_prompts.py +0 -570
  294. package/backend/tests/unit/providers/__pycache__/test_anthropic_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  295. package/backend/tests/unit/providers/__pycache__/test_errors.cpython-313-pytest-9.0.3.pyc +0 -0
  296. package/backend/tests/unit/providers/__pycache__/test_extract_delta_parts.cpython-313-pytest-9.0.3.pyc +0 -0
  297. package/backend/tests/unit/providers/__pycache__/test_openai_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  298. package/backend/tests/unit/providers/__pycache__/test_openai_responses.cpython-313-pytest-9.0.3.pyc +0 -0
  299. package/backend/tests/unit/providers/__pycache__/test_provider_gateway.cpython-313-pytest-9.0.3.pyc +0 -0
  300. package/backend/tests/unit/providers/__pycache__/test_think_tag_parser.cpython-313-pytest-9.0.3.pyc +0 -0
  301. package/backend/tests/unit/providers/test_anthropic_provider.py +0 -185
  302. package/backend/tests/unit/providers/test_errors.py +0 -68
  303. package/backend/tests/unit/providers/test_extract_delta_parts.py +0 -22
  304. package/backend/tests/unit/providers/test_openai_provider.py +0 -139
  305. package/backend/tests/unit/providers/test_openai_responses.py +0 -402
  306. package/backend/tests/unit/providers/test_provider_gateway.py +0 -359
  307. package/backend/tests/unit/providers/test_think_tag_parser.py +0 -36
  308. package/backend/tests/unit/routes/__pycache__/test_prompts_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  309. package/backend/tests/unit/routes/__pycache__/test_providers_route.cpython-313-pytest-9.0.3.pyc +0 -0
  310. package/backend/tests/unit/routes/__pycache__/test_roles_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  311. package/backend/tests/unit/routes/__pycache__/test_settings_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  312. package/backend/tests/unit/routes/test_prompts_routes.py +0 -82
  313. package/backend/tests/unit/routes/test_providers_route.py +0 -370
  314. package/backend/tests/unit/routes/test_roles_routes.py +0 -539
  315. package/backend/tests/unit/routes/test_settings_routes.py +0 -1123
  316. package/backend/tests/unit/runtime/__pycache__/test_bootstrap_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  317. package/backend/tests/unit/runtime/test_bootstrap_runtime.py +0 -1002
  318. package/backend/tests/unit/sandbox/__pycache__/test_sandbox_tools.cpython-313-pytest-9.0.3.pyc +0 -0
  319. package/backend/tests/unit/sandbox/test_sandbox_tools.py +0 -78
  320. package/backend/tests/unit/security/__pycache__/test_security.cpython-313-pytest-9.0.3.pyc +0 -0
  321. package/backend/tests/unit/security/test_security.py +0 -124
  322. package/backend/tests/unit/settings/__pycache__/test_settings_roles.cpython-313-pytest-9.0.3.pyc +0 -0
  323. package/backend/tests/unit/settings/test_settings_roles.py +0 -703
  324. package/backend/tests/unit/test_access.py +0 -45
  325. package/backend/tests/unit/test_cli.py +0 -102
  326. package/backend/tests/unit/test_graph_runtime.py +0 -72
  327. package/backend/tests/unit/test_network.py +0 -51
  328. package/backend/tests/unit/test_state_sqlite_storage.py +0 -87
  329. package/backend/tests/unit/test_workspace_store.py +0 -228
  330. package/backend/tests/unit/tools/__pycache__/test_connect_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  331. package/backend/tests/unit/tools/__pycache__/test_create_agent_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  332. package/backend/tests/unit/tools/__pycache__/test_delete_tab_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  333. package/backend/tests/unit/tools/__pycache__/test_edit_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  334. package/backend/tests/unit/tools/__pycache__/test_exec_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  335. package/backend/tests/unit/tools/__pycache__/test_fetch_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  336. package/backend/tests/unit/tools/__pycache__/test_manage_prompts_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  337. package/backend/tests/unit/tools/__pycache__/test_manage_providers_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  338. package/backend/tests/unit/tools/__pycache__/test_manage_roles_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  339. package/backend/tests/unit/tools/__pycache__/test_manage_settings_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  340. package/backend/tests/unit/tools/__pycache__/test_read_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  341. package/backend/tests/unit/tools/__pycache__/test_set_permissions_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  342. package/backend/tests/unit/tools/__pycache__/test_todo_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  343. package/backend/tests/unit/tools/__pycache__/test_tool_registry.cpython-313-pytest-9.0.3.pyc +0 -0
  344. package/backend/tests/unit/tools/test_connect_tool.py +0 -228
  345. package/backend/tests/unit/tools/test_create_agent_tool.py +0 -404
  346. package/backend/tests/unit/tools/test_delete_tab_tool.py +0 -116
  347. package/backend/tests/unit/tools/test_edit_tool.py +0 -115
  348. package/backend/tests/unit/tools/test_exec_tool.py +0 -81
  349. package/backend/tests/unit/tools/test_fetch_tool.py +0 -65
  350. package/backend/tests/unit/tools/test_manage_prompts_tool.py +0 -92
  351. package/backend/tests/unit/tools/test_manage_providers_tool.py +0 -460
  352. package/backend/tests/unit/tools/test_manage_roles_tool.py +0 -411
  353. package/backend/tests/unit/tools/test_manage_settings_tool.py +0 -611
  354. package/backend/tests/unit/tools/test_read_tool.py +0 -33
  355. package/backend/tests/unit/tools/test_set_permissions_tool.py +0 -595
  356. package/backend/tests/unit/tools/test_todo_tool.py +0 -37
  357. package/backend/tests/unit/tools/test_tool_registry.py +0 -199
  358. package/dist/frontend/assets/AssistantPage-BW7XAd9I.js +0 -1
  359. package/dist/frontend/assets/ChannelsPage-tCJHgt6m.js +0 -1
  360. package/dist/frontend/assets/PageScaffold-f6g2l7XN.js +0 -1
  361. package/dist/frontend/assets/PromptsPage-C3Sxn2D7.js +0 -1
  362. package/dist/frontend/assets/ProvidersPage-BfmdXmNt.js +0 -3
  363. package/dist/frontend/assets/RolesPage-DET8wO4r.js +0 -1
  364. package/dist/frontend/assets/SettingsPage-D-g3deMm.js +0 -3
  365. package/dist/frontend/assets/ToolsPage-CDmtE2g4.js +0 -1
  366. package/dist/frontend/assets/WorkspacePage-AZsJ0sD0.js +0 -3
  367. package/dist/frontend/assets/WorkspacePanels-CteCjolX.js +0 -1
  368. package/dist/frontend/assets/alert-dialog-Duorp_S-.js +0 -1
  369. package/dist/frontend/assets/dialog-C3ixjGjN.js +0 -1
  370. package/dist/frontend/assets/elk-worker.min-C9JGDOE-.js +0 -6312
  371. package/dist/frontend/assets/graph-vendor-CHpVij2M.css +0 -1
  372. package/dist/frontend/assets/graph-vendor-DRq_-6fV.js +0 -7
  373. package/dist/frontend/assets/index--o_0fv0N.css +0 -1
  374. package/dist/frontend/assets/index-C9HuekJm.js +0 -10
  375. package/dist/frontend/assets/layout.worker-jMHqAFbP.js +0 -24
  376. package/dist/frontend/assets/markdown-vendor-C9RtvaJh.js +0 -29
  377. package/dist/frontend/assets/modelParams-DmnF2hwR.js +0 -1
  378. package/dist/frontend/assets/providerTypes-DT3Ahwl_.js +0 -1
  379. package/dist/frontend/assets/react-vendor-mEs_JJxa.js +0 -9
  380. package/dist/frontend/assets/roles-CuRT_chR.js +0 -1
  381. package/dist/frontend/assets/rolldown-runtime-BYbx6iT9.js +0 -1
  382. package/dist/frontend/assets/select-DCfeNu-F.js +0 -1
  383. package/dist/frontend/assets/surface-pWwG5ogx.js +0 -1
  384. package/dist/frontend/assets/ui-vendor-C5pJa8N7.js +0 -51
  385. package/dist/frontend/assets/useAppRoute-FgSHBKhV.js +0 -1
  386. 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)