flock-core 0.5.4__py3-none-any.whl → 0.5.6__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 +153 -17
- flock/components.py +36 -0
- flock/dashboard/collector.py +2 -0
- 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 +1 -1
- flock/frontend/src/components/settings/SettingsPanel.css +1 -1
- flock/frontend/src/components/settings/ThemeSelector.tsx +2 -2
- flock/frontend/src/services/indexeddb.ts +1 -1
- flock/frontend/src/styles/variables.css +1 -1
- flock/orchestrator.py +500 -140
- flock/orchestrator_component.py +686 -0
- flock/runtime.py +3 -0
- {flock_core-0.5.4.dist-info → flock_core-0.5.6.dist-info}/METADATA +69 -3
- {flock_core-0.5.4.dist-info → flock_core-0.5.6.dist-info}/RECORD +24 -21
- {flock_core-0.5.4.dist-info → flock_core-0.5.6.dist-info}/WHEEL +0 -0
- {flock_core-0.5.4.dist-info → flock_core-0.5.6.dist-info}/entry_points.txt +0 -0
- {flock_core-0.5.4.dist-info → flock_core-0.5.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>🦆🐓 Flock 🐤🐧</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-DFRnI_mt.js"></script>
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-fPLNdmp1.css">
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-DFRnI_mt.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-fPLNdmp1.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
|
-
<div id="root"></div>
|
|
11
|
+
<div id="root"></div>
|
|
12
12
|
</body>
|
|
13
13
|
</html>
|
flock/engines/dspy_engine.py
CHANGED
|
@@ -153,6 +153,19 @@ class DSPyEngine(EngineComponent):
|
|
|
153
153
|
)
|
|
154
154
|
|
|
155
155
|
async def evaluate(self, agent, ctx, inputs: EvalInputs) -> EvalResult: # type: ignore[override]
|
|
156
|
+
return await self._evaluate_internal(agent, ctx, inputs, batched=False)
|
|
157
|
+
|
|
158
|
+
async def evaluate_batch(self, agent, ctx, inputs: EvalInputs) -> EvalResult: # type: ignore[override]
|
|
159
|
+
return await self._evaluate_internal(agent, ctx, inputs, batched=True)
|
|
160
|
+
|
|
161
|
+
async def _evaluate_internal(
|
|
162
|
+
self,
|
|
163
|
+
agent,
|
|
164
|
+
ctx,
|
|
165
|
+
inputs: EvalInputs,
|
|
166
|
+
*,
|
|
167
|
+
batched: bool,
|
|
168
|
+
) -> EvalResult:
|
|
156
169
|
if not inputs.artifacts:
|
|
157
170
|
return EvalResult(artifacts=[], state=dict(inputs.state))
|
|
158
171
|
|
|
@@ -169,7 +182,13 @@ class DSPyEngine(EngineComponent):
|
|
|
169
182
|
|
|
170
183
|
primary_artifact = self._select_primary_artifact(inputs.artifacts)
|
|
171
184
|
input_model = self._resolve_input_model(primary_artifact)
|
|
172
|
-
|
|
185
|
+
if batched:
|
|
186
|
+
validated_input = [
|
|
187
|
+
self._validate_input_payload(input_model, artifact.payload)
|
|
188
|
+
for artifact in inputs.artifacts
|
|
189
|
+
]
|
|
190
|
+
else:
|
|
191
|
+
validated_input = self._validate_input_payload(input_model, primary_artifact.payload)
|
|
173
192
|
output_model = self._resolve_output_model(agent)
|
|
174
193
|
|
|
175
194
|
# Fetch conversation context from blackboard
|
|
@@ -183,6 +202,7 @@ class DSPyEngine(EngineComponent):
|
|
|
183
202
|
input_schema=input_model,
|
|
184
203
|
output_schema=output_model,
|
|
185
204
|
has_context=has_context,
|
|
205
|
+
batched=batched,
|
|
186
206
|
)
|
|
187
207
|
|
|
188
208
|
sys_desc = self._system_description(self.instructions or agent.description)
|
|
@@ -193,7 +213,11 @@ class DSPyEngine(EngineComponent):
|
|
|
193
213
|
pre_generated_artifact_id = uuid4()
|
|
194
214
|
|
|
195
215
|
# Build execution payload with context
|
|
196
|
-
if
|
|
216
|
+
if batched:
|
|
217
|
+
execution_payload = {"input": validated_input}
|
|
218
|
+
if has_context:
|
|
219
|
+
execution_payload["context"] = context_history
|
|
220
|
+
elif has_context:
|
|
197
221
|
execution_payload = {
|
|
198
222
|
"input": validated_input,
|
|
199
223
|
"context": context_history,
|
|
@@ -383,6 +407,7 @@ class DSPyEngine(EngineComponent):
|
|
|
383
407
|
input_schema: type[BaseModel] | None,
|
|
384
408
|
output_schema: type[BaseModel] | None,
|
|
385
409
|
has_context: bool = False,
|
|
410
|
+
batched: bool = False,
|
|
386
411
|
) -> Any:
|
|
387
412
|
"""Prepare DSPy signature, optionally including context field."""
|
|
388
413
|
fields = {
|
|
@@ -398,7 +423,15 @@ class DSPyEngine(EngineComponent):
|
|
|
398
423
|
),
|
|
399
424
|
)
|
|
400
425
|
|
|
401
|
-
|
|
426
|
+
if batched:
|
|
427
|
+
if input_schema is not None:
|
|
428
|
+
input_type = list[input_schema]
|
|
429
|
+
else:
|
|
430
|
+
input_type = list[dict[str, Any]]
|
|
431
|
+
else:
|
|
432
|
+
input_type = input_schema or dict
|
|
433
|
+
|
|
434
|
+
fields["input"] = (input_type, dspy_mod.InputField())
|
|
402
435
|
fields["output"] = (output_schema or dict, dspy_mod.OutputField())
|
|
403
436
|
|
|
404
437
|
signature = dspy_mod.Signature(fields)
|
|
@@ -406,6 +439,11 @@ class DSPyEngine(EngineComponent):
|
|
|
406
439
|
instruction = description or "Produce a valid output that matches the 'output' schema."
|
|
407
440
|
if has_context:
|
|
408
441
|
instruction += " Consider the conversation context provided to inform your response."
|
|
442
|
+
if batched:
|
|
443
|
+
instruction += (
|
|
444
|
+
" The 'input' field will contain a list of items representing the batch; "
|
|
445
|
+
"process the entire collection coherently."
|
|
446
|
+
)
|
|
409
447
|
instruction += " Return only JSON."
|
|
410
448
|
|
|
411
449
|
return signature.with_instructions(instruction)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Reference batch-aware engine used in tutorials and tests."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
from flock.components import EngineComponent
|
|
8
|
+
from flock.registry import flock_type
|
|
9
|
+
from flock.runtime import EvalInputs, EvalResult
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@flock_type(name="BatchItem")
|
|
13
|
+
class BatchItem(BaseModel):
|
|
14
|
+
"""Input payload used by reference tests and tutorials."""
|
|
15
|
+
|
|
16
|
+
value: int = Field(description="Numeric value contributed by the artifact")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@flock_type(name="BatchSummary")
|
|
20
|
+
class BatchSummary(BaseModel):
|
|
21
|
+
"""Output payload describing the batch that was processed."""
|
|
22
|
+
|
|
23
|
+
batch_size: int = Field(description="Number of items included in this evaluation")
|
|
24
|
+
values: list[int] = Field(description="Original values processed", default_factory=list)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SimpleBatchEngine(EngineComponent):
|
|
28
|
+
"""Example engine that processes items individually or in batches.
|
|
29
|
+
|
|
30
|
+
- ``evaluate`` is used when the agent is invoked directly without BatchSpec.
|
|
31
|
+
- ``evaluate_batch`` is triggered when BatchSpec flushes accumulated artifacts.
|
|
32
|
+
|
|
33
|
+
The engine simply annotates each item with the current batch size so tests can
|
|
34
|
+
verify that all artifacts were processed together.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
async def evaluate(self, agent, ctx, inputs: EvalInputs) -> EvalResult:
|
|
38
|
+
item = inputs.first_as(BatchItem)
|
|
39
|
+
if item is None:
|
|
40
|
+
return EvalResult.empty()
|
|
41
|
+
|
|
42
|
+
annotated = BatchSummary(batch_size=1, values=[item.value])
|
|
43
|
+
state = dict(inputs.state)
|
|
44
|
+
state.setdefault("batch_size", annotated.batch_size)
|
|
45
|
+
state.setdefault("processed_values", list(annotated.values))
|
|
46
|
+
|
|
47
|
+
return EvalResult.from_object(annotated, agent=agent, state=state)
|
|
48
|
+
|
|
49
|
+
async def evaluate_batch(self, agent, ctx, inputs: EvalInputs) -> EvalResult:
|
|
50
|
+
items = inputs.all_as(BatchItem)
|
|
51
|
+
if not items:
|
|
52
|
+
return EvalResult.empty()
|
|
53
|
+
|
|
54
|
+
batch_size = len(items)
|
|
55
|
+
summary = BatchSummary(batch_size=batch_size, values=[item.value for item in items])
|
|
56
|
+
|
|
57
|
+
state = dict(inputs.state)
|
|
58
|
+
state["batch_size"] = summary.batch_size
|
|
59
|
+
state["processed_values"] = list(summary.values)
|
|
60
|
+
|
|
61
|
+
return EvalResult.from_object(summary, agent=agent, state=state)
|
flock/frontend/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Flock
|
|
1
|
+
# Flock Dashboard
|
|
2
2
|
|
|
3
|
-
A real-time visualization dashboard for monitoring and controlling Flock
|
|
3
|
+
A real-time visualization dashboard for monitoring and controlling Flock agent orchestration systems. Built with modern web technologies to provide an intuitive, high-performance interface for observing multi-agent workflows.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
The Flock
|
|
7
|
+
The Flock Dashboard provides real-time visibility into your agent orchestration system through an interactive graph-based interface. Watch agents activate, messages flow, and data transform in real-time as your multi-agent system operates.
|
|
8
8
|
|
|
9
9
|
The dashboard offers two complementary visualization modes:
|
|
10
10
|
- **Agent View**: Shows agents as nodes with message flows as edges - perfect for understanding agent communication patterns
|
|
@@ -149,7 +149,7 @@ Launch the module via the context menu (or `Add Module → Historical Blackboard
|
|
|
149
149
|
|
|
150
150
|
- **Node.js**: Version 18 or higher
|
|
151
151
|
- **Package Manager**: npm (included with Node.js) or yarn
|
|
152
|
-
- **Flock
|
|
152
|
+
- **Flock Backend**: Running orchestrator instance (typically on port 8344)
|
|
153
153
|
|
|
154
154
|
### Installation
|
|
155
155
|
|
flock/frontend/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flock-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "flock-ui",
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.8",
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@types/dagre": "^0.7.53",
|
flock/frontend/package.json
CHANGED
|
@@ -150,7 +150,7 @@ const ThemeSelector: React.FC = () => {
|
|
|
150
150
|
justifyContent: 'space-between',
|
|
151
151
|
}}>
|
|
152
152
|
<span style={{ color: 'var(--color-text-primary)' }}>
|
|
153
|
-
{currentTheme === 'default' ? 'Default (Flock
|
|
153
|
+
{currentTheme === 'default' ? 'Default (Flock)' : currentTheme}
|
|
154
154
|
</span>
|
|
155
155
|
{currentTheme !== 'default' && (
|
|
156
156
|
<button
|
|
@@ -191,7 +191,7 @@ const ThemeSelector: React.FC = () => {
|
|
|
191
191
|
transition: 'var(--transition-all)',
|
|
192
192
|
}}
|
|
193
193
|
>
|
|
194
|
-
Default (Flock
|
|
194
|
+
Default (Flock)
|
|
195
195
|
</button>
|
|
196
196
|
</div>
|
|
197
197
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* IndexedDB Persistence Service for Flock
|
|
2
|
+
* IndexedDB Persistence Service for Flock Dashboard
|
|
3
3
|
*
|
|
4
4
|
* Provides persistent storage for dashboard data with LRU eviction strategy.
|
|
5
5
|
* Implements separate layout storage for Agent View and Blackboard View.
|