fix: timeout do provedor nunca chegava ao httpx; endpoint agora visível
Causa do 'Provedor de LLM indisponível' no ambiente com Ollama local foi externa: OLLAMA_BASE_URL exportada no shell (http://localhost:11434/v1) vence o .env na interpolação do docker-compose, e localhost dentro do container é o próprio container. Nada no app indicava a URL em uso. Dois defeitos de código que tornavam isso indetectável — e um deles produziria a mesma mensagem mesmo com a URL correta: - _BaseProvider criava o httpx.AsyncClient com o atributo de classe (120 s) e as subclasses atribuíam self.timeout depois. O httpx congela o timeout na construção, então os 300 s pedidos pelo Ollama nunca valeram: um primeiro atendimento com modelo frio era cortado em 120 s com exatamente a mensagem 'provedor indisponível'. O timeout agora é passado ao super(). - LLMProviderError de conexão não citava o endereço tentado; o log dizia só 'All connection attempts failed'. Passa a incluir a endpoint, com credenciais user:pass@ redigidas. /api/health expõe llm_endpoint para comparação direta com o .env. README e .env.example documentam a precedência shell > .env, o fato de /v1 ser a superfície OpenAI-compatível (o adaptador usa /api/chat nativo) e a latência medida do primeiro atendimento.
This commit is contained in:
1 parent
ebf430c535
commit
68861b502c
7 files changed
+188
-8
No files matched your search
@@ -278,3 +278,44 @@ def test_embedder_fallback_is_surfaced_in_status(monkeypatch, tmp_path):
|
||||
|
||||
assert any("semântica" in error for error in body["errors"])
|
||||
assert app.state.services.embedder.name == HashEmbedder.name
|
||||
|
||||
|
||||
def test_health_reports_the_llm_endpoint_in_use(client):
|
||||
"""/api/health precisa mostrar a URL efetiva, não a que o .env parece dizer.
|
||||
|
||||
Variável de shell vence o `.env` na interpolação do compose: um
|
||||
`OLLAMA_BASE_URL` herdado do ambiente apontando para `localhost` dentro do
|
||||
container derrubava o chat sem nenhum indício do endereço tentado.
|
||||
"""
|
||||
body = client.get("/api/health").json()
|
||||
|
||||
assert body["llm_provider"] == "stub"
|
||||
assert body["llm_endpoint"] is None, "o stub não tem endpoint"
|
||||
|
||||
|
||||
def test_health_exposes_ollama_endpoint_without_credentials(tmp_path):
|
||||
"""A endpoint vai para o health, mas credenciais na URL não podem vazar."""
|
||||
from app.llm import OllamaProvider
|
||||
|
||||
settings = Settings(
|
||||
corpus_dir=tmp_path / "corpus",
|
||||
vector_db_dir=tmp_path / "vector_db",
|
||||
embedding_model="hash-test",
|
||||
llm_provider="ollama",
|
||||
auto_index=False,
|
||||
)
|
||||
provider = OllamaProvider(
|
||||
base_url="http://user:segredo@ollama:11434", model="m"
|
||||
)
|
||||
app = create_app(
|
||||
settings=settings,
|
||||
store=InMemoryVectorStore(),
|
||||
embedder=HashEmbedder(dimensions=64),
|
||||
provider=provider,
|
||||
indexer=FakeIndexer(),
|
||||
)
|
||||
|
||||
body = TestClient(app).get("/api/health").json()
|
||||
|
||||
assert "segredo" not in body["llm_endpoint"]
|
||||
assert body["llm_endpoint"].endswith("ollama:11434")
|
||||
Reference in new issue
Block a user