Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions app/services/summarizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@
client = OpenAI(api_key=settings.openai_api_key)


def _to_text(value) -> str:
if value is None:
return ""

if isinstance(value, str):
return value.strip()

if isinstance(value, list):
return "\n".join(text for item in value if (text := _to_text(item)))

if isinstance(value, dict):
return "\n".join(
f"{key}: {text}" for key, val in value.items() if (text := _to_text(val))
)

return str(value)
Comment thread
kimssirr marked this conversation as resolved.


def summarize_notice(title: str, content: str) -> NoticeSummaryData:
settings = get_settings()
prompt = f"""
Expand Down Expand Up @@ -39,9 +57,9 @@ def summarize_notice(title: str, content: str) -> NoticeSummaryData:
payload = json.loads(response_text)

return NoticeSummaryData(
summary=payload["summary"],
target_info=payload.get("target_info"),
schedule_info=payload.get("schedule_info"),
caution_info=payload.get("caution_info"),
summary=_to_text(payload.get("summary")),
target_info=_to_text(payload.get("target_info")),
schedule_info=_to_text(payload.get("schedule_info")),
caution_info=_to_text(payload.get("caution_info")),
generated_model=response.model,
)
41 changes: 41 additions & 0 deletions tests/test_summarizer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import json
from types import SimpleNamespace

from app.services import summarizer


def test_summarize_notice_normalizes_structured_llm_fields(monkeypatch) -> None:
payload = {
"summary": {"핵심": "생활관 소독 안내입니다."},
"target_info": {"소독 대상": "전체 생활관"},
"schedule_info": {"일시": "2026년 5월 8일 10시"},
"caution_info": ["귀중품은 보관해 주세요.", "소독 시간에는 협조 바랍니다."],
}

fake_response = SimpleNamespace(
choices=[
SimpleNamespace(
message=SimpleNamespace(content=json.dumps(payload, ensure_ascii=False))
)
],
model="fake-model",
)
fake_client = SimpleNamespace(
chat=SimpleNamespace(
completions=SimpleNamespace(create=lambda **_kwargs: fake_response)
)
)
monkeypatch.setattr(summarizer, "client", fake_client)

result = summarizer.summarize_notice("소독 안내", "생활관 소독을 진행합니다.")

assert result.summary == "핵심: 생활관 소독 안내입니다."
assert result.target_info == "소독 대상: 전체 생활관"
assert result.schedule_info == "일시: 2026년 5월 8일 10시"
assert result.caution_info == "귀중품은 보관해 주세요.\n소독 시간에는 협조 바랍니다."
assert result.generated_model == "fake-model"


def test_to_text_omits_empty_nested_values() -> None:
assert summarizer._to_text(["A", None, " ", "B"]) == "A\nB"
assert summarizer._to_text({"대상": "전체", "비고": None, "공백": " "}) == "대상: 전체"
Loading