Files
wehub-resource-sync 97e91a83f3
Ruff / Ruff (push) Has been cancelled
Test / Core Tests (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.10) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.11) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.12) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.13) (push) Has been cancelled
Test / Offline Coverage Tests (Python 3.9) (push) Has been cancelled
Test / Full Coverage (Python 3.11) (push) Has been cancelled
Test / Core Provider Tests (OpenAI) (push) Has been cancelled
Test / Core Provider Tests (Anthropic) (push) Has been cancelled
Test / Core Provider Tests (Google) (push) Has been cancelled
Test / Core Provider Tests (Other) (push) Has been cancelled
Test / Anthropic Tests (push) Has been cancelled
Test / Gemini Tests (push) Has been cancelled
Test / Google GenAI Tests (push) Has been cancelled
Test / Vertex AI Tests (push) Has been cancelled
Test / OpenAI Tests (push) Has been cancelled
Test / Writer Tests (push) Has been cancelled
Test / Auto Client Tests (push) Has been cancelled
ty / type-check (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:36:38 +08:00

979 lines
28 KiB
Python

from __future__ import annotations
from typing import (
TYPE_CHECKING,
TypeVar,
Callable,
Literal,
Any,
cast,
get_origin,
get_args,
)
if TYPE_CHECKING:
import openai
from openai.types.chat import ChatCompletionMessageParam
from instructor.v2.core.mode import Mode
from instructor.v2.core.providers import Provider
from tenacity import (
AsyncRetrying,
Retrying,
)
from collections.abc import Generator, Iterable, Awaitable, AsyncGenerator, Coroutine
from typing_extensions import Self, overload
from instructor.v2.dsl.partial import Partial
from instructor.v2.core.hooks import Hooks, HookName
T = TypeVar("T")
class _ResponseBase:
@staticmethod
def _normalize_messages(
messages: str | list[ChatCompletionMessageParam] | None,
kwargs: dict[str, Any],
) -> str | list[ChatCompletionMessageParam]:
if messages is None:
if "input" not in kwargs:
raise TypeError("Either 'messages' or 'input' must be provided")
messages = kwargs.pop("input")
elif "input" in kwargs:
raise TypeError("Pass only one of 'messages' or 'input'")
if isinstance(messages, str):
return [{"role": "user", "content": messages}]
return messages
class Response(_ResponseBase):
"""Helper for responses API using a patched client."""
def __init__(
self,
client: Instructor,
):
self.client = client
@overload
def create(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] = ...,
max_retries: int | Retrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
**kwargs: Any,
) -> T: ...
@overload
def create(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: None = None,
max_retries: int | Retrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
**kwargs: Any,
) -> Any: ...
def create(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] | None = None,
max_retries: int | Retrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
**kwargs,
) -> T | Any:
messages = self._normalize_messages(messages, kwargs)
create = cast(Callable[..., Any], self.client.create)
return create(
response_model=response_model,
context=context,
max_retries=max_retries,
strict=strict,
messages=messages,
**kwargs,
)
@overload
def create_with_completion(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] = ...,
max_retries: int | Retrying = 3,
**kwargs: Any,
) -> tuple[T, Any]: ...
@overload
def create_with_completion(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: None = None,
max_retries: int | Retrying = 3,
**kwargs: Any,
) -> tuple[Any, Any]: ...
def create_with_completion(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] | None = None,
max_retries: int | Retrying = 3,
**kwargs,
) -> tuple[T, Any]:
messages = self._normalize_messages(messages, kwargs)
create_with_completion = cast(
Callable[..., tuple[T, Any]], self.client.create_with_completion
)
return create_with_completion(
messages=messages,
response_model=response_model,
max_retries=max_retries,
**kwargs,
)
@overload
def create_iterable(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] = ...,
max_retries: int | Retrying = 3,
**kwargs: Any,
) -> Generator[T, None, None]: ...
@overload
def create_iterable(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: None = None,
max_retries: int | Retrying = 3,
**kwargs: Any,
) -> Generator[Any, None, None]: ...
def create_iterable(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] | None = None,
max_retries: int | Retrying = 3,
**kwargs,
) -> Generator[T, None, None]:
messages = self._normalize_messages(messages, kwargs)
create_iterable = cast(
Callable[..., Generator[T, None, None]], self.client.create_iterable
)
return create_iterable(
messages=messages,
response_model=response_model,
max_retries=max_retries,
**kwargs,
)
@overload
def create_partial(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] = ...,
max_retries: int | Retrying = 3,
**kwargs: Any,
) -> Generator[T, None, None]: ...
@overload
def create_partial(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: None = None,
max_retries: int | Retrying = 3,
**kwargs: Any,
) -> Generator[Any, None, None]: ...
def create_partial(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] | None = None,
max_retries: int | Retrying = 3,
**kwargs,
) -> Generator[T, None, None]:
messages = self._normalize_messages(messages, kwargs)
create_partial = cast(
Callable[..., Generator[T, None, None]], self.client.create_partial
)
return create_partial(
messages=messages,
response_model=response_model,
max_retries=max_retries,
**kwargs,
)
class AsyncResponse(_ResponseBase):
def __init__(self, client: AsyncInstructor):
self.client = client
@overload
async def create(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] = ...,
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
**kwargs: Any,
) -> T: ...
@overload
async def create(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: None = None,
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
**kwargs: Any,
) -> Any: ...
async def create(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] | None = None,
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
**kwargs,
) -> T | Any:
messages = self._normalize_messages(messages, kwargs)
create = cast(Callable[..., Awaitable[Any]], self.client.create)
return await create(
response_model=response_model,
context=context,
max_retries=max_retries,
strict=strict,
messages=messages,
**kwargs,
)
@overload
async def create_with_completion(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] = ...,
max_retries: int | AsyncRetrying = 3,
**kwargs: Any,
) -> tuple[T, Any]: ...
@overload
async def create_with_completion(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: None = None,
max_retries: int | AsyncRetrying = 3,
**kwargs: Any,
) -> tuple[Any, Any]: ...
async def create_with_completion(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] | None = None,
max_retries: int | AsyncRetrying = 3,
**kwargs,
) -> tuple[T, Any]:
messages = self._normalize_messages(messages, kwargs)
create_with_completion = cast(
Callable[..., Awaitable[tuple[T, Any]]],
self.client.create_with_completion,
)
return await create_with_completion(
messages=messages,
response_model=response_model,
max_retries=max_retries,
**kwargs,
)
@overload
async def create_iterable(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] = ...,
max_retries: int | AsyncRetrying = 3,
**kwargs: Any,
) -> AsyncGenerator[T, None]: ...
@overload
async def create_iterable(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: None = None,
max_retries: int | AsyncRetrying = 3,
**kwargs: Any,
) -> AsyncGenerator[Any, None]: ...
async def create_iterable(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] | None = None,
max_retries: int | AsyncRetrying = 3,
**kwargs,
) -> AsyncGenerator[T, None]:
messages = self._normalize_messages(messages, kwargs)
create_iterable = cast(
Callable[..., AsyncGenerator[T, None]], self.client.create_iterable
)
return create_iterable(
messages=messages,
response_model=response_model,
max_retries=max_retries,
**kwargs,
)
@overload
def create_partial(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] = ...,
max_retries: int | AsyncRetrying = 3,
**kwargs: Any,
) -> AsyncGenerator[T, None]: ...
@overload
def create_partial(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: None = None,
max_retries: int | AsyncRetrying = 3,
**kwargs: Any,
) -> AsyncGenerator[Any, None]: ...
def create_partial(
self,
messages: str | list[ChatCompletionMessageParam] | None = None,
response_model: type[T] | None = None,
max_retries: int | AsyncRetrying = 3,
**kwargs: Any,
) -> AsyncGenerator[T, None]:
messages = self._normalize_messages(messages, kwargs)
create_partial = cast(
Callable[..., AsyncGenerator[T, None]], self.client.create_partial
)
return create_partial(
messages=messages,
response_model=response_model,
max_retries=max_retries,
**kwargs,
)
class Instructor:
"""Sync client wrapper that adds structured output support."""
client: Any | None
create_fn: Callable[..., Any]
mode: Mode
default_model: str | None = None
provider: Provider
hooks: Hooks
def __init__(
self,
client: Any | None,
create: Callable[..., Any],
mode: Mode = Mode.TOOLS,
provider: Provider = Provider.OPENAI,
hooks: Hooks | None = None,
**kwargs: Any,
):
self.client = client
self.create_fn = create
self.mode = mode
if mode == Mode.FUNCTIONS:
Mode.warn_mode_functions_deprecation()
self.kwargs = kwargs
self.provider = provider
self.hooks = hooks or Hooks()
if mode in {
Mode.RESPONSES_TOOLS,
Mode.RESPONSES_TOOLS_WITH_INBUILT_TOOLS,
}:
import openai as _openai
assert isinstance(client, (_openai.OpenAI, _openai.AsyncOpenAI))
self.responses = Response(client=self)
def on(
self,
hook_name: (
HookName
| Literal[
"completion:kwargs",
"completion:response",
"completion:error",
"completion:last_attempt",
"parse:error",
]
),
handler: Callable[[Any], None],
) -> None:
self.hooks.on(hook_name, handler)
def off(
self,
hook_name: (
HookName
| Literal[
"completion:kwargs",
"completion:response",
"completion:error",
"completion:last_attempt",
"parse:error",
]
),
handler: Callable[[Any], None],
) -> None:
self.hooks.off(hook_name, handler)
def clear(
self,
hook_name: (
HookName
| Literal[
"completion:kwargs",
"completion:response",
"completion:error",
"completion:last_attempt",
"parse:error",
]
)
| None = None,
) -> None:
self.hooks.clear(hook_name)
@property
def chat(self) -> Self:
return self
@property
def completions(self) -> Self:
return self
@property
def messages(self) -> Self:
return self
@overload
def create(
self: AsyncInstructor,
response_model: type[T],
messages: list[ChatCompletionMessageParam],
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None, # {{ edit_1 }}
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> Awaitable[T]: ...
@overload
def create(
self: Self,
response_model: type[T],
messages: list[ChatCompletionMessageParam],
max_retries: int | Retrying = 3,
context: dict[str, Any] | None = None, # {{ edit_1 }}
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> T: ...
@overload
def create(
self: AsyncInstructor,
response_model: None,
messages: list[ChatCompletionMessageParam],
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None, # {{ edit_1 }}
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> Awaitable[Any]: ...
@overload
def create(
self: Self,
response_model: None,
messages: list[ChatCompletionMessageParam],
max_retries: int | Retrying = 3,
context: dict[str, Any] | None = None, # {{ edit_1 }}
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> Any: ...
def create(
self,
response_model: type[T] | None,
messages: list[ChatCompletionMessageParam],
max_retries: int | Retrying | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> T | Any | Awaitable[T] | Awaitable[Any]:
kwargs = self.handle_kwargs(kwargs)
# Combine client hooks with per-call hooks
combined_hooks = self.hooks
if hooks is not None:
combined_hooks = self.hooks + hooks
return self.create_fn(
response_model=response_model,
messages=messages,
max_retries=max_retries,
context=context,
strict=strict,
hooks=combined_hooks,
**kwargs,
)
@overload
def create_partial(
self: AsyncInstructor,
response_model: type[T],
messages: list[ChatCompletionMessageParam],
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None, # {{ edit_1 }}
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> AsyncGenerator[T, None]: ...
@overload
def create_partial(
self: Self,
response_model: type[T],
messages: list[ChatCompletionMessageParam],
max_retries: int | Retrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> Generator[T, None, None]: ...
def create_partial(
self,
response_model: type[T],
messages: list[ChatCompletionMessageParam],
max_retries: int | Retrying | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> Generator[T, None, None] | AsyncGenerator[T, None]:
kwargs["stream"] = True
kwargs = self.handle_kwargs(kwargs)
# Combine client hooks with per-call hooks
combined_hooks = self.hooks
if hooks is not None:
combined_hooks = self.hooks + hooks
response_model = Partial[response_model] # type: ignore
return self.create_fn(
messages=messages,
response_model=response_model,
max_retries=max_retries,
context=context,
strict=strict,
hooks=combined_hooks,
**kwargs,
)
@overload
def create_iterable(
self: AsyncInstructor,
messages: list[ChatCompletionMessageParam],
response_model: type[T],
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> AsyncGenerator[T, None]: ...
@overload
def create_iterable(
self: Self,
messages: list[ChatCompletionMessageParam],
response_model: type[T],
max_retries: int | Retrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> Generator[T, None, None]: ...
def create_iterable(
self,
messages: list[ChatCompletionMessageParam],
response_model: type[T],
max_retries: int | Retrying | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> Generator[T, None, None] | AsyncGenerator[T, None]:
kwargs["stream"] = True
kwargs = self.handle_kwargs(kwargs)
# Combine client hooks with per-call hooks
combined_hooks = self.hooks
if hooks is not None:
combined_hooks = self.hooks + hooks
response_model = Iterable[response_model] # type: ignore
return self.create_fn(
messages=messages,
response_model=response_model,
max_retries=max_retries,
context=context,
strict=strict,
hooks=combined_hooks,
**kwargs,
)
@overload
def create_with_completion(
self: AsyncInstructor,
messages: list[ChatCompletionMessageParam],
response_model: type[T],
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> Awaitable[tuple[T, Any]]: ...
@overload
def create_with_completion(
self: Self,
messages: list[ChatCompletionMessageParam],
response_model: type[T],
max_retries: int | Retrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> tuple[T, Any]: ...
def create_with_completion(
self,
messages: list[ChatCompletionMessageParam],
response_model: type[T],
max_retries: int | Retrying | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> tuple[T, Any] | Awaitable[tuple[T, Any]]:
kwargs = self.handle_kwargs(kwargs)
# Combine client hooks with per-call hooks
combined_hooks = self.hooks
if hooks is not None:
combined_hooks = self.hooks + hooks
model = self.create_fn(
messages=messages,
response_model=response_model,
max_retries=max_retries,
context=context,
strict=strict,
hooks=combined_hooks,
**kwargs,
)
return model, model._raw_response
def handle_kwargs(self, kwargs: dict[str, Any]) -> dict[str, Any]:
"""
Handle and process keyword arguments for the API call.
This method merges the provided kwargs with the default kwargs stored in the instance.
It ensures that any kwargs passed to the method call take precedence over the default ones.
"""
for key, value in self.kwargs.items():
if key not in kwargs:
kwargs[key] = value
return kwargs
def __getattr__(self, attr: str) -> Any:
if attr not in {"create", "chat", "messages"}:
return getattr(self.client, attr)
return getattr(self, attr)
class AsyncInstructor(Instructor):
"""Async client wrapper that adds structured output support."""
client: Any | None
create_fn: Callable[..., Any]
mode: Mode
default_model: str | None = None
provider: Provider
hooks: Hooks
def __init__(
self,
client: Any | None,
create: Callable[..., Any],
mode: Mode = Mode.TOOLS,
provider: Provider = Provider.OPENAI,
hooks: Hooks | None = None,
**kwargs: Any,
):
self.client = client
self.create_fn = create
self.mode = mode
self.kwargs = kwargs
self.provider = provider
self.hooks = hooks or Hooks()
if mode in {
Mode.RESPONSES_TOOLS,
Mode.RESPONSES_TOOLS_WITH_INBUILT_TOOLS,
}:
import openai as _openai
assert isinstance(client, (_openai.OpenAI, _openai.AsyncOpenAI))
self.responses = AsyncResponse(client=self)
async def create( # type: ignore[override] # ty: ignore[invalid-method-override]
self,
response_model: type[T] | None,
messages: list[ChatCompletionMessageParam],
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> T | Any:
kwargs = self.handle_kwargs(kwargs)
# Combine client hooks with per-call hooks
combined_hooks = self.hooks
if hooks is not None:
combined_hooks = self.hooks + hooks
# Check if the response model is an iterable type
if (
get_origin(response_model) in {Iterable}
and get_args(response_model)
and get_args(response_model)[0] is not None
and self.mode not in Mode.parallel_modes()
):
return self.create_iterable(
messages=messages,
response_model=get_args(response_model)[0],
max_retries=max_retries,
context=context,
strict=strict,
hooks=hooks, # Pass the per-call hooks to create_iterable
**kwargs,
)
return await self.create_fn(
response_model=response_model,
context=context,
max_retries=max_retries,
messages=messages,
strict=strict,
hooks=combined_hooks,
**kwargs,
)
async def create_partial( # type: ignore[override] # ty: ignore[invalid-method-override]
self,
response_model: type[T],
messages: list[ChatCompletionMessageParam],
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> AsyncGenerator[T, None]:
kwargs = self.handle_kwargs(kwargs)
kwargs["stream"] = True
# Combine client hooks with per-call hooks
combined_hooks = self.hooks
if hooks is not None:
combined_hooks = self.hooks + hooks
async for item in await self.create_fn(
response_model=Partial[response_model], # type: ignore
context=context,
max_retries=max_retries,
messages=messages,
strict=strict,
hooks=combined_hooks,
**kwargs,
):
yield item
async def create_iterable( # type: ignore[override] # ty: ignore[invalid-method-override]
self,
messages: list[ChatCompletionMessageParam],
response_model: type[T],
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> AsyncGenerator[T, None]:
kwargs = self.handle_kwargs(kwargs)
kwargs["stream"] = True
# Combine client hooks with per-call hooks
combined_hooks = self.hooks
if hooks is not None:
combined_hooks = self.hooks + hooks
iterable_model: Any = Iterable
async for item in await self.create_fn(
response_model=iterable_model[response_model],
context=context,
max_retries=max_retries,
messages=messages,
strict=strict,
hooks=combined_hooks,
**kwargs,
):
yield item
async def create_with_completion( # type: ignore[override] # ty: ignore[invalid-method-override]
self,
messages: list[ChatCompletionMessageParam],
response_model: type[T],
max_retries: int | AsyncRetrying = 3,
context: dict[str, Any] | None = None,
strict: bool = True,
hooks: Hooks | None = None,
**kwargs: Any,
) -> tuple[T, Any]:
kwargs = self.handle_kwargs(kwargs)
# Combine client hooks with per-call hooks
combined_hooks = self.hooks
if hooks is not None:
combined_hooks = self.hooks + hooks
response = await self.create_fn(
response_model=response_model,
context=context,
max_retries=max_retries,
messages=messages,
strict=strict,
hooks=combined_hooks,
**kwargs,
)
return response, response._raw_response
@overload
def from_openai(
client: openai.OpenAI,
mode: Mode = Mode.TOOLS,
**kwargs: Any,
) -> Instructor: ...
@overload
def from_openai(
client: openai.AsyncOpenAI,
mode: Mode = Mode.TOOLS,
**kwargs: Any,
) -> AsyncInstructor: ...
def from_openai(
client: openai.OpenAI | openai.AsyncOpenAI,
mode: Mode = Mode.TOOLS,
**kwargs: Any,
) -> Instructor | AsyncInstructor:
"""Compatibility wrapper for the v2 OpenAI factory."""
from instructor.v2.providers.openai.client import from_openai as from_openai_v2
return from_openai_v2(client=client, mode=mode, **kwargs)
@overload
def from_litellm(
completion: Callable[..., Coroutine[Any, Any, T]],
mode: Mode = Mode.TOOLS,
*,
async_client: Literal[True],
**kwargs: Any,
) -> AsyncInstructor: ...
@overload
def from_litellm(
completion: Callable[..., Awaitable[T]],
mode: Mode = Mode.TOOLS,
*,
async_client: Literal[True],
**kwargs: Any,
) -> AsyncInstructor: ...
@overload
def from_litellm(
completion: Callable[..., object],
mode: Mode = Mode.TOOLS,
*,
async_client: Literal[False] = False,
**kwargs: Any,
) -> Instructor: ...
def from_litellm(
completion: Callable[..., object] | Callable[..., Awaitable[Any]],
mode: Mode = Mode.TOOLS,
*,
async_client: bool | None = None,
**kwargs: Any,
) -> Instructor | AsyncInstructor:
"""Compatibility wrapper for the v2 LiteLLM factory."""
from instructor.v2.providers.litellm.client import from_litellm as from_litellm_v2
if async_client is True:
return from_litellm_v2(
completion=cast(Callable[..., Awaitable[Any]], completion),
mode=mode,
async_client=True,
**kwargs,
)
if async_client is False:
return from_litellm_v2(
completion=completion,
mode=mode,
async_client=False,
**kwargs,
)
return from_litellm_v2(
completion=completion,
mode=mode,
**kwargs,
)