From 9ba0346935c612a2e6f7d5ee7247bb6cdb2d1e9a Mon Sep 17 00:00:00 2001 From: sauravniraula Date: Wed, 20 Aug 2025 20:45:45 +0545 Subject: [PATCH 1/3] fix(fastapi): adds checks for none parts for google structured, chore: removes fastmcp logs --- servers/fastapi/api/v1/ppt/endpoints/presentation.py | 10 +++++----- servers/fastapi/services/llm_client.py | 6 +++++- start.js | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/servers/fastapi/api/v1/ppt/endpoints/presentation.py b/servers/fastapi/api/v1/ppt/endpoints/presentation.py index d3e6dc65..0c0f4565 100644 --- a/servers/fastapi/api/v1/ppt/endpoints/presentation.py +++ b/servers/fastapi/api/v1/ppt/endpoints/presentation.py @@ -141,6 +141,8 @@ async def prepare_presentation( if not presentation: raise HTTPException(status_code=404, detail="Presentation not found") + presentation_outline_model = PresentationOutlineModel(slides=outlines) + total_slide_layouts = len(layout.slides) total_outlines = len(outlines) @@ -149,7 +151,7 @@ async def prepare_presentation( else: presentation_structure: PresentationStructureModel = ( await generate_presentation_structure( - presentation_outline=presentation.get_presentation_outline(), + presentation_outline=presentation_outline_model, presentation_layout=layout, ) ) @@ -164,9 +166,7 @@ async def prepare_presentation( presentation_structure.slides[index] = random_slide_index sql_session.add(presentation) - presentation.outlines = PresentationOutlineModel(slides=outlines).model_dump( - mode="json" - ) + presentation.outlines = presentation_outline_model.model_dump(mode="json") presentation.title = title or presentation.title presentation.set_layout(layout) presentation.set_structure(presentation_structure) @@ -338,7 +338,7 @@ async def generate_presentation_api( detail="Failed to generate presentation outlines. Please try again.", ) presentation_outlines = PresentationOutlineModel(**presentation_outlines_json) - outlines = presentation_outlines.slides[:request.n_slides] + outlines = presentation_outlines.slides[: request.n_slides] total_outlines = len(outlines) print("-" * 40) diff --git a/servers/fastapi/services/llm_client.py b/servers/fastapi/services/llm_client.py index 487300ef..def6a9d5 100644 --- a/servers/fastapi/services/llm_client.py +++ b/servers/fastapi/services/llm_client.py @@ -1328,7 +1328,11 @@ class LLMClient: max_output_tokens=max_tokens, ), ): - if not (event.candidates and event.candidates[0].content): + if not ( + event.candidates + and event.candidates[0].content + and event.candidates[0].content.parts + ): continue generated_contents.append(event.candidates[0].content) diff --git a/start.js b/start.js index 86e56d79..c71fead0 100644 --- a/start.js +++ b/start.js @@ -113,7 +113,7 @@ const startServers = async () => { ], { cwd: fastapiDir, - stdio: "inherit", + stdio: "ignore", env: process.env, }, ); @@ -151,7 +151,7 @@ const startServers = async () => { console.error("Ollama process failed to start:", err); }); - + // Keep the Node process alive until both servers exit const exitCode = await Promise.race([ From 4156933c9bda83adea2d3b4becdfc731ea15e4dc Mon Sep 17 00:00:00 2001 From: sauravniraula Date: Wed, 20 Aug 2025 20:46:49 +0545 Subject: [PATCH 2/3] fix(fastapi): adds missing parts check in unstructured google stream --- servers/fastapi/services/llm_client.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/servers/fastapi/services/llm_client.py b/servers/fastapi/services/llm_client.py index def6a9d5..3bc9399c 100644 --- a/servers/fastapi/services/llm_client.py +++ b/servers/fastapi/services/llm_client.py @@ -950,7 +950,11 @@ class LLMClient: max_output_tokens=max_tokens, ), ): - if not (event.candidates and event.candidates[0].content): + if not ( + event.candidates + and event.candidates[0].content + and event.candidates[0].content.parts + ): continue generated_contents.append(event.candidates[0].content) From 1299d37e5927ecf3c1a99a5ae72e85a86fedf1d7 Mon Sep 17 00:00:00 2001 From: sauravniraula Date: Wed, 20 Aug 2025 21:29:48 +0545 Subject: [PATCH 3/3] fix(fastapi): improves llm client for structured output --- servers/fastapi/services/llm_client.py | 4 ++-- .../fastapi/utils/llm_calls/generate_presentation_outlines.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/servers/fastapi/services/llm_client.py b/servers/fastapi/services/llm_client.py index 3bc9399c..6fb8ec4e 100644 --- a/servers/fastapi/services/llm_client.py +++ b/servers/fastapi/services/llm_client.py @@ -1203,7 +1203,7 @@ class LLMClient: continue content_chunk = event.choices[0].delta.content - if content_chunk: + if content_chunk and not use_tool_calls_for_structured_output: yield content_chunk tool_call_chunk = event.choices[0].delta.tool_calls @@ -1342,7 +1342,7 @@ class LLMClient: generated_contents.append(event.candidates[0].content) for each_part in event.candidates[0].content.parts: - if each_part.text: + if each_part.text and not google_tools: yield each_part.text if each_part.function_call: diff --git a/servers/fastapi/utils/llm_calls/generate_presentation_outlines.py b/servers/fastapi/utils/llm_calls/generate_presentation_outlines.py index 8abb3c64..9f330a3c 100644 --- a/servers/fastapi/utils/llm_calls/generate_presentation_outlines.py +++ b/servers/fastapi/utils/llm_calls/generate_presentation_outlines.py @@ -9,6 +9,8 @@ from utils.llm_provider import get_model system_prompt = """ You are an expert presentation creator. Generate structured presentations based on user requirements and format them according to the specified JSON schema with markdown content. + Try to use available tools for better results. + - Provide content for each slide in markdown format. - Make sure that flow of the presentation is logical and consistent. - Place greater emphasis on numerical data.