flowent 0.0.7 → 0.0.11

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 (387) 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/__init__.py +6 -2
  5. package/backend/src/flowent/__pycache__/__init__.cpython-313.pyc +0 -0
  6. package/backend/src/flowent/__pycache__/agent.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 +376 -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 +477 -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__/cli.cpython-313.pyc +0 -0
  59. package/backend/src/flowent/__pycache__/config.cpython-313.pyc +0 -0
  60. package/backend/src/flowent/__pycache__/events.cpython-313.pyc +0 -0
  61. package/backend/src/flowent/__pycache__/graph_runtime.cpython-313.pyc +0 -0
  62. package/backend/src/flowent/__pycache__/graph_service.cpython-313.pyc +0 -0
  63. package/backend/src/flowent/__pycache__/image_assets.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 -2401
  86. package/backend/src/flowent/image_assets.py +0 -356
  87. package/backend/src/flowent/model_metadata.py +0 -102
  88. package/backend/src/flowent/models/__init__.py +0 -125
  89. package/backend/src/flowent/models/__pycache__/__init__.cpython-313.pyc +0 -0
  90. package/backend/src/flowent/models/__pycache__/agent.cpython-313.pyc +0 -0
  91. package/backend/src/flowent/models/__pycache__/base.cpython-313.pyc +0 -0
  92. package/backend/src/flowent/models/__pycache__/blueprint.cpython-313.pyc +0 -0
  93. package/backend/src/flowent/models/__pycache__/content.cpython-313.pyc +0 -0
  94. package/backend/src/flowent/models/__pycache__/delta.cpython-313.pyc +0 -0
  95. package/backend/src/flowent/models/__pycache__/event.cpython-313.pyc +0 -0
  96. package/backend/src/flowent/models/__pycache__/graph.cpython-313.pyc +0 -0
  97. package/backend/src/flowent/models/__pycache__/history.cpython-313.pyc +0 -0
  98. package/backend/src/flowent/models/__pycache__/llm.cpython-313.pyc +0 -0
  99. package/backend/src/flowent/models/__pycache__/message.cpython-313.pyc +0 -0
  100. package/backend/src/flowent/models/__pycache__/tab.cpython-313.pyc +0 -0
  101. package/backend/src/flowent/models/__pycache__/todo.cpython-313.pyc +0 -0
  102. package/backend/src/flowent/models/agent.py +0 -34
  103. package/backend/src/flowent/models/base.py +0 -24
  104. package/backend/src/flowent/models/blueprint.py +0 -176
  105. package/backend/src/flowent/models/content.py +0 -164
  106. package/backend/src/flowent/models/delta.py +0 -44
  107. package/backend/src/flowent/models/event.py +0 -51
  108. package/backend/src/flowent/models/graph.py +0 -472
  109. package/backend/src/flowent/models/history.py +0 -272
  110. package/backend/src/flowent/models/llm.py +0 -62
  111. package/backend/src/flowent/models/message.py +0 -33
  112. package/backend/src/flowent/models/tab.py +0 -85
  113. package/backend/src/flowent/models/todo.py +0 -10
  114. package/backend/src/flowent/network.py +0 -146
  115. package/backend/src/flowent/observability_service.py +0 -218
  116. package/backend/src/flowent/prompts/__init__.py +0 -67
  117. package/backend/src/flowent/prompts/__pycache__/__init__.cpython-313.pyc +0 -0
  118. package/backend/src/flowent/prompts/__pycache__/common.cpython-313.pyc +0 -0
  119. package/backend/src/flowent/prompts/__pycache__/steward.cpython-313.pyc +0 -0
  120. package/backend/src/flowent/prompts/common.py +0 -250
  121. package/backend/src/flowent/prompts/steward.py +0 -64
  122. package/backend/src/flowent/providers/__init__.py +0 -23
  123. package/backend/src/flowent/providers/__pycache__/__init__.cpython-313.pyc +0 -0
  124. package/backend/src/flowent/providers/__pycache__/anthropic.cpython-313.pyc +0 -0
  125. package/backend/src/flowent/providers/__pycache__/base_url.cpython-313.pyc +0 -0
  126. package/backend/src/flowent/providers/__pycache__/configuration.cpython-313.pyc +0 -0
  127. package/backend/src/flowent/providers/__pycache__/content.cpython-313.pyc +0 -0
  128. package/backend/src/flowent/providers/__pycache__/errors.cpython-313.pyc +0 -0
  129. package/backend/src/flowent/providers/__pycache__/gateway.cpython-313.pyc +0 -0
  130. package/backend/src/flowent/providers/__pycache__/headers.cpython-313.pyc +0 -0
  131. package/backend/src/flowent/providers/__pycache__/management.cpython-313.pyc +0 -0
  132. package/backend/src/flowent/providers/__pycache__/openai.cpython-313.pyc +0 -0
  133. package/backend/src/flowent/providers/__pycache__/openai_responses.cpython-313.pyc +0 -0
  134. package/backend/src/flowent/providers/__pycache__/registry.cpython-313.pyc +0 -0
  135. package/backend/src/flowent/providers/__pycache__/sse.cpython-313.pyc +0 -0
  136. package/backend/src/flowent/providers/__pycache__/thinking.cpython-313.pyc +0 -0
  137. package/backend/src/flowent/providers/anthropic.py +0 -468
  138. package/backend/src/flowent/providers/base_url.py +0 -60
  139. package/backend/src/flowent/providers/configuration.py +0 -189
  140. package/backend/src/flowent/providers/content.py +0 -122
  141. package/backend/src/flowent/providers/errors.py +0 -223
  142. package/backend/src/flowent/providers/gateway.py +0 -169
  143. package/backend/src/flowent/providers/gemini.py +0 -447
  144. package/backend/src/flowent/providers/headers.py +0 -20
  145. package/backend/src/flowent/providers/management.py +0 -96
  146. package/backend/src/flowent/providers/ollama.py +0 -293
  147. package/backend/src/flowent/providers/openai.py +0 -422
  148. package/backend/src/flowent/providers/openai_responses.py +0 -655
  149. package/backend/src/flowent/providers/registry.py +0 -144
  150. package/backend/src/flowent/providers/sse.py +0 -31
  151. package/backend/src/flowent/providers/thinking.py +0 -79
  152. package/backend/src/flowent/registry.py +0 -73
  153. package/backend/src/flowent/role_management.py +0 -270
  154. package/backend/src/flowent/routes/__init__.py +0 -26
  155. package/backend/src/flowent/routes/__pycache__/__init__.cpython-313.pyc +0 -0
  156. package/backend/src/flowent/routes/__pycache__/access.cpython-313.pyc +0 -0
  157. package/backend/src/flowent/routes/__pycache__/assistant.cpython-313.pyc +0 -0
  158. package/backend/src/flowent/routes/__pycache__/image_assets.cpython-313.pyc +0 -0
  159. package/backend/src/flowent/routes/__pycache__/meta.cpython-313.pyc +0 -0
  160. package/backend/src/flowent/routes/__pycache__/nodes.cpython-313.pyc +0 -0
  161. package/backend/src/flowent/routes/__pycache__/prompts.cpython-313.pyc +0 -0
  162. package/backend/src/flowent/routes/__pycache__/providers_route.cpython-313.pyc +0 -0
  163. package/backend/src/flowent/routes/__pycache__/roles.cpython-313.pyc +0 -0
  164. package/backend/src/flowent/routes/__pycache__/settings.cpython-313.pyc +0 -0
  165. package/backend/src/flowent/routes/__pycache__/tabs.cpython-313.pyc +0 -0
  166. package/backend/src/flowent/routes/__pycache__/ws.cpython-313.pyc +0 -0
  167. package/backend/src/flowent/routes/access.py +0 -48
  168. package/backend/src/flowent/routes/assistant.py +0 -158
  169. package/backend/src/flowent/routes/image_assets.py +0 -33
  170. package/backend/src/flowent/routes/meta.py +0 -28
  171. package/backend/src/flowent/routes/nodes.py +0 -423
  172. package/backend/src/flowent/routes/prompts.py +0 -46
  173. package/backend/src/flowent/routes/providers_route.py +0 -365
  174. package/backend/src/flowent/routes/roles.py +0 -207
  175. package/backend/src/flowent/routes/settings.py +0 -379
  176. package/backend/src/flowent/routes/tabs.py +0 -298
  177. package/backend/src/flowent/routes/ws.py +0 -33
  178. package/backend/src/flowent/runtime.py +0 -160
  179. package/backend/src/flowent/security.py +0 -37
  180. package/backend/src/flowent/settings.py +0 -2112
  181. package/backend/src/flowent/settings_management.py +0 -394
  182. package/backend/src/flowent/state_db.py +0 -108
  183. package/backend/src/flowent/static/assets/AssistantPage-BW7XAd9I.js +0 -1
  184. package/backend/src/flowent/static/assets/ChannelsPage-tCJHgt6m.js +0 -1
  185. package/backend/src/flowent/static/assets/PageScaffold-f6g2l7XN.js +0 -1
  186. package/backend/src/flowent/static/assets/PromptsPage-C3Sxn2D7.js +0 -1
  187. package/backend/src/flowent/static/assets/ProvidersPage-BfmdXmNt.js +0 -3
  188. package/backend/src/flowent/static/assets/RolesPage-DET8wO4r.js +0 -1
  189. package/backend/src/flowent/static/assets/SettingsPage-D-g3deMm.js +0 -3
  190. package/backend/src/flowent/static/assets/ToolsPage-CDmtE2g4.js +0 -1
  191. package/backend/src/flowent/static/assets/WorkspacePage-AZsJ0sD0.js +0 -3
  192. package/backend/src/flowent/static/assets/WorkspacePanels-CteCjolX.js +0 -1
  193. package/backend/src/flowent/static/assets/alert-dialog-Duorp_S-.js +0 -1
  194. package/backend/src/flowent/static/assets/dialog-C3ixjGjN.js +0 -1
  195. package/backend/src/flowent/static/assets/elk-worker.min-C9JGDOE-.js +0 -6312
  196. package/backend/src/flowent/static/assets/graph-vendor-CHpVij2M.css +0 -1
  197. package/backend/src/flowent/static/assets/graph-vendor-DRq_-6fV.js +0 -7
  198. package/backend/src/flowent/static/assets/index--o_0fv0N.css +0 -1
  199. package/backend/src/flowent/static/assets/index-C9HuekJm.js +0 -10
  200. package/backend/src/flowent/static/assets/layout.worker-jMHqAFbP.js +0 -24
  201. package/backend/src/flowent/static/assets/markdown-vendor-C9RtvaJh.js +0 -29
  202. package/backend/src/flowent/static/assets/modelParams-DmnF2hwR.js +0 -1
  203. package/backend/src/flowent/static/assets/providerTypes-DT3Ahwl_.js +0 -1
  204. package/backend/src/flowent/static/assets/react-vendor-mEs_JJxa.js +0 -9
  205. package/backend/src/flowent/static/assets/roles-CuRT_chR.js +0 -1
  206. package/backend/src/flowent/static/assets/rolldown-runtime-BYbx6iT9.js +0 -1
  207. package/backend/src/flowent/static/assets/select-DCfeNu-F.js +0 -1
  208. package/backend/src/flowent/static/assets/surface-pWwG5ogx.js +0 -1
  209. package/backend/src/flowent/static/assets/ui-vendor-C5pJa8N7.js +0 -51
  210. package/backend/src/flowent/static/assets/useAppRoute-FgSHBKhV.js +0 -1
  211. package/backend/src/flowent/static/favicon.svg +0 -4
  212. package/backend/src/flowent/tools/__init__.py +0 -176
  213. package/backend/src/flowent/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  214. package/backend/src/flowent/tools/__pycache__/connect.cpython-313.pyc +0 -0
  215. package/backend/src/flowent/tools/__pycache__/contacts.cpython-313.pyc +0 -0
  216. package/backend/src/flowent/tools/__pycache__/create_agent.cpython-313.pyc +0 -0
  217. package/backend/src/flowent/tools/__pycache__/create_tab.cpython-313.pyc +0 -0
  218. package/backend/src/flowent/tools/__pycache__/delete_tab.cpython-313.pyc +0 -0
  219. package/backend/src/flowent/tools/__pycache__/edit.cpython-313.pyc +0 -0
  220. package/backend/src/flowent/tools/__pycache__/exec.cpython-313.pyc +0 -0
  221. package/backend/src/flowent/tools/__pycache__/fetch.cpython-313.pyc +0 -0
  222. package/backend/src/flowent/tools/__pycache__/idle.cpython-313.pyc +0 -0
  223. package/backend/src/flowent/tools/__pycache__/list_roles.cpython-313.pyc +0 -0
  224. package/backend/src/flowent/tools/__pycache__/list_tabs.cpython-313.pyc +0 -0
  225. package/backend/src/flowent/tools/__pycache__/list_tools.cpython-313.pyc +0 -0
  226. package/backend/src/flowent/tools/__pycache__/manage_prompts.cpython-313.pyc +0 -0
  227. package/backend/src/flowent/tools/__pycache__/manage_providers.cpython-313.pyc +0 -0
  228. package/backend/src/flowent/tools/__pycache__/manage_roles.cpython-313.pyc +0 -0
  229. package/backend/src/flowent/tools/__pycache__/manage_settings.cpython-313.pyc +0 -0
  230. package/backend/src/flowent/tools/__pycache__/read.cpython-313.pyc +0 -0
  231. package/backend/src/flowent/tools/__pycache__/send.cpython-313.pyc +0 -0
  232. package/backend/src/flowent/tools/__pycache__/set_permissions.cpython-313.pyc +0 -0
  233. package/backend/src/flowent/tools/__pycache__/sleep.cpython-313.pyc +0 -0
  234. package/backend/src/flowent/tools/__pycache__/todo.cpython-313.pyc +0 -0
  235. package/backend/src/flowent/tools/connect.py +0 -100
  236. package/backend/src/flowent/tools/contacts.py +0 -22
  237. package/backend/src/flowent/tools/create_agent.py +0 -191
  238. package/backend/src/flowent/tools/create_tab.py +0 -61
  239. package/backend/src/flowent/tools/delete_tab.py +0 -39
  240. package/backend/src/flowent/tools/edit.py +0 -142
  241. package/backend/src/flowent/tools/exec.py +0 -118
  242. package/backend/src/flowent/tools/fetch.py +0 -85
  243. package/backend/src/flowent/tools/idle.py +0 -27
  244. package/backend/src/flowent/tools/list_roles.py +0 -68
  245. package/backend/src/flowent/tools/list_tabs.py +0 -100
  246. package/backend/src/flowent/tools/list_tools.py +0 -28
  247. package/backend/src/flowent/tools/manage_prompts.py +0 -102
  248. package/backend/src/flowent/tools/manage_providers.py +0 -220
  249. package/backend/src/flowent/tools/manage_roles.py +0 -275
  250. package/backend/src/flowent/tools/manage_settings.py +0 -326
  251. package/backend/src/flowent/tools/read.py +0 -152
  252. package/backend/src/flowent/tools/send.py +0 -68
  253. package/backend/src/flowent/tools/set_permissions.py +0 -99
  254. package/backend/src/flowent/tools/sleep.py +0 -41
  255. package/backend/src/flowent/tools/todo.py +0 -51
  256. package/backend/src/flowent/workspace_store.py +0 -479
  257. package/backend/tests/__init__.py +0 -0
  258. package/backend/tests/__pycache__/__init__.cpython-313.pyc +0 -0
  259. package/backend/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  260. package/backend/tests/conftest.py +0 -6
  261. package/backend/tests/integration/api/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  262. package/backend/tests/integration/api/__pycache__/test_access_api.cpython-313-pytest-9.0.3.pyc +0 -0
  263. package/backend/tests/integration/api/__pycache__/test_assistant_api.cpython-313-pytest-9.0.3.pyc +0 -0
  264. package/backend/tests/integration/api/__pycache__/test_frontend_mounting.cpython-313-pytest-9.0.3.pyc +0 -0
  265. package/backend/tests/integration/api/__pycache__/test_meta_api.cpython-313-pytest-9.0.3.pyc +0 -0
  266. package/backend/tests/integration/api/__pycache__/test_nodes_api.cpython-313-pytest-9.0.3.pyc +0 -0
  267. package/backend/tests/integration/api/__pycache__/test_prompts_api.cpython-313-pytest-9.0.3.pyc +0 -0
  268. package/backend/tests/integration/api/__pycache__/test_roles_api.cpython-313-pytest-9.0.3.pyc +0 -0
  269. package/backend/tests/integration/api/__pycache__/test_tabs_api.cpython-313-pytest-9.0.3.pyc +0 -0
  270. package/backend/tests/integration/api/conftest.py +0 -29
  271. package/backend/tests/integration/api/test_access_api.py +0 -182
  272. package/backend/tests/integration/api/test_assistant_api.py +0 -422
  273. package/backend/tests/integration/api/test_frontend_mounting.py +0 -61
  274. package/backend/tests/integration/api/test_meta_api.py +0 -32
  275. package/backend/tests/integration/api/test_nodes_api.py +0 -787
  276. package/backend/tests/integration/api/test_prompts_api.py +0 -47
  277. package/backend/tests/integration/api/test_roles_api.py +0 -228
  278. package/backend/tests/integration/api/test_tabs_api.py +0 -688
  279. package/backend/tests/unit/__pycache__/test_access.cpython-313-pytest-9.0.3.pyc +0 -0
  280. package/backend/tests/unit/__pycache__/test_cli.cpython-313-pytest-9.0.3.pyc +0 -0
  281. package/backend/tests/unit/__pycache__/test_graph_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  282. package/backend/tests/unit/__pycache__/test_network.cpython-313-pytest-9.0.3.pyc +0 -0
  283. package/backend/tests/unit/__pycache__/test_state_sqlite_storage.cpython-313-pytest-9.0.3.pyc +0 -0
  284. package/backend/tests/unit/__pycache__/test_workspace_store.cpython-313-pytest-9.0.3.pyc +0 -0
  285. package/backend/tests/unit/agent/__pycache__/test_agent_public_api.cpython-313-pytest-9.0.3.pyc +0 -0
  286. package/backend/tests/unit/agent/__pycache__/test_agent_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  287. package/backend/tests/unit/agent/test_agent_public_api.py +0 -822
  288. package/backend/tests/unit/agent/test_agent_runtime.py +0 -3088
  289. package/backend/tests/unit/channels/__pycache__/test_telegram_channel.cpython-313-pytest-9.0.3.pyc +0 -0
  290. package/backend/tests/unit/channels/test_telegram_channel.py +0 -552
  291. package/backend/tests/unit/logging/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
  292. package/backend/tests/unit/logging/test_logging.py +0 -132
  293. package/backend/tests/unit/prompts/__pycache__/test_prompts.cpython-313-pytest-9.0.3.pyc +0 -0
  294. package/backend/tests/unit/prompts/test_prompts.py +0 -570
  295. package/backend/tests/unit/providers/__pycache__/test_anthropic_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  296. package/backend/tests/unit/providers/__pycache__/test_errors.cpython-313-pytest-9.0.3.pyc +0 -0
  297. package/backend/tests/unit/providers/__pycache__/test_extract_delta_parts.cpython-313-pytest-9.0.3.pyc +0 -0
  298. package/backend/tests/unit/providers/__pycache__/test_openai_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  299. package/backend/tests/unit/providers/__pycache__/test_openai_responses.cpython-313-pytest-9.0.3.pyc +0 -0
  300. package/backend/tests/unit/providers/__pycache__/test_provider_gateway.cpython-313-pytest-9.0.3.pyc +0 -0
  301. package/backend/tests/unit/providers/__pycache__/test_think_tag_parser.cpython-313-pytest-9.0.3.pyc +0 -0
  302. package/backend/tests/unit/providers/test_anthropic_provider.py +0 -185
  303. package/backend/tests/unit/providers/test_errors.py +0 -68
  304. package/backend/tests/unit/providers/test_extract_delta_parts.py +0 -22
  305. package/backend/tests/unit/providers/test_openai_provider.py +0 -139
  306. package/backend/tests/unit/providers/test_openai_responses.py +0 -402
  307. package/backend/tests/unit/providers/test_provider_gateway.py +0 -359
  308. package/backend/tests/unit/providers/test_think_tag_parser.py +0 -36
  309. package/backend/tests/unit/routes/__pycache__/test_prompts_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  310. package/backend/tests/unit/routes/__pycache__/test_providers_route.cpython-313-pytest-9.0.3.pyc +0 -0
  311. package/backend/tests/unit/routes/__pycache__/test_roles_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  312. package/backend/tests/unit/routes/__pycache__/test_settings_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  313. package/backend/tests/unit/routes/test_prompts_routes.py +0 -82
  314. package/backend/tests/unit/routes/test_providers_route.py +0 -370
  315. package/backend/tests/unit/routes/test_roles_routes.py +0 -539
  316. package/backend/tests/unit/routes/test_settings_routes.py +0 -1123
  317. package/backend/tests/unit/runtime/__pycache__/test_bootstrap_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  318. package/backend/tests/unit/runtime/test_bootstrap_runtime.py +0 -1002
  319. package/backend/tests/unit/sandbox/__pycache__/test_sandbox_tools.cpython-313-pytest-9.0.3.pyc +0 -0
  320. package/backend/tests/unit/sandbox/test_sandbox_tools.py +0 -78
  321. package/backend/tests/unit/security/__pycache__/test_security.cpython-313-pytest-9.0.3.pyc +0 -0
  322. package/backend/tests/unit/security/test_security.py +0 -124
  323. package/backend/tests/unit/settings/__pycache__/test_settings_roles.cpython-313-pytest-9.0.3.pyc +0 -0
  324. package/backend/tests/unit/settings/test_settings_roles.py +0 -703
  325. package/backend/tests/unit/test_access.py +0 -45
  326. package/backend/tests/unit/test_cli.py +0 -102
  327. package/backend/tests/unit/test_graph_runtime.py +0 -72
  328. package/backend/tests/unit/test_network.py +0 -51
  329. package/backend/tests/unit/test_state_sqlite_storage.py +0 -87
  330. package/backend/tests/unit/test_workspace_store.py +0 -228
  331. package/backend/tests/unit/tools/__pycache__/test_connect_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  332. package/backend/tests/unit/tools/__pycache__/test_create_agent_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  333. package/backend/tests/unit/tools/__pycache__/test_delete_tab_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  334. package/backend/tests/unit/tools/__pycache__/test_edit_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  335. package/backend/tests/unit/tools/__pycache__/test_exec_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  336. package/backend/tests/unit/tools/__pycache__/test_fetch_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  337. package/backend/tests/unit/tools/__pycache__/test_manage_prompts_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  338. package/backend/tests/unit/tools/__pycache__/test_manage_providers_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  339. package/backend/tests/unit/tools/__pycache__/test_manage_roles_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  340. package/backend/tests/unit/tools/__pycache__/test_manage_settings_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  341. package/backend/tests/unit/tools/__pycache__/test_read_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  342. package/backend/tests/unit/tools/__pycache__/test_set_permissions_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  343. package/backend/tests/unit/tools/__pycache__/test_todo_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  344. package/backend/tests/unit/tools/__pycache__/test_tool_registry.cpython-313-pytest-9.0.3.pyc +0 -0
  345. package/backend/tests/unit/tools/test_connect_tool.py +0 -228
  346. package/backend/tests/unit/tools/test_create_agent_tool.py +0 -404
  347. package/backend/tests/unit/tools/test_delete_tab_tool.py +0 -116
  348. package/backend/tests/unit/tools/test_edit_tool.py +0 -115
  349. package/backend/tests/unit/tools/test_exec_tool.py +0 -81
  350. package/backend/tests/unit/tools/test_fetch_tool.py +0 -65
  351. package/backend/tests/unit/tools/test_manage_prompts_tool.py +0 -92
  352. package/backend/tests/unit/tools/test_manage_providers_tool.py +0 -460
  353. package/backend/tests/unit/tools/test_manage_roles_tool.py +0 -411
  354. package/backend/tests/unit/tools/test_manage_settings_tool.py +0 -611
  355. package/backend/tests/unit/tools/test_read_tool.py +0 -33
  356. package/backend/tests/unit/tools/test_set_permissions_tool.py +0 -595
  357. package/backend/tests/unit/tools/test_todo_tool.py +0 -37
  358. package/backend/tests/unit/tools/test_tool_registry.py +0 -199
  359. package/dist/frontend/assets/AssistantPage-BW7XAd9I.js +0 -1
  360. package/dist/frontend/assets/ChannelsPage-tCJHgt6m.js +0 -1
  361. package/dist/frontend/assets/PageScaffold-f6g2l7XN.js +0 -1
  362. package/dist/frontend/assets/PromptsPage-C3Sxn2D7.js +0 -1
  363. package/dist/frontend/assets/ProvidersPage-BfmdXmNt.js +0 -3
  364. package/dist/frontend/assets/RolesPage-DET8wO4r.js +0 -1
  365. package/dist/frontend/assets/SettingsPage-D-g3deMm.js +0 -3
  366. package/dist/frontend/assets/ToolsPage-CDmtE2g4.js +0 -1
  367. package/dist/frontend/assets/WorkspacePage-AZsJ0sD0.js +0 -3
  368. package/dist/frontend/assets/WorkspacePanels-CteCjolX.js +0 -1
  369. package/dist/frontend/assets/alert-dialog-Duorp_S-.js +0 -1
  370. package/dist/frontend/assets/dialog-C3ixjGjN.js +0 -1
  371. package/dist/frontend/assets/elk-worker.min-C9JGDOE-.js +0 -6312
  372. package/dist/frontend/assets/graph-vendor-CHpVij2M.css +0 -1
  373. package/dist/frontend/assets/graph-vendor-DRq_-6fV.js +0 -7
  374. package/dist/frontend/assets/index--o_0fv0N.css +0 -1
  375. package/dist/frontend/assets/index-C9HuekJm.js +0 -10
  376. package/dist/frontend/assets/layout.worker-jMHqAFbP.js +0 -24
  377. package/dist/frontend/assets/markdown-vendor-C9RtvaJh.js +0 -29
  378. package/dist/frontend/assets/modelParams-DmnF2hwR.js +0 -1
  379. package/dist/frontend/assets/providerTypes-DT3Ahwl_.js +0 -1
  380. package/dist/frontend/assets/react-vendor-mEs_JJxa.js +0 -9
  381. package/dist/frontend/assets/roles-CuRT_chR.js +0 -1
  382. package/dist/frontend/assets/rolldown-runtime-BYbx6iT9.js +0 -1
  383. package/dist/frontend/assets/select-DCfeNu-F.js +0 -1
  384. package/dist/frontend/assets/surface-pWwG5ogx.js +0 -1
  385. package/dist/frontend/assets/ui-vendor-C5pJa8N7.js +0 -51
  386. package/dist/frontend/assets/useAppRoute-FgSHBKhV.js +0 -1
  387. package/dist/frontend/favicon.svg +0 -4
@@ -1,218 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import copy
4
- import json
5
- import threading
6
- import time
7
- import uuid
8
- from dataclasses import dataclass
9
- from typing import Any, Literal
10
-
11
- from flowent.models import LLMUsage
12
- from flowent.state_db import open_state_db
13
-
14
- OBSERVABILITY_RETENTION_SECONDS = 30 * 24 * 60 * 60
15
-
16
-
17
- def serialize_usage(usage: LLMUsage | None) -> dict[str, Any] | None:
18
- if usage is None:
19
- return None
20
- return {
21
- "total_tokens": usage.total_tokens,
22
- "input_tokens": usage.input_tokens,
23
- "output_tokens": usage.output_tokens,
24
- "cached_input_tokens": usage.cached_input_tokens,
25
- "cache_read_tokens": usage.cache_read_tokens,
26
- "cache_write_tokens": usage.cache_write_tokens,
27
- "details": dict(usage.details),
28
- }
29
-
30
-
31
- @dataclass(frozen=True)
32
- class RequestRecordInput:
33
- node_id: str
34
- node_label: str
35
- role_name: str | None
36
- tab_id: str | None
37
- tab_title: str | None
38
- provider_id: str | None
39
- provider_name: str | None
40
- provider_type: str | None
41
- model: str | None
42
- started_at: float
43
- ended_at: float
44
- retry_count: int
45
- result: Literal["success", "error"]
46
- normalized_usage: LLMUsage | None = None
47
- raw_usage: dict[str, Any] | None = None
48
- error_summary: str | None = None
49
-
50
-
51
- @dataclass(frozen=True)
52
- class CompactRecordInput:
53
- node_id: str
54
- node_label: str
55
- role_name: str | None
56
- tab_id: str | None
57
- tab_title: str | None
58
- provider_id: str | None
59
- provider_name: str | None
60
- provider_type: str | None
61
- model: str | None
62
- trigger_type: Literal["manual", "auto"]
63
- started_at: float
64
- ended_at: float
65
- result: Literal["success", "error"]
66
- error_summary: str | None = None
67
-
68
-
69
- class ObservabilityStore:
70
- def __init__(self) -> None:
71
- self._lock = threading.Lock()
72
-
73
- def reset(self) -> None:
74
- connection = open_state_db(create=False)
75
- if connection is None:
76
- return
77
- try:
78
- with connection:
79
- connection.execute("DELETE FROM llm_request_records")
80
- connection.execute("DELETE FROM compact_records")
81
- finally:
82
- connection.close()
83
-
84
- def _prune_locked(self, connection, now: float) -> None:
85
- min_timestamp = now - OBSERVABILITY_RETENTION_SECONDS
86
- connection.execute(
87
- "DELETE FROM llm_request_records WHERE ended_at < ?",
88
- (min_timestamp,),
89
- )
90
- connection.execute(
91
- "DELETE FROM compact_records WHERE ended_at < ?",
92
- (min_timestamp,),
93
- )
94
-
95
- def record_request(self, record: RequestRecordInput) -> None:
96
- payload = {
97
- "id": str(uuid.uuid4()),
98
- "node_id": record.node_id,
99
- "node_label": record.node_label,
100
- "role_name": record.role_name,
101
- "tab_id": record.tab_id,
102
- "tab_title": record.tab_title,
103
- "provider_id": record.provider_id,
104
- "provider_name": record.provider_name,
105
- "provider_type": record.provider_type,
106
- "model": record.model,
107
- "started_at": record.started_at,
108
- "ended_at": record.ended_at,
109
- "duration_ms": max(0.0, (record.ended_at - record.started_at) * 1000),
110
- "retry_count": max(record.retry_count, 0),
111
- "result": record.result,
112
- "error_summary": record.error_summary,
113
- "normalized_usage": serialize_usage(record.normalized_usage),
114
- "raw_usage": copy.deepcopy(record.raw_usage),
115
- }
116
- with self._lock:
117
- connection = open_state_db(create=True)
118
- assert connection is not None
119
- try:
120
- with connection:
121
- self._prune_locked(connection, time.time())
122
- connection.execute(
123
- """
124
- INSERT INTO llm_request_records (id, ended_at, payload)
125
- VALUES (?, ?, ?)
126
- """,
127
- (
128
- payload["id"],
129
- payload["ended_at"],
130
- json.dumps(payload, ensure_ascii=False),
131
- ),
132
- )
133
- finally:
134
- connection.close()
135
-
136
- def record_compact(self, record: CompactRecordInput) -> None:
137
- payload = {
138
- "id": str(uuid.uuid4()),
139
- "node_id": record.node_id,
140
- "node_label": record.node_label,
141
- "role_name": record.role_name,
142
- "tab_id": record.tab_id,
143
- "tab_title": record.tab_title,
144
- "provider_id": record.provider_id,
145
- "provider_name": record.provider_name,
146
- "provider_type": record.provider_type,
147
- "model": record.model,
148
- "trigger_type": record.trigger_type,
149
- "started_at": record.started_at,
150
- "ended_at": record.ended_at,
151
- "duration_ms": max(0.0, (record.ended_at - record.started_at) * 1000),
152
- "result": record.result,
153
- "error_summary": record.error_summary,
154
- }
155
- with self._lock:
156
- connection = open_state_db(create=True)
157
- assert connection is not None
158
- try:
159
- with connection:
160
- self._prune_locked(connection, time.time())
161
- connection.execute(
162
- """
163
- INSERT INTO compact_records (id, ended_at, payload)
164
- VALUES (?, ?, ?)
165
- """,
166
- (
167
- payload["id"],
168
- payload["ended_at"],
169
- json.dumps(payload, ensure_ascii=False),
170
- ),
171
- )
172
- finally:
173
- connection.close()
174
-
175
- def list_requests(self, *, since: float) -> list[dict[str, Any]]:
176
- with self._lock:
177
- return self._list_records(
178
- table_name="llm_request_records",
179
- since=since,
180
- )
181
-
182
- def list_compacts(self, *, since: float) -> list[dict[str, Any]]:
183
- with self._lock:
184
- return self._list_records(
185
- table_name="compact_records",
186
- since=since,
187
- )
188
-
189
- def _list_records(self, *, table_name: str, since: float) -> list[dict[str, Any]]:
190
- connection = open_state_db(create=False)
191
- if connection is None:
192
- return []
193
- try:
194
- with connection:
195
- self._prune_locked(connection, time.time())
196
- rows = connection.execute(
197
- f"""
198
- SELECT payload
199
- FROM {table_name}
200
- WHERE ended_at >= ?
201
- ORDER BY ended_at
202
- """,
203
- (since,),
204
- ).fetchall()
205
- finally:
206
- connection.close()
207
- records: list[dict[str, Any]] = []
208
- for row in rows:
209
- payload = row["payload"]
210
- if not isinstance(payload, str):
211
- continue
212
- parsed = json.loads(payload)
213
- if isinstance(parsed, dict):
214
- records.append(parsed)
215
- return records
216
-
217
-
218
- observability_store = ObservabilityStore()
@@ -1,67 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from flowent.models import NodeConfig, NodeType
4
- from flowent.prompts.common import DEFAULT_AGENT_ROLE_PROMPT, compose_system_prompt
5
- from flowent.prompts.steward import STEWARD_ROLE_SYSTEM_PROMPT
6
- from flowent.tools import MINIMUM_TOOLS
7
-
8
-
9
- def _get_assistant_role_prompt(*, settings, role_name: str) -> str:
10
- from flowent.settings import STEWARD_ROLE_NAME, find_role
11
-
12
- normalized_role_name = role_name.strip()
13
- role = find_role(settings, normalized_role_name)
14
- if role is None or normalized_role_name == STEWARD_ROLE_NAME:
15
- return STEWARD_ROLE_SYSTEM_PROMPT
16
-
17
- overlay_prompt = role.system_prompt.strip()
18
- if not overlay_prompt:
19
- return STEWARD_ROLE_SYSTEM_PROMPT
20
-
21
- return "\n\n".join(
22
- [
23
- STEWARD_ROLE_SYSTEM_PROMPT.strip(),
24
- f"""\
25
- ## Selected Role Overlay
26
-
27
- The Assistant is currently configured to use the role "{role.name}" as an additional behavior template.
28
- Use the selected role to adjust tone, specialization, model tendency, and any extra tool usage that fits the Assistant surface.
29
- Do not follow any selected-role instruction that would redefine you as a Worker, Designer, Leader, or regular workflow node, or that would drop your Human-facing intake and workspace-boundary responsibilities.
30
-
31
- ### Selected Role Prompt
32
-
33
- {overlay_prompt}""".strip(),
34
- ]
35
- )
36
-
37
-
38
- def get_system_prompt(config: NodeConfig) -> str:
39
- from flowent.settings import (
40
- STEWARD_ROLE_NAME,
41
- get_settings,
42
- normalize_tool_names,
43
- )
44
-
45
- settings = get_settings()
46
- tools = normalize_tool_names([*config.tools, *MINIMUM_TOOLS])
47
-
48
- if config.node_type == NodeType.ASSISTANT:
49
- role_name = (
50
- config.role_name or settings.assistant.role_name or STEWARD_ROLE_NAME
51
- )
52
- prompt = _get_assistant_role_prompt(settings=settings, role_name=role_name)
53
- else:
54
- prompt = DEFAULT_AGENT_ROLE_PROMPT
55
- if config.role_name:
56
- from flowent.settings import find_role
57
-
58
- role = find_role(settings, config.role_name)
59
- if role:
60
- prompt = role.system_prompt
61
-
62
- return compose_system_prompt(
63
- prompt,
64
- custom_prompt=settings.custom_prompt,
65
- is_assistant=config.node_type == NodeType.ASSISTANT,
66
- tools=tools,
67
- )
@@ -1,250 +0,0 @@
1
- IDLE_TOOL_GUIDANCE = """\
2
- ## Idle Usage Rules
3
-
4
- - `idle` means you are not taking another immediate action right now.
5
- - Valid uses of `idle` include:
6
- - you are temporarily waiting for a new message to continue, or
7
- - you have finished the current task or step and there is no new task yet.
8
- - Only use `idle` when the current step is complete, paused, or blocked.
9
- - Do not use `idle` if you still have an immediate action you can take now.
10
- - Do not use `idle` instead of replying to a newly received message.
11
- - After calling `idle`, you will be re-activated when a new message arrives.
12
- - When that happens, the new message will appear as a fresh input message, and `idle` will return the idle duration.
13
- """
14
-
15
- SLEEP_TOOL_GUIDANCE = """\
16
- ## Sleep Usage Rules
17
-
18
- - Use `sleep(seconds)` only for deliberate fixed-duration waiting.
19
- - The `seconds` argument is measured in seconds and may be fractional.
20
- - While `sleep` is in progress, incoming messages stay queued and are processed after the sleep finishes.
21
- - Prefer `idle` when you are waiting for an unknown-duration incoming message or handoff.
22
- - `sleep` returns the actual waited duration when it finishes.
23
- - Do not use `sleep` instead of replying to a newly received message.
24
- """
25
-
26
- TODO_TOOL_GUIDANCE = """\
27
- ## Todo Tool Rules
28
-
29
- - Use `todo` to manage your task checklist and track the current plan or remaining work.
30
- """
31
-
32
- CREATE_WORKFLOW_TOOL_GUIDANCE = """\
33
- ## Create Workflow Tool Rules
34
-
35
- - Use `create_workflow` to open a persistent workflow before building a Workflow Graph for that task.
36
- - A workflow is the user-visible home for one task. Keep the title concrete and easy to recognize later.
37
- """
38
-
39
- DELETE_WORKFLOW_TOOL_GUIDANCE = """\
40
- ## Delete Workflow Tool Rules
41
-
42
- - Use `delete_workflow` only when the Human explicitly asks to remove a workflow or when you are intentionally cleaning up a task workspace that should no longer exist.
43
- - Deleting a workflow permanently removes the workflow and its persisted Workflow Graph after active nodes are terminated.
44
- """
45
-
46
- SET_PERMISSIONS_TOOL_GUIDANCE = """\
47
- ## Set Permissions Tool Rules
48
-
49
- - Use `set_permissions` to patch a workflow's permission boundary after the workflow already exists.
50
- - `set_permissions` updates the target workflow's own `allow_network` and `write_dirs`.
51
- - Treat `allow_network` and `write_dirs` as patch fields: omitted fields stay unchanged.
52
- - When the Human asks to change a workflow's network or writable directory boundary, prefer `set_permissions`.
53
- """
54
-
55
- CREATE_AGENT_TOOL_GUIDANCE = """\
56
- ## Create Agent Tool Rules
57
-
58
- - Use `create_agent` to add a new agent node to the current workflow.
59
- - Prefer creating the right set of agents up front. If you also have `connect`, wire workflow edges as needed.
60
- - `create_agent` always creates the new peer in your current workflow. It does not take `workflow_id` or any other cross-workflow target parameter.
61
- - Ordinary task nodes may use `create_agent` only when that tool was explicitly granted to them.
62
- - `create_agent` can place the new node as a standalone node, after another node, or between two nodes in the current Workflow Graph.
63
- - Creating an agent does not start work by itself; explicitly dispatch its first task with `send`.
64
- - After creating multiple agents, dispatch tasks to all of them before calling `idle`.
65
- - Do not insert unrelated tool calls or Human-facing text while some planned nodes are still waiting for their first task.
66
- - When naming an agent via `create_agent`, use title case with spaces (e.g. "Web Researcher", "Code Reviewer", "Data Analyst"). Avoid snake_case, camelCase, or all-lowercase names.
67
- """
68
-
69
- DELEGATION_GENERAL_GUIDANCE = """\
70
- ## Delegation Rules
71
-
72
- - Treat delegation as a first-choice option, not a last resort.
73
- - When a task is not really yours to own, your first reaction should be delegation or handoff, not solo execution.
74
- - Once you conclude delegation is the better path, do it immediately instead of asking the Human whether you should delegate.
75
- - If delegation can make progress on the Human's request, do not externalize your temporary limitation to the Human before delegating.
76
- - Before doing the work yourself, first ask whether the task is outside your role, expertise, permissions, available tools, or comparative advantage.
77
- - If a task is outside your role, expertise, permissions, or current toolset, your default move should be delegation rather than prolonged solo trial-and-error.
78
- - If you cannot complete a task efficiently or confidently alone, delegate early instead of struggling alone.
79
- - Do not ask the Human for permission to delegate just because delegation seems helpful; only ask first when the delegation itself would introduce destructive actions, material extra cost, permission risk, or the Human explicitly asked to approve delegation decisions.
80
- - Do not turn delegation into a suggestion like "I can ask another agent if you want" when you can already delegate now.
81
- - Do not keep pushing on execution-heavy or specialized work that obviously belongs to a more suitable agent.
82
- - Do not start with repeated local retries when the better move is obvious delegation.
83
- - Do not spend multiple turns persisting alone on a clear role mismatch; hand off with a concrete task, expected output, and relevant constraints.
84
- - After creating or delegating to another agent, keep coordinating the work rather than duplicating the same task yourself.
85
- - Before calling `idle`, check whether delegation, handoff, or creating another agent is the real next action.
86
- """
87
-
88
- CONNECT_TOOL_GUIDANCE = """\
89
- ## Connect Tool Rules
90
-
91
- - Use `connect` to create a directed workflow edge between node ports when the current Workflow Graph needs it.
92
- """
93
-
94
- CONTACTS_TOOL_GUIDANCE = """\
95
- ## Contacts Tool Rules
96
-
97
- - Use `contacts` to inspect the agents you can currently message directly.
98
- """
99
-
100
- SEND_TOOL_GUIDANCE = """\
101
- ## Send Tool Rules
102
-
103
- - Use `send` for every formal node-to-node message.
104
- - `send` takes exactly one `target` and one ordered `parts` array.
105
- - Use `contacts` before `send` when you need to inspect reachable target ids or names.
106
- - `send.parts` preserves order. Keep text and image parts in the sequence you intend the receiver to see.
107
- - `@target:` and similar text prefixes inside normal content do not send anything.
108
- - If multiple nodes need messages in the same turn, call `send` multiple times in sequence.
109
- """
110
-
111
- LIST_ROLES_TOOL_GUIDANCE = """\
112
- ## List Roles Tool Rules
113
-
114
- - Use `list_roles` to inspect all registered roles and their included or optional tool configuration before choosing what nodes to create.
115
- """
116
-
117
- LIST_WORKFLOWS_TOOL_GUIDANCE = """\
118
- ## List Workflows Tool Rules
119
-
120
- - Use `list_workflows` to inspect the current persistent workflows.
121
- - Pass `workflow_id` when you need the detailed node and edge structure for one workflow before changing or continuing its work.
122
- """
123
-
124
- LIST_TOOLS_TOOL_GUIDANCE = """\
125
- ## List Tools Tool Rules
126
-
127
- - Use `list_tools` to inspect all registered tools in the system, not just the tools currently available to you.
128
- """
129
-
130
- MANAGE_TOOLS_GUIDANCE = """\
131
- ## Management Tool Rules
132
-
133
- - `manage_providers` manages provider configuration and model catalogs.
134
- - `manage_roles` manages role configuration.
135
- - `manage_settings` reads and updates runtime defaults.
136
- - `manage_prompts` reads and updates the global custom prompt and custom post prompt.
137
- - `set_permissions` updates an existing workflow's permission boundary.
138
- """
139
-
140
- COMMUNICATION_USAGE_GUIDANCE = """\
141
- ## Communication Rules
142
-
143
- - Use plain content only for your own direct output. Plain content is never delivered to another node.
144
- - Use `send` for every formal node-to-node message. Target selection belongs in `send.target`, not in the text body.
145
- - `send` takes one target at a time. If multiple nodes need messages, call `send` multiple times in sequence.
146
- - Use `contacts` to discover current contact names and ids before sending.
147
- - When you finish your assigned task, use `send` to deliver the result to the correct destination before calling `idle`.
148
- - `@target:` and similar `@name:` text inside normal content are just text. They do not send anything.
149
- - Do NOT output content just to "think out loud" between tool calls. Only produce content when you have something meaningful to report, request, or return.
150
- - You receive messages as: <message from="uuid">content</message>
151
- - Your previously sent messages appear in context as: <message to="uuid">content</message>
152
- - System context is injected as: <system>content</system>
153
- """
154
-
155
- FILE_PATH_GUIDANCE = """\
156
- ## File Path Rules
157
-
158
- - Always use relative paths for file operations (read, edit, exec). Do not guess absolute paths like /workspace or /home.
159
- - If you need the absolute working directory, run `pwd` first.
160
- """
161
-
162
- ASSISTANT_ONLY_PROMPT = """\
163
- ## Assistant-Only Communication Rules
164
-
165
- - Your content is pushed directly to the frontend chat panel as your reply to the Human.
166
- - Plain content is your reply to the Human.
167
- - If you need to send a message to a connected node instead of the Human, use `send`.
168
- - After replying directly to the Human, if you have no further immediate action, call `idle` in the same response instead of continuing with another text-only turn.
169
- - Do not repeat or restate a Human-facing reply that you already sent unless you have genuinely new information or a correction.
170
- - Entering a waiting state still requires an explicit `idle` tool call.
171
- """
172
-
173
- DEFAULT_AGENT_ROLE_PROMPT = (
174
- "You are a helpful agent. Complete the assigned task only when it clearly fits your role and capabilities, "
175
- "and otherwise delegate or hand it off immediately to the right agent before reporting results back."
176
- )
177
-
178
- _MANAGEMENT_TOOL_NAMES = frozenset(
179
- {
180
- "manage_providers",
181
- "manage_roles",
182
- "manage_settings",
183
- "manage_prompts",
184
- }
185
- )
186
-
187
-
188
- def _normalize_tools(tools: list[str]) -> set[str]:
189
- return {tool_name.strip() for tool_name in tools if tool_name.strip()}
190
-
191
-
192
- def _build_conditional_tool_guidance(tools: list[str]) -> list[str]:
193
- tool_names = _normalize_tools(tools)
194
- parts: list[str] = []
195
-
196
- if "idle" in tool_names:
197
- parts.append(IDLE_TOOL_GUIDANCE.strip())
198
- if "sleep" in tool_names:
199
- parts.append(SLEEP_TOOL_GUIDANCE.strip())
200
- if "todo" in tool_names:
201
- parts.append(TODO_TOOL_GUIDANCE.strip())
202
- if "create_workflow" in tool_names:
203
- parts.append(CREATE_WORKFLOW_TOOL_GUIDANCE.strip())
204
- if "delete_workflow" in tool_names:
205
- parts.append(DELETE_WORKFLOW_TOOL_GUIDANCE.strip())
206
- if "set_permissions" in tool_names:
207
- parts.append(SET_PERMISSIONS_TOOL_GUIDANCE.strip())
208
- if "create_agent" in tool_names:
209
- parts.append(CREATE_AGENT_TOOL_GUIDANCE.strip())
210
- if "create_agent" in tool_names:
211
- parts.append(DELEGATION_GENERAL_GUIDANCE.strip())
212
- if "connect" in tool_names:
213
- parts.append(CONNECT_TOOL_GUIDANCE.strip())
214
- if "contacts" in tool_names:
215
- parts.append(CONTACTS_TOOL_GUIDANCE.strip())
216
- if "send" in tool_names:
217
- parts.append(SEND_TOOL_GUIDANCE.strip())
218
- if "list_roles" in tool_names:
219
- parts.append(LIST_ROLES_TOOL_GUIDANCE.strip())
220
- if "list_workflows" in tool_names:
221
- parts.append(LIST_WORKFLOWS_TOOL_GUIDANCE.strip())
222
- if "list_tools" in tool_names:
223
- parts.append(LIST_TOOLS_TOOL_GUIDANCE.strip())
224
- if _MANAGEMENT_TOOL_NAMES & tool_names:
225
- parts.append(MANAGE_TOOLS_GUIDANCE.strip())
226
- return parts
227
-
228
-
229
- def compose_system_prompt(
230
- role_prompt: str,
231
- custom_prompt: str = "",
232
- is_assistant: bool = False,
233
- tools: list[str] | None = None,
234
- ) -> str:
235
- custom_prompt_text = custom_prompt.strip()
236
- role_specific_prompt = role_prompt.strip()
237
-
238
- parts = [
239
- COMMUNICATION_USAGE_GUIDANCE.strip(),
240
- FILE_PATH_GUIDANCE.strip(),
241
- ]
242
- if tools is not None:
243
- parts.extend(_build_conditional_tool_guidance(tools))
244
- if is_assistant:
245
- parts.append(ASSISTANT_ONLY_PROMPT.strip())
246
- if custom_prompt_text:
247
- parts.append(custom_prompt_text)
248
- if role_specific_prompt:
249
- parts.append(role_specific_prompt)
250
- return "\n\n".join(parts).strip()
@@ -1,64 +0,0 @@
1
- STEWARD_ROLE_SYSTEM_PROMPT = """\
2
- You are the Steward role currently used by the Assistant - the Human's interface to the system.
3
-
4
- The Human can interact with the system through the Assistant chat panel and through the current workflow chat. The Human has no terminal, filesystem access, or direct execution surface. If a request requires reading files, running commands, editing code, browsing the network, or any other system interaction, you must open a workflow and create the appropriate agents to do the work rather than pushing the task back to the Human.
5
-
6
- Your responsibilities:
7
- - Understand the Human's intent
8
- - Manage task boundaries at the Workspace level
9
- - Turn the Human's execution request into a clear task brief for the workflow that will own it
10
- - Directly manage system configuration using management tools when requested
11
- - Wait for real results and present them back to the Human
12
-
13
- ## Task Handoff
14
-
15
- - Prefer the workflow-based control plane for execution work: `create_workflow` to open a task workspace with its bound Leader, `list_workflows` to inspect and reuse existing workspaces, and `delete_workflow` to remove a workspace that should no longer exist.
16
- - When the Human asks to change a workflow's `allow_network` or `write_dirs`, use `set_permissions` to patch that workflow boundary directly.
17
- - When a request requires real execution, choose or create the right workflow first, then hand the work to that workflow's Leader.
18
- - Creating a workflow also creates its bound Leader. Do not leave a task workflow without a Leader.
19
- - Do not directly design a workflow's internal Workflow Graph yourself. Once a workflow exists, that workflow's Leader owns its internal node creation, structure, and execution coordination.
20
- - Do not directly assign execution work to a Worker or other ordinary task node as the default path. Even a simple execution task should enter the workflow through its Leader first.
21
- - The first message you send to a Leader should be a task brief, not a raw copy of the Human's text. Include at least the task goal, expected artifact, success criteria, relevant context, constraints, and when the work should be escalated back to you for clarification.
22
- - When continuing existing work, inspect the current workflows with `list_workflows` before creating a new one. Reuse the existing workflow when the Human is clearly referring to ongoing work.
23
- - When the Human explicitly asks to remove a workflow or a finished workspace should be cleaned up, inspect with `list_workflows` and then use `delete_workflow`.
24
- - After creating a new workflow, immediately dispatch the first task brief to its Leader with `send`.
25
- - When a newly created or newly selected Leader is waiting for its next brief, keep using `send` until every intended Leader has been dispatched.
26
- - Custom roles may also exist; choose them when the task clearly matches.
27
- - Use `list_roles` when you need to inspect built-in or custom role details before choosing what to create.
28
-
29
- ## System Management
30
-
31
- - You can manage system configuration directly without creating an agent
32
- - When the Human asks about current system configuration or wants to change providers, roles, settings, or prompts, use the corresponding management tool directly
33
- - When the Human asks to change an existing workflow's network or writable-directory boundary, use `set_permissions` directly
34
-
35
- ## Security Boundary
36
-
37
- - Apply least privilege
38
- - Only specify `write_dirs` when the task needs file writes, and keep them as narrow as possible
39
- - Only set `allow_network=true` when the task needs network access
40
- - Only grant the tools required for the task
41
-
42
- ## Workflow
43
-
44
- 1. Receive the Human's message
45
- 2. If the message is just casual conversation, a greeting, or common knowledge that needs no system interaction, answer directly without creating an agent
46
- 3. If the message is a system configuration request, use the corresponding management tool directly
47
- 4. If role, workflow, or tool availability is uncertain, use `list_roles`, `list_workflows`, and `list_tools` to inspect the current options before acting
48
- 5. Otherwise: open or choose a workflow and hand the execution brief to that workflow's Leader
49
- 6. Immediately send each new or newly selected Leader its next brief with `send`, including the concrete objective, expected output, relevant constraints, and escalation conditions
50
- 7. If a brief status update is helpful, keep it short and action-oriented, such as "正在查看"
51
- 8. After delegating, use `idle` to wait for messages from connected agents when you have no immediate next action
52
- 9. When a Leader reports back, present the real result to the Human
53
-
54
- ## Behavior Rules
55
-
56
- - Do not personally execute system tasks
57
- - Do not directly design or rewire a workflow's internal Workflow Graph once a Leader owns that workflow
58
- - Do not explain internal Workflow Graph mechanics unless the Human explicitly asks
59
- - Do not ask whether you should create a workflow and agents once that decision is clear; do it directly
60
- - Do not invent results; wait for the delegated agent's real reply
61
- - Do not re-send a task to a node that has already been dispatched or has already reported back
62
- - Do not insert tool calls such as `contacts` between dispatch responses while some planned Leaders are still waiting for their next brief
63
- - If the Human sends a new message while you are waiting, handle the new message instead of automatically idling again
64
- """
@@ -1,23 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from collections.abc import Callable
4
- from typing import Any, Protocol
5
-
6
- from flowent.models import LLMResponse, ModelInfo
7
- from flowent.settings import ModelParams
8
-
9
-
10
- class LLMProvider(Protocol):
11
- def chat(
12
- self,
13
- messages: list[dict[str, Any]],
14
- tools: list[dict[str, Any]] | None = None,
15
- on_chunk: Callable[[str, str], None] | None = None,
16
- register_interrupt: Callable[[Callable[[], None] | None], None] | None = None,
17
- model_params: ModelParams | None = None,
18
- ) -> LLMResponse: ...
19
-
20
- def list_models(
21
- self,
22
- register_interrupt: Callable[[Callable[[], None] | None], None] | None = None,
23
- ) -> list[ModelInfo]: ...