feat(domain): add category descriptions - #225
Conversation
There was a problem hiding this comment.
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify review — findings
Adds a description property to Category returning human-readable text for each enum member, and wires the install-category command's argument help to list every category with its description via _category_help() instead of the hardcoded "(e.g. coding)" hint.
No blocking issues surfaced.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 397 functions depend on the 99 functions this change touches.
Health — this change adds coupling hotspots:
- new:
load_settings()— 14 callers, 6 callees - new:
_manager()— 21 callers, 3 callees - new:
test_composite_versions_and_resolve_delegate()— 0 callers, 7 callees - new:
test_huggingface_specs_carry_provenance()— 0 callers, 7 callees - new:
test_cli_console_helpers()— 0 callers, 6 callees
Verification — 397 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 385 function(s) in the blast radius were not formally verified this run
· 5 more finding(s) on lines outside this diff (see the check run).
| output = " ".join(result.output.replace("│", " ").split()) | ||
|
|
||
| assert result.exit_code == 0 | ||
| for category in Category: |
Code Review SuggestionsNice, focused change — the existing enum values and serialization are untouched, and the CLI test normalising Rich's box-drawing characters is a sensible workaround. One design issue to fix before merge, plus a few smaller points. Important1. The dict-lookup approach silently becomes a runtime crash the moment anyone adds a new @property
def description(self) -> str:
return {
Category.CHAT: "...",
...
}[self] # ← KeyError if a new member is addedSince The class Category(str, Enum):
def __new__(cls, value: str, description: str = "") -> "Category":
obj = str.__new__(cls, value)
obj._value_ = value
obj._description = description
return obj
@property
def description(self) -> str:
return self._description
CHAT = ("chat", "General-purpose conversational models")
CODING = ("coding", "Models optimized for code generation and completion")
EMBEDDING = ("embedding", "Models that convert text into vector representations")
VISION = ("vision", "Models that understand images and text")
REASONING = ("reasoning", "Models optimized for multi-step reasoning")
INSTRUCT = ("instruct", "Models tuned to follow instructions")
The 2. Dict rebuilt on every The current implementation recreates the dict on each property access. For 6 categories iterated in _DESCRIPTIONS: dict["Category", str] = {
Category.CHAT: "General-purpose conversational models",
...
}
@property
def description(self) -> str:
return self._DESCRIPTIONS[self]Minor3. The function is only ever called once, at import time (as a default-argument value). A named constant is clearer about its immutability: _CATEGORY_HELP: str = "Category name. Available: " + "; ".join(
f"{item.value} ({item.description})" for item in Category
)
def install_category_cmd(
category: str = typer.Argument(..., help=_CATEGORY_HELP),
...4. The test copies the description strings verbatim from the implementation. That's fine as a regression/pinning test, but a comment explaining the intent would help future contributors understand why the strings are duplicated rather than derived: def test_category_descriptions() -> None:
# Pin exact wording so accidental rewording is caught in CI.
expected = { ... }Strengths
|
There was a problem hiding this comment.
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify review — findings
Adds a human-readable description to each Category member via a custom __new__ that carries (value, description) tuples, and derives the install-category argument help text from those descriptions instead of a hardcoded example. New tests pin the exact wording of each category description and assert the install-category --help output lists every category's value and description.
No blocking issues surfaced. 2 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 398 functions depend on the 100 functions this change touches.
Health — this change adds coupling hotspots:
- new:
load_settings()— 14 callers, 6 callees - new:
_manager()— 21 callers, 3 callees - new:
test_composite_versions_and_resolve_delegate()— 0 callers, 7 callees - new:
test_huggingface_specs_carry_provenance()— 0 callers, 7 callees - new:
test_cli_console_helpers()— 0 callers, 6 callees
Verification — 398 functions in the blast radius were not formally verified this run (proofs are advisory here).
Health delta baseline: last indexed commit 12a87e2 (diverged from this PR's base — delta is approximate).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 386 function(s) in the blast radius were not formally verified this run
· 5 more finding(s) on lines outside this diff (see the check run).
What changed
descriptionproperty to eachCategory.install-category --help.The existing enum values and serialization behavior are unchanged.
Tests
ruff check src testsruff format --check src testsmypy srcbandit -q -r srcpytest -q --cov=modeldock --cov-report=termResult: 589 passed, 2 skipped because Ollama was not running, 87% coverage.
pre-commit run --all-filesstill reports the same existing notebook Ruff errors and isolated-hook mypy errors found on cleanmain; this change adds no new failures.Closes #103