lingo.dev icon indicating copy to clipboard operation
lingo.dev copied to clipboard

[Feature Request] Expose `response_mime_type` setting for Google Gemini provider to enable structured JSON output

Open serkanhaslak opened this issue 2 months ago • 16 comments

Problem

When using Google Gemini models (gemini-2.5-pro, gemini-2.5-flash) as a provider, translations intermittently fail with markdown-wrapped JSON responses instead of raw JSON:

Unexpected token '`', "```json\n{\n..." is not valid JSON

Root Cause

Gemini models support structured JSON output via the response_mime_type: "application/json" parameter (https://ai.google.dev/gemini-api/docs/structured-output), but Lingo.dev's i18n.json schema does not expose this setting.

Current schema supports: { "provider": { "id": "google", "model": "gemini-2.5-pro", "prompt": "...", "settings": { "temperature": 0 // ← Only setting available } } }

Gemini needs: { "provider": { "id": "google", "model": "gemini-2.5-pro", "prompt": "...", "settings": { "temperature": 0, "response_mime_type": "application/json", // ← Missing "response_schema": {} // ← Optional but useful } } }

Current Behavior

  • Small files (<8KB): Usually succeed with careful prompt engineering
  • Large files (>10KB): Frequently fail with markdown code blocks despite explicit prompt instructions

Expected Behavior

Setting response_mime_type: "application/json" forces Gemini to output raw JSON without markdown formatting, eliminating this class of errors entirely.

Reproduction

  1. Create i18n.json with Gemini provider: { "provider": { "id": "google", "model": "gemini-2.5-pro", "prompt": "Translate from {source} to {target}. Output raw JSON only." } }

  2. Run translation on a large file (>15KB): npx lingo.dev@latest run --target-locale es --file "large-file.json"

  3. Observe intermittent failures with markdown-wrapped JSON

Proposed Solution

Extend i18n.json schema to support Gemini-specific settings:

// i18n.json schema interface ProviderSettings { temperature?: number;

// Gemini-specific
response_mime_type?: "application/json" | "text/x.enum";
response_schema?: object;  // JSON schema for output structure

// OpenAI-specific (future)
response_format?: { type: "json_object" };

}

Map these to Gemini's generationConfig: // When provider.id === "google" const config = { temperature: settings.temperature, responseMimeType: settings.response_mime_type, // ← Add this responseSchema: settings.response_schema // ← Add this };

Workaround (Current)

Heavy prompt engineering with temperature: 0: { "provider": { "prompt": "You are a JSON translation API. Your output MUST be parseable JSON. FORBIDDEN: Do NOT write json or or any text outside the JSON object. OUTPUT FORMAT: Start with { and end with }. No markdown, no code blocks...", "settings": { "temperature": 0 } } }

This works ~70% of the time but is unreliable for large files.

serkanhaslak avatar Oct 27 '25 13:10 serkanhaslak

Hi , i would like to work on this , can you assign it to me. Thanks

kmr-rohit avatar Oct 29 '25 14:10 kmr-rohit

Hi, could you please assign this issue to me? I’ve reviewed the project’s Code of Conduct and Contribution Guidelines, and I have the required skills and understanding of the tech stack to work on this effectively. I’ve already started analyzing the codebase and begun initial work toward resolving the issue. I’m confident I can implement a clean, optimized, and maintainable solution that aligns with the project’s standards. Looking forward to contributing!

shbhmexe avatar Oct 29 '25 15:10 shbhmexe

I’d like to work on this issue. I’ve read the contributing guidelines and set up the project locally. Please let me know if it’s still available or if there’s anything specific I should keep in mind before starting. Thankyou!

palashranka avatar Oct 29 '25 16:10 palashranka

Hi @serkanhaslak , @maxprilutskiy , i tried passing response_mime_type setting , but i see that to call llm provider api , code make usage of generativeText (from vercel's ai sdk ) , even if i add these 2 setting attribute. the api call to google , contains on the temprature setting. i tried looking into ai sdk documentation , but i couldn't find any way to pass this provider option. can you check once or any suggestion what should i aim for.

references : https://v6.ai-sdk.dev/docs/reference/ai-sdk-core/generate-text#provider-options

there is one more approach which can be helpfull. https://ai-sdk.dev/providers/ai-sdk-providers/google-generative-ai#schema-limitations

please let me know what can be out next step.

kmr-rohit avatar Oct 29 '25 23:10 kmr-rohit

Also , the rest api mentioned here : https://v6.ai-sdk.dev/providers/ai-sdk-providers/google-generative-ai , generateText method doesnt accept generationConfig settings. However generateContent function allow us to pass generationConfig object. https://ai.google.dev/api/generate-content#v1beta.GenerationConfig

kmr-rohit avatar Oct 29 '25 23:10 kmr-rohit

Hi @vrcprl , @maxprilutskiy
Can you please review comments and help me out to decide what could be the next steps.

kmr-rohit avatar Oct 30 '25 11:10 kmr-rohit

Reminder: If you aren't assigned to this issue yet, don't work on it! cc @kmr-rohit

The-Best-Codes avatar Nov 09 '25 01:11 The-Best-Codes

assigning to @kmr-rohit since he was the first to volunteer. Before starting the work - how you would approach this?

maxprilutskiy avatar Nov 11 '25 06:11 maxprilutskiy

Hi @maxprilutskiy ,

i did analyize the requirement. upon further looking my findings are :

  1. Even after passing response_mime_type & response_schema , in setting for GenerateText ( vercel ai sdk function ) , the actual call made to gemini doesn't include them in generationConfig object.

  2. Vercel sdk's generateText function only accepts few settings ( temperature , topk , stopsequences etc) but , it does not accept the above mentioned. i have tried passing then in ProviderOptions too , but that also does not result in adding them to generationConfig.

  3. After trying above steps , i tried sanitizing recieved output to json format. i.e removing md backticks form json block.

So now i want to know what should be the final call.

Attaching few references to docs available and are in context to the issue.

  1. https://ai.google.dev/api/generate-content#v1beta.GenerationConfig
  2. https://ai.google.dev/gemini-api/docs/text-generation#system-instructions
  3. https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-text

kmr-rohit avatar Nov 11 '25 16:11 kmr-rohit

Based on latest vercel's v6 beta documentation , we can utilize Output parameter in generateText function. https://v6.ai-sdk.dev/docs/reference/ai-sdk-core/generate-text#output.output.output.json()

kmr-rohit avatar Nov 11 '25 18:11 kmr-rohit

@kmr-rohit The best thing to use would probably be the generateObject function. https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-object

If my PR #1559 gets merged you'll be able to use all the AI SDK v5 features in the codebase 😀

The-Best-Codes avatar Nov 11 '25 19:11 The-Best-Codes

@kmr-rohit The best thing to use would probably be the generateObject function. https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-object

If my PR #1559 gets merged you'll be able to use all the AI SDK v5 features in the codebase 😀

But then we have to call conditionally , when settings involves response_mime_type , we call generateObject(with output:"no-schema" , otherwise generateText.

kmr-rohit avatar Nov 11 '25 20:11 kmr-rohit

@kmr-rohit Not sure I'm understanding you..? Is there a problem with calling it conditionally?

The-Best-Codes avatar Nov 11 '25 20:11 The-Best-Codes

i tried implementing , using generateObject. Please review the changes.

kmr-rohit avatar Nov 12 '25 21:11 kmr-rohit

@maxprilutskiy @The-Best-Codes had a chance to review MR once ?

kmr-rohit avatar Nov 15 '25 18:11 kmr-rohit

@maxprilutskiy Thanks for your response in mr. can you please go through the discussion and suggest what can be final call. Is sanitizing response ( removing markdown quote's from json block ) is viable approach to try. or anything else

kmr-rohit avatar Nov 19 '25 04:11 kmr-rohit