Conversation
…pi id
building_pzz_check assumed a numeric functional_zone_type_id keyed to the
built-in fz→pzz mapping. A real ПЗЗ layer carries letter indices («Ж-1», «П-1»)
and text names instead, so build_zone_gdf silently dropped every zone (int("Ж-1")
fails) and all buildings came back "нет пересечения с ПЗЗ" — a quiet wrong result.
Add a second zone backend, mirroring the regular pzz_check zone side:
- load_pzz_label_mapping reads the letter-index label schema
(pzz_zone_llm_labels_template.json), keyed by a normalised index.
- normalise_zone_code folds trivial spelling drift (Ж-1 ≈ ж1 ≈ Ж–1) while the
user's verbatim code is preserved for display (zone_code_display).
- build_zone_gdf gains a numeric flag; join_objects_to_zones preserves the key
type (int for urban_api, str for ПЗЗ indices).
- The runner auto-picks the backend from the zone code values, falls back to the
built-in template when no descriptions file is uploaded (not required), and
collects zone codes absent from the mapping (uncovered_zones) plus a
used_default_mapping flag for the chat answer.
Numeric urban_api flow is unchanged (verdicts identical on the 843-zone sample).
Adds building_pzz_zone_suggest_threshold setting (used by the upcoming confirm flow).
…d flow Builds on the letter-index backend: when a real ПЗЗ is checked against the built-in template (no user descriptions), be honest about it and help close the gap, instead of silently emitting no_zone_metadata for unmapped zones. Before the task runs, review_building_zones decides: - proceed — numeric urban_api zones, the user's own descriptions, or the template already covers every zone. Template/overlay-based runs prepend an approximate- classification disclaimer (build_disclaimer) listing any still-uncovered zones. - suggest_upload — many zone indices absent from the template (≥ threshold): stream a terminal message asking to upload proper descriptions (no task run). - confirm — a few absent: one batched LLM call suggests the nearest template zone per uncovered code (by name), streamed for the user to confirm and re-submit via confirmed_zone_map. build_confirmed_overlay turns confirmations into an overlay labels file fed back as the descriptions upload, so «СХ-3» resolves against the confirmed template zone's ВРИ. The zone-review logic, disclaimer, overlay and LLM prompt/parse are pure and unit- tested (tests/test_building_zone_review.py); the SSE endpoint is thin glue over them. Also: - classifier accepts a letter-index label list (not just the fz dict) for the building descriptions upload; - building auto-detect now also picks the zone-name column (powers suggestions); - new confirmed_zone_map form param + zone_review_generator SSE event (status zone_review_required, mirroring detection_failed); - zone_codes_are_numeric / zone_code_display_map moved to _deterministic_pzz so the endpoint and runner share them.
The auto/chat/stream flow opens the LLM client for column detection and, in
building_pzz_check, for the zone-suggestion step. Both caught only OllamaChatError,
so an unreachable model host raised httpx.ConnectError straight through → HTTP 500.
- detect_columns_for_file: catch httpx.HTTPError too; unresolved targets fall back
to heuristic-only ("not found") instead of failing the whole request.
- _run_building_pzz_auto zone-suggest: on LLM failure, degrade to the
"upload your descriptions" (suggest_upload) response naming the uncovered zones,
instead of 500.
Surfaced while testing the two-phase flow against a stack whose LLM host was
temporarily unreachable.
…e examples - frontend-api-guide.md (section H): letter-index vs numeric zone backends, the zone_review SSE event (confirm / suggest_upload), confirmed_zone_map, the approximate-classification disclaimer, threshold, per-zone flow + Scenario 5. - input-files-examples.md (new): worked examples of every input file across all endpoints — parcels, buildings, zones (numeric/letter), descriptions (both schemas), VRI classifier, confirmed_zone_map, and request examples per endpoint.
Add POST /pzz/zone-descriptions/convert: read a tidy zone-description table (one row per zone/VRI/permission) and fold it into the pzz_check label schema, so users can supply PZZ descriptions as spreadsheets. - table_reader: CSV (encoding + delimiter sniff) and XLSX (openpyxl). - convert_zone_table: group by zone, split by permission, dedupe VRI. - detect_columns: LLM-first table column detection (heuristic_first flag) so arbitrary headers map by values, with a heuristic offline backstop. - input-files-examples.md: document the table contract and the endpoint.
Resolve human-written building type/service names to the catalogue by embedding similarity (vectorizer) when they match neither an id nor an alias, before the LLM enum-pick fallback; below-threshold names go to manual review, flagged in the resolution basis. Add embeddings_client, vectorizer_url and building_semantic_* settings. Deterministic id/alias matches never reach the embedder; if it is unreachable the flow degrades to the LLM, then manual review.
Ground the building_pzz_check chat answer with a building-specific system prompt (objects/buildings/services, not parcels). Thread an optional system_prompt_path through the answer generator; parcel modes keep the default prompt.
Key the answer grounding by the result file's Russian attribute names (Kod_podobrannogo_VRI, Podobrannyj_VRI, Verdikt_PZZ...) instead of English field names, and instruct the model to name the attribute when citing its value and to take the VRI code and name strictly from the provided data.
…xt building types - frontend-api-guide.md: new POST /pzz/zone-descriptions/convert section (request, response, frontend flow) and updated building_pzz_check resolution to the id/alias/embedder/LLM/manual ladder. - input-files-examples.md: buildings (S2) note that type/service can be free human text, resolved by the embedder with a basis flag.
Format staged Python with Black on every commit via a pre-commit hook (Black runs in pre-commit's isolated env, so no reliance on the active venv). line-length 88 matches the codebase (vast majority of lines already fit). Setup per clone: pip install -r requirements-dev.txt && pre-commit install.
Mechanical reformat only (Black 26.5.1, line-length 88); no logic changes. Vendored pipeline_modules/ is excluded via [tool.black] extend-exclude. See .git-blame-ignore-revs to keep git blame clean.
Add .git-blame-ignore-revs pointing at the style commit so line authorship survives the reformat. Enable locally: git config blame.ignoreRevsFile .git-blame-ignore-revs (GitHub uses it automatically).
In building_pzz_check, a pzz_descriptions_file with a .csv/.xlsx name is converted to the label JSON up front (read_table + LLM column detect + convert_zone_table), so the frontend can drop a spreadsheet without a separate /convert call. What was recognised (zones/VRI + warnings) is prepended to the leading narrative chunk; an unresolvable required column yields a terminal detection_failed. JSON descriptions pass through unchanged. /convert stays for verify-before-run.
…hat/stream Note that pzz_descriptions_file accepts a table directly (converted inline, recognised columns announced in the leading chunk), and when to use that vs the /convert preview.
…zz_check Symmetry with the building descriptions flow: pzz_descriptions_file (building) and pzz_zone_vri_labels_file (pzz_check) are the same labels slot (task field pzz_zone_vri_labels_path, same default template). So a .csv/.xlsx labels file for pzz_check is now converted to the label JSON up front too, via the shared _convert_descriptions_if_table helper, with the recognised columns announced in the leading narrative chunk and a terminal detection_failed on an unresolvable required column.
…before definition The inline-conversion note now lists which table columns were matched to which role (код зоны — «Zone», тип разрешения — «Code», …) and spells out «правила землепользования и застройки» / «виды разрешённого использования» in full, since this leading narrative precedes the model's «ВРИ — …; ПЗЗ — …» definition line. Same for the table read/convert error messages and the converter's ВРИ warnings.
… name The result attribute «Название фактической зоны нахождения кадастра» (and the answer's per-zone breakdown) now resolves the zone name as: description zone_name → zones-layer name column → code. So when the uploaded zones layer names its zones but the descriptions don't, a reader sees «Зона жилой застройки» instead of «Ж-1». Numeric backends keep the existing nickname.
Feat/building pzz letter index
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.