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,413 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import Literal
4
-
5
- from fastapi import APIRouter, HTTPException
6
- from pydantic import BaseModel
7
-
8
- from flowent.assistant_commands import (
9
- ConversationCommandError,
10
- execute_conversation_command_input,
11
- )
12
- from flowent.graph_service import (
13
- is_tab_leader,
14
- list_node_connection_ids,
15
- resolve_effective_permissions_for_agent,
16
- resolve_effective_permissions_for_node_record,
17
- )
18
- from flowent.providers.errors import LLMProviderError
19
- from flowent.registry import registry
20
- from flowent.settings import (
21
- find_provider,
22
- find_role,
23
- get_settings,
24
- resolve_model_info,
25
- )
26
- from flowent.tools import MINIMUM_TOOLS
27
- from flowent.workspace_store import workspace_store
28
-
29
- router = APIRouter()
30
-
31
-
32
- class DispatchNodeMessagePart(BaseModel):
33
- type: Literal["text", "image"]
34
- text: str | None = None
35
- asset_id: str | None = None
36
- mime_type: str | None = None
37
- width: int | None = None
38
- height: int | None = None
39
- alt: str | None = None
40
-
41
-
42
- class DispatchNodeMessageRequest(BaseModel):
43
- content: str | None = None
44
- parts: list[DispatchNodeMessagePart] | None = None
45
- from_id: str = "human"
46
-
47
-
48
- DispatchNodeMessageRequest.model_rebuild()
49
-
50
-
51
- def _parse_dispatch_parts(req: DispatchNodeMessageRequest):
52
- from flowent.image_assets import require_image_asset
53
- from flowent.models import TextPart as ModelTextPart
54
- from flowent.models import (
55
- content_parts_to_text,
56
- has_image_parts,
57
- parse_content_parts_payload,
58
- )
59
-
60
- if req.parts:
61
- parts = parse_content_parts_payload(
62
- [part.model_dump(exclude_none=True) for part in req.parts]
63
- )
64
- elif isinstance(req.content, str):
65
- parts = [ModelTextPart(text=req.content)]
66
- else:
67
- parts = []
68
-
69
- if not parts:
70
- raise HTTPException(status_code=400, detail="Node message cannot be empty")
71
- if not has_image_parts(parts) and not content_parts_to_text(parts).strip():
72
- raise HTTPException(status_code=400, detail="Node message cannot be empty")
73
-
74
- for part in parts:
75
- asset_id = getattr(part, "asset_id", None)
76
- if isinstance(asset_id, str):
77
- require_image_asset(asset_id)
78
- return parts
79
-
80
-
81
- def _serialize_model_capabilities(role_name: str | None) -> dict[str, bool] | None:
82
- settings = get_settings()
83
- provider_id = settings.model.active_provider_id
84
- model_id = settings.model.active_model
85
- use_system_model_overrides = True
86
- role_cfg = find_role(settings, role_name) if role_name else None
87
- if (
88
- role_cfg is not None
89
- and role_cfg.model is not None
90
- and role_cfg.model.provider_id
91
- and role_cfg.model.model
92
- ):
93
- provider_id = role_cfg.model.provider_id
94
- model_id = role_cfg.model.model
95
- use_system_model_overrides = False
96
- if not provider_id or not model_id:
97
- return None
98
- provider = find_provider(settings, provider_id)
99
- if provider is None:
100
- return None
101
- model_info = resolve_model_info(
102
- provider=provider,
103
- model_id=model_id,
104
- input_image=settings.model.input_image if use_system_model_overrides else None,
105
- output_image=(
106
- settings.model.output_image if use_system_model_overrides else None
107
- ),
108
- context_window_tokens=(
109
- settings.model.context_window_tokens if use_system_model_overrides else None
110
- ),
111
- )
112
- return {
113
- "input_image": model_info.capabilities.input_image,
114
- "output_image": model_info.capabilities.output_image,
115
- }
116
-
117
-
118
- @router.get("/api/nodes")
119
- async def list_nodes() -> dict:
120
- nodes_by_id: dict[str, dict[str, object]] = {}
121
-
122
- assistant = registry.get_assistant()
123
- if assistant is not None:
124
- nodes_by_id[assistant.uuid] = {
125
- "id": assistant.uuid,
126
- "node_type": assistant.config.node_type.value,
127
- "workflow_id": assistant.config.tab_id,
128
- "role_name": assistant.config.role_name,
129
- "state": assistant.state.value,
130
- "connections": assistant.get_connections_snapshot(),
131
- "name": assistant.config.name,
132
- "is_leader": False,
133
- "todos": [t.serialize() for t in assistant.todos],
134
- "capabilities": _serialize_model_capabilities(assistant.config.role_name),
135
- "position": None,
136
- }
137
-
138
- for record in workspace_store.list_node_records():
139
- live = registry.get(record.id)
140
- nodes_by_id[record.id] = {
141
- "id": record.id,
142
- "node_type": record.config.node_type.value,
143
- "workflow_id": record.config.tab_id,
144
- "role_name": record.config.role_name,
145
- "is_leader": is_tab_leader(node_id=record.id, tab_id=record.config.tab_id),
146
- "state": (live.state if live is not None else record.state).value,
147
- "connections": (
148
- list_node_connection_ids(
149
- tab_id=record.config.tab_id,
150
- node_id=record.id,
151
- )
152
- if record.config.tab_id
153
- else []
154
- ),
155
- "name": record.config.name,
156
- "todos": [
157
- todo.serialize()
158
- for todo in (
159
- live.get_todos_snapshot() if live is not None else record.todos
160
- )
161
- ],
162
- "capabilities": _serialize_model_capabilities(record.config.role_name),
163
- "position": record.position.serialize()
164
- if record.position is not None
165
- else None,
166
- }
167
-
168
- for node in registry.get_all():
169
- if node.uuid in nodes_by_id:
170
- continue
171
- nodes_by_id[node.uuid] = {
172
- "id": node.uuid,
173
- "node_type": node.config.node_type.value,
174
- "workflow_id": node.config.tab_id,
175
- "role_name": node.config.role_name,
176
- "is_leader": is_tab_leader(node_id=node.uuid, tab_id=node.config.tab_id),
177
- "state": node.state.value,
178
- "connections": (
179
- list_node_connection_ids(
180
- tab_id=node.config.tab_id,
181
- node_id=node.uuid,
182
- )
183
- if node.config.tab_id
184
- else node.get_connections_snapshot()
185
- ),
186
- "name": node.config.name,
187
- "todos": [t.serialize() for t in node.todos],
188
- "capabilities": _serialize_model_capabilities(node.config.role_name),
189
- "position": None,
190
- }
191
-
192
- return {
193
- "nodes": list(nodes_by_id.values()),
194
- }
195
-
196
-
197
- @router.get("/api/nodes/{node_id}")
198
- async def get_node(node_id: str) -> dict:
199
- node = registry.get(node_id)
200
- record = workspace_store.get_node_record(node_id)
201
-
202
- if node is None and record is None:
203
- raise HTTPException(status_code=404, detail="Node not found")
204
-
205
- if node is not None:
206
- record_id = node.uuid
207
- record_state = node.state
208
- target_config = node.config
209
- allow_network, write_dirs = resolve_effective_permissions_for_agent(node)
210
- else:
211
- assert record is not None
212
- record_id = record.id
213
- record_state = record.state
214
- target_config = record.config
215
- allow_network, write_dirs = resolve_effective_permissions_for_node_record(
216
- record
217
- )
218
- history = (
219
- node.get_history_snapshot()
220
- if node is not None
221
- else (record.history if record is not None else [])
222
- )
223
- todos = (
224
- node.get_todos_snapshot()
225
- if node is not None
226
- else (record.todos if record is not None else [])
227
- )
228
-
229
- return {
230
- "id": record_id,
231
- "node_type": target_config.node_type.value,
232
- "workflow_id": target_config.tab_id,
233
- "role_name": target_config.role_name,
234
- "is_leader": is_tab_leader(node_id=record_id, tab_id=target_config.tab_id),
235
- "state": record_state.value,
236
- "contacts": node.get_contacts_info() if node is not None else [],
237
- "connections": (
238
- list_node_connection_ids(
239
- tab_id=target_config.tab_id,
240
- node_id=record_id,
241
- )
242
- if target_config.tab_id
243
- else (node.get_connections_snapshot() if node is not None else [])
244
- ),
245
- "name": target_config.name,
246
- "todos": [t.serialize() for t in todos],
247
- "capabilities": _serialize_model_capabilities(target_config.role_name),
248
- "tools": sorted(set(target_config.tools) | set(MINIMUM_TOOLS)),
249
- "write_dirs": list(write_dirs),
250
- "allow_network": allow_network,
251
- "workflow_permissions": {
252
- "allow_network": allow_network,
253
- "write_dirs": list(write_dirs),
254
- },
255
- "position": record.position.serialize()
256
- if record is not None and record.position is not None
257
- else None,
258
- "history": [entry.serialize() for entry in history],
259
- }
260
-
261
-
262
- @router.post("/api/nodes/{node_id}/terminate")
263
- async def terminate_node(node_id: str) -> dict:
264
- node = registry.get(node_id)
265
- if node is None:
266
- raise HTTPException(status_code=404, detail="Node not found")
267
-
268
- from flowent.models import NodeType
269
-
270
- if node.config.node_type == NodeType.ASSISTANT:
271
- raise HTTPException(status_code=400, detail="Cannot terminate assistant")
272
- if is_tab_leader(node_id=node.uuid, tab_id=node.config.tab_id):
273
- raise HTTPException(
274
- status_code=400,
275
- detail="Cannot terminate a workflow Leader directly",
276
- )
277
-
278
- node.request_termination("user_requested")
279
- return {"status": "terminating"}
280
-
281
-
282
- @router.post("/api/nodes/{node_id}/interrupt")
283
- async def interrupt_node(node_id: str) -> dict:
284
- node = registry.get(node_id)
285
- if node is None:
286
- raise HTTPException(status_code=404, detail="Node not found")
287
- if not node.request_interrupt():
288
- return {"status": "ignored"}
289
- return {"status": "interrupting"}
290
-
291
-
292
- @router.post("/api/nodes/{node_id}/messages/{message_id}/retry")
293
- async def retry_node_message(node_id: str, message_id: str) -> dict:
294
- node = registry.get(node_id)
295
- if node is None:
296
- raise HTTPException(status_code=404, detail="Node not found")
297
- from flowent.models import NodeType
298
-
299
- if node.config.node_type == NodeType.ASSISTANT:
300
- raise HTTPException(
301
- status_code=400,
302
- detail="Use /api/assistant/messages/{message_id}/retry for Assistant retry",
303
- )
304
- if not is_tab_leader(node_id=node.uuid, tab_id=node.config.tab_id):
305
- raise HTTPException(
306
- status_code=400,
307
- detail="Only a Workflow Leader can retry chat history",
308
- )
309
- try:
310
- retried_message_id = node.retry_received_message(message_id=message_id)
311
- except LookupError as exc:
312
- raise HTTPException(status_code=404, detail=str(exc)) from exc
313
- except (RuntimeError, TimeoutError, ValueError) as exc:
314
- raise HTTPException(status_code=409, detail=str(exc)) from exc
315
- return {"status": "retried", "message_id": retried_message_id}
316
-
317
-
318
- @router.post("/api/nodes/{node_id}/clear-chat")
319
- async def clear_node_chat(node_id: str) -> dict:
320
- from flowent.models import NodeType
321
-
322
- node = registry.get(node_id)
323
- if node is None:
324
- raise HTTPException(status_code=404, detail="Node not found")
325
- if node.config.node_type != NodeType.ASSISTANT and not is_tab_leader(
326
- node_id=node.uuid,
327
- tab_id=node.config.tab_id,
328
- ):
329
- raise HTTPException(
330
- status_code=400,
331
- detail="Can only clear Assistant or workflow chats",
332
- )
333
-
334
- try:
335
- node.clear_chat_history()
336
- except RuntimeError as exc:
337
- raise HTTPException(status_code=409, detail=str(exc)) from exc
338
- except TimeoutError as exc:
339
- raise HTTPException(status_code=409, detail=str(exc)) from exc
340
-
341
- return {"status": "cleared"}
342
-
343
-
344
- @router.post("/api/nodes/{node_id}/messages")
345
- async def dispatch_node_message(node_id: str, req: DispatchNodeMessageRequest) -> dict:
346
- from flowent.graph_service import dispatch_node_message
347
- from flowent.models import NodeType, content_parts_to_text, has_image_parts
348
- from flowent.models import TextPart as ModelTextPart
349
-
350
- node = registry.get(node_id)
351
- if node is None:
352
- raise HTTPException(status_code=404, detail="Node not found")
353
-
354
- if req.from_id != "human":
355
- raise HTTPException(
356
- status_code=400,
357
- detail="Web UI node messages must originate from `human`",
358
- )
359
-
360
- if node.config.node_type == NodeType.ASSISTANT:
361
- raise HTTPException(
362
- status_code=400,
363
- detail="Use /api/assistant/message for Assistant input",
364
- )
365
- if not is_tab_leader(node_id=node.uuid, tab_id=node.config.tab_id):
366
- raise HTTPException(
367
- status_code=400,
368
- detail="Human input can only target Assistant or a Workflow Leader",
369
- )
370
-
371
- try:
372
- parts = _parse_dispatch_parts(req)
373
- except ValueError as exc:
374
- raise HTTPException(status_code=400, detail=str(exc)) from exc
375
-
376
- if has_image_parts(parts) and not node.supports_input_image():
377
- raise HTTPException(
378
- status_code=409,
379
- detail="Current model does not support `input_image`.",
380
- )
381
-
382
- command_input = (
383
- parts[0].text
384
- if len(parts) == 1 and isinstance(parts[0], ModelTextPart)
385
- else None
386
- )
387
-
388
- try:
389
- executed_command = (
390
- execute_conversation_command_input(node, command_input)
391
- if isinstance(command_input, str)
392
- else None
393
- )
394
- except ConversationCommandError as exc:
395
- raise HTTPException(status_code=400, detail=str(exc)) from exc
396
- except (RuntimeError, TimeoutError, LLMProviderError) as exc:
397
- raise HTTPException(status_code=409, detail=str(exc)) from exc
398
-
399
- if executed_command is not None:
400
- return {
401
- "status": "command_executed",
402
- "command_name": executed_command.command_name,
403
- }
404
-
405
- error, message_id = dispatch_node_message(
406
- node_id=node_id,
407
- content=content_parts_to_text(parts),
408
- parts=parts,
409
- from_id="human",
410
- )
411
- if error is not None:
412
- raise HTTPException(status_code=400, detail=error)
413
- return {"status": "sent", "message_id": message_id}
@@ -1,46 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from fastapi import APIRouter
4
- from pydantic import AliasChoices, BaseModel, Field
5
-
6
- from flowent.settings import get_settings, save_settings
7
-
8
- router = APIRouter()
9
-
10
-
11
- class PromptSettingsResponse(BaseModel):
12
- custom_prompt: str
13
- custom_post_prompt: str
14
-
15
-
16
- class UpdatePromptSettingsRequest(BaseModel):
17
- custom_prompt: str | None = None
18
- custom_post_prompt: str | None = Field(
19
- default=None,
20
- validation_alias=AliasChoices("custom_post_prompt", "post_prompt"),
21
- )
22
-
23
-
24
- @router.get("/api/prompts")
25
- async def get_prompts() -> PromptSettingsResponse:
26
- settings = get_settings()
27
- return PromptSettingsResponse(
28
- custom_prompt=settings.custom_prompt,
29
- custom_post_prompt=settings.custom_post_prompt,
30
- )
31
-
32
-
33
- @router.put("/api/prompts")
34
- async def update_prompts(
35
- req: UpdatePromptSettingsRequest,
36
- ) -> PromptSettingsResponse:
37
- settings = get_settings()
38
- if req.custom_prompt is not None:
39
- settings.custom_prompt = req.custom_prompt
40
- if req.custom_post_prompt is not None:
41
- settings.custom_post_prompt = req.custom_post_prompt
42
- save_settings(settings)
43
- return PromptSettingsResponse(
44
- custom_prompt=settings.custom_prompt,
45
- custom_post_prompt=settings.custom_post_prompt,
46
- )