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,44 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
-
5
- from flowent.models.base import Serializable
6
-
7
-
8
- @dataclass
9
- class ContentDelta(Serializable):
10
- text: str
11
-
12
-
13
- @dataclass
14
- class ThinkingDelta(Serializable):
15
- text: str
16
-
17
-
18
- @dataclass
19
- class ToolResultDelta(Serializable):
20
- tool_call_id: str
21
- text: str
22
-
23
-
24
- @dataclass
25
- class SentMessageDelta(Serializable):
26
- message_id: str
27
- to_id: str
28
- text: str
29
-
30
-
31
- @dataclass
32
- class ReceivedMessageDelta(Serializable):
33
- message_id: str
34
- from_id: str
35
- text: str
36
-
37
-
38
- StreamingDelta = (
39
- ContentDelta
40
- | ThinkingDelta
41
- | ToolResultDelta
42
- | SentMessageDelta
43
- | ReceivedMessageDelta
44
- )
@@ -1,51 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import time
4
- from dataclasses import dataclass, field
5
- from enum import StrEnum
6
- from typing import Any
7
-
8
-
9
- class EventType(StrEnum):
10
- TAB_CREATED = "tab_created"
11
- TAB_UPDATED = "tab_updated"
12
- TAB_DELETED = "tab_deleted"
13
- NODE_CREATED = "node_created"
14
- NODE_STATE_CHANGED = "node_state_changed"
15
- NODE_TODOS_CHANGED = "node_todos_changed"
16
- NODE_MESSAGE = "node_message"
17
- NODE_TERMINATED = "node_terminated"
18
- NODE_DELETED = "node_deleted"
19
- NODE_CONNECTED = "node_connected"
20
- NODE_DISCONNECTED = "node_disconnected"
21
- ASSISTANT_CONTENT = "assistant_content"
22
- TOOL_CALLED = "tool_called"
23
- HISTORY_CLEARED = "history_cleared"
24
- HISTORY_REPLACED = "history_replaced"
25
- HISTORY_ENTRY_ADDED = "history_entry_added"
26
- HISTORY_ENTRY_DELTA = "history_entry_delta"
27
-
28
-
29
- DISPLAY_EVENTS: set[EventType] = {
30
- EventType.TAB_CREATED,
31
- EventType.TAB_UPDATED,
32
- EventType.TAB_DELETED,
33
- EventType.NODE_CREATED,
34
- EventType.NODE_STATE_CHANGED,
35
- EventType.NODE_TODOS_CHANGED,
36
- EventType.NODE_MESSAGE,
37
- EventType.NODE_TERMINATED,
38
- EventType.NODE_DELETED,
39
- EventType.NODE_CONNECTED,
40
- EventType.NODE_DISCONNECTED,
41
- EventType.ASSISTANT_CONTENT,
42
- EventType.TOOL_CALLED,
43
- }
44
-
45
-
46
- @dataclass
47
- class Event:
48
- type: EventType
49
- agent_id: str
50
- data: dict[str, Any] = field(default_factory=dict)
51
- timestamp: float = field(default_factory=time.time)
@@ -1,472 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import time
4
- from dataclasses import dataclass, field
5
- from enum import StrEnum
6
-
7
- from flowent.models.agent import AgentState, NodeConfig, NodeType
8
- from flowent.models.history import HistoryEntry, deserialize_history_entries
9
- from flowent.models.todo import TodoItem
10
-
11
-
12
- class WorkflowNodeKind(StrEnum):
13
- TRIGGER = "trigger"
14
- LLM = "llm"
15
- AGENT = "agent"
16
- CODE = "code"
17
- IF = "if"
18
- MERGE = "merge"
19
-
20
-
21
- class PortDirection(StrEnum):
22
- INPUT = "in"
23
- OUTPUT = "out"
24
-
25
-
26
- class PortType(StrEnum):
27
- PARTS = "parts"
28
- STRING = "string"
29
- JSON = "json"
30
-
31
-
32
- class EdgeKind(StrEnum):
33
- CONTROL = "control"
34
- DATA = "data"
35
- EVENT = "event"
36
-
37
-
38
- class WorkflowActivationState(StrEnum):
39
- INACTIVE = "inactive"
40
- ACTIVE = "active"
41
-
42
-
43
- def _parse_port_direction(raw_direction: object) -> PortDirection:
44
- if raw_direction == "input":
45
- return PortDirection.INPUT
46
- if raw_direction == "output":
47
- return PortDirection.OUTPUT
48
- return PortDirection(str(raw_direction))
49
-
50
-
51
- def _port_type_from_legacy_kind(raw_kind: object) -> PortType | None:
52
- try:
53
- kind = EdgeKind(str(raw_kind))
54
- except ValueError:
55
- return None
56
- if kind == EdgeKind.DATA:
57
- return PortType.JSON
58
- return PortType.PARTS
59
-
60
-
61
- @dataclass
62
- class NodePosition:
63
- x: float
64
- y: float
65
-
66
- def serialize(self) -> dict[str, float]:
67
- return {"x": self.x, "y": self.y}
68
-
69
- @classmethod
70
- def from_mapping(cls, data: dict[str, object] | None) -> NodePosition | None:
71
- if not isinstance(data, dict):
72
- return None
73
- x = data.get("x")
74
- y = data.get("y")
75
- if not isinstance(x, (int, float)) or not isinstance(y, (int, float)):
76
- return None
77
- return cls(x=float(x), y=float(y))
78
-
79
-
80
- @dataclass
81
- class WorkflowPort:
82
- key: str
83
- direction: PortDirection
84
- type: PortType
85
- required: bool = False
86
- multiple: bool = False
87
-
88
- def serialize(self) -> dict[str, object]:
89
- return {
90
- "key": self.key,
91
- "direction": self.direction.value,
92
- "type": self.type.value,
93
- "required": self.required,
94
- "multiple": self.multiple,
95
- }
96
-
97
- @classmethod
98
- def from_mapping(cls, data: dict[str, object]) -> WorkflowPort | None:
99
- key = data.get("key")
100
- direction = data.get("direction")
101
- port_type = data.get("type")
102
- if not isinstance(key, str) or not key.strip():
103
- return None
104
- try:
105
- parsed_direction = _parse_port_direction(direction)
106
- except ValueError:
107
- return None
108
- try:
109
- parsed_type = PortType(str(port_type))
110
- except ValueError:
111
- legacy_type = _port_type_from_legacy_kind(data.get("kind"))
112
- if legacy_type is None:
113
- return None
114
- parsed_type = legacy_type
115
- return cls(
116
- key=key.strip(),
117
- direction=parsed_direction,
118
- type=parsed_type,
119
- required=bool(data.get("required", False)),
120
- multiple=bool(data.get("multiple", False)),
121
- )
122
-
123
-
124
- @dataclass
125
- class GraphEdge:
126
- id: str
127
- from_node_id: str
128
- from_port_key: str
129
- to_node_id: str
130
- to_port_key: str
131
- kind: EdgeKind = EdgeKind.CONTROL
132
- tab_id: str | None = None
133
- created_at: float = field(default_factory=time.time)
134
-
135
- def serialize(self) -> dict[str, object]:
136
- payload: dict[str, object] = {
137
- "id": self.id,
138
- "from_node_id": self.from_node_id,
139
- "from_port_key": self.from_port_key,
140
- "to_node_id": self.to_node_id,
141
- "to_port_key": self.to_port_key,
142
- "created_at": self.created_at,
143
- }
144
- if self.tab_id is not None:
145
- payload["tab_id"] = self.tab_id
146
- return payload
147
-
148
- @classmethod
149
- def from_mapping(cls, data: dict[str, object]) -> GraphEdge:
150
- created_at = data.get("created_at")
151
- kind = data.get("kind")
152
- try:
153
- parsed_kind = EdgeKind(str(kind))
154
- except ValueError:
155
- parsed_kind = EdgeKind.CONTROL
156
- from_port_key = data.get("from_port_key")
157
- to_port_key = data.get("to_port_key")
158
- return cls(
159
- id=str(data.get("id", "")),
160
- tab_id=str(data["tab_id"]) if isinstance(data.get("tab_id"), str) else None,
161
- from_node_id=str(data.get("from_node_id", "")),
162
- from_port_key=(
163
- str(from_port_key)
164
- if isinstance(from_port_key, str) and from_port_key.strip()
165
- else "out"
166
- ),
167
- to_node_id=str(data.get("to_node_id", "")),
168
- to_port_key=(
169
- str(to_port_key)
170
- if isinstance(to_port_key, str) and to_port_key.strip()
171
- else "in"
172
- ),
173
- kind=parsed_kind,
174
- created_at=created_at
175
- if isinstance(created_at, (int, float))
176
- else time.time(),
177
- )
178
-
179
-
180
- @dataclass
181
- class WorkflowNodeDefinition:
182
- id: str
183
- type: WorkflowNodeKind
184
- config: dict[str, object] = field(default_factory=dict)
185
- inputs: list[WorkflowPort] = field(default_factory=list)
186
- outputs: list[WorkflowPort] = field(default_factory=list)
187
-
188
- def serialize(self) -> dict[str, object]:
189
- return {
190
- "id": self.id,
191
- "type": self.type.value,
192
- "config": dict(self.config),
193
- "inputs": [port.serialize() for port in self.inputs],
194
- "outputs": [port.serialize() for port in self.outputs],
195
- }
196
-
197
- @classmethod
198
- def from_mapping(
199
- cls,
200
- data: dict[str, object],
201
- ) -> WorkflowNodeDefinition | None:
202
- node_id = data.get("id")
203
- node_type = data.get("type")
204
- if not isinstance(node_id, str) or not node_id.strip():
205
- return None
206
- try:
207
- parsed_type = WorkflowNodeKind(str(node_type))
208
- except ValueError:
209
- return None
210
- raw_config = data.get("config")
211
- raw_inputs = data.get("inputs")
212
- raw_outputs = data.get("outputs")
213
- return cls(
214
- id=node_id.strip(),
215
- type=parsed_type,
216
- config=dict(raw_config) if isinstance(raw_config, dict) else {},
217
- inputs=[
218
- port
219
- for port in (
220
- WorkflowPort.from_mapping(item)
221
- for item in (raw_inputs if isinstance(raw_inputs, list) else [])
222
- if isinstance(item, dict)
223
- )
224
- if port is not None
225
- ],
226
- outputs=[
227
- port
228
- for port in (
229
- WorkflowPort.from_mapping(item)
230
- for item in (raw_outputs if isinstance(raw_outputs, list) else [])
231
- if isinstance(item, dict)
232
- )
233
- if port is not None
234
- ],
235
- )
236
-
237
-
238
- @dataclass
239
- class WorkflowViewDefinition:
240
- positions: dict[str, NodePosition] = field(default_factory=dict)
241
-
242
- def serialize(self) -> dict[str, object]:
243
- if not self.positions:
244
- return {}
245
- return {
246
- "positions": {
247
- node_id: position.serialize()
248
- for node_id, position in self.positions.items()
249
- }
250
- }
251
-
252
- @classmethod
253
- def from_mapping(cls, data: dict[str, object] | None) -> WorkflowViewDefinition:
254
- if not isinstance(data, dict):
255
- return cls()
256
- raw_positions = data.get("positions")
257
- if not isinstance(raw_positions, dict):
258
- return cls()
259
- positions = {
260
- str(node_id): position
261
- for node_id, position in (
262
- (
263
- node_id,
264
- NodePosition.from_mapping(payload),
265
- )
266
- for node_id, payload in raw_positions.items()
267
- if isinstance(node_id, str) and isinstance(payload, dict)
268
- )
269
- if position is not None
270
- }
271
- return cls(positions=positions)
272
-
273
-
274
- @dataclass
275
- class WorkflowDefinition:
276
- version: int = 1
277
- nodes: list[WorkflowNodeDefinition] = field(default_factory=list)
278
- edges: list[GraphEdge] = field(default_factory=list)
279
- view: WorkflowViewDefinition = field(default_factory=WorkflowViewDefinition)
280
-
281
- def serialize(self) -> dict[str, object]:
282
- payload: dict[str, object] = {
283
- "version": self.version,
284
- "nodes": [node.serialize() for node in self.nodes],
285
- "edges": [edge.serialize() for edge in self.edges],
286
- }
287
- serialized_view = self.view.serialize()
288
- if serialized_view:
289
- payload["view"] = serialized_view
290
- return payload
291
-
292
- @classmethod
293
- def from_mapping(cls, data: dict[str, object] | None) -> WorkflowDefinition:
294
- if not isinstance(data, dict):
295
- return cls()
296
- raw_version = data.get("version")
297
- raw_nodes = data.get("nodes")
298
- raw_edges = data.get("edges")
299
- raw_view = data.get("view")
300
- return cls(
301
- version=raw_version
302
- if isinstance(raw_version, int) and raw_version > 0
303
- else 1,
304
- nodes=[
305
- node
306
- for node in (
307
- WorkflowNodeDefinition.from_mapping(item)
308
- for item in (raw_nodes if isinstance(raw_nodes, list) else [])
309
- if isinstance(item, dict)
310
- )
311
- if node is not None
312
- ],
313
- edges=[
314
- GraphEdge.from_mapping(item)
315
- for item in (raw_edges if isinstance(raw_edges, list) else [])
316
- if isinstance(item, dict)
317
- ],
318
- view=WorkflowViewDefinition.from_mapping(
319
- raw_view if isinstance(raw_view, dict) else None
320
- ),
321
- )
322
-
323
- def get_node(self, node_id: str) -> WorkflowNodeDefinition | None:
324
- return next((node for node in self.nodes if node.id == node_id), None)
325
-
326
-
327
- @dataclass
328
- class GraphNodeRecord:
329
- id: str
330
- config: NodeConfig
331
- state: AgentState
332
- todos: list[TodoItem] = field(default_factory=list)
333
- history: list[HistoryEntry] = field(default_factory=list)
334
- execution_context_summary: str = ""
335
- execution_context_history_cutoff: int = 0
336
- position: NodePosition | None = None
337
- created_at: float = field(default_factory=time.time)
338
- updated_at: float = field(default_factory=time.time)
339
-
340
- def serialize(self) -> dict[str, object]:
341
- return {
342
- "id": self.id,
343
- "config": {
344
- "node_type": self.config.node_type.value,
345
- "role_name": self.config.role_name,
346
- "tab_id": self.config.tab_id,
347
- "name": self.config.name,
348
- "tools": list(self.config.tools),
349
- "write_dirs": list(self.config.write_dirs),
350
- "allow_network": self.config.allow_network,
351
- },
352
- "state": self.state.value,
353
- "todos": [item.serialize() for item in self.todos],
354
- "history": [entry.serialize() for entry in self.history],
355
- "execution_context_summary": self.execution_context_summary,
356
- "execution_context_history_cutoff": self.execution_context_history_cutoff,
357
- "position": self.position.serialize()
358
- if self.position is not None
359
- else None,
360
- "created_at": self.created_at,
361
- "updated_at": self.updated_at,
362
- }
363
-
364
- @classmethod
365
- def from_mapping(cls, data: dict[str, object]) -> GraphNodeRecord:
366
- from flowent.settings import (
367
- build_assistant_write_dirs,
368
- normalize_tool_names,
369
- )
370
-
371
- raw_config = data.get("config")
372
- config = raw_config if isinstance(raw_config, dict) else {}
373
- raw_todos = data.get("todos")
374
- raw_history = data.get("history")
375
- raw_execution_context_summary = data.get("execution_context_summary")
376
- raw_execution_context_history_cutoff = data.get(
377
- "execution_context_history_cutoff"
378
- )
379
- created_at = data.get("created_at")
380
- updated_at = data.get("updated_at")
381
- raw_state = data.get("state")
382
-
383
- node_type = config.get("node_type")
384
- try:
385
- parsed_node_type = NodeType(str(node_type))
386
- except ValueError:
387
- parsed_node_type = NodeType.AGENT
388
-
389
- try:
390
- state = AgentState(str(raw_state))
391
- except ValueError:
392
- state = AgentState.INITIALIZING
393
-
394
- todos = []
395
- if isinstance(raw_todos, list):
396
- todos = [
397
- TodoItem(text=str(item.get("text", "")))
398
- for item in raw_todos
399
- if isinstance(item, dict)
400
- ]
401
-
402
- history_items: list[HistoryEntry] = []
403
- if isinstance(raw_history, list):
404
- history_items = deserialize_history_entries(
405
- [item for item in raw_history if isinstance(item, dict)]
406
- )
407
- raw_position = data.get("position")
408
-
409
- raw_write_dirs = (
410
- [
411
- str(item)
412
- for item in config.get("write_dirs", [])
413
- if isinstance(item, str)
414
- ]
415
- if isinstance(config.get("write_dirs"), list)
416
- else []
417
- )
418
-
419
- return cls(
420
- id=str(data.get("id", "")),
421
- config=NodeConfig(
422
- node_type=parsed_node_type,
423
- role_name=(
424
- str(config["role_name"])
425
- if isinstance(config.get("role_name"), str)
426
- else None
427
- ),
428
- tab_id=str(config["tab_id"])
429
- if isinstance(config.get("tab_id"), str)
430
- else None,
431
- name=str(config["name"])
432
- if isinstance(config.get("name"), str)
433
- else None,
434
- tools=normalize_tool_names(
435
- [
436
- str(item)
437
- for item in config.get("tools", [])
438
- if isinstance(item, str)
439
- ]
440
- if isinstance(config.get("tools"), list)
441
- else []
442
- ),
443
- write_dirs=build_assistant_write_dirs(
444
- raw_write_dirs,
445
- field_name="write_dirs",
446
- ),
447
- allow_network=bool(config.get("allow_network", False)),
448
- ),
449
- state=state,
450
- todos=todos,
451
- history=history_items,
452
- execution_context_summary=(
453
- str(raw_execution_context_summary)
454
- if isinstance(raw_execution_context_summary, str)
455
- else ""
456
- ),
457
- execution_context_history_cutoff=(
458
- raw_execution_context_history_cutoff
459
- if isinstance(raw_execution_context_history_cutoff, int)
460
- and raw_execution_context_history_cutoff >= 0
461
- else 0
462
- ),
463
- position=NodePosition.from_mapping(
464
- raw_position if isinstance(raw_position, dict) else None
465
- ),
466
- created_at=created_at
467
- if isinstance(created_at, (int, float))
468
- else time.time(),
469
- updated_at=updated_at
470
- if isinstance(updated_at, (int, float))
471
- else time.time(),
472
- )