better data models
This commit is contained in:
@@ -1,56 +0,0 @@
|
||||
from pathlib import PurePosixPath
|
||||
from typing import Self
|
||||
|
||||
from .common import StrictFrozenModel
|
||||
|
||||
|
||||
class MarkdownDocumentModel(StrictFrozenModel):
|
||||
"""Normalized markdown document content with path and frontmatter."""
|
||||
|
||||
relpath: str
|
||||
content: str
|
||||
frontmatter: str | None = None
|
||||
skill_slug: str | None = None
|
||||
|
||||
|
||||
class SkillFilesBundleModel(StrictFrozenModel):
|
||||
"""Grouped skill documents partitioned into skill, references, and other files."""
|
||||
|
||||
slug: str
|
||||
skill: MarkdownDocumentModel
|
||||
references: tuple[MarkdownDocumentModel, ...] = ()
|
||||
other: tuple[MarkdownDocumentModel, ...] = ()
|
||||
|
||||
@classmethod
|
||||
def from_parts(
|
||||
cls,
|
||||
*,
|
||||
slug: str,
|
||||
skill: MarkdownDocumentModel,
|
||||
references: tuple[MarkdownDocumentModel, ...] = (),
|
||||
other: tuple[MarkdownDocumentModel, ...] = (),
|
||||
) -> Self:
|
||||
# Ensure deterministic ordering even when the source collection is unordered.
|
||||
references_sorted = tuple(sorted(references, key=lambda doc: doc.relpath))
|
||||
other_sorted = tuple(sorted(other, key=lambda doc: doc.relpath))
|
||||
return cls(
|
||||
slug=slug,
|
||||
skill=skill,
|
||||
references=references_sorted,
|
||||
other=other_sorted,
|
||||
)
|
||||
|
||||
|
||||
def to_markdown_document_model(
|
||||
*,
|
||||
relpath: PurePosixPath,
|
||||
content: str,
|
||||
frontmatter: str | None,
|
||||
skill_slug: str | None,
|
||||
) -> MarkdownDocumentModel:
|
||||
return MarkdownDocumentModel(
|
||||
relpath=relpath.as_posix(),
|
||||
content=content,
|
||||
frontmatter=frontmatter,
|
||||
skill_slug=skill_slug,
|
||||
)
|
||||
@@ -1,8 +1,10 @@
|
||||
import re
|
||||
from collections.abc import Mapping
|
||||
from pathlib import PurePosixPath
|
||||
from typing import Any
|
||||
from typing import Literal
|
||||
|
||||
import yaml
|
||||
from pydantic import Field
|
||||
from pydantic import field_validator
|
||||
|
||||
@@ -100,10 +102,21 @@ class PromptFrontmatter(StrictFrozenModel):
|
||||
return value
|
||||
|
||||
|
||||
class PromptDocumentModel(StrictFrozenModel):
|
||||
"""Structured representation of a prompt markdown document."""
|
||||
class StoredPrompt(StrictFrozenModel):
|
||||
"""Normalized prompt document content with path and frontmatter for storage in the registry."""
|
||||
|
||||
prompt_id: str
|
||||
relpath: str
|
||||
relpath: PurePosixPath
|
||||
content: str
|
||||
frontmatter: PromptFrontmatter
|
||||
frontmatter: PromptFrontmatter | None = None
|
||||
|
||||
@field_validator("frontmatter", mode="before")
|
||||
@classmethod
|
||||
def parse_frontmatter_yaml(cls, value: str | None):
|
||||
if value is None:
|
||||
return None
|
||||
try:
|
||||
data = yaml.safe_load(value)
|
||||
except yaml.YAMLError as e:
|
||||
raise ValueError(f"invalid YAML in frontmatter: {e}") from e
|
||||
return PromptFrontmatter.model_validate(data)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from collections.abc import Mapping
|
||||
from pathlib import PurePosixPath
|
||||
|
||||
import yaml
|
||||
from pydantic import Field
|
||||
from pydantic import field_validator
|
||||
|
||||
@@ -107,19 +108,31 @@ class SkillFrontmatter(StrictFrozenModel):
|
||||
return value
|
||||
|
||||
|
||||
class SkillDocumentModel(StrictFrozenModel):
|
||||
"""Structured representation of a skill markdown document."""
|
||||
|
||||
skill_id: str
|
||||
relpath: PurePosixPath
|
||||
content: str
|
||||
frontmatter: SkillFrontmatter
|
||||
|
||||
|
||||
class SkillReferenceDocumentModel(StrictFrozenModel):
|
||||
class StoredSkillReference(StrictFrozenModel):
|
||||
"""Structured representation of a skill reference markdown document."""
|
||||
|
||||
ref_id: str
|
||||
relpath: PurePosixPath
|
||||
content: str
|
||||
entry: ReferenceEntry
|
||||
|
||||
|
||||
class StoredSkill(StrictFrozenModel):
|
||||
"""Structured representation of a skill markdown document."""
|
||||
|
||||
skill_id: str
|
||||
relpath: PurePosixPath
|
||||
content: str
|
||||
frontmatter: SkillFrontmatter
|
||||
references: dict[str, StoredSkillReference] = Field(default_factory=dict)
|
||||
|
||||
@field_validator("frontmatter", mode="before")
|
||||
@classmethod
|
||||
def parse_frontmatter_yaml(cls, value: str | None):
|
||||
if value is None:
|
||||
return None
|
||||
try:
|
||||
data = yaml.safe_load(value)
|
||||
except yaml.YAMLError as e:
|
||||
raise ValueError(f"invalid YAML in frontmatter: {e}") from e
|
||||
return SkillFrontmatter.model_validate(data)
|
||||
|
||||
Reference in New Issue
Block a user