WIP loading
This commit is contained in:
@@ -1,43 +1,57 @@
|
||||
from collections.abc import Generator
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
from fnmatch import fnmatch
|
||||
from functools import partial
|
||||
from importlib.resources.abc import Traversable
|
||||
from itertools import groupby
|
||||
from itertools import starmap
|
||||
from typing import Self
|
||||
|
||||
|
||||
def get_skill_filemap(content: dict[str, str]) -> dict[str, list[str]]:
|
||||
"""Get the map of skill slugs to their associated files."""
|
||||
|
||||
def get_skill_name(relpath: str) -> str | None:
|
||||
if relpath.startswith("skills/"):
|
||||
return relpath.split("/")[1]
|
||||
|
||||
grouped = groupby(content.keys(), key=get_skill_name)
|
||||
return {k: list(v) for k, v in grouped if k is not None}
|
||||
from .file import MarkdownDocument
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class SkillBundle:
|
||||
class SkillFilesBundle:
|
||||
"""Represents a skill and all of its associated markdown files."""
|
||||
|
||||
slug: str
|
||||
skill: str
|
||||
references: list[str]
|
||||
other: list[str]
|
||||
skill: MarkdownDocument
|
||||
references: tuple[MarkdownDocument, ...]
|
||||
other: tuple[MarkdownDocument, ...]
|
||||
|
||||
@classmethod
|
||||
def from_root(cls, root: Traversable) -> list[Self]:
|
||||
# Should only be used for testing
|
||||
return list(cls.from_docs(MarkdownDocument.from_root(root).values()))
|
||||
|
||||
def gen_skill_bundles(content: dict[str, str]) -> Generator[SkillBundle]:
|
||||
"""Generate the skill bundles from the map of raw markdown content."""
|
||||
matcher = partial(fnmatch, pat="skills/*/references/*.md")
|
||||
for slug, paths in get_skill_filemap(content).items():
|
||||
skill = next(iter(p for p in paths if fnmatch(p, "skills/*/SKILL.md")))
|
||||
groups = {k: list(v) for k, v in groupby(paths, key=matcher)}
|
||||
yield SkillBundle(
|
||||
@classmethod
|
||||
def from_docs(cls, docs: Iterable[MarkdownDocument]) -> tuple[Self, ...]:
|
||||
return tuple(starmap(cls.from_paths, group_skill_paths(docs).items()))
|
||||
|
||||
@classmethod
|
||||
def from_paths(cls, slug: str, paths: set[MarkdownDocument]) -> Self:
|
||||
skill = next(iter(p for p in paths if p.relpath.name == "SKILL.md"))
|
||||
groups = {
|
||||
k: tuple(v)
|
||||
for k, v in groupby(
|
||||
paths,
|
||||
key=lambda p: fnmatch(p.relpath.as_posix(), f"skills/{slug}/references/*.md"),
|
||||
)
|
||||
}
|
||||
references = groups.get(True, ())
|
||||
other = tuple(p for p in groups.get(False, ()) if p != skill)
|
||||
return cls(
|
||||
slug=slug,
|
||||
skill=skill,
|
||||
references=list(groups.get(True, [])),
|
||||
other=[f for f in groups.get(False, []) if f != skill],
|
||||
references=references,
|
||||
other=other,
|
||||
)
|
||||
|
||||
|
||||
def get_all_skill_bundles(content: dict[str, str]) -> list[SkillBundle]:
|
||||
"""Get all skill bundles from the map of raw markdown content."""
|
||||
return list(gen_skill_bundles(content))
|
||||
def group_skill_paths(docs: Iterable[MarkdownDocument]) -> dict[str, set[MarkdownDocument]]:
|
||||
"""Group skills from a list of markdown documents by their skill slug."""
|
||||
s = sorted(
|
||||
filter(lambda d: d.skill_slug is not None, docs),
|
||||
key=lambda d: (d.skill_slug or "", d.relpath.stem),
|
||||
)
|
||||
grouped = groupby(s, key=lambda doc: doc.skill_slug)
|
||||
return {k: set(g) for k, g in grouped if k}
|
||||
|
||||
Reference in New Issue
Block a user