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,116 +0,0 @@
1
- import json
2
-
3
- import pytest
4
-
5
- from flowent.agent import Agent
6
- from flowent.graph_service import create_agent_node, create_edge, create_tab
7
- from flowent.models import NodeConfig, NodeType
8
- from flowent.registry import registry
9
- from flowent.settings import RoleConfig, Settings
10
- from flowent.tools.create_tab import CreateTabTool
11
- from flowent.tools.delete_tab import DeleteTabTool
12
- from flowent.tools.list_tabs import ListTabsTool
13
- from flowent.workspace_store import workspace_store
14
-
15
-
16
- @pytest.fixture(autouse=True)
17
- def reset_runtime_state(monkeypatch, tmp_path):
18
- import flowent.settings as settings_module
19
-
20
- settings_file = tmp_path / "settings.json"
21
- settings_file.write_text("{}", encoding="utf-8")
22
- monkeypatch.setattr(settings_module, "_SETTINGS_FILE", settings_file)
23
- monkeypatch.setattr(settings_module, "_cached_settings", None)
24
- registry.reset()
25
- workspace_store.reset_cache()
26
- yield
27
- registry.reset()
28
- workspace_store.reset_cache()
29
- monkeypatch.setattr(settings_module, "_cached_settings", None)
30
-
31
-
32
- def test_delete_tab_tool_deletes_tab_and_graph(monkeypatch):
33
- monkeypatch.setattr(
34
- "flowent.settings.get_settings",
35
- lambda: Settings(
36
- roles=[
37
- RoleConfig(
38
- name="Worker",
39
- system_prompt="Do work.",
40
- included_tools=["read"],
41
- )
42
- ]
43
- ),
44
- )
45
-
46
- assistant = Agent(
47
- NodeConfig(node_type=NodeType.ASSISTANT, tools=["delete_workflow"]),
48
- uuid="assistant",
49
- )
50
- registry.register(assistant)
51
-
52
- tab = create_tab(title="Cleanup")
53
- left, error = create_agent_node(role_name="Worker", tab_id=tab.id, name="Left")
54
- assert error is None and left is not None
55
- right, error = create_agent_node(role_name="Worker", tab_id=tab.id, name="Right")
56
- assert error is None and right is not None
57
- edge, error = create_edge(from_node_id=left.id, to_node_id=right.id)
58
- assert error is None and edge is not None
59
-
60
- result = json.loads(DeleteTabTool().execute(assistant, {"workflow_id": tab.id}))
61
-
62
- assert result["id"] == tab.id
63
- assert set(result["removed_node_ids"]) == {tab.leader_id, left.id, right.id}
64
- assert result["removed_edge_ids"] == [edge.id]
65
- assert workspace_store.get_tab(tab.id) is None
66
- assert workspace_store.list_node_records(tab.id) == []
67
- assert workspace_store.list_edges(tab.id) == []
68
- assert registry.get(tab.leader_id) is None
69
- assert registry.get(left.id) is None
70
- assert registry.get(right.id) is None
71
-
72
-
73
- def test_delete_tab_tool_rejects_non_assistant():
74
- agent = Agent(
75
- NodeConfig(
76
- node_type=NodeType.AGENT,
77
- role_name="Worker",
78
- tools=["delete_workflow"],
79
- ),
80
- uuid="worker",
81
- )
82
-
83
- result = json.loads(DeleteTabTool().execute(agent, {"workflow_id": "tab-1"}))
84
-
85
- assert result == {"error": "Only the Assistant may delete workflows"}
86
-
87
-
88
- def test_create_tab_tool_rejects_non_assistant():
89
- agent = Agent(
90
- NodeConfig(
91
- node_type=NodeType.AGENT,
92
- role_name="Worker",
93
- tools=["create_workflow"],
94
- ),
95
- uuid="worker",
96
- )
97
-
98
- result = json.loads(CreateTabTool().execute(agent, {"title": "Draft"}))
99
-
100
- assert result == {"error": "Only the Assistant may create workflows"}
101
- assert workspace_store.list_tabs() == []
102
-
103
-
104
- def test_list_tabs_tool_rejects_non_assistant():
105
- agent = Agent(
106
- NodeConfig(
107
- node_type=NodeType.AGENT,
108
- role_name="Worker",
109
- tools=["list_workflows"],
110
- ),
111
- uuid="worker",
112
- )
113
-
114
- result = json.loads(ListTabsTool().execute(agent, {}))
115
-
116
- assert result == {"error": "Only the Assistant may list workflows"}
@@ -1,115 +0,0 @@
1
- import json
2
-
3
- from flowent.agent import Agent
4
- from flowent.models import NodeConfig, NodeType
5
- from flowent.tools.edit import EditTool
6
-
7
-
8
- def test_edit_tool_applies_multiple_edits_in_sequence(tmp_path):
9
- target = tmp_path / "sample.txt"
10
- target.write_text("alpha\nbeta\ngamma\n", encoding="utf-8")
11
- agent = Agent(
12
- NodeConfig(
13
- node_type=NodeType.AGENT,
14
- tools=["edit"],
15
- write_dirs=[str(tmp_path)],
16
- )
17
- )
18
-
19
- result = json.loads(
20
- EditTool().execute(
21
- agent,
22
- {
23
- "path": str(target),
24
- "edits": [
25
- {
26
- "start_line": 2,
27
- "end_line": 2,
28
- "new_content": "beta-1\nbeta-2\n",
29
- },
30
- {
31
- "start_line": 4,
32
- "end_line": 4,
33
- "new_content": "gamma-updated\n",
34
- },
35
- ],
36
- },
37
- )
38
- )
39
-
40
- assert result["status"] == "edited"
41
- assert (
42
- target.read_text(encoding="utf-8") == "alpha\nbeta-1\nbeta-2\ngamma-updated\n"
43
- )
44
-
45
-
46
- def test_edit_tool_creates_missing_file_with_edits(tmp_path):
47
- target = tmp_path / "new.txt"
48
- agent = Agent(
49
- NodeConfig(
50
- node_type=NodeType.AGENT,
51
- tools=["edit"],
52
- write_dirs=[str(tmp_path)],
53
- )
54
- )
55
-
56
- result = json.loads(
57
- EditTool().execute(
58
- agent,
59
- {
60
- "path": str(target),
61
- "edits": [
62
- {
63
- "start_line": 1,
64
- "end_line": 1,
65
- "new_content": "hello\nworld\n",
66
- }
67
- ],
68
- },
69
- )
70
- )
71
-
72
- assert result["status"] == "edited"
73
- assert target.read_text(encoding="utf-8") == "hello\nworld\n"
74
-
75
-
76
- def test_edit_tool_streams_progress_updates(tmp_path):
77
- target = tmp_path / "sample.txt"
78
- target.write_text("alpha\nbeta\ngamma\n", encoding="utf-8")
79
- agent = Agent(
80
- NodeConfig(
81
- node_type=NodeType.AGENT,
82
- tools=["edit"],
83
- write_dirs=[str(tmp_path)],
84
- )
85
- )
86
- chunks: list[str] = []
87
-
88
- result = json.loads(
89
- EditTool().execute(
90
- agent,
91
- {
92
- "path": str(target),
93
- "edits": [
94
- {
95
- "start_line": 2,
96
- "end_line": 2,
97
- "new_content": "beta-updated\n",
98
- },
99
- {
100
- "start_line": 3,
101
- "end_line": 3,
102
- "new_content": "gamma-updated\n",
103
- },
104
- ],
105
- },
106
- on_output=chunks.append,
107
- )
108
- )
109
-
110
- assert result["status"] == "edited"
111
- assert "".join(chunks) == (
112
- f"Applying edit 1/2 at lines 2-2\n"
113
- f"Applying edit 2/2 at lines 3-3\n"
114
- f"Wrote {target}\n"
115
- )
@@ -1,81 +0,0 @@
1
- import json
2
- import shutil
3
- import subprocess
4
-
5
- import pytest
6
-
7
- from flowent.agent import Agent
8
- from flowent.models import NodeConfig, NodeType
9
- from flowent.settings import Settings
10
- from flowent.tools.exec import ExecTool
11
-
12
-
13
- def _sandbox_exec_supported(tmp_path) -> bool:
14
- if shutil.which("bwrap") is None:
15
- return False
16
-
17
- probe = subprocess.run(
18
- [
19
- "bwrap",
20
- "--ro-bind",
21
- "/",
22
- "/",
23
- "--dev",
24
- "/dev",
25
- "--proc",
26
- "/proc",
27
- "--tmpfs",
28
- "/tmp",
29
- "--ro-bind",
30
- str(tmp_path),
31
- str(tmp_path),
32
- "--chdir",
33
- str(tmp_path),
34
- "--die-with-parent",
35
- "--new-session",
36
- "--",
37
- "bash",
38
- "-c",
39
- "pwd >/dev/null",
40
- ],
41
- capture_output=True,
42
- text=True,
43
- )
44
- return probe.returncode == 0
45
-
46
-
47
- def test_exec_tool_runs_in_working_dir_when_tmp_is_sandboxed(
48
- monkeypatch,
49
- tmp_path,
50
- ):
51
- if not _sandbox_exec_supported(tmp_path):
52
- pytest.skip("bwrap sandbox is unavailable in this environment")
53
-
54
- target = tmp_path / "settings.json"
55
- target.write_text('{"name": "demo"}\n', encoding="utf-8")
56
- monkeypatch.setattr(
57
- "flowent.settings.get_settings",
58
- lambda: Settings(working_dir=str(tmp_path)),
59
- )
60
-
61
- agent = Agent(
62
- NodeConfig(
63
- node_type=NodeType.AGENT,
64
- tools=["exec"],
65
- write_dirs=[],
66
- )
67
- )
68
-
69
- result = json.loads(
70
- ExecTool().execute(
71
- agent,
72
- {
73
- "command": "pwd; cat settings.json",
74
- "timeout": 30,
75
- },
76
- )
77
- )
78
-
79
- assert result["returncode"] == 0
80
- assert result["stdout"] == f"{tmp_path}\n" + '{"name": "demo"}\n'
81
- assert result["stderr"] == ""
@@ -1,65 +0,0 @@
1
- import json
2
-
3
- from flowent.agent import Agent
4
- from flowent.models import NodeConfig, NodeType
5
- from flowent.tools.fetch import FetchTool
6
-
7
-
8
- class _FakeResponse:
9
- def __init__(self, status_code: int, chunks: list[str]):
10
- self.status_code = status_code
11
- self._chunks = chunks
12
-
13
- def __enter__(self):
14
- return self
15
-
16
- def __exit__(self, exc_type, exc, tb):
17
- return False
18
-
19
- def iter_content(self):
20
- for chunk in self._chunks:
21
- yield chunk.encode()
22
-
23
-
24
- class _FakeClient:
25
- last_impersonate_browser: bool | None = None
26
-
27
- def __init__(self, *, timeout: float, impersonate_browser: bool = False):
28
- self.timeout = timeout
29
- self.impersonate_browser = impersonate_browser
30
- type(self).last_impersonate_browser = impersonate_browser
31
-
32
- def __enter__(self):
33
- return self
34
-
35
- def __exit__(self, exc_type, exc, tb):
36
- return False
37
-
38
- def stream(self, method, url, headers=None, data=None):
39
- assert method == "GET"
40
- assert url == "https://example.com/data"
41
- assert headers is None
42
- assert data is None
43
- return _FakeResponse(200, ["hello ", "world"])
44
-
45
-
46
- def test_fetch_tool_streams_response_body_chunks(monkeypatch):
47
- agent = Agent(
48
- NodeConfig(node_type=NodeType.AGENT, tools=["fetch"], allow_network=True)
49
- )
50
- chunks: list[str] = []
51
- _FakeClient.last_impersonate_browser = None
52
-
53
- monkeypatch.setattr("flowent.tools.fetch.create_http_session", _FakeClient)
54
-
55
- result = json.loads(
56
- FetchTool().execute(
57
- agent,
58
- {"method": "GET", "url": "https://example.com/data"},
59
- on_output=chunks.append,
60
- )
61
- )
62
-
63
- assert result == {"status_code": 200, "body": "hello world"}
64
- assert "".join(chunks) == "GET https://example.com/data\nHTTP 200\n\nhello world"
65
- assert _FakeClient.last_impersonate_browser is True
@@ -1,117 +0,0 @@
1
- import json
2
-
3
- from flowent.agent import Agent
4
- from flowent.models import NodeConfig, NodeType
5
- from flowent.settings import Settings
6
- from flowent.tools.manage_prompts import ManagePromptsTool
7
-
8
-
9
- def test_manage_prompts_get_returns_current_prompt(monkeypatch):
10
- agent = Agent(NodeConfig(node_type=NodeType.ASSISTANT, tools=["manage_prompts"]))
11
- settings = Settings(
12
- custom_prompt="Be concise.",
13
- custom_post_prompt="Stay routed.",
14
- )
15
-
16
- monkeypatch.setattr("flowent.settings.get_settings", lambda: settings)
17
-
18
- result = json.loads(ManagePromptsTool().execute(agent, {"action": "get"}))
19
-
20
- assert result == {
21
- "custom_prompt": "Be concise.",
22
- "custom_post_prompt": "Stay routed.",
23
- }
24
-
25
-
26
- def test_manage_prompts_update_saves_custom_prompt(monkeypatch):
27
- agent = Agent(NodeConfig(node_type=NodeType.ASSISTANT, tools=["manage_prompts"]))
28
- settings = Settings(custom_prompt="", custom_post_prompt="")
29
- saved: list[Settings] = []
30
-
31
- monkeypatch.setattr("flowent.settings.get_settings", lambda: settings)
32
- monkeypatch.setattr(
33
- "flowent.settings.save_settings", lambda current: saved.append(current)
34
- )
35
-
36
- result = json.loads(
37
- ManagePromptsTool().execute(
38
- agent,
39
- {
40
- "action": "update",
41
- "custom_prompt": "Always prefer terse answers.",
42
- "custom_post_prompt": "Only route with @target.",
43
- },
44
- )
45
- )
46
-
47
- assert result == {
48
- "custom_prompt": "Always prefer terse answers.",
49
- "custom_post_prompt": "Only route with @target.",
50
- }
51
- assert settings.custom_prompt == "Always prefer terse answers."
52
- assert settings.custom_post_prompt == "Only route with @target."
53
- assert saved == [settings]
54
-
55
-
56
- def test_manage_prompts_update_requires_prompt_field(monkeypatch):
57
- agent = Agent(NodeConfig(node_type=NodeType.ASSISTANT, tools=["manage_prompts"]))
58
- monkeypatch.setattr("flowent.settings.get_settings", lambda: Settings())
59
-
60
- result = json.loads(
61
- ManagePromptsTool().execute(
62
- agent,
63
- {"action": "update"},
64
- )
65
- )
66
-
67
- assert result == {"error": "custom_prompt or custom_post_prompt is required"}
68
-
69
-
70
- def test_manage_prompts_update_allows_custom_post_prompt_only(monkeypatch):
71
- agent = Agent(NodeConfig(node_type=NodeType.ASSISTANT, tools=["manage_prompts"]))
72
- settings = Settings(custom_prompt="Keep this.", custom_post_prompt="")
73
-
74
- monkeypatch.setattr("flowent.settings.get_settings", lambda: settings)
75
- monkeypatch.setattr("flowent.settings.save_settings", lambda current: None)
76
-
77
- result = json.loads(
78
- ManagePromptsTool().execute(
79
- agent,
80
- {
81
- "action": "update",
82
- "custom_post_prompt": "Append this after history.",
83
- },
84
- )
85
- )
86
-
87
- assert result == {
88
- "custom_prompt": "Keep this.",
89
- "custom_post_prompt": "Append this after history.",
90
- }
91
- assert settings.custom_prompt == "Keep this."
92
- assert settings.custom_post_prompt == "Append this after history."
93
-
94
-
95
- def test_manage_prompts_update_accepts_legacy_post_prompt_alias(monkeypatch):
96
- agent = Agent(NodeConfig(node_type=NodeType.ASSISTANT, tools=["manage_prompts"]))
97
- settings = Settings(custom_prompt="Keep this.", custom_post_prompt="")
98
-
99
- monkeypatch.setattr("flowent.settings.get_settings", lambda: settings)
100
- monkeypatch.setattr("flowent.settings.save_settings", lambda current: None)
101
-
102
- result = json.loads(
103
- ManagePromptsTool().execute(
104
- agent,
105
- {
106
- "action": "update",
107
- "post_prompt": "Append this after history.",
108
- },
109
- )
110
- )
111
-
112
- assert result == {
113
- "custom_prompt": "Keep this.",
114
- "custom_post_prompt": "Append this after history.",
115
- }
116
- assert settings.custom_prompt == "Keep this."
117
- assert settings.custom_post_prompt == "Append this after history."