diff --git a/.github/workflows/main-release.yaml b/.github/workflows/main-release.yaml index 90c83ac..1481ed8 100644 --- a/.github/workflows/main-release.yaml +++ b/.github/workflows/main-release.yaml @@ -6,8 +6,6 @@ concurrency: on: push: - branches: - - main jobs: build-and-push: diff --git a/.gitignore b/.gitignore index 290b078..11ba271 100644 --- a/.gitignore +++ b/.gitignore @@ -255,3 +255,4 @@ dist-ssr *.sln *.sw? +**/.vim/ diff --git a/Makefile b/Makefile index d5ad67b..8bc2cb6 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ build_images: FULL_TAG=$(call get_full_tag,$$SERVICE); \ echo "Building Docker image $$FULL_TAG"; \ docker build -t $$FULL_TAG --build-context core=./core $$dir; \ + if [ $$? -ne 0 ]; then exit 1; fi; \ else \ if [ -d "$$dir" ]; then \ echo "Skipping $$dir, no Dockerfile found."; \ diff --git a/core/common.py b/core/common.py new file mode 100644 index 0000000..9335c8f --- /dev/null +++ b/core/common.py @@ -0,0 +1,62 @@ +import os + +_mongo_url = "" +_redis_url = "" +_litellm_url = "" + + +def get_mongo_url(): + global _mongo_url + if _mongo_url: + return _mongo_url + + _mongo_url = os.getenv("MONGODB_URL") + if _mongo_url: + return _mongo_url + + host = os.getenv("MONGODB_HOST", "localhost") + user = os.getenv("MONGODB_USER") + password = os.getenv("MONGODB_PASSWORD") + port = os.getenv("MONGODB_PORT", 27017) + if ( + not user or not password + ): # if any of these not passed, just return unauthenticated url + _mongo_url = f"mongodb://{host}:{port}" + return _mongo_url + + _mongo_url = f"mongodb://{user}:{password}@{host}:{port}" + return _mongo_url + + +def get_litellm_proxy_url(): + global _litellm_url + if _litellm_url: + return _litellm_url + + host = os.getenv("LITELLM_HOST", "localhost") + port = os.getenv("LITELLM_PORT", 8002) + + _litellm_url = f"http://{host}:{port}" + return _litellm_url + + +def get_redis_url(): + global _redis_url + if _redis_url: + return _redis_url + + _redis_url = os.getenv("REDIS_URL") + if _redis_url: + return _redis_url + + host = os.getenv("REDIS_HOST", "localhost") + user = os.getenv("REDIS_USER") + password = os.getenv("REDIS_PASSWORD") + port = os.getenv("REDIS_PORT", 6379) + + if not password: + _redis_url = f"redis://{host}:{port}/0" + return _redis_url + + _redis_url = f"redis://{user}:{password}@{host}:{port}/0" + return _redis_url diff --git a/core/local_model.py b/core/local_model.py index e00b52d..ac64783 100644 --- a/core/local_model.py +++ b/core/local_model.py @@ -28,12 +28,12 @@ QUERY_FORMAT = '{"query": "refined question"}' litellm_host = os.getenv("LITELLM_HOST", "localhost") - +litellm_api_key = os.getenv("LITELLM_MASTER_KEY") oai_client = OpenAI( base_url=f"http://{litellm_host}:8002/v1/", # base_url="http://localhost:1234/v1/", - api_key="abc", + api_key=litellm_api_key, ) model_name = "custom" diff --git a/core/tasks/celery_config.py b/core/tasks/celery_config.py index 2e8e6b1..4597107 100644 --- a/core/tasks/celery_config.py +++ b/core/tasks/celery_config.py @@ -1,7 +1,6 @@ # Standard Library -import os +from core.common import get_redis_url -CELERY_REDIS_HOST = os.getenv("REDIS_HOST", "localhost") -BROKER_URL = f"redis://{CELERY_REDIS_HOST}:6379/0" # Redis configuration -CELERY_RESULT_BACKEND = f"redis://{CELERY_REDIS_HOST}:6379/0" +BROKER_URL = get_redis_url() +CELERY_RESULT_BACKEND = BROKER_URL CELERY_IMPORTS = ("core.tasks.tasks",) diff --git a/core/tasks/tasks.py b/core/tasks/tasks.py index 3bd6eba..221c94e 100644 --- a/core/tasks/tasks.py +++ b/core/tasks/tasks.py @@ -31,17 +31,17 @@ from openai import OpenAI from pymongo import MongoClient +from core.common import get_redis_url, get_litellm_proxy_url, get_mongo_url + litellm_host = os.getenv("LITELLM_HOST", "localhost") -redis_host = os.getenv("REDIS_HOST", "localhost") -mongodb_host = os.getenv("MONGODB_HOST", "localhost") -redis_client = redis.Redis(host=redis_host, port=6379, db=0) -app = Celery("tasks", broker=f"redis://{redis_host}:6379/0") +redis_client = redis.Redis(get_redis_url()) +app = Celery("tasks", broker=get_redis_url()) app.config_from_object("core.tasks.celery_config") app.autodiscover_tasks(["core.tasks"]) # Explicitly discover tasks in 'app' package # MongoDB Configuration -MONGODB_URL = f"mongodb://{mongodb_host}:27017" +MONGODB_URL = get_mongo_url() DATABASE_NAME = "rubra_db" # Global MongoDB client @@ -51,7 +51,7 @@ @signals.worker_process_init.connect def setup_mongo_connection(*args, **kwargs): global mongo_client - mongo_client = MongoClient(f"mongodb://{mongodb_host}:27017") + mongo_client = MongoClient(MONGODB_URL) def create_assistant_message( @@ -216,7 +216,8 @@ def form_openai_tools(tools, assistant_id: str): def execute_chat_completion(assistant_id, thread_id, redis_channel, run_id): try: oai_client = OpenAI( - base_url=f"http://{litellm_host}:8002/v1/", + base_url=get_litellm_proxy_url(), + # FIXME: actual master key api_key="abc", # point to litellm server ) db = mongo_client[DATABASE_NAME] diff --git a/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py b/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py index 085f281..9a60413 100644 --- a/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py +++ b/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py @@ -8,7 +8,7 @@ from langchain.embeddings.base import Embeddings HOST = os.getenv("EMBEDDING_HOST", "localhost") -EMBEDDING_URL = f"http://{HOST}:8020/embed_multiple" +EMBEDDING_URL = os.getenv("EMBEDDING_URL", f"http://{HOST}:8020/embed_multiple") def embed_text(texts: List[str]) -> List[List[float]]: diff --git a/services/backend/api_server/Dockerfile b/services/backend/api_server/Dockerfile index 4a905e5..a9f5ee7 100644 --- a/services/backend/api_server/Dockerfile +++ b/services/backend/api_server/Dockerfile @@ -8,6 +8,7 @@ COPY . /app COPY --from=core ./ /app/core # Install any needed packages specified in requirements.txt +RUN apt-get update && apt-get install gcc g++ -y RUN pip install --no-cache-dir -r requirements.txt RUN spacy download en_core_web_sm RUN playwright install diff --git a/services/backend/api_server/app/backend.py b/services/backend/api_server/app/backend.py index 9d67d55..afa3b5c 100644 --- a/services/backend/api_server/app/backend.py +++ b/services/backend/api_server/app/backend.py @@ -104,18 +104,16 @@ generate_thread_id, ) -litellm_host = os.getenv("LITELLM_HOST", "localhost") -redis_host = os.getenv("REDIS_HOST", "localhost") -mongodb_host = os.getenv("MONGODB_HOST", "localhost") - app = FastAPI() -origins = [ +default_origins = [ "http://localhost:3000", # Add the frontend host here "http://localhost", "https://docs.rubra.ai", ] +origins = os.getenv("CORS_ALLOWED_ORIGINS", default_origins) + app.add_middleware( CORSMiddleware, allow_origins=origins, @@ -124,17 +122,59 @@ allow_headers=["*"], # Allows all headers ) + +def _get_mongo_url(): + url = os.getenv("MONGODB_URL") + if url: + return url + + host = os.getenv("MONGODB_HOST", "localhost") + user = os.getenv("MONGODB_USER") + password = os.getenv("MONGODB_PASSWORD") + port = os.getenv("MONGODB_PORT", 27017) + if ( + not user or not password + ): # if any of these not passed, just return unauthenticated url + return f"mongodb://{host}:{port}" + + return f"mongodb://{user}:{password}@{host}:{port}" + + +def _get_litellm_proxy_url(): + host = os.getenv("LITELLM_HOST", "localhost") + port = os.getenv("LITELLM_PORT", 8002) + return f"http://{host}:{port}" + + +def _get_redis_url(): + url = os.getenv("REDIS_URL") + if url: + return url + + host = os.getenv("REDIS_HOST", "localhost") + user = os.getenv("REDIS_USER") + password = os.getenv("REDIS_PASSWORD") + port = os.getenv("REDIS_PORT", 6379) + + if not password: + return f"redis://{host}:{port}/0" + + return f"redis://{user}:{password}@{host}:{port}/0" + + # MongoDB Configurationget -MONGODB_URL = f"mongodb://{mongodb_host}:27017" -DATABASE_NAME = "rubra_db" -LITELLM_URL = f"http://{litellm_host}:8002" +MONGODB_URL = _get_mongo_url() +DATABASE_NAME = os.getenv("MONGODB_DATABASE", "rubra_db") +LITELLM_URL = _get_litellm_proxy_url() HEADERS = {"accept": "application/json", "Content-Type": "application/json"} # Initialize MongoDB client mongo_client = AsyncIOMotorClient(MONGODB_URL) database = mongo_client[DATABASE_NAME] -celery_app = Celery(broker=f"redis://{redis_host}:6379/0") +redis_url = _get_redis_url() + +celery_app = Celery(broker=redis_url) logging.basicConfig(level=logging.INFO) @@ -203,7 +243,7 @@ async def on_startup(): async def get_api_key_status(): try: redis = await aioredis.from_url( - f"redis://{redis_host}:6379/0", encoding="utf-8", decode_responses=True + redis_url, encoding="utf-8", decode_responses=True ) openai_key = await redis.get("OPENAI_API_KEY") anthropic_key = await redis.get("ANTHROPIC_API_KEY") @@ -226,7 +266,7 @@ async def get_api_key_status(): async def set_api_key_status(api_keys: ApiKeysUpdateModel): try: redis = await aioredis.from_url( - f"redis://{redis_host}:6379/0", encoding="utf-8", decode_responses=True + redis_url, encoding="utf-8", decode_responses=True ) logging.info("Setting API keys") @@ -752,7 +792,7 @@ async def list_messages( async def redis_subscriber(channel, timeout=1): logging.info(f"Connecting to Redis and subscribing to channel: {channel}") redis = await aioredis.from_url( - f"redis://{redis_host}:6379/0", encoding="utf-8", decode_responses=True + redis_url, encoding="utf-8", decode_responses=True ) pubsub = redis.pubsub() await pubsub.subscribe(channel) @@ -782,7 +822,7 @@ async def listen_for_task_status( pubsub = None try: redis = await aioredis.from_url( - f"redis://{redis_host}:6379/0", encoding="utf-8", decode_responses=True + redis_url, encoding="utf-8", decode_responses=True ) pubsub = redis.pubsub() await pubsub.subscribe(task_status_channel) diff --git a/services/backend/task_executor/Dockerfile b/services/backend/task_executor/Dockerfile index 4844f47..eabb063 100644 --- a/services/backend/task_executor/Dockerfile +++ b/services/backend/task_executor/Dockerfile @@ -7,6 +7,7 @@ WORKDIR /app ADD requirements.txt /app/ # Install any needed packages specified in requirements.txt +RUN apt-get update && apt-get install gcc g++ -y RUN pip install --no-cache-dir -r requirements.txt RUN spacy download en_core_web_sm RUN playwright install