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,220 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import json
4
- from collections.abc import Callable
5
- from typing import TYPE_CHECKING, Any, ClassVar
6
-
7
- from loguru import logger
8
-
9
- if TYPE_CHECKING:
10
- from flowent.agent import Agent
11
-
12
- from flowent.providers.configuration import serialize_discovered_model_catalog_entry
13
- from flowent.providers.management import (
14
- ProviderNotFoundError,
15
- create_provider_entry,
16
- delete_provider_entry,
17
- list_provider_payloads,
18
- update_provider_entry,
19
- )
20
- from flowent.settings import (
21
- build_provider_headers,
22
- build_provider_retry_429_delay_seconds,
23
- )
24
- from flowent.tools import Tool, re_raise_interrupt
25
-
26
-
27
- class ManageProvidersTool(Tool):
28
- name = "manage_providers"
29
- description = (
30
- "Manage LLM provider configuration. Supports listing, creating, "
31
- "updating, deleting providers, and listing models for a provider."
32
- )
33
- parameters: ClassVar[dict[str, Any]] = {
34
- "type": "object",
35
- "properties": {
36
- "action": {
37
- "type": "string",
38
- "enum": ["list", "create", "update", "delete", "list_models"],
39
- "description": "Provider management action",
40
- },
41
- "id": {
42
- "type": "string",
43
- "description": "Target provider ID for update, delete, or list_models",
44
- },
45
- "name": {
46
- "type": "string",
47
- "description": "Provider display name",
48
- },
49
- "type": {
50
- "type": "string",
51
- "description": "Provider type, such as openai_compatible",
52
- },
53
- "base_url": {
54
- "type": "string",
55
- "description": "Provider API base URL",
56
- },
57
- "api_key": {
58
- "type": "string",
59
- "description": "Provider API key",
60
- },
61
- "headers": {
62
- "type": "object",
63
- "description": "Provider request header overrides",
64
- "additionalProperties": {"type": "string"},
65
- },
66
- "retry_429_delay_seconds": {
67
- "type": "integer",
68
- "description": "Extra wait time in seconds after HTTP 429 before retrying",
69
- },
70
- },
71
- "required": ["action"],
72
- }
73
-
74
- def execute(self, agent: Agent, args: dict[str, Any], **kwargs: Any) -> str:
75
- from flowent.providers.gateway import gateway
76
- from flowent.settings import get_settings, save_settings
77
-
78
- on_output: Callable[[str], None] | None = kwargs.get("on_output")
79
- action = args.get("action")
80
- provider_id = args.get("id")
81
- name = args.get("name")
82
- provider_type = args.get("type")
83
- base_url = args.get("base_url")
84
- api_key = args.get("api_key")
85
- raw_headers = args.get("headers")
86
- retry_429_delay_seconds = args.get("retry_429_delay_seconds")
87
-
88
- if not isinstance(action, str):
89
- return json.dumps({"error": "action must be a string"})
90
-
91
- if provider_id is not None and not isinstance(provider_id, str):
92
- return json.dumps({"error": "id must be a string"})
93
- if name is not None and not isinstance(name, str):
94
- return json.dumps({"error": "name must be a string"})
95
- if provider_type is not None and not isinstance(provider_type, str):
96
- return json.dumps({"error": "type must be a string"})
97
- if base_url is not None and not isinstance(base_url, str):
98
- return json.dumps({"error": "base_url must be a string"})
99
- if api_key is not None and not isinstance(api_key, str):
100
- return json.dumps({"error": "api_key must be a string"})
101
- if raw_headers is not None and not isinstance(raw_headers, dict):
102
- return json.dumps({"error": "headers must be a JSON object"})
103
- if retry_429_delay_seconds is not None:
104
- try:
105
- build_provider_retry_429_delay_seconds(retry_429_delay_seconds)
106
- except ValueError as exc:
107
- return json.dumps({"error": str(exc)})
108
-
109
- try:
110
- headers = (
111
- build_provider_headers(raw_headers) if raw_headers is not None else None
112
- )
113
- except ValueError as exc:
114
- return json.dumps({"error": str(exc)})
115
-
116
- settings = get_settings()
117
-
118
- if action == "list":
119
- return json.dumps(list_provider_payloads(settings, include_api_key=False))
120
-
121
- if action == "create":
122
- if not isinstance(name, str) or not name.strip():
123
- return json.dumps({"error": "name is required"})
124
- if not isinstance(provider_type, str) or not provider_type.strip():
125
- return json.dumps({"error": "type is required"})
126
- if not isinstance(base_url, str) or not base_url.strip():
127
- return json.dumps({"error": "base_url is required"})
128
- try:
129
- provider = create_provider_entry(
130
- settings,
131
- name=name,
132
- provider_type=provider_type,
133
- base_url=base_url,
134
- api_key=api_key or "",
135
- raw_headers=headers,
136
- raw_retry_429_delay_seconds=(
137
- retry_429_delay_seconds
138
- if retry_429_delay_seconds is not None
139
- else 0
140
- ),
141
- base_url_required_message="base_url is required",
142
- )
143
- except ValueError as exc:
144
- return json.dumps({"error": str(exc)})
145
- save_settings(settings)
146
- gateway.invalidate_cache()
147
- return json.dumps(
148
- list_provider_payloads(settings, include_api_key=False)[-1]
149
- )
150
-
151
- if action == "update":
152
- if not isinstance(provider_id, str) or not provider_id:
153
- return json.dumps({"error": "id is required"})
154
-
155
- try:
156
- provider = update_provider_entry(
157
- settings,
158
- provider_id,
159
- name=name,
160
- provider_type=provider_type,
161
- base_url=base_url,
162
- api_key=api_key,
163
- raw_headers=headers,
164
- raw_retry_429_delay_seconds=retry_429_delay_seconds,
165
- )
166
- except ValueError as exc:
167
- return json.dumps({"error": str(exc)})
168
- except ProviderNotFoundError:
169
- return json.dumps({"error": f"Provider '{provider_id}' not found"})
170
- save_settings(settings)
171
- gateway.invalidate_cache()
172
- return json.dumps(
173
- list_provider_payloads(settings, include_api_key=False)[
174
- settings.providers.index(provider)
175
- ]
176
- )
177
-
178
- if action == "delete":
179
- if not isinstance(provider_id, str) or not provider_id:
180
- return json.dumps({"error": "id is required"})
181
-
182
- try:
183
- delete_provider_entry(settings, provider_id)
184
- except ProviderNotFoundError:
185
- return json.dumps({"error": f"Provider '{provider_id}' not found"})
186
- save_settings(settings)
187
- gateway.invalidate_cache()
188
- return json.dumps({"status": "deleted"})
189
-
190
- if action == "list_models":
191
- if not isinstance(provider_id, str) or not provider_id:
192
- return json.dumps({"error": "id is required"})
193
- try:
194
- if on_output is not None:
195
- on_output(f"Listing models for {provider_id}\n")
196
- models = gateway.list_models_for(
197
- provider_id,
198
- register_interrupt=agent.set_interrupt_callback,
199
- )
200
- if on_output is not None:
201
- for model in models:
202
- on_output(f"{model.id}\n")
203
- return json.dumps(
204
- [
205
- serialize_discovered_model_catalog_entry(model)
206
- for model in models
207
- ]
208
- )
209
- except Exception as exc:
210
- re_raise_interrupt(agent, exc)
211
- logger.error(
212
- "Failed to list models for provider '{}': {}",
213
- provider_id,
214
- exc,
215
- )
216
- return json.dumps({"error": str(exc)})
217
- finally:
218
- agent.set_interrupt_callback(None)
219
-
220
- return json.dumps({"error": f"Unsupported action: {action}"})
@@ -1,275 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import json
4
- from typing import TYPE_CHECKING, Any, ClassVar
5
-
6
- if TYPE_CHECKING:
7
- from flowent.agent import Agent
8
-
9
- from flowent.role_management import (
10
- apply_role_update,
11
- build_role_config,
12
- ensure_role_name_available,
13
- find_role_by_name,
14
- normalize_optional_role_description,
15
- normalize_optional_role_name,
16
- remove_role,
17
- require_role_description,
18
- require_role_name,
19
- resolve_role_model,
20
- resolve_role_model_params,
21
- resolve_role_tool_config,
22
- sync_running_system_roles,
23
- validate_builtin_role_update,
24
- )
25
- from flowent.tools import Tool
26
-
27
-
28
- class ManageRolesTool(Tool):
29
- name = "manage_roles"
30
- description = (
31
- "Manage Role configuration. Supports listing, creating, updating, "
32
- "and deleting roles. Built-in roles cannot be deleted, renamed, "
33
- "or modified except for model and model_params configuration."
34
- )
35
- parameters: ClassVar[dict[str, Any]] = {
36
- "type": "object",
37
- "properties": {
38
- "action": {
39
- "type": "string",
40
- "enum": ["list", "create", "update", "delete"],
41
- "description": "Role management action",
42
- },
43
- "name": {
44
- "type": "string",
45
- "description": "Role name for create, update, or delete",
46
- },
47
- "new_name": {
48
- "type": "string",
49
- "description": "New role name for update",
50
- },
51
- "description": {
52
- "type": "string",
53
- "description": "Short role description used when choosing a role",
54
- },
55
- "system_prompt": {
56
- "type": "string",
57
- "description": "Role system prompt",
58
- },
59
- "model": {
60
- "type": ["object", "null"],
61
- "description": "Optional provider and model override for this role",
62
- "properties": {
63
- "provider_id": {"type": "string"},
64
- "model": {"type": "string"},
65
- },
66
- "required": ["provider_id", "model"],
67
- "additionalProperties": False,
68
- },
69
- "model_params": {
70
- "type": ["object", "null"],
71
- "description": "Optional canonical model parameter overrides",
72
- "properties": {
73
- "reasoning_effort": {
74
- "type": "string",
75
- "enum": ["none", "low", "medium", "high", "xhigh"],
76
- },
77
- "verbosity": {
78
- "type": "string",
79
- "enum": ["low", "medium", "high"],
80
- },
81
- "max_output_tokens": {"type": "integer"},
82
- "temperature": {"type": "number"},
83
- "top_p": {"type": "number"},
84
- },
85
- "additionalProperties": False,
86
- },
87
- "included_tools": {
88
- "type": "array",
89
- "items": {"type": "string"},
90
- "description": "Tools always included in the role",
91
- },
92
- "excluded_tools": {
93
- "type": "array",
94
- "items": {"type": "string"},
95
- "description": "Tools always excluded from the role",
96
- },
97
- },
98
- "required": ["action"],
99
- }
100
-
101
- def execute(self, agent: Agent, args: dict[str, Any], **_kwargs: Any) -> str:
102
- from flowent.providers.gateway import gateway
103
- from flowent.settings import (
104
- get_settings,
105
- is_builtin_role_name,
106
- save_settings,
107
- serialize_role,
108
- )
109
-
110
- action = args.get("action")
111
- role_name = args.get("name")
112
- new_name = args.get("new_name")
113
- description = args.get("description")
114
- system_prompt = args.get("system_prompt")
115
- role_model = args.get("model")
116
- role_model_params = args.get("model_params")
117
- included_tools = args.get("included_tools")
118
- excluded_tools = args.get("excluded_tools")
119
-
120
- if not isinstance(action, str):
121
- return json.dumps({"error": "action must be a string"})
122
-
123
- if role_name is not None and not isinstance(role_name, str):
124
- return json.dumps({"error": "name must be a string"})
125
- if new_name is not None and not isinstance(new_name, str):
126
- return json.dumps({"error": "new_name must be a string"})
127
- if description is not None and not isinstance(description, str):
128
- return json.dumps({"error": "description must be a string"})
129
- if system_prompt is not None and not isinstance(system_prompt, str):
130
- return json.dumps({"error": "system_prompt must be a string"})
131
- if included_tools is not None and (
132
- not isinstance(included_tools, list)
133
- or not all(isinstance(tool_name, str) for tool_name in included_tools)
134
- ):
135
- return json.dumps({"error": "included_tools must be an array of strings"})
136
- if excluded_tools is not None and (
137
- not isinstance(excluded_tools, list)
138
- or not all(isinstance(tool_name, str) for tool_name in excluded_tools)
139
- ):
140
- return json.dumps({"error": "excluded_tools must be an array of strings"})
141
-
142
- settings = get_settings()
143
-
144
- if action == "list":
145
- return json.dumps([serialize_role(role) for role in settings.roles])
146
-
147
- if action == "create":
148
- if not isinstance(system_prompt, str):
149
- return json.dumps({"error": "system_prompt is required"})
150
- try:
151
- name = require_role_name(role_name or "")
152
- description_text = require_role_description(description or "")
153
- ensure_role_name_available(settings.roles, name)
154
- next_included, next_excluded = resolve_role_tool_config(
155
- None,
156
- included_tools,
157
- excluded_tools,
158
- )
159
- next_model = resolve_role_model(
160
- role_model,
161
- settings=settings,
162
- current=None,
163
- provided="model" in args,
164
- invalid_type_error="model must be an object or null",
165
- missing_provider_id_error=(
166
- "model.provider_id must be a non-empty string"
167
- ),
168
- missing_model_error="model.model must be a non-empty string",
169
- )
170
- next_model_params = resolve_role_model_params(
171
- role_model_params,
172
- current=None,
173
- provided="model_params" in args,
174
- )
175
- except ValueError as exc:
176
- return json.dumps({"error": str(exc)})
177
- new_role = build_role_config(
178
- name=name,
179
- description=description_text,
180
- system_prompt=system_prompt,
181
- model=next_model,
182
- model_params=next_model_params,
183
- included_tools=next_included,
184
- excluded_tools=next_excluded,
185
- )
186
- settings.roles.append(new_role)
187
- save_settings(settings)
188
- gateway.invalidate_cache()
189
- return json.dumps(serialize_role(new_role))
190
-
191
- if action == "update":
192
- if not isinstance(role_name, str) or not role_name:
193
- return json.dumps({"error": "name is required"})
194
-
195
- target_role = find_role_by_name(settings.roles, role_name)
196
- if target_role is None:
197
- return json.dumps({"error": f"Role '{role_name}' not found"})
198
-
199
- try:
200
- next_included, next_excluded = resolve_role_tool_config(
201
- target_role,
202
- included_tools,
203
- excluded_tools,
204
- )
205
- next_model = resolve_role_model(
206
- role_model,
207
- settings=settings,
208
- current=target_role.model,
209
- provided="model" in args,
210
- invalid_type_error="model must be an object or null",
211
- missing_provider_id_error=(
212
- "model.provider_id must be a non-empty string"
213
- ),
214
- missing_model_error="model.model must be a non-empty string",
215
- )
216
- next_model_params = resolve_role_model_params(
217
- role_model_params,
218
- current=target_role.model_params,
219
- provided="model_params" in args,
220
- )
221
- stripped_name = normalize_optional_role_name(new_name)
222
- stripped_description = normalize_optional_role_description(description)
223
- if stripped_name is not None:
224
- ensure_role_name_available(
225
- settings.roles,
226
- stripped_name,
227
- current_name=target_role.name,
228
- )
229
- validate_builtin_role_update(
230
- target_role,
231
- next_name=stripped_name,
232
- next_description=stripped_description,
233
- next_system_prompt=system_prompt,
234
- next_included_tools=next_included,
235
- next_excluded_tools=next_excluded,
236
- )
237
- except ValueError as exc:
238
- return json.dumps({"error": str(exc)})
239
- target_role = apply_role_update(
240
- settings=settings,
241
- role=target_role,
242
- next_name=stripped_name,
243
- next_description=stripped_description,
244
- next_system_prompt=system_prompt,
245
- next_model=next_model,
246
- update_model="model" in args,
247
- next_model_params=next_model_params,
248
- update_model_params="model_params" in args,
249
- next_included_tools=next_included,
250
- next_excluded_tools=next_excluded,
251
- )
252
- save_settings(settings)
253
- sync_running_system_roles()
254
- gateway.invalidate_cache()
255
- return json.dumps(serialize_role(target_role))
256
-
257
- if action == "delete":
258
- if not isinstance(role_name, str) or not role_name:
259
- return json.dumps({"error": "name is required"})
260
- if is_builtin_role_name(role_name):
261
- return json.dumps(
262
- {"error": f"Cannot delete built-in role '{role_name}'"}
263
- )
264
-
265
- target_role = find_role_by_name(settings.roles, role_name)
266
- if target_role is None:
267
- return json.dumps({"error": f"Role '{role_name}' not found"})
268
-
269
- remove_role(settings, target_role)
270
- save_settings(settings)
271
- sync_running_system_roles()
272
- gateway.invalidate_cache()
273
- return json.dumps({"status": "deleted"})
274
-
275
- return json.dumps({"error": f"Unsupported action: {action}"})