Skip to content

Warn when model output stops at the token limit - #592

Merged
aksg87 merged 3 commits into
google:mainfrom
inamdarmihir:fix/287-truncated-output-diagnostics
Nov 10, 2026
Merged

aksg87 merged 3 commits into
google:mainfrom
inamdarmihir:fix/287-truncated-output-diagnostics

Conversation

@inamdarmihir

@inamdarmihir inamdarmihir commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Description

Summary

  • Previously, token-limit diagnostics in the Gemini and OpenAI providers only ran when the returned text was empty (for example, when reasoning tokens consumed the entire output budget). When a model stopped at the output token limit (finish_reason=MAX_TOKENS / numeric 2 in Gemini, or finish_reason=length in OpenAI) after emitting non-empty partial text, the truncated payload reached Resolver silently and surfaced only as ResolverParsingError: Failed to parse JSON content: Unterminated string ... (or was dropped without explanation when suppress_parse_errors=True).
  • Log an actionable logging.warning naming the finish_reason and pointing to max_output_tokens and max_char_buffer whenever a non-empty response stops at the output token limit across:
    • GeminiLanguageModel._response_to_scored_output (langextract/providers/gemini.py)
    • Gemini Batch JSONL / in-memory parsing (_is_max_tokens_finish and _parse_batch_line in langextract/providers/gemini_batch.py, supporting string "MAX_TOKENS", numeric 2, and FinishReason.MAX_TOKENS enum values while rejecting bool)
    • OpenAILanguageModel._response_to_scored_output (langextract/providers/openai.py)
    • OpenAI Batch JSONL parsing (_extract_text_from_response_body and _collect_outputs_from_jsonl in langextract/providers/openai_batch.py, including the batch item custom_id)
  • Preserve existing return values, empty-response InferenceRuntimeError behavior, downstream Resolver parsing, and public signatures unchanged.

Fixes #287

Bug fix

How Has This Been Tested?

Tests

  • Focused unit tests across all four provider paths (266 passed under both google-genai==2.29.0 and google-genai==3.0.0):
    • pytest tests/gemini_retry_test.py tests/test_gemini_batch_api.py tests/inference_test.py tests/openai_batch_test.py -q
  • Formatting and lint checks (10.00/10 on both source and test modules):
    • isort --check-only and pyink --check --config pyproject.toml on all modified files
    • pylint --rcfile=.pylintrc langextract/providers/gemini.py langextract/providers/gemini_batch.py langextract/providers/openai.py langextract/providers/openai_batch.py
    • pylint --rcfile=tests/.pylintrc tests/gemini_retry_test.py tests/test_gemini_batch_api.py tests/inference_test.py tests/openai_batch_test.py
  • PR CI on 9de5b6bbcd722c23a3fea7dfd316fb69bacdce50: https://github.com/google/langextract/actions/runs/42734188186 (format-check, Python 3.10/3.11/3.12 unit + lint suites, ollama-integration-test, and plugin-integration-test passed).
  • Secure fork live-API dispatch on 9de5b6bbcd722c23a3fea7dfd316fb69bacdce50: https://github.com/google/langextract/actions/runs/42735393166 (12 passed live Gemini and OpenAI tests; 4 skipped opt-in Vertex AI Batch and live OpenAI Batch tests).

Checklist

  • I have read and acknowledged Google's Open Source Code of conduct.
  • I have read the Contributing page, and I either signed the Google Individual CLA or am covered by my company's Corporate CLA.
  • I have discussed my proposed solution with code owners in the linked issue(s) and we have agreed upon the general approach.
  • I have made any needed documentation changes, or noted in the linked issue(s) that documentation elsewhere needs updating.
  • I have added tests, or I have ensured existing tests cover the changes
  • I have followed Google's Python Style Guide and ran pylint over the affected code.

@github-actions github-actions Bot added the size/S Pull request with 50-150 lines changed label Oct 27, 2026
@google-cla

google-cla Bot commented Oct 27, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

A Gemini MAX_TOKENS or OpenAI length finish with non-empty text was
passed through silently, so a truncated JSON response surfaced only as
an opaque 'Unterminated string' ResolverParsingError (or was dropped
without a trace under suppress_parse_errors).

Log a warning naming the finish reason and the max_output_tokens and
max_char_buffer knobs in the Gemini, Gemini batch and OpenAI providers.
The output is still returned unchanged.

Related to google#287
@inamdarmihir
inamdarmihir force-pushed the fix/287-truncated-output-diagnostics branch from 3151906 to f233b03 Compare October 27, 2026 07:16
@github-actions

Copy link
Copy Markdown

⚠️ Branch Update Required

Your branch is 1 commits behind main. Please update your branch to ensure CI checks run with the latest code:

git fetch origin main
git merge origin/main
git push

Note: Enable "Allow edits by maintainers" to allow automatic updates.

@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

⚠️ Branch Update Required

Your branch is 8 commits behind main. Please update your branch to ensure CI checks run with the latest code:

git fetch origin main
git merge origin/main
git push

Note: Enable "Allow edits by maintainers" to allow automatic updates.

# Conflicts:
#	tests/inference_test.py
@github-actions github-actions Bot added size/M Pull request with 150-600 lines changed and removed size/S Pull request with 50-150 lines changed labels Nov 9, 2026
@aksg87
aksg87 force-pushed the fix/287-truncated-output-diagnostics branch from aa2e702 to 9de5b6b Compare November 10, 2026 01:13
@aksg87
aksg87 merged commit 0e441bf into google:main Nov 10, 2026
23 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M Pull request with 150-600 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

batch langextract: langextract.resolver.ResolverParsingError: Failed to parse JSON content: Unterminated string starting at

2 participants