fix(llm): konfiguracja per dostawca — przelacznik w UI byl iluzja
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m53s
Testy / Build obrazu silnika B (swisseph) (push) Failing after 25s
Testy / Kontrola składni wszystkich warstw (push) Successful in 21s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m49s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m55s
Testy / Build obrazu silnika B (swisseph) (pull_request) Failing after 28s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 23s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m53s
Testy / Build obrazu silnika B (swisseph) (push) Failing after 25s
Testy / Kontrola składni wszystkich warstw (push) Successful in 21s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m49s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m55s
Testy / Build obrazu silnika B (swisseph) (pull_request) Failing after 28s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 23s
UI pozwala wybrac dostawce przy KAZDYM zadaniu, ale factory czytalo jedna wspolna trojke LLM_MODEL / LLM_BASE_URL / LLM_API_KEY dla wszystkich. Na klastrze LLM_BASE_URL trzeba ustawic na lokalny model (localhost:11434 w podzie nie istnieje) — i wtedy: - wybor „OpenAI" wysylal zadanie do Ollamy, - LLM_MODEL=llama3.1:8b kazal Anthropic uzyc modelu llama, - jeden LLM_API_KEY nie moze byc kluczem OpenAI i Anthropic naraz. Czyli nie bylo miejsca, w ktore dalo sie sensownie wpisac klucze do chmury. - konfiguracja per dostawca: <DOSTAWCA>_MODEL / _BASE_URL / _API_KEY (LOCAL_*, OPENAI_*, ANTHROPIC_*), - zgodnosc wstecz: wspolne LLM_* dziala nadal, ale stosuje sie WYLACZNIE do dostawcy domyslnego (LLM_PROVIDER) — instalacja jednodostawcowa bez zmian, - Anthropic dostal brakujaca walidacje klucza (mial ja tylko OpenAI), - komunikat bledu wskazuje konkretna zmienna do ustawienia. Testy regresyjne pilnuja, ze ustawienia jednego dostawcy NIE przeciekaja na pozostalych. Calosc: 143 passed / 1 skipped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4,13 +4,26 @@ Domyślny jest **model lokalny**: prompt niesie oryginalne opisy z baz, więc
|
||||
domyślnie nic nie opuszcza naszej sieci (LOG-32). Chmurę włącza się świadomie —
|
||||
przez konfigurację albo pojedyncze żądanie.
|
||||
|
||||
Konfiguracja jest **per dostawca**, bo UI pozwala przełączać go przy każdym żądaniu.
|
||||
Wspólne `LLM_*` nie wystarczy: ustawienie `LLM_BASE_URL` na lokalny model kierowałoby
|
||||
tam także żądania do OpenAI, a `LLM_MODEL=llama3.1:8b` kazałoby Anthropic użyć modelu
|
||||
llama. Dlatego każdy dostawca ma własny komplet zmiennych.
|
||||
|
||||
Zmienne środowiskowe:
|
||||
LLM_PROVIDER local (domyślnie) | openai | anthropic
|
||||
LLM_MODEL nazwa modelu (domyślna zależy od dostawcy)
|
||||
LLM_BASE_URL adres API (domyślnie: lokalny serwer zgodny z OpenAI)
|
||||
LLM_API_KEY klucz — WYŁĄCZNIE z sekretu; niepotrzebny dla modelu lokalnego
|
||||
LLM_TIMEOUT sekundy (domyślnie 120)
|
||||
LLM_MAX_TOKENS limit długości odpowiedzi (domyślnie 2000)
|
||||
LLM_PROVIDER local (domyślnie) | openai | anthropic — dostawca domyślny
|
||||
LLM_TIMEOUT sekundy (domyślnie 120)
|
||||
LLM_MAX_TOKENS limit długości odpowiedzi (domyślnie 2000)
|
||||
|
||||
<DOSTAWCA>_MODEL / _BASE_URL / _API_KEY — konfiguracja konkretnego dostawcy:
|
||||
LOCAL_MODEL, LOCAL_BASE_URL (klucz zwykle zbędny)
|
||||
OPENAI_MODEL, OPENAI_BASE_URL, OPENAI_API_KEY
|
||||
ANTHROPIC_MODEL, ANTHROPIC_BASE_URL, ANTHROPIC_API_KEY
|
||||
|
||||
Klucze WYŁĄCZNIE z sekretu — nigdy w repo, w UI ani w logach.
|
||||
|
||||
Zgodność wstecz: wspólne `LLM_MODEL` / `LLM_BASE_URL` / `LLM_API_KEY` nadal działają,
|
||||
ale stosują się TYLKO do dostawcy domyślnego (LLM_PROVIDER) — czyli konfiguracja
|
||||
instalacji jednodostawcowej zostaje nietknięta, a pozostali dostawcy jej nie dziedziczą.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -49,20 +62,39 @@ def timeout() -> float:
|
||||
return float(os.getenv("LLM_TIMEOUT", "120"))
|
||||
|
||||
|
||||
def setting(provider: str, suffix: str, fallback: str = "") -> str:
|
||||
"""Ustawienie dostawcy: <DOSTAWCA>_<SUFIKS> → LLM_<SUFIKS> → wbudowana domyślna.
|
||||
|
||||
Wspólne `LLM_*` stosuje się WYŁĄCZNIE do dostawcy domyślnego — inaczej adres
|
||||
lokalnego modelu przejąłby żądania do chmury (i odwrotnie).
|
||||
"""
|
||||
specific = os.getenv(f"{provider.upper()}_{suffix}")
|
||||
if specific:
|
||||
return specific
|
||||
if provider == default_provider_name():
|
||||
generic = os.getenv(f"LLM_{suffix}")
|
||||
if generic:
|
||||
return generic
|
||||
return fallback
|
||||
|
||||
|
||||
def build_provider(name: str | None = None) -> LLMProvider:
|
||||
name = (name or default_provider_name()).lower()
|
||||
if name not in PROVIDERS:
|
||||
raise LLMError(f"Nieznany dostawca LLM: {name!r} (dostępne: {', '.join(PROVIDERS)})")
|
||||
|
||||
model = os.getenv("LLM_MODEL") or _DEFAULT_MODEL[name]
|
||||
base_url = os.getenv("LLM_BASE_URL") or _DEFAULT_URL[name]
|
||||
api_key = os.getenv("LLM_API_KEY", "")
|
||||
model = setting(name, "MODEL", _DEFAULT_MODEL[name])
|
||||
base_url = setting(name, "BASE_URL", _DEFAULT_URL[name])
|
||||
api_key = setting(name, "API_KEY")
|
||||
|
||||
if name in (OPENAI, ANTHROPIC) and not api_key:
|
||||
raise LLMError(
|
||||
f"Brak klucza dla dostawcy {name} — ustaw {name.upper()}_API_KEY "
|
||||
f"(z sekretu). Model lokalny klucza nie wymaga."
|
||||
)
|
||||
if name == ANTHROPIC:
|
||||
return AnthropicProvider(base_url, model, api_key, timeout())
|
||||
if name == OPENAI:
|
||||
if not api_key:
|
||||
raise LLMError("Brak LLM_API_KEY — dostawca openai wymaga klucza.")
|
||||
return ChatCompletionsProvider(OPENAI, base_url, model, api_key, timeout(),
|
||||
leaves_lan=True)
|
||||
# lokalny — klucz zwykle zbędny; treść NIE opuszcza sieci
|
||||
|
||||
Reference in New Issue
Block a user