From 7d47ca54be6e6b04a45d54d764f612421f82e2d1 Mon Sep 17 00:00:00 2001 From: Roberto Date: Tue, 12 May 2026 16:40:20 +0200 Subject: [PATCH] feat(api): emit Langfuse generation traces for folder indexer --- app/core/folder_indexer.py | 39 +++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/app/core/folder_indexer.py b/app/core/folder_indexer.py index 4a070db..43af1c5 100644 --- a/app/core/folder_indexer.py +++ b/app/core/folder_indexer.py @@ -12,6 +12,7 @@ from docx import Document as DocxDocument from app.core.langfuse_client import ( compile_prompt, extract_usage, + get_langfuse, get_prompt_or_fallback, ) from app.core.llm import get_llm @@ -55,7 +56,7 @@ async def _llm_vision(messages: list) -> object: return await llm.ainvoke(messages) -async def summarize_image(*, image_b64: str, mime: str) -> IndexResult: +async def summarize_image(*, image_b64: str, mime: str, file_name: str | None = None) -> IndexResult: """Return a compact summary of an image file using vision. Parameters @@ -64,6 +65,8 @@ async def summarize_image(*, image_b64: str, mime: str) -> IndexResult: Base64-encoded image bytes. mime: MIME type of the image, e.g. ``"image/png"``. + file_name: + Optional file name, attached to the Langfuse trace as input metadata. """ template, prompt_obj = get_prompt_or_fallback("folder_file_summary_image", _IMAGE_FALLBACK) messages = [ @@ -73,8 +76,21 @@ async def summarize_image(*, image_b64: str, mime: str) -> IndexResult: {"type": "image_url", "image_url": {"url": f"data:{mime};base64,{image_b64}"}}, ]), ] - response = await _llm_vision(messages) - usage = extract_usage(response) + lf = get_langfuse() + if lf is not None: + with lf.start_as_current_observation( + as_type="generation", + name="folder-summarize-image", + model="gpt-4o-mini", + prompt=prompt_obj, + input={"file_name": file_name, "mime": mime}, + ) as gen: + response = await _llm_vision(messages) + usage = extract_usage(response) + gen.update(output=response.content, usage_details=usage) + else: + response = await _llm_vision(messages) + usage = extract_usage(response) summary = (response.content or "").strip()[:500] return IndexResult(summary=summary, tokens_used=usage.get("total", 0)) @@ -98,8 +114,21 @@ async def summarize_text(*, content: str, ext: str, name: str) -> IndexResult: SystemMessage(content=compiled), HumanMessage(content="Summarise this file."), ] - response = await _llm_text(messages) - usage = extract_usage(response) + lf = get_langfuse() + if lf is not None: + with lf.start_as_current_observation( + as_type="generation", + name="folder-summarize-text", + model="gpt-4o-mini", + prompt=prompt_obj, + input={"file_name": name, "ext": ext, "content_chars": len(truncated)}, + ) as gen: + response = await _llm_text(messages) + usage = extract_usage(response) + gen.update(output=response.content, usage_details=usage) + else: + response = await _llm_text(messages) + usage = extract_usage(response) summary = (response.content or "").strip()[:500] return IndexResult(summary=summary, tokens_used=usage.get("total", 0))