feat: add fallback embedding provider

This commit is contained in:
zhayujie
2026-03-09 11:03:31 +08:00
parent 924dc79f00
commit 6be2034110
3 changed files with 57 additions and 26 deletions

View File

@@ -138,24 +138,24 @@ def create_embedding_provider(
) -> EmbeddingProvider: ) -> EmbeddingProvider:
""" """
Factory function to create embedding provider Factory function to create embedding provider
Only supports OpenAI embedding via REST API. Supports "openai" and "linkai" providers (both use OpenAI-compatible REST API).
If initialization fails, caller should fall back to keyword-only search. If initialization fails, caller should fall back to keyword-only search.
Args: Args:
provider: Provider name (only "openai" is supported) provider: Provider name ("openai" or "linkai")
model: Model name (default: text-embedding-3-small) model: Model name (default: text-embedding-3-small)
api_key: OpenAI API key (required) api_key: API key (required)
api_base: API base URL (default: https://api.openai.com/v1) api_base: API base URL
Returns: Returns:
EmbeddingProvider instance EmbeddingProvider instance
Raises: Raises:
ValueError: If provider is not "openai" or api_key is missing ValueError: If provider is unsupported or api_key is missing
""" """
if provider != "openai": if provider not in ("openai", "linkai"):
raise ValueError(f"Only 'openai' provider is supported, got: {provider}") raise ValueError(f"Unsupported embedding provider: {provider}. Use 'openai' or 'linkai'.")
model = model or "text-embedding-3-small" model = model or "text-embedding-3-small"
return OpenAIEmbeddingProvider(model=model, api_key=api_key, api_base=api_base) return OpenAIEmbeddingProvider(model=model, api_key=api_key, api_base=api_base)

View File

@@ -50,28 +50,44 @@ class MemoryManager:
overlap_tokens=self.config.chunk_overlap_tokens overlap_tokens=self.config.chunk_overlap_tokens
) )
# Initialize embedding provider (optional) # Initialize embedding provider (optional, prefer OpenAI, fallback to LinkAI)
self.embedding_provider = None self.embedding_provider = None
if embedding_provider: if embedding_provider:
self.embedding_provider = embedding_provider self.embedding_provider = embedding_provider
else: else:
# Try to create embedding provider, but allow failure # Try OpenAI first
try: try:
# Get API key from environment or config
api_key = os.environ.get('OPENAI_API_KEY') api_key = os.environ.get('OPENAI_API_KEY')
api_base = os.environ.get('OPENAI_API_BASE') api_base = os.environ.get('OPENAI_API_BASE')
if api_key:
self.embedding_provider = create_embedding_provider( self.embedding_provider = create_embedding_provider(
provider=self.config.embedding_provider, provider="openai",
model=self.config.embedding_model, model=self.config.embedding_model,
api_key=api_key, api_key=api_key,
api_base=api_base api_base=api_base
) )
except Exception as e: except Exception as e:
# Embedding provider failed, but that's OK
# We can still use keyword search and file operations
from common.log import logger from common.log import logger
logger.warning(f"[MemoryManager] Embedding provider initialization failed: {e}") logger.warning(f"[MemoryManager] OpenAI embedding failed: {e}")
# Fallback to LinkAI
if self.embedding_provider is None:
try:
linkai_key = os.environ.get('LINKAI_API_KEY')
linkai_base = os.environ.get('LINKAI_API_BASE', 'https://api.link-ai.tech')
if linkai_key:
self.embedding_provider = create_embedding_provider(
provider="linkai",
model=self.config.embedding_model,
api_key=linkai_key,
api_base=f"{linkai_base}/v1"
)
except Exception as e:
from common.log import logger
logger.warning(f"[MemoryManager] LinkAI embedding failed: {e}")
if self.embedding_provider is None:
from common.log import logger
logger.info(f"[MemoryManager] Memory will work with keyword search only (no vector search)") logger.info(f"[MemoryManager] Memory will work with keyword search only (no vector search)")
# Initialize memory flush manager # Initialize memory flush manager

View File

@@ -272,12 +272,11 @@ class AgentInitializer:
from agent.tools import MemorySearchTool, MemoryGetTool from agent.tools import MemorySearchTool, MemoryGetTool
from config import conf from config import conf
# Get OpenAI config # Initialize embedding provider (prefer OpenAI, fallback to LinkAI)
embedding_provider = None
openai_api_key = conf().get("open_ai_api_key", "") openai_api_key = conf().get("open_ai_api_key", "")
openai_api_base = conf().get("open_ai_api_base", "") openai_api_base = conf().get("open_ai_api_base", "")
# Initialize embedding provider
embedding_provider = None
if openai_api_key and openai_api_key not in ["", "YOUR API KEY", "YOUR_API_KEY"]: if openai_api_key and openai_api_key not in ["", "YOUR API KEY", "YOUR_API_KEY"]:
try: try:
embedding_provider = create_embedding_provider( embedding_provider = create_embedding_provider(
@@ -290,6 +289,22 @@ class AgentInitializer:
logger.info("[AgentInitializer] OpenAI embedding initialized") logger.info("[AgentInitializer] OpenAI embedding initialized")
except Exception as e: except Exception as e:
logger.warning(f"[AgentInitializer] OpenAI embedding failed: {e}") logger.warning(f"[AgentInitializer] OpenAI embedding failed: {e}")
if embedding_provider is None:
linkai_api_key = conf().get("linkai_api_key", "") or os.environ.get("LINKAI_API_KEY", "")
linkai_api_base = conf().get("linkai_api_base", "https://api.link-ai.tech")
if linkai_api_key and linkai_api_key not in ["", "YOUR API KEY", "YOUR_API_KEY"]:
try:
embedding_provider = create_embedding_provider(
provider="linkai",
model="text-embedding-3-small",
api_key=linkai_api_key,
api_base=f"{linkai_api_base}/v1"
)
if session_id is None:
logger.info("[AgentInitializer] LinkAI embedding initialized (fallback)")
except Exception as e:
logger.warning(f"[AgentInitializer] LinkAI embedding failed: {e}")
# Create memory manager # Create memory manager
memory_config = MemoryConfig(workspace_root=workspace_root) memory_config = MemoryConfig(workspace_root=workspace_root)