Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion api/services/pipecat/service_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,7 @@ def create_llm_service_from_provider(
location: str | None = None,
credentials: str | None = None,
temperature: float | None = None,
max_tokens: int | None = None,
bill_to: str | None = None,
usage_context: str | None = None,
):
Expand Down Expand Up @@ -1000,9 +1001,18 @@ def create_llm_service_from_provider(
)
elif provider == ServiceProviders.GOOGLE.value:
model = _migrate_deprecated_google_model(model)
google_settings_kwargs: dict = {"model": model, "temperature": 0.1}
if max_tokens is not None:
# Give the grader a large explicit output ceiling and cap "thinking"
# so the reasoning budget can't crowd out the answer. Gemini's default
# (4096, shared with dynamic thinking) truncated long QA-grader JSON.
google_settings_kwargs["max_tokens"] = max_tokens
google_settings_kwargs["thinking"] = GoogleLLMService.ThinkingConfig(
thinking_budget=4096
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
)
Comment thread
greptile-apps[bot] marked this conversation as resolved.
Outdated
return DograhGoogleLLMService(
api_key=api_key,
settings=GoogleLLMSettings(model=model, temperature=0.1),
settings=GoogleLLMSettings(**google_settings_kwargs),
)
elif provider == ServiceProviders.GOOGLE_VERTEX.value:
return DograhGoogleVertexLLMService(
Expand Down Expand Up @@ -1282,6 +1292,7 @@ def create_llm_service(
user_config,
correlation_id: str | None = None,
usage_context: str | None = None,
max_tokens: int | None = None,
):
"""Create and return appropriate LLM service based on user configuration."""
provider = user_config.llm.provider
Expand Down Expand Up @@ -1323,6 +1334,7 @@ def create_llm_service(
api_key,
correlation_id=correlation_id,
usage_context=usage_context,
max_tokens=max_tokens,
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
**kwargs,
)

Expand All @@ -1332,6 +1344,7 @@ def create_llm_service_with_model_override(
model_override: str | None,
correlation_id: str | None = None,
usage_context: str | None = None,
max_tokens: int | None = None,
):
"""Create an LLM service with an optional model override.

Expand All @@ -1343,6 +1356,7 @@ def create_llm_service_with_model_override(
user_config,
correlation_id=correlation_id,
usage_context=usage_context,
max_tokens=max_tokens,
)

if user_config.llm is None:
Expand All @@ -1354,4 +1368,5 @@ def create_llm_service_with_model_override(
overridden_config,
correlation_id=correlation_id,
usage_context=usage_context,
max_tokens=max_tokens,
)
6 changes: 6 additions & 0 deletions api/services/workflow/qa/llm_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
from api.services.workflow.dto import QANodeData

QA_USAGE_CONTEXT = "qa_analysis"
# Explicit output ceiling for QA grader inference. Google/Anthropic default to
# 4096 output tokens (shared with dynamic thinking on Gemini), truncating long
# grading JSON. A generous ceiling + bounded thinking lets a full grade complete.
QA_MAX_OUTPUT_TOKENS = 16384


async def create_qa_llm_service(
Expand Down Expand Up @@ -47,6 +51,7 @@ async def create_qa_llm_service(
api_key,
correlation_id=correlation_id,
usage_context=QA_USAGE_CONTEXT,
max_tokens=QA_MAX_OUTPUT_TOKENS,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: max_tokens is threaded unconditionally from the QA path for every provider, but create_llm_service_from_provider only honors it in the GOOGLE branch (service_factory.py ~1005). The GOOGLE_VERTEX and Anthropic branches accept the new parameter and silently ignore it. The comment added next to QA_MAX_OUTPUT_TOKENS explicitly notes that Anthropic also defaults to 4096 output tokens, so an Anthropic (or Vertex) QA grader will still hit the same mid-object truncation that this PR is fixing, while the caller believes a generous ceiling was requested. Consider applying the output ceiling on the Anthropic branch (and Vertex if it shares the same cap) or scoping the QA flag to the provider actually covered, so the fix is not silently ineffective for other providers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At api/services/workflow/qa/llm_config.py, line 54:

<comment>max_tokens is threaded unconditionally from the QA path for every provider, but create_llm_service_from_provider only honors it in the GOOGLE branch (service_factory.py ~1005). The GOOGLE_VERTEX and Anthropic branches accept the new parameter and silently ignore it. The comment added next to QA_MAX_OUTPUT_TOKENS explicitly notes that Anthropic also defaults to 4096 output tokens, so an Anthropic (or Vertex) QA grader will still hit the same mid-object truncation that this PR is fixing, while the caller believes a generous ceiling was requested. Consider applying the output ceiling on the Anthropic branch (and Vertex if it shares the same cap) or scoping the QA flag to the provider actually covered, so the fix is not silently ineffective for other providers.</comment>

<file context>
@@ -47,6 +51,7 @@ async def create_qa_llm_service(
             api_key,
             correlation_id=correlation_id,
             usage_context=QA_USAGE_CONTEXT,
+            max_tokens=QA_MAX_OUTPUT_TOKENS,
             **kwargs,
         )
</file context>

**kwargs,
)
return llm, model
Expand Down Expand Up @@ -75,6 +80,7 @@ async def create_qa_llm_service(
model_override,
correlation_id=correlation_id,
usage_context=QA_USAGE_CONTEXT,
max_tokens=QA_MAX_OUTPUT_TOKENS,
)
return llm, model

Expand Down
Loading