flowent 0.0.6 → 0.0.7

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 (265) hide show
  1. package/README.md +1 -1
  2. package/backend/README.md +1 -1
  3. package/backend/pyproject.toml +1 -1
  4. package/backend/src/flowent/__pycache__/__init__.cpython-313.pyc +0 -0
  5. package/backend/src/flowent/__pycache__/_version.cpython-313.pyc +0 -0
  6. package/backend/src/flowent/__pycache__/access.cpython-313.pyc +0 -0
  7. package/backend/src/flowent/__pycache__/agent.cpython-313.pyc +0 -0
  8. package/backend/src/flowent/__pycache__/assistant_commands.cpython-313.pyc +0 -0
  9. package/backend/src/flowent/__pycache__/cli.cpython-313.pyc +0 -0
  10. package/backend/src/flowent/__pycache__/config.cpython-313.pyc +0 -0
  11. package/backend/src/flowent/__pycache__/events.cpython-313.pyc +0 -0
  12. package/backend/src/flowent/__pycache__/graph_runtime.cpython-313.pyc +0 -0
  13. package/backend/src/flowent/__pycache__/graph_service.cpython-313.pyc +0 -0
  14. package/backend/src/flowent/__pycache__/image_assets.cpython-313.pyc +0 -0
  15. package/backend/src/flowent/__pycache__/logging.cpython-313.pyc +0 -0
  16. package/backend/src/flowent/__pycache__/main.cpython-313.pyc +0 -0
  17. package/backend/src/flowent/__pycache__/model_metadata.cpython-313.pyc +0 -0
  18. package/backend/src/flowent/__pycache__/network.cpython-313.pyc +0 -0
  19. package/backend/src/flowent/__pycache__/observability_service.cpython-313.pyc +0 -0
  20. package/backend/src/flowent/__pycache__/registry.cpython-313.pyc +0 -0
  21. package/backend/src/flowent/__pycache__/role_management.cpython-313.pyc +0 -0
  22. package/backend/src/flowent/__pycache__/runtime.cpython-313.pyc +0 -0
  23. package/backend/src/flowent/__pycache__/sandbox.cpython-313.pyc +0 -0
  24. package/backend/src/flowent/__pycache__/security.cpython-313.pyc +0 -0
  25. package/backend/src/flowent/__pycache__/settings.cpython-313.pyc +0 -0
  26. package/backend/src/flowent/__pycache__/settings_management.cpython-313.pyc +0 -0
  27. package/backend/src/flowent/__pycache__/state_db.cpython-313.pyc +0 -0
  28. package/backend/src/flowent/__pycache__/workspace_store.cpython-313.pyc +0 -0
  29. package/backend/src/flowent/agent.py +91 -8
  30. package/backend/src/flowent/channels/__pycache__/__init__.cpython-313.pyc +0 -0
  31. package/backend/src/flowent/channels/__pycache__/telegram.cpython-313.pyc +0 -0
  32. package/backend/src/flowent/graph_service.py +3 -110
  33. package/backend/src/flowent/models/__pycache__/__init__.cpython-313.pyc +0 -0
  34. package/backend/src/flowent/models/__pycache__/agent.cpython-313.pyc +0 -0
  35. package/backend/src/flowent/models/__pycache__/base.cpython-313.pyc +0 -0
  36. package/backend/src/flowent/models/__pycache__/blueprint.cpython-313.pyc +0 -0
  37. package/backend/src/flowent/models/__pycache__/content.cpython-313.pyc +0 -0
  38. package/backend/src/flowent/models/__pycache__/delta.cpython-313.pyc +0 -0
  39. package/backend/src/flowent/models/__pycache__/event.cpython-313.pyc +0 -0
  40. package/backend/src/flowent/models/__pycache__/graph.cpython-313.pyc +0 -0
  41. package/backend/src/flowent/models/__pycache__/history.cpython-313.pyc +0 -0
  42. package/backend/src/flowent/models/__pycache__/llm.cpython-313.pyc +0 -0
  43. package/backend/src/flowent/models/__pycache__/message.cpython-313.pyc +0 -0
  44. package/backend/src/flowent/models/__pycache__/tab.cpython-313.pyc +0 -0
  45. package/backend/src/flowent/models/__pycache__/todo.cpython-313.pyc +0 -0
  46. package/backend/src/flowent/prompts/__pycache__/__init__.cpython-313.pyc +0 -0
  47. package/backend/src/flowent/prompts/__pycache__/common.cpython-313.pyc +0 -0
  48. package/backend/src/flowent/prompts/__pycache__/steward.cpython-313.pyc +0 -0
  49. package/backend/src/flowent/providers/__pycache__/__init__.cpython-313.pyc +0 -0
  50. package/backend/src/flowent/providers/__pycache__/anthropic.cpython-313.pyc +0 -0
  51. package/backend/src/flowent/providers/__pycache__/base_url.cpython-313.pyc +0 -0
  52. package/backend/src/flowent/providers/__pycache__/configuration.cpython-313.pyc +0 -0
  53. package/backend/src/flowent/providers/__pycache__/content.cpython-313.pyc +0 -0
  54. package/backend/src/flowent/providers/__pycache__/errors.cpython-313.pyc +0 -0
  55. package/backend/src/flowent/providers/__pycache__/gateway.cpython-313.pyc +0 -0
  56. package/backend/src/flowent/providers/__pycache__/headers.cpython-313.pyc +0 -0
  57. package/backend/src/flowent/providers/__pycache__/management.cpython-313.pyc +0 -0
  58. package/backend/src/flowent/providers/__pycache__/openai.cpython-313.pyc +0 -0
  59. package/backend/src/flowent/providers/__pycache__/openai_responses.cpython-313.pyc +0 -0
  60. package/backend/src/flowent/providers/__pycache__/registry.cpython-313.pyc +0 -0
  61. package/backend/src/flowent/providers/__pycache__/sse.cpython-313.pyc +0 -0
  62. package/backend/src/flowent/providers/__pycache__/thinking.cpython-313.pyc +0 -0
  63. package/backend/src/flowent/role_management.py +9 -6
  64. package/backend/src/flowent/routes/__init__.py +0 -2
  65. package/backend/src/flowent/routes/__pycache__/__init__.cpython-313.pyc +0 -0
  66. package/backend/src/flowent/routes/__pycache__/access.cpython-313.pyc +0 -0
  67. package/backend/src/flowent/routes/__pycache__/assistant.cpython-313.pyc +0 -0
  68. package/backend/src/flowent/routes/__pycache__/image_assets.cpython-313.pyc +0 -0
  69. package/backend/src/flowent/routes/__pycache__/meta.cpython-313.pyc +0 -0
  70. package/backend/src/flowent/routes/__pycache__/nodes.cpython-313.pyc +0 -0
  71. package/backend/src/flowent/routes/__pycache__/prompts.cpython-313.pyc +0 -0
  72. package/backend/src/flowent/routes/__pycache__/providers_route.cpython-313.pyc +0 -0
  73. package/backend/src/flowent/routes/__pycache__/roles.cpython-313.pyc +0 -0
  74. package/backend/src/flowent/routes/__pycache__/settings.cpython-313.pyc +0 -0
  75. package/backend/src/flowent/routes/__pycache__/tabs.cpython-313.pyc +0 -0
  76. package/backend/src/flowent/routes/__pycache__/ws.cpython-313.pyc +0 -0
  77. package/backend/src/flowent/routes/assistant.py +3 -0
  78. package/backend/src/flowent/routes/nodes.py +11 -1
  79. package/backend/src/flowent/routes/settings.py +169 -118
  80. package/backend/src/flowent/routes/tabs.py +0 -12
  81. package/backend/src/flowent/runtime.py +0 -5
  82. package/backend/src/flowent/security.py +1 -21
  83. package/backend/src/flowent/settings.py +15 -421
  84. package/backend/src/flowent/settings_management.py +260 -164
  85. package/backend/src/flowent/state_db.py +2 -14
  86. package/backend/src/flowent/static/assets/AssistantPage-BW7XAd9I.js +1 -0
  87. package/backend/src/flowent/static/assets/ChannelsPage-tCJHgt6m.js +1 -0
  88. package/backend/src/flowent/static/assets/{PageScaffold-DteOA8V7.js → PageScaffold-f6g2l7XN.js} +1 -1
  89. package/backend/src/flowent/static/assets/PromptsPage-C3Sxn2D7.js +1 -0
  90. package/backend/src/flowent/static/assets/ProvidersPage-BfmdXmNt.js +3 -0
  91. package/backend/src/flowent/static/assets/RolesPage-DET8wO4r.js +1 -0
  92. package/backend/src/flowent/static/assets/SettingsPage-D-g3deMm.js +3 -0
  93. package/backend/src/flowent/static/assets/ToolsPage-CDmtE2g4.js +1 -0
  94. package/backend/src/flowent/static/assets/WorkspacePage-AZsJ0sD0.js +3 -0
  95. package/backend/src/flowent/static/assets/WorkspacePanels-CteCjolX.js +1 -0
  96. package/backend/src/flowent/static/assets/{alert-dialog-DIBUCmqM.js → alert-dialog-Duorp_S-.js} +1 -1
  97. package/backend/src/flowent/static/assets/{dialog-BOvHIBrg.js → dialog-C3ixjGjN.js} +1 -1
  98. package/backend/src/flowent/static/assets/index--o_0fv0N.css +1 -0
  99. package/backend/src/flowent/static/assets/index-C9HuekJm.js +10 -0
  100. package/backend/src/flowent/static/assets/{modelParams-DcEhGnu0.js → modelParams-DmnF2hwR.js} +1 -1
  101. package/backend/src/flowent/static/assets/providerTypes-DT3Ahwl_.js +1 -0
  102. package/backend/src/flowent/static/assets/roles-CuRT_chR.js +1 -0
  103. package/{dist/frontend/assets/select-D9SwnlXF.js → backend/src/flowent/static/assets/select-DCfeNu-F.js} +1 -1
  104. package/backend/src/flowent/static/assets/surface-pWwG5ogx.js +1 -0
  105. package/backend/src/flowent/static/assets/{ui-vendor-UazN8rcv.js → ui-vendor-C5pJa8N7.js} +15 -15
  106. package/backend/src/flowent/static/assets/useAppRoute-FgSHBKhV.js +1 -0
  107. package/backend/src/flowent/static/index.html +3 -3
  108. package/backend/src/flowent/tools/__init__.py +2 -101
  109. package/backend/src/flowent/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  110. package/backend/src/flowent/tools/__pycache__/connect.cpython-313.pyc +0 -0
  111. package/backend/src/flowent/tools/__pycache__/contacts.cpython-313.pyc +0 -0
  112. package/backend/src/flowent/tools/__pycache__/create_agent.cpython-313.pyc +0 -0
  113. package/backend/src/flowent/tools/__pycache__/create_tab.cpython-313.pyc +0 -0
  114. package/backend/src/flowent/tools/__pycache__/delete_tab.cpython-313.pyc +0 -0
  115. package/backend/src/flowent/tools/__pycache__/edit.cpython-313.pyc +0 -0
  116. package/backend/src/flowent/tools/__pycache__/exec.cpython-313.pyc +0 -0
  117. package/backend/src/flowent/tools/__pycache__/fetch.cpython-313.pyc +0 -0
  118. package/backend/src/flowent/tools/__pycache__/idle.cpython-313.pyc +0 -0
  119. package/backend/src/flowent/tools/__pycache__/list_roles.cpython-313.pyc +0 -0
  120. package/backend/src/flowent/tools/__pycache__/list_tabs.cpython-313.pyc +0 -0
  121. package/backend/src/flowent/tools/__pycache__/list_tools.cpython-313.pyc +0 -0
  122. package/backend/src/flowent/tools/__pycache__/manage_prompts.cpython-313.pyc +0 -0
  123. package/backend/src/flowent/tools/__pycache__/manage_providers.cpython-313.pyc +0 -0
  124. package/backend/src/flowent/tools/__pycache__/manage_roles.cpython-313.pyc +0 -0
  125. package/backend/src/flowent/tools/__pycache__/manage_settings.cpython-313.pyc +0 -0
  126. package/backend/src/flowent/tools/__pycache__/read.cpython-313.pyc +0 -0
  127. package/backend/src/flowent/tools/__pycache__/send.cpython-313.pyc +0 -0
  128. package/backend/src/flowent/tools/__pycache__/set_permissions.cpython-313.pyc +0 -0
  129. package/backend/src/flowent/tools/__pycache__/sleep.cpython-313.pyc +0 -0
  130. package/backend/src/flowent/tools/__pycache__/todo.cpython-313.pyc +0 -0
  131. package/backend/src/flowent/tools/list_roles.py +2 -9
  132. package/backend/src/flowent/tools/manage_settings.py +134 -172
  133. package/backend/tests/__pycache__/__init__.cpython-313.pyc +0 -0
  134. package/backend/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  135. package/backend/tests/integration/api/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  136. package/backend/tests/integration/api/__pycache__/test_access_api.cpython-313-pytest-9.0.3.pyc +0 -0
  137. package/backend/tests/integration/api/__pycache__/test_assistant_api.cpython-313-pytest-9.0.3.pyc +0 -0
  138. package/backend/tests/integration/api/__pycache__/test_frontend_mounting.cpython-313-pytest-9.0.3.pyc +0 -0
  139. package/backend/tests/integration/api/__pycache__/test_meta_api.cpython-313-pytest-9.0.3.pyc +0 -0
  140. package/backend/tests/integration/api/__pycache__/test_nodes_api.cpython-313-pytest-9.0.3.pyc +0 -0
  141. package/backend/tests/integration/api/__pycache__/test_prompts_api.cpython-313-pytest-9.0.3.pyc +0 -0
  142. package/backend/tests/integration/api/__pycache__/test_roles_api.cpython-313-pytest-9.0.3.pyc +0 -0
  143. package/backend/tests/integration/api/__pycache__/test_tabs_api.cpython-313-pytest-9.0.3.pyc +0 -0
  144. package/backend/tests/integration/api/test_assistant_api.py +68 -0
  145. package/backend/tests/integration/api/test_meta_api.py +0 -1
  146. package/backend/tests/integration/api/test_nodes_api.py +73 -8
  147. package/backend/tests/integration/api/test_tabs_api.py +0 -114
  148. package/backend/tests/unit/__pycache__/test_access.cpython-313-pytest-9.0.3.pyc +0 -0
  149. package/backend/tests/unit/__pycache__/test_cli.cpython-313-pytest-9.0.3.pyc +0 -0
  150. package/backend/tests/unit/__pycache__/test_graph_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  151. package/backend/tests/unit/__pycache__/test_network.cpython-313-pytest-9.0.3.pyc +0 -0
  152. package/backend/tests/unit/__pycache__/test_state_sqlite_storage.cpython-313-pytest-9.0.3.pyc +0 -0
  153. package/backend/tests/unit/__pycache__/test_workspace_store.cpython-313-pytest-9.0.3.pyc +0 -0
  154. package/backend/tests/unit/agent/__pycache__/test_agent_public_api.cpython-313-pytest-9.0.3.pyc +0 -0
  155. package/backend/tests/unit/agent/__pycache__/test_agent_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  156. package/backend/tests/unit/agent/test_agent_public_api.py +0 -15
  157. package/backend/tests/unit/agent/test_agent_runtime.py +148 -2
  158. package/backend/tests/unit/channels/__pycache__/test_telegram_channel.cpython-313-pytest-9.0.3.pyc +0 -0
  159. package/backend/tests/unit/logging/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
  160. package/backend/tests/unit/prompts/__pycache__/test_prompts.cpython-313-pytest-9.0.3.pyc +0 -0
  161. package/backend/tests/unit/providers/__pycache__/test_anthropic_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  162. package/backend/tests/unit/providers/__pycache__/test_errors.cpython-313-pytest-9.0.3.pyc +0 -0
  163. package/backend/tests/unit/providers/__pycache__/test_extract_delta_parts.cpython-313-pytest-9.0.3.pyc +0 -0
  164. package/backend/tests/unit/providers/__pycache__/test_openai_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  165. package/backend/tests/unit/providers/__pycache__/test_openai_responses.cpython-313-pytest-9.0.3.pyc +0 -0
  166. package/backend/tests/unit/providers/__pycache__/test_provider_gateway.cpython-313-pytest-9.0.3.pyc +0 -0
  167. package/backend/tests/unit/providers/__pycache__/test_think_tag_parser.cpython-313-pytest-9.0.3.pyc +0 -0
  168. package/backend/tests/unit/routes/__pycache__/test_prompts_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  169. package/backend/tests/unit/routes/__pycache__/test_providers_route.cpython-313-pytest-9.0.3.pyc +0 -0
  170. package/backend/tests/unit/routes/__pycache__/test_roles_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  171. package/backend/tests/unit/routes/__pycache__/test_settings_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  172. package/backend/tests/unit/routes/test_prompts_routes.py +0 -22
  173. package/backend/tests/unit/routes/test_roles_routes.py +6 -2
  174. package/backend/tests/unit/routes/test_settings_routes.py +0 -19
  175. package/backend/tests/unit/runtime/__pycache__/test_bootstrap_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  176. package/backend/tests/unit/sandbox/__pycache__/test_sandbox_tools.cpython-313-pytest-9.0.3.pyc +0 -0
  177. package/backend/tests/unit/security/__pycache__/test_security.cpython-313-pytest-9.0.3.pyc +0 -0
  178. package/backend/tests/unit/settings/__pycache__/test_settings_roles.cpython-313-pytest-9.0.3.pyc +0 -0
  179. package/backend/tests/unit/settings/test_settings_roles.py +3 -51
  180. package/backend/tests/unit/test_cli.py +0 -22
  181. package/backend/tests/unit/test_state_sqlite_storage.py +27 -99
  182. package/backend/tests/unit/test_workspace_store.py +0 -3
  183. package/backend/tests/unit/tools/__pycache__/test_connect_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  184. package/backend/tests/unit/tools/__pycache__/test_create_agent_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  185. package/backend/tests/unit/tools/__pycache__/test_delete_tab_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  186. package/backend/tests/unit/tools/__pycache__/test_edit_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  187. package/backend/tests/unit/tools/__pycache__/test_exec_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  188. package/backend/tests/unit/tools/__pycache__/test_fetch_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  189. package/backend/tests/unit/tools/__pycache__/test_manage_prompts_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  190. package/backend/tests/unit/tools/__pycache__/test_manage_providers_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  191. package/backend/tests/unit/tools/__pycache__/test_manage_roles_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  192. package/backend/tests/unit/tools/__pycache__/test_manage_settings_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  193. package/backend/tests/unit/tools/__pycache__/test_read_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  194. package/backend/tests/unit/tools/__pycache__/test_set_permissions_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  195. package/backend/tests/unit/tools/__pycache__/test_todo_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  196. package/backend/tests/unit/tools/__pycache__/test_tool_registry.cpython-313-pytest-9.0.3.pyc +0 -0
  197. package/backend/tests/unit/tools/test_create_agent_tool.py +0 -32
  198. package/backend/tests/unit/tools/test_manage_prompts_tool.py +5 -30
  199. package/backend/tests/unit/tools/test_tool_registry.py +45 -40
  200. package/backend/uv.lock +1 -1
  201. package/dist/frontend/assets/AssistantPage-BW7XAd9I.js +1 -0
  202. package/dist/frontend/assets/ChannelsPage-tCJHgt6m.js +1 -0
  203. package/dist/frontend/assets/{PageScaffold-DteOA8V7.js → PageScaffold-f6g2l7XN.js} +1 -1
  204. package/dist/frontend/assets/PromptsPage-C3Sxn2D7.js +1 -0
  205. package/dist/frontend/assets/ProvidersPage-BfmdXmNt.js +3 -0
  206. package/dist/frontend/assets/RolesPage-DET8wO4r.js +1 -0
  207. package/dist/frontend/assets/SettingsPage-D-g3deMm.js +3 -0
  208. package/dist/frontend/assets/ToolsPage-CDmtE2g4.js +1 -0
  209. package/dist/frontend/assets/WorkspacePage-AZsJ0sD0.js +3 -0
  210. package/dist/frontend/assets/WorkspacePanels-CteCjolX.js +1 -0
  211. package/dist/frontend/assets/{alert-dialog-DIBUCmqM.js → alert-dialog-Duorp_S-.js} +1 -1
  212. package/dist/frontend/assets/{dialog-BOvHIBrg.js → dialog-C3ixjGjN.js} +1 -1
  213. package/dist/frontend/assets/index--o_0fv0N.css +1 -0
  214. package/dist/frontend/assets/index-C9HuekJm.js +10 -0
  215. package/dist/frontend/assets/{modelParams-DcEhGnu0.js → modelParams-DmnF2hwR.js} +1 -1
  216. package/dist/frontend/assets/providerTypes-DT3Ahwl_.js +1 -0
  217. package/dist/frontend/assets/roles-CuRT_chR.js +1 -0
  218. package/{backend/src/flowent/static/assets/select-D9SwnlXF.js → dist/frontend/assets/select-DCfeNu-F.js} +1 -1
  219. package/dist/frontend/assets/surface-pWwG5ogx.js +1 -0
  220. package/dist/frontend/assets/{ui-vendor-UazN8rcv.js → ui-vendor-C5pJa8N7.js} +15 -15
  221. package/dist/frontend/assets/useAppRoute-FgSHBKhV.js +1 -0
  222. package/dist/frontend/index.html +3 -3
  223. package/package.json +1 -1
  224. package/backend/src/flowent/__pycache__/mcp_service.cpython-313.pyc +0 -0
  225. package/backend/src/flowent/mcp_service.py +0 -1918
  226. package/backend/src/flowent/routes/__pycache__/mcp.cpython-313.pyc +0 -0
  227. package/backend/src/flowent/routes/mcp.py +0 -125
  228. package/backend/src/flowent/static/assets/AssistantPage-VBohhz4d.js +0 -1
  229. package/backend/src/flowent/static/assets/ChannelsPage-CIydPZA_.js +0 -1
  230. package/backend/src/flowent/static/assets/McpPage-CHPm2TPY.js +0 -7
  231. package/backend/src/flowent/static/assets/PromptsPage-CSmJ3sZg.js +0 -1
  232. package/backend/src/flowent/static/assets/ProvidersPage-sl2jeG4e.js +0 -3
  233. package/backend/src/flowent/static/assets/RolesPage-DCe7W6Km.js +0 -1
  234. package/backend/src/flowent/static/assets/SettingsPage-Bix9e63E.js +0 -3
  235. package/backend/src/flowent/static/assets/ToolsPage-favNkj5C.js +0 -1
  236. package/backend/src/flowent/static/assets/WorkspaceCommandDialog-DRS6wiD6.js +0 -1
  237. package/backend/src/flowent/static/assets/WorkspacePage-KuaDjt_D.js +0 -3
  238. package/backend/src/flowent/static/assets/WorkspacePanels-BZxBw8M5.js +0 -1
  239. package/backend/src/flowent/static/assets/datetime-eJqd0V2S.js +0 -1
  240. package/backend/src/flowent/static/assets/index-Biio-CoI.js +0 -10
  241. package/backend/src/flowent/static/assets/index-CmQvO7sl.css +0 -1
  242. package/backend/src/flowent/static/assets/roles-BbIEIMeG.js +0 -1
  243. package/backend/src/flowent/static/assets/surface-Bzr1FRG4.js +0 -1
  244. package/backend/src/flowent/static/assets/triState-DgLlKdRR.js +0 -1
  245. package/backend/src/flowent/tools/__pycache__/mcp.cpython-313.pyc +0 -0
  246. package/backend/src/flowent/tools/mcp.py +0 -199
  247. package/backend/tests/integration/api/__pycache__/test_mcp_api.cpython-313-pytest-9.0.3.pyc +0 -0
  248. package/backend/tests/integration/api/test_mcp_api.py +0 -116
  249. package/dist/frontend/assets/AssistantPage-VBohhz4d.js +0 -1
  250. package/dist/frontend/assets/ChannelsPage-CIydPZA_.js +0 -1
  251. package/dist/frontend/assets/McpPage-CHPm2TPY.js +0 -7
  252. package/dist/frontend/assets/PromptsPage-CSmJ3sZg.js +0 -1
  253. package/dist/frontend/assets/ProvidersPage-sl2jeG4e.js +0 -3
  254. package/dist/frontend/assets/RolesPage-DCe7W6Km.js +0 -1
  255. package/dist/frontend/assets/SettingsPage-Bix9e63E.js +0 -3
  256. package/dist/frontend/assets/ToolsPage-favNkj5C.js +0 -1
  257. package/dist/frontend/assets/WorkspaceCommandDialog-DRS6wiD6.js +0 -1
  258. package/dist/frontend/assets/WorkspacePage-KuaDjt_D.js +0 -3
  259. package/dist/frontend/assets/WorkspacePanels-BZxBw8M5.js +0 -1
  260. package/dist/frontend/assets/datetime-eJqd0V2S.js +0 -1
  261. package/dist/frontend/assets/index-Biio-CoI.js +0 -10
  262. package/dist/frontend/assets/index-CmQvO7sl.css +0 -1
  263. package/dist/frontend/assets/roles-BbIEIMeG.js +0 -1
  264. package/dist/frontend/assets/surface-Bzr1FRG4.js +0 -1
  265. package/dist/frontend/assets/triState-DgLlKdRR.js +0 -1
@@ -175,15 +175,17 @@ def test_create_role_filters_assistant_only_tools(monkeypatch):
175
175
  "create_workflow",
176
176
  "delete_workflow",
177
177
  "list_workflows",
178
- "mcp__flowent__list_workflows",
179
178
  "manage_settings",
180
179
  ],
180
+ excluded_tools=["fetch"],
181
181
  )
182
182
  )
183
183
  )
184
184
 
185
185
  assert result["included_tools"] == ["read"]
186
+ assert result["excluded_tools"] == ["fetch"]
186
187
  assert settings.roles[0].included_tools == ["read"]
188
+ assert settings.roles[0].excluded_tools == ["fetch"]
187
189
 
188
190
 
189
191
  def test_create_role_rejects_duplicate_name(monkeypatch):
@@ -284,15 +286,17 @@ def test_update_role_filters_assistant_only_tools(monkeypatch):
284
286
  "create_workflow",
285
287
  "delete_workflow",
286
288
  "list_workflows",
287
- "mcp__flowent__list_workflows",
288
289
  "manage_roles",
289
290
  ],
291
+ excluded_tools=["fetch"],
290
292
  ),
291
293
  )
292
294
  )
293
295
 
294
296
  assert result["included_tools"] == ["read"]
297
+ assert result["excluded_tools"] == ["fetch"]
295
298
  assert settings.roles[0].included_tools == ["read"]
299
+ assert settings.roles[0].excluded_tools == ["fetch"]
296
300
 
297
301
 
298
302
  def test_update_role_rejects_duplicate_name(monkeypatch):
@@ -140,7 +140,6 @@ def test_get_settings_bootstrap_returns_related_resources(monkeypatch):
140
140
  "excluded_tools": [],
141
141
  }
142
142
  ],
143
- "mcp_servers": [],
144
143
  },
145
144
  "providers": [
146
145
  {
@@ -1108,24 +1107,6 @@ def test_update_settings_rejects_invalid_assistant_allow_network(monkeypatch):
1108
1107
  assert excinfo.value.detail == "assistant.allow_network must be a boolean"
1109
1108
 
1110
1109
 
1111
- def test_update_settings_rejects_removed_assistant_mcp_servers(monkeypatch):
1112
- settings = Settings(
1113
- roles=[RoleConfig(name="Steward", system_prompt="Default assistant role.")]
1114
- )
1115
-
1116
- monkeypatch.setattr("flowent.routes.settings.get_settings", lambda: settings)
1117
-
1118
- with pytest.raises(HTTPException) as excinfo:
1119
- asyncio.run(
1120
- update_settings(
1121
- UpdateSettingsRequest(assistant={"mcp_servers": ["filesystem"]}),
1122
- )
1123
- )
1124
-
1125
- assert excinfo.value.status_code == 400
1126
- assert excinfo.value.detail == "Unknown assistant fields: mcp_servers"
1127
-
1128
-
1129
1110
  def test_update_settings_rejects_unknown_leader_role(monkeypatch):
1130
1111
  settings = Settings(roles=[RoleConfig(name="Conductor", system_prompt="Default.")])
1131
1112
 
@@ -415,56 +415,6 @@ def test_load_settings_defaults_provider_retry_429_delay_seconds(monkeypatch, tm
415
415
  assert persisted["providers"][0]["retry_429_delay_seconds"] == 0
416
416
 
417
417
 
418
- def test_load_settings_drops_removed_exit_tool_from_roles(monkeypatch, tmp_path):
419
- settings_file = tmp_path / "settings.json"
420
- settings_file.write_text(
421
- json.dumps(
422
- {
423
- "event_log": {"timestamp_format": "absolute"},
424
- "model": {"active_provider_id": "", "active_model": ""},
425
- "providers": [],
426
- "roles": [
427
- {
428
- "name": "Worker",
429
- "system_prompt": "Do work.",
430
- "included_tools": ["read", "exit", "exec"],
431
- "excluded_tools": ["exit", "fetch"],
432
- }
433
- ],
434
- }
435
- ),
436
- encoding="utf-8",
437
- )
438
-
439
- monkeypatch.setattr(settings_module, "_SETTINGS_FILE", settings_file)
440
- monkeypatch.setattr(settings_module, "_cached_settings", None)
441
-
442
- loaded = settings_module.load_settings()
443
-
444
- assert loaded.roles == [
445
- RoleConfig(
446
- name="Worker",
447
- description="Do work.",
448
- system_prompt="Do work.",
449
- included_tools=["read", "exec"],
450
- excluded_tools=["fetch"],
451
- )
452
- ]
453
-
454
- persisted = json.loads(settings_file.read_text(encoding="utf-8"))
455
- assert persisted["roles"] == [
456
- {
457
- "name": "Worker",
458
- "description": "Do work.",
459
- "system_prompt": "Do work.",
460
- "model": None,
461
- "model_params": None,
462
- "included_tools": ["read", "exec"],
463
- "excluded_tools": ["fetch"],
464
- }
465
- ]
466
-
467
-
468
418
  def test_load_settings_drops_assistant_only_tools_from_custom_roles(
469
419
  monkeypatch,
470
420
  tmp_path,
@@ -485,7 +435,9 @@ def test_load_settings_drops_assistant_only_tools_from_custom_roles(
485
435
  "create_workflow",
486
436
  "delete_workflow",
487
437
  "list_workflows",
488
- "mcp__flowent__list_workflows",
438
+ "mcp__external__search_notes",
439
+ "mcp__external__summarize",
440
+ "mcp__external__classify",
489
441
  "manage_settings",
490
442
  ],
491
443
  }
@@ -59,17 +59,6 @@ def test_access_reset_command_clears_persisted_access_code(
59
59
  assert not is_access_configured(reloaded_settings.access)
60
60
 
61
61
 
62
- def test_help_output_no_longer_lists_mcp_command(capsys):
63
- with pytest.raises(SystemExit) as exc:
64
- main(["--help"])
65
-
66
- assert exc.value.code == 0
67
- output = capsys.readouterr().out
68
-
69
- assert "access" in output
70
- assert "mcp" not in output
71
-
72
-
73
62
  def test_version_short_option_matches_version_output(capsys):
74
63
  with pytest.raises(SystemExit) as exc:
75
64
  main(["-v"])
@@ -97,17 +86,6 @@ def test_server_options_accept_npm_wrapper_aliases(monkeypatch):
97
86
  }
98
87
 
99
88
 
100
- def test_removed_mcp_command_is_rejected(capsys):
101
- with pytest.raises(SystemExit) as exc:
102
- main(["mcp", "serve"])
103
-
104
- assert exc.value.code == 2
105
- error_output = capsys.readouterr().err
106
-
107
- assert "invalid choice" in error_output
108
- assert "'mcp'" in error_output
109
-
110
-
111
89
  def test_cli_sets_app_data_dir_env_before_dispatch(monkeypatch, tmp_path, capsys):
112
90
  monkeypatch.delenv(APP_DATA_DIR_ENV_VAR, raising=False)
113
91
  called: list[str] = []
@@ -1,13 +1,8 @@
1
1
  import base64
2
2
  import sqlite3
3
- import time
4
3
 
5
4
  import flowent.settings as settings_module
6
- from flowent.agent import Agent
7
5
  from flowent.image_assets import create_image_asset
8
- from flowent.mcp_service import MCPDiscoverySnapshot, MCPToolDescriptor, mcp_service
9
- from flowent.models import NodeConfig, NodeType
10
- from flowent.settings import MCPServerConfig, Settings
11
6
 
12
7
  _ONE_PIXEL_PNG = base64.b64decode(
13
8
  "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+aF9sAAAAASUVORK5CYII="
@@ -49,111 +44,44 @@ def test_create_image_asset_persists_metadata_in_state_sqlite(monkeypatch, tmp_p
49
44
  assert row["original_name"] == "pixel.png"
50
45
 
51
46
 
52
- def test_mcp_service_restores_persisted_snapshot_and_activity_after_runtime_clear(
53
- monkeypatch,
54
- tmp_path,
55
- ):
47
+ def test_state_schema_removes_retired_connection_tables(monkeypatch, tmp_path):
56
48
  settings_file = tmp_path / "settings.json"
57
49
  settings_file.write_text("{}", encoding="utf-8")
58
50
  monkeypatch.setattr(settings_module, "_SETTINGS_FILE", settings_file)
59
51
  monkeypatch.setattr(settings_module, "_cached_settings", None)
60
- mcp_service.reset()
61
- now = time.time()
62
52
 
53
+ db_path = tmp_path / "state.sqlite"
54
+ connection = sqlite3.connect(db_path)
63
55
  try:
64
- mcp_service._set_snapshot(
65
- MCPDiscoverySnapshot(
66
- server_name="filesystem",
67
- transport="stdio",
68
- status="connected",
69
- auth_status="unsupported",
70
- last_refresh_result="success",
71
- )
72
- )
73
- mcp_service._record_activity(
74
- server_name="filesystem",
75
- action="refresh",
76
- actor_node_id=None,
77
- tab_id=None,
78
- started_at=now - 2.0,
79
- ended_at=now,
80
- result="success",
81
- summary="Capabilities refreshed",
56
+ connection.executescript(
57
+ """
58
+ CREATE TABLE mcp_snapshots (id TEXT PRIMARY KEY);
59
+ CREATE TABLE mcp_activities (id TEXT PRIMARY KEY);
60
+ """
82
61
  )
83
-
84
- mcp_service.clear_runtime_state()
85
-
86
- restored_snapshot = mcp_service._get_snapshot("filesystem")
87
- restored_activities = mcp_service.list_activities(server_name="filesystem")
88
-
89
- assert restored_snapshot is not None
90
- assert restored_snapshot.status == "connected"
91
- assert restored_snapshot.last_refresh_result == "success"
92
- assert len(restored_activities) == 1
93
- assert restored_activities[0].server_name == "filesystem"
94
- assert restored_activities[0].summary == "Capabilities refreshed"
95
62
  finally:
96
- mcp_service.reset()
97
-
63
+ connection.close()
98
64
 
99
- def test_mcp_service_filters_workflow_management_tools_for_non_assistant(
100
- monkeypatch,
101
- tmp_path,
102
- ):
103
- settings_file = tmp_path / "settings.json"
104
- settings_file.write_text("{}", encoding="utf-8")
105
- monkeypatch.setattr(settings_module, "_SETTINGS_FILE", settings_file)
106
- monkeypatch.setattr(settings_module, "_cached_settings", None)
107
- monkeypatch.setattr(
108
- "flowent.mcp_service.get_settings",
109
- lambda: Settings(
110
- mcp_servers=[
111
- MCPServerConfig(
112
- name="flowent",
113
- transport="stdio",
114
- )
115
- ]
116
- ),
65
+ create_image_asset(
66
+ _ONE_PIXEL_PNG,
67
+ mime_type="image/png",
68
+ original_name="pixel.png",
117
69
  )
118
- mcp_service.reset()
119
70
 
71
+ connection = sqlite3.connect(db_path)
120
72
  try:
121
- mcp_service._set_snapshot(
122
- MCPDiscoverySnapshot(
123
- server_name="flowent",
124
- transport="stdio",
125
- status="connected",
126
- auth_status="unsupported",
127
- tools=[
128
- MCPToolDescriptor(
129
- server_name="flowent",
130
- tool_name="list_workflows",
131
- fully_qualified_id="mcp__flowent__list_workflows",
132
- ),
133
- MCPToolDescriptor(
134
- server_name="flowent",
135
- tool_name="search_notes",
136
- fully_qualified_id="mcp__flowent__search_notes",
137
- ),
138
- ],
139
- )
140
- )
141
- worker = Agent(NodeConfig(node_type=NodeType.AGENT), uuid="worker")
142
- assistant = Agent(NodeConfig(node_type=NodeType.ASSISTANT), uuid="assistant")
143
-
144
- worker_tools = {
145
- descriptor.fully_qualified_id
146
- for descriptor in mcp_service.list_agent_dynamic_tools(worker)
147
- }
148
- assistant_tools = {
149
- descriptor.fully_qualified_id
150
- for descriptor in mcp_service.list_agent_dynamic_tools(assistant)
151
- }
152
-
153
- assert worker_tools == {"mcp__flowent__search_notes"}
154
- assert assistant_tools == {
155
- "mcp__flowent__list_workflows",
156
- "mcp__flowent__search_notes",
73
+ existing_tables = {
74
+ row[0]
75
+ for row in connection.execute(
76
+ """
77
+ SELECT name
78
+ FROM sqlite_master
79
+ WHERE type = 'table'
80
+ """
81
+ ).fetchall()
157
82
  }
158
83
  finally:
159
- mcp_service.reset()
84
+ connection.close()
85
+
86
+ assert "mcp_snapshots" not in existing_tables
87
+ assert "mcp_activities" not in existing_tables
@@ -38,7 +38,6 @@ def test_workspace_store_normalizes_relative_write_dirs_on_load(
38
38
  }
39
39
  ],
40
40
  "edges": [],
41
- "blueprints": [],
42
41
  }
43
42
  ),
44
43
  encoding="utf-8",
@@ -103,7 +102,6 @@ def test_workspace_store_prefers_legacy_workspace_data_when_state_db_is_still_em
103
102
  }
104
103
  ],
105
104
  "edges": [],
106
- "blueprints": [],
107
105
  }
108
106
  ),
109
107
  encoding="utf-8",
@@ -157,7 +155,6 @@ def test_workspace_store_does_not_overwrite_state_db_with_legacy_workspace_data(
157
155
  }
158
156
  ],
159
157
  "edges": [],
160
- "blueprints": [],
161
158
  }
162
159
  ),
163
160
  encoding="utf-8",
@@ -362,38 +362,6 @@ def test_create_agent_rejects_node_level_permissions(monkeypatch, tmp_path):
362
362
  }
363
363
 
364
364
 
365
- def test_create_agent_rejects_removed_connect_to_creator_parameter(monkeypatch):
366
- monkeypatch.setattr(
367
- "flowent.settings.get_settings",
368
- lambda: Settings(roles=[RoleConfig(name="Worker", system_prompt="Do work.")]),
369
- )
370
- tab = create_tab(title="Task")
371
-
372
- owner = Agent(
373
- NodeConfig(
374
- node_type=NodeType.AGENT,
375
- role_name="Conductor",
376
- tab_id=tab.id,
377
- tools=["create_agent"],
378
- ),
379
- uuid=tab.leader_id,
380
- )
381
-
382
- result = json.loads(
383
- CreateAgentTool().execute(
384
- owner,
385
- {
386
- "role_name": "Worker",
387
- "connect_to_creator": "yes",
388
- },
389
- )
390
- )
391
-
392
- assert result == {
393
- "error": "create_agent no longer supports connect_to_creator; use placement"
394
- }
395
-
396
-
397
365
  def test_create_agent_tool_schema_exposes_workflow_placement_options():
398
366
  assert CreateAgentTool.parameters == {
399
367
  "type": "object",
@@ -10,7 +10,7 @@ def test_manage_prompts_get_returns_current_prompt(monkeypatch):
10
10
  agent = Agent(NodeConfig(node_type=NodeType.ASSISTANT, tools=["manage_prompts"]))
11
11
  settings = Settings(
12
12
  custom_prompt="Be concise.",
13
- custom_post_prompt="Stay routed.",
13
+ custom_post_prompt="Summarize decisions before the next step.",
14
14
  )
15
15
 
16
16
  monkeypatch.setattr("flowent.settings.get_settings", lambda: settings)
@@ -19,7 +19,7 @@ def test_manage_prompts_get_returns_current_prompt(monkeypatch):
19
19
 
20
20
  assert result == {
21
21
  "custom_prompt": "Be concise.",
22
- "custom_post_prompt": "Stay routed.",
22
+ "custom_post_prompt": "Summarize decisions before the next step.",
23
23
  }
24
24
 
25
25
 
@@ -39,17 +39,17 @@ def test_manage_prompts_update_saves_custom_prompt(monkeypatch):
39
39
  {
40
40
  "action": "update",
41
41
  "custom_prompt": "Always prefer terse answers.",
42
- "custom_post_prompt": "Only route with @target.",
42
+ "custom_post_prompt": "Summarize decisions before the next step.",
43
43
  },
44
44
  )
45
45
  )
46
46
 
47
47
  assert result == {
48
48
  "custom_prompt": "Always prefer terse answers.",
49
- "custom_post_prompt": "Only route with @target.",
49
+ "custom_post_prompt": "Summarize decisions before the next step.",
50
50
  }
51
51
  assert settings.custom_prompt == "Always prefer terse answers."
52
- assert settings.custom_post_prompt == "Only route with @target."
52
+ assert settings.custom_post_prompt == "Summarize decisions before the next step."
53
53
  assert saved == [settings]
54
54
 
55
55
 
@@ -90,28 +90,3 @@ def test_manage_prompts_update_allows_custom_post_prompt_only(monkeypatch):
90
90
  }
91
91
  assert settings.custom_prompt == "Keep this."
92
92
  assert settings.custom_post_prompt == "Append this after history."
93
-
94
-
95
- def test_manage_prompts_update_accepts_legacy_post_prompt_alias(monkeypatch):
96
- agent = Agent(NodeConfig(node_type=NodeType.ASSISTANT, tools=["manage_prompts"]))
97
- settings = Settings(custom_prompt="Keep this.", custom_post_prompt="")
98
-
99
- monkeypatch.setattr("flowent.settings.get_settings", lambda: settings)
100
- monkeypatch.setattr("flowent.settings.save_settings", lambda current: None)
101
-
102
- result = json.loads(
103
- ManagePromptsTool().execute(
104
- agent,
105
- {
106
- "action": "update",
107
- "post_prompt": "Append this after history.",
108
- },
109
- )
110
- )
111
-
112
- assert result == {
113
- "custom_prompt": "Keep this.",
114
- "custom_post_prompt": "Append this after history.",
115
- }
116
- assert settings.custom_prompt == "Keep this."
117
- assert settings.custom_post_prompt == "Append this after history."
@@ -3,17 +3,6 @@ from flowent.models import NodeConfig, NodeType
3
3
  from flowent.tools import build_tool_registry
4
4
 
5
5
 
6
- class _FakeMCPService:
7
- def __init__(self, descriptors):
8
- self._descriptors = descriptors
9
-
10
- def list_agent_dynamic_tools(self, agent):
11
- return list(self._descriptors)
12
-
13
- def list_discovered_tools(self):
14
- return list(self._descriptors)
15
-
16
-
17
6
  def test_empty_tools_list_grants_minimum_tools():
18
7
  agent = Agent(NodeConfig(node_type=NodeType.AGENT, tools=[]))
19
8
 
@@ -42,7 +31,7 @@ def test_tool_registry_merges_explicit_allow_list_with_minimum_tools():
42
31
  ]
43
32
 
44
33
 
45
- def test_tool_registry_registers_connect_and_removes_create_root():
34
+ def test_tool_registry_registers_management_and_workflow_tools():
46
35
  tool_names = [tool.name for tool in build_tool_registry().list_tools()]
47
36
 
48
37
  assert "create_workflow" in tool_names
@@ -52,7 +41,6 @@ def test_tool_registry_registers_connect_and_removes_create_root():
52
41
  assert "connect" in tool_names
53
42
  assert "send" in tool_names
54
43
  assert "list_workflows" in tool_names
55
- assert "create_root" not in tool_names
56
44
  assert "manage_providers" in tool_names
57
45
  assert "manage_roles" in tool_names
58
46
  assert "manage_settings" in tool_names
@@ -120,41 +108,42 @@ def test_tool_registry_filters_assistant_only_tools_for_workflow_nodes():
120
108
  ]
121
109
 
122
110
 
123
- def test_tool_registry_filters_assistant_only_mcp_tools_for_workflow_nodes(
124
- monkeypatch,
125
- ):
126
- from flowent.mcp_service import MCPToolDescriptor
127
-
128
- workflow_tool = MCPToolDescriptor(
129
- server_name="flowent",
130
- tool_name="list_workflows",
131
- fully_qualified_id="mcp__flowent__list_workflows",
132
- )
133
- regular_tool = MCPToolDescriptor(
134
- server_name="flowent",
135
- tool_name="search_notes",
136
- fully_qualified_id="mcp__flowent__search_notes",
137
- )
138
- fake_service = _FakeMCPService([workflow_tool, regular_tool])
139
- monkeypatch.setattr("flowent.mcp_service.mcp_service", fake_service)
111
+ def test_tool_registry_ignores_mcp_prefixed_tools_for_workflow_nodes():
140
112
  agent = Agent(
141
113
  NodeConfig(
142
114
  node_type=NodeType.AGENT,
143
115
  role_name="Worker",
144
116
  tools=[
145
- "mcp__flowent__list_workflows",
146
- "mcp__flowent__search_notes",
117
+ "mcp__external__search_notes",
118
+ "mcp__external__lookup",
119
+ ],
120
+ )
121
+ )
122
+
123
+ tools = build_tool_registry().get_tools_for_agent(agent)
124
+
125
+ assert "mcp__external__search_notes" not in {tool.name for tool in tools}
126
+ assert "mcp__external__lookup" not in {tool.name for tool in tools}
127
+
128
+
129
+ def test_tool_registry_ignores_mcp_prefixed_tools_for_assistant():
130
+ agent = Agent(
131
+ NodeConfig(
132
+ node_type=NodeType.ASSISTANT,
133
+ tools=[
134
+ "mcp__external__summarize",
135
+ "mcp__external__lookup",
147
136
  ],
148
137
  )
149
138
  )
150
139
 
151
140
  tools = build_tool_registry().get_tools_for_agent(agent)
152
141
 
153
- assert "mcp__flowent__list_workflows" not in {tool.name for tool in tools}
154
- assert "mcp__flowent__search_notes" in {tool.name for tool in tools}
142
+ assert "mcp__external__summarize" not in {tool.name for tool in tools}
143
+ assert "mcp__external__lookup" not in {tool.name for tool in tools}
155
144
 
156
145
 
157
- def test_build_tools_for_role_filters_assistant_only_mcp_tools(monkeypatch):
146
+ def test_build_tools_for_role_filters_mcp_prefixed_tools(monkeypatch):
158
147
  from flowent.graph_service import build_tools_for_role
159
148
  from flowent.settings import RoleConfig, Settings
160
149
 
@@ -165,7 +154,7 @@ def test_build_tools_for_role_filters_assistant_only_mcp_tools(monkeypatch):
165
154
  RoleConfig(
166
155
  name="Worker",
167
156
  system_prompt="Do work.",
168
- included_tools=["mcp__flowent__list_workflows", "read"],
157
+ included_tools=["mcp__external__search_notes", "read"],
169
158
  )
170
159
  ]
171
160
  ),
@@ -173,12 +162,28 @@ def test_build_tools_for_role_filters_assistant_only_mcp_tools(monkeypatch):
173
162
 
174
163
  tools = build_tools_for_role(
175
164
  "Worker",
176
- requested_tools=["mcp__flowent__delete_workflow", "mcp__flowent__search_notes"],
165
+ requested_tools=[
166
+ "mcp__external__lookup",
167
+ "mcp__external__summarize",
168
+ "mcp__external__classify",
169
+ "mcp__external__search_notes",
170
+ ],
177
171
  )
178
172
 
179
- assert "mcp__flowent__list_workflows" not in tools
180
- assert "mcp__flowent__delete_workflow" not in tools
181
- assert "mcp__flowent__search_notes" in tools
173
+ assert "mcp__external__lookup" not in tools
174
+ assert "mcp__external__summarize" not in tools
175
+ assert "mcp__external__classify" not in tools
176
+ assert "mcp__external__search_notes" not in tools
177
+
178
+
179
+ def test_list_agent_visible_tool_descriptors_excludes_external_tools():
180
+ from flowent.tools import list_agent_visible_tool_descriptors
181
+
182
+ tool_names = {
183
+ descriptor["name"] for descriptor in list_agent_visible_tool_descriptors()
184
+ }
185
+
186
+ assert all(not tool_name.startswith("mcp__") for tool_name in tool_names)
182
187
 
183
188
 
184
189
  def test_tool_registry_shows_management_tools_in_agent_visible_list():
package/backend/uv.lock CHANGED
@@ -286,7 +286,7 @@ wheels = [
286
286
 
287
287
  [[package]]
288
288
  name = "flowent"
289
- version = "0.0.6"
289
+ version = "0.0.7"
290
290
  source = { editable = "." }
291
291
  dependencies = [
292
292
  { name = "curl-cffi" },