flock-core 0.3.41__py3-none-any.whl → 0.4.0b2__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 +31 -0
- flock/cli/create_flock.py +58 -3
- flock/cli/load_flock.py +135 -1
- flock/cli/registry_management.py +367 -96
- flock/cli/yaml_editor.py +119 -6
- flock/core/__init__.py +13 -1
- flock/core/flock.py +918 -49
- flock/core/flock_agent.py +114 -22
- flock/core/flock_registry.py +37 -5
- flock/core/serialization/serializable.py +35 -8
- flock/core/serialization/serialization_utils.py +96 -1
- flock/core/util/cli_helper.py +2 -2
- flock/core/util/file_path_utils.py +223 -0
- {flock_core-0.3.41.dist-info → flock_core-0.4.0b2.dist-info}/METADATA +1 -1
- {flock_core-0.3.41.dist-info → flock_core-0.4.0b2.dist-info}/RECORD +18 -17
- {flock_core-0.3.41.dist-info → flock_core-0.4.0b2.dist-info}/WHEEL +0 -0
- {flock_core-0.3.41.dist-info → flock_core-0.4.0b2.dist-info}/entry_points.txt +0 -0
- {flock_core-0.3.41.dist-info → flock_core-0.4.0b2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"""Utility functions for handling file paths in Flock.
|
|
2
|
+
|
|
3
|
+
This module provides utilities for working with file paths,
|
|
4
|
+
especially for components that may be loaded from file system paths
|
|
5
|
+
rather than module imports.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import importlib.util
|
|
9
|
+
import inspect
|
|
10
|
+
import os
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_file_path(obj: Any) -> str | None:
|
|
17
|
+
"""Get the file path for a Python object.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
obj: The object to get the file path for
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
The file path if it can be determined, None otherwise
|
|
24
|
+
"""
|
|
25
|
+
try:
|
|
26
|
+
if inspect.ismodule(obj):
|
|
27
|
+
return obj.__file__
|
|
28
|
+
elif inspect.isclass(obj) or inspect.isfunction(obj):
|
|
29
|
+
return inspect.getfile(obj)
|
|
30
|
+
return None
|
|
31
|
+
except (TypeError, ValueError):
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def normalize_path(path: str) -> str:
|
|
36
|
+
"""Normalize a path for consistent representation.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
path: The path to normalize
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
The normalized path
|
|
43
|
+
"""
|
|
44
|
+
return os.path.normpath(path)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def is_same_path(path1: str, path2: str) -> bool:
|
|
48
|
+
"""Check if two paths point to the same file.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
path1: The first path
|
|
52
|
+
path2: The second path
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
True if the paths point to the same file, False otherwise
|
|
56
|
+
"""
|
|
57
|
+
return os.path.normpath(os.path.abspath(path1)) == os.path.normpath(
|
|
58
|
+
os.path.abspath(path2)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_relative_path(path: str, base_path: str | None = None) -> str:
|
|
63
|
+
"""Get a path relative to a base path.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
path: The path to make relative
|
|
67
|
+
base_path: The base path (defaults to current working directory)
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
The relative path
|
|
71
|
+
"""
|
|
72
|
+
if base_path is None:
|
|
73
|
+
base_path = os.getcwd()
|
|
74
|
+
|
|
75
|
+
return os.path.relpath(path, base_path)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def load_class_from_file(file_path: str, class_name: str) -> type | None:
|
|
79
|
+
"""Load a class from a file.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
file_path: The path to the file
|
|
83
|
+
class_name: The name of the class to load
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
The loaded class, or None if it could not be loaded
|
|
87
|
+
"""
|
|
88
|
+
try:
|
|
89
|
+
# Generate a unique module name to avoid conflicts
|
|
90
|
+
module_name = f"flock_dynamic_import_{hash(file_path)}"
|
|
91
|
+
|
|
92
|
+
# Create a spec for the module
|
|
93
|
+
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
|
94
|
+
if not spec or not spec.loader:
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
# Create and load the module
|
|
98
|
+
module = importlib.util.module_from_spec(spec)
|
|
99
|
+
sys.modules[module_name] = module
|
|
100
|
+
spec.loader.exec_module(module)
|
|
101
|
+
|
|
102
|
+
# Get the class from the module
|
|
103
|
+
if not hasattr(module, class_name):
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
return getattr(module, class_name)
|
|
107
|
+
except Exception:
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def get_project_root() -> Path:
|
|
112
|
+
"""Get the project root directory.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
The project root path
|
|
116
|
+
"""
|
|
117
|
+
# Try to find the directory containing pyproject.toml or setup.py
|
|
118
|
+
current_dir = Path(os.getcwd())
|
|
119
|
+
|
|
120
|
+
# Walk up the directory tree looking for project markers
|
|
121
|
+
for path in [current_dir, *current_dir.parents]:
|
|
122
|
+
if (path / "pyproject.toml").exists() or (path / "setup.py").exists():
|
|
123
|
+
return path
|
|
124
|
+
|
|
125
|
+
# Default to current directory if no project markers found
|
|
126
|
+
return current_dir
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def component_path_to_file_path(component_path: str) -> str | None:
|
|
130
|
+
"""Convert a component path (module.ClassName) to a file path.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
component_path: The component path in the form module.ClassName
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
The file path if it can be determined, None otherwise
|
|
137
|
+
"""
|
|
138
|
+
try:
|
|
139
|
+
# Split into module path and class name
|
|
140
|
+
if "." not in component_path:
|
|
141
|
+
return None
|
|
142
|
+
|
|
143
|
+
module_path, class_name = component_path.rsplit(".", 1)
|
|
144
|
+
|
|
145
|
+
# Import the module
|
|
146
|
+
module = importlib.import_module(module_path)
|
|
147
|
+
|
|
148
|
+
# Get the file path
|
|
149
|
+
if hasattr(module, "__file__"):
|
|
150
|
+
return module.__file__
|
|
151
|
+
|
|
152
|
+
return None
|
|
153
|
+
except (ImportError, AttributeError):
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def file_path_to_component_path(file_path: str, class_name: str) -> str | None:
|
|
158
|
+
"""Convert a file path and class name to a component path (module.ClassName).
|
|
159
|
+
|
|
160
|
+
This is approximate and may not work in all cases, especially for non-standard
|
|
161
|
+
module structures.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
file_path: The file path to the module
|
|
165
|
+
class_name: The name of the class
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
The component path if it can be determined, None otherwise
|
|
169
|
+
"""
|
|
170
|
+
try:
|
|
171
|
+
# Convert the file path to an absolute path
|
|
172
|
+
abs_path = os.path.abspath(file_path)
|
|
173
|
+
|
|
174
|
+
# Get the project root
|
|
175
|
+
root = get_project_root()
|
|
176
|
+
|
|
177
|
+
# Get the relative path from the project root
|
|
178
|
+
rel_path = os.path.relpath(abs_path, root)
|
|
179
|
+
|
|
180
|
+
# Convert to a module path
|
|
181
|
+
module_path = os.path.splitext(rel_path)[0].replace(os.sep, ".")
|
|
182
|
+
|
|
183
|
+
# Remove 'src.' prefix if present (common in Python projects)
|
|
184
|
+
if module_path.startswith("src."):
|
|
185
|
+
module_path = module_path[4:]
|
|
186
|
+
|
|
187
|
+
# Combine with the class name
|
|
188
|
+
return f"{module_path}.{class_name}"
|
|
189
|
+
except Exception:
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def register_file_paths_in_registry(
|
|
194
|
+
component_paths: dict[str, str], registry: Any | None = None
|
|
195
|
+
) -> bool:
|
|
196
|
+
"""Register file paths in the registry.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
component_paths: Dictionary mapping component paths to file paths
|
|
200
|
+
registry: The registry to register in (defaults to the global registry)
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
True if all paths were registered, False otherwise
|
|
204
|
+
"""
|
|
205
|
+
try:
|
|
206
|
+
# Get the global registry if none provided
|
|
207
|
+
if registry is None:
|
|
208
|
+
from flock.core.flock_registry import get_registry
|
|
209
|
+
|
|
210
|
+
registry = get_registry()
|
|
211
|
+
|
|
212
|
+
# Initialize component_file_paths if needed
|
|
213
|
+
if not hasattr(registry, "_component_file_paths"):
|
|
214
|
+
registry._component_file_paths = {}
|
|
215
|
+
|
|
216
|
+
# Register each path
|
|
217
|
+
for component_name, file_path in component_paths.items():
|
|
218
|
+
if component_name in registry._components:
|
|
219
|
+
registry._component_file_paths[component_name] = file_path
|
|
220
|
+
|
|
221
|
+
return True
|
|
222
|
+
except Exception:
|
|
223
|
+
return False
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
flock/__init__.py,sha256=
|
|
1
|
+
flock/__init__.py,sha256=LhuAmkwwNuNbEvo2N4r1myDgGqQwDRe_HYU3sTZQgDc,4139
|
|
2
2
|
flock/config.py,sha256=O5QJGlStf4DWSK4ovZsKw01ud4YK3_ij6Ay8sWU8ih0,1522
|
|
3
3
|
flock/cli/constants.py,sha256=EgGwFYl6TD7GVm9gASPJTjSl-aYROiFGltwFYp7u1AQ,668
|
|
4
4
|
flock/cli/create_agent.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
|
|
5
|
-
flock/cli/create_flock.py,sha256=
|
|
5
|
+
flock/cli/create_flock.py,sha256=XjTZEMQcEuAhniDJFrZoV103c-iTS1j-8AnagWZYxGE,8229
|
|
6
6
|
flock/cli/execute_flock.py,sha256=rAP-5nFfyOivi5uWG8mloZwXF9Tj9iD8MYSbllPllQ4,5726
|
|
7
7
|
flock/cli/load_agent.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
|
|
8
8
|
flock/cli/load_examples.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
|
|
9
|
-
flock/cli/load_flock.py,sha256=
|
|
9
|
+
flock/cli/load_flock.py,sha256=sfZ9B9aiyC5TCEbn1xR5Yd5SoaVji6MBNYzXlWOpoZ4,7111
|
|
10
10
|
flock/cli/load_release_notes.py,sha256=qFcgUrMddAE_TP6x1P-6ZywTUjTknfhTDW5LTxtg1yk,599
|
|
11
11
|
flock/cli/loaded_flock_cli.py,sha256=LpPBBSMOw0780EQ4KHz7QMpwz29KZZW7AuTerHvramw,6351
|
|
12
12
|
flock/cli/manage_agents.py,sha256=wkNF0IqNFfePrFueR57SILPW885IPqs3U8Cp-fcPPmo,12710
|
|
13
|
-
flock/cli/registry_management.py,sha256=
|
|
13
|
+
flock/cli/registry_management.py,sha256=mAHy3wT97YgODR0gVOkTXDqR5NIPzM-E-z9dEtw9-tw,29790
|
|
14
14
|
flock/cli/settings.py,sha256=Z_TXBzCYlCmSaKrJ_CQCdYy-Cj29gpI4kbC_2KzoKqg,27025
|
|
15
15
|
flock/cli/view_results.py,sha256=dOzK0O1FHSIDERnx48y-2Xke9BkOHS7pcOhs64AyIg0,781
|
|
16
|
-
flock/cli/yaml_editor.py,sha256=
|
|
16
|
+
flock/cli/yaml_editor.py,sha256=K3N0bh61G1TSDAZDnurqW9e_-hO6CtSQKXQqlDhCjVo,12527
|
|
17
17
|
flock/cli/assets/release_notes.md,sha256=bqnk50jxM3w5uY44Dc7MkdT8XmRREFxrVBAG9XCOSSU,4896
|
|
18
|
-
flock/core/__init__.py,sha256=
|
|
19
|
-
flock/core/flock.py,sha256=
|
|
20
|
-
flock/core/flock_agent.py,sha256=
|
|
18
|
+
flock/core/__init__.py,sha256=R64A7zi51Uz6jzzCFWGol9SZQnMFz3ynEse5ivhSkEA,805
|
|
19
|
+
flock/core/flock.py,sha256=jKhI1UyrgPpel-r8Qjwp82Zwz2AghHMudKQYgy-8kYA,62329
|
|
20
|
+
flock/core/flock_agent.py,sha256=L5sZ6weY4pNFbk8CEUrRD1506ojq_tx1jjQy02qEdC8,29126
|
|
21
21
|
flock/core/flock_evaluator.py,sha256=dOXZeDOGZcAmJ9ahqq_2bdGUU1VOXY4skmwTVpAjiVw,1685
|
|
22
22
|
flock/core/flock_factory.py,sha256=MGTkJCP1WGpV614f87r1vwe0tqAvBCoH9PlqtqDyJDk,2828
|
|
23
23
|
flock/core/flock_module.py,sha256=96aFVYAgwpKN53xGbivQDUpikOYGFCxK5mqhclOcxY0,3003
|
|
24
|
-
flock/core/flock_registry.py,sha256=
|
|
24
|
+
flock/core/flock_registry.py,sha256=ax2pIxv6hVqRw3eJCPQ9jAul_ocYWfl9BZttmu054d0,20830
|
|
25
25
|
flock/core/flock_router.py,sha256=A5GaxcGvtiFlRLHBTW7okh5RDm3BdKam2uXvRHRaj7k,2187
|
|
26
26
|
flock/core/api/__init__.py,sha256=OKlhzDWZJfA6ddBwxQUmATY0TSzESsH032u00iVGvdA,228
|
|
27
27
|
flock/core/api/endpoints.py,sha256=m-QAyizCHGh3sd5IXaDEhquSxNgTZLpUVTXLdVjiDVw,9086
|
|
@@ -55,14 +55,15 @@ flock/core/serialization/__init__.py,sha256=CML7fPgG6p4c0CDBlJ_uwV1aZZhJKK9uy3Io
|
|
|
55
55
|
flock/core/serialization/callable_registry.py,sha256=sUZECTZWsM3fJ8FDRQ-FgLNW9hF26nY17AD6fJKADMc,1419
|
|
56
56
|
flock/core/serialization/json_encoder.py,sha256=gAKj2zU_8wQiNvdkby2hksSA4fbPNwTjup_yz1Le1Vw,1229
|
|
57
57
|
flock/core/serialization/secure_serializer.py,sha256=n5-zRvvXddgJv1FFHsaQ2wuYdL3WUSGPvG_LGaffEJo,6144
|
|
58
|
-
flock/core/serialization/serializable.py,sha256=
|
|
59
|
-
flock/core/serialization/serialization_utils.py,sha256=
|
|
58
|
+
flock/core/serialization/serializable.py,sha256=qlv8TsTqRuklXiNuCMrvro5VKz764xC2i3FlgLJSkdk,12129
|
|
59
|
+
flock/core/serialization/serialization_utils.py,sha256=ONv7KUhc66e4sKYu9uFc3qU1jOg4DvIXRJ5QXaTIQj0,10298
|
|
60
60
|
flock/core/tools/azure_tools.py,sha256=9Bi6IrB5pzBTBhBSxpCVMgx8HBud8nl4gDp8aN0NT6c,17031
|
|
61
61
|
flock/core/tools/basic_tools.py,sha256=hEG14jNZ2itVvubCHTfsWkuJK6yuNwBtuFj2Js0VHZs,9043
|
|
62
62
|
flock/core/tools/llm_tools.py,sha256=Bdt4Dpur5dGpxd2KFEQyxjfZazvW1HCDKY6ydMj6UgQ,21811
|
|
63
63
|
flock/core/tools/markdown_tools.py,sha256=W6fGM48yGHbifVlaOk1jOtVcybfRbRmf20VbDOZv8S4,6031
|
|
64
64
|
flock/core/tools/dev_tools/github.py,sha256=a2OTPXS7kWOVA4zrZHynQDcsmEi4Pac5MfSjQOLePzA,5308
|
|
65
|
-
flock/core/util/cli_helper.py,sha256=
|
|
65
|
+
flock/core/util/cli_helper.py,sha256=mbxFhAGDES1AySbz5D672Az-EWk88FIvtFIGJMEp6fc,49800
|
|
66
|
+
flock/core/util/file_path_utils.py,sha256=Odf7uU32C-x1KNighbNERSiMtkzW4h8laABIoFK7A5M,6246
|
|
66
67
|
flock/core/util/hydrator.py,sha256=6qNwOwCZB7r6y25BZ--0PGofrAlfMaXbDKFQeP5NLts,11196
|
|
67
68
|
flock/core/util/input_resolver.py,sha256=g9vDPdY4OH-G7qjas5ksGEHueokHGFPMoLOvC-ngeLo,5984
|
|
68
69
|
flock/evaluators/declarative/declarative_evaluator.py,sha256=WZ74LG81JcuApG2KcTk8plh0fFqDhJjtl6ubW1K-fqc,1750
|
|
@@ -429,8 +430,8 @@ flock/workflow/activities.py,sha256=eVZDnxGJl_quNO-UTV3YgvTV8LrRaHN3QDAA1ANKzac,
|
|
|
429
430
|
flock/workflow/agent_activities.py,sha256=NhBZscflEf2IMfSRa_pBM_TRP7uVEF_O0ROvWZ33eDc,963
|
|
430
431
|
flock/workflow/temporal_setup.py,sha256=VWBgmBgfTBjwM5ruS_dVpA5AVxx6EZ7oFPGw4j3m0l0,1091
|
|
431
432
|
flock/workflow/workflow.py,sha256=I9MryXW_bqYVTHx-nl2epbTqeRy27CAWHHA7ZZA0nAk,1696
|
|
432
|
-
flock_core-0.
|
|
433
|
-
flock_core-0.
|
|
434
|
-
flock_core-0.
|
|
435
|
-
flock_core-0.
|
|
436
|
-
flock_core-0.
|
|
433
|
+
flock_core-0.4.0b2.dist-info/METADATA,sha256=qGomy57c5JrnrpayoVAJK7xq6eJ20uM97ydTKJdttwQ,20773
|
|
434
|
+
flock_core-0.4.0b2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
435
|
+
flock_core-0.4.0b2.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
|
|
436
|
+
flock_core-0.4.0b2.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
|
|
437
|
+
flock_core-0.4.0b2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|