name: centralized-registry description: The single source of truth for models, schemas, pipelines, and stacks. Load when adding/changing/toggling any model, schema, pipeline, or stack. Covers MODEL_REGISTRY (52 entries / 7 families including the 22-entry ocr_vision subset + 6 CLASSICAL_OCR backends + BIEP v2 4-path ensemble), notebooks/_shared/schema.py (5 introspection helpers), deployment-choice.yaml (the enablement file), notebooks/00_control_panel.py (the 5-tab marimo control panel), and the central registry audit via mise run lint:registry. Per the centralized-model-registry + centralized-schema-registry + deployment-control-panel openspec capabilities (post-2026-08-15; §11 OCR/VLM Pipeline added 2026-08-13).
Centralized Registries — Models, Schemas, Pipelines, Stacks
Version: 2026-08-13 | Last Updated: 2026-08-13 (added §11 OCR/VLM Pipeline)
The Cianfhoghlaim platform now has one canonical source of truth for every model, schema, pipeline, and stack. This replaces the ~70 hardcoded model strings + 96 hand-written Pydantic duplicates + 54 nearly-identical CocoIndex Apps + 619 empty placeholder YAMLs that the 2026-08-15 audit found.
1. The 4 canonical artifacts
| Artifact | Path | Purpose |
|:--|:--|:--|
| MODEL_REGISTRY | meaisinfhoghlaim/models/model_registry.py | 52 entries across 7 families (ocr_vision / text_llm / embedder / rerank / image_gen / voice / translation). |
| schema introspection | notebooks/_shared/schema.py | 5 helpers: schema_introspect, schema_introspect_table, schema_introspect_full, list_dlt_sources, list_cocoindex_apps, list_baml_classes. |
| deployment-choice.yaml | repo root | The canonical enablement file. Read/written by the marimo notebook + web UI + CLI. |
| 00_control_panel notebook | notebooks/00_control_panel.py | The 5-tab marimo control panel (Models / Pipelines / Datasets / Stacks / Registry). |
2. MODEL_REGISTRY — the single source for models
The 7 families
| Family | Count | Examples |
|:--|--:|:--|
| ocr_vision | 20 | qwen3-vl-8b, molmo2-8b, gemma-4-26B-A4B, dots-ocr, unstract-api |
| text_llm | 13 | minimax-m3, qwen3.6-27b-mtp, uccix-mistral-24b, claude-sonnet-4-20250514 |
| embedder | 3 | BAAI/bge-m3, BAAI/bge-large-en-v1.5, all-MiniLM-L6-v2 |
| rerank | 3 | jina-reranker-v2-base-multilingual, rerank-v3.5, gte-rerank-v2 |
| image_gen | 5 | local/image/flux2-dev, local/image/z-image-turbo, local/image/qwen-image, local/image/sdxl, local/image/fibo |
| voice | 5 | whisper-large, wav2vec2-irish, chatterbox, aba-tts, ResembleAI/chatterbox |
| translation | 3 | opus-mt, m2m100, nllb |
The 2-axis key API
from meaisinfhoghlaim.models import (
MODEL_REGISTRY, # the registry object
model_for, # resolve a single model key
filter_models, # filter by family (returns list[ModelRegistryEntry])
)
# Resolve a single model
default = model_for("text_llm", "default") # → "minimax-m3"
irish = model_for("text_llm", "irish", language="ga") # → "uccix-mistral-24b"
embed = model_for("embedder", "default") # → "BAAI/bge-m3"
voice = model_for("voice", "tts") # → "chatterbox"
# Filter by family
embedders = filter_models("embedder") # → [3 ModelRegistryEntry entries]
for e in embedders:
print(f"{e.key} ({e.upstream_id}) — {e.role}")
# Direct registry access
entry = MODEL_REGISTRY["minimax-m3"]
print(f"family={entry.family}, role={entry.role}, upstream={entry.upstream_id}")
Adding a new model
To add a new model to the registry, append a ModelRegistryEntry
to the relevant family section in
meaisinfhoghlaim/models/model_registry.py (one of the 7
_xxx_entries() functions):
def _text_llm_entries() -> dict[str, ModelRegistryEntry]:
entries = {
# ... existing entries ...
"my-new-model-v1": ModelRegistryEntry(
key="my-new-model-v1",
family="text_llm",
role="default", # or any free-form role string
display_name="My New Model v1",
unsloth_id=None, # or "unsloth/my-new-model-GGUF" if local
mlx_id=None,
upstream_id="myorg/my-new-model", # canonical HF ID
backend="hf", # or "openai", "google", "anthropic", etc.
available=True,
litellm_alias="my-new-model-alias", # None if not via LiteLLM
env_var="MY_NEW_MODEL_API_KEY",
notes="Used by the X agent (per the audit 2026-08-15).",
),
}
return entries
Then run mise run lint:registry to verify no drift was introduced.
Audit drift
mise run lint:registry # reports 0 hardcoded model strings
mise run lint:registry --strict # exits non-zero if drift detected
The lint walks agents/, baml_src/, notebooks/, web/,
orchestration/, spaces/ and uses AST-aware regex against a tight
family-prefix whitelist. New strings (not in the canonical
MODEL_REGISTRY key set) trip the linter.
List all models
mise run models:list # 52 entries grouped by family
mise run models:count # just the counts (informational)
3. Schema introspection — discover the lakehouse
5 helpers in notebooks/_shared/schema.py:
from notebooks._shared.schema import (
schema_introspect, # every BIEP DuckDB table + column metadata
schema_introspect_table, # the canonical column metadata for any table
schema_introspect_full, # DuckDB + LanceDB + BAML union (control panel Tab 3)
list_dlt_sources, # all 920 @dlt.source + 4900 @dlt.resource functions
list_cocoindex_apps, # all CocoIndex Apps + their LanceDB mount targets
list_baml_classes, # all 838 BAML classes + their parent files
read_deployment_choice, # read deployment-choice.yaml (atomic + fcntl.flock)
write_deployment_choice, # write deployment-choice.yaml (atomic + fcntl.flock)
deployment_choice_path, # canonical path to deployment-choice.yaml
)
Usage
from notebooks._shared.db import connect_md
conn = connect_md()
# 1. Discover the lakehouse schema
rows = schema_introspect_full(conn) # DuckDB + Lance + BAML
print(f"Found {len(rows)} columns across all tables")
# 2. Check what DLT sources are wired
sources = list_dlt_sources()
print(f"Found {len(sources)} DLT sources/resources")
# 3. Check what CocoIndex Apps are loaded
apps = list_cocoindex_apps()
print(f"Found {len(apps)} CocoIndex Apps")
# 4. Check what BAML classes are extracted
classes = list_baml_classes()
print(f"Found {len(classes)} BAML classes")
# 5. Read/write deployment-choice.yaml
state = read_deployment_choice()
state["enabled_models"]["my-new-model-v1"] = True
write_deployment_choice(state)
4. Deployment control panel
Open the 5-tab marimo notebook
mise run notebook:control-panel
# or: marimo edit notebooks/00_control_panel.py
The 5 tabs:
- Models — every MODEL_REGISTRY entry grouped by family. Toggle on/off.
- Pipelines — every DLT source + every CocoIndex App. Toggle on/off.
- Datasets — read-only view of every BIEP DuckDB table + LanceDB mount + BAML class (via
schema_introspect_full). - Stacks — every Docker Compose stack. Toggle on/off.
- Registry — full MODEL_REGISTRY view + drift count.
The deployment-choice.yaml file
The notebook reads/writes deployment-choice.yaml at the repo root:
version: 1
enabled_models:
minimax-m3: true
uccix-mistral-24b: true
qwen3-vl-8b: true
# ... 50+ entries ...
enabled_pipelines:
ireland_jurisdiction_pipeline: true
european_nations_embedding_factory: true
# ... 28 entries ...
enabled_stacks:
litellm: true
langfuse: true
# ... 8 high-priority stacks ...
monitoring:
registry_audit: true
baml_ts_codegen: true
The same file is read/written by the web UI control panel (deferred to issue #143) and the CLI (deferred to issue #146).
5. ADK agent construction (LiteLlm migration)
After the 2026-08-15 drift fix, every ADK agent routes through the
LiteLLM gateway via the canonical litellm_model("minimax") helper:
from agents.adk.litellm_agent import make_litellm_agent, litellm_model
# Option A: Use the make_litellm_agent helper
agent = make_litellm_agent(
name="my_agent",
description="Routes through the KCG minimax LiteLLM gateway.",
model_alias="minimax",
tools=[my_tool],
instruction="...",
)
# Option B: Use litellm_model with LlmAgent directly
from google.adk.agents import LlmAgent
agent = LlmAgent(
name="my_agent",
model=litellm_model("minimax"),
description="...",
)
The 32 hardcoded LlmAgent(model=config.model_name) sites that were
bypassing the registry are now all routed through MODEL_REGISTRY.
6. Dagster JurisdictionAssetsBase
The base class for the 10 per-jurisdiction Dagster asset wrappers.
Lives at orchestration/defs/2_materials/_base/jurisdiction_assets_base.py:
from orchestration.defs.2_materials._base.jurisdiction_assets_base import (
JurisdictionAssetsBase,
IrelandAssets, # the reference implementation
make_jurisdiction_assets, # dynamic factory for one-line rollouts
all_jurisdiction_assets, # list of all 10 AssetsDefinition
)
Each per-jurisdiction file becomes a ~30-LOC subclass instead of the current ~378-LOC. Full rollout saves ~3,300 LOC across 10 files (issue #146).
7. CocoIndex factory pattern
The canonical example: cocoindex/european_nations/_factory.py
collapses 40 nation CocoIndex Apps into one factory. See
cocoindex/AGENTS.md "The factory pattern" section.
7. CocoIndex factory pattern
The canonical example: cocoindex/european_nations/_factory.py
collapses 40 nation CocoIndex Apps into one factory. See
cocoindex/AGENTS.md "The factory pattern" section.
Marimo v14 Helper Modules
The canonical shared notebook helpers are:
notebooks/_shared/marimo_patterns.py— reusable v14 dashboard patterns and CLI/interactive execution helpers.notebooks/_shared/area_shims/biiep_v3_dashboard.py— BIEP v3 dashboard surface and area-specific shims.notebooks/_shared/ragas_gauge.py— RAGAS evaluation gauge rendering.
Use LITELLM_BASE_URL for LLM routing in notebooks and helper modules; do not
introduce hardcoded gateway URLs. The helpers support the 17 BIEP v3 dashboards,
the 7 grouped dashboards, and the consolidated notebooks/sync_health.py
sync-health dashboard.
8. The 3 openspec capabilities
| Spec | One-liner |
|:--|:--|
| centralized-model-registry | The 4 canonical artifacts + the 4 Requirements (registry family coverage, no-hardcode-consumption, model_for() API, lint:registry audit). |
| centralized-schema-registry | BAML is the source of truth + Pydantic + Zod are codegen + 96 Pydantic dupes removed + schema_introspect_full(). |
| deployment-control-panel | The marimo notebook + web UI + CLI for picking models/pipelines/datasets/stacks. |
9. Reference
openspec/changes/archive/2026-08-15-centralized-model-schema-registry-and-deployment-control-panel-v1/(the archived change record)
Pre-commit hook
A pre-commit hook blocks commits that introduce hardcoded model strings:
mise run pre-commit-install # install the hook
mise run pre-commit-run # run on all files manually
git commit --no-verify # skip (rare)
The hook runs mise run lint:registry (which invokes
scripts/registry_audit.py) and fails the commit if any hardcoded
model name/ID is found in agents/, baml_src/, notebooks/,
web/, orchestration/, spaces/, or meaisinfhoghlaim/ that
isn't routed through MODEL_REGISTRY.
openspec/specs/centralized-model-registry/spec.md(4 Requirements)openspec/specs/centralized-schema-registry/spec.md(4 Requirements)openspec/specs/deployment-control-panel/spec.md(5 Requirements)meaisinfhoghlaim/models/model_registry.py:MODEL_REGISTRYnotebooks/_shared/schema.py(5 helpers)notebooks/00_control_panel.py(the 5-tab notebook)scripts/registry_audit.py(the drift detector)agents/adk/litellm_agent.py(the LiteLlm helper)orchestration/defs/2_materials/_base/jurisdiction_assets_base.pycocoindex/european_nations/_factory.py(the factory pattern)deployment-choice.yaml(the canonical enablement file)
10. The 6 follow-up issues
| # | Title | Work | |--:|:--|:--| | #141 | Complete remaining MODEL_REGISTRY migrations (Phase 1.3-1.10 + 1.12-1.19) | 15 remaining model hardcodes | | #142 | Activate BAML TypeScript codegen (baml_client_ts/) | TS codegen via Node @baml/cli | | #143 | Build web UI control panel | 5 TanStack Start routes | | #144 | Pydantic dedup rollout (7 remaining subjects) | ~1320 LOC reduction | | #145 | CocoIndex factory rollout (Irish LC + BI parity) | 14 files → 2 factories | | #146 | Dagster JurisdictionAssetsBase rollout | ~3300 LOC reduction |
11. OCR/VLM Pipeline
The OCR/VLM surface lives under meaisinfhoghlaim/. This
section is the canonical entrypoint for any agent adding,
modifying, or evaluating vision models, OCR backends,
PDF converters, alignment methods, or the BIEP v2 4-path
ensemble.
11.1 The ocr_vision family in MODEL_REGISTRY
The ocr_vision family is a 22-entry subset view of
MODEL_REGISTRY exposed via
MODEL_REGISTRY.filter(family="ocr_vision"). Each entry
groups by role into 4 tiers:
| Tier | Models |
|:--|:--|
| tier1_heavy (≥ 27B params, full-document) | qwen3-vl-30b-a3b, qwen3.6-27b-mtp |
| tier2_medium (8-12B params, page-level) | gemma-4-12B, gemma-4-26B-A4B, glm-4.6v-flash, qwen3-vl-8b, internvl3-8b |
| tier3_light (≤ 4B params, fast inference) | gemma-4-E2B, gemma-4-E4B, qwen3-vl-4b |
| specialist (single-purpose OCR/VLM) | deepseek-ocr-2, olmocr-2-7b-1025, granite-docling-258M, uccix-mistral-24b, uccix-llama-3.1-8b, dots-ocr, paddleocr-vl-1.6, molmo2-4b, molmo2-8b, unstract-api, docling-serve |
| legacy (deprecated, kept for back-compat) | uccix-llama2-13b, llama-3.2-vision-11b |
Resolve via the canonical 2-axis key:
from meaisinfhoghlaim.models import MODEL_REGISTRY
# Pick the M4-Max optimal model
m4_max = MODEL_REGISTRY.resolve("ocr_vision", "tier1_heavy")
# → "qwen3-vl-30b-a3b"
# Pick by language
irish_specialist = MODEL_REGISTRY.filter(family="ocr_vision", role="specialist")
# → 11 entries (deepseek-ocr-2, olmocr-2-7b-1025, ...)
# List all available (non-legacy)
available = MODEL_REGISTRY.filter(family="ocr_vision", available=True)
# → 20 entries (excludes the 2 legacy entries)
11.2 The 6 CLASSICAL_OCR backends
The classical OCR registry (meaisinfhoghlaim/models/registry.py:CLASSICAL_OCR)
holds 6 Docker-backed backends — each runs as a separate
Compose stack at bonneagar/stacks/ocr-classical/<name>/:
| Key | Image | Port | Notes |
|:--|:--|--:|:--|
| docling-serve | docker.io/ds4sd/docling-serve:latest | 5001 | IBM Docling — 258M params, DocTags layout. The "safety net" when VLM extraction fails. |
| paddleocr | docker.io/paddlepaddle/paddleocr:latest | 8888 | PaddlePaddle OCR — multilingual, first-party GGUF. |
| paddleocr-vl | docker.io/paddlepaddle/paddleocr-vl:latest | 8889 | PaddleOCR-VL — vision-language variant for diagrams. |
| tesseract | docker.io/tesseractshadow/tesseract4re:latest | 8880 | Tesseract 4 + LSTM. English/Irish/Latin scripts. |
| pylaia | docker.io/ocrhn/pylaia:latest | 8881 | PyLaia HTR — best for handwritten Irish manuscripts. |
| trocr | docker.io/microsoft/trocr:latest | 8882 | Microsoft TrOCR — transformer-based HTR for printed + handwritten. |
All 6 are wrapped by meaisinfhoghlaim/backends/adapters.py:OCRAdapterRegistry
(the 4th backend protocol) and are reachable via the
select_ocr_backend() helper:
from meaisinfhoghlaim.models.registry import CLASSICAL_OCR, select_ocr_backend
backend = select_ocr_backend(task="handwritten_irish", quality="high")
# → "pylaia" (the optimal choice for handwritten Irish manuscripts)
11.3 The BIEP v2 4-path ensemble (EnsembledExtractor)
The flagship extraction pipeline. Located at
meaisinfhoghlaim/ocr/ensemble/ensembled_extractor.py:EnsembledExtractor.
Runs 4 OCR paths in parallel via asyncio.gather:
| Path | Tool | Input | Output format |
|:--|:--|:--|:--|
| 1. BAML | Docling-serve → text → BAML function | PDF | Typed Pydantic row |
| 2. Unstract | Docling-serve → Unstract workflow → JSON | PDF | Structured JSON |
| 3. qwen3_vl | qwen3-vl-8b page-level image → JSON | Page images | Structured JSON |
| 4. gemma4 | gemma-4-26B-A4B page-level image → JSON | Page images | Structured JSON |
Each path output lands in its own per-jurisdiction DuckLake
table. The RAGAS biiep_extraction_consensus metric then
votes the canonical row.
Webhook emission (post-2026-08-15): on every successful
extraction, the canonical envelope is POSTed to
os.getenv("OCR_WEBHOOK_URL", "") via httpx.AsyncClient
(fire-and-forget). Schema (per
british-isles-education-pipeline-v3 spec delta):
{
"document_id": "<uuid>",
"capability": "<forms|layout|tables+latex|doctags|gaelic|english>",
"backend_used": "<paddleocr|mlx-omni|olmocr|docling-serve|llama-swap|dots-ocr>",
"model": "<model name>",
"result_url": "<s3://lakehouse/ocr/...>",
"duration_ms": <int>,
"trace_id": "<opentelemetry trace id>",
"completed_at": "<iso-8601 utc>"
}
Invocation:
from meaisinfhoghlaim.ocr.ensemble.ensembled_extractor import EnsembledExtractor
extractor = EnsembledExtractor(
document_id="<uuid>",
pdf_path="leabharlann/ncca/lc_mathematics_2024.pdf",
jurisdiction="ireland",
)
result = await extractor.extract()
# `result` is a RAGAS-voted Envelope with the canonical row
11.4 The 7 PDF converters (meaisinfhoghlaim/document_factory/)
Each converter transforms a PDF into markdown/dict/structured
output. All live under
meaisinfhoghlaim/document_factory/converters/:
| Converter | Module | Best for |
|:--|:--|:--|
| docling | docling_converter.py | Layout-aware extraction (DocTags) |
| marker | marker_converter.py | High-quality markdown + figure extraction |
| unstructured | unstructured_converter.py | Partitioning + element classification |
| deepseekocr | deepseekocr_converter.py | Compressed-document specialist (DeepSeek-OCR-2) |
| pymupdf4llm | pymupdf4llm_converter.py | Fast text extraction (PyMuPDF4LLM) |
| curriculum_document | ../curriculum_document.py | Curriculum document representation |
| pdf_factory | ../pdf_factory.py | Orchestrator — picks the right converter per document |
The pdf_factory is the canonical entrypoint — it routes
each PDF to the optimal converter based on document type,
language, and quality requirements.
11.5 The 4 alignment methods + ColPaliAligner
meaisinfhoghlaim/alignment/aligner.py ships 4 methods
for Irish-English cross-lingual alignment:
| Method | Best for | Quality |
|:--|:--|:--|
| VecAlign | Large parallel corpora | High (deep embedding) |
| HunAlign | Medium corpora, sentence-level | Medium (HMM-based) |
| GaoisAlign | Irish terminology alignment | High (Gaois-trained) |
| Hybrid | Production (VecAlign + HunAlign fallback) | Highest |
Plus the ColPaliAligner (colpali_aligner.py) for
manuscript bbox extraction — uses ColPali vision embeddings
to map extracted text back to manuscript page coordinates.
from meaisinfhoghlaim.alignment import aligner
a = aligner.IrishEnglishAligner(method="hybrid")
result = a.align_parallel_texts(
irish=["Tá an lá go hálainn.", "Is maith liom an Ghaeilge."],
english=["The day is beautiful.", "I like Irish."],
)
# → AlignmentResult with per-sentence confidence scores
11.6 The Irish HTR dataset
meaisinfhoghlaim/datasets/irish_htr_dataset.py (25KB) is
the canonical training dataset for Irish handwriting
recognition (HTR). Built from 3 sources:
- NLI manuscripts (National Library of Ireland) — scanned 18th-19th century Irish-language manuscripts
- RIA archives (Royal Irish Academy) — handwritten letters + diaries
- School copybooks — modern (20th century) school copybook scans
The dataset is the training source for the pylaia classical
backend + the uccix-mistral-24b specialist VLM.
11.7 The M4-Max dispatch helper
meaisinfhoghlaim/models/registry.py:select_optimal_for_m4_max()
returns the recommended OCR/VLM model for the M4 Max 64GB
workstation:
from meaisinfhoghlaim.models.registry import select_optimal_for_m4_max
m4_max_model = select_optimal_for_m4_max()
# → "gemma-4-26B-A4B" (the M4-Max optimal choice)
# With a constraint
m4_max_irish = select_optimal_for_m4_max(task="irish_handwritten")
# → "uccix-mistral-24b" (the Irish HTR specialist)
11.8 llama-swap GGUF inference
The local inference path is configured by
meaisinfhoghlaim/models/llama_swap_config.yaml (the
llama-swap GGUF server config). It exposes all 22
VISION_MODELS entries as GGUF endpoints behind a single
OpenAI-compatible API:
# llama_swap_config.yaml — relevant snippet
models:
"qwen3-vl-8b":
name: "Qwen3-VL-8B-Instruct"
gguf: "unsloth/Qwen3-VL-8B-Instruct-GGUF"
cmd: >-
llama-server -m unsloth/Qwen3-VL-8B-Instruct-GGUF/qwen3-vl-8b-instruct-q4_k_m.gguf
--port 8080 --host 0.0.0.0 -ngl 99
The docling-serve classical backend is the safety net —
when llama-swap is unavailable, the adapter falls back
automatically.
11.9 BAML clients_ocr_ensemble.baml patterns
baml_src/clients_ocr_ensemble.baml declares the 3
ensemble clients used by the BIEP v2 4-path pipeline:
| Client | Provider | Used by |
|:--|:--|:--|
| LocalVision | llama-swap | Path 3 (qwen3_vl) + Path 4 (gemma4) |
| ExtractEnStrong | BAML function (calls Path 1) | Path 1 (BAML) |
| UnstractFlow | Unstract API | Path 2 (Unstract) |
Each client references MODEL_REGISTRY (no hardcoded
model strings) and exposes a typed BAML function that
the BIEP v2 pipeline consumes.
11.10 RAGAS-voted chunk emission
The EnsembledExtractor emits RAGAS-voted chunks after
the 4-path consensus. The voting metric is
biiep_extraction_consensus (registered in
scripts/ragas_metrics.py). Each chunk carries:
chunk_id(UUID)document_id(parent PDF)path_votes(4 booleans — which paths agreed)consensus_score(RAGAS score, 0-1)text(the canonical chunk text)bbox(page-level coordinates, from ColPali)
11.11 The meaisinfhoghlaim/ocr/ back-compat shim
The nested meaisinfhoghlaim/ocr/ sub-package exists for
back-compat only. It re-exports VISION_MODELS + the
ensemble with a DeprecationWarning:
# LEGACY — emits DeprecationWarning
from meaisinfhoghlaim.ocr.models.registry import VISION_MODELS
# CANONICAL — no warning
from meaisinfhoghlaim.models.registry import VISION_MODELS
The canonical home for all OCR/VLM models is
meaisinfhoghlaim.models.registry (per the v4 platform
convention: the outer models/ package is canonical).
The meaisinfhoghlaim/ocr/ shim will be removed in v5 of
the registry.
11.12 The image_generation_agent consumer (NEW 2026-08-13)
The image_generation_agent (registered in
agents/agent_registry.py:AGENT_REGISTRY as the 13th main agent,
per Phase L of the
2026-08-13-web-monorepo-consolidation-and-agent-integration-v1 change)
consumes the 5 image_gen MODEL_REGISTRY entries for 2D asset
generation + Babylon.js texture creation.
The agent's 5 tools live at agents/adk/tools/image_generation.py:
| Tool | Purpose | Role |
|:--|:--|:--|
| list_image_models | List the 5 image_gen entries + availability | (inspector) |
| generate_2d_asset | Generate a 2D image (subject illustration, sprite, diagram) | default, fast, bilingual, legacy |
| generate_texture | Generate a Babylon.js PBR texture | diagrams |
| style_match | Generate N style-preserved variants | default |
| cocoindex_register | Register the generated asset in the CocoIndex | (always) |
The BAML client wiring is at baml_src/clients_image_gen.baml with
5 client<llm> blocks (ImageGenDefault + ImageGenFast +
ImageGenBilingual + ImageGenLegacy + ImageGenDiagrams). Each client
routes via model_for('image_gen', role) — never hardcodes a model
string.
The CocoIndex flow is at
cocoindex/media/image_generation_flow.py (R1–R4 conformance +
the canonical bge-m3 embedder + LanceDB target table
cianhoghlaim.media.image_gen_chunks).
11.13 Quick routing — "I want to add X, where do I go?"
| If you want to... | Look at... |
|:--|:--|
| Add a new OCR/VLM model | meaisinfhoghlaim/models/registry.py:VISION_MODELS (or model_registry.py:MODEL_REGISTRY for the 7-family view) |
| Add a new classical OCR backend | meaisinfhoghlaim/models/registry.py:CLASSICAL_OCR + bonneagar/stacks/ocr-classical/<name>/ |
| Add a new image_gen model | meaisinfhoghlaim/models/model_registry.py:MODEL_REGISTRY (family=image_gen) + agents/adk/image_generation_agent.py |
| Add a new image_gen BAML client | baml_src/clients_image_gen.baml + agents/adk/tools/image_generation.py |
| Run the image_gen agent | agents/adk/image_generation_agent.py:image_generation_agent |
| Wire a model into BAML | baml_src/clients_ocr_ensemble.baml (the 3 ensemble clients) |
| Run the 4-path ensemble | meaisinfhoghlaim/ocr/ensemble/ensembled_extractor.py:EnsembledExtractor |
| Add a new PDF converter | meaisinfhoghlaim/document_factory/converters/<name>_converter.py + register in pdf_factory.py |
| Add a new alignment method | meaisinfhoghlaim/alignment/aligner.py:AlignmentMethod (StrEnum) |
| Evaluate a new OCR backend | meaisinfhoghlaim/evaluation/ (the OCR evaluation harness) |
| Train an Irish HTR model | meaisinfhoghlaim/datasets/irish_htr_dataset.py (25KB training data) |
| Configure local inference | meaisinfhoghlaim/models/llama_swap_config.yaml (the llama-swap config) |
| Pick the optimal M4-Max model | select_optimal_for_m4_max() (the dispatch helper) |
11.14 Cross-references
meaisinfhoghlaim/README.md— the deeper sub-package docs (the canonical home for OCR/HTR/Alignment)
12. Firecrawl MCP — the external search surface (NEW 2026-08-14)
Per the 2026-08-14-firecrawl-mcp-ccc-dual-search-v1 change, Firecrawl MCP
is the canonical external search surface (analogous to how ccc is the
internal code search surface and Cognee is the internal docs search
surface). The FirecrawlMCPClient wrapper at
agents/meaisinfhoghlaim/firecrawl_mcp/client.py exposes all 12 MCP tools
with Pydantic validation + Langfuse @observe. The agent routing table
for ccc vs cognee vs firecrawl_search is documented at AGENTS.md
§"Triple-search architecture" and the
dual-search-architecture
spec. The Firecrawl API key lives in Infisical under the
firecrawl-api-key secret (per the .agents/skills/secrets-management/SKILL.md
contract). The agent reference corpus (built by the Phase 4a change)
federates firecrawl_search + Cognee + Graphiti + LanceDB over the
docs_index table.
meaisinfhoghlaim/AGENTS.md— the agent routing for the meaisinfhoghlaim sub-treeopenspec/specs/meaisinfhoghlaim-ocr-htr/spec.md— the 10 OCR backends across the canonical 6openspec/specs/meaisin-24-ocr-models/spec.md— the 24 VISION_MODELS spec (v4 registry)openspec/specs/celtic-language-pipeline/spec.md— the 6 Celtic-language OCR consumer.agents/skills/centralized-registry/SKILL.md— this skill (the canonical model registry).agents/skills/baml/SKILL.md— the BAML extraction pattern.agents/skills/cocoindex/SKILL.md— the CocoIndex v1 embedding layer
Last updated: 2026-08-13 (added §11.12 image_generation_agent consumer row + the 5 image_gen BAML clients + the CocoIndex flow + the 5 tools; updated the routing table with the image_gen entry).
Owner: Build agent.
Expert Next.js App Router
Developpement
Un skill qui transforme Claude en expert Next.js App Router.
Générateur de README
Developpement
Crée des README.md professionnels et complets pour vos projets.
Rédacteur de Documentation API
Developpement
Génère de la documentation API complète au format OpenAPI/Swagger.