163ace4283
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m14s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 10m19s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 46s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 27s
build / build (push) Successful in 1m18s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m45s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 10m2s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 36s
Testy / Kontrola składni wszystkich warstw (push) Successful in 23s
Uzytkownik wybiera nie tylko dostawce, ale konkretny model — Fable czy Opus u Anthropica, gpt-4o-mini czy gpt-5 u OpenAI, cokolwiek ma pobrane lokalnie. - app/llm/catalog.py: podpowiedzi modeli per dostawca wraz z oknem kontekstu, nadpisywalne przez <DOSTAWCA>_MODELS; GET /llm/models wystawia je dla UI. - Pole modelu w UI jest TEKSTOWE z datalista, nie zamknietym <select> — konto moze miec dostep do modeli, o ktorych kod nie wie, a nowe wychodza szybciej, niz aktualizuje sie katalog. Puste pole = model domyslny dostawcy. - static/models.js: zmiana dostawcy przelacza podpowiedzi, podmienia placeholder na model domyslny i pokazuje okno kontekstu wybranego modelu. - build_provider(name, model) — model z zadania wygrywa nad konfiguracja. WAZNE (znalezione przy tescie e2e): liczenie budzetu „maksymalny kontekst modelu" szlo przez build_provider(), ktory WYMAGA klucza API — bez klucza budzet cicho spadal do wartosci zapasowej i byl identyczny dla wszystkich modeli Anthropic. Budzet zalezy wylacznie od okna kontekstu, wiec doszlo resolve_model(), ktore rozwiazuje nazwe modelu bez budowania dostawcy. Teraz budzet realnie sie rozni: Opus/Fable 3,48 mln znakow, Haiku 536 tys., gpt-4o-mini 438 tys., llama3.1 8 tys. Pewnosc danych w katalogu: modele Anthropic pochodza z oficjalnej dokumentacji API (okna i limity zgodne z limits.py); modele OpenAI to podpowiedzi, ktorych nie weryfikowalem; lokalne zaleza od tego, co masz pobrane. Testy: 174 passed / 1 skipped (logika) + 17 (prezentacja). Nowy test strukturalny pilnuje, ze KAZDE wywolanie w dol niesie wybrany model i dostawce — dokladnie ta klasa bledu zlapala brakujacy parametr przy horoskopie okresowym. Zweryfikowane w przegladarce: przelaczanie dostawcy podmienia liste modeli. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
76 lines
2.9 KiB
Python
76 lines
2.9 KiB
Python
"""Katalog modeli do wyboru w UI (LOG-31).
|
|
|
|
To są **podpowiedzi**, nie zamknięta lista. Pole modelu w UI jest tekstowe z
|
|
datalistą, więc można wpisać dowolny identyfikator — konto może mieć dostęp do
|
|
modeli, których tu nie ma, a nowe wychodzą szybciej, niż aktualizuje się kod.
|
|
Puste pole = model domyślny dostawcy.
|
|
|
|
Uwaga o pewności danych:
|
|
* modele **Anthropic** pochodzą z oficjalnej dokumentacji API (okna kontekstu
|
|
i limity wyjścia zgadzają się z `app/llm/limits.py`);
|
|
* modele **OpenAI** to podpowiedzi — nie weryfikowałem ich katalogu, więc
|
|
traktuj je jako wygodę, a nie źródło prawdy;
|
|
* modele **lokalne** zależą wyłącznie od tego, co masz pobrane w Ollamie/vLLM.
|
|
|
|
Katalog można nadpisać/rozszerzyć zmienną `<DOSTAWCA>_MODELS` (lista po przecinku),
|
|
np. `OPENAI_MODELS="gpt-5,gpt-4o"`.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
from app.llm.limits import limits_for
|
|
|
|
# dostawca -> [(id modelu, krótki opis dla człowieka)]
|
|
_CATALOG: dict[str, list[tuple[str, str]]] = {
|
|
"anthropic": [
|
|
("claude-opus-4-8", "Opus 4.8 — domyślny, bardzo zdolny, 1M kontekstu"),
|
|
("claude-fable-5", "Fable 5 — najbardziej zdolny, do najtrudniejszych zadań"),
|
|
("claude-sonnet-5", "Sonnet 5 — szybszy i tańszy, jakość blisko Opusa"),
|
|
("claude-opus-4-7", "Opus 4.7 — poprzednia generacja Opusa"),
|
|
("claude-haiku-4-5", "Haiku 4.5 — najszybszy i najtańszy, mniejsze okno"),
|
|
],
|
|
"openai": [
|
|
("gpt-4o-mini", "GPT-4o mini — tani i szybki"),
|
|
("gpt-4o", "GPT-4o"),
|
|
("gpt-5", "GPT-5 — jeśli Twoje konto ma dostęp"),
|
|
("gpt-4.1", "GPT-4.1"),
|
|
("gpt-4.1-mini", "GPT-4.1 mini"),
|
|
],
|
|
"local": [
|
|
("llama3.1:8b", "Llama 3.1 8B"),
|
|
("llama3.2", "Llama 3.2"),
|
|
("qwen2.5", "Qwen 2.5 — większe okno kontekstu"),
|
|
("mistral", "Mistral"),
|
|
],
|
|
}
|
|
|
|
|
|
def models_for(provider: str) -> list[dict]:
|
|
"""Podpowiedzi modeli dla dostawcy, wraz z oknem kontekstu.
|
|
|
|
Okno kontekstu podajemy, bo wprost przekłada się na opcję „maksymalny
|
|
kontekst modelu" — użytkownik widzi, na ile budżetu promptu może liczyć.
|
|
"""
|
|
override = os.getenv(f"{provider.upper()}_MODELS", "").strip()
|
|
if override:
|
|
entries = [(m.strip(), "") for m in override.split(",") if m.strip()]
|
|
else:
|
|
entries = _CATALOG.get(provider, [])
|
|
|
|
out = []
|
|
for model_id, label in entries:
|
|
context_window, max_output = limits_for(provider, model_id)
|
|
out.append({
|
|
"id": model_id,
|
|
"label": label or model_id,
|
|
"context_window": context_window,
|
|
"max_output": max_output,
|
|
})
|
|
return out
|
|
|
|
|
|
def catalog() -> dict[str, list[dict]]:
|
|
"""Pełny katalog dla UI — jedno żądanie zamiast trzech."""
|
|
return {provider: models_for(provider) for provider in ("local", "anthropic", "openai")}
|