Spaces:
Sleeping
Sleeping
| """Render practical answer drafts from source-backed retrieval contracts.""" | |
| from __future__ import annotations | |
| from typing import Any | |
| def _as_list(value: Any) -> list[Any]: | |
| return value if isinstance(value, list) else [] | |
| def _first_text(*values: Any) -> str: | |
| for value in values: | |
| text = str(value or "").strip() | |
| if text: | |
| return text | |
| return "" | |
| def _status_label(status: str) -> str: | |
| if status == "covered": | |
| return "κ·Όκ±° νμΈ" | |
| if status == "missing": | |
| return "μΆκ° νμΈ νμ" | |
| return "μν λ―ΈνμΈ" | |
| def _markdown_link(label: str, url: str | None) -> str: | |
| if url and str(url).startswith("https://www.kcsc.re.kr/"): | |
| return f"[{label}]({url})" | |
| return label | |
| def _numbered(items: list[str], *, empty: str) -> list[str]: | |
| if not items: | |
| return [f"- {empty}"] | |
| return [f"{index}. {item}" for index, item in enumerate(items, start=1)] | |
| def _bullets(items: list[str], *, empty: str) -> list[str]: | |
| if not items: | |
| return [f"- {empty}"] | |
| return [f"- {item}" for item in items] | |
| def build_practical_answer_sections(query: str, draft: dict[str, Any]) -> dict[str, Any]: | |
| """Build stable user-facing sections from a response draft. | |
| This intentionally does not infer new technical conclusions. It only | |
| restructures the concept contract and retrieved evidence into a readable | |
| answer shape. | |
| """ | |
| outline = draft.get("answer_outline") or {} | |
| abstention = draft.get("abstention") or {} | |
| should_abstain = bool(abstention.get("should_abstain")) | |
| standards = [] | |
| for item in _as_list(draft.get("basis_evidence"))[:8]: | |
| code = _first_text(item.get("code")) | |
| role = _first_text(item.get("role"), item.get("title")) | |
| status = _first_text(item.get("evidence_status"), "unknown") | |
| revision_note = f", {item.get('revision_date')}" if item.get("revision_date") else "" | |
| standards.append({ | |
| "code": code, | |
| "title": _first_text(item.get("title")), | |
| "role": role, | |
| "evidence_status": status, | |
| "status_label": _status_label(status), | |
| "official_url": item.get("official_url"), | |
| "revision_date": item.get("revision_date"), | |
| "link_status": item.get("link_status"), | |
| "line": ( | |
| f"{_markdown_link(code, item.get('official_url'))} - {role} ({_status_label(status)}{revision_note})" | |
| if role | |
| else f"{_markdown_link(code, item.get('official_url'))} ({_status_label(status)}{revision_note})" | |
| ), | |
| }) | |
| evidence = [] | |
| for item in _as_list(draft.get("evidence_summary"))[:5]: | |
| code = _first_text(item.get("code")) | |
| title = _first_text(item.get("title")) | |
| section = _first_text(item.get("section")) | |
| preview = _first_text(item.get("evidence_preview")) | |
| label = " / ".join(part for part in (code, section) if part) | |
| evidence.append({ | |
| "label": label or code or title or "κ²μ κ·Όκ±°", | |
| "title": title, | |
| "preview": preview, | |
| "official_url": item.get("official_url"), | |
| "revision_date": item.get("revision_date"), | |
| "link_status": item.get("link_status"), | |
| }) | |
| required_inputs = [str(item) for item in _as_list(outline.get("required_inputs"))[:8]] | |
| compliance_workflow = [str(item) for item in _as_list(outline.get("compliance_workflow"))[:8]] | |
| cautions = [str(item) for item in _as_list(outline.get("evidence_cautions"))[:4]] | |
| if should_abstain: | |
| summary = "κ²μλ μ‘°ν κ·Όκ±°κ° λΆμ‘±ν΄ μλ λ΅λ³μ 보λ₯ν©λλ€. κΈ°μ€λͺ , μμΉ, μ ν©μ± νλ¨μ μΆκ° κ²μ λλ μλ κ²ν ν νμ ν΄μΌ ν©λλ€." | |
| else: | |
| summary = "κ²μ κ·Όκ±°μ μ€λ¬΄ concept λ§€νμ λ°νμΌλ‘ μμ±ν κΈ°μ€ κ²ν μ΄μμ λλ€. ꡬ쑰 μμ , νμ§ νμ , 보μ κ³΅λ² νμ μ μ± μκΈ°μ μ κ²ν κ° νμν©λλ€." | |
| return { | |
| "query": query, | |
| "summary": summary, | |
| "standard_priority": standards, | |
| "required_inputs": required_inputs, | |
| "compliance_workflow": compliance_workflow, | |
| "evidence_summary": evidence, | |
| "cautions": cautions, | |
| "should_abstain": should_abstain, | |
| "review_required": bool(draft.get("review_required")), | |
| "confidence": draft.get("confidence"), | |
| } | |
| def render_practical_answer_markdown(query: str, draft: dict[str, Any]) -> str: | |
| """Render a concise Markdown answer from the structured draft.""" | |
| sections = build_practical_answer_sections(query, draft) | |
| heading = "κ²ν 보λ₯" if sections["should_abstain"] else "κ²ν μ΄μ" | |
| lines: list[str] = [ | |
| f"**{heading}**", | |
| sections["summary"], | |
| "", | |
| "**κΈ°μ€ μ°μ μμ**", | |
| ] | |
| standard_lines = [item["line"] for item in sections["standard_priority"] if item.get("line")] | |
| lines.extend(_numbered(standard_lines, empty="κ²μ κ·Όκ±°κ° μμ΄ μ°μ μ μ© κΈ°μ€μ νμ νμ§ μμ΅λλ€.")) | |
| lines.extend(["", "**νμ νμΈ μ‘°κ±΄**"]) | |
| lines.extend(_bullets(sections["required_inputs"], empty="νμ₯ 쑰건과 μ€κ³ μ λ ₯κ°μ μΆκ° νμΈν΄μΌ ν©λλ€.")) | |
| lines.extend(["", "**μ€μ 체ν¬λ¦¬μ€νΈ**"]) | |
| lines.extend(_bullets(sections["compliance_workflow"], empty="κ²μλ μ‘°ν κ·Όκ±° ν보 ν 체ν¬λ¦¬μ€νΈλ₯Ό νμ ν©λλ€.")) | |
| lines.extend(["", "**κ·Όκ±° μμ½**"]) | |
| if sections["evidence_summary"]: | |
| for item in sections["evidence_summary"]: | |
| label = _markdown_link(item["label"], item.get("official_url")) | |
| preview = f": {item['preview']}" if item.get("preview") else "" | |
| lines.append(f"- {label}{preview}") | |
| else: | |
| lines.append("- κ²μλ μ‘°ν κ·Όκ±°κ° μμ΅λλ€.") | |
| lines.extend(["", "**μ£Όμ**"]) | |
| caution_lines = sections["cautions"] or [ | |
| "κ²μ traceκ° μλ κΈ°μ€μ μ΅μ’ μμΉλ μ ν©μ± νλ¨μ μ¬μ©νμ§ μμ΅λλ€.", | |
| ] | |
| lines.extend(_bullets(caution_lines, empty="κ²μ traceκ° μλ κΈ°μ€μ μ΅μ’ μμΉλ μ ν©μ± νλ¨μ μ¬μ©νμ§ μμ΅λλ€.")) | |
| return "\n".join(lines) | |