flock-core 0.5.10__py3-none-any.whl → 0.5.20__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/__init__.py +1 -1
- flock/agent/__init__.py +30 -0
- flock/agent/builder_helpers.py +192 -0
- flock/agent/builder_validator.py +169 -0
- flock/agent/component_lifecycle.py +325 -0
- flock/agent/context_resolver.py +141 -0
- flock/agent/mcp_integration.py +212 -0
- flock/agent/output_processor.py +304 -0
- flock/api/__init__.py +20 -0
- flock/api/models.py +283 -0
- flock/{service.py → api/service.py} +121 -63
- flock/cli.py +2 -2
- flock/components/__init__.py +41 -0
- flock/components/agent/__init__.py +22 -0
- flock/{components.py → components/agent/base.py} +4 -3
- flock/{utility/output_utility_component.py → components/agent/output_utility.py} +12 -7
- flock/components/orchestrator/__init__.py +22 -0
- flock/{orchestrator_component.py → components/orchestrator/base.py} +5 -293
- flock/components/orchestrator/circuit_breaker.py +95 -0
- flock/components/orchestrator/collection.py +143 -0
- flock/components/orchestrator/deduplication.py +78 -0
- flock/core/__init__.py +30 -0
- flock/core/agent.py +953 -0
- flock/{artifacts.py → core/artifacts.py} +1 -1
- flock/{context_provider.py → core/context_provider.py} +3 -3
- flock/core/orchestrator.py +1102 -0
- flock/{store.py → core/store.py} +99 -454
- flock/{subscription.py → core/subscription.py} +1 -1
- flock/dashboard/collector.py +5 -5
- flock/dashboard/graph_builder.py +7 -7
- flock/dashboard/routes/__init__.py +21 -0
- flock/dashboard/routes/control.py +327 -0
- flock/dashboard/routes/helpers.py +340 -0
- flock/dashboard/routes/themes.py +76 -0
- flock/dashboard/routes/traces.py +521 -0
- flock/dashboard/routes/websocket.py +108 -0
- flock/dashboard/service.py +44 -1294
- flock/engines/dspy/__init__.py +20 -0
- flock/engines/dspy/artifact_materializer.py +216 -0
- flock/engines/dspy/signature_builder.py +474 -0
- flock/engines/dspy/streaming_executor.py +858 -0
- flock/engines/dspy_engine.py +45 -1330
- flock/engines/examples/simple_batch_engine.py +2 -2
- flock/examples.py +7 -7
- flock/logging/logging.py +1 -16
- flock/models/__init__.py +10 -0
- flock/models/system_artifacts.py +33 -0
- flock/orchestrator/__init__.py +45 -0
- flock/{artifact_collector.py → orchestrator/artifact_collector.py} +3 -3
- flock/orchestrator/artifact_manager.py +168 -0
- flock/{batch_accumulator.py → orchestrator/batch_accumulator.py} +2 -2
- flock/orchestrator/component_runner.py +389 -0
- flock/orchestrator/context_builder.py +167 -0
- flock/{correlation_engine.py → orchestrator/correlation_engine.py} +2 -2
- flock/orchestrator/event_emitter.py +167 -0
- flock/orchestrator/initialization.py +184 -0
- flock/orchestrator/lifecycle_manager.py +226 -0
- flock/orchestrator/mcp_manager.py +202 -0
- flock/orchestrator/scheduler.py +189 -0
- flock/orchestrator/server_manager.py +234 -0
- flock/orchestrator/tracing.py +147 -0
- flock/storage/__init__.py +10 -0
- flock/storage/artifact_aggregator.py +158 -0
- flock/storage/in_memory/__init__.py +6 -0
- flock/storage/in_memory/artifact_filter.py +114 -0
- flock/storage/in_memory/history_aggregator.py +115 -0
- flock/storage/sqlite/__init__.py +10 -0
- flock/storage/sqlite/agent_history_queries.py +154 -0
- flock/storage/sqlite/consumption_loader.py +100 -0
- flock/storage/sqlite/query_builder.py +112 -0
- flock/storage/sqlite/query_params_builder.py +91 -0
- flock/storage/sqlite/schema_manager.py +168 -0
- flock/storage/sqlite/summary_queries.py +194 -0
- flock/utils/__init__.py +14 -0
- flock/utils/async_utils.py +67 -0
- flock/{runtime.py → utils/runtime.py} +3 -3
- flock/utils/time_utils.py +53 -0
- flock/utils/type_resolution.py +38 -0
- flock/{utilities.py → utils/utilities.py} +2 -2
- flock/utils/validation.py +57 -0
- flock/utils/visibility.py +79 -0
- flock/utils/visibility_utils.py +134 -0
- {flock_core-0.5.10.dist-info → flock_core-0.5.20.dist-info}/METADATA +69 -61
- {flock_core-0.5.10.dist-info → flock_core-0.5.20.dist-info}/RECORD +89 -31
- flock/agent.py +0 -1578
- flock/orchestrator.py +0 -1746
- /flock/{visibility.py → core/visibility.py} +0 -0
- /flock/{helper → utils}/cli_helper.py +0 -0
- {flock_core-0.5.10.dist-info → flock_core-0.5.20.dist-info}/WHEEL +0 -0
- {flock_core-0.5.10.dist-info → flock_core-0.5.20.dist-info}/entry_points.txt +0 -0
- {flock_core-0.5.10.dist-info → flock_core-0.5.20.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,9 +4,9 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel, Field
|
|
6
6
|
|
|
7
|
-
from flock.components import EngineComponent
|
|
7
|
+
from flock.components.agent import EngineComponent
|
|
8
8
|
from flock.registry import flock_type
|
|
9
|
-
from flock.runtime import EvalInputs, EvalResult
|
|
9
|
+
from flock.utils.runtime import EvalInputs, EvalResult
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@flock_type(name="BatchItem")
|
flock/examples.py
CHANGED
|
@@ -13,17 +13,17 @@ from typing import TYPE_CHECKING
|
|
|
13
13
|
|
|
14
14
|
from pydantic import BaseModel, Field
|
|
15
15
|
|
|
16
|
-
from flock.
|
|
17
|
-
from flock.
|
|
18
|
-
from flock.
|
|
16
|
+
from flock.components.agent import EngineComponent
|
|
17
|
+
from flock.core import Flock
|
|
18
|
+
from flock.core.artifacts import Artifact
|
|
19
|
+
from flock.core.store import BlackboardStore
|
|
19
20
|
from flock.registry import flock_tool, flock_type, type_registry
|
|
20
|
-
from flock.runtime import EvalInputs, EvalResult
|
|
21
|
-
from flock.
|
|
22
|
-
from flock.utilities import LoggingUtility, MetricsUtility
|
|
21
|
+
from flock.utils.runtime import EvalInputs, EvalResult
|
|
22
|
+
from flock.utils.utilities import LoggingUtility, MetricsUtility
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
if TYPE_CHECKING:
|
|
26
|
-
from flock.
|
|
26
|
+
from flock.core import AgentBuilder
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
@flock_type
|
flock/logging/logging.py
CHANGED
|
@@ -42,13 +42,6 @@ def in_workflow_context() -> bool:
|
|
|
42
42
|
if successful. Otherwise, it returns False.
|
|
43
43
|
"""
|
|
44
44
|
return False
|
|
45
|
-
# try:
|
|
46
|
-
# workflow.logger.debug("Checking if in workflow context...")
|
|
47
|
-
# # loguru_logger.debug("Checking if in workflow context...")
|
|
48
|
-
# # This call will succeed only if we're in a workflow context.
|
|
49
|
-
# return bool(hasattr(workflow.info(), "is_replaying"))
|
|
50
|
-
# except Exception:
|
|
51
|
-
# return False
|
|
52
45
|
|
|
53
46
|
|
|
54
47
|
def get_current_trace_id() -> str:
|
|
@@ -374,9 +367,6 @@ class FlockLogger:
|
|
|
374
367
|
self.min_level_severity = initial_min_level_severity
|
|
375
368
|
|
|
376
369
|
def _get_logger(self):
|
|
377
|
-
# if in_workflow_context():
|
|
378
|
-
# # Use Temporal's workflow.logger inside a workflow context.
|
|
379
|
-
# return workflow.logger
|
|
380
370
|
# Bind our logger with category and trace_id
|
|
381
371
|
return loguru_logger.bind(
|
|
382
372
|
name=self.name,
|
|
@@ -562,12 +552,7 @@ def get_logger(name: str = "flock") -> FlockLogger:
|
|
|
562
552
|
|
|
563
553
|
def get_module_loggers() -> list[FlockLogger]:
|
|
564
554
|
"""Return a cached FlockLogger instance for the given module name."""
|
|
565
|
-
|
|
566
|
-
for kvp in _LOGGER_CACHE:
|
|
567
|
-
if kvp.startswith("module."):
|
|
568
|
-
result.append(_LOGGER_CACHE[kvp])
|
|
569
|
-
|
|
570
|
-
return result
|
|
555
|
+
return [_LOGGER_CACHE[kvp] for kvp in _LOGGER_CACHE if kvp.startswith("module.")]
|
|
571
556
|
|
|
572
557
|
|
|
573
558
|
def truncate_for_logging(obj, max_item_length=100, max_items=10):
|
flock/models/__init__.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""System data models for Flock.
|
|
2
|
+
|
|
3
|
+
This module contains system-level artifact types used by the orchestrator
|
|
4
|
+
for error handling, workflow tracking, and internal communication.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from flock.models.system_artifacts import WorkflowError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
__all__ = ["WorkflowError"]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""System-level artifact types published by the Flock orchestrator.
|
|
2
|
+
|
|
3
|
+
These artifacts provide workflow telemetry and error tracking.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
from flock.registry import flock_type
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@flock_type
|
|
14
|
+
class WorkflowError(BaseModel):
|
|
15
|
+
"""Error artifact published when an agent execution fails.
|
|
16
|
+
|
|
17
|
+
This artifact is automatically published by the orchestrator when an agent
|
|
18
|
+
raises an exception during execution. It includes the correlation_id to enable
|
|
19
|
+
error tracking for workflows.
|
|
20
|
+
|
|
21
|
+
The workflow continues execution for other branches even when this is published.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
failed_agent: str = Field(description="Name of the agent that failed")
|
|
25
|
+
error_type: str = Field(description="Type of exception that occurred")
|
|
26
|
+
error_message: str = Field(description="Error message from the exception")
|
|
27
|
+
timestamp: datetime = Field(description="When the error occurred")
|
|
28
|
+
task_id: str | None = Field(
|
|
29
|
+
default=None, description="Task ID of the failed execution"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
__all__ = ["WorkflowError"]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Orchestrator implementation modules.
|
|
2
|
+
|
|
3
|
+
This package contains internal implementation details for the Flock orchestrator.
|
|
4
|
+
|
|
5
|
+
Phase 5A Additions:
|
|
6
|
+
- ContextBuilder: Security-critical context building with provider resolution
|
|
7
|
+
- EventEmitter: Dashboard WebSocket event emission
|
|
8
|
+
- LifecycleManager: Background task coordination for batches and correlations
|
|
9
|
+
|
|
10
|
+
Phase 3 Additions (Orchestrator Simplification):
|
|
11
|
+
- TracingManager: Unified tracing and trace database management
|
|
12
|
+
- ServerManager: HTTP service startup and dashboard integration
|
|
13
|
+
- OrchestratorInitializer: Component setup and state initialization
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from flock.orchestrator.artifact_collector import ArtifactCollector
|
|
17
|
+
from flock.orchestrator.artifact_manager import ArtifactManager
|
|
18
|
+
from flock.orchestrator.batch_accumulator import BatchAccumulator
|
|
19
|
+
from flock.orchestrator.component_runner import ComponentRunner
|
|
20
|
+
from flock.orchestrator.context_builder import ContextBuilder
|
|
21
|
+
from flock.orchestrator.correlation_engine import CorrelationEngine
|
|
22
|
+
from flock.orchestrator.event_emitter import EventEmitter
|
|
23
|
+
from flock.orchestrator.initialization import OrchestratorInitializer
|
|
24
|
+
from flock.orchestrator.lifecycle_manager import LifecycleManager
|
|
25
|
+
from flock.orchestrator.mcp_manager import MCPManager
|
|
26
|
+
from flock.orchestrator.scheduler import AgentScheduler
|
|
27
|
+
from flock.orchestrator.server_manager import ServerManager
|
|
28
|
+
from flock.orchestrator.tracing import TracingManager
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"AgentScheduler",
|
|
33
|
+
"ArtifactCollector",
|
|
34
|
+
"ArtifactManager",
|
|
35
|
+
"BatchAccumulator",
|
|
36
|
+
"ComponentRunner",
|
|
37
|
+
"ContextBuilder",
|
|
38
|
+
"CorrelationEngine",
|
|
39
|
+
"EventEmitter",
|
|
40
|
+
"LifecycleManager",
|
|
41
|
+
"MCPManager",
|
|
42
|
+
"OrchestratorInitializer",
|
|
43
|
+
"ServerManager",
|
|
44
|
+
"TracingManager",
|
|
45
|
+
]
|
|
@@ -17,9 +17,9 @@ from typing import TYPE_CHECKING
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
if TYPE_CHECKING:
|
|
20
|
-
from flock.
|
|
21
|
-
from flock.artifacts import Artifact
|
|
22
|
-
from flock.subscription import Subscription
|
|
20
|
+
from flock.core import Agent
|
|
21
|
+
from flock.core.artifacts import Artifact
|
|
22
|
+
from flock.core.subscription import Subscription
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class ArtifactCollector:
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""Artifact publishing and persistence."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
from uuid import uuid4
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
from flock.core.artifacts import Artifact
|
|
12
|
+
from flock.core.visibility import PublicVisibility, Visibility
|
|
13
|
+
from flock.registry import type_registry
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from flock.core import Flock
|
|
18
|
+
from flock.core.store import BlackboardStore
|
|
19
|
+
from flock.orchestrator import AgentScheduler
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ArtifactManager:
|
|
23
|
+
"""Manages artifact publishing and persistence.
|
|
24
|
+
|
|
25
|
+
Responsibilities:
|
|
26
|
+
- Normalize different input types (BaseModel, dict, Artifact)
|
|
27
|
+
- Persist artifacts to store
|
|
28
|
+
- Trigger scheduling after publish
|
|
29
|
+
- Handle batch publishing
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self, orchestrator: Flock, store: BlackboardStore, scheduler: AgentScheduler
|
|
34
|
+
):
|
|
35
|
+
"""Initialize artifact manager.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
orchestrator: Flock orchestrator instance
|
|
39
|
+
store: Blackboard store for persistence
|
|
40
|
+
scheduler: Scheduler for triggering agent execution
|
|
41
|
+
"""
|
|
42
|
+
self._orchestrator = orchestrator
|
|
43
|
+
self._store = store
|
|
44
|
+
self._scheduler = scheduler
|
|
45
|
+
self._logger = orchestrator._logger
|
|
46
|
+
|
|
47
|
+
async def publish(
|
|
48
|
+
self,
|
|
49
|
+
obj: BaseModel | dict | Artifact,
|
|
50
|
+
*,
|
|
51
|
+
visibility: Visibility | None = None,
|
|
52
|
+
correlation_id: str | None = None,
|
|
53
|
+
partition_key: str | None = None,
|
|
54
|
+
tags: set[str] | None = None,
|
|
55
|
+
is_dashboard: bool = False,
|
|
56
|
+
) -> Artifact:
|
|
57
|
+
"""Publish an artifact to the blackboard (event-driven).
|
|
58
|
+
|
|
59
|
+
All agents with matching subscriptions will be triggered according to
|
|
60
|
+
their filters (type, predicates, visibility, etc).
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
obj: Object to publish (BaseModel instance, dict, or Artifact)
|
|
64
|
+
visibility: Access control (defaults to PublicVisibility)
|
|
65
|
+
correlation_id: Optional correlation ID for request tracing
|
|
66
|
+
partition_key: Optional partition key for sharding
|
|
67
|
+
tags: Optional tags for channel-based routing
|
|
68
|
+
is_dashboard: Internal flag for dashboard events
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
The published Artifact
|
|
72
|
+
|
|
73
|
+
Examples:
|
|
74
|
+
>>> # Publish a model instance (recommended)
|
|
75
|
+
>>> task = Task(name="Deploy", priority=5)
|
|
76
|
+
>>> await artifact_manager.publish(task)
|
|
77
|
+
|
|
78
|
+
>>> # Publish with custom visibility
|
|
79
|
+
>>> await artifact_manager.publish(
|
|
80
|
+
... task, visibility=PrivateVisibility(agents={"admin"})
|
|
81
|
+
... )
|
|
82
|
+
"""
|
|
83
|
+
# Handle different input types
|
|
84
|
+
if isinstance(obj, Artifact):
|
|
85
|
+
# Already an artifact - publish as-is
|
|
86
|
+
artifact = obj
|
|
87
|
+
elif isinstance(obj, BaseModel):
|
|
88
|
+
# BaseModel instance - get type from registry
|
|
89
|
+
type_name = type_registry.name_for(type(obj))
|
|
90
|
+
artifact = Artifact(
|
|
91
|
+
type=type_name,
|
|
92
|
+
payload=obj.model_dump(),
|
|
93
|
+
produced_by="external",
|
|
94
|
+
visibility=visibility or PublicVisibility(),
|
|
95
|
+
correlation_id=correlation_id or uuid4(),
|
|
96
|
+
partition_key=partition_key,
|
|
97
|
+
tags=tags or set(),
|
|
98
|
+
)
|
|
99
|
+
elif isinstance(obj, dict):
|
|
100
|
+
# Dict must have 'type' key
|
|
101
|
+
if "type" not in obj:
|
|
102
|
+
raise ValueError(
|
|
103
|
+
"Dict input must contain 'type' key. "
|
|
104
|
+
"Example: {'type': 'Task', 'name': 'foo', 'priority': 5}"
|
|
105
|
+
)
|
|
106
|
+
# Support both {'type': 'X', 'payload': {...}} and {'type': 'X', ...}
|
|
107
|
+
type_name = obj["type"]
|
|
108
|
+
if "payload" in obj:
|
|
109
|
+
payload = obj["payload"]
|
|
110
|
+
else:
|
|
111
|
+
payload = {k: v for k, v in obj.items() if k != "type"}
|
|
112
|
+
|
|
113
|
+
artifact = Artifact(
|
|
114
|
+
type=type_name,
|
|
115
|
+
payload=payload,
|
|
116
|
+
produced_by="external",
|
|
117
|
+
visibility=visibility or PublicVisibility(),
|
|
118
|
+
correlation_id=correlation_id,
|
|
119
|
+
partition_key=partition_key,
|
|
120
|
+
tags=tags or set(),
|
|
121
|
+
)
|
|
122
|
+
else:
|
|
123
|
+
raise TypeError(
|
|
124
|
+
f"Cannot publish object of type {type(obj).__name__}. "
|
|
125
|
+
"Expected BaseModel, dict, or Artifact."
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Persist and schedule matching agents
|
|
129
|
+
await self.persist_and_schedule(artifact)
|
|
130
|
+
return artifact
|
|
131
|
+
|
|
132
|
+
async def publish_many(
|
|
133
|
+
self, objects: Iterable[BaseModel | dict | Artifact], **kwargs: Any
|
|
134
|
+
) -> list[Artifact]:
|
|
135
|
+
"""Publish multiple artifacts at once (event-driven).
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
objects: Iterable of objects to publish
|
|
139
|
+
**kwargs: Passed to each publish() call (visibility, tags, etc)
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
List of published Artifacts
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
>>> tasks = [
|
|
146
|
+
... Task(name="Deploy", priority=5),
|
|
147
|
+
... Task(name="Test", priority=3),
|
|
148
|
+
... ]
|
|
149
|
+
>>> await artifact_manager.publish_many(tasks, tags={"sprint-3"})
|
|
150
|
+
"""
|
|
151
|
+
artifacts = []
|
|
152
|
+
for obj in objects:
|
|
153
|
+
artifact = await self.publish(obj, **kwargs)
|
|
154
|
+
artifacts.append(artifact)
|
|
155
|
+
return artifacts
|
|
156
|
+
|
|
157
|
+
async def persist_and_schedule(self, artifact: Artifact) -> None:
|
|
158
|
+
"""Persist artifact to store and trigger scheduling.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
artifact: Artifact to publish
|
|
162
|
+
"""
|
|
163
|
+
await self._store.publish(artifact)
|
|
164
|
+
self._orchestrator.metrics["artifacts_published"] += 1
|
|
165
|
+
await self._scheduler.schedule_artifact(artifact)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
__all__ = ["ArtifactManager"]
|
|
@@ -16,8 +16,8 @@ from typing import TYPE_CHECKING
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
if TYPE_CHECKING:
|
|
19
|
-
from flock.artifacts import Artifact
|
|
20
|
-
from flock.subscription import BatchSpec, Subscription
|
|
19
|
+
from flock.core.artifacts import Artifact
|
|
20
|
+
from flock.core.subscription import BatchSpec, Subscription
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class BatchAccumulator:
|