File size: 4,016 Bytes
7edb85f 849c819 7edb85f 819cf97 7edb85f 819cf97 849c819 819cf97 7edb85f 819cf97 849c819 819cf97 849c819 819cf97 849c819 819cf97 849c819 819cf97 849c819 819cf97 849c819 819cf97 849c819 819cf97 7edb85f 819cf97 7edb85f 849c819 819cf97 7edb85f 819cf97 7edb85f 849c819 7edb85f 819cf97 7edb85f 849c819 7edb85f 819cf97 7edb85f 849c819 7edb85f 849c819 7edb85f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | from types import SimpleNamespace
from typing import Any
from huggingface_hub import InferenceClient
from config import HF_MODEL, HF_PROVIDER, HF_TOKEN
class LLMClient:
"""
Hugging Face Inference Providers üzerinden sohbet tamamlama
ve structured output üretir.
Dönen veri yapısı eski Ollama istemcisiyle uyumludur:
response.message.content
response.message.thinking
"""
def __init__(self) -> None:
if not HF_TOKEN:
raise RuntimeError(
"HF_TOKEN bulunamadı. Hugging Face Space ayarlarında "
"HF_TOKEN adında bir Secret oluşturun."
)
self.client = InferenceClient(
provider=HF_PROVIDER,
api_key=HF_TOKEN,
timeout=90,
)
self.model = HF_MODEL
@staticmethod
def _create_response(
content: str,
thinking: str = "",
) -> SimpleNamespace:
return SimpleNamespace(
message=SimpleNamespace(
content=content,
thinking=thinking,
)
)
def _chat_completion(
self,
request_kwargs: dict[str, Any],
) -> Any:
"""
Planner için JSON Schema kullanır.
Responder için standart chat completion çağrısı yapar.
"""
schema = request_kwargs.pop("_schema", None)
try:
if schema is not None:
request_kwargs["response_format"] = {
"type": "json_schema",
"json_schema": {
"name": "ToolPlan",
"schema": schema,
"strict": True,
},
}
return self.client.chat_completion(
**request_kwargs
)
except Exception as exc:
call_type = (
"structured output"
if schema is not None
else "standart chat completion"
)
raise RuntimeError(
"Hugging Face LLM çağrısı başarısız oldu.\n"
f"Çağrı türü: {call_type}\n"
f"Model: {self.model}\n"
f"Provider: {HF_PROVIDER}\n"
f"Hata türü: {type(exc).__name__}\n"
f"Hata: {repr(exc)}"
) from exc
def generate(
self,
messages: list[dict[str, str]],
schema: dict[str, Any] | None = None,
think: bool = True,
) -> SimpleNamespace:
"""
Modele mesaj gönderir.
`think` parametresi Planner ve Responder kodlarıyla
geriye dönük uyumluluk amacıyla korunmaktadır.
"""
request_kwargs: dict[str, Any] = {
"model": self.model,
"messages": messages,
"temperature": 0.0,
"max_tokens": 1024,
"_schema": schema,
}
response = self._chat_completion(
request_kwargs=request_kwargs,
)
choices = getattr(response, "choices", None)
if not choices:
raise RuntimeError(
"Hugging Face modeli boş bir choices listesi döndürdü."
)
message = getattr(choices[0], "message", None)
if message is None:
raise RuntimeError(
"Hugging Face yanıtında message alanı bulunamadı."
)
content = getattr(message, "content", None)
if content is None:
raise RuntimeError(
"Hugging Face yanıtında content alanı boş döndü."
)
if not isinstance(content, str):
content = str(content)
content = content.strip()
if not content:
raise RuntimeError(
"Hugging Face modeli boş metin döndürdü."
)
return self._create_response(
content=content,
thinking="",
)
llm = LLMClient() |