Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
ab30a2d
plans for model facade overhaul
nabinchha Feb 19, 2026
43824ea
update plan
nabinchha Feb 20, 2026
2a5f1e4
add review
johnnygreco Feb 20, 2026
f945d5b
address feedback + add more details after several self reviews
nabinchha Feb 20, 2026
dfa3817
update plan doc
nabinchha Feb 25, 2026
5b18f74
Merge branch 'main' into nm/overhaul-model-facade-guts
nabinchha Feb 25, 2026
0f449a7
address nits
nabinchha Feb 25, 2026
37f092a
Merge branch 'nm/overhaul-model-facade-guts' into nm/overhaul-model-f…
nabinchha Feb 25, 2026
08e57f8
Add cannonical objects
nabinchha Feb 26, 2026
3ab18ee
Merge branch 'main' into nm/overhaul-model-facade-guts-pr1
nabinchha Feb 27, 2026
34349c7
self-review feedback + address
nabinchha Feb 28, 2026
6aae4b6
add LiteLLMRouter protocol to strongly type bridge router param
nabinchha Feb 28, 2026
2a53d37
simplify some things
nabinchha Feb 28, 2026
4e2f3af
add a protol for http response like object
nabinchha Feb 28, 2026
b1c85f2
move HttpResponse
nabinchha Feb 28, 2026
f6dc769
update PR-1 architecture notes for lifecycle and router protocol
nabinchha Feb 28, 2026
ec5ed9b
Address PR #359 feedback: exception wrapping, shared parsing, test im…
nabinchha Mar 4, 2026
b6b4028
Merge branch 'main' into nm/overhaul-model-facade-guts-pr1
nabinchha Mar 4, 2026
ba22397
Use contextlib to dry out some code
nabinchha Mar 4, 2026
aeac3b9
Address Greptile feedback: HTTP-date retry-after parsing, docstring c…
nabinchha Mar 4, 2026
55f3c96
Address Greptile feedback: FastAPI detail parsing, comment fixes
nabinchha Mar 4, 2026
c390912
Merge branch 'main' into nm/overhaul-model-facade-guts-pr1
nabinchha Mar 4, 2026
828cc49
add PR-2 architecture notes for model facade overhaul
nabinchha Mar 4, 2026
89a6d4e
save progress on pr2
nabinchha Mar 5, 2026
e527503
Merge branch 'main' into nm/overhaul-model-facade-guts-pr1
nabinchha Mar 5, 2026
f6fa447
Merge branch 'nm/overhaul-model-facade-guts-pr1' into nm/overhaul-mod…
nabinchha Mar 5, 2026
b8579c2
small refactor
nabinchha Mar 5, 2026
61024c0
address feedback
nabinchha Mar 5, 2026
d47d508
Merge branch 'nm/overhaul-model-facade-guts-pr1' into nm/overhaul-mod…
nabinchha Mar 5, 2026
49a45ba
Address greptile comment in pr1
nabinchha Mar 5, 2026
e8445cc
refactor ProviderError from dataclass to regular Exception
nabinchha Mar 5, 2026
8a385ff
Merge branch 'main' into nm/overhaul-model-facade-guts-pr2
nabinchha Mar 6, 2026
521c1e4
Address greptile feedback
nabinchha Mar 6, 2026
a831d24
Merge branch 'main' into nm/overhaul-model-facade-guts-pr2
nabinchha Mar 6, 2026
4836e03
PR feedback
nabinchha Mar 6, 2026
ae1bf98
track usage tracking in finally block for images
nabinchha Mar 6, 2026
18b9966
pr feedback
nabinchha Mar 6, 2026
ad45ee2
add native OpenAI adapter with retry and throttle infrastructure
nabinchha Mar 6, 2026
724e734
Self CR
nabinchha Mar 6, 2026
25650b0
Merge branch 'main' into nm/overhaul-model-facade-guts-pr2
nabinchha Mar 6, 2026
651813b
Merge branch 'main' into nm/overhaul-model-facade-guts-pr2
nabinchha Mar 6, 2026
bfed5af
Merge branch 'main' into nm/overhaul-model-facade-guts-pr2
nabinchha Mar 6, 2026
3636c56
Merge branch 'nm/overhaul-model-facade-guts-pr2' into nm/overhaul-mod…
nabinchha Mar 6, 2026
504d040
fix claude slop
nabinchha Mar 6, 2026
afbe197
Updates after self-review. Simplify use of ThrottleManager in light o…
nabinchha Mar 6, 2026
c9d6f4c
Merge branch 'main' into nm/overhaul-model-facade-guts-pr2
nabinchha Mar 9, 2026
a084038
Merge branch 'main' into nm/overhaul-model-facade-guts-pr2
nabinchha Mar 9, 2026
632c7c6
wrap facade close in try/catch
nabinchha Mar 10, 2026
40c05ae
Merge branch 'main' into nm/overhaul-model-facade-guts-pr2
nabinchha Mar 10, 2026
c1d807c
clean up stray params
nabinchha Mar 10, 2026
56caed5
Merge branch 'nm/overhaul-model-facade-guts-pr2' into nm/overhaul-mod…
nabinchha Mar 10, 2026
e34e566
fix: address review findings from model facade overhaul PR3
nabinchha Mar 10, 2026
879b941
fix stray inclusion of metadata
nabinchha Mar 10, 2026
dcbbcba
small regression fix
nabinchha Mar 10, 2026
462810c
address more feedback
nabinchha Mar 10, 2026
ac02f2c
Merge branch 'main' into nm/overhaul-model-facade-guts-pr2
nabinchha Mar 11, 2026
fb809bd
Merge branch 'nm/overhaul-model-facade-guts-pr2' into nm/overhaul-mod…
nabinchha Mar 12, 2026
c538367
Merge branch 'main' into nm/overhaul-model-facade-guts-pr3
nabinchha Mar 12, 2026
117baf4
self review
nabinchha Mar 12, 2026
843227b
Fixes
nabinchha Mar 12, 2026
c7e67d6
new test for aimd lifecycle
nabinchha Mar 12, 2026
707a22f
update plan docs
nabinchha Mar 12, 2026
0f55d4c
update plans with refs to prs
nabinchha Mar 12, 2026
e13f7b6
fix: cap acquire_sync/acquire_async sleep to remaining budget to prev…
nabinchha Mar 12, 2026
664e3cf
test lay init
nabinchha Mar 12, 2026
eb27418
Merge branch 'main' into nm/overhaul-model-facade-guts-pr3
nabinchha Mar 12, 2026
7d7fd41
fix timeout for openaicompatibleadapter
nabinchha Mar 12, 2026
9142494
remove unused attr
nabinchha Mar 12, 2026
bdd0202
fix: address review findings from PR #402
nabinchha Mar 12, 2026
e46efdf
Merge branch 'main' into nm/overhaul-model-facade-guts-pr3
nabinchha Mar 12, 2026
5c5bfab
Merge branch 'main' into nm/overhaul-model-facade-guts-pr3
nabinchha Mar 12, 2026
c23e360
Address pr feedback
nabinchha Mar 13, 2026
7bd4763
fix method order
nabinchha Mar 13, 2026
1658544
Merge branch 'main' into nm/overhaul-model-facade-guts-pr3
nabinchha Mar 13, 2026
f9e7c34
feat: native Anthropic adapter with image block translation
nabinchha Mar 13, 2026
9170e57
fix: exclude OpenAI-specific params from Anthropic payload and drop u…
nabinchha Mar 13, 2026
ffa0e11
Merge branch 'main' into nm/overhaul-model-facade-guts-pr3
nabinchha Mar 13, 2026
c0c2418
Merge branch 'main' into nm/overhaul-model-facade-guts-pr3
nabinchha Mar 13, 2026
3b491c9
Fix failing test
nabinchha Mar 13, 2026
4b8dd11
fix: address PR #402 review findings
nabinchha Mar 16, 2026
fd2d168
Merge branch 'main' into nm/overhaul-model-facade-guts-pr3
nabinchha Mar 16, 2026
327b100
Merge branch 'main' into nm/overhaul-model-facade-guts-pr3
nabinchha Mar 17, 2026
6fd0035
Merge branch 'nm/overhaul-model-facade-guts-pr3' into nm/overhaul-mod…
nabinchha Mar 17, 2026
10ae083
Merge branch 'main' into nm/overhaul-model-facade-guts-pr4
nabinchha Mar 17, 2026
ac9c28e
updates to DRY out code between the two adapters
nabinchha Mar 17, 2026
e0ad32d
refactor code to introduce HttpModelClient
nabinchha Mar 17, 2026
36775dc
update tests
nabinchha Mar 17, 2026
aa694bd
fix: address PR #426 review findings
nabinchha Mar 17, 2026
d3e4482
Merge branch 'main' into nm/overhaul-model-facade-guts-pr4
nabinchha Mar 17, 2026
13170da
fix: improve error classification and surface provider messages for 400s
nabinchha Mar 18, 2026
b8add5d
fix: address PR #426 review findings (round 2)
nabinchha Mar 18, 2026
bed3c54
Update license headers
nabinchha Mar 18, 2026
f5b0b39
Fix anthropic tool call flow
nabinchha Mar 18, 2026
05dab75
Merge branch 'main' into nm/overhaul-model-facade-guts-pr4
nabinchha Mar 18, 2026
8778678
fix: add explicit UNSUPPORTED_CAPABILITY error mapping
nabinchha Mar 19, 2026
3e8cac4
Merge branch 'main' into nm/overhaul-model-facade-guts-pr4
nabinchha Mar 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

from __future__ import annotations

from data_designer.engine.models.clients.adapters.anthropic import AnthropicClient
from data_designer.engine.models.clients.adapters.litellm_bridge import LiteLLMBridgeClient, LiteLLMRouter
from data_designer.engine.models.clients.adapters.openai_compatible import OpenAICompatibleClient

__all__ = ["LiteLLMBridgeClient", "LiteLLMRouter", "OpenAICompatibleClient"]
__all__ = ["AnthropicClient", "LiteLLMBridgeClient", "LiteLLMRouter", "OpenAICompatibleClient"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

from __future__ import annotations

from typing import Any

from data_designer.engine.models.clients.adapters.anthropic_translation import (
build_anthropic_payload,
parse_anthropic_response,
)
from data_designer.engine.models.clients.adapters.http_model_client import (
HttpModelClient,
)
from data_designer.engine.models.clients.errors import (
ProviderError,
ProviderErrorKind,
)
from data_designer.engine.models.clients.types import (
ChatCompletionRequest,
ChatCompletionResponse,
EmbeddingRequest,
EmbeddingResponse,
ImageGenerationRequest,
ImageGenerationResponse,
TransportKwargs,
)


class AnthropicClient(HttpModelClient):
"""Native HTTP adapter for the Anthropic Messages API.

Uses ``httpx`` with ``httpx_retries.RetryTransport`` for resilient HTTP
calls. Concurrency / throttle policy is an orchestration concern and
is not managed here — see ``ThrottleManager`` and ``AsyncTaskScheduler``.
"""

_ROUTE_MESSAGES = "/messages"
_API_VERSION_PATH = "/v1"
_ANTHROPIC_VERSION = "2023-06-01"
# Fields handled explicitly and excluded from TransportKwargs forwarding.
_TRANSPORT_EXCLUDE = frozenset(
{
"stop",
"max_tokens",
"tools",
"response_format",
"frequency_penalty",
"presence_penalty",
"seed",
}
)

# -------------------------------------------------------------------
# Capability checks
# -------------------------------------------------------------------

def supports_chat_completion(self) -> bool:
return True

def supports_embeddings(self) -> bool:
return False

def supports_image_generation(self) -> bool:
return False

# -------------------------------------------------------------------
# Chat completion
# -------------------------------------------------------------------

def completion(self, request: ChatCompletionRequest) -> ChatCompletionResponse:
payload = self._build_payload_or_raise(request)
transport = TransportKwargs.from_request(request, exclude=self._TRANSPORT_EXCLUDE)
payload.update(transport.body)
response_json = self._post_sync(
self._get_messages_route(), payload, transport.headers, request.model, transport.timeout
)
return parse_anthropic_response(response_json)

async def acompletion(self, request: ChatCompletionRequest) -> ChatCompletionResponse:
payload = self._build_payload_or_raise(request)
transport = TransportKwargs.from_request(request, exclude=self._TRANSPORT_EXCLUDE)
payload.update(transport.body)
response_json = await self._apost(
self._get_messages_route(), payload, transport.headers, request.model, transport.timeout
)
return parse_anthropic_response(response_json)

# -------------------------------------------------------------------
# Unsupported capabilities
# -------------------------------------------------------------------

def embeddings(self, request: EmbeddingRequest) -> EmbeddingResponse:
raise ProviderError.unsupported_capability(provider_name=self.provider_name, operation="embeddings")

async def aembeddings(self, request: EmbeddingRequest) -> EmbeddingResponse:
raise ProviderError.unsupported_capability(provider_name=self.provider_name, operation="embeddings")

def generate_image(self, request: ImageGenerationRequest) -> ImageGenerationResponse:
raise ProviderError.unsupported_capability(provider_name=self.provider_name, operation="image-generation")

async def agenerate_image(self, request: ImageGenerationRequest) -> ImageGenerationResponse:
raise ProviderError.unsupported_capability(provider_name=self.provider_name, operation="image-generation")

def _build_payload_or_raise(self, request: ChatCompletionRequest) -> dict[str, Any]:
try:
return build_anthropic_payload(request)
except ValueError as exc:
raise ProviderError(
kind=ProviderErrorKind.BAD_REQUEST,
message=str(exc),
provider_name=self.provider_name,
model_name=request.model,
cause=exc,
) from exc

def _build_headers(self, extra_headers: dict[str, str]) -> dict[str, str]:
headers: dict[str, str] = {
"Content-Type": "application/json",
"anthropic-version": self._ANTHROPIC_VERSION,
}
if self._api_key:
headers["x-api-key"] = self._api_key
if extra_headers:
headers.update(extra_headers)
return headers

def _get_messages_route(self) -> str:
if self._endpoint.endswith(self._API_VERSION_PATH):
return self._ROUTE_MESSAGES
return f"{self._API_VERSION_PATH}{self._ROUTE_MESSAGES}"
Loading
Loading