"""Formatting utilities for pipeline outputs with agent support."""fromtypingimportListfromtextwrapimportdedentfromshared.llmimportget_agent_modelfrom.modelsimportPipelineOutput,TelegramSummaryfromshared.loggingimportget_loggerlogger=get_logger(__name__)def_get_formatter():"""Lazy initialization of the formatter agent."""fromagentsimportAgentreturnAgent(name="Telegram Formatter",model=get_agent_model(),instructions=dedent(""" Format a set of analyzed papers into short Telegram HTML. Keep it compact. Output JSON with a single field `html` containing the final HTML. """),output_type=TelegramSummary,)def_fallback_format(output:PipelineOutput)->str:"""Local compact HTML formatter used when the agent is not available. :param output: Full pipeline output to format. :returns: Telegram-friendly HTML string. """logger.debug(f"Fallback formatting: items={len(output.analyzed)} queries={len(output.generated_queries)}")lines:List[str]=[]lines.append("<b>Research pipeline results</b>\n")lines.append(f"<b>Task:</b> {output.task.query}\n")ifoutput.generated_queries:lines.append("<b>Queries:</b> "+", ".join(output.generated_queries[:5])+"\n\n")forresinoutput.analyzed[:10]:title=res.candidate.titlelink=res.candidate.abs_urlorres.candidate.pdf_urlor""lines.append(f"📄 <b>{title}</b>")lines.append(f"Relevance: {res.relevance:.1f}%")ifres.summary:lines.append(res.summary.strip())iflink:lines.append(f'🔗 <a href="{link}">Link</a>')lines.append("")return"\n".join(lines).strip()
[docs]asyncdefto_telegram_html_agent(output:PipelineOutput)->str:"""Agent-based formatter; falls back to local template on failure. :param output: Full pipeline output to format. :returns: Telegram-friendly HTML string. """try:logger=get_logger(__name__)# Prepare compact JSON-like context to keep tokens lowitems=[]forresinoutput.analyzed[:10]:items.append({"title":res.candidate.title,"url":res.candidate.abs_urlorres.candidate.pdf_urlor"","relevance":res.relevance,"summary":res.summary,})importjsonprompt=json.dumps({"task":output.task.query,"queries":output.generated_queries[:5],"items":items,})logger.debug("Calling formatter agent")fromagentsimportRunnerrun_result=awaitRunner.run(_get_formatter(),prompt)out=getattr(run_result,"parsed",None)ifoutandout.html:logger.info("Formatter agent produced HTML output")returnout.htmlexceptException:passreturn_fallback_format(output)
[docs]defto_telegram_html(output:PipelineOutput)->str:"""Synchronous facade using the fallback to avoid event loop requirements. :param output: Full pipeline output to format. :returns: Telegram-friendly HTML string. """return_fallback_format(output)