machineconfig 4.4__py3-none-any.whl → 4.5__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 machineconfig might be problematic. Click here for more details.

@@ -120,12 +120,9 @@ class ZellijLocalManager:
120
120
  session_name = manager.session_name
121
121
  if session_name is None:
122
122
  continue # Skip managers without a session name
123
-
124
123
  cmd = f"zellij delete-session --force {session_name}"
125
-
126
124
  logger.info(f"Killing session '{session_name}'")
127
125
  result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=10)
128
-
129
126
  results[session_name] = {"success": result.returncode == 0, "message": "Session killed" if result.returncode == 0 else result.stderr}
130
127
 
131
128
  except Exception as e:
@@ -25,7 +25,7 @@ from machineconfig.scripts.python.fire_agents_help_launch import prep_agent_laun
25
25
  from machineconfig.scripts.python.fire_agents_help_search import search_files_by_pattern, search_python_files
26
26
  from machineconfig.scripts.python.fire_agents_load_balancer import chunk_prompts
27
27
  from machineconfig.utils.schemas.layouts.layout_types import LayoutsFile
28
- from machineconfig.utils.accessories import get_repo_root
28
+ from machineconfig.utils.accessories import get_repo_root, randstr
29
29
 
30
30
  SEARCH_STRATEGIES: TypeAlias = Literal["file_path", "keyword_search", "filename_pattern"]
31
31
 
@@ -50,6 +50,7 @@ def create(
50
50
  job_name: str = typer.Option("AI_Agents", help="Job name"),
51
51
  keep_separate: bool = typer.Option(True, help="Keep prompt material in separate file to the context."),
52
52
  output_path: Optional[Path] = typer.Option(None, help="Path to write the layout.json file"),
53
+ agents_dir: Optional[Path] = typer.Option(None, help="Directory to store agent files. If not provided, will be constructed automatically."),
53
54
  ):
54
55
  # validate mutual exclusive
55
56
  context_options = [context_path, keyword_search, filename_pattern]
@@ -103,7 +104,12 @@ def create(
103
104
  agent_selected = agent
104
105
  keep_material_in_separate_file_input = keep_separate
105
106
  prompt_material_re_splitted = chunk_prompts(prompt_material_path, tasks_per_prompt=tasks_per_prompt, joiner=separator)
106
- agents_dir = prep_agent_launch(repo_root=repo_root, prompts_material=prompt_material_re_splitted, keep_material_in_separate_file=keep_material_in_separate_file_input, prompt_prefix=prompt_prefix, agent=agent_selected, job_name=job_name)
107
+ if agents_dir is None: agents_dir = repo_root / ".ai" / f"tmp_prompts/{job_name}_{randstr()}"
108
+ else:
109
+ import shutil
110
+ if agents_dir.exists():
111
+ shutil.rmtree(agents_dir)
112
+ prep_agent_launch(agents_dir=agents_dir, prompts_material=prompt_material_re_splitted, keep_material_in_separate_file=keep_material_in_separate_file_input, prompt_prefix=prompt_prefix, agent=agent_selected, job_name=job_name)
107
113
  layoutfile = get_agents_launch_layout(session_root=agents_dir)
108
114
  regenerate_py_code = f"""
109
115
  #!/usr/bin/env uv run --python 3.13 --with machineconfig
@@ -119,25 +125,34 @@ fire_agents create --context-path "{prompt_material_path}" \\
119
125
  """
120
126
  (agents_dir / "aa_agents_relaunch.py").write_text(data=regenerate_py_code, encoding="utf-8")
121
127
  layout_output_path = output_path if output_path is not None else agents_dir / "layout.json"
128
+ layout_output_path.parent.mkdir(parents=True, exist_ok=True)
122
129
  layout_output_path.write_text(data=json.dumps(layoutfile, indent=4), encoding="utf-8")
123
130
  typer.echo(f"Created agents in {agents_dir}")
131
+ typer.echo(f"Ceated layout in {layout_output_path}")
124
132
 
125
133
 
126
134
  @app.command()
127
135
  def run(layout_path: Path = typer.Argument(..., help="Path to the layout.json file"),
128
136
  max_tabs: int = typer.Option(6, help="Maximum number of tabs to launch"),
129
- sleep_between_layouts: float = typer.Option(1.0, help="Sleep time in seconds between launching layouts")):
137
+ sleep_inbetween: float = typer.Option(1.0, help="Sleep time in seconds between launching layouts"),
138
+ kill_upon_completion: bool = typer.Option(False, help="Kill the layout sessions upon completion")):
130
139
  layoutfile: LayoutsFile = json.loads(layout_path.read_text())
131
- if len(layoutfile["layouts"][0]["layoutTabs"]) > max_tabs:
132
- typer.echo(f"Too many tabs (>{max_tabs}) to launch. Skipping launch.")
133
- raise typer.Exit(0)
140
+ for a_layout in layoutfile["layouts"]:
141
+ if len(a_layout["layoutTabs"]) > max_tabs:
142
+ typer.echo(f"Layout '{a_layout.get('layoutName', 'Unnamed')}' has {len(a_layout['layoutTabs'])} tabs which exceeds the max of {max_tabs}.")
143
+ confirm = typer.confirm("Do you want to proceed with launching this layout?", default=False)
144
+ if not confirm:
145
+ typer.echo("Aborting launch.")
146
+ raise typer.Exit(0)
134
147
  from machineconfig.cluster.sessions_managers.zellij_local_manager import ZellijLocalManager
135
148
  for i, a_layouts in enumerate(layoutfile["layouts"]):
136
149
  manager = ZellijLocalManager(session_layouts=[a_layouts])
137
150
  manager.start_all_sessions(poll_interval=2, poll_seconds=2)
138
151
  manager.run_monitoring_routine(wait_ms=2000)
152
+ if kill_upon_completion:
153
+ manager.kill_all_sessions()
139
154
  if i < len(layoutfile["layouts"]) - 1: # Don't sleep after the last layout
140
- time.sleep(sleep_between_layouts)
155
+ time.sleep(sleep_inbetween)
141
156
 
142
157
 
143
158
  @app.command(help="Adjust layout file to limit max tabs per layout, etc.")
@@ -152,9 +167,52 @@ def load_balance(layout_path: Path = typer.Argument(..., help="Path to the layou
152
167
  new_layouts = limit_tab_num(layout_configs=layout_configs, max_thresh=max_thresh, threshold_type=thresh_type, breaking_method=breaking_method)
153
168
  layoutfile["layouts"] = new_layouts
154
169
  target_file = output_path if output_path is not None else layout_path.parent / f'{layout_path.stem}_adjusted_{max_thresh}_{thresh_type}_{breaking_method}.json'
170
+ target_file.parent.mkdir(parents=True, exist_ok=True)
155
171
  target_file.write_text(data=json.dumps(layoutfile, indent=4), encoding="utf-8")
156
172
  typer.echo(f"Adjusted layout saved to {target_file}")
157
173
 
158
174
 
175
+ @app.command()
176
+ def collect(
177
+ agent_dir: Path = typer.Argument(..., help="Path to the agent directory containing the prompts folder"),
178
+ output_path: Path = typer.Argument(..., help="Path to write the concatenated material files"),
179
+ separator: str = typer.Option("\n", help="Separator to use when concatenating material files"),
180
+ ) -> None:
181
+ """Collect all material files from an agent directory and concatenate them."""
182
+ if not agent_dir.exists() or not agent_dir.is_dir():
183
+ raise typer.BadParameter(f"Agent directory does not exist or is not a directory: {agent_dir}")
184
+
185
+ prompts_dir = agent_dir / "prompts"
186
+ if not prompts_dir.exists():
187
+ raise typer.BadParameter(f"Prompts directory not found: {prompts_dir}")
188
+
189
+ material_files = []
190
+ for agent_subdir in prompts_dir.iterdir():
191
+ if agent_subdir.is_dir() and agent_subdir.name.startswith("agent_"):
192
+ material_file = agent_subdir / f"{agent_subdir.name}_material.txt"
193
+ if material_file.exists():
194
+ material_files.append(material_file)
195
+
196
+ if not material_files:
197
+ typer.echo("No material files found in the agent directory.")
198
+ return
199
+
200
+ # Sort by agent index for consistent ordering
201
+ material_files.sort(key=lambda x: int(x.parent.name.split("_")[-1]))
202
+
203
+ # Read and concatenate all material files
204
+ concatenated_content = []
205
+ for material_file in material_files:
206
+ content = material_file.read_text(encoding="utf-8")
207
+ concatenated_content.append(content)
208
+
209
+ result = separator.join(concatenated_content)
210
+
211
+ # Write to output file
212
+ output_path.parent.mkdir(parents=True, exist_ok=True)
213
+ output_path.write_text(result, encoding="utf-8")
214
+ typer.echo(f"Concatenated material written to {output_path}")
215
+
216
+
159
217
  if __name__ == "__main__": # pragma: no cover
160
218
  app()
@@ -1,4 +1,3 @@
1
- from machineconfig.utils.accessories import randstr
2
1
 
3
2
  import random
4
3
  import shlex
@@ -28,10 +27,9 @@ def get_gemini_api_keys() -> list[str]:
28
27
  return res
29
28
 
30
29
 
31
- def prep_agent_launch(repo_root: Path, prompts_material: list[str], prompt_prefix: str, keep_material_in_separate_file: bool, agent: AGENTS, *, job_name: str) -> Path:
32
- session_root = repo_root / ".ai" / f"tmp_prompts/{job_name}_{randstr()}"
33
- session_root.mkdir(parents=True, exist_ok=True)
34
- prompt_folder = session_root / "prompts"
30
+ def prep_agent_launch(agents_dir: Path, prompts_material: list[str], prompt_prefix: str, keep_material_in_separate_file: bool, agent: AGENTS, *, job_name: str) -> None:
31
+ agents_dir.mkdir(parents=True, exist_ok=True)
32
+ prompt_folder = agents_dir / "prompts"
35
33
  prompt_folder.mkdir(parents=True, exist_ok=True)
36
34
 
37
35
  for idx, a_prompt_material in enumerate(prompts_material):
@@ -110,7 +108,7 @@ echo "---------END OF AGENT OUTPUT---------"
110
108
  """
111
109
  agent_cmd_launch_path.write_text(cmd_prefix + cmd + cmd_postfix, encoding="utf-8")
112
110
 
113
- return session_root
111
+ return None
114
112
 
115
113
 
116
114
  def get_agents_launch_layout(session_root: Path):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machineconfig
3
- Version: 4.4
3
+ Version: 4.5
4
4
  Summary: Dotfiles management package
5
5
  Author-email: Alex Al-Saffar <programmer@usa.com>
6
6
  License: Apache 2.0
@@ -16,7 +16,7 @@ machineconfig/cluster/sessions_managers/wt_local_manager.py,sha256=LqOuA9fqVDu5m
16
16
  machineconfig/cluster/sessions_managers/wt_remote.py,sha256=XmZV9rLubwxND5UYAS15mAcpzDdXvm4KyubVGYkVBmo,8743
17
17
  machineconfig/cluster/sessions_managers/wt_remote_manager.py,sha256=CnnOtPiwLx0pIfs_KlcKnclLSqiDTNzfm8t8sW6nXf0,19764
18
18
  machineconfig/cluster/sessions_managers/zellij_local.py,sha256=T2wXkW9ug1nzdnhlD-1G2HPlBpBaNw6rdM9rk4KKeHQ,26137
19
- machineconfig/cluster/sessions_managers/zellij_local_manager.py,sha256=4ap0Gtd8wOybFc461OItA2kU-1jpgPQUX03s8Zjyk_4,24028
19
+ machineconfig/cluster/sessions_managers/zellij_local_manager.py,sha256=HaofZHTvjp1xFmcwJ5XaMfDVUCRdYk27eBlTKrqVr0E,24025
20
20
  machineconfig/cluster/sessions_managers/zellij_remote.py,sha256=3gz-wgqVW7B-4CgvJq0fiDh8691h4yeK3Xh3CfSPc2s,8749
21
21
  machineconfig/cluster/sessions_managers/zellij_remote_manager.py,sha256=T-j1KMV7mDTeGSHC5To0_JmqNtjSR_LVZT9VanP4lyI,8313
22
22
  machineconfig/cluster/sessions_managers/utils/enhanced_command_runner.py,sha256=3vcQVg-HHa_WTxBGPtKMAdoSqJVa2EO5KAtrY8a6I3c,5264
@@ -155,8 +155,8 @@ machineconfig/scripts/python/devops_backup_retrieve.py,sha256=jZe5Vki7E2GCMG8hvq
155
155
  machineconfig/scripts/python/devops_devapps_install.py,sha256=QbRQhNdDRLLtgJwaRl2pbLmWvajb1b_Xte2ql8N3JRs,9096
156
156
  machineconfig/scripts/python/devops_update_repos.py,sha256=c5qBc9cuTGDEqDHufkjDT4d_vvJsswv3tlqk9MAulYk,8063
157
157
  machineconfig/scripts/python/dotfile.py,sha256=SRcX-9Ak1jRvF-killBTTm2IWcsNxfiLucH6ZsytAFA,2202
158
- machineconfig/scripts/python/fire_agents.py,sha256=An6OE2dVyni_XGt3V-5kMhPxDSfXOnJuO2N6AokQHyo,8860
159
- machineconfig/scripts/python/fire_agents_help_launch.py,sha256=TpuARLC_9b3SNMYeYIi_h1qKCSifT074QEvZ-ZK967M,5264
158
+ machineconfig/scripts/python/fire_agents.py,sha256=lBnA4uYZ2tFmkhEmixAlIagAvl-nJ-AE-p-w0M2KfOY,11653
159
+ machineconfig/scripts/python/fire_agents_help_launch.py,sha256=UO-rV0z0G6WoL3RtnbqjIo97fq-FQO8ynmQ2lLrIdSg,5124
160
160
  machineconfig/scripts/python/fire_agents_help_search.py,sha256=qIfSS_su2YJ1Gb0_lu4cbjlJlYMBw0v52NTGiSrGjk8,2991
161
161
  machineconfig/scripts/python/fire_agents_load_balancer.py,sha256=mpqx3uaQdBXYieuvhdK-qsvLepf9oIMo3pwPj9mSEDI,1079
162
162
  machineconfig/scripts/python/fire_jobs.py,sha256=qD_9JtoNTjOjAyX0_QPysfHNQ-qq55t-Tv9ctEK17MI,20569
@@ -406,8 +406,8 @@ machineconfig/utils/schemas/fire_agents/fire_agents_input.py,sha256=pTxvLzIpD5RF
406
406
  machineconfig/utils/schemas/installer/installer_types.py,sha256=DLagmIe0G5-xg7HZ9VrlFCDk1gIbwvX7O4gZjwq0wh0,1326
407
407
  machineconfig/utils/schemas/layouts/layout_types.py,sha256=TcqlZdGVoH8htG5fHn1KWXhRdPueAcoyApppZsPAPto,2020
408
408
  machineconfig/utils/schemas/repos/repos_types.py,sha256=ECVr-3IVIo8yjmYmVXX2mnDDN1SLSwvQIhx4KDDQHBQ,405
409
- machineconfig-4.4.dist-info/METADATA,sha256=lyni_bLaEQayMHJkaaRhSCbb0g7svm5l25Ek_EaQ7lw,7060
410
- machineconfig-4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
411
- machineconfig-4.4.dist-info/entry_points.txt,sha256=fhSTJGrT7JZ7PcN-F3nrb5xXIohicZo57rbM23Mdblk,1065
412
- machineconfig-4.4.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
413
- machineconfig-4.4.dist-info/RECORD,,
409
+ machineconfig-4.5.dist-info/METADATA,sha256=hwREinHY-RApFYtMH7odfRdK32LRkZ9mKm05Cry8uBk,7060
410
+ machineconfig-4.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
411
+ machineconfig-4.5.dist-info/entry_points.txt,sha256=fhSTJGrT7JZ7PcN-F3nrb5xXIohicZo57rbM23Mdblk,1065
412
+ machineconfig-4.5.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
413
+ machineconfig-4.5.dist-info/RECORD,,