flock-core 0.5.0b28__py3-none-any.whl → 0.5.56b0__py3-none-any.whl

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.

Potentially problematic release.


This version of flock-core might be problematic. Click here for more details.

Files changed (359) hide show
  1. flock/__init__.py +12 -217
  2. flock/agent.py +678 -0
  3. flock/api/themes.py +71 -0
  4. flock/artifacts.py +79 -0
  5. flock/cli.py +75 -0
  6. flock/components.py +173 -0
  7. flock/dashboard/__init__.py +28 -0
  8. flock/dashboard/collector.py +283 -0
  9. flock/dashboard/events.py +182 -0
  10. flock/dashboard/launcher.py +230 -0
  11. flock/dashboard/service.py +537 -0
  12. flock/dashboard/websocket.py +235 -0
  13. flock/engines/__init__.py +6 -0
  14. flock/engines/dspy_engine.py +856 -0
  15. flock/examples.py +128 -0
  16. flock/{core/util → helper}/cli_helper.py +4 -3
  17. flock/{core/logging → logging}/__init__.py +2 -3
  18. flock/{core/logging → logging}/formatters/enum_builder.py +3 -4
  19. flock/{core/logging → logging}/formatters/theme_builder.py +19 -44
  20. flock/{core/logging → logging}/formatters/themed_formatter.py +69 -115
  21. flock/{core/logging → logging}/logging.py +77 -61
  22. flock/{core/logging → logging}/telemetry.py +20 -26
  23. flock/{core/logging → logging}/telemetry_exporter/base_exporter.py +2 -2
  24. flock/{core/logging → logging}/telemetry_exporter/file_exporter.py +6 -9
  25. flock/{core/logging → logging}/telemetry_exporter/sqlite_exporter.py +2 -3
  26. flock/{core/logging → logging}/trace_and_logged.py +20 -24
  27. flock/mcp/__init__.py +91 -0
  28. flock/{core/mcp/mcp_client.py → mcp/client.py} +103 -154
  29. flock/{core/mcp/mcp_config.py → mcp/config.py} +62 -117
  30. flock/mcp/manager.py +255 -0
  31. flock/mcp/servers/sse/__init__.py +1 -1
  32. flock/mcp/servers/sse/flock_sse_server.py +11 -53
  33. flock/mcp/servers/stdio/__init__.py +1 -1
  34. flock/mcp/servers/stdio/flock_stdio_server.py +8 -48
  35. flock/mcp/servers/streamable_http/flock_streamable_http_server.py +17 -62
  36. flock/mcp/servers/websockets/flock_websocket_server.py +7 -40
  37. flock/{core/mcp/flock_mcp_tool.py → mcp/tool.py} +16 -26
  38. flock/mcp/types/__init__.py +42 -0
  39. flock/{core/mcp → mcp}/types/callbacks.py +9 -15
  40. flock/{core/mcp → mcp}/types/factories.py +7 -6
  41. flock/{core/mcp → mcp}/types/handlers.py +13 -18
  42. flock/{core/mcp → mcp}/types/types.py +70 -74
  43. flock/{core/mcp → mcp}/util/helpers.py +1 -1
  44. flock/orchestrator.py +645 -0
  45. flock/registry.py +148 -0
  46. flock/runtime.py +262 -0
  47. flock/service.py +140 -0
  48. flock/store.py +69 -0
  49. flock/subscription.py +111 -0
  50. flock/themes/andromeda.toml +1 -1
  51. flock/themes/apple-system-colors.toml +1 -1
  52. flock/themes/arcoiris.toml +1 -1
  53. flock/themes/atomonelight.toml +1 -1
  54. flock/themes/ayu copy.toml +1 -1
  55. flock/themes/ayu-light.toml +1 -1
  56. flock/themes/belafonte-day.toml +1 -1
  57. flock/themes/belafonte-night.toml +1 -1
  58. flock/themes/blulocodark.toml +1 -1
  59. flock/themes/breeze.toml +1 -1
  60. flock/themes/broadcast.toml +1 -1
  61. flock/themes/brogrammer.toml +1 -1
  62. flock/themes/builtin-dark.toml +1 -1
  63. flock/themes/builtin-pastel-dark.toml +1 -1
  64. flock/themes/catppuccin-latte.toml +1 -1
  65. flock/themes/catppuccin-macchiato.toml +1 -1
  66. flock/themes/catppuccin-mocha.toml +1 -1
  67. flock/themes/cga.toml +1 -1
  68. flock/themes/chalk.toml +1 -1
  69. flock/themes/ciapre.toml +1 -1
  70. flock/themes/coffee-theme.toml +1 -1
  71. flock/themes/cyberpunkscarletprotocol.toml +1 -1
  72. flock/themes/dark+.toml +1 -1
  73. flock/themes/darkermatrix.toml +1 -1
  74. flock/themes/darkside.toml +1 -1
  75. flock/themes/desert.toml +1 -1
  76. flock/themes/django.toml +1 -1
  77. flock/themes/djangosmooth.toml +1 -1
  78. flock/themes/doomone.toml +1 -1
  79. flock/themes/dotgov.toml +1 -1
  80. flock/themes/dracula+.toml +1 -1
  81. flock/themes/duckbones.toml +1 -1
  82. flock/themes/encom.toml +1 -1
  83. flock/themes/espresso.toml +1 -1
  84. flock/themes/everblush.toml +1 -1
  85. flock/themes/fairyfloss.toml +1 -1
  86. flock/themes/fideloper.toml +1 -1
  87. flock/themes/fishtank.toml +1 -1
  88. flock/themes/flexoki-light.toml +1 -1
  89. flock/themes/floraverse.toml +1 -1
  90. flock/themes/framer.toml +1 -1
  91. flock/themes/galizur.toml +1 -1
  92. flock/themes/github.toml +1 -1
  93. flock/themes/grass.toml +1 -1
  94. flock/themes/grey-green.toml +1 -1
  95. flock/themes/gruvboxlight.toml +1 -1
  96. flock/themes/guezwhoz.toml +1 -1
  97. flock/themes/harper.toml +1 -1
  98. flock/themes/hax0r-blue.toml +1 -1
  99. flock/themes/hopscotch.256.toml +1 -1
  100. flock/themes/ic-green-ppl.toml +1 -1
  101. flock/themes/iceberg-dark.toml +1 -1
  102. flock/themes/japanesque.toml +1 -1
  103. flock/themes/jubi.toml +1 -1
  104. flock/themes/kibble.toml +1 -1
  105. flock/themes/kolorit.toml +1 -1
  106. flock/themes/kurokula.toml +1 -1
  107. flock/themes/materialdesigncolors.toml +1 -1
  108. flock/themes/matrix.toml +1 -1
  109. flock/themes/mellifluous.toml +1 -1
  110. flock/themes/midnight-in-mojave.toml +1 -1
  111. flock/themes/monokai-remastered.toml +1 -1
  112. flock/themes/monokai-soda.toml +1 -1
  113. flock/themes/neon.toml +1 -1
  114. flock/themes/neopolitan.toml +1 -1
  115. flock/themes/nord-light.toml +1 -1
  116. flock/themes/ocean.toml +1 -1
  117. flock/themes/onehalfdark.toml +1 -1
  118. flock/themes/onehalflight.toml +1 -1
  119. flock/themes/palenighthc.toml +1 -1
  120. flock/themes/paulmillr.toml +1 -1
  121. flock/themes/pencildark.toml +1 -1
  122. flock/themes/pnevma.toml +1 -1
  123. flock/themes/purple-rain.toml +1 -1
  124. flock/themes/purplepeter.toml +1 -1
  125. flock/themes/raycast-dark.toml +1 -1
  126. flock/themes/red-sands.toml +1 -1
  127. flock/themes/relaxed.toml +1 -1
  128. flock/themes/retro.toml +1 -1
  129. flock/themes/rose-pine.toml +1 -1
  130. flock/themes/royal.toml +1 -1
  131. flock/themes/ryuuko.toml +1 -1
  132. flock/themes/sakura.toml +1 -1
  133. flock/themes/scarlet-protocol.toml +1 -1
  134. flock/themes/seoulbones-dark.toml +1 -1
  135. flock/themes/shades-of-purple.toml +1 -1
  136. flock/themes/smyck.toml +1 -1
  137. flock/themes/softserver.toml +1 -1
  138. flock/themes/solarized-darcula.toml +1 -1
  139. flock/themes/square.toml +1 -1
  140. flock/themes/sugarplum.toml +1 -1
  141. flock/themes/thayer-bright.toml +1 -1
  142. flock/themes/tokyonight.toml +1 -1
  143. flock/themes/tomorrow.toml +1 -1
  144. flock/themes/ubuntu.toml +1 -1
  145. flock/themes/ultradark.toml +1 -1
  146. flock/themes/ultraviolent.toml +1 -1
  147. flock/themes/unikitty.toml +1 -1
  148. flock/themes/urple.toml +1 -1
  149. flock/themes/vesper.toml +1 -1
  150. flock/themes/vimbones.toml +1 -1
  151. flock/themes/wildcherry.toml +1 -1
  152. flock/themes/wilmersdorf.toml +1 -1
  153. flock/themes/wryan.toml +1 -1
  154. flock/themes/xcodedarkhc.toml +1 -1
  155. flock/themes/xcodelight.toml +1 -1
  156. flock/themes/zenbones-light.toml +1 -1
  157. flock/themes/zenwritten-dark.toml +1 -1
  158. flock/utilities.py +301 -0
  159. flock/{components/utility → utility}/output_utility_component.py +68 -53
  160. flock/visibility.py +107 -0
  161. flock_core-0.5.56b0.dist-info/METADATA +747 -0
  162. flock_core-0.5.56b0.dist-info/RECORD +398 -0
  163. flock_core-0.5.56b0.dist-info/entry_points.txt +2 -0
  164. {flock_core-0.5.0b28.dist-info → flock_core-0.5.56b0.dist-info}/licenses/LICENSE +1 -1
  165. flock/adapter/__init__.py +0 -14
  166. flock/adapter/azure_adapter.py +0 -68
  167. flock/adapter/chroma_adapter.py +0 -73
  168. flock/adapter/faiss_adapter.py +0 -97
  169. flock/adapter/pinecone_adapter.py +0 -51
  170. flock/adapter/vector_base.py +0 -47
  171. flock/cli/assets/release_notes.md +0 -140
  172. flock/cli/config.py +0 -8
  173. flock/cli/constants.py +0 -36
  174. flock/cli/create_agent.py +0 -1
  175. flock/cli/create_flock.py +0 -280
  176. flock/cli/execute_flock.py +0 -620
  177. flock/cli/load_agent.py +0 -1
  178. flock/cli/load_examples.py +0 -1
  179. flock/cli/load_flock.py +0 -192
  180. flock/cli/load_release_notes.py +0 -20
  181. flock/cli/loaded_flock_cli.py +0 -254
  182. flock/cli/manage_agents.py +0 -459
  183. flock/cli/registry_management.py +0 -889
  184. flock/cli/runner.py +0 -41
  185. flock/cli/settings.py +0 -857
  186. flock/cli/utils.py +0 -135
  187. flock/cli/view_results.py +0 -29
  188. flock/cli/yaml_editor.py +0 -396
  189. flock/components/__init__.py +0 -30
  190. flock/components/evaluation/__init__.py +0 -9
  191. flock/components/evaluation/declarative_evaluation_component.py +0 -606
  192. flock/components/routing/__init__.py +0 -15
  193. flock/components/routing/conditional_routing_component.py +0 -494
  194. flock/components/routing/default_routing_component.py +0 -103
  195. flock/components/routing/llm_routing_component.py +0 -206
  196. flock/components/utility/__init__.py +0 -22
  197. flock/components/utility/example_utility_component.py +0 -250
  198. flock/components/utility/feedback_utility_component.py +0 -206
  199. flock/components/utility/memory_utility_component.py +0 -550
  200. flock/components/utility/metrics_utility_component.py +0 -700
  201. flock/config.py +0 -61
  202. flock/core/__init__.py +0 -110
  203. flock/core/agent/__init__.py +0 -16
  204. flock/core/agent/default_agent.py +0 -216
  205. flock/core/agent/flock_agent_components.py +0 -104
  206. flock/core/agent/flock_agent_execution.py +0 -101
  207. flock/core/agent/flock_agent_integration.py +0 -260
  208. flock/core/agent/flock_agent_lifecycle.py +0 -186
  209. flock/core/agent/flock_agent_serialization.py +0 -381
  210. flock/core/api/__init__.py +0 -10
  211. flock/core/api/custom_endpoint.py +0 -45
  212. flock/core/api/endpoints.py +0 -254
  213. flock/core/api/main.py +0 -162
  214. flock/core/api/models.py +0 -97
  215. flock/core/api/run_store.py +0 -224
  216. flock/core/api/runner.py +0 -44
  217. flock/core/api/service.py +0 -214
  218. flock/core/component/__init__.py +0 -15
  219. flock/core/component/agent_component_base.py +0 -309
  220. flock/core/component/evaluation_component.py +0 -62
  221. flock/core/component/routing_component.py +0 -74
  222. flock/core/component/utility_component.py +0 -69
  223. flock/core/config/flock_agent_config.py +0 -58
  224. flock/core/config/scheduled_agent_config.py +0 -40
  225. flock/core/context/context.py +0 -213
  226. flock/core/context/context_manager.py +0 -37
  227. flock/core/context/context_vars.py +0 -10
  228. flock/core/evaluation/utils.py +0 -396
  229. flock/core/execution/batch_executor.py +0 -369
  230. flock/core/execution/evaluation_executor.py +0 -438
  231. flock/core/execution/local_executor.py +0 -31
  232. flock/core/execution/opik_executor.py +0 -103
  233. flock/core/execution/temporal_executor.py +0 -164
  234. flock/core/flock.py +0 -634
  235. flock/core/flock_agent.py +0 -336
  236. flock/core/flock_factory.py +0 -613
  237. flock/core/flock_scheduler.py +0 -166
  238. flock/core/flock_server_manager.py +0 -136
  239. flock/core/interpreter/python_interpreter.py +0 -689
  240. flock/core/mcp/__init__.py +0 -1
  241. flock/core/mcp/flock_mcp_server.py +0 -680
  242. flock/core/mcp/mcp_client_manager.py +0 -201
  243. flock/core/mcp/types/__init__.py +0 -1
  244. flock/core/mixin/dspy_integration.py +0 -403
  245. flock/core/mixin/prompt_parser.py +0 -125
  246. flock/core/orchestration/__init__.py +0 -15
  247. flock/core/orchestration/flock_batch_processor.py +0 -94
  248. flock/core/orchestration/flock_evaluator.py +0 -113
  249. flock/core/orchestration/flock_execution.py +0 -295
  250. flock/core/orchestration/flock_initialization.py +0 -149
  251. flock/core/orchestration/flock_server_manager.py +0 -67
  252. flock/core/orchestration/flock_web_server.py +0 -117
  253. flock/core/registry/__init__.py +0 -45
  254. flock/core/registry/agent_registry.py +0 -69
  255. flock/core/registry/callable_registry.py +0 -139
  256. flock/core/registry/component_discovery.py +0 -142
  257. flock/core/registry/component_registry.py +0 -64
  258. flock/core/registry/config_mapping.py +0 -64
  259. flock/core/registry/decorators.py +0 -137
  260. flock/core/registry/registry_hub.py +0 -205
  261. flock/core/registry/server_registry.py +0 -57
  262. flock/core/registry/type_registry.py +0 -86
  263. flock/core/serialization/__init__.py +0 -13
  264. flock/core/serialization/callable_registry.py +0 -52
  265. flock/core/serialization/flock_serializer.py +0 -832
  266. flock/core/serialization/json_encoder.py +0 -41
  267. flock/core/serialization/secure_serializer.py +0 -175
  268. flock/core/serialization/serializable.py +0 -342
  269. flock/core/serialization/serialization_utils.py +0 -412
  270. flock/core/util/file_path_utils.py +0 -223
  271. flock/core/util/hydrator.py +0 -309
  272. flock/core/util/input_resolver.py +0 -164
  273. flock/core/util/loader.py +0 -59
  274. flock/core/util/splitter.py +0 -219
  275. flock/di.py +0 -27
  276. flock/platform/docker_tools.py +0 -49
  277. flock/platform/jaeger_install.py +0 -86
  278. flock/webapp/__init__.py +0 -1
  279. flock/webapp/app/__init__.py +0 -0
  280. flock/webapp/app/api/__init__.py +0 -0
  281. flock/webapp/app/api/agent_management.py +0 -241
  282. flock/webapp/app/api/execution.py +0 -709
  283. flock/webapp/app/api/flock_management.py +0 -129
  284. flock/webapp/app/api/registry_viewer.py +0 -30
  285. flock/webapp/app/chat.py +0 -665
  286. flock/webapp/app/config.py +0 -104
  287. flock/webapp/app/dependencies.py +0 -117
  288. flock/webapp/app/main.py +0 -1070
  289. flock/webapp/app/middleware.py +0 -113
  290. flock/webapp/app/models_ui.py +0 -7
  291. flock/webapp/app/services/__init__.py +0 -0
  292. flock/webapp/app/services/feedback_file_service.py +0 -363
  293. flock/webapp/app/services/flock_service.py +0 -337
  294. flock/webapp/app/services/sharing_models.py +0 -81
  295. flock/webapp/app/services/sharing_store.py +0 -762
  296. flock/webapp/app/templates/theme_mapper.html +0 -326
  297. flock/webapp/app/theme_mapper.py +0 -812
  298. flock/webapp/app/utils.py +0 -85
  299. flock/webapp/run.py +0 -215
  300. flock/webapp/static/css/chat.css +0 -301
  301. flock/webapp/static/css/components.css +0 -167
  302. flock/webapp/static/css/header.css +0 -39
  303. flock/webapp/static/css/layout.css +0 -46
  304. flock/webapp/static/css/sidebar.css +0 -127
  305. flock/webapp/static/css/two-pane.css +0 -48
  306. flock/webapp/templates/base.html +0 -200
  307. flock/webapp/templates/chat.html +0 -152
  308. flock/webapp/templates/chat_settings.html +0 -19
  309. flock/webapp/templates/flock_editor.html +0 -16
  310. flock/webapp/templates/index.html +0 -12
  311. flock/webapp/templates/partials/_agent_detail_form.html +0 -93
  312. flock/webapp/templates/partials/_agent_list.html +0 -18
  313. flock/webapp/templates/partials/_agent_manager_view.html +0 -51
  314. flock/webapp/templates/partials/_agent_tools_checklist.html +0 -14
  315. flock/webapp/templates/partials/_chat_container.html +0 -15
  316. flock/webapp/templates/partials/_chat_messages.html +0 -57
  317. flock/webapp/templates/partials/_chat_settings_form.html +0 -85
  318. flock/webapp/templates/partials/_create_flock_form.html +0 -50
  319. flock/webapp/templates/partials/_dashboard_flock_detail.html +0 -17
  320. flock/webapp/templates/partials/_dashboard_flock_file_list.html +0 -16
  321. flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +0 -28
  322. flock/webapp/templates/partials/_dashboard_upload_flock_form.html +0 -16
  323. flock/webapp/templates/partials/_dynamic_input_form_content.html +0 -22
  324. flock/webapp/templates/partials/_env_vars_table.html +0 -23
  325. flock/webapp/templates/partials/_execution_form.html +0 -118
  326. flock/webapp/templates/partials/_execution_view_container.html +0 -28
  327. flock/webapp/templates/partials/_flock_file_list.html +0 -23
  328. flock/webapp/templates/partials/_flock_properties_form.html +0 -52
  329. flock/webapp/templates/partials/_flock_upload_form.html +0 -16
  330. flock/webapp/templates/partials/_header_flock_status.html +0 -5
  331. flock/webapp/templates/partials/_load_manager_view.html +0 -49
  332. flock/webapp/templates/partials/_registry_table.html +0 -25
  333. flock/webapp/templates/partials/_registry_viewer_content.html +0 -70
  334. flock/webapp/templates/partials/_results_display.html +0 -78
  335. flock/webapp/templates/partials/_settings_env_content.html +0 -9
  336. flock/webapp/templates/partials/_settings_theme_content.html +0 -14
  337. flock/webapp/templates/partials/_settings_view.html +0 -36
  338. flock/webapp/templates/partials/_share_chat_link_snippet.html +0 -11
  339. flock/webapp/templates/partials/_share_link_snippet.html +0 -35
  340. flock/webapp/templates/partials/_sidebar.html +0 -74
  341. flock/webapp/templates/partials/_streaming_results_container.html +0 -195
  342. flock/webapp/templates/partials/_structured_data_view.html +0 -40
  343. flock/webapp/templates/partials/_theme_preview.html +0 -36
  344. flock/webapp/templates/registry_viewer.html +0 -84
  345. flock/webapp/templates/shared_run_page.html +0 -140
  346. flock/workflow/__init__.py +0 -0
  347. flock/workflow/activities.py +0 -196
  348. flock/workflow/agent_activities.py +0 -24
  349. flock/workflow/agent_execution_activity.py +0 -202
  350. flock/workflow/flock_workflow.py +0 -214
  351. flock/workflow/temporal_config.py +0 -96
  352. flock/workflow/temporal_setup.py +0 -68
  353. flock_core-0.5.0b28.dist-info/METADATA +0 -274
  354. flock_core-0.5.0b28.dist-info/RECORD +0 -561
  355. flock_core-0.5.0b28.dist-info/entry_points.txt +0 -2
  356. /flock/{core/logging → logging}/formatters/themes.py +0 -0
  357. /flock/{core/logging → logging}/span_middleware/baggage_span_processor.py +0 -0
  358. /flock/{core/mcp → mcp}/util/__init__.py +0 -0
  359. {flock_core-0.5.0b28.dist-info → flock_core-0.5.56b0.dist-info}/WHEEL +0 -0
@@ -1,254 +0,0 @@
1
- # src/flock/core/api/endpoints.py
2
- """FastAPI endpoints for the Flock API, using FastAPI's dependency injection."""
3
-
4
- import uuid
5
- from typing import TYPE_CHECKING
6
-
7
- from fastapi import (
8
- APIRouter,
9
- BackgroundTasks,
10
- Depends, # Crucial import for dependency injection
11
- HTTPException,
12
- )
13
-
14
- from flock.core.logging.logging import get_logger
15
-
16
- # Import the dependency provider functions
17
- # This assumes you'll create 'src/flock/webapp/app/dependencies.py' (or similar)
18
- # with get_flock_instance and get_run_store functions.
19
- # For now, to make this file runnable in isolation for generation,
20
- # we might need temporary stubs or to adjust the import path later.
21
- # Let's assume a common location for dependencies.
22
- from flock.webapp.app.dependencies import get_flock_instance, get_run_store
23
-
24
- from .models import (
25
- FlockAPIRequest,
26
- FlockAPIResponse,
27
- FlockBatchRequest,
28
- FlockBatchResponse,
29
- )
30
-
31
- if TYPE_CHECKING:
32
- from flock.core.flock import Flock
33
-
34
- from .run_store import RunStore
35
- # We also need the _run_flock, _run_batch, _type_convert_inputs methods.
36
- # These will be part of the Flock instance itself or helper functions
37
- # that take Flock/RunStore as arguments. For now, let's assume they
38
- # are methods on the Flock instance or can be called statically with it.
39
-
40
- logger = get_logger("api.endpoints")
41
-
42
- # The create_api_router function no longer needs to be passed the FlockAPI instance
43
- # as dependencies will be injected directly into the route handlers.
44
- def create_api_router() -> APIRouter:
45
- """Creates the APIRouter for core Flock API endpoints."""
46
- router = APIRouter()
47
-
48
- # --- API Endpoints ---
49
- @router.post("/run/flock", response_model=FlockAPIResponse, tags=["Flock API Core"])
50
- async def run_flock_workflow(
51
- request_model: FlockAPIRequest, # Renamed from 'request' to avoid conflict with FastAPI's Request
52
- background_tasks: BackgroundTasks,
53
- flock_instance: "Flock" = Depends(get_flock_instance), # Injected
54
- run_store: "RunStore" = Depends(get_run_store) # Injected
55
- ):
56
- """Run a flock workflow starting with the specified agent."""
57
- run_id = None
58
- try:
59
- run_id = str(uuid.uuid4())
60
- run_store.create_run(run_id)
61
- response_data = run_store.get_run(run_id)
62
-
63
- if not response_data:
64
- logger.error(f"Failed to create run record for run_id: {run_id}")
65
- raise HTTPException(status_code=500, detail="Failed to initialize run.")
66
-
67
- processed_inputs = request_model.inputs if request_model.inputs else {}
68
- logger.info(
69
- f"API request: run flock '{request_model.agent_name}' (run_id: {run_id})",
70
- inputs=processed_inputs,
71
- )
72
-
73
- # The _run_flock logic now needs to be called. It could be a method on
74
- # flock_instance, or a static/helper function that takes flock_instance.
75
- # Let's assume it's a method on flock_instance for now.
76
- # To avoid direct calls to private-like methods from router,
77
- # Flock class would expose a public method that handles this internal logic.
78
- # For this refactoring step, let's assume a helper `_execute_flock_run` exists
79
- # that we can call.
80
-
81
- async def _execute_flock_run_task(run_id_task, agent_name_task, inputs_task):
82
- # This is a simplified version of what was in FlockAPI._run_flock
83
- try:
84
- if agent_name_task not in flock_instance.agents:
85
- raise ValueError(f"Starting agent '{agent_name_task}' not found")
86
- # Type conversion would ideally be part of the Flock's run logic
87
- # or a utility. For now, assume it's handled or simple.
88
- # typed_inputs = flock_instance._type_convert_inputs(agent_name_task, inputs_task) # Example if kept on Flock
89
- typed_inputs = inputs_task # Simplified for now
90
-
91
- result = await flock_instance.run_async(
92
- agent=agent_name_task, input=typed_inputs
93
- )
94
- run_store.update_run_result(run_id_task, result)
95
- except Exception as e_task:
96
- logger.error(f"Error in background flock run {run_id_task}: {e_task!s}", exc_info=True)
97
- run_store.update_run_status(run_id_task, "failed", str(e_task))
98
-
99
-
100
- if request_model.async_run:
101
- logger.debug(
102
- f"Running flock '{request_model.agent_name}' asynchronously (run_id: {run_id})"
103
- )
104
- background_tasks.add_task(
105
- _execute_flock_run_task,
106
- run_id,
107
- request_model.agent_name,
108
- processed_inputs,
109
- )
110
- run_store.update_run_status(run_id, "running")
111
- response_data.status = "running"
112
- else:
113
- logger.debug(
114
- f"Running flock '{request_model.agent_name}' synchronously (run_id: {run_id})"
115
- )
116
- await _execute_flock_run_task(
117
- run_id, request_model.agent_name, processed_inputs
118
- )
119
- response_data = run_store.get_run(run_id)
120
-
121
- if not response_data:
122
- logger.error(f"Run data lost for run_id: {run_id} after execution.")
123
- raise HTTPException(status_code=500, detail="Run data lost after execution.")
124
-
125
- return response_data
126
- except ValueError as ve:
127
- logger.error(f"Value error starting run for agent '{request_model.agent_name}': {ve}", exc_info=True)
128
- if run_id: run_store.update_run_status(run_id, "failed", str(ve))
129
- raise HTTPException(status_code=400, detail=str(ve))
130
- except Exception as e:
131
- error_msg = f"Internal server error during flock run: {type(e).__name__}"
132
- logger.error(f"Error starting flock run: {e!s}", exc_info=True)
133
- if run_id: run_store.update_run_status(run_id, "failed", error_msg)
134
- raise HTTPException(status_code=500, detail=error_msg)
135
-
136
- @router.post("/run/batch", response_model=FlockBatchResponse, tags=["Flock API Core"])
137
- async def run_batch_workflow(
138
- request_model: FlockBatchRequest, # Renamed from 'request'
139
- background_tasks: BackgroundTasks,
140
- flock_instance: "Flock" = Depends(get_flock_instance),
141
- run_store: "RunStore" = Depends(get_run_store)
142
- ):
143
- """Run a batch of inputs through the flock workflow."""
144
- batch_id = None
145
- try:
146
- if request_model.agent_name not in flock_instance.agents:
147
- raise ValueError(f"Agent '{request_model.agent_name}' not found in current Flock.")
148
-
149
- if isinstance(request_model.batch_inputs, list) and not request_model.batch_inputs:
150
- raise ValueError("Batch inputs list cannot be empty if provided as a list.")
151
-
152
- batch_id = str(uuid.uuid4())
153
- run_store.create_batch(batch_id)
154
- response_data = run_store.get_batch(batch_id)
155
-
156
- if not response_data:
157
- logger.error(f"Failed to create batch record for batch_id: {batch_id}")
158
- raise HTTPException(status_code=500, detail="Failed to initialize batch run.")
159
-
160
- batch_size = (
161
- len(request_model.batch_inputs)
162
- if isinstance(request_model.batch_inputs, list)
163
- else "CSV/DataFrame"
164
- )
165
- logger.info(
166
- f"API request: run batch with '{request_model.agent_name}' (batch_id: {batch_id})",
167
- batch_size=batch_size,
168
- )
169
-
170
- async def _execute_flock_batch_task(batch_id_task, batch_request_task: FlockBatchRequest):
171
- # This is a simplified version of what was in FlockAPI._run_batch
172
- try:
173
- # Directly use the flock_instance's run_batch_async method
174
- results = await flock_instance.run_batch_async(
175
- start_agent=batch_request_task.agent_name,
176
- batch_inputs=batch_request_task.batch_inputs,
177
- input_mapping=batch_request_task.input_mapping,
178
- static_inputs=batch_request_task.static_inputs,
179
- parallel=batch_request_task.parallel,
180
- max_workers=batch_request_task.max_workers,
181
- use_temporal=batch_request_task.use_temporal,
182
- box_results=batch_request_task.box_results,
183
- return_errors=batch_request_task.return_errors,
184
- silent_mode=True, # API batch runs should be internally silent
185
- write_to_csv=None # API handles CSV writing based on request if needed, not here
186
- )
187
- run_store.update_batch_result(batch_id_task, results)
188
- logger.info(f"Batch run completed (batch_id: {batch_id_task})", num_results=len(results))
189
- except Exception as e_task:
190
- logger.error(f"Error in background flock batch {batch_id_task}: {e_task!s}", exc_info=True)
191
- run_store.update_batch_status(batch_id_task, "failed", str(e_task))
192
-
193
- logger.debug(
194
- f"Running batch with '{request_model.agent_name}' asynchronously (batch_id: {batch_id})"
195
- )
196
- background_tasks.add_task(
197
- _execute_flock_batch_task,
198
- batch_id,
199
- request_model, # Pass the Pydantic request model
200
- )
201
- run_store.update_batch_status(batch_id, "running")
202
- response_data.status = "running"
203
-
204
- return response_data
205
- except ValueError as ve:
206
- error_msg = f"Value error starting batch for agent '{request_model.agent_name}': {ve}"
207
- logger.error(error_msg, exc_info=True)
208
- if batch_id: run_store.update_batch_status(batch_id, "failed", str(ve))
209
- raise HTTPException(status_code=400, detail=str(ve))
210
- except Exception as e:
211
- error_msg = f"Internal server error during batch run: {type(e).__name__}: {e!s}"
212
- logger.error(error_msg, exc_info=True)
213
- if batch_id: run_store.update_batch_status(batch_id, "failed", error_msg)
214
- raise HTTPException(status_code=500, detail=error_msg)
215
-
216
- @router.get("/run/{run_id}", response_model=FlockAPIResponse, tags=["Flock API Core"])
217
- async def get_run_status(
218
- run_id: str,
219
- run_store: "RunStore" = Depends(get_run_store)
220
- ):
221
- """Get the status of a specific run."""
222
- logger.debug(f"API request: get status for run_id: {run_id}")
223
- run_data = run_store.get_run(run_id)
224
- if not run_data:
225
- logger.warning(f"Run ID not found: {run_id}")
226
- raise HTTPException(status_code=404, detail="Run not found")
227
- return run_data
228
-
229
- @router.get("/batch/{batch_id}", response_model=FlockBatchResponse, tags=["Flock API Core"])
230
- async def get_batch_status(
231
- batch_id: str,
232
- run_store: "RunStore" = Depends(get_run_store)
233
- ):
234
- """Get the status and results of a specific batch run."""
235
- logger.debug(f"API request: get status for batch_id: {batch_id}")
236
- batch_data = run_store.get_batch(batch_id)
237
- if not batch_data:
238
- logger.warning(f"Batch ID not found: {batch_id}")
239
- raise HTTPException(status_code=404, detail="Batch not found")
240
- return batch_data
241
-
242
- @router.get("/agents", tags=["Flock API Core"])
243
- async def list_agents(
244
- flock_instance: "Flock" = Depends(get_flock_instance)
245
- ):
246
- """List all available agents in the currently loaded Flock."""
247
- logger.debug("API request: list agents")
248
- agents_list = [
249
- agent.to_dict()
250
- for agent in flock_instance.agents.values()
251
- ]
252
- return {"agents": agents_list}
253
-
254
- return router
flock/core/api/main.py DELETED
@@ -1,162 +0,0 @@
1
- # src/flock/core/api/main.py
2
- """This module defines the FlockAPI class, which is now primarily responsible for
3
- managing and adding user-defined custom API endpoints to a main FastAPI application.
4
- """
5
-
6
- import inspect
7
- from collections.abc import Callable, Sequence
8
- from typing import TYPE_CHECKING, Any
9
-
10
- from fastapi import ( # Ensure Request is aliased
11
- Body,
12
- Depends,
13
- FastAPI,
14
- Request as FastAPIRequest,
15
- )
16
-
17
- from flock.core.logging.logging import get_logger
18
-
19
- from .custom_endpoint import FlockEndpoint
20
-
21
- if TYPE_CHECKING:
22
- from flock.core.flock import Flock
23
-
24
- logger = get_logger("core.api.custom_setup")
25
-
26
-
27
- class FlockAPI:
28
- """A helper class to manage the addition of user-defined custom API endpoints
29
- to an existing FastAPI application, in the context of a Flock instance.
30
- """
31
-
32
- def __init__(
33
- self,
34
- flock_instance: "Flock",
35
- custom_endpoints: Sequence[FlockEndpoint] | dict[tuple[str, list[str] | None], Callable[..., Any]] | None = None,
36
- ):
37
- self.flock = flock_instance
38
- self.processed_custom_endpoints: list[FlockEndpoint] = []
39
- if custom_endpoints:
40
- if isinstance(custom_endpoints, dict):
41
- logger.warning("Received custom_endpoints as dict, converting. Prefer Sequence[FlockEndpoint].")
42
- for (path, methods), cb in custom_endpoints.items():
43
- self.processed_custom_endpoints.append(
44
- FlockEndpoint(path=path, methods=list(methods) if methods else ["GET"], callback=cb)
45
- )
46
- elif isinstance(custom_endpoints, Sequence):
47
- for ep_item in custom_endpoints: # Renamed loop variable
48
- if isinstance(ep_item, FlockEndpoint):
49
- self.processed_custom_endpoints.append(ep_item)
50
- else:
51
- logger.warning(f"Skipping non-FlockEndpoint item in custom_endpoints sequence: {type(ep_item)}")
52
- else:
53
- logger.warning(f"Unsupported type for custom_endpoints: {type(custom_endpoints)}")
54
- logger.info(
55
- f"FlockAPI helper initialized for Flock: '{self.flock.name}'. "
56
- f"Prepared {len(self.processed_custom_endpoints)} custom endpoints."
57
- )
58
-
59
- def add_custom_routes_to_app(self, app: FastAPI):
60
- if not self.processed_custom_endpoints:
61
- logger.debug("No custom endpoints to add to the FastAPI app.")
62
- return
63
-
64
- logger.info(f"Adding {len(self.processed_custom_endpoints)} custom endpoints to the FastAPI app instance.")
65
-
66
- for current_ep_def in self.processed_custom_endpoints: # Use current_ep_def to avoid closure issues
67
-
68
- # This factory now takes current_ep_def to ensure it uses the correct endpoint's details
69
- def _create_handler_factory(
70
- # Capture the specific endpoint definition for this factory instance
71
- specific_ep: FlockEndpoint
72
- ):
73
- # This inner function prepares the payload and calls the user's callback
74
- async def _invoke_user_callback(
75
- request_param: FastAPIRequest, # Parameter for FastAPI's Request object
76
- body_param: Any, # Will be populated by the _route_handler
77
- query_param: Any # Will be populated by the _route_handler
78
- ):
79
- payload_to_user: dict[str, Any] = {"flock": self.flock} # self here refers to FlockAPI instance
80
-
81
- if request_param: # Ensure request_param is not None
82
- payload_to_user.update(request_param.path_params)
83
- # query_param is already the parsed Pydantic model or None
84
- if specific_ep.query_model and query_param is not None:
85
- payload_to_user["query"] = query_param
86
- # Fallback for raw query if callback expects 'query' but no query_model was set
87
- elif 'query' in inspect.signature(specific_ep.callback).parameters and not specific_ep.query_model:
88
- if request_param.query_params:
89
- payload_to_user["query"] = dict(request_param.query_params)
90
-
91
- # body_param is already the parsed Pydantic model or None
92
- if specific_ep.request_model and body_param is not None:
93
- payload_to_user["body"] = body_param
94
- # Fallback for raw body if callback expects 'body' but no request_model was set
95
- elif 'body' in inspect.signature(specific_ep.callback).parameters and \
96
- not specific_ep.request_model and \
97
- request_param.method in {"POST", "PUT", "PATCH"}:
98
- try: payload_to_user["body"] = await request_param.json()
99
- except Exception: payload_to_user["body"] = await request_param.body()
100
-
101
- # If user callback explicitly asks for 'request'
102
- if 'request' in inspect.signature(specific_ep.callback).parameters:
103
- payload_to_user['request'] = request_param
104
-
105
-
106
- user_callback_sig = inspect.signature(specific_ep.callback)
107
- final_kwargs = {
108
- k: v for k, v in payload_to_user.items() if k in user_callback_sig.parameters
109
- }
110
-
111
- if inspect.iscoroutinefunction(specific_ep.callback):
112
- return await specific_ep.callback(**final_kwargs)
113
- return specific_ep.callback(**final_kwargs)
114
-
115
- # --- Select the correct handler signature based on specific_ep's models ---
116
- if specific_ep.request_model and specific_ep.query_model:
117
- async def _route_handler_body_query(
118
- request: FastAPIRequest, # Correct alias for FastAPI Request
119
- body: specific_ep.request_model = Body(...), # type: ignore
120
- query: specific_ep.query_model = Depends(specific_ep.query_model) # type: ignore
121
- ):
122
- return await _invoke_user_callback(request, body, query)
123
- return _route_handler_body_query
124
- elif specific_ep.request_model and not specific_ep.query_model:
125
- async def _route_handler_body_only(
126
- request: FastAPIRequest, # Correct alias
127
- body: specific_ep.request_model = Body(...) # type: ignore
128
- ):
129
- return await _invoke_user_callback(request, body, None)
130
- return _route_handler_body_only
131
- elif not specific_ep.request_model and specific_ep.query_model:
132
- async def _route_handler_query_only(
133
- request: FastAPIRequest, # Correct alias
134
- query: specific_ep.query_model = Depends(specific_ep.query_model) # type: ignore
135
- ):
136
- return await _invoke_user_callback(request, None, query)
137
- return _route_handler_query_only
138
- else: # Neither request_model nor query_model
139
- async def _route_handler_request_only(
140
- request: FastAPIRequest # Correct alias
141
- ):
142
- return await _invoke_user_callback(request, None, None)
143
- return _route_handler_request_only
144
-
145
- # Create the handler for the current_ep_def
146
- selected_handler = _create_handler_factory(current_ep_def) # Pass current_ep_def
147
- selected_handler.__name__ = f"handler_for_{current_ep_def.path.replace('/', '_').lstrip('_')}_{current_ep_def.methods[0]}"
148
-
149
-
150
- app.add_api_route(
151
- current_ep_def.path,
152
- selected_handler,
153
- methods=current_ep_def.methods or ["GET"],
154
- name=current_ep_def.name or f"custom:{current_ep_def.path.replace('/', '_').lstrip('_')}",
155
- include_in_schema=current_ep_def.include_in_schema,
156
- response_model=current_ep_def.response_model,
157
- summary=current_ep_def.summary,
158
- description=current_ep_def.description,
159
- dependencies=current_ep_def.dependencies,
160
- tags=["Flock API Custom Endpoints"],
161
- )
162
- logger.debug(f"Added custom route to app: {current_ep_def.methods} {current_ep_def.path} (Handler: {selected_handler.__name__}, Summary: {current_ep_def.summary})")
flock/core/api/models.py DELETED
@@ -1,97 +0,0 @@
1
- # src/flock/core/api/models.py
2
- """Pydantic models for the Flock API."""
3
-
4
- from datetime import datetime
5
- from typing import Any
6
-
7
- from pydantic import BaseModel, Field
8
-
9
-
10
- class FlockAPIRequest(BaseModel):
11
- """Request model for running an agent via JSON API."""
12
-
13
- agent_name: str = Field(..., description="Name of the agent to run")
14
- inputs: dict[str, Any] = Field(
15
- default_factory=dict, description="Input data for the agent"
16
- )
17
- async_run: bool = Field(
18
- default=False, description="Whether to run asynchronously"
19
- )
20
-
21
-
22
- class FlockAPIResponse(BaseModel):
23
- """Response model for API run requests."""
24
-
25
- run_id: str = Field(..., description="Unique ID for this run")
26
- status: str = Field(..., description="Status of the run")
27
- result: dict[str, Any] | None = Field(
28
- None, description="Run result if completed"
29
- )
30
- started_at: datetime = Field(..., description="When the run started")
31
- completed_at: datetime | None = Field(
32
- None, description="When the run completed"
33
- )
34
- error: str | None = Field(None, description="Error message if failed")
35
-
36
-
37
- class FlockBatchRequest(BaseModel):
38
- """Request model for batch processing via JSON API."""
39
-
40
- agent_name: str = Field(..., description="Name of the agent to run")
41
- batch_inputs: list[dict[str, Any]] | str = Field(
42
- ..., description="List of input dictionaries or path to CSV file"
43
- )
44
- input_mapping: dict[str, str] | None = Field(
45
- None, description="Maps DataFrame/CSV column names to agent input keys"
46
- )
47
- static_inputs: dict[str, Any] | None = Field(
48
- None, description="Inputs constant across all batch runs"
49
- )
50
- parallel: bool = Field(
51
- default=True, description="Whether to run jobs in parallel"
52
- )
53
- max_workers: int = Field(
54
- default=5, description="Max concurrent workers for parallel runs"
55
- )
56
- use_temporal: bool | None = Field(
57
- None, description="Override Flock's enable_temporal setting"
58
- )
59
- box_results: bool = Field(
60
- default=True, description="Wrap results in Box objects"
61
- )
62
- return_errors: bool = Field(
63
- default=False, description="Return Exception objects for failed runs"
64
- )
65
- silent_mode: bool = Field(
66
- default=True, description="Suppress output and show progress bar"
67
- )
68
- write_to_csv: str | None = Field(
69
- None, description="Path to save results as CSV file"
70
- )
71
-
72
-
73
- class FlockBatchResponse(BaseModel):
74
- """Response model for batch processing requests."""
75
-
76
- batch_id: str = Field(..., description="Unique ID for this batch run")
77
- status: str = Field(..., description="Status of the batch run")
78
- results: list[Any] = Field(
79
- default_factory=list,
80
- description="List of results from batch processing",
81
- )
82
- started_at: datetime = Field(..., description="When the batch run started")
83
- completed_at: datetime | None = Field(
84
- None, description="When the batch run completed"
85
- )
86
- error: str | None = Field(None, description="Error message if failed")
87
-
88
- # Additional fields for batch progress tracking
89
- total_items: int = Field(
90
- 0, description="Total number of items in the batch"
91
- )
92
- completed_items: int = Field(
93
- 0, description="Number of completed items in the batch"
94
- )
95
- progress_percentage: float = Field(
96
- 0.0, description="Percentage of completion (0-100)"
97
- )