EvoScientist 0.0.1.dev3__py3-none-any.whl → 0.1.0rc1__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.
Files changed (108) hide show
  1. EvoScientist/EvoScientist.py +17 -49
  2. EvoScientist/backends.py +0 -26
  3. EvoScientist/cli.py +1109 -255
  4. EvoScientist/middleware.py +8 -61
  5. EvoScientist/stream/__init__.py +0 -25
  6. EvoScientist/stream/utils.py +16 -23
  7. EvoScientist/tools.py +0 -64
  8. evoscientist-0.1.0rc1.dist-info/METADATA +199 -0
  9. evoscientist-0.1.0rc1.dist-info/RECORD +21 -0
  10. evoscientist-0.1.0rc1.dist-info/entry_points.txt +2 -0
  11. EvoScientist/memory.py +0 -715
  12. EvoScientist/paths.py +0 -45
  13. EvoScientist/skills/accelerate/SKILL.md +0 -332
  14. EvoScientist/skills/accelerate/references/custom-plugins.md +0 -453
  15. EvoScientist/skills/accelerate/references/megatron-integration.md +0 -489
  16. EvoScientist/skills/accelerate/references/performance.md +0 -525
  17. EvoScientist/skills/bitsandbytes/SKILL.md +0 -411
  18. EvoScientist/skills/bitsandbytes/references/memory-optimization.md +0 -521
  19. EvoScientist/skills/bitsandbytes/references/qlora-training.md +0 -521
  20. EvoScientist/skills/bitsandbytes/references/quantization-formats.md +0 -447
  21. EvoScientist/skills/find-skills/SKILL.md +0 -133
  22. EvoScientist/skills/find-skills/scripts/install_skill.py +0 -211
  23. EvoScientist/skills/flash-attention/SKILL.md +0 -367
  24. EvoScientist/skills/flash-attention/references/benchmarks.md +0 -215
  25. EvoScientist/skills/flash-attention/references/transformers-integration.md +0 -293
  26. EvoScientist/skills/llama-cpp/SKILL.md +0 -258
  27. EvoScientist/skills/llama-cpp/references/optimization.md +0 -89
  28. EvoScientist/skills/llama-cpp/references/quantization.md +0 -213
  29. EvoScientist/skills/llama-cpp/references/server.md +0 -125
  30. EvoScientist/skills/lm-evaluation-harness/SKILL.md +0 -490
  31. EvoScientist/skills/lm-evaluation-harness/references/api-evaluation.md +0 -490
  32. EvoScientist/skills/lm-evaluation-harness/references/benchmark-guide.md +0 -488
  33. EvoScientist/skills/lm-evaluation-harness/references/custom-tasks.md +0 -602
  34. EvoScientist/skills/lm-evaluation-harness/references/distributed-eval.md +0 -519
  35. EvoScientist/skills/ml-paper-writing/SKILL.md +0 -937
  36. EvoScientist/skills/ml-paper-writing/references/checklists.md +0 -361
  37. EvoScientist/skills/ml-paper-writing/references/citation-workflow.md +0 -562
  38. EvoScientist/skills/ml-paper-writing/references/reviewer-guidelines.md +0 -367
  39. EvoScientist/skills/ml-paper-writing/references/sources.md +0 -159
  40. EvoScientist/skills/ml-paper-writing/references/writing-guide.md +0 -476
  41. EvoScientist/skills/ml-paper-writing/templates/README.md +0 -251
  42. EvoScientist/skills/ml-paper-writing/templates/aaai2026/README.md +0 -534
  43. EvoScientist/skills/ml-paper-writing/templates/aaai2026/aaai2026-unified-supp.tex +0 -144
  44. EvoScientist/skills/ml-paper-writing/templates/aaai2026/aaai2026-unified-template.tex +0 -952
  45. EvoScientist/skills/ml-paper-writing/templates/aaai2026/aaai2026.bib +0 -111
  46. EvoScientist/skills/ml-paper-writing/templates/aaai2026/aaai2026.bst +0 -1493
  47. EvoScientist/skills/ml-paper-writing/templates/aaai2026/aaai2026.sty +0 -315
  48. EvoScientist/skills/ml-paper-writing/templates/acl/README.md +0 -50
  49. EvoScientist/skills/ml-paper-writing/templates/acl/acl.sty +0 -312
  50. EvoScientist/skills/ml-paper-writing/templates/acl/acl_latex.tex +0 -377
  51. EvoScientist/skills/ml-paper-writing/templates/acl/acl_lualatex.tex +0 -101
  52. EvoScientist/skills/ml-paper-writing/templates/acl/acl_natbib.bst +0 -1940
  53. EvoScientist/skills/ml-paper-writing/templates/acl/anthology.bib.txt +0 -26
  54. EvoScientist/skills/ml-paper-writing/templates/acl/custom.bib +0 -70
  55. EvoScientist/skills/ml-paper-writing/templates/acl/formatting.md +0 -326
  56. EvoScientist/skills/ml-paper-writing/templates/colm2025/README.md +0 -3
  57. EvoScientist/skills/ml-paper-writing/templates/colm2025/colm2025_conference.bib +0 -11
  58. EvoScientist/skills/ml-paper-writing/templates/colm2025/colm2025_conference.bst +0 -1440
  59. EvoScientist/skills/ml-paper-writing/templates/colm2025/colm2025_conference.pdf +0 -0
  60. EvoScientist/skills/ml-paper-writing/templates/colm2025/colm2025_conference.sty +0 -218
  61. EvoScientist/skills/ml-paper-writing/templates/colm2025/colm2025_conference.tex +0 -305
  62. EvoScientist/skills/ml-paper-writing/templates/colm2025/fancyhdr.sty +0 -485
  63. EvoScientist/skills/ml-paper-writing/templates/colm2025/math_commands.tex +0 -508
  64. EvoScientist/skills/ml-paper-writing/templates/colm2025/natbib.sty +0 -1246
  65. EvoScientist/skills/ml-paper-writing/templates/iclr2026/fancyhdr.sty +0 -485
  66. EvoScientist/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.bib +0 -24
  67. EvoScientist/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.bst +0 -1440
  68. EvoScientist/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.pdf +0 -0
  69. EvoScientist/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.sty +0 -246
  70. EvoScientist/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.tex +0 -414
  71. EvoScientist/skills/ml-paper-writing/templates/iclr2026/math_commands.tex +0 -508
  72. EvoScientist/skills/ml-paper-writing/templates/iclr2026/natbib.sty +0 -1246
  73. EvoScientist/skills/ml-paper-writing/templates/icml2026/algorithm.sty +0 -79
  74. EvoScientist/skills/ml-paper-writing/templates/icml2026/algorithmic.sty +0 -201
  75. EvoScientist/skills/ml-paper-writing/templates/icml2026/example_paper.bib +0 -75
  76. EvoScientist/skills/ml-paper-writing/templates/icml2026/example_paper.pdf +0 -0
  77. EvoScientist/skills/ml-paper-writing/templates/icml2026/example_paper.tex +0 -662
  78. EvoScientist/skills/ml-paper-writing/templates/icml2026/fancyhdr.sty +0 -864
  79. EvoScientist/skills/ml-paper-writing/templates/icml2026/icml2026.bst +0 -1443
  80. EvoScientist/skills/ml-paper-writing/templates/icml2026/icml2026.sty +0 -767
  81. EvoScientist/skills/ml-paper-writing/templates/icml2026/icml_numpapers.pdf +0 -0
  82. EvoScientist/skills/ml-paper-writing/templates/neurips2025/Makefile +0 -36
  83. EvoScientist/skills/ml-paper-writing/templates/neurips2025/extra_pkgs.tex +0 -53
  84. EvoScientist/skills/ml-paper-writing/templates/neurips2025/main.tex +0 -38
  85. EvoScientist/skills/ml-paper-writing/templates/neurips2025/neurips.sty +0 -382
  86. EvoScientist/skills/peft/SKILL.md +0 -431
  87. EvoScientist/skills/peft/references/advanced-usage.md +0 -514
  88. EvoScientist/skills/peft/references/troubleshooting.md +0 -480
  89. EvoScientist/skills/ray-data/SKILL.md +0 -326
  90. EvoScientist/skills/ray-data/references/integration.md +0 -82
  91. EvoScientist/skills/ray-data/references/transformations.md +0 -83
  92. EvoScientist/skills/skill-creator/LICENSE.txt +0 -202
  93. EvoScientist/skills/skill-creator/SKILL.md +0 -356
  94. EvoScientist/skills/skill-creator/references/output-patterns.md +0 -82
  95. EvoScientist/skills/skill-creator/references/workflows.md +0 -28
  96. EvoScientist/skills/skill-creator/scripts/init_skill.py +0 -303
  97. EvoScientist/skills/skill-creator/scripts/package_skill.py +0 -110
  98. EvoScientist/skills/skill-creator/scripts/quick_validate.py +0 -95
  99. EvoScientist/skills_manager.py +0 -392
  100. EvoScientist/stream/display.py +0 -604
  101. EvoScientist/stream/events.py +0 -415
  102. EvoScientist/stream/state.py +0 -343
  103. evoscientist-0.0.1.dev3.dist-info/METADATA +0 -321
  104. evoscientist-0.0.1.dev3.dist-info/RECORD +0 -113
  105. evoscientist-0.0.1.dev3.dist-info/entry_points.txt +0 -5
  106. {evoscientist-0.0.1.dev3.dist-info → evoscientist-0.1.0rc1.dist-info}/WHEEL +0 -0
  107. {evoscientist-0.0.1.dev3.dist-info → evoscientist-0.1.0rc1.dist-info}/licenses/LICENSE +0 -0
  108. {evoscientist-0.0.1.dev3.dist-info → evoscientist-0.1.0rc1.dist-info}/top_level.txt +0 -0
@@ -1,392 +0,0 @@
1
- """Skill installation and management for EvoScientist.
2
-
3
- This module provides functions for installing, listing, and uninstalling user skills.
4
- Skills are installed to USER_SKILLS_DIR (~/.evoscientist/workspace/skills/).
5
-
6
- Supported installation sources:
7
- - Local directory paths
8
- - GitHub URLs (https://github.com/owner/repo or .../tree/branch/path)
9
- - GitHub shorthand (owner/repo@skill-name)
10
-
11
- Usage:
12
- from EvoScientist.skills_manager import install_skill, list_skills, uninstall_skill
13
-
14
- # Install from local path
15
- install_skill("./my-skill")
16
-
17
- # Install from GitHub
18
- install_skill("https://github.com/user/repo/tree/main/my-skill")
19
-
20
- # List installed skills
21
- for skill in list_skills():
22
- print(skill["name"], skill["description"])
23
-
24
- # Uninstall a skill
25
- uninstall_skill("my-skill")
26
- """
27
-
28
- from __future__ import annotations
29
-
30
- import os
31
- import re
32
- import shutil
33
- import subprocess
34
- import tempfile
35
- from dataclasses import dataclass
36
- from pathlib import Path
37
- from typing import Iterator
38
-
39
- import yaml
40
-
41
- from .paths import USER_SKILLS_DIR
42
-
43
-
44
- @dataclass
45
- class SkillInfo:
46
- """Information about an installed skill."""
47
-
48
- name: str
49
- description: str
50
- path: Path
51
- source: str # "user" or "system"
52
-
53
-
54
- def _parse_skill_md(skill_md_path: Path) -> dict[str, str]:
55
- """Parse SKILL.md frontmatter to extract name and description.
56
-
57
- SKILL.md format:
58
- ---
59
- name: skill-name
60
- description: A brief description...
61
- ---
62
- # Skill Title
63
- ...
64
-
65
- Returns:
66
- Dictionary with 'name' and 'description' keys.
67
- """
68
- content = skill_md_path.read_text(encoding="utf-8")
69
-
70
- # Extract YAML frontmatter
71
- frontmatter_match = re.match(r"^---\s*\n(.*?)\n---", content, re.DOTALL)
72
- if not frontmatter_match:
73
- # No frontmatter, use directory name
74
- return {
75
- "name": skill_md_path.parent.name,
76
- "description": "(no description)",
77
- }
78
-
79
- try:
80
- frontmatter = yaml.safe_load(frontmatter_match.group(1))
81
- return {
82
- "name": frontmatter.get("name", skill_md_path.parent.name),
83
- "description": frontmatter.get("description", "(no description)"),
84
- }
85
- except yaml.YAMLError:
86
- return {
87
- "name": skill_md_path.parent.name,
88
- "description": "(invalid frontmatter)",
89
- }
90
-
91
-
92
- def _parse_github_url(url: str) -> tuple[str, str | None, str | None]:
93
- """Parse a GitHub URL into (repo, ref, path).
94
-
95
- Supports formats:
96
- https://github.com/owner/repo
97
- https://github.com/owner/repo/tree/main/path/to/skill
98
- github.com/owner/repo/tree/branch/path
99
- owner/repo@skill-name (shorthand from skills.sh)
100
-
101
- Returns:
102
- (repo, ref_or_none, path_or_none)
103
- """
104
- # Shorthand: owner/repo@path
105
- if "@" in url and "://" not in url:
106
- repo, path = url.split("@", 1)
107
- return repo.strip(), None, path.strip()
108
-
109
- # Strip protocol and github.com prefix
110
- cleaned = re.sub(r"^https?://", "", url)
111
- cleaned = re.sub(r"^github\.com/", "", cleaned)
112
- cleaned = cleaned.rstrip("/")
113
-
114
- # Match: owner/repo/tree/ref/path...
115
- m = re.match(r"^([^/]+/[^/]+)/tree/([^/]+)(?:/(.+))?$", cleaned)
116
- if m:
117
- return m.group(1), m.group(2), m.group(3)
118
-
119
- # Match: owner/repo (no tree)
120
- m = re.match(r"^([^/]+/[^/]+)$", cleaned)
121
- if m:
122
- return m.group(1), None, None
123
-
124
- raise ValueError(f"Cannot parse GitHub URL: {url}")
125
-
126
-
127
- def _clone_repo(repo: str, ref: str | None, dest: str) -> None:
128
- """Shallow-clone a GitHub repo."""
129
- clone_url = f"https://github.com/{repo}.git"
130
- cmd = ["git", "clone", "--depth", "1"]
131
- if ref:
132
- cmd += ["--branch", ref]
133
- cmd += [clone_url, dest]
134
-
135
- result = subprocess.run(cmd, capture_output=True, text=True)
136
- if result.returncode != 0:
137
- raise RuntimeError(f"git clone failed: {result.stderr.strip()}")
138
-
139
-
140
- def _is_github_url(source: str) -> bool:
141
- """Check if the source looks like a GitHub URL or shorthand."""
142
- if "github.com" in source.lower():
143
- return True
144
- if "://" in source:
145
- return False # Non-GitHub URL
146
- # Check for owner/repo@skill shorthand
147
- if "@" in source and "/" in source.split("@")[0]:
148
- return True
149
- # Check for owner/repo format (but not local paths like ./foo or /foo)
150
- if "/" in source and not source.startswith((".", "/")):
151
- parts = source.split("/")
152
- # GitHub shorthand: exactly 2 parts, both non-empty, no extensions
153
- if len(parts) == 2 and all(parts) and "." not in parts[0]:
154
- return True
155
- return False
156
-
157
-
158
- def _validate_skill_dir(path: Path) -> bool:
159
- """Check if a directory contains a valid skill (has SKILL.md)."""
160
- return (path / "SKILL.md").is_file()
161
-
162
-
163
- def install_skill(source: str, dest_dir: str | None = None) -> dict:
164
- """Install a skill from a local path or GitHub URL.
165
-
166
- Args:
167
- source: Local directory path or GitHub URL/shorthand.
168
- dest_dir: Destination directory (defaults to USER_SKILLS_DIR).
169
-
170
- Returns:
171
- Dictionary with installation result:
172
- - success: bool
173
- - name: skill name (if successful)
174
- - path: installed path (if successful)
175
- - error: error message (if failed)
176
- """
177
- dest_dir = dest_dir or str(USER_SKILLS_DIR)
178
- os.makedirs(dest_dir, exist_ok=True)
179
-
180
- if _is_github_url(source):
181
- return _install_from_github(source, dest_dir)
182
- else:
183
- return _install_from_local(source, dest_dir)
184
-
185
-
186
- def _install_from_local(source: str, dest_dir: str) -> dict:
187
- """Install a skill from a local directory path."""
188
- source_path = Path(source).expanduser().resolve()
189
-
190
- if not source_path.exists():
191
- return {"success": False, "error": f"Path does not exist: {source}"}
192
-
193
- if not source_path.is_dir():
194
- return {"success": False, "error": f"Not a directory: {source}"}
195
-
196
- if not _validate_skill_dir(source_path):
197
- return {"success": False, "error": f"No SKILL.md found in: {source}"}
198
-
199
- # Parse SKILL.md to get the skill name
200
- skill_info = _parse_skill_md(source_path / "SKILL.md")
201
- skill_name = skill_info["name"]
202
-
203
- # Destination path
204
- target_path = Path(dest_dir) / skill_name
205
-
206
- # Remove existing if present
207
- if target_path.exists():
208
- shutil.rmtree(target_path)
209
-
210
- # Copy skill directory
211
- shutil.copytree(source_path, target_path)
212
-
213
- return {
214
- "success": True,
215
- "name": skill_name,
216
- "path": str(target_path),
217
- "description": skill_info["description"],
218
- }
219
-
220
-
221
- def _install_from_github(source: str, dest_dir: str) -> dict:
222
- """Install a skill from a GitHub URL or shorthand."""
223
- try:
224
- repo, ref, path = _parse_github_url(source)
225
- except ValueError as e:
226
- return {"success": False, "error": str(e)}
227
-
228
- with tempfile.TemporaryDirectory(prefix="evoscientist-skill-") as tmp:
229
- clone_dir = os.path.join(tmp, "repo")
230
-
231
- try:
232
- _clone_repo(repo, ref, clone_dir)
233
- except RuntimeError as e:
234
- return {"success": False, "error": str(e)}
235
-
236
- # Determine the skill source directory
237
- if path:
238
- skill_source = Path(clone_dir) / path
239
- else:
240
- skill_source = Path(clone_dir)
241
-
242
- if not skill_source.exists():
243
- return {"success": False, "error": f"Path not found in repo: {path or '/'}"}
244
-
245
- if not _validate_skill_dir(skill_source):
246
- # Maybe the repo root contains multiple skills?
247
- if not path:
248
- # Try to find skills in repo root
249
- found_skills = []
250
- for entry in os.listdir(clone_dir):
251
- entry_path = Path(clone_dir) / entry
252
- if entry_path.is_dir() and _validate_skill_dir(entry_path):
253
- found_skills.append(entry)
254
-
255
- if found_skills:
256
- return {
257
- "success": False,
258
- "error": (
259
- f"Multiple skills found in repo. "
260
- f"Please specify one: {', '.join(found_skills)}"
261
- ),
262
- }
263
-
264
- return {"success": False, "error": f"No SKILL.md found in: {source}"}
265
-
266
- # Parse skill info and copy
267
- skill_info = _parse_skill_md(skill_source / "SKILL.md")
268
- skill_name = skill_info["name"]
269
- target_path = Path(dest_dir) / skill_name
270
-
271
- if target_path.exists():
272
- shutil.rmtree(target_path)
273
-
274
- # Copy, excluding .git directory
275
- def ignore_git(dir_name: str, files: list[str]) -> list[str]:
276
- return [f for f in files if f == ".git"]
277
-
278
- shutil.copytree(skill_source, target_path, ignore=ignore_git)
279
-
280
- return {
281
- "success": True,
282
- "name": skill_name,
283
- "path": str(target_path),
284
- "description": skill_info["description"],
285
- "source": source,
286
- }
287
-
288
-
289
- def list_skills(include_system: bool = False) -> list[SkillInfo]:
290
- """List all installed user skills.
291
-
292
- Args:
293
- include_system: If True, also include system (built-in) skills.
294
-
295
- Returns:
296
- List of SkillInfo objects for each installed skill.
297
- """
298
- skills: list[SkillInfo] = []
299
-
300
- # User skills
301
- user_dir = Path(USER_SKILLS_DIR)
302
- if user_dir.exists():
303
- for entry in sorted(user_dir.iterdir()):
304
- if entry.is_dir() and _validate_skill_dir(entry):
305
- skill_md = entry / "SKILL.md"
306
- info = _parse_skill_md(skill_md)
307
- skills.append(
308
- SkillInfo(
309
- name=info["name"],
310
- description=info["description"],
311
- path=entry,
312
- source="user",
313
- )
314
- )
315
-
316
- # System skills (optional)
317
- if include_system:
318
- from .EvoScientist import SKILLS_DIR
319
-
320
- system_dir = Path(SKILLS_DIR)
321
- if system_dir.exists():
322
- for entry in sorted(system_dir.iterdir()):
323
- if entry.is_dir() and _validate_skill_dir(entry):
324
- # Skip if user has overridden this skill
325
- if any(s.name == entry.name for s in skills):
326
- continue
327
- skill_md = entry / "SKILL.md"
328
- info = _parse_skill_md(skill_md)
329
- skills.append(
330
- SkillInfo(
331
- name=info["name"],
332
- description=info["description"],
333
- path=entry,
334
- source="system",
335
- )
336
- )
337
-
338
- return skills
339
-
340
-
341
- def uninstall_skill(name: str) -> dict:
342
- """Uninstall a user-installed skill.
343
-
344
- Args:
345
- name: Name of the skill to uninstall.
346
-
347
- Returns:
348
- Dictionary with result:
349
- - success: bool
350
- - error: error message (if failed)
351
- """
352
- user_dir = Path(USER_SKILLS_DIR)
353
- target_path = user_dir / name
354
-
355
- if not target_path.exists():
356
- # Try to find by directory name (in case name differs from dir name)
357
- found = None
358
- if user_dir.exists():
359
- for entry in user_dir.iterdir():
360
- if entry.is_dir() and _validate_skill_dir(entry):
361
- info = _parse_skill_md(entry / "SKILL.md")
362
- if info["name"] == name:
363
- found = entry
364
- break
365
-
366
- if not found:
367
- return {"success": False, "error": f"Skill not found: {name}"}
368
- target_path = found
369
-
370
- # Check if it's a user skill (not system)
371
- if not str(target_path).startswith(str(user_dir)):
372
- return {"success": False, "error": f"Cannot uninstall system skill: {name}"}
373
-
374
- # Remove the skill directory
375
- shutil.rmtree(target_path)
376
-
377
- return {"success": True, "name": name}
378
-
379
-
380
- def get_skill_info(name: str) -> SkillInfo | None:
381
- """Get information about a specific skill.
382
-
383
- Args:
384
- name: Name of the skill.
385
-
386
- Returns:
387
- SkillInfo if found, None otherwise.
388
- """
389
- for skill in list_skills(include_system=True):
390
- if skill.name == name:
391
- return skill
392
- return None