MCPcopy Create free account
hub / github.com/VectifyAI/OpenKB / validate_deck

Function validate_deck

openkb/deck/validator.py:128–197  ·  view source on GitHub ↗

Validate the generated deck at ``deck_dir/index.html``. Args: deck_dir: Directory containing ``index.html``. grammar: Optional skill-declared grammar (typically read from the skill's frontmatter under ``od.deck_grammar``). When ``None``, only skill-agnost

(
    deck_dir: Path,
    grammar: Optional[DeckGrammar] = None,
)

Source from the content-addressed store, hash-verified

126
127
128def validate_deck(
129 deck_dir: Path,
130 grammar: Optional[DeckGrammar] = None,
131) -> ValidationResult:
132 """Validate the generated deck at ``deck_dir/index.html``.
133
134 Args:
135 deck_dir: Directory containing ``index.html``.
136 grammar: Optional skill-declared grammar (typically read from the
137 skill's frontmatter under ``od.deck_grammar``). When ``None``,
138 only skill-agnostic invariants are checked (file present,
139 parses, ≥5 slides, self-contained). When provided, also
140 enforces required/allowed slide kinds.
141
142 Returns a :class:`ValidationResult` with categorised issues. Never
143 raises for structural failures — those become entries in ``errors``.
144 """
145 result = ValidationResult()
146 index = deck_dir / "index.html"
147
148 if not index.is_file():
149 result.errors.append(f"index.html not found at {index}")
150 return result
151
152 size = index.stat().st_size
153 if size > MAX_FILE_BYTES:
154 result.warnings.append(
155 f"index.html is {size / 1024 / 1024:.1f} MB (> {MAX_FILE_BYTES // 1024 // 1024} MB) — "
156 f"likely too many inlined images."
157 )
158
159 text = index.read_text(encoding="utf-8", errors="replace")
160 kind_attr = grammar.get("kind_attr") if grammar else None
161 parser = _DeckParser(kind_attr=kind_attr)
162 try:
163 parser.feed(text)
164 parser.close()
165 except Exception as exc:
166 result.errors.append(f"index.html failed to parse: {exc}")
167 return result
168
169 n = len(parser.slide_kinds)
170
171 # ─── Skill-agnostic checks (always run) ──────────────────────────────────
172 if n < MIN_SLIDES_HARD:
173 result.errors.append(
174 f'deck has {n} slides; need at least {MIN_SLIDES_HARD} <section class="slide"> blocks.'
175 )
176
177 if parser.external_links:
178 result.errors.append(
179 "deck is not self-contained: external references found: "
180 + ", ".join(parser.external_links[:3])
181 + (
182 f", … (+{len(parser.external_links) - 3} more)"
183 if len(parser.external_links) > 3
184 else ""
185 )

Callers 15

test_good_deck_passesFunction · 0.90
test_missing_fileFunction · 0.90
test_too_few_slidesFunction · 0.90
test_missing_coverFunction · 0.90
test_missing_closingFunction · 0.90
test_unknown_data_typeFunction · 0.90
test_external_img_blocksFunction · 0.90

Calls 4

_DeckParserClass · 0.85
_apply_grammar_checksFunction · 0.85
ValidationResultClass · 0.70
getMethod · 0.45

Tested by 15

test_good_deck_passesFunction · 0.72
test_missing_fileFunction · 0.72
test_too_few_slidesFunction · 0.72
test_missing_coverFunction · 0.72
test_missing_closingFunction · 0.72
test_unknown_data_typeFunction · 0.72
test_external_img_blocksFunction · 0.72