flock-core 0.5.3__py3-none-any.whl → 0.5.5__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.
- flock/agent.py +20 -1
- flock/artifact_collector.py +2 -3
- flock/batch_accumulator.py +4 -4
- flock/components.py +32 -0
- flock/correlation_engine.py +9 -4
- flock/dashboard/collector.py +4 -0
- flock/dashboard/events.py +74 -0
- flock/dashboard/graph_builder.py +272 -0
- flock/dashboard/models/graph.py +3 -1
- flock/dashboard/service.py +363 -14
- flock/dashboard/static_v2/assets/index-DFRnI_mt.js +1 -1
- flock/dashboard/static_v2/index.html +3 -3
- flock/engines/dspy_engine.py +41 -3
- flock/engines/examples/__init__.py +6 -0
- flock/engines/examples/simple_batch_engine.py +61 -0
- flock/frontend/README.md +4 -4
- flock/frontend/docs/DESIGN_SYSTEM.md +1 -1
- flock/frontend/package-lock.json +2 -2
- flock/frontend/package.json +2 -2
- flock/frontend/src/components/controls/PublishControl.test.tsx +11 -11
- flock/frontend/src/components/controls/PublishControl.tsx +1 -1
- flock/frontend/src/components/graph/AgentNode.tsx +4 -0
- flock/frontend/src/components/graph/GraphCanvas.tsx +4 -0
- flock/frontend/src/components/graph/LogicOperationsDisplay.tsx +463 -0
- flock/frontend/src/components/graph/PendingBatchEdge.tsx +141 -0
- flock/frontend/src/components/graph/PendingJoinEdge.tsx +144 -0
- flock/frontend/src/components/settings/SettingsPanel.css +1 -1
- flock/frontend/src/components/settings/ThemeSelector.tsx +2 -2
- flock/frontend/src/services/graphService.ts +3 -1
- flock/frontend/src/services/indexeddb.ts +1 -1
- flock/frontend/src/services/websocket.ts +99 -1
- flock/frontend/src/store/graphStore.test.ts +2 -1
- flock/frontend/src/store/graphStore.ts +36 -5
- flock/frontend/src/styles/variables.css +1 -1
- flock/frontend/src/types/graph.ts +86 -0
- flock/orchestrator.py +268 -13
- flock/patches/__init__.py +1 -0
- flock/patches/dspy_streaming_patch.py +1 -0
- flock/runtime.py +3 -0
- {flock_core-0.5.3.dist-info → flock_core-0.5.5.dist-info}/METADATA +11 -1
- {flock_core-0.5.3.dist-info → flock_core-0.5.5.dist-info}/RECORD +44 -39
- {flock_core-0.5.3.dist-info → flock_core-0.5.5.dist-info}/WHEEL +0 -0
- {flock_core-0.5.3.dist-info → flock_core-0.5.5.dist-info}/entry_points.txt +0 -0
- {flock_core-0.5.3.dist-info → flock_core-0.5.5.dist-info}/licenses/LICENSE +0 -0
flock/orchestrator.py
CHANGED
|
@@ -8,7 +8,7 @@ import os
|
|
|
8
8
|
from asyncio import Task
|
|
9
9
|
from collections.abc import AsyncGenerator, Iterable, Mapping, Sequence
|
|
10
10
|
from contextlib import asynccontextmanager
|
|
11
|
-
from datetime import datetime, timezone
|
|
11
|
+
from datetime import datetime, timedelta, timezone
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from typing import TYPE_CHECKING, Any
|
|
14
14
|
from uuid import uuid4
|
|
@@ -135,8 +135,16 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
135
135
|
self._artifact_collector = ArtifactCollector()
|
|
136
136
|
# JoinSpec logic: Correlation engine for correlated AND gates
|
|
137
137
|
self._correlation_engine = CorrelationEngine()
|
|
138
|
+
# Background task for checking correlation expiry (time-based JoinSpec)
|
|
139
|
+
self._correlation_cleanup_task: Task[Any] | None = None
|
|
140
|
+
self._correlation_cleanup_interval: float = 0.1 # Check every 100ms
|
|
138
141
|
# BatchSpec logic: Batch accumulator for size/timeout batching
|
|
139
142
|
self._batch_engine = BatchEngine()
|
|
143
|
+
# Background task for checking batch timeouts
|
|
144
|
+
self._batch_timeout_task: Task[Any] | None = None
|
|
145
|
+
self._batch_timeout_interval: float = 0.1 # Check every 100ms
|
|
146
|
+
# Phase 1.2: WebSocket manager for real-time dashboard events (set by serve())
|
|
147
|
+
self._websocket_manager: Any = None
|
|
140
148
|
# Unified tracing support
|
|
141
149
|
self._workflow_span = None
|
|
142
150
|
self._auto_workflow_enabled = os.getenv("FLOCK_AUTO_WORKFLOW_TRACE", "false").lower() in {
|
|
@@ -471,6 +479,33 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
471
479
|
await asyncio.sleep(0.01)
|
|
472
480
|
pending = {task for task in self._tasks if not task.done()}
|
|
473
481
|
self._tasks = pending
|
|
482
|
+
|
|
483
|
+
# Determine whether any deferred work (timeouts/cleanup) is still pending.
|
|
484
|
+
pending_batches = any(
|
|
485
|
+
accumulator.artifacts for accumulator in self._batch_engine.batches.values()
|
|
486
|
+
)
|
|
487
|
+
pending_correlations = any(
|
|
488
|
+
groups and any(group.waiting_artifacts for group in groups.values())
|
|
489
|
+
for groups in self._correlation_engine.correlation_groups.values()
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
# Ensure watchdog loops remain active while pending work exists.
|
|
493
|
+
if pending_batches and (
|
|
494
|
+
self._batch_timeout_task is None or self._batch_timeout_task.done()
|
|
495
|
+
):
|
|
496
|
+
self._batch_timeout_task = asyncio.create_task(self._batch_timeout_checker_loop())
|
|
497
|
+
|
|
498
|
+
if pending_correlations and (
|
|
499
|
+
self._correlation_cleanup_task is None or self._correlation_cleanup_task.done()
|
|
500
|
+
):
|
|
501
|
+
self._correlation_cleanup_task = asyncio.create_task(self._correlation_cleanup_loop())
|
|
502
|
+
|
|
503
|
+
# If deferred work is still outstanding, consider the orchestrator quiescent for
|
|
504
|
+
# now but leave watchdog tasks running to finish the job.
|
|
505
|
+
if pending_batches or pending_correlations:
|
|
506
|
+
self._agent_iteration_count.clear()
|
|
507
|
+
return
|
|
508
|
+
|
|
474
509
|
# T068: Reset circuit breaker counters when idle
|
|
475
510
|
self._agent_iteration_count.clear()
|
|
476
511
|
|
|
@@ -546,6 +581,22 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
546
581
|
|
|
547
582
|
async def shutdown(self) -> None:
|
|
548
583
|
"""Shutdown orchestrator and clean up resources."""
|
|
584
|
+
# Cancel correlation cleanup task if running
|
|
585
|
+
if self._correlation_cleanup_task and not self._correlation_cleanup_task.done():
|
|
586
|
+
self._correlation_cleanup_task.cancel()
|
|
587
|
+
try:
|
|
588
|
+
await self._correlation_cleanup_task
|
|
589
|
+
except asyncio.CancelledError:
|
|
590
|
+
pass
|
|
591
|
+
|
|
592
|
+
# Cancel batch timeout checker if running
|
|
593
|
+
if self._batch_timeout_task and not self._batch_timeout_task.done():
|
|
594
|
+
self._batch_timeout_task.cancel()
|
|
595
|
+
try:
|
|
596
|
+
await self._batch_timeout_task
|
|
597
|
+
except asyncio.CancelledError:
|
|
598
|
+
pass
|
|
599
|
+
|
|
549
600
|
if self._mcp_manager is not None:
|
|
550
601
|
await self._mcp_manager.cleanup_all()
|
|
551
602
|
self._mcp_manager = None
|
|
@@ -602,6 +653,8 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
602
653
|
|
|
603
654
|
# Store collector reference for agents added later
|
|
604
655
|
self._dashboard_collector = event_collector
|
|
656
|
+
# Store websocket manager for real-time event emission (Phase 1.2)
|
|
657
|
+
self._websocket_manager = websocket_manager
|
|
605
658
|
|
|
606
659
|
# Inject event collector into all existing agents
|
|
607
660
|
for agent in self._agents.values():
|
|
@@ -905,8 +958,23 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
905
958
|
subscription_index=subscription_index,
|
|
906
959
|
)
|
|
907
960
|
|
|
961
|
+
# Start correlation cleanup task if time-based window and not running
|
|
962
|
+
if (
|
|
963
|
+
isinstance(subscription.join.within, timedelta)
|
|
964
|
+
and self._correlation_cleanup_task is None
|
|
965
|
+
):
|
|
966
|
+
self._correlation_cleanup_task = asyncio.create_task(
|
|
967
|
+
self._correlation_cleanup_loop()
|
|
968
|
+
)
|
|
969
|
+
|
|
908
970
|
if completed_group is None:
|
|
909
971
|
# Still waiting for correlation to complete
|
|
972
|
+
# Phase 1.2: Emit real-time correlation update event
|
|
973
|
+
await self._emit_correlation_updated_event(
|
|
974
|
+
agent_name=agent.name,
|
|
975
|
+
subscription_index=subscription_index,
|
|
976
|
+
artifact=artifact,
|
|
977
|
+
)
|
|
910
978
|
continue
|
|
911
979
|
|
|
912
980
|
# Correlation complete! Get all correlated artifacts
|
|
@@ -938,6 +1006,12 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
938
1006
|
subscription=subscription,
|
|
939
1007
|
subscription_index=subscription_index,
|
|
940
1008
|
)
|
|
1009
|
+
|
|
1010
|
+
# Start timeout checker if this batch has a timeout and checker not running
|
|
1011
|
+
if subscription.batch.timeout and self._batch_timeout_task is None:
|
|
1012
|
+
self._batch_timeout_task = asyncio.create_task(
|
|
1013
|
+
self._batch_timeout_checker_loop()
|
|
1014
|
+
)
|
|
941
1015
|
else:
|
|
942
1016
|
# Single type subscription: Add each artifact individually
|
|
943
1017
|
should_flush = False
|
|
@@ -948,12 +1022,25 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
948
1022
|
subscription_index=subscription_index,
|
|
949
1023
|
)
|
|
950
1024
|
|
|
1025
|
+
# Start timeout checker if this batch has a timeout and checker not running
|
|
1026
|
+
if subscription.batch.timeout and self._batch_timeout_task is None:
|
|
1027
|
+
self._batch_timeout_task = asyncio.create_task(
|
|
1028
|
+
self._batch_timeout_checker_loop()
|
|
1029
|
+
)
|
|
1030
|
+
|
|
951
1031
|
if should_flush:
|
|
952
1032
|
# Size threshold reached! Flush batch now
|
|
953
1033
|
break
|
|
954
1034
|
|
|
955
1035
|
if not should_flush:
|
|
956
1036
|
# Batch not full yet - wait for more artifacts
|
|
1037
|
+
# Phase 1.2: Emit real-time batch update event
|
|
1038
|
+
await self._emit_batch_item_added_event(
|
|
1039
|
+
agent_name=agent.name,
|
|
1040
|
+
subscription_index=subscription_index,
|
|
1041
|
+
subscription=subscription,
|
|
1042
|
+
artifact=artifact,
|
|
1043
|
+
)
|
|
957
1044
|
continue
|
|
958
1045
|
|
|
959
1046
|
# Flush the batch and get all accumulated artifacts
|
|
@@ -977,10 +1064,14 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
977
1064
|
self._mark_processed(collected_artifact, agent)
|
|
978
1065
|
|
|
979
1066
|
# Schedule agent with ALL artifacts (batched, correlated, or AND gate complete)
|
|
980
|
-
|
|
1067
|
+
# NEW: Mark as batch execution if flushed from BatchSpec
|
|
1068
|
+
is_batch_execution = subscription.batch is not None
|
|
1069
|
+
self._schedule_task(agent, artifacts, is_batch=is_batch_execution)
|
|
981
1070
|
|
|
982
|
-
def _schedule_task(
|
|
983
|
-
|
|
1071
|
+
def _schedule_task(
|
|
1072
|
+
self, agent: Agent, artifacts: list[Artifact], is_batch: bool = False
|
|
1073
|
+
) -> None:
|
|
1074
|
+
task = asyncio.create_task(self._run_agent_task(agent, artifacts, is_batch=is_batch))
|
|
984
1075
|
self._tasks.add(task)
|
|
985
1076
|
task.add_done_callback(self._tasks.discard)
|
|
986
1077
|
|
|
@@ -995,14 +1086,17 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
995
1086
|
key = (str(artifact.id), agent.name)
|
|
996
1087
|
return key in self._processed
|
|
997
1088
|
|
|
998
|
-
async def _run_agent_task(
|
|
1089
|
+
async def _run_agent_task(
|
|
1090
|
+
self, agent: Agent, artifacts: list[Artifact], is_batch: bool = False
|
|
1091
|
+
) -> None:
|
|
999
1092
|
correlation_id = artifacts[0].correlation_id if artifacts else uuid4()
|
|
1000
1093
|
|
|
1001
1094
|
ctx = Context(
|
|
1002
1095
|
board=BoardHandle(self),
|
|
1003
1096
|
orchestrator=self,
|
|
1004
1097
|
task_id=str(uuid4()),
|
|
1005
|
-
correlation_id=correlation_id,
|
|
1098
|
+
correlation_id=correlation_id,
|
|
1099
|
+
is_batch=is_batch, # NEW!
|
|
1006
1100
|
)
|
|
1007
1101
|
self._record_agent_run(agent)
|
|
1008
1102
|
await agent.execute(ctx, artifacts)
|
|
@@ -1026,13 +1120,174 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
1026
1120
|
except Exception as exc: # pragma: no cover - defensive logging
|
|
1027
1121
|
self._logger.exception("Failed to record artifact consumption: %s", exc)
|
|
1028
1122
|
|
|
1123
|
+
# Phase 1.2: Logic Operations Event Emission ----------------------------
|
|
1124
|
+
|
|
1125
|
+
async def _emit_correlation_updated_event(
|
|
1126
|
+
self, *, agent_name: str, subscription_index: int, artifact: Artifact
|
|
1127
|
+
) -> None:
|
|
1128
|
+
"""Emit CorrelationGroupUpdatedEvent for real-time dashboard updates.
|
|
1129
|
+
|
|
1130
|
+
Called when an artifact is added to a correlation group that is not yet complete.
|
|
1131
|
+
|
|
1132
|
+
Args:
|
|
1133
|
+
agent_name: Name of the agent with the JoinSpec subscription
|
|
1134
|
+
subscription_index: Index of the subscription in the agent's subscriptions list
|
|
1135
|
+
artifact: The artifact that triggered this update
|
|
1136
|
+
"""
|
|
1137
|
+
# Only emit if dashboard is enabled
|
|
1138
|
+
if self._websocket_manager is None:
|
|
1139
|
+
return
|
|
1140
|
+
|
|
1141
|
+
# Import _get_correlation_groups helper from dashboard service
|
|
1142
|
+
from flock.dashboard.service import _get_correlation_groups
|
|
1143
|
+
|
|
1144
|
+
# Get current correlation groups state from engine
|
|
1145
|
+
groups = _get_correlation_groups(self._correlation_engine, agent_name, subscription_index)
|
|
1146
|
+
|
|
1147
|
+
if not groups:
|
|
1148
|
+
return # No groups to report (shouldn't happen, but defensive)
|
|
1149
|
+
|
|
1150
|
+
# Find the group that was just updated (match by last updated time or artifact ID)
|
|
1151
|
+
# For now, we'll emit an event for the FIRST group that's still waiting
|
|
1152
|
+
# In practice, the artifact we just added should be in one of these groups
|
|
1153
|
+
for group_state in groups:
|
|
1154
|
+
if not group_state["is_complete"]:
|
|
1155
|
+
# Import CorrelationGroupUpdatedEvent
|
|
1156
|
+
from flock.dashboard.events import CorrelationGroupUpdatedEvent
|
|
1157
|
+
|
|
1158
|
+
# Build and emit event
|
|
1159
|
+
event = CorrelationGroupUpdatedEvent(
|
|
1160
|
+
agent_name=agent_name,
|
|
1161
|
+
subscription_index=subscription_index,
|
|
1162
|
+
correlation_key=group_state["correlation_key"],
|
|
1163
|
+
collected_types=group_state["collected_types"],
|
|
1164
|
+
required_types=group_state["required_types"],
|
|
1165
|
+
waiting_for=group_state["waiting_for"],
|
|
1166
|
+
elapsed_seconds=group_state["elapsed_seconds"],
|
|
1167
|
+
expires_in_seconds=group_state["expires_in_seconds"],
|
|
1168
|
+
expires_in_artifacts=group_state["expires_in_artifacts"],
|
|
1169
|
+
artifact_id=str(artifact.id),
|
|
1170
|
+
artifact_type=artifact.type,
|
|
1171
|
+
is_complete=group_state["is_complete"],
|
|
1172
|
+
)
|
|
1173
|
+
|
|
1174
|
+
# Broadcast via WebSocket
|
|
1175
|
+
await self._websocket_manager.broadcast(event)
|
|
1176
|
+
break # Only emit one event per artifact addition
|
|
1177
|
+
|
|
1178
|
+
async def _emit_batch_item_added_event(
|
|
1179
|
+
self,
|
|
1180
|
+
*,
|
|
1181
|
+
agent_name: str,
|
|
1182
|
+
subscription_index: int,
|
|
1183
|
+
subscription: Subscription, # noqa: F821
|
|
1184
|
+
artifact: Artifact,
|
|
1185
|
+
) -> None:
|
|
1186
|
+
"""Emit BatchItemAddedEvent for real-time dashboard updates.
|
|
1187
|
+
|
|
1188
|
+
Called when an artifact is added to a batch that hasn't reached flush threshold.
|
|
1189
|
+
|
|
1190
|
+
Args:
|
|
1191
|
+
agent_name: Name of the agent with the BatchSpec subscription
|
|
1192
|
+
subscription_index: Index of the subscription in the agent's subscriptions list
|
|
1193
|
+
subscription: The subscription with BatchSpec configuration
|
|
1194
|
+
artifact: The artifact that triggered this update
|
|
1195
|
+
"""
|
|
1196
|
+
# Only emit if dashboard is enabled
|
|
1197
|
+
if self._websocket_manager is None:
|
|
1198
|
+
return
|
|
1199
|
+
|
|
1200
|
+
# Import _get_batch_state helper from dashboard service
|
|
1201
|
+
from flock.dashboard.service import _get_batch_state
|
|
1202
|
+
|
|
1203
|
+
# Get current batch state from engine
|
|
1204
|
+
batch_state = _get_batch_state(
|
|
1205
|
+
self._batch_engine, agent_name, subscription_index, subscription.batch
|
|
1206
|
+
)
|
|
1207
|
+
|
|
1208
|
+
if not batch_state:
|
|
1209
|
+
return # No batch to report (shouldn't happen, but defensive)
|
|
1210
|
+
|
|
1211
|
+
# Import BatchItemAddedEvent
|
|
1212
|
+
from flock.dashboard.events import BatchItemAddedEvent
|
|
1213
|
+
|
|
1214
|
+
# Build and emit event
|
|
1215
|
+
event = BatchItemAddedEvent(
|
|
1216
|
+
agent_name=agent_name,
|
|
1217
|
+
subscription_index=subscription_index,
|
|
1218
|
+
items_collected=batch_state["items_collected"],
|
|
1219
|
+
items_target=batch_state.get("items_target"),
|
|
1220
|
+
items_remaining=batch_state.get("items_remaining"),
|
|
1221
|
+
elapsed_seconds=batch_state["elapsed_seconds"],
|
|
1222
|
+
timeout_seconds=batch_state.get("timeout_seconds"),
|
|
1223
|
+
timeout_remaining_seconds=batch_state.get("timeout_remaining_seconds"),
|
|
1224
|
+
will_flush=batch_state["will_flush"],
|
|
1225
|
+
artifact_id=str(artifact.id),
|
|
1226
|
+
artifact_type=artifact.type,
|
|
1227
|
+
)
|
|
1228
|
+
|
|
1229
|
+
# Broadcast via WebSocket
|
|
1230
|
+
await self._websocket_manager.broadcast(event)
|
|
1231
|
+
|
|
1029
1232
|
# Batch Helpers --------------------------------------------------------
|
|
1030
1233
|
|
|
1234
|
+
async def _correlation_cleanup_loop(self) -> None:
|
|
1235
|
+
"""Background task that periodically cleans up expired correlation groups.
|
|
1236
|
+
|
|
1237
|
+
Runs continuously until all correlation groups are cleared or orchestrator shuts down.
|
|
1238
|
+
Checks every 100ms for time-based expired correlations and discards them.
|
|
1239
|
+
"""
|
|
1240
|
+
try:
|
|
1241
|
+
while True:
|
|
1242
|
+
await asyncio.sleep(self._correlation_cleanup_interval)
|
|
1243
|
+
self._cleanup_expired_correlations()
|
|
1244
|
+
|
|
1245
|
+
# Stop if no correlation groups remain
|
|
1246
|
+
if not self._correlation_engine.correlation_groups:
|
|
1247
|
+
self._correlation_cleanup_task = None
|
|
1248
|
+
break
|
|
1249
|
+
except asyncio.CancelledError:
|
|
1250
|
+
# Clean shutdown
|
|
1251
|
+
self._correlation_cleanup_task = None
|
|
1252
|
+
raise
|
|
1253
|
+
|
|
1254
|
+
def _cleanup_expired_correlations(self) -> None:
|
|
1255
|
+
"""Clean up all expired correlation groups across all subscriptions.
|
|
1256
|
+
|
|
1257
|
+
Called periodically by background task to enforce time-based correlation windows.
|
|
1258
|
+
Discards incomplete correlations that have exceeded their time window.
|
|
1259
|
+
"""
|
|
1260
|
+
# Get all active subscription keys
|
|
1261
|
+
for agent_name, subscription_index in list(
|
|
1262
|
+
self._correlation_engine.correlation_groups.keys()
|
|
1263
|
+
):
|
|
1264
|
+
self._correlation_engine.cleanup_expired(agent_name, subscription_index)
|
|
1265
|
+
|
|
1266
|
+
async def _batch_timeout_checker_loop(self) -> None:
|
|
1267
|
+
"""Background task that periodically checks for batch timeouts.
|
|
1268
|
+
|
|
1269
|
+
Runs continuously until all batches are cleared or orchestrator shuts down.
|
|
1270
|
+
Checks every 100ms for expired batches and flushes them.
|
|
1271
|
+
"""
|
|
1272
|
+
try:
|
|
1273
|
+
while True:
|
|
1274
|
+
await asyncio.sleep(self._batch_timeout_interval)
|
|
1275
|
+
await self._check_batch_timeouts()
|
|
1276
|
+
|
|
1277
|
+
# Stop if no batches remain
|
|
1278
|
+
if not self._batch_engine.batches:
|
|
1279
|
+
self._batch_timeout_task = None
|
|
1280
|
+
break
|
|
1281
|
+
except asyncio.CancelledError:
|
|
1282
|
+
# Clean shutdown
|
|
1283
|
+
self._batch_timeout_task = None
|
|
1284
|
+
raise
|
|
1285
|
+
|
|
1031
1286
|
async def _check_batch_timeouts(self) -> None:
|
|
1032
1287
|
"""Check all batches for timeout expiry and flush expired batches.
|
|
1033
1288
|
|
|
1034
|
-
This method is called periodically
|
|
1035
|
-
timeout-based batching.
|
|
1289
|
+
This method is called periodically by the background timeout checker
|
|
1290
|
+
or manually (in tests) to enforce timeout-based batching.
|
|
1036
1291
|
"""
|
|
1037
1292
|
expired_batches = self._batch_engine.check_timeouts()
|
|
1038
1293
|
|
|
@@ -1048,21 +1303,21 @@ class Flock(metaclass=AutoTracedMeta):
|
|
|
1048
1303
|
if agent is None:
|
|
1049
1304
|
continue
|
|
1050
1305
|
|
|
1051
|
-
# Schedule agent with batched artifacts
|
|
1052
|
-
self._schedule_task(agent, artifacts)
|
|
1306
|
+
# Schedule agent with batched artifacts (timeout flush)
|
|
1307
|
+
self._schedule_task(agent, artifacts, is_batch=True)
|
|
1053
1308
|
|
|
1054
1309
|
async def _flush_all_batches(self) -> None:
|
|
1055
1310
|
"""Flush all partial batches (for shutdown - ensures zero data loss)."""
|
|
1056
1311
|
all_batches = self._batch_engine.flush_all()
|
|
1057
1312
|
|
|
1058
|
-
for agent_name,
|
|
1313
|
+
for agent_name, _subscription_index, artifacts in all_batches:
|
|
1059
1314
|
# Get the agent
|
|
1060
1315
|
agent = self._agents.get(agent_name)
|
|
1061
1316
|
if agent is None:
|
|
1062
1317
|
continue
|
|
1063
1318
|
|
|
1064
|
-
# Schedule agent with partial batch
|
|
1065
|
-
self._schedule_task(agent, artifacts)
|
|
1319
|
+
# Schedule agent with partial batch (shutdown flush)
|
|
1320
|
+
self._schedule_task(agent, artifacts, is_batch=True)
|
|
1066
1321
|
|
|
1067
1322
|
# Wait for all scheduled tasks to complete
|
|
1068
1323
|
await self.run_until_idle()
|
flock/patches/__init__.py
CHANGED
flock/runtime.py
CHANGED
|
@@ -250,6 +250,9 @@ class Context(BaseModel):
|
|
|
250
250
|
correlation_id: UUID | None = None # NEW!
|
|
251
251
|
task_id: str
|
|
252
252
|
state: dict[str, Any] = Field(default_factory=dict)
|
|
253
|
+
is_batch: bool = Field(
|
|
254
|
+
default=False, description="True if this execution is processing a BatchSpec accumulation"
|
|
255
|
+
)
|
|
253
256
|
|
|
254
257
|
def get_variable(self, key: str, default: Any = None) -> Any:
|
|
255
258
|
return self.state.get(key, default)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flock-core
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.5
|
|
4
4
|
Summary: Flock: A declrative framework for building and orchestrating AI agents.
|
|
5
5
|
Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
|
|
6
6
|
License: MIT
|
|
@@ -57,6 +57,8 @@ Flock is a production-focused framework for orchestrating AI agents through **de
|
|
|
57
57
|
**Quick links:**
|
|
58
58
|
- **[Getting Started](https://whiteducksoftware.github.io/flock/getting-started/installation/)** - Installation and first steps
|
|
59
59
|
- **[Tutorials](https://whiteducksoftware.github.io/flock/tutorials/)** - Step-by-step learning path
|
|
60
|
+
- [Custom Engines: Emoji Vibes & Batch Brews](https://whiteducksoftware.github.io/flock/tutorials/custom-engines/)
|
|
61
|
+
- [Custom Agent Components: Foreshadow & Hype](https://whiteducksoftware.github.io/flock/tutorials/custom-agent-components/)
|
|
60
62
|
- **[User Guides](https://whiteducksoftware.github.io/flock/guides/)** - In-depth feature documentation
|
|
61
63
|
- **[API Reference](https://whiteducksoftware.github.io/flock/reference/api/)** - Complete API documentation
|
|
62
64
|
- **[Roadmap](https://whiteducksoftware.github.io/flock/about/roadmap/)** - What's coming in v1.0
|
|
@@ -373,6 +375,10 @@ validator = flock.agent("validator").consumes(Image, Image, Metadata).publishes(
|
|
|
373
375
|
|
|
374
376
|
**Advanced subscriptions unlock crazy powerful patterns:**
|
|
375
377
|
|
|
378
|
+
<p align="center">
|
|
379
|
+
<img alt="Event Join" src="docs/assets/images/join.png" width="800">
|
|
380
|
+
</p>
|
|
381
|
+
|
|
376
382
|
```python
|
|
377
383
|
# 🎯 Predicates - Smart filtering (only process critical cases)
|
|
378
384
|
urgent_care = flock.agent("urgent").consumes(
|
|
@@ -414,6 +420,10 @@ quality_control = flock.agent("qc").consumes(
|
|
|
414
420
|
- 🏭 Manufacturing: Monitor 1000+ IoT sensors with efficient batching
|
|
415
421
|
- 📊 Finance: Match trades + confirmations within 5-minute windows
|
|
416
422
|
|
|
423
|
+
<p align="center">
|
|
424
|
+
<img alt="Event Batch" src="docs/assets/images/batch.png" width="800">
|
|
425
|
+
</p>
|
|
426
|
+
|
|
417
427
|
### Visibility Controls (The Security)
|
|
418
428
|
|
|
419
429
|
**Unlike other frameworks, Flock has zero-trust security built-in:**
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
flock/__init__.py,sha256=fvp4ltfaAGmYliShuTY_XVIpOUN6bMXbWiBnwb1NBoM,310
|
|
2
|
-
flock/agent.py,sha256=
|
|
3
|
-
flock/artifact_collector.py,sha256=
|
|
2
|
+
flock/agent.py,sha256=zlhrY8jWE6LK8hmOHaQWbfnX7_T_6Eg6Qb7oviujJiY,42715
|
|
3
|
+
flock/artifact_collector.py,sha256=8rsg5NzmXeXKNT07TqX1_Z6aAGud2dXKzvS0jhjX3gQ,6372
|
|
4
4
|
flock/artifacts.py,sha256=3vQQ1J7QxTzeQBUGaNLiyojlmBv1NfdhFC98-qj8fpU,2541
|
|
5
|
-
flock/batch_accumulator.py,sha256=
|
|
5
|
+
flock/batch_accumulator.py,sha256=YcZSpdYMhm8wAGqKEF49NJ_Jl2HZX78NrJYqfyHqTuE,8003
|
|
6
6
|
flock/cli.py,sha256=lPtKxEXnGtyuTh0gyG3ixEIFS4Ty6Y0xsPd6SpUTD3U,4526
|
|
7
|
-
flock/components.py,sha256=
|
|
8
|
-
flock/correlation_engine.py,sha256=
|
|
7
|
+
flock/components.py,sha256=7y2UWaIU0wBl44xO0SkU1m04ixbj4gd_FP9wFpsuZhY,7609
|
|
8
|
+
flock/correlation_engine.py,sha256=iGB6-G5F-B-pw-clLx4-pZEiUrK_Q2l3kOn4jtEO_kw,8103
|
|
9
9
|
flock/examples.py,sha256=eQb8k6EYBbUhauFuSN_0EIIu5KW0mTqJU0HM4-p14sc,3632
|
|
10
|
-
flock/orchestrator.py,sha256=
|
|
10
|
+
flock/orchestrator.py,sha256=YJ8M7HxCUjq4hZ9wj3XKbOfLPVq-_zeTPclhI0YBaA0,54530
|
|
11
11
|
flock/registry.py,sha256=s0-H-TMtOsDZiZQCc7T1tYiWQg3OZHn5T--jaI_INIc,4786
|
|
12
|
-
flock/runtime.py,sha256=
|
|
12
|
+
flock/runtime.py,sha256=uEq_zpCd--zqVAGU95uQt9QXqp2036iWo2lRr1JGlM8,8651
|
|
13
13
|
flock/service.py,sha256=JDdjjPTPH6NFezAr8x6svtqxIGXA7-AyHS11GF57g9Q,11041
|
|
14
14
|
flock/store.py,sha256=H6z1_y5uDp_4UnHWqrxNksyoSGlzeVTgLY3Sv-guSTU,45793
|
|
15
15
|
flock/subscription.py,sha256=0fqjGVAr-3u1azSsXJ-xVjnUgSSYVO2a0Gd_zln2tZA,5422
|
|
@@ -17,28 +17,30 @@ flock/utilities.py,sha256=bqTPnFF6E-pDqx1ISswDNEzTU2-ED_URlkyKWLjF3mU,12109
|
|
|
17
17
|
flock/visibility.py,sha256=Cu2PMBjRtqjiWzlwHLCIC2AUFBjJ2augecG-jvK8ky0,2949
|
|
18
18
|
flock/api/themes.py,sha256=BOj1e0LHx6BDLdnVdXh1LKsbQ_ZeubH9UCoj08dC1yc,1886
|
|
19
19
|
flock/dashboard/__init__.py,sha256=_W6Id_Zb7mkSz0iHY1nfdUqF9p9uV_NyHsU7PFsRnFI,813
|
|
20
|
-
flock/dashboard/collector.py,sha256=
|
|
21
|
-
flock/dashboard/events.py,sha256=
|
|
22
|
-
flock/dashboard/graph_builder.py,sha256=
|
|
20
|
+
flock/dashboard/collector.py,sha256=m0dh1HNvJsf-9vM9NGpvPz6wYjzSSQdc8UgVCVbMN-k,21685
|
|
21
|
+
flock/dashboard/events.py,sha256=ICqpBKE68HjevJg7GAT7rrUbPV8Adkird34ZC45_oYA,7679
|
|
22
|
+
flock/dashboard/graph_builder.py,sha256=jdiaruce5uRybndlA4aiOXW-gKkHeGtnndzYQ1WyU9Y,32006
|
|
23
23
|
flock/dashboard/launcher.py,sha256=dCfwaeMLtyIkik3aVSEsbBdABS5ADRlKWYkih7sF5hM,8196
|
|
24
|
-
flock/dashboard/service.py,sha256=
|
|
24
|
+
flock/dashboard/service.py,sha256=_jyHQ_hC9sFgj8mwtuW2r8labZ3NsBJ-1FYcKB0qq9E,52410
|
|
25
25
|
flock/dashboard/websocket.py,sha256=_DCZApJPXc8OQnxFDFS9TA9ozq7kM73QByRj-_a8n-8,9508
|
|
26
26
|
flock/dashboard/models/__init__.py,sha256=T4Yz8IXMm7lBqa2HLDSv7WJBtaKcdZIlTrz6GHNFZxs,68
|
|
27
|
-
flock/dashboard/models/graph.py,sha256=
|
|
28
|
-
flock/dashboard/static_v2/index.html,sha256=
|
|
29
|
-
flock/dashboard/static_v2/assets/index-DFRnI_mt.js,sha256=
|
|
27
|
+
flock/dashboard/models/graph.py,sha256=oQAGAVMV32tim8xscUxZ9nFOci0RvryjdPf1sJgiGxQ,5402
|
|
28
|
+
flock/dashboard/static_v2/index.html,sha256=0KNfWwmpr0JmVNbalnsaQta0y3XlVhOQ_HSts2LuU3A,423
|
|
29
|
+
flock/dashboard/static_v2/assets/index-DFRnI_mt.js,sha256=qeezaWLISr_EKNBBh8v0jzspd2KRcz8jW1r0p7z0Ht0,764860
|
|
30
30
|
flock/dashboard/static_v2/assets/index-fPLNdmp1.css,sha256=skpvfkkrlw7WbmBh7HN-rUKAtKP-gpuLUH4klUgFHT4,74529
|
|
31
31
|
flock/engines/__init__.py,sha256=waNyObJ8PKCLFZL3WUFynxSK-V47m559P3Px-vl_OSc,124
|
|
32
|
-
flock/engines/dspy_engine.py,sha256=
|
|
33
|
-
flock/
|
|
32
|
+
flock/engines/dspy_engine.py,sha256=Q2stZi6jMjjNlhXvzmW3m-Y8AdVo1QuNunbnxEZl6rA,52232
|
|
33
|
+
flock/engines/examples/__init__.py,sha256=cDAjF8_NPL7nhpwa_xxgnPYRAXZWppKE2HkxmL8LGAI,126
|
|
34
|
+
flock/engines/examples/simple_batch_engine.py,sha256=RZVuFJHr3j_4dJZc2AXUcjKZJdct0A7UKOSwWgVEKk4,2235
|
|
35
|
+
flock/frontend/README.md,sha256=0dEzu4UxacGfSstz9_R0KSeFWJ1vNRi0p-KLIay_TfU,26212
|
|
34
36
|
flock/frontend/index.html,sha256=BFg1VR_YVAJ_MGN16xa7sT6wTGwtFYUhfJhGuKv89VM,312
|
|
35
|
-
flock/frontend/package-lock.json,sha256=
|
|
36
|
-
flock/frontend/package.json,sha256=
|
|
37
|
+
flock/frontend/package-lock.json,sha256=vNOaISeq3EfEDDEsFYPWFaMsqypDgQIE0P_u6tzE0g4,150798
|
|
38
|
+
flock/frontend/package.json,sha256=SFwHeNZ0mS9p4_enSXZNMtuXxSM5cl52dzEr-MuRZ90,1253
|
|
37
39
|
flock/frontend/tsconfig.json,sha256=B9p9jXohg_jrCZAq5_yIHvznpeXHiHQkwUZrVE2oMRA,705
|
|
38
40
|
flock/frontend/tsconfig.node.json,sha256=u5_YWSqeNkZBRBIZ8Q2E2q6bospcyF23mO-taRO7glc,233
|
|
39
41
|
flock/frontend/vite.config.ts,sha256=M76uTsyn7fvHI4NhaGyizOGmml0fJvuhSljOQm_UvGs,566
|
|
40
42
|
flock/frontend/vitest.config.ts,sha256=xSWyGrBv2Cy_5eeZA68NCO5AXS6q8WKZXXzqu2JnXPY,244
|
|
41
|
-
flock/frontend/docs/DESIGN_SYSTEM.md,sha256=
|
|
43
|
+
flock/frontend/docs/DESIGN_SYSTEM.md,sha256=a7hbH7kQCOrOQu3CMTYthTZTrFCQUIRcqtXaYHMkPbo,48498
|
|
42
44
|
flock/frontend/src/App.tsx,sha256=3vwTT_WJP7OUb0LJDVMXfkb5hD-uZZmiGBK2wl1QgeM,5233
|
|
43
45
|
flock/frontend/src/main.tsx,sha256=sfWsPgNn5AyDH4LJJLTz2c5OwOPl0o4oi-FArpqc-W4,354
|
|
44
46
|
flock/frontend/src/vite-env.d.ts,sha256=tDjMtvUVN9uIgSCHe__Jhp0-nZiIV21pkcQuyOjaryw,344
|
|
@@ -54,8 +56,8 @@ flock/frontend/src/components/common/KeyboardShortcutsDialog.tsx,sha256=zKrMAWhO
|
|
|
54
56
|
flock/frontend/src/components/common/LoadingSpinner.module.css,sha256=ziZSTIi4dLECTDNJvnkvpCnvo3CuVZ6STNWsHHoZSU8,1769
|
|
55
57
|
flock/frontend/src/components/common/LoadingSpinner.tsx,sha256=ZtI9BOGQg4t-n923y8m1MkL9H8sDWX3wECjr6cdk51o,766
|
|
56
58
|
flock/frontend/src/components/controls/PublishControl.css,sha256=yr73R7lf1fnq22DoPsOOfe2vM_FiWr-ekr5pZE_-KxA,12504
|
|
57
|
-
flock/frontend/src/components/controls/PublishControl.test.tsx,sha256=
|
|
58
|
-
flock/frontend/src/components/controls/PublishControl.tsx,sha256=
|
|
59
|
+
flock/frontend/src/components/controls/PublishControl.test.tsx,sha256=1PMNOAcnfdm2mg_7m31MdcZrth_AN0F-G8QT9CMH6AQ,17711
|
|
60
|
+
flock/frontend/src/components/controls/PublishControl.tsx,sha256=fDLR1qYhshUv26MFxHvDwCGQzvPzcByv8ApM-6d97Bw,14739
|
|
59
61
|
flock/frontend/src/components/details/DetailWindowContainer.tsx,sha256=eKfFNBoSSl_JYj6Aaij9a9n6H24oQrfzZtE1uiUr0k8,1868
|
|
60
62
|
flock/frontend/src/components/details/LiveOutputTab.test.tsx,sha256=YyxsBP3QpbeWDGKNGZsOjqLLqUkvuI-L-5tB2Sh7ATc,24160
|
|
61
63
|
flock/frontend/src/components/details/LiveOutputTab.tsx,sha256=4mmN4DxI6rF9g9fVIAqbC8UsTwf4uzdNbPqGvvvP2FM,6908
|
|
@@ -84,12 +86,15 @@ flock/frontend/src/components/filters/TimeRangeFilter.test.tsx,sha256=4vkGYNecXc
|
|
|
84
86
|
flock/frontend/src/components/filters/TimeRangeFilter.tsx,sha256=4-INbQXk0RrDfP4NK1LBNcLQQWhNYos2Ken8cizb114,3311
|
|
85
87
|
flock/frontend/src/components/filters/VisibilityFilter.tsx,sha256=rFS4U90ltzYIUyfVR8NFRDLuTOLZdk_rTIQsXlB9EuI,679
|
|
86
88
|
flock/frontend/src/components/graph/AgentNode.test.tsx,sha256=D2OirlLSd22Ae5ocLLiBkL2lLz3vXtcx0LWAnqRYc58,2058
|
|
87
|
-
flock/frontend/src/components/graph/AgentNode.tsx,sha256=
|
|
88
|
-
flock/frontend/src/components/graph/GraphCanvas.tsx,sha256=
|
|
89
|
+
flock/frontend/src/components/graph/AgentNode.tsx,sha256=S0bZ3tIcxBfVHLBYIcJh-iXpfGMwb31K5aXuOh7Q_Xg,12979
|
|
90
|
+
flock/frontend/src/components/graph/GraphCanvas.tsx,sha256=E0pqDH5eezp14xdfaH_6ggnqAgTe7W_aJVVSQIUIFEw,22416
|
|
91
|
+
flock/frontend/src/components/graph/LogicOperationsDisplay.tsx,sha256=E_z9c5RvE7pOJi8tFrmiLpZzbfeKr8kie-AnUGUKSu8,19862
|
|
89
92
|
flock/frontend/src/components/graph/MessageFlowEdge.tsx,sha256=OWYmmlS5P9yIxfCddEleEd27MA-djMd_3fcQmyT22r4,3914
|
|
90
93
|
flock/frontend/src/components/graph/MessageNode.test.tsx,sha256=xFBdOPQuWGm7_QUROkV8B9iRHEpyqsosxG_6i4K7ThE,1922
|
|
91
94
|
flock/frontend/src/components/graph/MessageNode.tsx,sha256=cirokPB3MKKLwCPtssGbD3FdhpxX5Ie2h1mM4Vv97w0,4114
|
|
92
95
|
flock/frontend/src/components/graph/MiniMap.tsx,sha256=i2lQ51EAp35mwo2C35U6zktwm8o54iKm4MBSN4UJh3Y,1305
|
|
96
|
+
flock/frontend/src/components/graph/PendingBatchEdge.tsx,sha256=8MHs68YmLOocWQ6lxCooeuwCjpwQn5KFdI-pfu5oXx8,4442
|
|
97
|
+
flock/frontend/src/components/graph/PendingJoinEdge.tsx,sha256=nawJ4Hm8JjfJBypdYgAYkd3t4PcaYdzd6aEyFzTC0-Y,4495
|
|
93
98
|
flock/frontend/src/components/graph/TransformEdge.tsx,sha256=dL-FH4a7ujNd7mBgzQvFXrj_KvZeyYXKoEALfnDDCxA,3737
|
|
94
99
|
flock/frontend/src/components/layout/DashboardLayout.css,sha256=CPiz_GqEMx6WDR6FTtlnbLJJPVKezNxdKLM7DJ3ANv8,9409
|
|
95
100
|
flock/frontend/src/components/layout/DashboardLayout.tsx,sha256=GyKvJZX-a3OwNsVgPxP26T-j6khh7B5tGpWrrRb0R1I,10906
|
|
@@ -109,9 +114,9 @@ flock/frontend/src/components/settings/AdvancedSettings.tsx,sha256=Ngw5jAIRn3ocX
|
|
|
109
114
|
flock/frontend/src/components/settings/AppearanceSettings.tsx,sha256=UHH4BcJ9-F-nRJEJf2rzmX0W-0hvmeKo6AYNF3lZPWE,6872
|
|
110
115
|
flock/frontend/src/components/settings/GraphSettings.tsx,sha256=qX1F4hnsxGcCbn3oHP7nsPPMLyETHG3UL55kJ_3tA-s,3815
|
|
111
116
|
flock/frontend/src/components/settings/MultiSelect.tsx,sha256=aFjk8pt18UFHIPh-MXxEepjh-haNYhxEwzMiewSKFbU,7005
|
|
112
|
-
flock/frontend/src/components/settings/SettingsPanel.css,sha256=
|
|
117
|
+
flock/frontend/src/components/settings/SettingsPanel.css,sha256=SUUfMHGXVxX8GDDQcb0f6v7ZG983tXa9pC6Xrwctep8,7062
|
|
113
118
|
flock/frontend/src/components/settings/SettingsPanel.tsx,sha256=62GXPCQzYdbk17XYVOx_vCeWlVyFZSxp3w0JTkp3z60,4392
|
|
114
|
-
flock/frontend/src/components/settings/ThemeSelector.tsx,sha256=
|
|
119
|
+
flock/frontend/src/components/settings/ThemeSelector.tsx,sha256=FqyRtWhN8vm6cxfPI1pxFCCuCFDb4YXrwzdufwrXFqM,10538
|
|
115
120
|
flock/frontend/src/components/settings/TracingSettings.tsx,sha256=zHZrUuVQzUANclHfvTndm50zHYX1y-LecFnrloh2Hkc,14224
|
|
116
121
|
flock/frontend/src/hooks/useKeyboardShortcuts.ts,sha256=Dsf64nPtJdW2kV-a-bBpaq1VXZkXyxpioBnI1WIGduM,5019
|
|
117
122
|
flock/frontend/src/hooks/useModulePersistence.test.ts,sha256=kqYlFSzqYK_0jGxeRTeXORZ2KTDo3MdByJ2t2ivbg20,14323
|
|
@@ -120,18 +125,18 @@ flock/frontend/src/hooks/useModules.ts,sha256=3p47NfBIOWVuHP6tH5sYKhiqK7TuJIsdB5
|
|
|
120
125
|
flock/frontend/src/hooks/usePersistence.ts,sha256=_fHxWLCwNunESIeJVqGB3Z-ANosRGwyAiISCtF5TcmY,4728
|
|
121
126
|
flock/frontend/src/services/api.ts,sha256=kNHBHvbSk50M3pUtwDMNYwco5Cd4AbQbGGHkpROYHhw,8529
|
|
122
127
|
flock/frontend/src/services/graphService.test.ts,sha256=wftS4QX-Bw6hogTWXVYaV3F7z6AN94d7iI8jrMVwwkg,11493
|
|
123
|
-
flock/frontend/src/services/graphService.ts,sha256=
|
|
128
|
+
flock/frontend/src/services/graphService.ts,sha256=MaFdj8S2l7UOkQBkACDv29BuroMy1vJEhliVnsYkmwM,1964
|
|
124
129
|
flock/frontend/src/services/indexeddb.test.ts,sha256=lY1JzyKRd4Kaw135JlO7njy5rpaAsRRXLM8SwYxDhAc,27452
|
|
125
|
-
flock/frontend/src/services/indexeddb.ts,sha256=
|
|
130
|
+
flock/frontend/src/services/indexeddb.ts,sha256=2sXodUZAp3jSiS-3a7Bwvkjdjp_Tc47bk5eR_1f9qqw,28703
|
|
126
131
|
flock/frontend/src/services/layout.test.ts,sha256=-KwUxWCum_Rsyc5NIpk99UB3prfAkMO5ksJULhjOiwA,16174
|
|
127
132
|
flock/frontend/src/services/layout.ts,sha256=5WzlOv7OBlQXiUxrv4l1JwaAfHbUK1C99JOT0fQCNRY,9503
|
|
128
133
|
flock/frontend/src/services/themeApplicator.ts,sha256=utRFw-45e1IEOrI6lHkB_E_-5kc2kFKbN-veAUdXiOM,5802
|
|
129
134
|
flock/frontend/src/services/themeService.ts,sha256=ltDAE30KzzVFDQJGm8awN0Go-l16NgTWYOxlvgxvx0E,1743
|
|
130
|
-
flock/frontend/src/services/websocket.ts,sha256=
|
|
135
|
+
flock/frontend/src/services/websocket.ts,sha256=Zx6xG9z4toNwt2wJ8Dit5mTVqqzHabIl_M-woi3ZFoY,26465
|
|
131
136
|
flock/frontend/src/store/filterStore.test.ts,sha256=0KEaZI1aucfGwZSP76zmJUR2Xl0qqfXqImo-JuSdp4c,8868
|
|
132
137
|
flock/frontend/src/store/filterStore.ts,sha256=mJYzgdm_FFyq-irqfZ7O4-fLrPuRVPBgM7fcIRlP6_s,8967
|
|
133
|
-
flock/frontend/src/store/graphStore.test.ts,sha256=
|
|
134
|
-
flock/frontend/src/store/graphStore.ts,sha256=
|
|
138
|
+
flock/frontend/src/store/graphStore.test.ts,sha256=YOg7MTYaIDQPnzV0qx9m1A7GgHNXRMXgE5AWDlYdCt4,19058
|
|
139
|
+
flock/frontend/src/store/graphStore.ts,sha256=7qI2tQpdEgZNbJ2GguIi9IJL4iyj2Bo6_hH2P7hQjME,17312
|
|
135
140
|
flock/frontend/src/store/moduleStore.test.ts,sha256=VxkoEPu0-B3ln20oBk3xLN-c7J55hMYLN2wQQPs4q-k,7800
|
|
136
141
|
flock/frontend/src/store/moduleStore.ts,sha256=Y2iTxYikvzuZTGBHtFNofcenzljcHvDUDcrZ093XdPA,2361
|
|
137
142
|
flock/frontend/src/store/settingsStore.ts,sha256=JNB25kkKxOlaSY1jFTM64BGynhUZ98jZL1mM87PLCF0,5995
|
|
@@ -141,10 +146,10 @@ flock/frontend/src/store/uiStore.ts,sha256=H5aH8YfaxOTfm3zCrT9A1QdC2dnHJWPUUg8uV
|
|
|
141
146
|
flock/frontend/src/store/wsStore.ts,sha256=vKaGd6H7UONN7A-8tCTOgdH8X2LxrZmVbZ7hRnfGQ2c,936
|
|
142
147
|
flock/frontend/src/styles/index.css,sha256=HVMvVEMvlFk8_vqxBdt8CzkleXkV-oSUcQUzom588PM,231
|
|
143
148
|
flock/frontend/src/styles/scrollbar.css,sha256=OHH2nryMANNvuJBloG_t1BPY_BtKMSb36Df4q2X47Rk,1207
|
|
144
|
-
flock/frontend/src/styles/variables.css,sha256=
|
|
149
|
+
flock/frontend/src/styles/variables.css,sha256=18UzMGPn_GOKWa2eXe1u0lJLI4yRLM7LjONASATwo6Q,13884
|
|
145
150
|
flock/frontend/src/test/setup.ts,sha256=pG1mhRrywFboBf3VdL9ew62xGBxDxeQfChxZLjOK_mQ,36
|
|
146
151
|
flock/frontend/src/types/filters.ts,sha256=zPa4AvL9xudvB6RZsqJCllMoLTnvPuBhqU6vLeWO89Y,1041
|
|
147
|
-
flock/frontend/src/types/graph.ts,sha256=
|
|
152
|
+
flock/frontend/src/types/graph.ts,sha256=mz62owu0OXO-xbzCPX2_arRRv0_Kp79tj5Ek-TqdHhI,4615
|
|
148
153
|
flock/frontend/src/types/modules.ts,sha256=l5ThtDoD1AxXLjGya-EdQM3eAU55Q0J4XZHQsFrUWws,341
|
|
149
154
|
flock/frontend/src/types/theme.ts,sha256=bjV2zWxBJilEXeosjSSirw05dL7zICShUDx2H0oA5J8,903
|
|
150
155
|
flock/frontend/src/utils/artifacts.ts,sha256=JjbNXKgcBaUJdR7VKDi0LK0T3d-ltYt4HHbiQNB3rmI,790
|
|
@@ -185,8 +190,8 @@ flock/mcp/types/handlers.py,sha256=6ukkSMv1VZSfk2QDUiJnm8xifHnQvWZsxWXqN21BYSg,7
|
|
|
185
190
|
flock/mcp/types/types.py,sha256=ZbzbVihABFnfmZz2X-CCN7hQDzaSY0T-en43PFbFwQQ,11469
|
|
186
191
|
flock/mcp/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
187
192
|
flock/mcp/util/helpers.py,sha256=jO8DqqSb_S4dyvsxv5vlMGRoMx92Su_5-Uv17gQNuLU,740
|
|
188
|
-
flock/patches/__init__.py,sha256=
|
|
189
|
-
flock/patches/dspy_streaming_patch.py,sha256=
|
|
193
|
+
flock/patches/__init__.py,sha256=KfRTpO_rz547iKxJDknymar1P3lS_8AhDh-sR1BkcZ0,194
|
|
194
|
+
flock/patches/dspy_streaming_patch.py,sha256=4v24wweqSP6r9GGIijMJgvZ_HgV92e10aPq7kaYNYDs,2763
|
|
190
195
|
flock/themes/3024-day.toml,sha256=uOVHqEzSyHx0WlUk3D0lne4RBsNBAPCTy3C58yU7kEY,667
|
|
191
196
|
flock/themes/3024-night.toml,sha256=qsXUwd6ZYz6J-R129_Ao2TKlvvK60svhZJJjB5c8Tfo,1667
|
|
192
197
|
flock/themes/aardvark-blue.toml,sha256=5ZgsxP3pWLPN3yJ2Wd9ErCo7fy_VJpIfje4kriDKlqo,1667
|
|
@@ -524,8 +529,8 @@ flock/themes/zenburned.toml,sha256=UEmquBbcAO3Zj652XKUwCsNoC2iQSlIh-q5c6DH-7Kc,1
|
|
|
524
529
|
flock/themes/zenwritten-dark.toml,sha256=-dgaUfg1iCr5Dv4UEeHv_cN4GrPUCWAiHSxWK20X1kI,1663
|
|
525
530
|
flock/themes/zenwritten-light.toml,sha256=G1iEheCPfBNsMTGaVpEVpDzYBHA_T-MV27rolUYolmE,1666
|
|
526
531
|
flock/utility/output_utility_component.py,sha256=yVHhlIIIoYKziI5UyT_zvQb4G-NsxCTgLwA1wXXTTj4,9047
|
|
527
|
-
flock_core-0.5.
|
|
528
|
-
flock_core-0.5.
|
|
529
|
-
flock_core-0.5.
|
|
530
|
-
flock_core-0.5.
|
|
531
|
-
flock_core-0.5.
|
|
532
|
+
flock_core-0.5.5.dist-info/METADATA,sha256=t-87LUTaHtfmkBW4U37oAhenOGcoq3WITQfRpuvrgsc,39584
|
|
533
|
+
flock_core-0.5.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
534
|
+
flock_core-0.5.5.dist-info/entry_points.txt,sha256=UQdPmtHd97gSA_IdLt9MOd-1rrf_WO-qsQeIiHWVrp4,42
|
|
535
|
+
flock_core-0.5.5.dist-info/licenses/LICENSE,sha256=U3IZuTbC0yLj7huwJdldLBipSOHF4cPf6cUOodFiaBE,1072
|
|
536
|
+
flock_core-0.5.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|