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,224 +0,0 @@
1
- # src/flock/core/api/run_store.py
2
- """Manages the state of active and completed Flock runs."""
3
-
4
- import threading
5
- from datetime import datetime
6
- from typing import Any
7
-
8
- from flock.core.logging.logging import get_logger
9
-
10
- from .models import ( # Import from the models file
11
- FlockAPIResponse,
12
- FlockBatchResponse,
13
- )
14
-
15
- logger = get_logger("api.run_store")
16
-
17
-
18
- class RunStore:
19
- """Stores and manages the state of Flock runs."""
20
-
21
- def __init__(self):
22
- self._runs: dict[str, FlockAPIResponse] = {}
23
- self._batches: dict[str, FlockBatchResponse] = {}
24
- self._lock = threading.Lock() # Basic lock for thread safety
25
-
26
- def create_run(self, run_id: str) -> FlockAPIResponse:
27
- """Creates a new run record with 'starting' status."""
28
- with self._lock:
29
- if run_id in self._runs:
30
- logger.warning(f"Run ID {run_id} already exists. Overwriting.")
31
- response = FlockAPIResponse(
32
- run_id=run_id, status="starting", started_at=datetime.now()
33
- )
34
- self._runs[run_id] = response
35
- logger.debug(f"Created run record for run_id: {run_id}")
36
- return response
37
-
38
- def get_run(self, run_id: str) -> FlockAPIResponse | None:
39
- """Gets the status of a run."""
40
- with self._lock:
41
- return self._runs.get(run_id)
42
-
43
- def update_run_status(
44
- self, run_id: str, status: str, error: str | None = None
45
- ):
46
- """Updates the status and potentially error of a run."""
47
- with self._lock:
48
- if run_id in self._runs:
49
- self._runs[run_id].status = status
50
- if error:
51
- self._runs[run_id].error = error
52
- if status in ["completed", "failed"]:
53
- self._runs[run_id].completed_at = datetime.now()
54
- logger.debug(f"Updated status for run_id {run_id} to {status}")
55
- else:
56
- logger.warning(
57
- f"Attempted to update status for non-existent run_id: {run_id}"
58
- )
59
-
60
- def update_run_result(self, run_id: str, result: dict):
61
- """Updates the result of a completed run."""
62
- with self._lock:
63
- if run_id in self._runs:
64
- # Ensure result is serializable (e.g., convert Box)
65
- final_result = (
66
- dict(result) if hasattr(result, "to_dict") else result
67
- )
68
- self._runs[run_id].result = final_result
69
- self._runs[run_id].status = "completed"
70
- self._runs[run_id].completed_at = datetime.now()
71
- logger.debug(f"Updated result for completed run_id: {run_id}")
72
- else:
73
- logger.warning(
74
- f"Attempted to update result for non-existent run_id: {run_id}"
75
- )
76
-
77
- def create_batch(self, batch_id: str) -> FlockBatchResponse:
78
- """Creates a new batch record with 'starting' status."""
79
- with self._lock:
80
- if batch_id in self._batches:
81
- logger.warning(
82
- f"Batch ID {batch_id} already exists. Overwriting."
83
- )
84
- response = FlockBatchResponse(
85
- batch_id=batch_id,
86
- status="starting",
87
- results=[],
88
- started_at=datetime.now(),
89
- total_items=0,
90
- completed_items=0,
91
- progress_percentage=0.0,
92
- )
93
- self._batches[batch_id] = response
94
- logger.debug(f"Created batch record for batch_id: {batch_id}")
95
- return response
96
-
97
- def get_batch(self, batch_id: str) -> FlockBatchResponse | None:
98
- """Gets the status of a batch run."""
99
- with self._lock:
100
- return self._batches.get(batch_id)
101
-
102
- def update_batch_status(
103
- self, batch_id: str, status: str, error: str | None = None
104
- ):
105
- """Updates the status and potentially error of a batch run."""
106
- with self._lock:
107
- if batch_id in self._batches:
108
- self._batches[batch_id].status = status
109
- if error:
110
- self._batches[batch_id].error = error
111
- if status in ["completed", "failed"]:
112
- self._batches[batch_id].completed_at = datetime.now()
113
- # When completed, ensure progress is 100%
114
- if (
115
- status == "completed"
116
- and self._batches[batch_id].total_items > 0
117
- ):
118
- self._batches[batch_id].completed_items = self._batches[
119
- batch_id
120
- ].total_items
121
- self._batches[batch_id].progress_percentage = 100.0
122
- logger.debug(
123
- f"Updated status for batch_id {batch_id} to {status}"
124
- )
125
- else:
126
- logger.warning(
127
- f"Attempted to update status for non-existent batch_id: {batch_id}"
128
- )
129
-
130
- def update_batch_result(self, batch_id: str, results: list[Any]):
131
- """Updates the results of a completed batch run."""
132
- with self._lock:
133
- if batch_id in self._batches:
134
- # Ensure results are serializable
135
- final_results = [
136
- dict(r) if hasattr(r, "to_dict") else r for r in results
137
- ]
138
- self._batches[batch_id].results = final_results
139
- self._batches[batch_id].status = "completed"
140
- self._batches[batch_id].completed_at = datetime.now()
141
-
142
- # Update progress tracking
143
- self._batches[batch_id].completed_items = len(final_results)
144
- self._batches[batch_id].total_items = len(final_results)
145
- self._batches[batch_id].progress_percentage = 100.0
146
-
147
- logger.debug(
148
- f"Updated results for completed batch_id: {batch_id}"
149
- )
150
- else:
151
- logger.warning(
152
- f"Attempted to update results for non-existent batch_id: {batch_id}"
153
- )
154
-
155
- def set_batch_total_items(self, batch_id: str, total_items: int):
156
- """Sets the total number of items in a batch."""
157
- try:
158
- with self._lock:
159
- if batch_id in self._batches:
160
- self._batches[batch_id].total_items = total_items
161
- # Recalculate percentage
162
- if total_items > 0:
163
- self._batches[batch_id].progress_percentage = (
164
- self._batches[batch_id].completed_items
165
- / total_items
166
- * 100.0
167
- )
168
- logger.debug(
169
- f"Set total_items for batch_id {batch_id} to {total_items}"
170
- )
171
- else:
172
- logger.warning(
173
- f"Attempted to set total_items for non-existent batch_id: {batch_id}"
174
- )
175
- except Exception as e:
176
- logger.error(f"Error setting batch total items: {e}", exc_info=True)
177
-
178
- def update_batch_progress(
179
- self,
180
- batch_id: str,
181
- completed_items: int,
182
- partial_results: list[Any] = None,
183
- ):
184
- """Updates the progress of a batch run and optionally adds partial results.
185
-
186
- Args:
187
- batch_id: The ID of the batch to update
188
- completed_items: The number of items that have been completed
189
- partial_results: Optional list of results for completed items to add to the batch
190
- """
191
- try:
192
- with self._lock:
193
- if batch_id in self._batches:
194
- self._batches[batch_id].completed_items = completed_items
195
-
196
- # Calculate percentage if we have a total
197
- if self._batches[batch_id].total_items > 0:
198
- self._batches[batch_id].progress_percentage = (
199
- completed_items
200
- / self._batches[batch_id].total_items
201
- * 100.0
202
- )
203
-
204
- # Add partial results if provided
205
- if partial_results:
206
- # Ensure results are serializable
207
- final_results = [
208
- dict(r) if hasattr(r, "to_dict") else r
209
- for r in partial_results
210
- ]
211
- self._batches[batch_id].results = final_results
212
-
213
- logger.debug(
214
- f"Updated progress for batch_id {batch_id}: {completed_items}/{self._batches[batch_id].total_items} "
215
- f"({self._batches[batch_id].progress_percentage:.1f}%)"
216
- )
217
- else:
218
- logger.warning(
219
- f"Attempted to update progress for non-existent batch_id: {batch_id}"
220
- )
221
- except Exception as e:
222
- logger.error(f"Error updating batch progress: {e}", exc_info=True)
223
-
224
- # Add methods for cleanup, persistence, etc. later
flock/core/api/runner.py DELETED
@@ -1,44 +0,0 @@
1
- # src/flock/api/runner.py
2
- """Provides functionality to start the Flock API server."""
3
-
4
- from collections.abc import Callable, Sequence
5
- from typing import TYPE_CHECKING, Any
6
-
7
- from flock.core.api.custom_endpoint import FlockEndpoint
8
- from flock.core.logging.logging import get_logger
9
-
10
- if TYPE_CHECKING:
11
- from flock.core.flock import Flock
12
-
13
- logger = get_logger("api.runner")
14
-
15
-
16
- def start_flock_api(
17
- flock: "Flock",
18
- host: str = "127.0.0.1",
19
- port: int = 8344,
20
- server_name: str = "Flock API",
21
- create_ui: bool = False,
22
- custom_endpoints: Sequence[FlockEndpoint] | dict[tuple[str, list[str] | None], Callable[..., Any]] | None = None,
23
- ) -> None:
24
- """Start a REST API server for the given Flock instance."""
25
- try:
26
- # Import API class locally to avoid making it a hard dependency for core flock
27
- from flock.core.api import FlockAPI
28
- except ImportError:
29
- logger.error(
30
- "API components not found. Cannot start API. "
31
- "Ensure 'fastapi' and 'uvicorn' are installed."
32
- )
33
- return
34
-
35
- logger.info(
36
- f"Preparing to start API server for Flock '{flock.name}' on {host}:{port} {'with UI' if create_ui else 'without UI'}"
37
- )
38
- api_instance = FlockAPI(flock, custom_endpoints=custom_endpoints) # Pass the Flock instance to the API
39
- api_instance.start(
40
- host=host,
41
- port=port,
42
- server_name=server_name,
43
- create_ui=create_ui,
44
- )
flock/core/api/service.py DELETED
@@ -1,214 +0,0 @@
1
- # flock/core/api/service.py
2
- from typing import TYPE_CHECKING, Any
3
-
4
- if TYPE_CHECKING:
5
- from flock.core.api.endpoints import FlockBatchRequest
6
- from flock.core.api.run_store import RunStore
7
- from flock.core.flock import Flock
8
-
9
-
10
- from flock.core.logging.logging import get_logger
11
-
12
- logger = get_logger("flock.api")
13
-
14
- class FlockApiService:
15
- def __init__(self, flock_instance: "Flock", run_store_instance: "RunStore"):
16
- self.flock = flock_instance
17
- self.run_store = run_store_instance
18
- # You would move the _run_flock, _run_batch, _type_convert_inputs methods here
19
- # from the old FlockAPI class.
20
- async def _run_flock(
21
- self, run_id: str, agent_name: str, inputs: dict[str, Any]
22
- ):
23
- """Executes a flock workflow run (internal helper)."""
24
- try:
25
- if agent_name not in self.flock.agents:
26
- raise ValueError(f"Starting agent '{agent_name}' not found")
27
-
28
- typed_inputs = self._type_convert_inputs(agent_name, inputs)
29
-
30
- logger.debug(
31
- f"Executing flock workflow starting with '{agent_name}' (run_id: {run_id})",
32
- inputs=typed_inputs,
33
- )
34
- # Flock.run_async now handles context creation and execution
35
- result = await self.flock.run_async(
36
- agent=agent_name, input=typed_inputs
37
- )
38
- self.run_store.update_run_result(run_id, result)
39
-
40
- final_agent_name = (
41
- result.get("agent_name", "N/A") if isinstance(result, dict) else "N/A"
42
- ) # Handle if result is not a dict (e.g. Box)
43
- logger.info(
44
- f"Flock workflow completed (run_id: {run_id})",
45
- final_agent=final_agent_name,
46
- )
47
- except Exception as e:
48
- logger.error(
49
- f"Error in flock run {run_id} (started with '{agent_name}'): {e!s}",
50
- exc_info=True,
51
- )
52
- self.run_store.update_run_status(run_id, "failed", str(e))
53
- raise
54
-
55
- async def _run_batch(self, batch_id: str, request: "FlockBatchRequest"):
56
- """Executes a batch of runs (internal helper)."""
57
- try:
58
- if request.agent_name not in self.flock.agents:
59
- raise ValueError(f"Agent '{request.agent_name}' not found")
60
-
61
- logger.debug(
62
- f"Executing batch run starting with '{request.agent_name}' (batch_id: {batch_id})",
63
- batch_size=len(request.batch_inputs)
64
- if isinstance(request.batch_inputs, list)
65
- else "CSV/DataFrame",
66
- )
67
-
68
- # --- Re-integrating the threaded batch execution from Flock.run_batch_async ---
69
- import asyncio
70
- import threading
71
- from concurrent.futures import ThreadPoolExecutor
72
-
73
- def run_batch_sync_in_thread():
74
- loop = asyncio.new_event_loop()
75
- asyncio.set_event_loop(loop)
76
- try:
77
- batch_size = (
78
- len(request.batch_inputs)
79
- if isinstance(request.batch_inputs, list)
80
- else 0 # Or attempt to get from DataFrame/CSV load
81
- )
82
- if batch_size > 0:
83
- self.run_store.set_batch_total_items(batch_id, batch_size)
84
-
85
- class ProgressTracker:
86
- def __init__(self, store, b_id, total_size):
87
- self.store, self.batch_id, self.total_size = store, b_id, total_size
88
- self.current_count, self.partial_results, self._lock = 0, [], threading.Lock()
89
- def increment(self, res=None):
90
- with self._lock:
91
- self.current_count += 1
92
- if res is not None: self.partial_results.append(res)
93
- try: self.store.update_batch_progress(self.batch_id, self.current_count, self.partial_results)
94
- except Exception as e_prog: logger.error(f"Error updating progress: {e_prog}")
95
- return self.current_count
96
-
97
- progress_tracker = ProgressTracker(self.run_store, batch_id, batch_size)
98
-
99
- async def progress_aware_worker(index, item_inputs):
100
- try:
101
- # Call Flock's run_async for a single item
102
- item_result = await self.flock.run_async(
103
- agent=request.agent_name,
104
- input=item_inputs,
105
- box_result=request.box_results,
106
- )
107
- progress_tracker.increment(item_result)
108
- return item_result
109
- except Exception as item_err:
110
- logger.error(f"Error processing batch item {index}: {item_err}")
111
- progress_tracker.increment(item_err if request.return_errors else None)
112
- if request.return_errors: return item_err
113
- return None
114
-
115
- batch_inputs_list = request.batch_inputs
116
- actual_results_list = []
117
-
118
- if isinstance(batch_inputs_list, list):
119
- tasks = []
120
- for i, item_inputs in enumerate(batch_inputs_list):
121
- full_inputs = {**(request.static_inputs or {}), **item_inputs}
122
- tasks.append(progress_aware_worker(i, full_inputs))
123
-
124
- if request.parallel and request.max_workers > 1:
125
- semaphore = asyncio.Semaphore(request.max_workers)
126
- async def bounded_worker(idx, inputs_item):
127
- async with semaphore: return await progress_aware_worker(idx, inputs_item)
128
- bounded_tasks = [bounded_worker(i, {**(request.static_inputs or {}), **item}) for i, item in enumerate(batch_inputs_list)]
129
- actual_results_list = loop.run_until_complete(asyncio.gather(*bounded_tasks, return_exceptions=request.return_errors))
130
- else:
131
- for i, item_inputs in enumerate(batch_inputs_list):
132
- full_inputs = {**(request.static_inputs or {}), **item_inputs}
133
- actual_results_list.append(loop.run_until_complete(progress_aware_worker(i, full_inputs)))
134
- else: # DataFrame or CSV path - let Flock's batch processor handle this directly
135
- # This path relies on self.flock.run_batch_async being able to run within this new event loop.
136
- # It might be simpler to always convert DataFrame/CSV to list of dicts before this point.
137
- actual_results_list = loop.run_until_complete(
138
- self.flock.run_batch_async(
139
- start_agent=request.agent_name,
140
- batch_inputs=request.batch_inputs, # DataFrame or path
141
- input_mapping=request.input_mapping,
142
- static_inputs=request.static_inputs,
143
- parallel=request.parallel, # Will be re-evaluated by internal BatchProcessor
144
- max_workers=request.max_workers,
145
- use_temporal=request.use_temporal, # Will be re-evaluated
146
- box_results=request.box_results,
147
- return_errors=request.return_errors,
148
- silent_mode=True, # Internal batch runs silently for API
149
- write_to_csv=None # API handles CSV output separately if needed
150
- )
151
- )
152
- # Progress for DataFrame/CSV would need integration into BatchProcessor or this loop
153
- if actual_results_list:
154
- self.run_store.set_batch_total_items(batch_id, len(actual_results_list))
155
- self.run_store.update_batch_progress(batch_id, len(actual_results_list), actual_results_list)
156
-
157
-
158
- self.run_store.update_batch_result(batch_id, actual_results_list)
159
- logger.info(f"Batch run completed (batch_id: {batch_id})", num_results=len(actual_results_list))
160
- return actual_results_list
161
- except Exception as thread_err:
162
- logger.error(f"Error in batch run thread {batch_id}: {thread_err!s}", exc_info=True)
163
- self.run_store.update_batch_status(batch_id, "failed", str(thread_err))
164
- return None
165
- finally:
166
- loop.close()
167
- # --- End of re-integrated threaded batch execution ---
168
-
169
- # Submit the synchronous function to a thread pool from the main event loop
170
- main_loop = asyncio.get_running_loop()
171
- with ThreadPoolExecutor(thread_name_prefix="flock-api-batch") as pool:
172
- await main_loop.run_in_executor(pool, run_batch_sync_in_thread)
173
-
174
- except Exception as e:
175
- logger.error(
176
- f"Error setting up batch run {batch_id} (started with '{request.agent_name}'): {e!s}",
177
- exc_info=True,
178
- )
179
- self.run_store.update_batch_status(batch_id, "failed", str(e))
180
- raise
181
-
182
-
183
-
184
-
185
-
186
- def _type_convert_inputs(
187
- self, agent_name: str, inputs: dict[str, Any]
188
- ) -> dict[str, Any]:
189
- """Converts input values (esp. from forms) to expected Python types."""
190
- typed_inputs = {}
191
- agent_def = self.flock.agents.get(agent_name)
192
- if not agent_def or not agent_def.input or not isinstance(agent_def.input, str):
193
- return inputs # Return original if no spec or spec is not a string
194
-
195
- parsed_fields = self._parse_input_spec(agent_def.input) # Relies on the old UI helper
196
- field_types = {f["name"]: f["type"] for f in parsed_fields}
197
-
198
- for k, v in inputs.items():
199
- target_type_str = field_types.get(k)
200
- if target_type_str:
201
- if target_type_str.startswith("bool"):
202
- typed_inputs[k] = str(v).lower() in ["true", "on", "1", "yes"] if isinstance(v, str) else bool(v)
203
- elif target_type_str.startswith("int"):
204
- try: typed_inputs[k] = int(v)
205
- except (ValueError, TypeError): logger.warning(f"Could not convert '{k}' value '{v}' to int for agent '{agent_name}'"); typed_inputs[k] = v
206
- elif target_type_str.startswith("float"):
207
- try: typed_inputs[k] = float(v)
208
- except (ValueError, TypeError): logger.warning(f"Could not convert '{k}' value '{v}' to float for agent '{agent_name}'"); typed_inputs[k] = v
209
- # TODO: Add list/dict parsing (e.g., json.loads) if type_str indicates these,
210
- # especially if inputs come from HTML forms as strings.
211
- else: typed_inputs[k] = v
212
- else:
213
- typed_inputs[k] = v
214
- return typed_inputs
@@ -1,15 +0,0 @@
1
- # src/flock/core/component/__init__.py
2
- """Unified component system for Flock agents."""
3
-
4
- from .agent_component_base import AgentComponent, AgentComponentConfig
5
- from .evaluation_component import EvaluationComponent
6
- from .routing_component import RoutingComponent
7
- from .utility_component import UtilityComponent
8
-
9
- __all__ = [
10
- "AgentComponent",
11
- "AgentComponentConfig",
12
- "EvaluationComponent",
13
- "RoutingComponent",
14
- "UtilityComponent",
15
- ]