flowent 0.0.6 → 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 (398) hide show
  1. package/README.md +1 -4
  2. package/backend/README.md +1 -4
  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 +217 -3094
  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__/mcp_service.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 -2508
  86. package/backend/src/flowent/image_assets.py +0 -356
  87. package/backend/src/flowent/mcp_service.py +0 -1918
  88. package/backend/src/flowent/model_metadata.py +0 -102
  89. package/backend/src/flowent/models/__init__.py +0 -125
  90. package/backend/src/flowent/models/__pycache__/__init__.cpython-313.pyc +0 -0
  91. package/backend/src/flowent/models/__pycache__/agent.cpython-313.pyc +0 -0
  92. package/backend/src/flowent/models/__pycache__/base.cpython-313.pyc +0 -0
  93. package/backend/src/flowent/models/__pycache__/blueprint.cpython-313.pyc +0 -0
  94. package/backend/src/flowent/models/__pycache__/content.cpython-313.pyc +0 -0
  95. package/backend/src/flowent/models/__pycache__/delta.cpython-313.pyc +0 -0
  96. package/backend/src/flowent/models/__pycache__/event.cpython-313.pyc +0 -0
  97. package/backend/src/flowent/models/__pycache__/graph.cpython-313.pyc +0 -0
  98. package/backend/src/flowent/models/__pycache__/history.cpython-313.pyc +0 -0
  99. package/backend/src/flowent/models/__pycache__/llm.cpython-313.pyc +0 -0
  100. package/backend/src/flowent/models/__pycache__/message.cpython-313.pyc +0 -0
  101. package/backend/src/flowent/models/__pycache__/tab.cpython-313.pyc +0 -0
  102. package/backend/src/flowent/models/__pycache__/todo.cpython-313.pyc +0 -0
  103. package/backend/src/flowent/models/agent.py +0 -34
  104. package/backend/src/flowent/models/base.py +0 -24
  105. package/backend/src/flowent/models/blueprint.py +0 -176
  106. package/backend/src/flowent/models/content.py +0 -164
  107. package/backend/src/flowent/models/delta.py +0 -44
  108. package/backend/src/flowent/models/event.py +0 -51
  109. package/backend/src/flowent/models/graph.py +0 -472
  110. package/backend/src/flowent/models/history.py +0 -272
  111. package/backend/src/flowent/models/llm.py +0 -62
  112. package/backend/src/flowent/models/message.py +0 -33
  113. package/backend/src/flowent/models/tab.py +0 -85
  114. package/backend/src/flowent/models/todo.py +0 -10
  115. package/backend/src/flowent/network.py +0 -146
  116. package/backend/src/flowent/observability_service.py +0 -218
  117. package/backend/src/flowent/prompts/__init__.py +0 -67
  118. package/backend/src/flowent/prompts/__pycache__/__init__.cpython-313.pyc +0 -0
  119. package/backend/src/flowent/prompts/__pycache__/common.cpython-313.pyc +0 -0
  120. package/backend/src/flowent/prompts/__pycache__/steward.cpython-313.pyc +0 -0
  121. package/backend/src/flowent/prompts/common.py +0 -250
  122. package/backend/src/flowent/prompts/steward.py +0 -64
  123. package/backend/src/flowent/providers/__init__.py +0 -23
  124. package/backend/src/flowent/providers/__pycache__/__init__.cpython-313.pyc +0 -0
  125. package/backend/src/flowent/providers/__pycache__/anthropic.cpython-313.pyc +0 -0
  126. package/backend/src/flowent/providers/__pycache__/base_url.cpython-313.pyc +0 -0
  127. package/backend/src/flowent/providers/__pycache__/configuration.cpython-313.pyc +0 -0
  128. package/backend/src/flowent/providers/__pycache__/content.cpython-313.pyc +0 -0
  129. package/backend/src/flowent/providers/__pycache__/errors.cpython-313.pyc +0 -0
  130. package/backend/src/flowent/providers/__pycache__/gateway.cpython-313.pyc +0 -0
  131. package/backend/src/flowent/providers/__pycache__/headers.cpython-313.pyc +0 -0
  132. package/backend/src/flowent/providers/__pycache__/management.cpython-313.pyc +0 -0
  133. package/backend/src/flowent/providers/__pycache__/openai.cpython-313.pyc +0 -0
  134. package/backend/src/flowent/providers/__pycache__/openai_responses.cpython-313.pyc +0 -0
  135. package/backend/src/flowent/providers/__pycache__/registry.cpython-313.pyc +0 -0
  136. package/backend/src/flowent/providers/__pycache__/sse.cpython-313.pyc +0 -0
  137. package/backend/src/flowent/providers/__pycache__/thinking.cpython-313.pyc +0 -0
  138. package/backend/src/flowent/providers/anthropic.py +0 -468
  139. package/backend/src/flowent/providers/base_url.py +0 -60
  140. package/backend/src/flowent/providers/configuration.py +0 -189
  141. package/backend/src/flowent/providers/content.py +0 -122
  142. package/backend/src/flowent/providers/errors.py +0 -223
  143. package/backend/src/flowent/providers/gateway.py +0 -169
  144. package/backend/src/flowent/providers/gemini.py +0 -447
  145. package/backend/src/flowent/providers/headers.py +0 -20
  146. package/backend/src/flowent/providers/management.py +0 -96
  147. package/backend/src/flowent/providers/ollama.py +0 -293
  148. package/backend/src/flowent/providers/openai.py +0 -422
  149. package/backend/src/flowent/providers/openai_responses.py +0 -655
  150. package/backend/src/flowent/providers/registry.py +0 -144
  151. package/backend/src/flowent/providers/sse.py +0 -31
  152. package/backend/src/flowent/providers/thinking.py +0 -79
  153. package/backend/src/flowent/registry.py +0 -73
  154. package/backend/src/flowent/role_management.py +0 -267
  155. package/backend/src/flowent/routes/__init__.py +0 -28
  156. package/backend/src/flowent/routes/__pycache__/__init__.cpython-313.pyc +0 -0
  157. package/backend/src/flowent/routes/__pycache__/access.cpython-313.pyc +0 -0
  158. package/backend/src/flowent/routes/__pycache__/assistant.cpython-313.pyc +0 -0
  159. package/backend/src/flowent/routes/__pycache__/image_assets.cpython-313.pyc +0 -0
  160. package/backend/src/flowent/routes/__pycache__/mcp.cpython-313.pyc +0 -0
  161. package/backend/src/flowent/routes/__pycache__/meta.cpython-313.pyc +0 -0
  162. package/backend/src/flowent/routes/__pycache__/nodes.cpython-313.pyc +0 -0
  163. package/backend/src/flowent/routes/__pycache__/prompts.cpython-313.pyc +0 -0
  164. package/backend/src/flowent/routes/__pycache__/providers_route.cpython-313.pyc +0 -0
  165. package/backend/src/flowent/routes/__pycache__/roles.cpython-313.pyc +0 -0
  166. package/backend/src/flowent/routes/__pycache__/settings.cpython-313.pyc +0 -0
  167. package/backend/src/flowent/routes/__pycache__/tabs.cpython-313.pyc +0 -0
  168. package/backend/src/flowent/routes/__pycache__/ws.cpython-313.pyc +0 -0
  169. package/backend/src/flowent/routes/access.py +0 -48
  170. package/backend/src/flowent/routes/assistant.py +0 -155
  171. package/backend/src/flowent/routes/image_assets.py +0 -33
  172. package/backend/src/flowent/routes/mcp.py +0 -125
  173. package/backend/src/flowent/routes/meta.py +0 -28
  174. package/backend/src/flowent/routes/nodes.py +0 -413
  175. package/backend/src/flowent/routes/prompts.py +0 -46
  176. package/backend/src/flowent/routes/providers_route.py +0 -365
  177. package/backend/src/flowent/routes/roles.py +0 -207
  178. package/backend/src/flowent/routes/settings.py +0 -328
  179. package/backend/src/flowent/routes/tabs.py +0 -310
  180. package/backend/src/flowent/routes/ws.py +0 -33
  181. package/backend/src/flowent/runtime.py +0 -165
  182. package/backend/src/flowent/security.py +0 -57
  183. package/backend/src/flowent/settings.py +0 -2518
  184. package/backend/src/flowent/settings_management.py +0 -298
  185. package/backend/src/flowent/state_db.py +0 -120
  186. package/backend/src/flowent/static/assets/AssistantPage-VBohhz4d.js +0 -1
  187. package/backend/src/flowent/static/assets/ChannelsPage-CIydPZA_.js +0 -1
  188. package/backend/src/flowent/static/assets/McpPage-CHPm2TPY.js +0 -7
  189. package/backend/src/flowent/static/assets/PageScaffold-DteOA8V7.js +0 -1
  190. package/backend/src/flowent/static/assets/PromptsPage-CSmJ3sZg.js +0 -1
  191. package/backend/src/flowent/static/assets/ProvidersPage-sl2jeG4e.js +0 -3
  192. package/backend/src/flowent/static/assets/RolesPage-DCe7W6Km.js +0 -1
  193. package/backend/src/flowent/static/assets/SettingsPage-Bix9e63E.js +0 -3
  194. package/backend/src/flowent/static/assets/ToolsPage-favNkj5C.js +0 -1
  195. package/backend/src/flowent/static/assets/WorkspaceCommandDialog-DRS6wiD6.js +0 -1
  196. package/backend/src/flowent/static/assets/WorkspacePage-KuaDjt_D.js +0 -3
  197. package/backend/src/flowent/static/assets/WorkspacePanels-BZxBw8M5.js +0 -1
  198. package/backend/src/flowent/static/assets/alert-dialog-DIBUCmqM.js +0 -1
  199. package/backend/src/flowent/static/assets/datetime-eJqd0V2S.js +0 -1
  200. package/backend/src/flowent/static/assets/dialog-BOvHIBrg.js +0 -1
  201. package/backend/src/flowent/static/assets/elk-worker.min-C9JGDOE-.js +0 -6312
  202. package/backend/src/flowent/static/assets/graph-vendor-CHpVij2M.css +0 -1
  203. package/backend/src/flowent/static/assets/graph-vendor-DRq_-6fV.js +0 -7
  204. package/backend/src/flowent/static/assets/index-Biio-CoI.js +0 -10
  205. package/backend/src/flowent/static/assets/index-CmQvO7sl.css +0 -1
  206. package/backend/src/flowent/static/assets/layout.worker-jMHqAFbP.js +0 -24
  207. package/backend/src/flowent/static/assets/markdown-vendor-C9RtvaJh.js +0 -29
  208. package/backend/src/flowent/static/assets/modelParams-DcEhGnu0.js +0 -1
  209. package/backend/src/flowent/static/assets/react-vendor-mEs_JJxa.js +0 -9
  210. package/backend/src/flowent/static/assets/roles-BbIEIMeG.js +0 -1
  211. package/backend/src/flowent/static/assets/rolldown-runtime-BYbx6iT9.js +0 -1
  212. package/backend/src/flowent/static/assets/select-D9SwnlXF.js +0 -1
  213. package/backend/src/flowent/static/assets/surface-Bzr1FRG4.js +0 -1
  214. package/backend/src/flowent/static/assets/triState-DgLlKdRR.js +0 -1
  215. package/backend/src/flowent/static/assets/ui-vendor-UazN8rcv.js +0 -51
  216. package/backend/src/flowent/static/favicon.svg +0 -4
  217. package/backend/src/flowent/tools/__init__.py +0 -275
  218. package/backend/src/flowent/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  219. package/backend/src/flowent/tools/__pycache__/connect.cpython-313.pyc +0 -0
  220. package/backend/src/flowent/tools/__pycache__/contacts.cpython-313.pyc +0 -0
  221. package/backend/src/flowent/tools/__pycache__/create_agent.cpython-313.pyc +0 -0
  222. package/backend/src/flowent/tools/__pycache__/create_tab.cpython-313.pyc +0 -0
  223. package/backend/src/flowent/tools/__pycache__/delete_tab.cpython-313.pyc +0 -0
  224. package/backend/src/flowent/tools/__pycache__/edit.cpython-313.pyc +0 -0
  225. package/backend/src/flowent/tools/__pycache__/exec.cpython-313.pyc +0 -0
  226. package/backend/src/flowent/tools/__pycache__/fetch.cpython-313.pyc +0 -0
  227. package/backend/src/flowent/tools/__pycache__/idle.cpython-313.pyc +0 -0
  228. package/backend/src/flowent/tools/__pycache__/list_roles.cpython-313.pyc +0 -0
  229. package/backend/src/flowent/tools/__pycache__/list_tabs.cpython-313.pyc +0 -0
  230. package/backend/src/flowent/tools/__pycache__/list_tools.cpython-313.pyc +0 -0
  231. package/backend/src/flowent/tools/__pycache__/manage_prompts.cpython-313.pyc +0 -0
  232. package/backend/src/flowent/tools/__pycache__/manage_providers.cpython-313.pyc +0 -0
  233. package/backend/src/flowent/tools/__pycache__/manage_roles.cpython-313.pyc +0 -0
  234. package/backend/src/flowent/tools/__pycache__/manage_settings.cpython-313.pyc +0 -0
  235. package/backend/src/flowent/tools/__pycache__/mcp.cpython-313.pyc +0 -0
  236. package/backend/src/flowent/tools/__pycache__/read.cpython-313.pyc +0 -0
  237. package/backend/src/flowent/tools/__pycache__/send.cpython-313.pyc +0 -0
  238. package/backend/src/flowent/tools/__pycache__/set_permissions.cpython-313.pyc +0 -0
  239. package/backend/src/flowent/tools/__pycache__/sleep.cpython-313.pyc +0 -0
  240. package/backend/src/flowent/tools/__pycache__/todo.cpython-313.pyc +0 -0
  241. package/backend/src/flowent/tools/connect.py +0 -100
  242. package/backend/src/flowent/tools/contacts.py +0 -22
  243. package/backend/src/flowent/tools/create_agent.py +0 -191
  244. package/backend/src/flowent/tools/create_tab.py +0 -61
  245. package/backend/src/flowent/tools/delete_tab.py +0 -39
  246. package/backend/src/flowent/tools/edit.py +0 -142
  247. package/backend/src/flowent/tools/exec.py +0 -118
  248. package/backend/src/flowent/tools/fetch.py +0 -85
  249. package/backend/src/flowent/tools/idle.py +0 -27
  250. package/backend/src/flowent/tools/list_roles.py +0 -75
  251. package/backend/src/flowent/tools/list_tabs.py +0 -100
  252. package/backend/src/flowent/tools/list_tools.py +0 -28
  253. package/backend/src/flowent/tools/manage_prompts.py +0 -102
  254. package/backend/src/flowent/tools/manage_providers.py +0 -220
  255. package/backend/src/flowent/tools/manage_roles.py +0 -275
  256. package/backend/src/flowent/tools/manage_settings.py +0 -364
  257. package/backend/src/flowent/tools/mcp.py +0 -199
  258. package/backend/src/flowent/tools/read.py +0 -152
  259. package/backend/src/flowent/tools/send.py +0 -68
  260. package/backend/src/flowent/tools/set_permissions.py +0 -99
  261. package/backend/src/flowent/tools/sleep.py +0 -41
  262. package/backend/src/flowent/tools/todo.py +0 -51
  263. package/backend/src/flowent/workspace_store.py +0 -479
  264. package/backend/tests/__init__.py +0 -0
  265. package/backend/tests/__pycache__/__init__.cpython-313.pyc +0 -0
  266. package/backend/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  267. package/backend/tests/conftest.py +0 -6
  268. package/backend/tests/integration/api/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  269. package/backend/tests/integration/api/__pycache__/test_access_api.cpython-313-pytest-9.0.3.pyc +0 -0
  270. package/backend/tests/integration/api/__pycache__/test_assistant_api.cpython-313-pytest-9.0.3.pyc +0 -0
  271. package/backend/tests/integration/api/__pycache__/test_frontend_mounting.cpython-313-pytest-9.0.3.pyc +0 -0
  272. package/backend/tests/integration/api/__pycache__/test_mcp_api.cpython-313-pytest-9.0.3.pyc +0 -0
  273. package/backend/tests/integration/api/__pycache__/test_meta_api.cpython-313-pytest-9.0.3.pyc +0 -0
  274. package/backend/tests/integration/api/__pycache__/test_nodes_api.cpython-313-pytest-9.0.3.pyc +0 -0
  275. package/backend/tests/integration/api/__pycache__/test_prompts_api.cpython-313-pytest-9.0.3.pyc +0 -0
  276. package/backend/tests/integration/api/__pycache__/test_roles_api.cpython-313-pytest-9.0.3.pyc +0 -0
  277. package/backend/tests/integration/api/__pycache__/test_tabs_api.cpython-313-pytest-9.0.3.pyc +0 -0
  278. package/backend/tests/integration/api/conftest.py +0 -29
  279. package/backend/tests/integration/api/test_access_api.py +0 -182
  280. package/backend/tests/integration/api/test_assistant_api.py +0 -354
  281. package/backend/tests/integration/api/test_frontend_mounting.py +0 -61
  282. package/backend/tests/integration/api/test_mcp_api.py +0 -116
  283. package/backend/tests/integration/api/test_meta_api.py +0 -33
  284. package/backend/tests/integration/api/test_nodes_api.py +0 -722
  285. package/backend/tests/integration/api/test_prompts_api.py +0 -47
  286. package/backend/tests/integration/api/test_roles_api.py +0 -228
  287. package/backend/tests/integration/api/test_tabs_api.py +0 -802
  288. package/backend/tests/unit/__pycache__/test_access.cpython-313-pytest-9.0.3.pyc +0 -0
  289. package/backend/tests/unit/__pycache__/test_cli.cpython-313-pytest-9.0.3.pyc +0 -0
  290. package/backend/tests/unit/__pycache__/test_graph_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  291. package/backend/tests/unit/__pycache__/test_network.cpython-313-pytest-9.0.3.pyc +0 -0
  292. package/backend/tests/unit/__pycache__/test_state_sqlite_storage.cpython-313-pytest-9.0.3.pyc +0 -0
  293. package/backend/tests/unit/__pycache__/test_workspace_store.cpython-313-pytest-9.0.3.pyc +0 -0
  294. package/backend/tests/unit/agent/__pycache__/test_agent_public_api.cpython-313-pytest-9.0.3.pyc +0 -0
  295. package/backend/tests/unit/agent/__pycache__/test_agent_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  296. package/backend/tests/unit/agent/test_agent_public_api.py +0 -837
  297. package/backend/tests/unit/agent/test_agent_runtime.py +0 -2942
  298. package/backend/tests/unit/channels/__pycache__/test_telegram_channel.cpython-313-pytest-9.0.3.pyc +0 -0
  299. package/backend/tests/unit/channels/test_telegram_channel.py +0 -552
  300. package/backend/tests/unit/logging/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
  301. package/backend/tests/unit/logging/test_logging.py +0 -132
  302. package/backend/tests/unit/prompts/__pycache__/test_prompts.cpython-313-pytest-9.0.3.pyc +0 -0
  303. package/backend/tests/unit/prompts/test_prompts.py +0 -570
  304. package/backend/tests/unit/providers/__pycache__/test_anthropic_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  305. package/backend/tests/unit/providers/__pycache__/test_errors.cpython-313-pytest-9.0.3.pyc +0 -0
  306. package/backend/tests/unit/providers/__pycache__/test_extract_delta_parts.cpython-313-pytest-9.0.3.pyc +0 -0
  307. package/backend/tests/unit/providers/__pycache__/test_openai_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  308. package/backend/tests/unit/providers/__pycache__/test_openai_responses.cpython-313-pytest-9.0.3.pyc +0 -0
  309. package/backend/tests/unit/providers/__pycache__/test_provider_gateway.cpython-313-pytest-9.0.3.pyc +0 -0
  310. package/backend/tests/unit/providers/__pycache__/test_think_tag_parser.cpython-313-pytest-9.0.3.pyc +0 -0
  311. package/backend/tests/unit/providers/test_anthropic_provider.py +0 -185
  312. package/backend/tests/unit/providers/test_errors.py +0 -68
  313. package/backend/tests/unit/providers/test_extract_delta_parts.py +0 -22
  314. package/backend/tests/unit/providers/test_openai_provider.py +0 -139
  315. package/backend/tests/unit/providers/test_openai_responses.py +0 -402
  316. package/backend/tests/unit/providers/test_provider_gateway.py +0 -359
  317. package/backend/tests/unit/providers/test_think_tag_parser.py +0 -36
  318. package/backend/tests/unit/routes/__pycache__/test_prompts_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  319. package/backend/tests/unit/routes/__pycache__/test_providers_route.cpython-313-pytest-9.0.3.pyc +0 -0
  320. package/backend/tests/unit/routes/__pycache__/test_roles_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  321. package/backend/tests/unit/routes/__pycache__/test_settings_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  322. package/backend/tests/unit/routes/test_prompts_routes.py +0 -104
  323. package/backend/tests/unit/routes/test_providers_route.py +0 -370
  324. package/backend/tests/unit/routes/test_roles_routes.py +0 -535
  325. package/backend/tests/unit/routes/test_settings_routes.py +0 -1142
  326. package/backend/tests/unit/runtime/__pycache__/test_bootstrap_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  327. package/backend/tests/unit/runtime/test_bootstrap_runtime.py +0 -1002
  328. package/backend/tests/unit/sandbox/__pycache__/test_sandbox_tools.cpython-313-pytest-9.0.3.pyc +0 -0
  329. package/backend/tests/unit/sandbox/test_sandbox_tools.py +0 -78
  330. package/backend/tests/unit/security/__pycache__/test_security.cpython-313-pytest-9.0.3.pyc +0 -0
  331. package/backend/tests/unit/security/test_security.py +0 -124
  332. package/backend/tests/unit/settings/__pycache__/test_settings_roles.cpython-313-pytest-9.0.3.pyc +0 -0
  333. package/backend/tests/unit/settings/test_settings_roles.py +0 -751
  334. package/backend/tests/unit/test_access.py +0 -45
  335. package/backend/tests/unit/test_cli.py +0 -124
  336. package/backend/tests/unit/test_graph_runtime.py +0 -72
  337. package/backend/tests/unit/test_network.py +0 -51
  338. package/backend/tests/unit/test_state_sqlite_storage.py +0 -159
  339. package/backend/tests/unit/test_workspace_store.py +0 -231
  340. package/backend/tests/unit/tools/__pycache__/test_connect_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  341. package/backend/tests/unit/tools/__pycache__/test_create_agent_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  342. package/backend/tests/unit/tools/__pycache__/test_delete_tab_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  343. package/backend/tests/unit/tools/__pycache__/test_edit_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  344. package/backend/tests/unit/tools/__pycache__/test_exec_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  345. package/backend/tests/unit/tools/__pycache__/test_fetch_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  346. package/backend/tests/unit/tools/__pycache__/test_manage_prompts_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  347. package/backend/tests/unit/tools/__pycache__/test_manage_providers_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  348. package/backend/tests/unit/tools/__pycache__/test_manage_roles_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  349. package/backend/tests/unit/tools/__pycache__/test_manage_settings_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  350. package/backend/tests/unit/tools/__pycache__/test_read_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  351. package/backend/tests/unit/tools/__pycache__/test_set_permissions_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  352. package/backend/tests/unit/tools/__pycache__/test_todo_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  353. package/backend/tests/unit/tools/__pycache__/test_tool_registry.cpython-313-pytest-9.0.3.pyc +0 -0
  354. package/backend/tests/unit/tools/test_connect_tool.py +0 -228
  355. package/backend/tests/unit/tools/test_create_agent_tool.py +0 -436
  356. package/backend/tests/unit/tools/test_delete_tab_tool.py +0 -116
  357. package/backend/tests/unit/tools/test_edit_tool.py +0 -115
  358. package/backend/tests/unit/tools/test_exec_tool.py +0 -81
  359. package/backend/tests/unit/tools/test_fetch_tool.py +0 -65
  360. package/backend/tests/unit/tools/test_manage_prompts_tool.py +0 -117
  361. package/backend/tests/unit/tools/test_manage_providers_tool.py +0 -460
  362. package/backend/tests/unit/tools/test_manage_roles_tool.py +0 -411
  363. package/backend/tests/unit/tools/test_manage_settings_tool.py +0 -611
  364. package/backend/tests/unit/tools/test_read_tool.py +0 -33
  365. package/backend/tests/unit/tools/test_set_permissions_tool.py +0 -595
  366. package/backend/tests/unit/tools/test_todo_tool.py +0 -37
  367. package/backend/tests/unit/tools/test_tool_registry.py +0 -194
  368. package/dist/frontend/assets/AssistantPage-VBohhz4d.js +0 -1
  369. package/dist/frontend/assets/ChannelsPage-CIydPZA_.js +0 -1
  370. package/dist/frontend/assets/McpPage-CHPm2TPY.js +0 -7
  371. package/dist/frontend/assets/PageScaffold-DteOA8V7.js +0 -1
  372. package/dist/frontend/assets/PromptsPage-CSmJ3sZg.js +0 -1
  373. package/dist/frontend/assets/ProvidersPage-sl2jeG4e.js +0 -3
  374. package/dist/frontend/assets/RolesPage-DCe7W6Km.js +0 -1
  375. package/dist/frontend/assets/SettingsPage-Bix9e63E.js +0 -3
  376. package/dist/frontend/assets/ToolsPage-favNkj5C.js +0 -1
  377. package/dist/frontend/assets/WorkspaceCommandDialog-DRS6wiD6.js +0 -1
  378. package/dist/frontend/assets/WorkspacePage-KuaDjt_D.js +0 -3
  379. package/dist/frontend/assets/WorkspacePanels-BZxBw8M5.js +0 -1
  380. package/dist/frontend/assets/alert-dialog-DIBUCmqM.js +0 -1
  381. package/dist/frontend/assets/datetime-eJqd0V2S.js +0 -1
  382. package/dist/frontend/assets/dialog-BOvHIBrg.js +0 -1
  383. package/dist/frontend/assets/elk-worker.min-C9JGDOE-.js +0 -6312
  384. package/dist/frontend/assets/graph-vendor-CHpVij2M.css +0 -1
  385. package/dist/frontend/assets/graph-vendor-DRq_-6fV.js +0 -7
  386. package/dist/frontend/assets/index-Biio-CoI.js +0 -10
  387. package/dist/frontend/assets/index-CmQvO7sl.css +0 -1
  388. package/dist/frontend/assets/layout.worker-jMHqAFbP.js +0 -24
  389. package/dist/frontend/assets/markdown-vendor-C9RtvaJh.js +0 -29
  390. package/dist/frontend/assets/modelParams-DcEhGnu0.js +0 -1
  391. package/dist/frontend/assets/react-vendor-mEs_JJxa.js +0 -9
  392. package/dist/frontend/assets/roles-BbIEIMeG.js +0 -1
  393. package/dist/frontend/assets/rolldown-runtime-BYbx6iT9.js +0 -1
  394. package/dist/frontend/assets/select-D9SwnlXF.js +0 -1
  395. package/dist/frontend/assets/surface-Bzr1FRG4.js +0 -1
  396. package/dist/frontend/assets/triState-DgLlKdRR.js +0 -1
  397. package/dist/frontend/assets/ui-vendor-UazN8rcv.js +0 -51
  398. 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,267 +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 (
71
- is_assistant_only_mcp_tool_name,
72
- is_assistant_only_tool_name,
73
- )
74
-
75
- next_included = normalize_tool_names(
76
- included_tools
77
- if included_tools is not None
78
- else current.included_tools
79
- if current
80
- else []
81
- )
82
- if included_tools is not None:
83
- next_included = [
84
- tool_name
85
- for tool_name in next_included
86
- if not is_assistant_only_tool_name(tool_name)
87
- and not is_assistant_only_mcp_tool_name(tool_name)
88
- ]
89
- next_excluded = normalize_tool_names(
90
- excluded_tools
91
- if excluded_tools is not None
92
- else current.excluded_tools
93
- if current
94
- else []
95
- )
96
- validate_role_tool_config(next_included, next_excluded)
97
- return next_included, next_excluded
98
-
99
-
100
- def resolve_role_model(
101
- requested: object,
102
- *,
103
- settings: Settings,
104
- current: RoleModelConfig | None,
105
- provided: bool,
106
- invalid_type_error: str,
107
- missing_provider_id_error: str,
108
- missing_model_error: str,
109
- ) -> RoleModelConfig | None:
110
- if not provided:
111
- return current
112
- if requested is None:
113
- return None
114
-
115
- extracted = _extract_role_model_fields(requested)
116
- if extracted is None:
117
- raise ValueError(invalid_type_error)
118
-
119
- provider_id_value, model_value = extracted
120
- if not isinstance(provider_id_value, str) or not provider_id_value.strip():
121
- raise ValueError(missing_provider_id_error)
122
- if not isinstance(model_value, str) or not model_value.strip():
123
- raise ValueError(missing_model_error)
124
-
125
- provider_id = provider_id_value.strip()
126
- model = model_value.strip()
127
- if find_provider(settings, provider_id) is None:
128
- raise ValueError(f"Provider '{provider_id}' not found")
129
-
130
- return RoleModelConfig(provider_id=provider_id, model=model)
131
-
132
-
133
- def resolve_role_model_params(
134
- requested: object,
135
- *,
136
- current: ModelParams | None,
137
- provided: bool,
138
- ) -> ModelParams | None:
139
- if not provided:
140
- return current
141
- return build_model_params_from_mapping(requested)
142
-
143
-
144
- def validate_builtin_role_update(
145
- role: RoleConfig,
146
- *,
147
- next_name: str | None,
148
- next_description: str | None,
149
- next_system_prompt: str | None,
150
- next_included_tools: list[str],
151
- next_excluded_tools: list[str],
152
- ) -> None:
153
- if not is_builtin_role_name(role.name):
154
- return
155
- if next_name is not None and next_name != role.name:
156
- raise ValueError(f"Cannot rename built-in role '{role.name}'")
157
- if next_description is not None and next_description != role.description:
158
- raise ValueError(
159
- f"Cannot modify built-in role '{role.name}' fields other than "
160
- "model or model_params"
161
- )
162
- if next_system_prompt is not None and next_system_prompt != role.system_prompt:
163
- raise ValueError(
164
- f"Cannot modify built-in role '{role.name}' fields other than "
165
- "model or model_params"
166
- )
167
- if (
168
- next_included_tools != role.included_tools
169
- or next_excluded_tools != role.excluded_tools
170
- ):
171
- raise ValueError(
172
- f"Cannot modify built-in role '{role.name}' fields other than "
173
- "model or model_params"
174
- )
175
-
176
-
177
- def build_role_config(
178
- *,
179
- name: str,
180
- description: str,
181
- system_prompt: str,
182
- model: RoleModelConfig | None,
183
- model_params: ModelParams | None,
184
- included_tools: list[str],
185
- excluded_tools: list[str],
186
- ) -> RoleConfig:
187
- return RoleConfig(
188
- name=name,
189
- description=description,
190
- system_prompt=system_prompt,
191
- model=model,
192
- model_params=model_params,
193
- included_tools=included_tools,
194
- excluded_tools=excluded_tools,
195
- )
196
-
197
-
198
- def apply_role_update(
199
- *,
200
- settings: Settings,
201
- role: RoleConfig,
202
- next_name: str | None,
203
- next_description: str | None,
204
- next_system_prompt: str | None,
205
- next_model: RoleModelConfig | None,
206
- update_model: bool,
207
- next_model_params: ModelParams | None,
208
- update_model_params: bool,
209
- next_included_tools: list[str],
210
- next_excluded_tools: list[str],
211
- ) -> RoleConfig:
212
- previous_name = role.name
213
- if next_name is not None:
214
- role.name = next_name
215
- rename_role_references(settings, previous_name, role.name)
216
- if next_description is not None:
217
- role.description = next_description
218
- if next_system_prompt is not None:
219
- role.system_prompt = next_system_prompt
220
- if update_model:
221
- role.model = next_model
222
- if update_model_params:
223
- role.model_params = next_model_params
224
- role.included_tools = next_included_tools
225
- role.excluded_tools = next_excluded_tools
226
- return role
227
-
228
-
229
- def remove_role(settings: Settings, role: RoleConfig) -> None:
230
- settings.roles = [existing for existing in settings.roles if existing is not role]
231
- clear_role_references(settings, role.name)
232
-
233
-
234
- def sync_running_system_roles() -> None:
235
- from flowent.graph_service import sync_assistant_role, sync_tab_leaders
236
-
237
- sync_assistant_role(reason="assistant role updated")
238
- sync_tab_leaders(reason="leader role updated")
239
-
240
-
241
- def _extract_role_model_fields(requested: object) -> tuple[object, object] | None:
242
- if isinstance(requested, dict):
243
- return requested.get("provider_id"), requested.get("model")
244
- provider_id = getattr(requested, "provider_id", None)
245
- model = getattr(requested, "model", None)
246
- if provider_id is None and model is None:
247
- return None
248
- return provider_id, model
249
-
250
-
251
- __all__ = [
252
- "RoleConflictError",
253
- "apply_role_update",
254
- "build_role_config",
255
- "ensure_role_name_available",
256
- "find_role_by_name",
257
- "normalize_optional_role_description",
258
- "normalize_optional_role_name",
259
- "remove_role",
260
- "require_role_description",
261
- "require_role_name",
262
- "resolve_role_model",
263
- "resolve_role_model_params",
264
- "resolve_role_tool_config",
265
- "sync_running_system_roles",
266
- "validate_builtin_role_update",
267
- ]
@@ -1,28 +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.mcp import router as mcp_router
7
- from flowent.routes.meta import router as meta_router
8
- from flowent.routes.nodes import router as nodes_router
9
- from flowent.routes.prompts import router as prompts_router
10
- from flowent.routes.providers_route import router as providers_router
11
- from flowent.routes.roles import router as roles_router
12
- from flowent.routes.settings import router as settings_router
13
- from flowent.routes.tabs import router as tabs_router
14
- from flowent.routes.ws import router as ws_router
15
-
16
- router = APIRouter()
17
- router.include_router(access_router)
18
- router.include_router(nodes_router)
19
- router.include_router(assistant_router)
20
- router.include_router(image_assets_router)
21
- router.include_router(mcp_router)
22
- router.include_router(roles_router)
23
- router.include_router(providers_router)
24
- router.include_router(prompts_router)
25
- router.include_router(settings_router)
26
- router.include_router(tabs_router)
27
- router.include_router(meta_router)
28
- router.include_router(ws_router)