Skip to content

Gemini TTS: Default Instructions Parsing - #1086

Open
Prajna1999 wants to merge 5 commits into
mainfrom
enhancement/tts-default-instruction-parsing
Open

Gemini TTS: Default Instructions Parsing#1086
Prajna1999 wants to merge 5 commits into
mainfrom
enhancement/tts-default-instruction-parsing

Conversation

@Prajna1999

@Prajna1999 Prajna1999 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Issue #1054

Summary

  • Before: The flow did not support the <transcript> tag in the TTS block.
  • Now: Improved text-to-speech request formatting by wrapping spoken text in ... tags for more consistent synthesis.
  • Implemented parsing for the new tag in the TTS instruction.
  • Updated existing code to accommodate the new functionality.

Checklist

Before submitting a pull request, please ensure that you mark these task.

  • Ran fastapi run --reload app/main.py or docker compose up in the repository root and test.
  • If you've fixed a bug or added code that is tested and has test cases.

Summary by CodeRabbit

Summary by CodeRabbit

  • Improvements

    • Updated the default text-to-speech model to a newer preview option.
    • Improved text-to-speech request formatting by wrapping spoken text in <transcript>...</transcript> tags for more consistent synthesis.
  • Tests

    • Updated existing TTS assertions and added a new unit test to verify transcript-tagged request payloads are sent correctly for Google-based TTS.

@Prajna1999 Prajna1999 self-assigned this Jul 27, 2026
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The default Gemini TTS model is updated, and Google Vertex AI and AI Studio TTS requests now wrap input text in <transcript> tags. Tests verify the updated payloads.

Changes

Gemini TTS

Layer / File(s) Summary
TTS model and provider payloads
backend/app/models/llm/constants.py, backend/app/services/llm/providers/google_ai.py, backend/app/services/llm/providers/google_aistudio.py
The default TTS model changes to gemini-3.1-flash-tts-preview, and both Google providers send transcript-tagged input to Gemini.
TTS payload assertions
backend/app/tests/services/llm/providers/test_google_aistudio.py, backend/app/tests/services/llm/providers/test_google_ai.py
Tests verify that AI Studio and Vertex AI TTS requests contain the transcript-tagged input.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: vprashrex, ayush8923

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and points to the Gemini TTS parsing change, though it doesn’t mention the model update or transcript tagging explicitly.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch enhancement/tts-default-instruction-parsing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot changed the title feat: add '<transcript>' tag in the tts block feat(tts): Support '<transcript>' tag Jul 27, 2026
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

OpenAPI changes   🟢 1 non-breaking change

Tip

Safe to merge from an API-contract perspective.

Full changelog  ·  1
Method Path Change
🟢 POST /api/v1/llm/chain/sts the model request property default value changed from gemini-2.5-flash-preview-tts to gemini-3.1-flash-tts-preview

main9beb2deb · generated by oasdiff

@Prajna1999 Prajna1999 changed the title feat(tts): Support '<transcript>' tag Gemini TTS: Default Instructions Parsing Jul 27, 2026
@Prajna1999
Prajna1999 marked this pull request as ready for review July 27, 2026 10:37

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
backend/app/services/llm/providers/google_ai.py (1)

521-525: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a Vertex-specific transcript payload assertion.

The AI Studio test covers the new wrapper, but this provider constructs a different contents shape. Add or verify a test_google_ai.py assertion that contents[0]["parts"][0]["text"] equals the <transcript>...</transcript> value.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/services/llm/providers/google_ai.py` around lines 521 - 525, Add
a Vertex-specific assertion in test_google_ai.py for the payload built by the
provider flow around decorate_resolved_input, verifying that
contents[0]["parts"][0]["text"] contains the expected
<transcript>...</transcript> wrapper around resolved_input.
backend/app/tests/services/llm/providers/test_google_aistudio.py (1)

526-526: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the new default model.

The fixture pins gemini-2.5-pro-preview-tts, so this assertion verifies tagging but never exercises DEFAULT_TTS_MODEL. Add a test that omits params["model"] and asserts the request uses gemini-3.1-flash-tts-preview.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/tests/services/llm/providers/test_google_aistudio.py` at line
526, Add coverage near the existing TTS request test for the default-model path:
omit params["model"], invoke the same request flow, and assert the generated
request uses gemini-3.1-flash-tts-preview. Keep the existing explicit-model
tagging assertion unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@backend/app/services/llm/providers/google_ai.py`:
- Around line 521-525: Add a Vertex-specific assertion in test_google_ai.py for
the payload built by the provider flow around decorate_resolved_input, verifying
that contents[0]["parts"][0]["text"] contains the expected
<transcript>...</transcript> wrapper around resolved_input.

In `@backend/app/tests/services/llm/providers/test_google_aistudio.py`:
- Line 526: Add coverage near the existing TTS request test for the
default-model path: omit params["model"], invoke the same request flow, and
assert the generated request uses gemini-3.1-flash-tts-preview. Keep the
existing explicit-model tagging assertion unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 60a5586a-d926-4a6b-8f67-cb7b77ea7573

📥 Commits

Reviewing files that changed from the base of the PR and between e0c64fc and ce56474.

📒 Files selected for processing (4)
  • backend/app/models/llm/constants.py
  • backend/app/services/llm/providers/google_ai.py
  • backend/app/services/llm/providers/google_aistudio.py
  • backend/app/tests/services/llm/providers/test_google_aistudio.py

@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/app/tests/services/llm/providers/test_google_ai.py`:
- Around line 266-275: Add narrow type annotations to the
test_tts_wraps_input_in_transcript_tags method for provider, tts_config, query,
and its None return value, using the concrete types already established by the
fixture definitions or surrounding tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4baede03-8532-4560-a05c-8a5a819df5ca

📥 Commits

Reviewing files that changed from the base of the PR and between ce56474 and 5cca87f.

📒 Files selected for processing (1)
  • backend/app/tests/services/llm/providers/test_google_ai.py

Comment on lines +266 to +275
def test_tts_wraps_input_in_transcript_tags(self, provider, tts_config, query):
with patch(
"app.services.llm.providers.google_ai.requests.post",
return_value=_mock_http_ok(_tts_response()),
) as mock_post:
provider.execute(tts_config, query, "Say this text")

parts = mock_post.call_args.kwargs["json"]["contents"][0]["parts"]
assert parts[0]["text"] == "<transcript>Say this text</transcript>"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add narrow type hints to the test method.

Annotate provider, tts_config, query, and the None return value, for example:

Proposed fix
-    def test_tts_wraps_input_in_transcript_tags(self, provider, tts_config, query):
+    def test_tts_wraps_input_in_transcript_tags(
+        self: TestGoogleVertexAIProvider,
+        provider: GoogleVertexAIProvider,
+        tts_config: NativeCompletionConfig,
+        query: QueryParams,
+    ) -> None:

As per coding guidelines, Python functions must provide narrow type hints for every parameter and return value.

🧰 Tools
🪛 ast-grep (0.44.1)

[info] 266-269: no timeout was given on call to external resource
Context: patch(
"app.services.llm.providers.google_ai.requests.post",
return_value=_mock_http_ok(_tts_response()),
)
Note: [CWE-1088] Synchronous Access of Remote Resource without Timeout.

(requests-timeout)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/tests/services/llm/providers/test_google_ai.py` around lines 266
- 275, Add narrow type annotations to the
test_tts_wraps_input_in_transcript_tags method for provider, tts_config, query,
and its None return value, using the concrete types already established by the
fixture definitions or surrounding tests.

Source: Coding guidelines

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/app/tests/services/llm/providers/test_google_ai.py`:
- Around line 336-340: Update the NativeCompletionConfig fixture in the Google
TTS test to omit the model parameter so _execute_tts exercises DEFAULT_TTS_MODEL
resolution, or set it to gemini-3.1-flash-tts-preview. Keep the existing
provider, completion type, and voice parameters unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: cc9b9ff7-3669-4bc7-a7ba-0618b0299c4b

📥 Commits

Reviewing files that changed from the base of the PR and between 5cca87f and 0bcc9c6.

📒 Files selected for processing (1)
  • backend/app/tests/services/llm/providers/test_google_ai.py

Comment on lines +336 to +340
config = NativeCompletionConfig(
provider="google-native",
type=CompletionType.TTS,
params={"model": "gemini-2.5-flash-preview-tts", "voice": "Kore"},
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
fd -a 'test_google_ai.py|google_ai.py|.*google.*' . | sed 's#^\./##' | head -50

echo "== target lines =="
if [ -f backend/app/tests/services/llm/providers/test_google_ai.py ]; then
  wc -l backend/app/tests/services/llm/providers/test_google_ai.py
  sed -n '310,360p' backend/app/tests/services/llm/providers/test_google_ai.py
fi

echo "== search default model references =="
rg -n "gemini-2\.5-flash-preview-tts|gemini-3\.1-flash-preview-tts|TTS|NativeCompletionConfig|model_defaults|defaults" backend/app -S

Repository: ProjectTech4DevAI/kaapi-backend

Length of output: 50387


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== google provider relevant outline =="
ast-grep outline backend/app/services/llm/providers/google_ai.py --view expanded | sed -n '1,220p'

echo "== google provider defaults/default resolution snippets =="
rg -n -C 4 "DEFAULT|default|execute|model|params\[" backend/app/services/llm/providers/google_ai.py backend/app/services/llm/providers -g '*.py' | rg -C 3 "gemini-3\.1-flash-preview-tts|gemini-2\.5-flash-preview-tts|DEFAULT_|default"

echo "== exact relevant google_ai.py sections =="
wc -l backend/app/services/llm/providers/google_ai.py
sed -n '1,220p' backend/app/services/llm/providers/google_ai.py
sed -n '220,420p' backend/app/services/llm/providers/google_ai.py

echo "== mapper Google TTS default references =="
rg -n -C 4 "gemini-3\.1-flash-preview-tts|gemini-2\.5-flash-preview-tts" backend/app/services backend/app/api backend/app/models backend/app/crud | head -220

Repository: ProjectTech4DevAI/kaapi-backend

Length of output: 34067


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== DEFAULT_TTS_MODEL definition =="
rg -n -C 5 "DEFAULT_TTS_MODEL\s*=" backend/app/models backend/app/services backend/app -g '*.py'

echo "== Google TTS execute section =="
sed -n '474,570p' backend/app/services/llm/providers/google_ai.py

echo "== mapper Google TTS implementation candidates =="
rg -n -C 3 '"gemini-3\.1-flash-preview-tts"|"gemini-2\.5-flash-preview-tts"|DEFAULT_TTS_MODEL|model.*=.*"gemini|TTSLLMParams|google' backend/app/services/llm -g '*.py' | sed -n '1,260p'

echo "== test_TTS wraps fixture config around payload assertion =="
sed -n '310,345p' backend/app/tests/services/llm/providers/test_google_ai.py

Repository: ProjectTech4DevAI/kaapi-backend

Length of output: 31313


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== gemini model refs =="
rg -n --iglob '*.py' --iglob '*.md' --iglob '*.yaml' --iglob '*.yml' "gemini-(3\.1|2\.5)-flash-preview-tts|flash-preview-tts|flash-tts-preview|DEFAULT_TTS_MODEL" backend/app tests 2>/dev/null | head -220

echo "== changed/default TTS model usage in tests =="
python3 - <<'PY'
from pathlib import Path
p = Path('backend/app/tests/services/llm/providers/test_google_ai.py')
text = p.read_text()
for needle in ['params={"model":', 'params.get("model")', 'model = params', 'gemini-2.5-flash-preview-tts', 'gemini-3.1-flash-preview-tts', 'gemini-3.1-flash-tts-preview']:
    print(f'{needle}: {text.count(needle)}')
PY

Repository: ProjectTech4DevAI/kaapi-backend

Length of output: 3516


Exercise the updated TTS model default.

GoogleVertexAIProvider._execute_tts uses params.get("model") or DEFAULT_TTS_MODEL. Since DEFAULT_TTS_MODEL is gemini-3.1-flash-tts-preview, this fixture should either use the new model or omit model so default resolution is covered instead of hardcoding an old model variant.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/tests/services/llm/providers/test_google_ai.py` around lines 336
- 340, Update the NativeCompletionConfig fixture in the Google TTS test to omit
the model parameter so _execute_tts exercises DEFAULT_TTS_MODEL resolution, or
set it to gemini-3.1-flash-tts-preview. Keep the existing provider, completion
type, and voice parameters unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant