flock-core 0.5.0b27__py3-none-any.whl → 0.5.0b50__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 (357) 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.0b50.dist-info/METADATA +747 -0
  162. flock_core-0.5.0b50.dist-info/RECORD +398 -0
  163. flock_core-0.5.0b50.dist-info/entry_points.txt +2 -0
  164. {flock_core-0.5.0b27.dist-info → flock_core-0.5.0b50.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 -15
  197. flock/components/utility/memory_utility_component.py +0 -550
  198. flock/components/utility/metrics_utility_component.py +0 -700
  199. flock/config.py +0 -61
  200. flock/core/__init__.py +0 -110
  201. flock/core/agent/__init__.py +0 -16
  202. flock/core/agent/default_agent.py +0 -180
  203. flock/core/agent/flock_agent_components.py +0 -104
  204. flock/core/agent/flock_agent_execution.py +0 -101
  205. flock/core/agent/flock_agent_integration.py +0 -260
  206. flock/core/agent/flock_agent_lifecycle.py +0 -186
  207. flock/core/agent/flock_agent_serialization.py +0 -381
  208. flock/core/api/__init__.py +0 -10
  209. flock/core/api/custom_endpoint.py +0 -45
  210. flock/core/api/endpoints.py +0 -254
  211. flock/core/api/main.py +0 -162
  212. flock/core/api/models.py +0 -97
  213. flock/core/api/run_store.py +0 -224
  214. flock/core/api/runner.py +0 -44
  215. flock/core/api/service.py +0 -214
  216. flock/core/component/__init__.py +0 -15
  217. flock/core/component/agent_component_base.py +0 -309
  218. flock/core/component/evaluation_component.py +0 -62
  219. flock/core/component/routing_component.py +0 -74
  220. flock/core/component/utility_component.py +0 -69
  221. flock/core/config/flock_agent_config.py +0 -58
  222. flock/core/config/scheduled_agent_config.py +0 -40
  223. flock/core/context/context.py +0 -213
  224. flock/core/context/context_manager.py +0 -37
  225. flock/core/context/context_vars.py +0 -10
  226. flock/core/evaluation/utils.py +0 -396
  227. flock/core/execution/batch_executor.py +0 -369
  228. flock/core/execution/evaluation_executor.py +0 -438
  229. flock/core/execution/local_executor.py +0 -31
  230. flock/core/execution/opik_executor.py +0 -103
  231. flock/core/execution/temporal_executor.py +0 -164
  232. flock/core/flock.py +0 -634
  233. flock/core/flock_agent.py +0 -336
  234. flock/core/flock_factory.py +0 -551
  235. flock/core/flock_scheduler.py +0 -166
  236. flock/core/flock_server_manager.py +0 -136
  237. flock/core/interpreter/python_interpreter.py +0 -689
  238. flock/core/mcp/__init__.py +0 -1
  239. flock/core/mcp/flock_mcp_server.py +0 -680
  240. flock/core/mcp/mcp_client_manager.py +0 -201
  241. flock/core/mcp/types/__init__.py +0 -1
  242. flock/core/mixin/dspy_integration.py +0 -403
  243. flock/core/mixin/prompt_parser.py +0 -125
  244. flock/core/orchestration/__init__.py +0 -15
  245. flock/core/orchestration/flock_batch_processor.py +0 -94
  246. flock/core/orchestration/flock_evaluator.py +0 -113
  247. flock/core/orchestration/flock_execution.py +0 -295
  248. flock/core/orchestration/flock_initialization.py +0 -149
  249. flock/core/orchestration/flock_server_manager.py +0 -67
  250. flock/core/orchestration/flock_web_server.py +0 -117
  251. flock/core/registry/__init__.py +0 -45
  252. flock/core/registry/agent_registry.py +0 -69
  253. flock/core/registry/callable_registry.py +0 -139
  254. flock/core/registry/component_discovery.py +0 -142
  255. flock/core/registry/component_registry.py +0 -64
  256. flock/core/registry/config_mapping.py +0 -64
  257. flock/core/registry/decorators.py +0 -137
  258. flock/core/registry/registry_hub.py +0 -205
  259. flock/core/registry/server_registry.py +0 -57
  260. flock/core/registry/type_registry.py +0 -86
  261. flock/core/serialization/__init__.py +0 -13
  262. flock/core/serialization/callable_registry.py +0 -52
  263. flock/core/serialization/flock_serializer.py +0 -832
  264. flock/core/serialization/json_encoder.py +0 -41
  265. flock/core/serialization/secure_serializer.py +0 -175
  266. flock/core/serialization/serializable.py +0 -342
  267. flock/core/serialization/serialization_utils.py +0 -412
  268. flock/core/util/file_path_utils.py +0 -223
  269. flock/core/util/hydrator.py +0 -309
  270. flock/core/util/input_resolver.py +0 -164
  271. flock/core/util/loader.py +0 -59
  272. flock/core/util/splitter.py +0 -219
  273. flock/di.py +0 -27
  274. flock/platform/docker_tools.py +0 -49
  275. flock/platform/jaeger_install.py +0 -86
  276. flock/webapp/__init__.py +0 -1
  277. flock/webapp/app/__init__.py +0 -0
  278. flock/webapp/app/api/__init__.py +0 -0
  279. flock/webapp/app/api/agent_management.py +0 -241
  280. flock/webapp/app/api/execution.py +0 -709
  281. flock/webapp/app/api/flock_management.py +0 -129
  282. flock/webapp/app/api/registry_viewer.py +0 -30
  283. flock/webapp/app/chat.py +0 -665
  284. flock/webapp/app/config.py +0 -104
  285. flock/webapp/app/dependencies.py +0 -117
  286. flock/webapp/app/main.py +0 -1070
  287. flock/webapp/app/middleware.py +0 -113
  288. flock/webapp/app/models_ui.py +0 -7
  289. flock/webapp/app/services/__init__.py +0 -0
  290. flock/webapp/app/services/feedback_file_service.py +0 -363
  291. flock/webapp/app/services/flock_service.py +0 -337
  292. flock/webapp/app/services/sharing_models.py +0 -81
  293. flock/webapp/app/services/sharing_store.py +0 -598
  294. flock/webapp/app/templates/theme_mapper.html +0 -326
  295. flock/webapp/app/theme_mapper.py +0 -812
  296. flock/webapp/app/utils.py +0 -85
  297. flock/webapp/run.py +0 -215
  298. flock/webapp/static/css/chat.css +0 -301
  299. flock/webapp/static/css/components.css +0 -167
  300. flock/webapp/static/css/header.css +0 -39
  301. flock/webapp/static/css/layout.css +0 -46
  302. flock/webapp/static/css/sidebar.css +0 -127
  303. flock/webapp/static/css/two-pane.css +0 -48
  304. flock/webapp/templates/base.html +0 -200
  305. flock/webapp/templates/chat.html +0 -152
  306. flock/webapp/templates/chat_settings.html +0 -19
  307. flock/webapp/templates/flock_editor.html +0 -16
  308. flock/webapp/templates/index.html +0 -12
  309. flock/webapp/templates/partials/_agent_detail_form.html +0 -93
  310. flock/webapp/templates/partials/_agent_list.html +0 -18
  311. flock/webapp/templates/partials/_agent_manager_view.html +0 -51
  312. flock/webapp/templates/partials/_agent_tools_checklist.html +0 -14
  313. flock/webapp/templates/partials/_chat_container.html +0 -15
  314. flock/webapp/templates/partials/_chat_messages.html +0 -57
  315. flock/webapp/templates/partials/_chat_settings_form.html +0 -85
  316. flock/webapp/templates/partials/_create_flock_form.html +0 -50
  317. flock/webapp/templates/partials/_dashboard_flock_detail.html +0 -17
  318. flock/webapp/templates/partials/_dashboard_flock_file_list.html +0 -16
  319. flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +0 -28
  320. flock/webapp/templates/partials/_dashboard_upload_flock_form.html +0 -16
  321. flock/webapp/templates/partials/_dynamic_input_form_content.html +0 -22
  322. flock/webapp/templates/partials/_env_vars_table.html +0 -23
  323. flock/webapp/templates/partials/_execution_form.html +0 -118
  324. flock/webapp/templates/partials/_execution_view_container.html +0 -28
  325. flock/webapp/templates/partials/_flock_file_list.html +0 -23
  326. flock/webapp/templates/partials/_flock_properties_form.html +0 -52
  327. flock/webapp/templates/partials/_flock_upload_form.html +0 -16
  328. flock/webapp/templates/partials/_header_flock_status.html +0 -5
  329. flock/webapp/templates/partials/_load_manager_view.html +0 -49
  330. flock/webapp/templates/partials/_registry_table.html +0 -25
  331. flock/webapp/templates/partials/_registry_viewer_content.html +0 -70
  332. flock/webapp/templates/partials/_results_display.html +0 -78
  333. flock/webapp/templates/partials/_settings_env_content.html +0 -9
  334. flock/webapp/templates/partials/_settings_theme_content.html +0 -14
  335. flock/webapp/templates/partials/_settings_view.html +0 -36
  336. flock/webapp/templates/partials/_share_chat_link_snippet.html +0 -11
  337. flock/webapp/templates/partials/_share_link_snippet.html +0 -35
  338. flock/webapp/templates/partials/_sidebar.html +0 -74
  339. flock/webapp/templates/partials/_streaming_results_container.html +0 -195
  340. flock/webapp/templates/partials/_structured_data_view.html +0 -40
  341. flock/webapp/templates/partials/_theme_preview.html +0 -36
  342. flock/webapp/templates/registry_viewer.html +0 -84
  343. flock/webapp/templates/shared_run_page.html +0 -140
  344. flock/workflow/__init__.py +0 -0
  345. flock/workflow/activities.py +0 -196
  346. flock/workflow/agent_activities.py +0 -24
  347. flock/workflow/agent_execution_activity.py +0 -202
  348. flock/workflow/flock_workflow.py +0 -214
  349. flock/workflow/temporal_config.py +0 -96
  350. flock/workflow/temporal_setup.py +0 -68
  351. flock_core-0.5.0b27.dist-info/METADATA +0 -274
  352. flock_core-0.5.0b27.dist-info/RECORD +0 -559
  353. flock_core-0.5.0b27.dist-info/entry_points.txt +0 -2
  354. /flock/{core/logging → logging}/formatters/themes.py +0 -0
  355. /flock/{core/logging → logging}/span_middleware/baggage_span_processor.py +0 -0
  356. /flock/{core/mcp → mcp}/util/__init__.py +0 -0
  357. {flock_core-0.5.0b27.dist-info → flock_core-0.5.0b50.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
- )