mirror of
https://github.com/NCBM/plyngent.git
synced 2026-07-23 05:55:16 +08:00
core/runtime: map Provider config to protocol clients
create_client supports openai, openai-compatible, and deepseek (openai convention); anthropic and deepseek anthropic raise.
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
from .client_factory import ProviderNotSupportedError as ProviderNotSupportedError
|
||||||
|
from .client_factory import create_client as create_client
|
||||||
|
from .client_factory import provider_to_openai_config as provider_to_openai_config
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from plyngent.config.models import (
|
||||||
|
DeepseekProvider,
|
||||||
|
OpenAICompatibleProvider,
|
||||||
|
OpenAIProvider,
|
||||||
|
Provider,
|
||||||
|
)
|
||||||
|
from plyngent.lmproto.deepseek import DeepseekOpenAIClient
|
||||||
|
from plyngent.lmproto.openai_compatible import OpenAIClient, OpenAIConfig
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from collections.abc import Mapping
|
||||||
|
|
||||||
|
DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1"
|
||||||
|
DEFAULT_DEEPSEEK_BASE_URL = "https://api.deepseek.com/v1"
|
||||||
|
|
||||||
|
type OpenAICompatibleClient = OpenAIClient | DeepseekOpenAIClient
|
||||||
|
|
||||||
|
|
||||||
|
class ProviderNotSupportedError(NotImplementedError):
|
||||||
|
"""Raised when a provider preset cannot be turned into a runtime client."""
|
||||||
|
|
||||||
|
|
||||||
|
def provider_to_openai_config(provider: OpenAIProvider | OpenAICompatibleProvider | DeepseekProvider) -> OpenAIConfig:
|
||||||
|
"""Map a provider config entry to :class:`OpenAIConfig`."""
|
||||||
|
if isinstance(provider, OpenAIProvider):
|
||||||
|
base_url = provider.url or DEFAULT_OPENAI_BASE_URL
|
||||||
|
elif isinstance(provider, DeepseekProvider):
|
||||||
|
base_url = provider.url or DEFAULT_DEEPSEEK_BASE_URL
|
||||||
|
else:
|
||||||
|
base_url = provider.url
|
||||||
|
if not base_url:
|
||||||
|
msg = "openai-compatible provider requires a non-empty url"
|
||||||
|
raise ProviderNotSupportedError(msg)
|
||||||
|
return OpenAIConfig(
|
||||||
|
access_key_or_token=provider.access_key_or_token,
|
||||||
|
base_url=base_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _deepseek_convention(extras: Mapping[str, str]) -> str:
|
||||||
|
return extras.get("convention", "openai").lower()
|
||||||
|
|
||||||
|
|
||||||
|
def create_client(provider: Provider) -> OpenAICompatibleClient:
|
||||||
|
"""Build a protocol client for the given provider config entry.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ProviderNotSupportedError: When the provider preset (or DeepSeek convention)
|
||||||
|
has no implemented client yet.
|
||||||
|
"""
|
||||||
|
if isinstance(provider, OpenAIProvider):
|
||||||
|
return OpenAIClient(provider_to_openai_config(provider))
|
||||||
|
if isinstance(provider, OpenAICompatibleProvider):
|
||||||
|
return OpenAIClient(provider_to_openai_config(provider))
|
||||||
|
if isinstance(provider, DeepseekProvider):
|
||||||
|
convention = _deepseek_convention(provider.extras)
|
||||||
|
if convention in {"openai", "openai_compat", "openai-compatible"}:
|
||||||
|
return DeepseekOpenAIClient(provider_to_openai_config(provider))
|
||||||
|
if convention == "anthropic":
|
||||||
|
msg = "deepseek anthropic convention is not implemented"
|
||||||
|
raise ProviderNotSupportedError(msg)
|
||||||
|
msg = f"unknown deepseek convention {convention!r}"
|
||||||
|
raise ProviderNotSupportedError(msg)
|
||||||
|
# Remaining Provider variant: AnthropicProvider
|
||||||
|
msg = "anthropic provider client is not implemented"
|
||||||
|
raise ProviderNotSupportedError(msg)
|
||||||
Reference in New Issue
Block a user