flock-core 0.3.23__py3-none-any.whl → 0.3.30__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.

@@ -1,12 +1,33 @@
1
- """Module for serializable objects in the system."""
2
-
1
+ # src/flock/core/serialization/serializable.py
3
2
  import json
4
3
  from abc import ABC, abstractmethod
5
4
  from pathlib import Path
6
5
  from typing import Any, TypeVar
7
6
 
8
- import cloudpickle
9
- import msgpack
7
+ # Use yaml if available, otherwise skip yaml methods
8
+ try:
9
+ import yaml
10
+
11
+ YAML_AVAILABLE = True
12
+ except ImportError:
13
+ YAML_AVAILABLE = False
14
+
15
+ # Use msgpack if available
16
+ try:
17
+ import msgpack
18
+
19
+ MSGPACK_AVAILABLE = True
20
+ except ImportError:
21
+ MSGPACK_AVAILABLE = False
22
+
23
+ # Use cloudpickle
24
+ try:
25
+ import cloudpickle
26
+
27
+ PICKLE_AVAILABLE = True
28
+ except ImportError:
29
+ PICKLE_AVAILABLE = False
30
+
10
31
 
11
32
  T = TypeVar("T", bound="Serializable")
12
33
 
@@ -15,79 +36,280 @@ class Serializable(ABC):
15
36
  """Base class for all serializable objects in the system.
16
37
 
17
38
  Provides methods for serializing/deserializing objects to various formats.
39
+ Subclasses MUST implement to_dict and from_dict.
18
40
  """
19
41
 
20
42
  @abstractmethod
21
43
  def to_dict(self) -> dict[str, Any]:
22
- """Convert instance to dictionary representation."""
44
+ """Convert instance to a dictionary representation suitable for serialization.
45
+ This method should handle converting nested Serializable objects and callables.
46
+ """
23
47
  pass
24
48
 
25
49
  @classmethod
26
50
  @abstractmethod
27
51
  def from_dict(cls: type[T], data: dict[str, Any]) -> T:
28
- """Create instance from dictionary representation."""
52
+ """Create instance from a dictionary representation.
53
+ This method should handle reconstructing nested Serializable objects and callables.
54
+ """
29
55
  pass
30
56
 
31
- def to_json(self) -> str:
57
+ # --- JSON Methods ---
58
+ def to_json(self, indent: int | None = 2) -> str:
32
59
  """Serialize to JSON string."""
60
+ # Import encoder locally to avoid making it a hard dependency if JSON isn't used
61
+ from .json_encoder import FlockJSONEncoder
62
+
33
63
  try:
34
- return json.dumps(self.to_dict())
35
- except Exception:
36
- raise
64
+ # Note: to_dict should ideally prepare the structure fully.
65
+ # FlockJSONEncoder is a fallback for types missed by to_dict.
66
+ return json.dumps(
67
+ self.to_dict(), cls=FlockJSONEncoder, indent=indent
68
+ )
69
+ except Exception as e:
70
+ raise RuntimeError(
71
+ f"Failed to serialize {self.__class__.__name__} to JSON: {e}"
72
+ ) from e
37
73
 
38
74
  @classmethod
39
75
  def from_json(cls: type[T], json_str: str) -> T:
40
76
  """Create instance from JSON string."""
41
77
  try:
42
- return cls.from_dict(json.loads(json_str))
43
- except Exception:
78
+ data = json.loads(json_str)
79
+ return cls.from_dict(data)
80
+ except json.JSONDecodeError as e:
81
+ raise ValueError(f"Invalid JSON string: {e}") from e
82
+ except Exception as e:
83
+ raise RuntimeError(
84
+ f"Failed to deserialize {cls.__name__} from JSON: {e}"
85
+ ) from e
86
+
87
+ # --- YAML Methods ---
88
+ def to_yaml(self, sort_keys=False, default_flow_style=False) -> str:
89
+ """Serialize to YAML string."""
90
+ if not YAML_AVAILABLE:
91
+ raise NotImplementedError(
92
+ "YAML support requires PyYAML: pip install pyyaml"
93
+ )
94
+ try:
95
+ # to_dict should prepare a structure suitable for YAML dumping
96
+ return yaml.dump(
97
+ self.to_dict(),
98
+ sort_keys=sort_keys,
99
+ default_flow_style=default_flow_style,
100
+ allow_unicode=True,
101
+ )
102
+ except Exception as e:
103
+ raise RuntimeError(
104
+ f"Failed to serialize {self.__class__.__name__} to YAML: {e}"
105
+ ) from e
106
+
107
+ @classmethod
108
+ def from_yaml(cls: type[T], yaml_str: str) -> T:
109
+ """Create instance from YAML string."""
110
+ if not YAML_AVAILABLE:
111
+ raise NotImplementedError(
112
+ "YAML support requires PyYAML: pip install pyyaml"
113
+ )
114
+ try:
115
+ data = yaml.safe_load(yaml_str)
116
+ if not isinstance(data, dict):
117
+ raise TypeError(
118
+ f"YAML did not yield a dictionary for {cls.__name__}"
119
+ )
120
+ return cls.from_dict(data)
121
+ except yaml.YAMLError as e:
122
+ raise ValueError(f"Invalid YAML string: {e}") from e
123
+ except Exception as e:
124
+ raise RuntimeError(
125
+ f"Failed to deserialize {cls.__name__} from YAML: {e}"
126
+ ) from e
127
+
128
+ def to_yaml_file(self, path: Path | str, **yaml_dump_kwargs) -> None:
129
+ """Serialize to YAML file."""
130
+ if not YAML_AVAILABLE:
131
+ raise NotImplementedError(
132
+ "YAML support requires PyYAML: pip install pyyaml"
133
+ )
134
+ path = Path(path)
135
+ try:
136
+ path.parent.mkdir(parents=True, exist_ok=True)
137
+ yaml_str = self.to_yaml(**yaml_dump_kwargs)
138
+ path.write_text(yaml_str, encoding="utf-8")
139
+ except Exception as e:
140
+ raise RuntimeError(
141
+ f"Failed to write {self.__class__.__name__} to YAML file {path}: {e}"
142
+ ) from e
143
+
144
+ @classmethod
145
+ def from_yaml_file(cls: type[T], path: Path | str) -> T:
146
+ """Create instance from YAML file."""
147
+ if not YAML_AVAILABLE:
148
+ raise NotImplementedError(
149
+ "YAML support requires PyYAML: pip install pyyaml"
150
+ )
151
+ path = Path(path)
152
+ try:
153
+ yaml_str = path.read_text(encoding="utf-8")
154
+ return cls.from_yaml(yaml_str)
155
+ except FileNotFoundError:
44
156
  raise
157
+ except Exception as e:
158
+ raise RuntimeError(
159
+ f"Failed to read {cls.__name__} from YAML file {path}: {e}"
160
+ ) from e
45
161
 
46
- def to_msgpack(self, path: Path | None = None) -> bytes:
162
+ # --- MsgPack Methods ---
163
+ def to_msgpack(self) -> bytes:
47
164
  """Serialize to msgpack bytes."""
165
+ if not MSGPACK_AVAILABLE:
166
+ raise NotImplementedError(
167
+ "MsgPack support requires msgpack: pip install msgpack"
168
+ )
48
169
  try:
49
- msgpack_bytes = msgpack.packb(self.to_dict())
50
- if path:
51
- path.write_bytes(msgpack_bytes)
52
- return msgpack_bytes
53
- except Exception:
54
- raise
170
+ # Use default hook for complex types if needed, or rely on to_dict
171
+ return msgpack.packb(self.to_dict(), use_bin_type=True)
172
+ except Exception as e:
173
+ raise RuntimeError(
174
+ f"Failed to serialize {self.__class__.__name__} to MsgPack: {e}"
175
+ ) from e
55
176
 
56
177
  @classmethod
57
178
  def from_msgpack(cls: type[T], msgpack_bytes: bytes) -> T:
58
179
  """Create instance from msgpack bytes."""
180
+ if not MSGPACK_AVAILABLE:
181
+ raise NotImplementedError(
182
+ "MsgPack support requires msgpack: pip install msgpack"
183
+ )
59
184
  try:
60
- return cls.from_dict(msgpack.unpackb(msgpack_bytes))
61
- except Exception:
62
- raise
185
+ # Use object_hook if custom deserialization is needed beyond from_dict
186
+ data = msgpack.unpackb(msgpack_bytes, raw=False)
187
+ if not isinstance(data, dict):
188
+ raise TypeError(
189
+ f"MsgPack did not yield a dictionary for {cls.__name__}"
190
+ )
191
+ return cls.from_dict(data)
192
+ except Exception as e:
193
+ raise RuntimeError(
194
+ f"Failed to deserialize {cls.__name__} from MsgPack: {e}"
195
+ ) from e
196
+
197
+ def to_msgpack_file(self, path: Path | str) -> None:
198
+ """Serialize to msgpack file."""
199
+ if not MSGPACK_AVAILABLE:
200
+ raise NotImplementedError(
201
+ "MsgPack support requires msgpack: pip install msgpack"
202
+ )
203
+ path = Path(path)
204
+ try:
205
+ path.parent.mkdir(parents=True, exist_ok=True)
206
+ msgpack_bytes = self.to_msgpack()
207
+ path.write_bytes(msgpack_bytes)
208
+ except Exception as e:
209
+ raise RuntimeError(
210
+ f"Failed to write {self.__class__.__name__} to MsgPack file {path}: {e}"
211
+ ) from e
63
212
 
64
213
  @classmethod
65
- def from_msgpack_file(cls: type[T], path: Path) -> T:
214
+ def from_msgpack_file(cls: type[T], path: Path | str) -> T:
66
215
  """Create instance from msgpack file."""
216
+ if not MSGPACK_AVAILABLE:
217
+ raise NotImplementedError(
218
+ "MsgPack support requires msgpack: pip install msgpack"
219
+ )
220
+ path = Path(path)
67
221
  try:
68
- return cls.from_msgpack(path.read_bytes())
69
- except Exception:
222
+ msgpack_bytes = path.read_bytes()
223
+ return cls.from_msgpack(msgpack_bytes)
224
+ except FileNotFoundError:
70
225
  raise
226
+ except Exception as e:
227
+ raise RuntimeError(
228
+ f"Failed to read {cls.__name__} from MsgPack file {path}: {e}"
229
+ ) from e
71
230
 
231
+ # --- Pickle Methods (Use with caution due to security risks) ---
72
232
  def to_pickle(self) -> bytes:
73
- """Serialize to pickle bytes."""
233
+ """Serialize to pickle bytes using cloudpickle."""
234
+ if not PICKLE_AVAILABLE:
235
+ raise NotImplementedError(
236
+ "Pickle support requires cloudpickle: pip install cloudpickle"
237
+ )
74
238
  try:
75
239
  return cloudpickle.dumps(self)
76
- except Exception:
77
- raise
240
+ except Exception as e:
241
+ raise RuntimeError(
242
+ f"Failed to serialize {self.__class__.__name__} to Pickle: {e}"
243
+ ) from e
78
244
 
79
245
  @classmethod
80
- def from_pickle(cls, pickle_bytes: bytes) -> T:
81
- """Create instance from pickle bytes."""
246
+ def from_pickle(cls: type[T], pickle_bytes: bytes) -> T:
247
+ """Create instance from pickle bytes using cloudpickle."""
248
+ if not PICKLE_AVAILABLE:
249
+ raise NotImplementedError(
250
+ "Pickle support requires cloudpickle: pip install cloudpickle"
251
+ )
82
252
  try:
83
- return cloudpickle.loads(pickle_bytes)
84
- except Exception:
85
- raise
253
+ instance = cloudpickle.loads(pickle_bytes)
254
+ if not isinstance(instance, cls):
255
+ raise TypeError(
256
+ f"Deserialized object is not of type {cls.__name__}"
257
+ )
258
+ return instance
259
+ except Exception as e:
260
+ raise RuntimeError(
261
+ f"Failed to deserialize {cls.__name__} from Pickle: {e}"
262
+ ) from e
263
+
264
+ def to_pickle_file(self, path: Path | str) -> None:
265
+ """Serialize to pickle file using cloudpickle."""
266
+ if not PICKLE_AVAILABLE:
267
+ raise NotImplementedError(
268
+ "Pickle support requires cloudpickle: pip install cloudpickle"
269
+ )
270
+ path = Path(path)
271
+ try:
272
+ path.parent.mkdir(parents=True, exist_ok=True)
273
+ pickle_bytes = self.to_pickle()
274
+ path.write_bytes(pickle_bytes)
275
+ except Exception as e:
276
+ raise RuntimeError(
277
+ f"Failed to write {self.__class__.__name__} to Pickle file {path}: {e}"
278
+ ) from e
86
279
 
87
280
  @classmethod
88
- def from_pickle_file(cls: type[T], path: Path) -> T:
89
- """Create instance from pickle file."""
281
+ def from_pickle_file(cls: type[T], path: Path | str) -> T:
282
+ """Create instance from pickle file using cloudpickle."""
283
+ if not PICKLE_AVAILABLE:
284
+ raise NotImplementedError(
285
+ "Pickle support requires cloudpickle: pip install cloudpickle"
286
+ )
287
+ path = Path(path)
90
288
  try:
91
- return cls.from_pickle(path.read_bytes())
92
- except Exception:
289
+ pickle_bytes = path.read_bytes()
290
+ return cls.from_pickle(pickle_bytes)
291
+ except FileNotFoundError:
93
292
  raise
293
+ except Exception as e:
294
+ raise RuntimeError(
295
+ f"Failed to read {cls.__name__} from Pickle file {path}: {e}"
296
+ ) from e
297
+
298
+ # _filter_none_values remains unchanged
299
+ @staticmethod
300
+ def _filter_none_values(data: Any) -> Any:
301
+ """Filter out None values from dictionaries and lists recursively."""
302
+ if isinstance(data, dict):
303
+ return {
304
+ k: Serializable._filter_none_values(v)
305
+ for k, v in data.items()
306
+ if v is not None
307
+ }
308
+ elif isinstance(data, list):
309
+ # Filter None from list items AND recursively filter within items
310
+ return [
311
+ Serializable._filter_none_values(item)
312
+ for item in data
313
+ if item is not None
314
+ ]
315
+ return data
@@ -0,0 +1,184 @@
1
+ # src/flock/core/serialization/serialization_utils.py
2
+ """Utilities for recursive serialization/deserialization with callable handling."""
3
+
4
+ import importlib
5
+ from collections.abc import Mapping, Sequence
6
+ from typing import Any
7
+
8
+ from pydantic import BaseModel
9
+
10
+ # Import the registry
11
+ # from .callable_registry import CallableRegistry # Old way
12
+ from flock.core.flock_registry import (
13
+ COMPONENT_BASE_TYPES,
14
+ get_registry, # New way
15
+ )
16
+ from flock.core.logging.logging import get_logger
17
+
18
+ logger = get_logger("serialization.utils")
19
+ FlockRegistry = get_registry() # Get singleton instance
20
+
21
+ # --- Serialization Helper ---
22
+
23
+
24
+ def serialize_item(item: Any) -> Any:
25
+ """Recursively prepares an item for serialization (e.g., to dict for YAML/JSON).
26
+ Converts known callables to their path strings using FlockRegistry.
27
+ Converts Pydantic models using model_dump.
28
+ """
29
+ if isinstance(item, BaseModel):
30
+ dumped = item.model_dump(mode="json", exclude_none=True)
31
+ return serialize_item(dumped)
32
+ elif callable(item) and not isinstance(item, type):
33
+ path_str = FlockRegistry.get_callable_path_string(
34
+ item
35
+ ) # Use registry helper
36
+ if path_str:
37
+ return {"__callable_ref__": path_str}
38
+ else:
39
+ logger.warning(
40
+ f"Could not get path string for callable {item}, storing as string."
41
+ )
42
+ return str(item)
43
+ elif isinstance(item, Mapping):
44
+ return {key: serialize_item(value) for key, value in item.items()}
45
+ elif isinstance(item, Sequence) and not isinstance(item, str):
46
+ return [serialize_item(sub_item) for sub_item in item]
47
+ elif isinstance(
48
+ item, type
49
+ ): # Handle type objects themselves (e.g. if stored directly)
50
+ type_name = FlockRegistry.get_component_type_name(
51
+ item
52
+ ) # Check components first
53
+ if type_name:
54
+ return {"__component_ref__": type_name}
55
+ type_name = FlockRegistry._get_path_string(
56
+ item
57
+ ) # Check regular types/classes by path
58
+ if type_name:
59
+ return {"__type_ref__": type_name}
60
+ logger.warning(
61
+ f"Could not serialize type object {item}, storing as string."
62
+ )
63
+ return str(item)
64
+ else:
65
+ # Return basic types as is
66
+ return item
67
+
68
+
69
+ # --- Deserialization Helper ---
70
+
71
+
72
+ def deserialize_item(item: Any) -> Any:
73
+ """Recursively processes a deserialized item (e.g., from YAML/JSON dict).
74
+ Converts reference dicts back to actual callables or types using FlockRegistry.
75
+ Handles nested lists and dicts.
76
+ """
77
+ if isinstance(item, Mapping):
78
+ if "__callable_ref__" in item and len(item) == 1:
79
+ path_str = item["__callable_ref__"]
80
+ try:
81
+ return FlockRegistry.get_callable(path_str)
82
+ except KeyError:
83
+ logger.error(
84
+ f"Callable reference '{path_str}' not found during deserialization."
85
+ )
86
+ return None
87
+ elif "__component_ref__" in item and len(item) == 1:
88
+ type_name = item["__component_ref__"]
89
+ try:
90
+ return FlockRegistry.get_component(type_name)
91
+ except KeyError:
92
+ logger.error(
93
+ f"Component reference '{type_name}' not found during deserialization."
94
+ )
95
+ return None
96
+ elif "__type_ref__" in item and len(item) == 1:
97
+ type_name = item["__type_ref__"]
98
+ try:
99
+ # For general types, use get_type or fallback to dynamic import like get_callable
100
+ # Using get_type for now, assuming it needs registration
101
+ return FlockRegistry.get_type(type_name)
102
+ except KeyError:
103
+ # Attempt dynamic import as fallback if get_type fails (similar to get_callable)
104
+ try:
105
+ if "." not in type_name: # Builtins?
106
+ mod = importlib.import_module("builtins")
107
+ else:
108
+ module_name, class_name = type_name.rsplit(".", 1)
109
+ mod = importlib.import_module(module_name)
110
+ type_obj = getattr(mod, class_name)
111
+ if isinstance(type_obj, type):
112
+ FlockRegistry.register_type(
113
+ type_obj, type_name
114
+ ) # Cache it
115
+ return type_obj
116
+ else:
117
+ raise TypeError()
118
+ except Exception:
119
+ logger.error(
120
+ f"Type reference '{type_name}' not found in registry or via dynamic import."
121
+ )
122
+ return None
123
+
124
+ else:
125
+ # Recursively deserialize dictionary values
126
+ return {key: deserialize_item(value) for key, value in item.items()}
127
+ elif isinstance(item, Sequence) and not isinstance(item, str):
128
+ return [deserialize_item(sub_item) for sub_item in item]
129
+ else:
130
+ # Return basic types as is
131
+ return item
132
+
133
+
134
+ # --- Component Deserialization Helper ---
135
+ def deserialize_component(
136
+ data: dict | None, expected_base_type: type
137
+ ) -> Any | None:
138
+ """Deserializes a component (Module, Evaluator, Router) from its dict representation.
139
+ Uses the 'type' field to find the correct class via FlockRegistry.
140
+ """
141
+ if data is None:
142
+ return None
143
+ if not isinstance(data, dict):
144
+ logger.error(
145
+ f"Expected dict for component deserialization, got {type(data)}"
146
+ )
147
+ return None
148
+
149
+ type_name = data.get(
150
+ "type"
151
+ ) # Assuming 'type' key holds the class name string
152
+ if not type_name:
153
+ logger.error(f"Component data missing 'type' field: {data}")
154
+ return None
155
+
156
+ try:
157
+ ComponentClass = FlockRegistry.get_component(type_name) # Use registry
158
+ # Optional: Keep the base type check
159
+ if COMPONENT_BASE_TYPES and not issubclass(
160
+ ComponentClass, expected_base_type
161
+ ):
162
+ raise TypeError(
163
+ f"Deserialized class {type_name} is not a subclass of {expected_base_type.__name__}"
164
+ )
165
+
166
+ # Recursively deserialize the data *before* passing to Pydantic constructor
167
+ # This handles nested callables/types within the component's config/data
168
+ deserialized_data_for_init = {}
169
+ for k, v in data.items():
170
+ # Don't pass the 'type' field itself to the constructor if it matches class name
171
+ if k == "type" and v == ComponentClass.__name__:
172
+ continue
173
+ deserialized_data_for_init[k] = deserialize_item(v)
174
+
175
+ # Use Pydantic constructor directly. Assumes keys match field names.
176
+ # from_dict could be added to components for more complex logic if needed.
177
+ return ComponentClass(**deserialized_data_for_init)
178
+
179
+ except (KeyError, TypeError, Exception) as e:
180
+ logger.error(
181
+ f"Failed to deserialize component of type '{type_name}': {e}",
182
+ exc_info=True,
183
+ )
184
+ return None
@@ -8,9 +8,9 @@ from temporalio import activity
8
8
  from flock.core.context.context import FlockContext
9
9
  from flock.core.context.context_vars import FLOCK_CURRENT_AGENT, FLOCK_MODEL
10
10
  from flock.core.flock_agent import FlockAgent
11
+ from flock.core.flock_registry import get_registry
11
12
  from flock.core.flock_router import HandOffRequest
12
13
  from flock.core.logging.logging import get_logger
13
- from flock.core.registry.agent_registry import Registry
14
14
  from flock.core.util.input_resolver import resolve_inputs
15
15
 
16
16
  logger = get_logger("activities")
@@ -26,7 +26,7 @@ async def run_agent(context: FlockContext) -> dict:
26
26
  """
27
27
  # Start a top-level span for the entire run_agent activity.
28
28
  with tracer.start_as_current_span("run_agent") as span:
29
- registry = Registry()
29
+ registry = get_registry()
30
30
  previous_agent_name = ""
31
31
  if isinstance(context, dict):
32
32
  context = FlockContext.from_dict(context)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flock-core
3
- Version: 0.3.23
3
+ Version: 0.3.30
4
4
  Summary: Declarative LLM Orchestration at Scale
5
5
  Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
6
6
  License-File: LICENSE
@@ -12,10 +12,11 @@ Requires-Dist: azure-search-documents>=11.5.2
12
12
  Requires-Dist: chromadb>=0.6.3
13
13
  Requires-Dist: cloudpickle>=3.1.1
14
14
  Requires-Dist: devtools>=0.12.2
15
- Requires-Dist: dspy==2.5.42
15
+ Requires-Dist: dspy==2.6.16
16
16
  Requires-Dist: duckduckgo-search>=7.3.2
17
17
  Requires-Dist: fastapi>=0.115.8
18
18
  Requires-Dist: httpx>=0.28.1
19
+ Requires-Dist: litellm==1.63.7
19
20
  Requires-Dist: loguru>=0.7.3
20
21
  Requires-Dist: matplotlib>=3.10.0
21
22
  Requires-Dist: msgpack>=1.1.0
@@ -33,6 +34,8 @@ Requires-Dist: pydantic>=2.10.5
33
34
  Requires-Dist: python-box>=7.3.2
34
35
  Requires-Dist: python-decouple>=3.8
35
36
  Requires-Dist: python-dotenv>=1.0.1
37
+ Requires-Dist: python-fasthtml>=0.12.6
38
+ Requires-Dist: pyyaml>=6.0
36
39
  Requires-Dist: questionary>=2.1.0
37
40
  Requires-Dist: rich>=13.9.4
38
41
  Requires-Dist: sentence-transformers>=3.4.1
@@ -59,7 +62,7 @@ Description-Content-Type: text/markdown
59
62
 
60
63
  ## Overview
61
64
 
62
- Flock is a framework for orchestrating LLM-powered agents. It leverages a **declarative approach** where you simply specify what each agent needs as input and what it produces as outputwithout having to write lengthy, brittle prompts. Under the hood, Flock transforms these declarations into robust workflows, using cutting-edge components such as Temporal and DSPy to handle fault tolerance, state management, and error recovery.
65
+ Flock is a framework for orchestrating LLM-powered agents. It leverages a **declarative approach** where you simply specify what each agent needs as input and what it produces as output, without having to write lengthy, brittle prompts. Under the hood, Flock transforms these declarations into robust workflows, using cutting-edge components such as Temporal and DSPy to handle fault tolerance, state management, and error recovery.
63
66
 
64
67
 
65
68
 
@@ -9,14 +9,22 @@ flock/cli/load_flock.py,sha256=3JdECvt5X7uyOG2vZS3-Zk5C5SI_84_QZjcsB3oJmfA,932
9
9
  flock/cli/load_release_notes.py,sha256=qFcgUrMddAE_TP6x1P-6ZywTUjTknfhTDW5LTxtg1yk,599
10
10
  flock/cli/settings.py,sha256=Z_TXBzCYlCmSaKrJ_CQCdYy-Cj29gpI4kbC_2KzoKqg,27025
11
11
  flock/cli/assets/release_notes.md,sha256=bqnk50jxM3w5uY44Dc7MkdT8XmRREFxrVBAG9XCOSSU,4896
12
- flock/core/__init__.py,sha256=mPlvKc0SxC2qCvSlgYeP_7EyV8ptmdn24NO8mlQoCSo,559
13
- flock/core/flock.py,sha256=IURlcuNvdsnqKkvgXtX4v_pGWQ8Lfb60X--MT0zvxHo,19881
14
- flock/core/flock_agent.py,sha256=F1wl54ivLQijSHlv_Q_znw_ElzdDlqpi-KugVUyHTRE,12238
15
- flock/core/flock_api.py,sha256=2rHnmEdtT5KPZYwGesRT7LqwbrgKClODHT-O56u7pcQ,7140
12
+ flock/core/__init__.py,sha256=6NmSXsdQOoOPWjWqdF8BYiUveb54CjH8Ta0WAjNM0Ps,574
13
+ flock/core/flock.py,sha256=O2ro_CZMKi_8ssY7BYpT6wSENcvcimO9mqwIxqENMpg,22202
14
+ flock/core/flock_agent.py,sha256=jkDwB7yVGYyLfg-WuwvR2X4XblXOs5DrB2dB30xBL7Q,24754
16
15
  flock/core/flock_evaluator.py,sha256=dOXZeDOGZcAmJ9ahqq_2bdGUU1VOXY4skmwTVpAjiVw,1685
17
16
  flock/core/flock_factory.py,sha256=MGTkJCP1WGpV614f87r1vwe0tqAvBCoH9PlqtqDyJDk,2828
18
17
  flock/core/flock_module.py,sha256=96aFVYAgwpKN53xGbivQDUpikOYGFCxK5mqhclOcxY0,3003
18
+ flock/core/flock_registry.py,sha256=cqW74n6RebrQ7uqqLb6DxBNxebqJsu4WyMtL1BcS5oI,22551
19
19
  flock/core/flock_router.py,sha256=A5GaxcGvtiFlRLHBTW7okh5RDm3BdKam2uXvRHRaj7k,2187
20
+ flock/core/api/__init__.py,sha256=OKlhzDWZJfA6ddBwxQUmATY0TSzESsH032u00iVGvdA,228
21
+ flock/core/api/endpoints.py,sha256=m-QAyizCHGh3sd5IXaDEhquSxNgTZLpUVTXLdVjiDVw,9086
22
+ flock/core/api/main.py,sha256=-MJClTcmkyUnaP9fmVu2CcHagFy_9lKk6CAbF05kraY,8928
23
+ flock/core/api/models.py,sha256=mMPCMCD52Txc56_yscwZQG0RRPCJTnIrVKQ8WbI7gts,1111
24
+ flock/core/api/run_store.py,sha256=kmrb0bq2Et5JiSxFWskAAf5a4jTeEFVZShTDlX5jfAk,2773
25
+ flock/core/api/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ flock/core/api/ui/routes.py,sha256=nS-wWO94mshE5ozWfOQZ-HOvtes_1qxDVcqpMZtU5JQ,8885
27
+ flock/core/api/ui/utils.py,sha256=V7PqYHNK519hFJ8jvvwf7bGpbBXCRz_HQG3BDCCqlNA,4802
20
28
  flock/core/context/context.py,sha256=8bjRLZ74oacRNBaHmDNXdQKfB-95poF7Pp03n2k0zcQ,6437
21
29
  flock/core/context/context_manager.py,sha256=FANSWa6DEhdhtZ7t_9Gza0v80UdpoDOhHbfVOccmjkA,1181
22
30
  flock/core/context/context_vars.py,sha256=zYTMi9b6mNSSEHowEQUOTpEDurmAjaUcyBCgfKY6-cU,300
@@ -24,7 +32,7 @@ flock/core/execution/local_executor.py,sha256=rnIQvaJOs6zZORUcR3vvyS6LPREDJTjayg
24
32
  flock/core/execution/temporal_executor.py,sha256=OF_uXgQsoUGp6U1ZkcuaidAEKyH7XDtbfrtdF10XQ_4,1675
25
33
  flock/core/interpreter/python_interpreter.py,sha256=RaUMZuufsKBNQ4FAeSaOgUuxzs8VYu5TgUUs-xwaxxM,26376
26
34
  flock/core/logging/__init__.py,sha256=Q8hp9-1ilPIUIV0jLgJ3_cP7COrea32cVwL7dicPnlM,82
27
- flock/core/logging/logging.py,sha256=uWtUZnQI_sdtzLfXo61JPENSNNwplvEuGMPIhsYd-gQ,12448
35
+ flock/core/logging/logging.py,sha256=-ViLNLTm5wqbvVsc6xYekOsAY38ZCIn6j1wciC7lgeM,15417
28
36
  flock/core/logging/telemetry.py,sha256=3E9Tyj6AUR6A5RlIufcdCdWm5BAA7tbOsCa7lHoUQaU,5404
29
37
  flock/core/logging/trace_and_logged.py,sha256=5vNrK1kxuPMoPJ0-QjQg-EDJL1oiEzvU6UNi6X8FiMs,2117
30
38
  flock/core/logging/formatters/enum_builder.py,sha256=LgEYXUv84wK5vwHflZ5h8HBGgvLH3sByvUQe8tZiyY0,981
@@ -35,13 +43,14 @@ flock/core/logging/span_middleware/baggage_span_processor.py,sha256=gJfRl8FeB6jd
35
43
  flock/core/logging/telemetry_exporter/base_exporter.py,sha256=rQJJzS6q9n2aojoSqwCnl7ZtHrh5LZZ-gkxUuI5WfrQ,1124
36
44
  flock/core/logging/telemetry_exporter/file_exporter.py,sha256=nKAjJSZtA7FqHSTuTiFtYYepaxOq7l1rDvs8U8rSBlA,3023
37
45
  flock/core/logging/telemetry_exporter/sqlite_exporter.py,sha256=CDsiMb9QcqeXelZ6ZqPSS56ovMPGqOu6whzBZRK__Vg,3498
38
- flock/core/mixin/dspy_integration.py,sha256=P5G4Y04nl5hFwFbJXCkQ-0TMR1L4skLL2IM_FlUjH_c,8364
46
+ flock/core/mixin/dspy_integration.py,sha256=Os2jZ505t_7Mg5jllUc06uDpCNTnhGBeCbUW-yAHfXc,17366
39
47
  flock/core/mixin/prompt_parser.py,sha256=eOqI-FK3y17gVqpc_y5GF-WmK1Jv8mFlkZxTcgweoxI,5121
40
- flock/core/registry/agent_registry.py,sha256=TUClh9e3eA6YzZC1CMTlsTPvQeqb9jYHewi-zPpcWM8,4987
41
- flock/core/serialization/__init__.py,sha256=j0uw1g-7SOEhD5Ozgc8WpbZNpDWRmu58UOGg4_QTu8U,320
48
+ flock/core/serialization/__init__.py,sha256=CML7fPgG6p4c0CDBlJ_uwV1aZZhJKK9uy3IoIHfO87w,431
49
+ flock/core/serialization/callable_registry.py,sha256=sUZECTZWsM3fJ8FDRQ-FgLNW9hF26nY17AD6fJKADMc,1419
42
50
  flock/core/serialization/json_encoder.py,sha256=gAKj2zU_8wQiNvdkby2hksSA4fbPNwTjup_yz1Le1Vw,1229
43
51
  flock/core/serialization/secure_serializer.py,sha256=n5-zRvvXddgJv1FFHsaQ2wuYdL3WUSGPvG_LGaffEJo,6144
44
- flock/core/serialization/serializable.py,sha256=SymJ0YrjBx48mOBItYSqoRpKuzIc4vKWRS6ScTzre7s,2573
52
+ flock/core/serialization/serializable.py,sha256=ymuJmm8teLbyUFMakkD7W3a_N8H4igZ1ITQnOqoLt0o,11270
53
+ flock/core/serialization/serialization_utils.py,sha256=UgMYYccwgfGxyMJ7qYaQ9-RWWjiE9p9qMehoY_X1zi0,7146
45
54
  flock/core/tools/azure_tools.py,sha256=9Bi6IrB5pzBTBhBSxpCVMgx8HBud8nl4gDp8aN0NT6c,17031
46
55
  flock/core/tools/basic_tools.py,sha256=hEG14jNZ2itVvubCHTfsWkuJK6yuNwBtuFj2Js0VHZs,9043
47
56
  flock/core/tools/llm_tools.py,sha256=Bdt4Dpur5dGpxd2KFEQyxjfZazvW1HCDKY6ydMj6UgQ,21811
@@ -410,12 +419,12 @@ flock/themes/zenburned.toml,sha256=UEmquBbcAO3Zj652XKUwCsNoC2iQSlIh-q5c6DH-7Kc,1
410
419
  flock/themes/zenwritten-dark.toml,sha256=To5l6520_3UqAGiEumpzGWsHhXxqu9ThrMildXKgIO0,1669
411
420
  flock/themes/zenwritten-light.toml,sha256=G1iEheCPfBNsMTGaVpEVpDzYBHA_T-MV27rolUYolmE,1666
412
421
  flock/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
413
- flock/workflow/activities.py,sha256=yah-lHjMW6_Ww1gt7hMXBis1cJRlcbHx0uLsMB9oNZ0,9066
422
+ flock/workflow/activities.py,sha256=eVZDnxGJl_quNO-UTV3YgvTV8LrRaHN3QDAA1ANKzac,9065
414
423
  flock/workflow/agent_activities.py,sha256=NhBZscflEf2IMfSRa_pBM_TRP7uVEF_O0ROvWZ33eDc,963
415
424
  flock/workflow/temporal_setup.py,sha256=VWBgmBgfTBjwM5ruS_dVpA5AVxx6EZ7oFPGw4j3m0l0,1091
416
425
  flock/workflow/workflow.py,sha256=I9MryXW_bqYVTHx-nl2epbTqeRy27CAWHHA7ZZA0nAk,1696
417
- flock_core-0.3.23.dist-info/METADATA,sha256=qwn0OaG4E4j-5vjAPcqSv6jqpxtL8e5NcuhyHgKHkCY,20649
418
- flock_core-0.3.23.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
419
- flock_core-0.3.23.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
420
- flock_core-0.3.23.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
421
- flock_core-0.3.23.dist-info/RECORD,,
426
+ flock_core-0.3.30.dist-info/METADATA,sha256=tEQMna6bPKeaSix98h5NnqVnb8vN8IQLtiKE3DP_F2U,20745
427
+ flock_core-0.3.30.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
428
+ flock_core-0.3.30.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
429
+ flock_core-0.3.30.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
430
+ flock_core-0.3.30.dist-info/RECORD,,