flock-core 0.3.31__py3-none-any.whl → 0.3.33__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 CHANGED
@@ -2,7 +2,12 @@
2
2
 
3
3
  from rich.panel import Panel
4
4
 
5
- from flock.cli.constants import CLI_EXIT, CLI_NOTES, CLI_THEME_BUILDER
5
+ from flock.cli.constants import (
6
+ CLI_EXIT,
7
+ CLI_NOTES,
8
+ CLI_REGISTRY_MANAGEMENT,
9
+ CLI_THEME_BUILDER,
10
+ )
6
11
  from flock.cli.load_release_notes import load_release_notes
7
12
  from flock.cli.settings import settings_editor
8
13
  from flock.core.logging.formatters.theme_builder import theme_builder
@@ -46,6 +51,7 @@ def main():
46
51
  # CLI_LOAD_EXAMPLE,
47
52
  questionary.Separator(),
48
53
  CLI_THEME_BUILDER,
54
+ CLI_REGISTRY_MANAGEMENT,
49
55
  CLI_SETTINGS,
50
56
  questionary.Separator(),
51
57
  CLI_START_WEB_SERVER,
@@ -64,6 +70,11 @@ def main():
64
70
  create_flock()
65
71
  elif result == CLI_THEME_BUILDER:
66
72
  theme_builder()
73
+ elif result == CLI_REGISTRY_MANAGEMENT:
74
+ # Import registry management when needed
75
+ from flock.cli.registry_management import manage_registry
76
+
77
+ manage_registry()
67
78
  elif result == CLI_SETTINGS:
68
79
  settings_editor()
69
80
  elif result == CLI_START_WEB_SERVER:
flock/cli/constants.py CHANGED
@@ -9,6 +9,7 @@ CLI_LOAD_EXAMPLE = "Load a example"
9
9
  CLI_SETTINGS = "Settings"
10
10
  CLI_NOTES = "'Hummingbird' release notes"
11
11
  CLI_START_WEB_SERVER = "Start web server"
12
+ CLI_REGISTRY_MANAGEMENT = "Registry management"
12
13
  CLI_EXIT = "Exit"
13
14
  CLI_CHOICES = [
14
15
  CLI_CREATE_AGENT,
@@ -16,6 +17,8 @@ CLI_CHOICES = [
16
17
  CLI_LOAD_AGENT,
17
18
  CLI_LOAD_FLOCK,
18
19
  CLI_LOAD_EXAMPLE,
20
+ CLI_THEME_BUILDER,
21
+ CLI_REGISTRY_MANAGEMENT,
19
22
  CLI_SETTINGS,
20
23
  CLI_START_WEB_SERVER,
21
24
  CLI_EXIT,
@@ -0,0 +1,618 @@
1
+ """Registry Management Module for the Flock CLI."""
2
+
3
+ import importlib
4
+ import inspect
5
+ import os
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ import questionary
10
+ from rich.console import Console
11
+ from rich.panel import Panel
12
+ from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn
13
+ from rich.table import Table
14
+
15
+ from flock.core.flock_registry import (
16
+ get_registry,
17
+ )
18
+ from flock.core.logging.logging import get_logger
19
+
20
+ logger = get_logger("registry_cli")
21
+ console = Console()
22
+
23
+ # Constants for registry item types
24
+ REGISTRY_CATEGORIES = ["Agent", "Callable", "Type", "Component"]
25
+ REGISTRY_ACTIONS = [
26
+ "View Registry Contents",
27
+ "Add Item to Registry",
28
+ "Remove Item from Registry",
29
+ "Auto-Registration Scanner",
30
+ "Export Registry",
31
+ "Back to Main Menu",
32
+ ]
33
+
34
+
35
+ def manage_registry() -> None:
36
+ """Main function for managing the Flock Registry from the CLI."""
37
+ while True:
38
+ console.clear()
39
+ console.print(
40
+ Panel("[bold blue]Flock Registry Management[/]"), justify="center"
41
+ )
42
+ console.line()
43
+
44
+ # Show registry stats
45
+ display_registry_stats()
46
+
47
+ action = questionary.select(
48
+ "What would you like to do?",
49
+ choices=REGISTRY_ACTIONS,
50
+ ).ask()
51
+
52
+ if action == "View Registry Contents":
53
+ view_registry_contents()
54
+ elif action == "Add Item to Registry":
55
+ add_item_to_registry()
56
+ elif action == "Remove Item from Registry":
57
+ remove_item_from_registry()
58
+ elif action == "Auto-Registration Scanner":
59
+ auto_registration_scanner()
60
+ elif action == "Export Registry":
61
+ export_registry()
62
+ elif action == "Back to Main Menu":
63
+ break
64
+
65
+ input("\nPress Enter to continue...")
66
+
67
+
68
+ def display_registry_stats() -> None:
69
+ """Display statistics about the current registry contents."""
70
+ registry = get_registry()
71
+
72
+ table = Table(title="Registry Statistics")
73
+ table.add_column("Category", style="cyan")
74
+ table.add_column("Count", style="green")
75
+
76
+ table.add_row("Agents", str(len(registry._agents)))
77
+ table.add_row("Callables", str(len(registry._callables)))
78
+ table.add_row("Types", str(len(registry._types)))
79
+ table.add_row("Components", str(len(registry._components)))
80
+
81
+ console.print(table)
82
+
83
+
84
+ def view_registry_contents(
85
+ category: str | None = None, search_pattern: str | None = None
86
+ ) -> None:
87
+ """Display registry contents with filtering options."""
88
+ registry = get_registry()
89
+
90
+ if category is None:
91
+ category = questionary.select(
92
+ "Select a category to view:",
93
+ choices=REGISTRY_CATEGORIES + ["All Categories"],
94
+ ).ask()
95
+
96
+ if search_pattern is None:
97
+ search_pattern = questionary.text(
98
+ "Enter search pattern (leave empty to show all):"
99
+ ).ask()
100
+
101
+ console.clear()
102
+
103
+ if category == "All Categories" or category == "Agent":
104
+ display_registry_section("Agents", registry._agents, search_pattern)
105
+
106
+ if category == "All Categories" or category == "Callable":
107
+ display_registry_section(
108
+ "Callables", registry._callables, search_pattern
109
+ )
110
+
111
+ if category == "All Categories" or category == "Type":
112
+ display_registry_section("Types", registry._types, search_pattern)
113
+
114
+ if category == "All Categories" or category == "Component":
115
+ display_registry_section(
116
+ "Components", registry._components, search_pattern
117
+ )
118
+
119
+
120
+ def display_registry_section(
121
+ title: str, items: dict[str, Any], search_pattern: str
122
+ ) -> None:
123
+ """Display a section of registry items in a table."""
124
+ filtered_items = {
125
+ k: v
126
+ for k, v in items.items()
127
+ if not search_pattern or search_pattern.lower() in k.lower()
128
+ }
129
+
130
+ if not filtered_items:
131
+ console.print(
132
+ f"[yellow]No {title.lower()} found matching the search pattern.[/]"
133
+ )
134
+ return
135
+
136
+ table = Table(title=f"Registered {title}")
137
+ table.add_column("Name/Path", style="cyan")
138
+ table.add_column("Type", style="green")
139
+
140
+ for name, item in filtered_items.items():
141
+ item_type = type(item).__name__
142
+ table.add_row(name, item_type)
143
+
144
+ console.print(table)
145
+ console.print(f"Total: {len(filtered_items)} {title.lower()}")
146
+
147
+
148
+ def add_item_to_registry() -> None:
149
+ """Add an item to the registry manually."""
150
+ registry = get_registry()
151
+
152
+ item_type = questionary.select(
153
+ "What type of item do you want to add?",
154
+ choices=["agent", "callable", "type", "component"],
155
+ ).ask()
156
+
157
+ module_path = questionary.text(
158
+ "Enter the module path (e.g., 'your_module.submodule'):"
159
+ ).ask()
160
+
161
+ item_name = questionary.text("Enter the item name within the module:").ask()
162
+
163
+ alias = questionary.text(
164
+ "Enter an alias (optional, press Enter to skip):"
165
+ ).ask()
166
+
167
+ if not alias:
168
+ alias = None
169
+
170
+ try:
171
+ # Attempt to import the module
172
+ module = importlib.import_module(module_path)
173
+
174
+ # Get the item from the module
175
+ if not hasattr(module, item_name):
176
+ console.print(
177
+ f"[red]Error: {item_name} not found in {module_path}[/]"
178
+ )
179
+ return False
180
+
181
+ item = getattr(module, item_name)
182
+
183
+ # Register the item based on its type
184
+ if item_type == "agent":
185
+ registry.register_agent(item)
186
+ console.print(
187
+ f"[green]Successfully registered agent: {item_name}[/]"
188
+ )
189
+ elif item_type == "callable":
190
+ result = registry.register_callable(item, alias)
191
+ console.print(
192
+ f"[green]Successfully registered callable: {result}[/]"
193
+ )
194
+ elif item_type == "type":
195
+ result = registry.register_type(item, alias)
196
+ console.print(f"[green]Successfully registered type: {result}[/]")
197
+ elif item_type == "component":
198
+ result = registry.register_component(item, alias)
199
+ console.print(
200
+ f"[green]Successfully registered component: {result}[/]"
201
+ )
202
+
203
+ return True
204
+
205
+ except ImportError:
206
+ console.print(f"[red]Error: Could not import module {module_path}[/]")
207
+ except Exception as e:
208
+ console.print(f"[red]Error: {e!s}[/]")
209
+
210
+ return False
211
+
212
+
213
+ def remove_item_from_registry() -> None:
214
+ """Remove an item from the registry."""
215
+ registry = get_registry()
216
+
217
+ item_type = questionary.select(
218
+ "What type of item do you want to remove?",
219
+ choices=["agent", "callable", "type", "component"],
220
+ ).ask()
221
+
222
+ # Get the appropriate dictionary based on item type
223
+ if item_type == "agent":
224
+ items = registry._agents
225
+ elif item_type == "callable":
226
+ items = registry._callables
227
+ elif item_type == "type":
228
+ items = registry._types
229
+ elif item_type == "component":
230
+ items = registry._components
231
+
232
+ if not items:
233
+ console.print(f"[yellow]No {item_type}s registered.[/]")
234
+ return False
235
+
236
+ # Create a list of items for selection
237
+ item_names = list(items.keys())
238
+ item_name = questionary.select(
239
+ f"Select the {item_type} to remove:",
240
+ choices=item_names + ["Cancel"],
241
+ ).ask()
242
+
243
+ if item_name == "Cancel":
244
+ return False
245
+
246
+ # Ask for confirmation
247
+ confirm = questionary.confirm(
248
+ f"Are you sure you want to remove {item_name}?",
249
+ default=False,
250
+ ).ask()
251
+
252
+ if not confirm:
253
+ console.print("[yellow]Operation cancelled.[/]")
254
+ return False
255
+
256
+ # Remove the item
257
+ try:
258
+ if item_type == "agent":
259
+ del registry._agents[item_name]
260
+ elif item_type == "callable":
261
+ del registry._callables[item_name]
262
+ elif item_type == "type":
263
+ del registry._types[item_name]
264
+ elif item_type == "component":
265
+ del registry._components[item_name]
266
+
267
+ console.print(
268
+ f"[green]Successfully removed {item_type}: {item_name}[/]"
269
+ )
270
+ return True
271
+
272
+ except Exception as e:
273
+ console.print(f"[red]Error: {e!s}[/]")
274
+ return False
275
+
276
+
277
+ def auto_registration_scanner() -> None:
278
+ """Scan directory for potential registry items and optionally register them."""
279
+ # Ask for the target path
280
+ target_path = questionary.text(
281
+ "Enter the path to scan (file or directory):",
282
+ default=os.getcwd(),
283
+ ).ask()
284
+
285
+ # Ask if we should recursively scan directories
286
+ recursive = True
287
+ if os.path.isdir(target_path):
288
+ recursive = questionary.confirm(
289
+ "Scan recursively through subdirectories?",
290
+ default=True,
291
+ ).ask()
292
+
293
+ # Ask if we should auto-register or just preview
294
+ auto_register = questionary.confirm(
295
+ "Auto-register discovered items? (No for preview only)",
296
+ default=False,
297
+ ).ask()
298
+
299
+ # Perform the scan
300
+ scan_results = scan_for_registry_items(
301
+ target_path, recursive, auto_register
302
+ )
303
+
304
+ # Display results
305
+ console.print(Panel("[bold green]Scan Results[/]"), justify="center")
306
+
307
+ for category, items in scan_results.items():
308
+ if items:
309
+ console.print(f"\n[cyan]{category}:[/] {len(items)} items")
310
+ for item in items:
311
+ console.print(f" - {item}")
312
+
313
+ if auto_register:
314
+ console.print("\n[green]Items have been registered to the registry.[/]")
315
+ else:
316
+ # Ask if we want to register the detected items
317
+ register_now = questionary.confirm(
318
+ "Register these items now?",
319
+ default=False,
320
+ ).ask()
321
+
322
+ if register_now:
323
+ # Re-scan with auto-register=True
324
+ scan_for_registry_items(target_path, recursive, True)
325
+ console.print(
326
+ "\n[green]Items have been registered to the registry.[/]"
327
+ )
328
+
329
+
330
+ def scan_for_registry_items(
331
+ target_path: str, recursive: bool = True, auto_register: bool = False
332
+ ) -> dict[str, list[str]]:
333
+ """Scan directory for potential registry items and optionally register them."""
334
+ results = {
335
+ "Agents": [],
336
+ "Callables": [],
337
+ "Types": [],
338
+ "Components": [],
339
+ "Potential Items": [],
340
+ }
341
+
342
+ registry = get_registry()
343
+ path = Path(target_path)
344
+
345
+ with Progress(
346
+ SpinnerColumn(),
347
+ TextColumn("[progress.description]{task.description}"),
348
+ BarColumn(),
349
+ TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
350
+ ) as progress:
351
+ scan_task = progress.add_task(f"Scanning {target_path}...", total=100)
352
+
353
+ # If path is a file, scan it directly
354
+ if path.is_file() and path.suffix == ".py":
355
+ module_path = get_module_path_from_file(path)
356
+ if module_path:
357
+ scan_python_file(path, module_path, results, auto_register)
358
+ progress.update(scan_task, completed=100)
359
+
360
+ # If path is a directory, scan all Python files
361
+ elif path.is_dir():
362
+ python_files = []
363
+ if recursive:
364
+ for root, _, files in os.walk(path):
365
+ python_files.extend(
366
+ [
367
+ Path(os.path.join(root, f))
368
+ for f in files
369
+ if f.endswith(".py")
370
+ ]
371
+ )
372
+ else:
373
+ python_files = [p for p in path.glob("*.py")]
374
+
375
+ total_files = len(python_files)
376
+ for i, file_path in enumerate(python_files):
377
+ module_path = get_module_path_from_file(file_path)
378
+ if module_path:
379
+ scan_python_file(
380
+ file_path, module_path, results, auto_register
381
+ )
382
+ progress.update(
383
+ scan_task, completed=(i + 1) / total_files * 100
384
+ )
385
+
386
+ return results
387
+
388
+
389
+ def get_module_path_from_file(file_path: Path) -> str | None:
390
+ """Convert a file path to a module path for import."""
391
+ try:
392
+ # Get absolute path
393
+ abs_path = file_path.resolve()
394
+
395
+ # Check if it's a Python file
396
+ if abs_path.suffix != ".py":
397
+ return None
398
+
399
+ # Get the directory containing the file
400
+ file_dir = abs_path.parent
401
+
402
+ # Find the nearest parent directory with __init__.py
403
+ # to determine the package root
404
+ package_root = None
405
+ current_dir = file_dir
406
+ while current_dir != current_dir.parent:
407
+ if (current_dir / "__init__.py").exists():
408
+ if package_root is None:
409
+ package_root = current_dir
410
+ else:
411
+ # We've reached a directory without __init__.py
412
+ # If we found a package root earlier, use that
413
+ if package_root is not None:
414
+ break
415
+ current_dir = current_dir.parent
416
+
417
+ # If no package root was found, this file can't be imported as a module
418
+ if package_root is None:
419
+ return None
420
+
421
+ # Calculate the module path
422
+ rel_path = abs_path.relative_to(package_root.parent)
423
+ module_path = str(rel_path.with_suffix("")).replace(os.sep, ".")
424
+
425
+ return module_path
426
+
427
+ except Exception as e:
428
+ logger.error(f"Error determining module path: {e}")
429
+ return None
430
+
431
+
432
+ def scan_python_file(
433
+ file_path: Path,
434
+ module_path: str,
435
+ results: dict[str, list[str]],
436
+ auto_register: bool,
437
+ ) -> None:
438
+ """Scan a Python file for registry-eligible items."""
439
+ try:
440
+ # Try to import the module
441
+ module = importlib.import_module(module_path)
442
+
443
+ # Scan for classes and functions
444
+ for name, obj in inspect.getmembers(module):
445
+ if name.startswith("_"):
446
+ continue
447
+
448
+ # Check for registry decorator presence
449
+ is_registry_item = False
450
+
451
+ # Check for classes
452
+ if inspect.isclass(obj):
453
+ # Check if it has a FlockAgent as a base class
454
+ if is_flock_agent(obj):
455
+ if auto_register:
456
+ get_registry().register_agent(obj)
457
+ results["Agents"].append(f"{module_path}.{name}")
458
+ is_registry_item = True
459
+
460
+ # Check for components
461
+ elif has_component_base(obj):
462
+ if auto_register:
463
+ get_registry().register_component(obj)
464
+ results["Components"].append(f"{module_path}.{name}")
465
+ is_registry_item = True
466
+
467
+ # Check for Pydantic models or dataclasses
468
+ elif is_potential_type(obj):
469
+ if auto_register:
470
+ get_registry().register_type(obj)
471
+ results["Types"].append(f"{module_path}.{name}")
472
+ is_registry_item = True
473
+
474
+ # If not already identified but seems like a potential candidate
475
+ elif not is_registry_item and is_potential_registry_candidate(
476
+ obj
477
+ ):
478
+ results["Potential Items"].append(
479
+ f"{module_path}.{name} (class)"
480
+ )
481
+
482
+ # Check for functions (potential callables/tools)
483
+ elif inspect.isfunction(obj) and obj.__module__ == module.__name__:
484
+ if auto_register:
485
+ get_registry().register_callable(obj)
486
+ results["Callables"].append(f"{module_path}.{name}")
487
+ is_registry_item = True
488
+
489
+ except (ImportError, AttributeError) as e:
490
+ logger.warning(f"Could not import {module_path}: {e}")
491
+ except Exception as e:
492
+ logger.error(f"Error scanning {file_path}: {e}")
493
+
494
+
495
+ def is_flock_agent(cls: type) -> bool:
496
+ """Check if a class is a FlockAgent or a subclass of FlockAgent."""
497
+ try:
498
+ from flock.core.flock_agent import FlockAgent
499
+
500
+ return issubclass(cls, FlockAgent)
501
+ except (ImportError, TypeError):
502
+ # If FlockAgent can't be imported or cls is not a class
503
+ return False
504
+
505
+
506
+ def has_component_base(cls: type) -> bool:
507
+ """Check if a class has a base class that looks like a Flock component."""
508
+ try:
509
+ # Common Flock component base classes
510
+ component_bases = ["FlockModule", "FlockEvaluator", "FlockRouter"]
511
+ bases = [base.__name__ for base in cls.__mro__]
512
+ return any(base in bases for base in component_bases)
513
+ except (AttributeError, TypeError):
514
+ return False
515
+
516
+
517
+ def is_potential_type(cls: type) -> bool:
518
+ """Check if a class is a Pydantic model or dataclass."""
519
+ try:
520
+ from dataclasses import is_dataclass
521
+
522
+ from pydantic import BaseModel
523
+
524
+ return issubclass(cls, BaseModel) or is_dataclass(cls)
525
+ except (ImportError, TypeError):
526
+ return False
527
+
528
+
529
+ def is_potential_registry_candidate(obj: Any) -> bool:
530
+ """Check if an object seems like it could be registry-eligible."""
531
+ # This is a heuristic function to identify potential registry candidates
532
+ if inspect.isclass(obj):
533
+ # Classes with "Flock" in their name
534
+ if "Flock" in obj.__name__:
535
+ return True
536
+
537
+ # Classes with docstrings mentioning certain keywords
538
+ if obj.__doc__ and any(
539
+ kw in obj.__doc__.lower()
540
+ for kw in [
541
+ "agent",
542
+ "flock",
543
+ "tool",
544
+ "module",
545
+ "evaluator",
546
+ "router",
547
+ ]
548
+ ):
549
+ return True
550
+
551
+ elif inspect.isfunction(obj):
552
+ # Functions with docstrings mentioning certain keywords
553
+ if obj.__doc__ and any(
554
+ kw in obj.__doc__.lower() for kw in ["tool", "agent", "flock"]
555
+ ):
556
+ return True
557
+
558
+ return False
559
+
560
+
561
+ def export_registry() -> None:
562
+ """Export the current registry state to a file."""
563
+ registry = get_registry()
564
+
565
+ # Choose export format
566
+ export_format = questionary.select(
567
+ "Select export format:",
568
+ choices=["YAML", "JSON", "Text Report"],
569
+ ).ask()
570
+
571
+ # Choose export path
572
+ export_path = questionary.text(
573
+ "Enter export file path:",
574
+ default=f"flock_registry_export.{export_format.lower()}",
575
+ ).ask()
576
+
577
+ try:
578
+ export_data = {
579
+ "agents": list(registry._agents.keys()),
580
+ "callables": list(registry._callables.keys()),
581
+ "types": list(registry._types.keys()),
582
+ "components": list(registry._components.keys()),
583
+ }
584
+
585
+ if export_format == "YAML":
586
+ import yaml
587
+
588
+ with open(export_path, "w") as f:
589
+ yaml.dump(export_data, f, sort_keys=False, indent=2)
590
+
591
+ elif export_format == "JSON":
592
+ import json
593
+
594
+ with open(export_path, "w") as f:
595
+ json.dump(export_data, f, indent=2)
596
+
597
+ elif export_format == "Text Report":
598
+ with open(export_path, "w") as f:
599
+ f.write("FLOCK REGISTRY EXPORT\n")
600
+ f.write("====================\n\n")
601
+
602
+ for category, items in export_data.items():
603
+ f.write(f"{category.upper()} ({len(items)})\n")
604
+ f.write(
605
+ "-" * (len(category) + 2 + len(str(len(items)))) + "\n"
606
+ )
607
+ for item in sorted(items):
608
+ f.write(f" - {item}\n")
609
+ f.write("\n")
610
+
611
+ console.print(f"[green]Registry exported to {export_path}[/]")
612
+
613
+ except Exception as e:
614
+ console.print(f"[red]Error exporting registry: {e!s}[/]")
615
+
616
+
617
+ if __name__ == "__main__":
618
+ manage_registry()
flock/core/flock.py CHANGED
@@ -108,6 +108,7 @@ class Flock(BaseModel, Serializable):
108
108
 
109
109
  def __init__(
110
110
  self,
111
+ name: str | None = None,
111
112
  model: str | None = "openai/gpt-4o",
112
113
  description: str | None = None,
113
114
  enable_temporal: bool = False,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flock-core
3
- Version: 0.3.31
3
+ Version: 0.3.33
4
4
  Summary: Declarative LLM Orchestration at Scale
5
5
  Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
- flock/__init__.py,sha256=TCFm-Ax0MINIW3-4KdaiGz36raTENp_AY68eO8_a_rQ,2574
1
+ flock/__init__.py,sha256=OO6igJPMOmmFARjY8xjQ2SO96rnSEw2ykJfL_NigtWY,2863
2
2
  flock/config.py,sha256=O5QJGlStf4DWSK4ovZsKw01ud4YK3_ij6Ay8sWU8ih0,1522
3
- flock/cli/constants.py,sha256=s2Mird8E0QXqPH1xG8gxG7rXYY0F4eftGfbBC5ceG2k,568
3
+ flock/cli/constants.py,sha256=EgGwFYl6TD7GVm9gASPJTjSl-aYROiFGltwFYp7u1AQ,668
4
4
  flock/cli/create_agent.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
5
5
  flock/cli/create_flock.py,sha256=Lry15fAwvnh0rHl1pIJ1xKqVj-nYBteNAE1G83LRaAo,6123
6
6
  flock/cli/execute_flock.py,sha256=rAP-5nFfyOivi5uWG8mloZwXF9Tj9iD8MYSbllPllQ4,5726
@@ -10,12 +10,13 @@ flock/cli/load_flock.py,sha256=5bsdjO5olLtpnFEl_UfisnwR8iSQAkOIWI49tnSwJHc,1537
10
10
  flock/cli/load_release_notes.py,sha256=qFcgUrMddAE_TP6x1P-6ZywTUjTknfhTDW5LTxtg1yk,599
11
11
  flock/cli/loaded_flock_cli.py,sha256=LXjvTjxt84VG67wBfownICGTbzx0Z2JmCOKAg_L2a6Q,5913
12
12
  flock/cli/manage_agents.py,sha256=wkNF0IqNFfePrFueR57SILPW885IPqs3U8Cp-fcPPmo,12710
13
+ flock/cli/registry_management.py,sha256=z1ip6AeC78C_YCjGM3PA5rD4eEauqtG9v5Qud1QFRr4,19705
13
14
  flock/cli/settings.py,sha256=Z_TXBzCYlCmSaKrJ_CQCdYy-Cj29gpI4kbC_2KzoKqg,27025
14
15
  flock/cli/view_results.py,sha256=dOzK0O1FHSIDERnx48y-2Xke9BkOHS7pcOhs64AyIg0,781
15
16
  flock/cli/yaml_editor.py,sha256=VpaSwC-Xcbu_gk4HgUeIL7PXNFu1CdstuJ3mRZOkmIk,8096
16
17
  flock/cli/assets/release_notes.md,sha256=bqnk50jxM3w5uY44Dc7MkdT8XmRREFxrVBAG9XCOSSU,4896
17
18
  flock/core/__init__.py,sha256=6NmSXsdQOoOPWjWqdF8BYiUveb54CjH8Ta0WAjNM0Ps,574
18
- flock/core/flock.py,sha256=iUHelhSO85qQclHbiJfQzLRepwUFcf3DGBDnrOwgzsM,23722
19
+ flock/core/flock.py,sha256=NhGYNhrZ_QDd57xSwl0zLg4M3nIqtb1Q-Wgq3Eyp0zk,23755
19
20
  flock/core/flock_agent.py,sha256=jkDwB7yVGYyLfg-WuwvR2X4XblXOs5DrB2dB30xBL7Q,24754
20
21
  flock/core/flock_evaluator.py,sha256=dOXZeDOGZcAmJ9ahqq_2bdGUU1VOXY4skmwTVpAjiVw,1685
21
22
  flock/core/flock_factory.py,sha256=MGTkJCP1WGpV614f87r1vwe0tqAvBCoH9PlqtqDyJDk,2828
@@ -428,8 +429,8 @@ flock/workflow/activities.py,sha256=eVZDnxGJl_quNO-UTV3YgvTV8LrRaHN3QDAA1ANKzac,
428
429
  flock/workflow/agent_activities.py,sha256=NhBZscflEf2IMfSRa_pBM_TRP7uVEF_O0ROvWZ33eDc,963
429
430
  flock/workflow/temporal_setup.py,sha256=VWBgmBgfTBjwM5ruS_dVpA5AVxx6EZ7oFPGw4j3m0l0,1091
430
431
  flock/workflow/workflow.py,sha256=I9MryXW_bqYVTHx-nl2epbTqeRy27CAWHHA7ZZA0nAk,1696
431
- flock_core-0.3.31.dist-info/METADATA,sha256=wWrCmQuj7lyJu1mmgezo7gmkgjwyGh8HC3i-4DyF2xI,20745
432
- flock_core-0.3.31.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
433
- flock_core-0.3.31.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
434
- flock_core-0.3.31.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
435
- flock_core-0.3.31.dist-info/RECORD,,
432
+ flock_core-0.3.33.dist-info/METADATA,sha256=YLv1f0lRExTHDwPn1a-xL2-GQI6yG8VVyR9V5jpq5QQ,20745
433
+ flock_core-0.3.33.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
434
+ flock_core-0.3.33.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
435
+ flock_core-0.3.33.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
436
+ flock_core-0.3.33.dist-info/RECORD,,