Files

93 lines
3.3 KiB
Python
Raw Permalink Normal View History

2026-03-19 22:54:29 +03:30
"""
2026-04-24 01:23:56 +03:30
Adapter Pattern برای API providers — سوئیچ بین GapGPT، Avalai و ArvanCloud AI.
2026-03-19 22:54:29 +03:30
"""
import logging
import os
2026-04-24 17:40:25 +03:30
try:
from openai import OpenAI
except ImportError: # pragma: no cover - optional for stripped test envs
class OpenAI: # type: ignore[override]
def __init__(self, *args, **kwargs):
raise ImportError("openai package is required for RAG clients.")
2026-03-19 22:54:29 +03:30
from .config import RAGConfig, load_rag_config
logger = logging.getLogger(__name__)
2026-04-02 16:17:48 +03:30
def _mask_secret(value: str | None) -> str:
if not value:
return "<missing>"
if len(value) <= 8:
return "****"
return f"{value[:4]}...{value[-4:]}"
2026-04-24 01:23:56 +03:30
def _get_env_or_value(env_var: str | None, direct_value: str | None) -> str | None:
if env_var:
return os.environ.get(env_var) or direct_value
return direct_value
2026-03-19 22:54:29 +03:30
def get_embedding_client(config: RAGConfig | None = None) -> OpenAI:
"""
ساخت کلاینت OpenAI برای Embedding بر اساس provider فعال.
2026-04-24 01:23:56 +03:30
provider از config.embedding.provider خوانده می‌شود.
2026-03-19 22:54:29 +03:30
"""
cfg = config or load_rag_config()
emb = cfg.embedding
2026-04-24 01:23:56 +03:30
provider = emb.provider or "gapgpt"
logger.info("embedding provider=%s", provider)
2026-03-19 22:54:29 +03:30
2026-04-24 01:23:56 +03:30
if provider == "avalai":
2026-03-19 22:54:29 +03:30
env_var = emb.avalai_api_key_env or emb.api_key_env or "AVALAI_API_KEY"
2026-04-24 01:23:56 +03:30
api_key = _get_env_or_value(env_var, emb.avalai_api_key or emb.api_key)
2026-03-19 22:54:29 +03:30
base_url = emb.avalai_base_url or emb.base_url or "https://api.avalai.ir/v1"
2026-04-24 01:23:56 +03:30
elif provider == "arvancloud":
env_var = emb.arvancloud_api_key_env or "ARVANCLOUD_EMBEDDING_API_KEY"
api_key = _get_env_or_value(env_var, emb.arvancloud_api_key)
base_url = (
emb.arvancloud_base_url
or "https://arvancloudai.ir/gateway/models/Bge-m3/rBA2PgcTC2sfhXwamupI4NvQ8crddUGTYXOsuKVye91PoNuGhbRgpHHNY8sMHBVQWWerZSAi4a0AijUL6YBqY9EW-Y1LhW_0ec6Mxr85GQy41lXiV6M8Od4mvLIeDF-wLRUHIervod0O5ZqGj2MOX8z1zdUpXkCrIS2uDjHlfHBZofledZjsOVDmFZU7IYfvkA__ljQqNeKXSFgpwUR7SmsbRUXGTDB2moLdeRq9zBpQIw/v1"
)
2026-03-19 22:54:29 +03:30
else:
env_var = emb.api_key_env or "GAPGPT_API_KEY"
2026-04-24 01:23:56 +03:30
api_key = _get_env_or_value(env_var, emb.api_key)
2026-03-19 22:54:29 +03:30
base_url = emb.base_url or "https://api.gapgpt.app/v1"
2026-04-02 16:17:48 +03:30
logger.info(
"embedding base_url=%s api_key=%s",
base_url,
_mask_secret(api_key),
)
2026-03-19 22:54:29 +03:30
return OpenAI(api_key=api_key, base_url=base_url)
def get_chat_client(config: RAGConfig | None = None) -> OpenAI:
"""
ساخت کلاینت OpenAI برای Chat/LLM بر اساس provider فعال.
2026-03-22 03:08:27 +03:30
provider از config.llm.provider خوانده می‌شود.
2026-03-19 22:54:29 +03:30
"""
cfg = config or load_rag_config()
llm = cfg.llm
2026-03-22 03:08:27 +03:30
provider = llm.provider or cfg.embedding.provider
2026-03-19 22:54:29 +03:30
2026-04-02 16:17:48 +03:30
logger.info("chat provider=%s", provider)
2026-03-19 22:54:29 +03:30
if provider == "avalai":
env_var = llm.avalai_api_key_env or llm.api_key_env or "AVALAI_API_KEY"
api_key = os.environ.get(env_var)
base_url = llm.avalai_base_url or llm.base_url or "https://api.avalai.ir/v1"
else:
env_var = llm.api_key_env or "GAPGPT_API_KEY"
api_key = os.environ.get(env_var)
base_url = llm.base_url or "https://api.gapgpt.app/v1"
2026-04-02 16:17:48 +03:30
logger.info(
"chat base_url=%s api_key=%s",
base_url,
_mask_secret(api_key),
)
2026-03-19 22:54:29 +03:30
return OpenAI(api_key=api_key, base_url=base_url)