MCPcopy Create free account
hub / github.com/HKUDS/OpenSpace / derive_skill

Function derive_skill

openspace/skill_engine/patch.py:181–279  ·  view source on GitHub ↗

Derive a new skill from one or more existing skills. **Single parent** (``source_dirs`` is one Path): Copies parent directory → applies LLM output. Supports PATCH / DIFF / FULL. **Multiple parents** (``source_dirs`` is a list of Paths): Creates a brand-new directory and applie

(
    source_dirs: Union[Path, List[Path]],
    target_dir: Path,
    content: str,
    patch_type: PatchType = PatchType.AUTO,
)

Source from the content-addressed store, hash-verified

179 )
180
181def derive_skill(
182 source_dirs: Union[Path, List[Path]],
183 target_dir: Path,
184 content: str,
185 patch_type: PatchType = PatchType.AUTO,
186) -> SkillEditResult:
187 """Derive a new skill from one or more existing skills.
188
189 **Single parent** (``source_dirs`` is one Path):
190 Copies parent directory → applies LLM output. Supports PATCH / DIFF / FULL.
191
192 **Multiple parents** (``source_dirs`` is a list of Paths):
193 Creates a brand-new directory and applies LLM output as FULL or PATCH
194 (DIFF not supported for multi-parent — no single base to search/replace).
195 ``content_diff`` is empty for multi-parent (no meaningful single-parent
196 diff); ``content_snapshot`` captures the full result for lineage tracking.
197
198 Source directories stay unchanged in both cases.
199
200 Args:
201 source_dirs: Parent skill directory (or list for multi-parent merge).
202 target_dir: New skill directory (must not exist).
203 content: LLM output.
204 patch_type: Output format (AUTO to auto-detect).
205 """
206 # Normalise to list
207 if isinstance(source_dirs, Path):
208 sources = [source_dirs]
209 else:
210 sources = list(source_dirs)
211
212 if not sources:
213 return SkillEditResult(error="derive_skill requires at least one source directory")
214 if target_dir.exists():
215 return SkillEditResult(error=f"Target already exists: {target_dir}")
216
217 # Validate all sources
218 for sd in sources:
219 if not sd.is_dir():
220 return SkillEditResult(error=f"Source does not exist: {sd}")
221 if not (sd / SKILL_FILENAME).exists():
222 return SkillEditResult(error=f"Source SKILL.md not found: {sd / SKILL_FILENAME}")
223
224 first_source = sources[0]
225 is_multi_parent = len(sources) > 1
226
227 if is_multi_parent:
228 # Multi-parent merge: create new directory, apply content (FULL or PATCH)
229 if patch_type == PatchType.AUTO:
230 patch_type = detect_patch_type(content)
231 if patch_type == PatchType.DIFF:
232 # DIFF (SEARCH/REPLACE) is not meaningful for merge — no single base
233 patch_type = PatchType.FULL
234
235 try:
236 target_dir.mkdir(parents=True, exist_ok=True)
237 if patch_type == PatchType.PATCH:
238 _apply_multi_file_patch(content, target_dir)

Callers 1

_evolve_derivedMethod · 0.85

Calls 9

SkillEditResultClass · 0.85
detect_patch_typeFunction · 0.85
_apply_multi_file_patchFunction · 0.85
_apply_multi_file_fullFunction · 0.85
_collect_filesFunction · 0.85
compute_skill_diffFunction · 0.85
infoMethod · 0.80

Tested by

no test coverage detected