Fix OCR zero credit and Bedrock support checks

This commit is contained in:
Cursor Agent 2026-05-01 18:37:04 +00:00 • committed by Sameer Kankute
parent 7fb5eeae92
commit 005f67bff3
No known key found for this signature in database
6 changed files with 89 additions and 3 deletions

View file

@ -1890,7 +1890,7 @@ def ocr_cost(
cost_per_credit = None
if model_info is not None:
cost_per_credit = model_info.get("ocr_cost_per_credit")
if credits is not None and cost_per_credit:
if credits is not None and cost_per_credit is not None:
return cost_per_credit * credits, 0.0
pages_processed = response.usage_info.pages_processed

View file

@ -171,7 +171,7 @@ class AmazonAnthropicClaudeConfig(AmazonInvokeConfig, AnthropicConfig):
anthropic_request.pop("stream", None)
anthropic_request.pop("output_format", None)
if not _supports_factory(
model=model, custom_llm_provider=None, key="supports_output_config"
model=model, custom_llm_provider="bedrock", key="supports_output_config"
):
anthropic_request.pop("output_config", None)
if "anthropic_version" not in anthropic_request:

View file

@ -562,7 +562,7 @@ class AmazonAnthropicClaudeMessagesConfig(
# but older models do not — strip it to avoid request rejection.
# Ref: https://github.com/BerriAI/litellm/issues/22797
if not _supports_factory(
model=model, custom_llm_provider=None, key="supports_output_config"
model=model, custom_llm_provider="bedrock", key="supports_output_config"
):
anthropic_messages_request.pop("output_config", None)

View file

@ -2,6 +2,7 @@ import asyncio
import json
import os
import sys
from unittest.mock import patch
import pytest
@ -429,6 +430,31 @@ def test_output_config_forwarded_for_bedrock_chat_invoke_request():
assert result["max_tokens"] == 100
def test_bedrock_chat_invoke_checks_output_config_support_with_bedrock_provider():
config = AmazonAnthropicClaudeConfig()
messages = [{"role": "user", "content": "test"}]
optional_params = {"max_tokens": 100, "output_config": {"effort": "high"}}
with patch(
"litellm.llms.bedrock.chat.invoke_transformations.anthropic_claude3_transformation._supports_factory",
return_value=True,
) as mock_supports_factory:
result = config.transform_request(
model="us.anthropic.claude-opus-4-7",
messages=messages,
optional_params=optional_params,
litellm_params={},
headers={},
)
mock_supports_factory.assert_called_once_with(
model="us.anthropic.claude-opus-4-7",
custom_llm_provider="bedrock",
key="supports_output_config",
)
assert result["output_config"] == {"effort": "high"}
def test_output_format_removed_from_bedrock_invoke_request():
"""
Test that output_format parameter is removed from Bedrock Invoke requests.

View file

@ -666,6 +666,40 @@ def test_bedrock_messages_preserves_output_config_for_claude_4_6():
assert result.get("max_tokens") == 4096
def test_bedrock_messages_checks_output_config_support_with_bedrock_provider():
from unittest.mock import patch
from litellm.types.router import GenericLiteLLMParams
cfg = AmazonAnthropicClaudeMessagesConfig()
messages = [{"role": "user", "content": [{"type": "text", "text": "Hello"}]}]
optional_params = {
"max_tokens": 4096,
"output_config": {
"effort": "high",
},
}
with patch(
"litellm.llms.bedrock.messages.invoke_transformations.anthropic_claude3_transformation._supports_factory",
return_value=True,
) as mock_supports_factory:
result = cfg.transform_anthropic_messages_request(
model="us.anthropic.claude-opus-4-7",
messages=messages,
anthropic_messages_optional_request_params=optional_params,
litellm_params=GenericLiteLLMParams(),
headers={},
)
mock_supports_factory.assert_called_with(
model="us.anthropic.claude-opus-4-7",
custom_llm_provider="bedrock",
key="supports_output_config",
)
assert result["output_config"] == {"effort": "high"}
def test_bedrock_messages_forwards_output_config():
"""Bedrock Invoke /v1/messages forwards ``output_config`` for supported models."""
from unittest.mock import patch

View file

@ -27,6 +27,32 @@ def test_ocr_cost_prefers_credit_pricing_when_pages_processed_is_none(monkeypatc
assert cost == 0.03
def test_ocr_cost_prefers_zero_credit_pricing_over_page_pricing(monkeypatch):
monkeypatch.setattr(
litellm,
"get_model_info",
lambda model, custom_llm_provider=None: {
"ocr_cost_per_credit": 0.0,
"ocr_cost_per_page": 0.5,
},
)
response = OCRResponse(
pages=[OCRPage(index=0, markdown="free credit priced")],
model="parse-v3",
usage_info=OCRUsageInfo(pages_processed=2, credits=10),
)
cost = completion_cost(
completion_response=response,
model="reducto/parse-v3",
custom_llm_provider="reducto",
call_type="ocr",
)
assert cost == 0.0
def test_ocr_cost_falls_back_to_page_pricing(monkeypatch):
monkeypatch.setattr(
litellm,