Specialist routing¶
The Router class in src/pipeline/router.py determines which specialist enrichment strategies apply to a given extraction result, plans their execution order, and assigns relevant context items to each specialist.
How routing works¶
The router receives an ExtractionResult and a UserTableSchema. It builds a compact summary of the extraction data — table roles, headers, row counts, sample cell values, context types, context_ids, and content snippets — and sends it to the advanced Gemini model (gemini-3.1-pro-preview) with the ROUTER prompt. Gemini returns a GeminiRoutingResult containing strategies, execution order, context assignments, and reasoning.
def route(self, extraction_result, schema) -> GeminiRoutingResult:
summary = self._build_summary(extraction_result, schema)
result = self.gemini.request(summary, GeminiRoutingResult, model=ModelType.ADVANCED)
return result
The summary includes sample cell values from the first three rows of each main table (up to five columns) and the context_id of each context item. This allows the router to detect patterns like compound references (GL-03/GMT-01) and to assign specific context items to strategies by ID.
The five strategy types¶
Each strategy type maps to a specialist prompt and a specific enrichment approach. The router selects a strategy only when clear evidence exists in the extraction data.
| Strategy | Prompt constant | Task | Evidence required |
|---|---|---|---|
auxiliary_table |
AUXILIARY_TABLE_ENRICHMENT |
Match reference codes to auxiliary table rows | At least one AUXILIARY table with rows |
text_rule |
TEXT_RULE_ENRICHMENT |
Apply general notes, code requirements, and performance specs | Text context with actionable rules or conditional statements |
image_legend |
LEGEND_ENRICHMENT |
Match style codes to legend diagram interpretations | Image context with style codes, operability types, or configurations |
dimension_card |
DIMENSION_ENRICHMENT |
Extract dimensions from item cards and detail drawings | Image context with specific measurements or dimensions |
multi_label |
MULTI_LABEL_ENRICHMENT |
Resolve compound references and shared item cards | Cell values with / or , separators, or image context with multiple type mark labels |
T1: Auxiliary table enrichment¶
The auxiliary table specialist handles cross-referencing between the main schedule and auxiliary reference tables. It matches reference codes (e.g., GL-03, HW-05) from main schedule columns to auxiliary table rows and pulls matching data into the target schema columns. For compound references like GL-03/GMT-01, it resolves the primary component and notes secondaries in Special Notes.
T2: Text rule enrichment¶
The text rule specialist applies document-level rules extracted as text context items. These include IBC code requirements (e.g., "tempered glass within 24 inches of a door"), performance specifications (U-value, STC, SHGC targets), material requirements, and general notes with conditional statements. Results appear primarily in Special Notes.
T3: Legend enrichment¶
The legend specialist matches style codes or type designations from the main schedule to legend diagram interpretations in image context. It fills operability (using constrained enum values for WindowOperabilityType / DoorOperabilityType), glass arrangement configuration, and panel attributes. It supports subtype inheritance — when a row like P1a has no direct legend match, it inherits from the base type P1.
T4: Dimension enrichment¶
The dimension specialist extracts Width, Height, Rough Opening Measurements, Glass Arrangement Configuration, and other dimensional values from item card diagrams and detail drawings in image context. It matches drawings to schedule rows via type marks or labels. Panel layout data (panel heights, types, counts) is extracted into the Glass Arrangement Configuration column rather than Special Notes.
T5: Multi-label enrichment¶
The multi-label specialist handles two patterns:
- Compound cell values — Main schedule cells containing
/or,separating multiple reference codes (e.g.,GL-03/GMT-01). The specialist determines primary vs. secondary components using construction domain knowledge (GL- prefix is typically primary for fenestration). - Shared item cards — A single image context diagram that labels multiple schedule items (e.g.,
W39A-PTHP / W39B-NO PTHP). The specialist maps variant-specific attributes to the correct rows by matching card labels to__row_id__values.
Execution planning¶
The router determines not only which strategies to run but in what order. The GeminiRoutingResult includes three key fields:
strategies— the list of selected strategy typesexecution_order— an ordered list of stages, where each stage is a list of strategies that can safely run in parallel. Strategies in later stages may depend on output from earlier stages.context_assignments— a dict mapping each strategy name to a list ofcontext_idvalues relevant to that strategy
Execution order¶
The router reasons about dependencies between strategies for the specific document. For example:
- If
text_ruleneeds resolved reference values fromauxiliary_tableto apply conditional rules correctly,auxiliary_tableruns in an earlier stage. multi_labelalways runs in the final stage so it can work with fully resolved data.- If no dependencies exist, all strategies (except
multi_label) run in a single parallel stage.
Example with dependencies:
Example without dependencies:
Context assignments¶
The router assigns specific context items to each strategy using their context_id values. Default assignment rules:
| Strategy | Default context assignment |
|---|---|
auxiliary_table |
No context items (reads auxiliary tables only) |
text_rule |
Text context items only (TextContextModel) |
image_legend |
Legend image context items only |
dimension_card |
Item card / elevation drawing image context items |
multi_label |
Same image context items as dimension_card |
A context item can be assigned to multiple strategies if relevant to both. The router overrides defaults when document evidence suggests a different assignment.
Model tier¶
The router uses ModelType.ADVANCED (Gemini Pro). The router's expanded responsibilities — dependency analysis, context assignment, and execution planning — justify the advanced model tier. Specialists are demoted to ModelType.FAST (Gemini Flash) since they receive pre-filtered, pre-assigned payloads.
Monolithic fallback¶
When the router returns an empty strategy list — meaning no specialist has clear supporting evidence — the enricher falls back to the monolithic ENRICHMENT prompt. This single Gemini call receives all tables, context, and schema, and attempts to fill every column from any available source in one pass. Unlike specialist mode, this path does not use FIELD_AUTHORITY_MATRIX resolution across multiple strategy outputs.
Routing decision flow¶
The following diagram shows, via an example run, how the router's output determines the enrichment path.
flowchart TB
ER["ExtractionResult + Schema"] --> ROUTER["Router<br/>(Gemini Pro)"]
ROUTER --> CHECK{strategies<br/>returned?}
CHECK -->|empty| MONO["Monolithic ENRICHMENT<br/>(single Gemini Pro call)"]
MONO --> OUT["list[EnrichedRow]"]
CHECK -->|non-empty| PLAN["Staged execution plan"]
PLAN --> STAGE1["Stage 1: [auxiliary_table]<br/>(Gemini Flash)"]
STAGE1 --> MERGE1["MergeResolver<br/>(all completed outputs)"]
MERGE1 --> STAGE2["Stage 2: [text_rule, image_legend, dimension_card]<br/>(Gemini Flash, concurrent)"]
STAGE2 --> MERGE2["MergeResolver<br/>(all completed outputs)"]
MERGE2 --> STAGE3["Stage 3: [multi_label]<br/>(Gemini Flash)"]
STAGE3 --> MERGE3["MergeResolver"]
MERGE3 --> ADJ["SpecialNotesAdjudicator<br/>(semantic bullets)"]
ADJ --> VALID["Enum validation<br/>(Other: ... fallback)"]
VALID --> OUT
Not every specialist runs on every document. The router only selects strategies with clear evidence, so a typical run activates two to three specialists. The number of stages depends on whether dependencies exist between the selected strategies.