Spaces:
Running
Running
| import logging | |
| from typing import Dict, List | |
| from datetime import datetime | |
| try: | |
| from core.sensitive_data_guard import anonymizer | |
| except ImportError: | |
| try: | |
| from backend.core.sensitive_data_guard import anonymizer | |
| except ImportError: | |
| anonymizer = None | |
| logger = logging.getLogger(__name__) | |
| class DocumentBuilder: | |
| """ | |
| Formatyzer sk\u0142adaj\u0105cy cz\u0119\u015bci dokumentu z GeneratorAgent | |
| w sp\u00f3jny format Markdown gotowy do eksportu docx/pdf. | |
| Przywraca PII stosuj\u0105c Deanonimizator. | |
| """ | |
| def build_markdown( | |
| sections_plan: List[Dict[str, str] | str], | |
| generated_sections: Dict[str, str], | |
| document_type: str, | |
| project_title: str = "", | |
| company_name: str = "", | |
| traceability_data: Dict[str, List[dict]] = None, | |
| ) -> str: | |
| """ | |
| Scala sekcje wed\u0142ug ich oryginalnej kolejno\u015bci ze stanu | |
| i tworzy reprezentacj\u0119 Markdown. | |
| """ | |
| logger.info(f"Scalanie dokumentu: {document_type}") | |
| title = project_title or document_type | |
| md_lines = [f"# {title}", ""] | |
| if company_name: | |
| md_lines += [f"**Wnioskodawca:** {company_name}", ""] | |
| md_lines += [ | |
| f"**Typ dokumentu:** {document_type}", | |
| f"**Data wygenerowania:** {datetime.now().strftime('%d.%m.%Y %H:%M')}", | |
| "", | |
| "---", | |
| "", | |
| ] | |
| for section_def in sections_plan: | |
| section = ( | |
| section_def["title"] if isinstance(section_def, dict) else section_def | |
| ) | |
| content = generated_sections.get( | |
| section, "*(Sekcja nie zosta艂a wygenerowana)*" | |
| ) | |
| md_lines.append(f"## {section}") | |
| md_lines.append(content) | |
| md_lines.append("") # odst臋p | |
| # Za艂膮cznik: 殴r贸d艂a i dokumenty (Traceability) | |
| if traceability_data: | |
| md_lines.append("## Za艂膮cznik: 殴r贸d艂a i dokumenty") | |
| md_lines.append("Poni偶ej znajduje si臋 lista dokument贸w (regulamin贸w, wytycznych), na podstawie kt贸rych sztuczna inteligencja wygenerowa艂a poszczeg贸lne sekcje. Ka偶dy dokument posiada unikalny skr贸t (Hash SHA-256) chroni膮cy przed niezauwa偶alnymi zmianami w przysz艂o艣ci.") | |
| md_lines.append("") | |
| for sec_name, traces in traceability_data.items(): | |
| if traces: | |
| md_lines.append(f"### Sekcja: {sec_name}") | |
| for t in traces: | |
| md_lines.append(f"- **殴r贸d艂o:** {t.get('source', 'Brak')}") | |
| ver_str = t.get('version_id') | |
| vf_str = t.get('valid_from') | |
| vt_str = t.get('valid_to') | |
| if ver_str or vf_str or vt_str: | |
| md_lines.append(f" - **Wersja dokumentu:** {ver_str or 'Nieznana'} (Obowi膮zuje od {vf_str or '-'} do {vt_str or '-'})") | |
| md_lines.append(f" - **Link:** {t.get('url', 'Brak')}") | |
| md_lines.append(f" - **Data pozyskania:** {t.get('date', 'Brak')}") | |
| md_lines.append(f" - **Hash (SHA-256):** `{t.get('hash', 'Brak')}`") | |
| md_lines.append("") | |
| # Stopka AI | |
| md_lines += [ | |
| "---", | |
| "", | |
| "cz\u0119\u015bciowo przy u\u017cyciu modeli j\u0119zykowych (AI). Tre\u015b\u0107 powinna zosta\u0107 " | |
| "zweryfikowana przez uprawnionego doradc\u0119 przed z\u0142o\u017ceniem wniosku. " | |
| "Wydawca nie ponosi odpowiedzialno\u015bci za b\u0142\u0119dy merytoryczne wygenerowanego tekstu.", | |
| "", | |
| ] | |
| full_text = "\n".join(md_lines) | |
| # Deanonimizacja PII (NIP, know-how, etc.) | |
| if anonymizer: | |
| try: | |
| full_text = anonymizer.deanonymize_text(full_text) | |
| except Exception as e: | |
| logger.warning(f"Deanonimizacja nie powiod\u0142a si\u0119: {e}") | |
| return full_text | |