File size: 5,465 Bytes
a63c61f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
daf250b
a63c61f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
daf250b
 
 
 
 
 
a63c61f
 
daf250b
a63c61f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
from fastapi import Depends
from sqlalchemy.orm import Session
from src.infrastructure.database import get_db

# Adapters
from src.infrastructure.adapters.bge_embedder_adapter import BgeEmbedderAdapter
from src.infrastructure.adapters.qdrant_adapter import QdrantAdapter
from src.infrastructure.adapters.bge_reranker_adapter import BgeRerankerAdapter
from src.infrastructure.adapters.openai_adapter import OpenAiAdapter
from src.infrastructure.adapters.ollama_adapter import OllamaAdapter
from src.infrastructure.adapters.groq_adapter import GroqAdapter
from src.infrastructure.adapters.gemini_adapter import GeminiAdapter
from src.infrastructure.adapters.together_adapter import TogetherAdapter
from src.infrastructure.adapters.huggingface_adapter import HuggingFaceAdapter
from src.infrastructure.adapters.clickhouse_adapter import ClickHouseAdapter
from src.infrastructure.adapters.postgres_adapter import PostgresAdapter
from src.infrastructure.adapters.redis_adapter import RedisAdapter
from src.infrastructure.adapters.duckduckgo_adapter import DuckDuckGoAdapter
from src.infrastructure.adapters.newsapi_adapter import NewsAPIAdapter

# Hybrid Search Components
from src.core.orchestrator.query_orchestrator import QueryOrchestrator
from src.core.ranking.hybrid_result_ranker import HybridResultRanker

# Use Cases
from src.core.use_cases.search_use_case import SearchUseCase
from src.core.use_cases.rag_chat_use_case import RagChatUseCase
from src.core.use_cases.analytics_use_case import AnalyticsUseCase

# Global Singletons for Stateless Adapters to avoid reloading models per request
embedder_adapter = BgeEmbedderAdapter()
qdrant_adapter = QdrantAdapter()
reranker_adapter = BgeRerankerAdapter()
openai_adapter = OpenAiAdapter()
ollama_adapter = OllamaAdapter()
groq_adapter = GroqAdapter()
gemini_adapter = GeminiAdapter()
together_adapter = TogetherAdapter()
huggingface_adapter = HuggingFaceAdapter()
clickhouse_adapter = ClickHouseAdapter()
redis_adapter = RedisAdapter()

# Hybrid Search Singletons
from src.core.config import settings
duckduckgo_adapter = DuckDuckGoAdapter(
    timeout=settings.LIVE_SEARCH_TIMEOUT,
    max_results=settings.LIVE_SEARCH_MAX_RESULTS
)
newsapi_adapter = NewsAPIAdapter(
    api_key=settings.NEWSAPI_KEY,
    timeout=settings.NEWSAPI_TIMEOUT,
    max_results=settings.NEWSAPI_MAX_RESULTS
) if settings.NEWSAPI_ENABLED else None

query_orchestrator = QueryOrchestrator(
    live_search_adapter=duckduckgo_adapter,
    newsapi_adapter=newsapi_adapter,
    enable_hybrid=settings.ENABLE_HYBRID_SEARCH,
    default_live_weight=settings.LIVE_SEARCH_WEIGHT,
    default_db_weight=settings.DB_SEARCH_WEIGHT
)
hybrid_result_ranker = HybridResultRanker(reranker=reranker_adapter)

# Model Pre-warming (Triggered dynamically if needed, usually on startup)
def prewarm_models():
    embedder_adapter._load_model()
    reranker_adapter._load_model()

# --- Dependency Providers ---

def get_embedder_port():
    return embedder_adapter

def get_vector_store_port():
    return qdrant_adapter

def get_reranker_port():
    return reranker_adapter

from src.core.config import settings
def get_llm_port():
    provider = settings.LLM_PROVIDER.lower()
    if provider == "groq":
        return groq_adapter
    elif provider == "gemini":
        return gemini_adapter
    elif provider == "together":
        return together_adapter
    elif provider == "huggingface" or provider == "hf":
        return huggingface_adapter
    elif provider == "ollama":
        return ollama_adapter
    return openai_adapter

def get_analytics_db_port():
    return clickhouse_adapter

def get_chat_history_port(db: Session = Depends(get_db)):
    return PostgresAdapter(db)

def get_cache_port():
    return redis_adapter

def get_live_search_port():
    return duckduckgo_adapter

def get_query_orchestrator():
    return query_orchestrator

def get_hybrid_ranker():
    return hybrid_result_ranker

# --- Use Case Providers ---

def get_search_use_case(
    embedder=Depends(get_embedder_port),
    vector_store=Depends(get_vector_store_port)
):
    return SearchUseCase(embedder, vector_store)

def get_rag_chat_use_case(
    embedder=Depends(get_embedder_port),
    vector_store=Depends(get_vector_store_port),
    reranker=Depends(get_reranker_port),
    llm=Depends(get_llm_port),
    chat_history=Depends(get_chat_history_port),
    analytics_db=Depends(get_analytics_db_port),
    cache=Depends(get_cache_port),
    orchestrator=Depends(get_query_orchestrator),
    hybrid_ranker=Depends(get_hybrid_ranker)
):
    return RagChatUseCase(
        embedder=embedder,
        vector_store=vector_store,
        reranker=reranker,
        llm=llm,
        chat_history_db=chat_history,
        analytics_db=analytics_db,
        cache=cache,
        orchestrator=orchestrator,
        hybrid_ranker=hybrid_ranker
    )

from src.core.use_cases.account_use_case import AccountUseCase
from src.core.use_cases.agent_router_use_case import AgentRouterUseCase

def get_analytics_use_case(
    analytics_db=Depends(get_analytics_db_port)
):
    return AnalyticsUseCase(analytics_db)

def get_account_use_case():
    return AccountUseCase()

def get_agent_router_use_case(
    llm=Depends(get_llm_port),
    rag_chat=Depends(get_rag_chat_use_case),
    account=Depends(get_account_use_case),
    chat_history=Depends(get_chat_history_port)
):
    return AgentRouterUseCase(llm=llm, rag_chat=rag_chat, account=account, chat_history_db=chat_history)