fix: refine web search handling in LLM client and presentation outline generation

- Updated LLMClient to include CODEX in web search checks.
- Simplified web search logic in generate_ppt_outline to improve clarity and efficiency.
- Ensured consistent usage of web search settings across methods.
This commit is contained in:
sudipnext 2026-04-16 20:11:25 +05:45
parent 8b22f2b142
commit 040c619889
4 changed files with 24 additions and 12 deletions

View file

@ -109,20 +109,24 @@ class LLMClient:
"""
if not web_search:
return False
if self.llm_provider in (LLMProvider.OLLAMA, LLMProvider.CUSTOM):
if self.llm_provider in (
LLMProvider.OLLAMA,
LLMProvider.CUSTOM,
LLMProvider.CODEX,
):
return False
return True
def outline_uses_prefetched_web_facts(self, web_search: bool) -> bool:
"""Chat Completions + json_schema rarely invoke custom function tools.
For OpenAI and Codex we prefetch via the Responses API (``web_search_preview``)
For OpenAI we can prefetch via the Responses API (``web_search_preview``)
and attach the result as context so Advanced settings **Web search** still
grounds outlines without relying on ``SearchWebTool`` in the same call.
"""
if not self.web_search_enabled_for_request(web_search):
return False
return self.llm_provider in (LLMProvider.OPENAI, LLMProvider.CODEX)
return self.llm_provider == LLMProvider.OPENAI
async def prefetch_outline_web_facts(
self,

View file

@ -196,6 +196,7 @@ async def generate_ppt_outline(
)
client = LLMClient()
web_search_enabled = client.web_search_enabled_for_request(web_search)
merged_context = additional_context
if client.outline_uses_prefetched_web_facts(web_search):
@ -207,9 +208,8 @@ async def generate_ppt_outline(
else f"## Web research (current sources)\n{facts}"
)
use_search_tool = (
client.web_search_enabled_for_request(web_search)
and not client.outline_uses_prefetched_web_facts(web_search)
use_search_tool = web_search_enabled and not client.outline_uses_prefetched_web_facts(
web_search
)
try:
@ -225,7 +225,7 @@ async def generate_ppt_outline(
instructions,
include_title_slide,
include_table_of_contents,
web_search=bool(web_search),
web_search=web_search_enabled,
),
response_model.model_json_schema(),
strict=True,

View file

@ -91,6 +91,7 @@ class LLMClient:
if (
self.llm_provider == LLMProvider.OLLAMA
or self.llm_provider == LLMProvider.CUSTOM
or self.llm_provider == LLMProvider.CODEX
):
return False
return parse_bool_or_none(get_web_grounding_env()) or False

View file

@ -1,6 +1,7 @@
from datetime import datetime
from typing import Optional
from enums.llm_provider import LLMProvider
from models.llm_message import LLMSystemMessage, LLMUserMessage
from models.llm_tools import SearchWebTool
from services.llm_client import LLMClient
@ -97,6 +98,16 @@ async def generate_ppt_outline(
response_model = get_presentation_outline_model_with_n_slides(n_slides)
client = LLMClient()
providers_with_search_tool = {
LLMProvider.OPENAI,
LLMProvider.ANTHROPIC,
LLMProvider.GOOGLE,
}
use_search_tool = (
web_search
and client.enable_web_grounding()
and client.llm_provider in providers_with_search_tool
)
try:
async for chunk in client.stream_structured(
@ -113,11 +124,7 @@ async def generate_ppt_outline(
),
response_model.model_json_schema(),
strict=True,
tools=(
[SearchWebTool]
if (client.enable_web_grounding() and web_search)
else None
),
tools=([SearchWebTool] if use_search_tool else None),
):
yield chunk
except Exception as e: