fix(api): enforce global ollama endpoint order
This commit is contained in:
@@ -22,7 +22,7 @@ import httpx
|
||||
import structlog
|
||||
|
||||
from src.services.model_registry import get_model as _get_model
|
||||
from src.services.ollama_endpoint_resolver import resolve_ollama_endpoint
|
||||
from src.services.ollama_endpoint_resolver import resolve_ollama_order
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
@@ -98,7 +98,15 @@ class OllamaEmbeddingService:
|
||||
P1 修復 (2026-03-29): 維度配置化,支援更多模型
|
||||
"""
|
||||
self._model = model
|
||||
self._ollama_url = ollama_url or resolve_ollama_endpoint("embedding")
|
||||
if ollama_url:
|
||||
self._ollama_endpoints = ((ollama_url, "custom"),)
|
||||
else:
|
||||
self._ollama_endpoints = tuple(
|
||||
(endpoint.url, endpoint.provider_name)
|
||||
for endpoint in resolve_ollama_order("embedding")
|
||||
if endpoint.url
|
||||
)
|
||||
self._ollama_url = self._ollama_endpoints[0][0] if self._ollama_endpoints else ""
|
||||
self._timeout = timeout
|
||||
self._default_dimension = default_dimension or self.MODEL_DIMENSIONS.get(
|
||||
model, self.DEFAULT_DIMENSION
|
||||
@@ -142,43 +150,65 @@ class OllamaEmbeddingService:
|
||||
"""
|
||||
client = await self._get_client()
|
||||
|
||||
try:
|
||||
response = await client.post(
|
||||
f"{self._ollama_url}/api/embeddings",
|
||||
json={
|
||||
"model": self._model,
|
||||
"prompt": text,
|
||||
},
|
||||
)
|
||||
response.raise_for_status()
|
||||
last_error: Exception | None = None
|
||||
for endpoint_url, provider_name in self._ollama_endpoints:
|
||||
try:
|
||||
response = await client.post(
|
||||
f"{endpoint_url}/api/embeddings",
|
||||
json={
|
||||
"model": self._model,
|
||||
"prompt": text,
|
||||
},
|
||||
)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
embedding = data.get("embedding", [])
|
||||
data = response.json()
|
||||
embedding = data.get("embedding", [])
|
||||
|
||||
# 更新維度快取
|
||||
if self._dimension is None and embedding:
|
||||
self._dimension = len(embedding)
|
||||
logger.info(
|
||||
"embedding_dimension_detected",
|
||||
# 更新維度快取
|
||||
if self._dimension is None and embedding:
|
||||
self._dimension = len(embedding)
|
||||
logger.info(
|
||||
"embedding_dimension_detected",
|
||||
model=self._model,
|
||||
dimension=self._dimension,
|
||||
provider=provider_name,
|
||||
)
|
||||
|
||||
return embedding
|
||||
|
||||
except httpx.TimeoutException as e:
|
||||
last_error = e
|
||||
logger.error(
|
||||
"embedding_timeout",
|
||||
model=self._model,
|
||||
dimension=self._dimension,
|
||||
text_len=len(text),
|
||||
provider=provider_name,
|
||||
)
|
||||
except httpx.HTTPStatusError as e:
|
||||
last_error = e
|
||||
logger.error(
|
||||
"embedding_http_error",
|
||||
status=e.response.status_code,
|
||||
model=self._model,
|
||||
provider=provider_name,
|
||||
)
|
||||
except Exception as e:
|
||||
last_error = e
|
||||
logger.error(
|
||||
"embedding_error",
|
||||
error=str(e),
|
||||
model=self._model,
|
||||
provider=provider_name,
|
||||
)
|
||||
|
||||
return embedding
|
||||
|
||||
except httpx.TimeoutException as e:
|
||||
logger.error("embedding_timeout", model=self._model, text_len=len(text))
|
||||
raise EmbeddingError(f"Embedding timeout after {self._timeout}s") from e
|
||||
except httpx.HTTPStatusError as e:
|
||||
logger.error(
|
||||
"embedding_http_error",
|
||||
status=e.response.status_code,
|
||||
model=self._model,
|
||||
)
|
||||
raise EmbeddingError(f"Ollama API error: {e.response.status_code}") from e
|
||||
except Exception as e:
|
||||
logger.error("embedding_error", error=str(e), model=self._model)
|
||||
raise EmbeddingError(f"Embedding failed: {e}") from e
|
||||
if isinstance(last_error, httpx.TimeoutException):
|
||||
raise EmbeddingError(f"Embedding timeout after {self._timeout}s") from last_error
|
||||
if isinstance(last_error, httpx.HTTPStatusError):
|
||||
raise EmbeddingError(
|
||||
f"Ollama API error: {last_error.response.status_code}"
|
||||
) from last_error
|
||||
raise EmbeddingError("Embedding failed on all Ollama endpoints") from last_error
|
||||
|
||||
async def embed_batch(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user