Alphalens / src /utils /config.py
ashish1265659565's picture
Fix HF LLM Groq base URL issue
9fe3f94
Raw
History Blame Contribute Delete
11.2 kB
import json
import os
from dotenv import load_dotenv
load_dotenv()
def _get_env(*names, default=None):
for name in names:
value = os.getenv(name)
if value is None:
continue
value = value.strip().strip('"').strip("'")
if value:
return value
return default
def _get_int(*names, default):
raw_value = _get_env(*names, default=None)
if raw_value is None:
return default
try:
return int(raw_value)
except ValueError:
return default
def _get_float(*names, default):
raw_value = _get_env(*names, default=None)
if raw_value is None:
return default
try:
return float(raw_value)
except ValueError:
return default
def _get_bool(*names, default=False):
raw_value = _get_env(*names, default=None)
if raw_value is None:
return default
normalized = raw_value.strip().lower()
if normalized in {"1", "true", "yes", "y", "on"}:
return True
if normalized in {"0", "false", "no", "n", "off"}:
return False
return default
def _get_list(*names, default=None, separator=","):
raw_value = _get_env(*names, default=None)
if raw_value is None:
return list(default) if default is not None else []
values = [item.strip() for item in raw_value.split(separator) if item.strip()]
if values:
return values
return list(default) if default is not None else []
def _get_dict(*names, default=None):
raw_value = _get_env(*names, default=None)
if raw_value is None:
return dict(default) if default is not None else {}
try:
parsed = json.loads(raw_value)
except json.JSONDecodeError:
return dict(default) if default is not None else {}
if isinstance(parsed, dict):
normalized = {}
for key, value in parsed.items():
if key is None or value is None:
continue
normalized[str(key).lower()] = str(value).lower()
return normalized
return dict(default) if default is not None else {}
class Config:
OPENAI_API_KEYS = _get_list("OPENAI_API_KEY", "XAI_API_KEY", "GROQ_API_KEY")
OPENAI_BASE_URL = _get_env("OPENAI_BASE_URL", "XAI_BASE_URL", "GROQ_BASE_URL", default="https://api.groq.com/openai/v1")
OPENAI_EMBEDDINGS_ENABLED = _get_bool("OPENAI_EMBEDDINGS_ENABLED", default=True)
OPENAI_FALLBACK_TO_LOCAL_ON_ERROR = _get_bool(
"OPENAI_FALLBACK_TO_LOCAL_ON_ERROR",
default=True,
)
EMBEDDING_FALLBACK_TO_LOCAL_ON_ERROR = _get_bool(
"EMBEDDING_FALLBACK_TO_LOCAL_ON_ERROR",
default=True,
)
EMBEDDING_BACKEND = _get_env("EMBEDDING_BACKEND", default="fastembed")
EMBEDDING_MODEL = _get_env(
"EMBEDDING_MODEL",
default="BAAI/bge-large-en-v1.5",
)
EMBEDDING_NORMALIZE = _get_bool("EMBEDDING_NORMALIZE", default=True)
EMBEDDING_DEVICE = _get_env("EMBEDDING_DEVICE", default="cpu")
EMBEDDING_TRUST_REMOTE_CODE = _get_bool("EMBEDDING_TRUST_REMOTE_CODE", default=False)
LLM_MODEL = _get_env("LLM_MODEL", default="llama-3.3-70b-versatile")
LLM_ENABLED = _get_bool("LLM_ENABLED", default=True)
SELF_RAG_ENABLED = _get_bool("SELF_RAG_ENABLED", default=True)
MAX_REFLECTION_LOOPS = _get_int("MAX_REFLECTION_LOOPS", default=2)
GRADER_LLM_MODEL = _get_env("GRADER_LLM_MODEL", default="llama-3.1-8b-instant")
QDRANT_API_KEY = _get_env(
"QDRANT_API_KEY",
"Qdrant_API_key",
"QADRANT_API_KEY",
"QADRANT_APIKEY",
)
QDRANT_PATH = _get_env(
"QDRANT_PATH",
"QDRANT_URL",
"QDRANT_ENDPOINT",
"Cluster_Endpoint",
"QADRANT_PATH",
"QADRANT_URL",
"QADRANT_ENDPOINT",
)
QDRANT_COLLECTION = _get_env(
"QDRANT_COLLECTION",
"Collection_name",
"QADRANT_COLLECTION",
)
QDRANT_LOCAL_PATH = _get_env("QDRANT_LOCAL_PATH", default=":memory:")
QDRANT_TIMEOUT_SECONDS = _get_float("QDRANT_TIMEOUT_SECONDS", default=30.0)
QDRANT_FALLBACK_TO_LOCAL_ON_ERROR = _get_bool(
"QDRANT_FALLBACK_TO_LOCAL_ON_ERROR",
default=True,
)
QDRANT_LOCAL_FALLBACK_TO_MEMORY_ON_ERROR = _get_bool(
"QDRANT_LOCAL_FALLBACK_TO_MEMORY_ON_ERROR",
default=True,
)
QDRANT_LOCAL_RECOVERY_PATH_ON_ERROR = _get_bool(
"QDRANT_LOCAL_RECOVERY_PATH_ON_ERROR",
default=True,
)
QDRANT_DENSE_VECTOR_NAME = _get_env("QDRANT_DENSE_VECTOR_NAME", default="dense")
QDRANT_SPARSE_VECTOR_NAME = _get_env("QDRANT_SPARSE_VECTOR_NAME", default="sparse")
QDRANT_RECREATE_ON_SCHEMA_MISMATCH = _get_bool(
"QDRANT_RECREATE_ON_SCHEMA_MISMATCH",
default=False,
)
QDRANT_DISTANCE = _get_env("QDRANT_DISTANCE", default="COSINE")
PDF_BASE_PATH = _get_env("PDF_BASE_PATH", default="Data/raw")
PDF_GLOB_PATTERN = _get_env("PDF_GLOB_PATTERN", default="*.pdf")
TEXT_CHUNK_SIZE = _get_int("TEXT_CHUNK_SIZE", default=300)
TEXT_CHUNK_OVERLAP = _get_int("TEXT_CHUNK_OVERLAP", default=50)
TABLE_CHUNK_SIZE = _get_int("TABLE_CHUNK_SIZE", default=120)
TABLE_CHUNK_OVERLAP = _get_int("TABLE_CHUNK_OVERLAP", default=20)
EMBEDDING_BATCH_SIZE = _get_int("EMBEDDING_BATCH_SIZE", default=100)
QDRANT_SCROLL_BATCH_SIZE = _get_int("QDRANT_SCROLL_BATCH_SIZE", default=512)
LOCAL_EMBEDDING_DIMENSION = _get_int("LOCAL_EMBEDDING_DIMENSION", default=1536)
SPARSE_HASH_SPACE = _get_int("SPARSE_HASH_SPACE", default=2000003)
SPARSE_BACKEND = _get_env("SPARSE_BACKEND", default="bm25")
SPARSE_MODEL = _get_env("SPARSE_MODEL", default="prithivida/Splade_PP_en_v1")
SPARSE_BM25_K1 = _get_float("SPARSE_BM25_K1", default=1.5)
SPARSE_BM25_B = _get_float("SPARSE_BM25_B", default=0.75)
SPARSE_BM25_STATS_PATH = _get_env(
"SPARSE_BM25_STATS_PATH",
default="Data/bm25_sparse_stats.json",
)
RETRIEVAL_TOP_K = _get_int("RETRIEVAL_TOP_K", default=10)
HYBRID_PREFETCH_LIMIT = _get_int("HYBRID_PREFETCH_LIMIT", default=40)
HYBRID_FUSION = _get_env("HYBRID_FUSION", default="RRF")
RETRIEVAL_SNIPPET_CHARS = _get_int("RETRIEVAL_SNIPPET_CHARS", default=240)
RERANK_ENABLED = _get_bool("RERANK_ENABLED", default=True)
RERANK_CANDIDATES = _get_int("RERANK_CANDIDATES", default=40)
RERANK_BACKEND = _get_env("RERANK_BACKEND", default="cross_encoder")
RERANK_MODEL = _get_env(
"RERANK_MODEL",
default="cross-encoder/ms-marco-MiniLM-L-6-v2",
)
RERANK_DEVICE = _get_env("RERANK_DEVICE", default="cpu")
RERANK_BATCH_SIZE = _get_int("RERANK_BATCH_SIZE", default=8)
RERANK_MAX_LENGTH = _get_int("RERANK_MAX_LENGTH", default=256)
RERANK_FALLBACK_TO_HEURISTIC = _get_bool(
"RERANK_FALLBACK_TO_HEURISTIC",
default=True,
)
RERANK_RETRIEVAL_WEIGHT = _get_float("RERANK_RETRIEVAL_WEIGHT", default=0.45)
RERANK_LEXICAL_WEIGHT = _get_float("RERANK_LEXICAL_WEIGHT", default=0.35)
RERANK_COHERENCE_WEIGHT = _get_float("RERANK_COHERENCE_WEIGHT", default=0.15)
RERANK_QUALITY_WEIGHT = _get_float("RERANK_QUALITY_WEIGHT", default=0.05)
GENERATION_CONTEXT_CHUNKS = _get_int("GENERATION_CONTEXT_CHUNKS", default=4)
GENERATION_CONTEXT_CHARS = _get_int("GENERATION_CONTEXT_CHARS", default=900)
GENERATION_FALLBACK_TOP_SOURCES = _get_int("GENERATION_FALLBACK_TOP_SOURCES", default=3)
GENERATOR_SYSTEM_PROMPT = _get_env(
"GENERATOR_SYSTEM_PROMPT",
default=(
"You are a financial filing assistant. Answer only from the provided context. "
"If context is insufficient, explicitly say so. Keep the answer concise without citation numbers."
),
)
GENERATOR_OUTPUT_INSTRUCTION = _get_env(
"GENERATOR_OUTPUT_INSTRUCTION",
default=(
"Please structure your answer clearly using markdown:\n"
"### ๐Ÿ“ Summary\n"
"Provide a brief 1-2 sentence summary here.\n\n"
"---\n\n"
"### ๐Ÿ’ก Detailed Answer\n"
"Provide a detailed answer with 2-4 bullet points. **Make the main points bold.** "
"You MUST NOT include citation brackets (like [1] or [2]) in your text.\n\n"
"CRITICAL: If the user asks for a comparison, you MUST present the data as a Markdown Table. You MUST leave a blank line before and after the table. "
"If the user asks to plot a graph or chart, you MUST output a strictly formatted JSON block (```json ... ```) with keys: 'chart_type' (bar/line/pie), 'title', 'labels' (array of strings), and 'values' (array of numbers). CRITICAL: The numbers in the values array MUST NOT contain commas (e.g., use 47302 instead of 47,302)."
),
)
RETRIEVER_DEFAULT_MODE = _get_env("RETRIEVER_DEFAULT_MODE", default="hybrid")
AUTO_BOOTSTRAP_INDEX_ON_QUERY = _get_bool(
"AUTO_BOOTSTRAP_INDEX_ON_QUERY",
default=True,
)
ASK_DEFAULT_LIMIT = _get_int("ASK_DEFAULT_LIMIT", default=5)
ASK_DEFAULT_SOURCES_LIMIT = _get_int("ASK_DEFAULT_SOURCES_LIMIT", default=1)
SEARCH_DEFAULT_LIMIT = _get_int("SEARCH_DEFAULT_LIMIT", default=0)
EVALUATE_DEFAULT_LIMIT = _get_int("EVALUATE_DEFAULT_LIMIT", default=5)
EVALUATE_DEFAULT_QUERIES = _get_list(
"EVALUATE_DEFAULT_QUERIES",
separator="||",
default=[
"What was Amazon's revenue trend in 2024?",
"What do Apple filings say about gross margin changes in 2024?",
"What did Meta say about AI spending in 2024?",
"Summarize Google Cloud performance in 2024 filings.",
],
)
RETRIEVER_COMPANY_ALIASES = _get_dict(
"RETRIEVER_COMPANY_ALIASES",
default={
"amazon": "amazon",
"amzn": "amazon",
"apple": "apple",
"aapl": "apple",
"meta": "meta",
"facebook": "meta",
"fb": "meta",
"google": "google",
"alphabet": "google",
"goog": "google",
"googl": "google",
},
)
RETRIEVER_FILTER_INDEX_FIELDS = _get_list(
"RETRIEVER_FILTER_INDEX_FIELDS",
default=["company", "year", "quarter", "report_type"],
)
QUALITY_HIGH_THRESHOLD = _get_float("QUALITY_HIGH_THRESHOLD", default=0.75)
QUALITY_MEDIUM_THRESHOLD = _get_float("QUALITY_MEDIUM_THRESHOLD", default=0.55)
POSTGRES_URL = _get_env("POSTGRES_URL", "DATABASE_URL")
CHAT_HISTORY_ENABLED = _get_bool("CHAT_HISTORY_ENABLED", default=True)
TEXT_TARGET_WORDS = _get_float("TEXT_TARGET_WORDS", default=80.0)
TABLE_TARGET_WORDS = _get_float("TABLE_TARGET_WORDS", default=60.0)
TEXT_UNIQUE_RATIO_TARGET = _get_float("TEXT_UNIQUE_RATIO_TARGET", default=0.55)
TABLE_UNIQUE_RATIO_TARGET = _get_float("TABLE_UNIQUE_RATIO_TARGET", default=0.65)
# Semantic cache similarity threshold.
# Range: 0.0โ€“1.0. Lower = more cache hits (catches paraphrases), higher = stricter matching.
# Previous hardcoded value was 0.9; 0.82 is a better balance for financial queries.
SEMANTIC_CACHE_THRESHOLD = _get_float("SEMANTIC_CACHE_THRESHOLD", default=0.82)