qfa.services.summarize#

Summarisation use cases — one aggregate summary, or one per record.

SummarizeService owns the two summarisation use cases extracted from Orchestrator (issue #264, epic #112): summarize_bulk behind POST /v1/summarize-bulk and summarize behind POST /v1/summarize. They are the clearest natural pair in the old god-class — both are a single generation call followed by a free-text judge call, differing only in bulk vs. single-record shape — so their prompts and hyperlinking conventions now sit together in one file a reader can hold in their head.

Per ADR-017 this is a plain class with no base class: the shared LLM-call scaffolding arrives as an injected LLMCallExecutor collaborator, and inheritance in this codebase means port↔adapter conformance and nothing else. The constructor names exactly the dependencies these two use cases need — no embedder, no analyze settings, no token ceiling (neither path runs the pre-flight budget guard).

Two module-level helpers these methods use are deliberately not defined here: hyperlink_form_references (also used by analyze_bulk and the hierarchical reduce) and JUDGE_USER_MESSAGE (also used by the analyse and hierarchical leaf judges). They live in qfa.services.record_links and qfa.services.prompts respectively, shared with their other users.

Classes

SummarizeService(llm, anonymizer, executor)

Summarisation use cases: one aggregate summary, or one per record.

class qfa.services.summarize.SummarizeService(llm: LLMPort, anonymizer: AnonymizationPort, executor: LLMCallExecutor, judge_llm: LLMPort | None = None)[source]#

Bases: object

Summarisation use cases: one aggregate summary, or one per record.

Both methods issue two LLM calls — the summary itself on llm, then a free-text judge call on judge_llm whose bare-float output becomes quality_score.

Parameters:
  • llm (LLMPort) – The LLM provider adapter used for the summary generation calls.

  • anonymizer (AnonymizationPort) – The anonymisation adapter used to redact PII before the LLM calls and to restore it in the result.

  • executor (LLMCallExecutor) – The shared LLM-call scaffolding (ADR-017): an injected collaborator, never a base class. These two use cases consult it for the deadline→timeout derivation; the composition root (qfa.api.composition.build_services()) hands over the same instance every other service holds.

  • judge_llm (LLMPort | None) – Optional separate adapter for the LLM-as-judge quality-score calls, so the model that writes a summary does not grade it. None (the default) routes judge calls to llm, which is the behaviour when no JUDGE_LLM_MODEL is configured. Configured via JUDGE_LLM_* and resolved in qfa.api.composition.resolve_judge_llm_settings().

async summarize_bulk(request: SummaryRequestModel, deadline: datetime) AggregateSummaryResultModel[source]#

Summarize multiple feedback records as a single aggregate summary.

Parameters:
  • request (SummaryRequest) – The summarization request containing feedback records and options.

  • deadline (datetime) – Absolute UTC deadline by which summarization must complete.

Returns:

A single aggregate summary with themes ordered by frequency.

Return type:

AggregateSummaryResult

async summarize(request: SingleSummaryRequestModel, deadline: datetime) FeedbackRecordSummaryModel[source]#

Summarize a single feedback record.

Parameters:
  • request (SingleSummaryRequestModel) – The summarization request containing a single feedback record.

  • deadline (datetime) – Absolute UTC deadline by which summarization must complete.

Returns:

The summary title and content for the feedback record.

Return type:

FeedbackRecordSummaryModel

Raises:

AnalysisError – When the LLM returns invalid output or another non-recoverable error occurs.

Notes

The output language is auto-detected from the record’s own content and pinned in the system message — there is no request field for it (#294).