Skip to content

Commit 963916f

Browse files
authored
Merge branch 'main' into feature/add-unstructured-api-provider
2 parents e3452e4 + 4b88d6f commit 963916f

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

src/ogx/providers/remote/inference/anthropic/anthropic.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010

1111
from ogx.providers.utils.inference.openai_mixin import OpenAIMixin
1212
from ogx_api.inference.models import (
13+
OpenAIChatCompletion,
14+
OpenAIChatCompletionChunk,
15+
OpenAIChatCompletionRequestWithExtraBody,
1316
OpenAICompletion,
1417
OpenAICompletionRequestWithExtraBody,
1518
)
@@ -42,6 +45,19 @@ async def list_provider_model_ids(self) -> Iterable[str]:
4245
api_key = self._get_api_key_from_config_or_provider_data()
4346
return [m.id async for m in AsyncAnthropic(api_key=api_key).models.list()]
4447

48+
async def openai_chat_completion(
49+
self,
50+
params: OpenAIChatCompletionRequestWithExtraBody,
51+
) -> OpenAIChatCompletion | AsyncIterator[OpenAIChatCompletionChunk]:
52+
# Anthropic rejects parameters: {} but OpenAI accepts it
53+
if params.tools:
54+
for tool in params.tools:
55+
func = tool.get("function", {})
56+
p = func.get("parameters")
57+
if isinstance(p, dict) and not p:
58+
func["parameters"] = {"type": "object"}
59+
return await super().openai_chat_completion(params)
60+
4561
async def openai_completion(
4662
self,
4763
params: OpenAICompletionRequestWithExtraBody,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright (c) The OGX Contributors.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the terms described in the LICENSE file in
5+
# the root directory of this source tree.
6+
7+
from unittest.mock import AsyncMock, patch
8+
9+
import pytest
10+
11+
from ogx.providers.remote.inference.anthropic.anthropic import AnthropicInferenceAdapter
12+
from ogx.providers.remote.inference.anthropic.config import AnthropicConfig
13+
from ogx_api.inference.models import OpenAIChatCompletionRequestWithExtraBody
14+
15+
16+
@pytest.fixture
17+
def adapter():
18+
config = AnthropicConfig(api_key="test-key")
19+
return AnthropicInferenceAdapter(config=config)
20+
21+
22+
@pytest.mark.parametrize(
23+
"input_params,expected_params",
24+
[
25+
({}, {"type": "object"}),
26+
({"type": "object", "properties": {}}, {"type": "object", "properties": {}}),
27+
],
28+
ids=["empty", "already-valid"],
29+
)
30+
async def test_empty_tool_parameters_normalized(adapter, input_params, expected_params):
31+
"""Anthropic rejects parameters: {} but OpenAI accepts it; the adapter normalizes."""
32+
params = OpenAIChatCompletionRequestWithExtraBody(
33+
model="claude-sonnet-4-6",
34+
messages=[{"role": "user", "content": "hi"}],
35+
tools=[{"type": "function", "function": {"name": "my_func", "parameters": input_params}}],
36+
)
37+
38+
with patch.object(type(adapter).__mro__[1], "openai_chat_completion", new_callable=AsyncMock) as mock_super:
39+
mock_super.return_value = {}
40+
await adapter.openai_chat_completion(params)
41+
42+
assert params.tools[0]["function"]["parameters"] == expected_params

0 commit comments

Comments
 (0)