diff --git a/.github/workflows/main-release.yaml b/.github/workflows/main-release.yaml index 90c83ac..88e313f 100644 --- a/.github/workflows/main-release.yaml +++ b/.github/workflows/main-release.yaml @@ -8,6 +8,7 @@ on: push: branches: - main + - develop jobs: build-and-push: @@ -32,13 +33,22 @@ jobs: - name: Expose GH Runtime uses: crazy-max/ghaction-github-runtime@v3 + - name: set lower case owner name + run: | + echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV} + env: + OWNER: "${{ github.repository_owner }}" + + - name: set lower case owner name + run: | + echo "REPO_LC=$(echo ${{ github.repository }} | awk 'BEGIN{FS=OFS="/"}{print tolower($1) "/" $2}')" >>${GITHUB_ENV} - name: Build and Push Docker Images run: | make build_and_push_images env: REGISTRY: "ghcr.io" - ORG: ${{ github.repository_owner }} - REPO: ${{ github.event.repository.name }} + ORG: ${{ env.OWNER_LC }} + REPO: ${{ env.REPO_LC }} GITHUB_WORKFLOW: ${{ github.workflow }} build-tauri: diff --git a/.github/workflows/tag-release.yaml b/.github/workflows/tag-release.yaml index 3102a57..7411b8a 100644 --- a/.github/workflows/tag-release.yaml +++ b/.github/workflows/tag-release.yaml @@ -30,7 +30,7 @@ jobs: - name: Build and Push Docker Images run: | - TAG=${GITHUB_REF#refs/tags/} make build_and_push_images + TAG=${GITHUB_REF#refs/heads/} make build_and_push_images env: REGISTRY: ghcr.io ORG: ${{ github.repository_owner }} @@ -69,7 +69,7 @@ jobs: - name: get release version id: get_release_version - run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV + run: echo "TAG=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV - name: get release id id: get_release_id diff --git a/core/config/__init__.py b/core/config/__init__.py new file mode 100644 index 0000000..27c9ec6 --- /dev/null +++ b/core/config/__init__.py @@ -0,0 +1 @@ +from .config import * diff --git a/core/config/config.py b/core/config/config.py new file mode 100644 index 0000000..f3d6b09 --- /dev/null +++ b/core/config/config.py @@ -0,0 +1,84 @@ +from os import getenv + +def get_mongo_database_name(): + return getenv("MONGODB_DATABASE", "rubra_db") + +def get_mongo_url() -> str: + url = getenv("MONGODB_URL") + if url: + return url + + host = getenv("MONGODB_HOST", "localhost") + user = getenv("MONGODB_USER", getenv("MONGODB_USERNAME", None)) + password = getenv("MONGODB_PASS", getenv("MONGODB_PASSWORD", None)) + port = getenv("MONGODB_PORT", 27017) + database = get_mongo_database_name() + + if user and not password: + print("MONGODB_USER set but password not found, ignoring user") + + if not user and password: + print("MONGODB_PASSWORD set but user not found, ignoring password") + + if user and password: + return f"mongodb://{user}:{password}@{host}:${port}/{database}" + + return f"mongodb://{host}:{port}/{database}" + +def get_redis_url() -> str: + url = getenv("REDIS_URL") + if url: + return url + + host = getenv("REDIS_HOST", "localhost") + password = getenv("REDIS_PASS", getenv("REDIS_PASSWORD", None)) + user = getenv("REDIS_USER", getenv("REDIS_USERNAME", None)) + port = getenv("REDIS_PORT", 6379) + database = getenv("REDIS_DATABASE", 0) + + if password: + return f"redis://{user or ''}:{password}@{host}:{port}/{database}" + + return f"redis://{host}:{port}/{database}" + +def get_litellm_url() -> str: + url = getenv("LITELLM_URL") + if url: + return url + + host = getenv("LITELLM_HOST", "localhost") + port = getenv("LITELLM_PORT", 8002) + + return f"http://{host}:{port}" + +def get_vector_db_url() -> str: + url = getenv("VECTOR_DB_URL") + if url: + return url + + host = getenv("VECTOR_DB_HOST", "localhost") + port = getenv("VECTOR_DB_PORT", 8010) + + return f"http://{host}:{port}" + +def get_embedding_url(): + url = getenv("EMBEDDING_URL") + if url: + return url + + host = getenv("EMBEDDING_HOST", "localhost") + port = getenv("EMBEDDING_PORT", 8020) + + return f"http://{host}:{port}" + +mongo_database = get_mongo_database_name() + +mongo_url = get_mongo_url() + +litellm_url = get_litellm_url() + +vector_db_url = get_vector_db_url() + +redis_url = get_redis_url() + +embedding_url = get_embedding_url() diff --git a/core/local_model.py b/core/local_model.py index e00b52d..5fc5b16 100644 --- a/core/local_model.py +++ b/core/local_model.py @@ -150,7 +150,7 @@ def simple_qa(query: str, context: str) -> str: temperature=0.1, messages=messages, stream=False, - response_format="web", + response_format={"type": "text"}, # mlc doesn't supports string "web" ) return response.choices[0].message.content diff --git a/core/tasks/__init__.py b/core/tasks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/tasks/celery_app.py b/core/tasks/celery_app.py new file mode 100644 index 0000000..4e6922f --- /dev/null +++ b/core/tasks/celery_app.py @@ -0,0 +1,10 @@ +import redis +from celery import Celery +from typing import cast +import core.config as configs + + +redis_client = cast(redis.Redis, redis.Redis.from_url(configs.redis_url)) # annoyingly from_url returns None, not Self +app = Celery("tasks", broker=configs.redis_url) + +app.autodiscover_tasks(["core.tasks"]) # Explicitly discover tasks in 'app' package diff --git a/core/tasks/celery_config.py b/core/tasks/celery_config.py deleted file mode 100644 index 2e8e6b1..0000000 --- a/core/tasks/celery_config.py +++ /dev/null @@ -1,7 +0,0 @@ -# Standard Library -import os - -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" -CELERY_IMPORTS = ("core.tasks.tasks",) diff --git a/core/tasks/is_ready.py b/core/tasks/is_ready.py new file mode 100644 index 0000000..ae59bcf --- /dev/null +++ b/core/tasks/is_ready.py @@ -0,0 +1,38 @@ +import socket + +import requests + +from core.config import litellm_url, vector_db_url + +from .celery_app import app + +def is_ready(): + # response = requests.get(f"{litellm_url}/health", headers={ + # "Authorization": f"Bearer {os.getenv('LITELLM_MASTER_KEY', '')}" + # }) + # if not response.ok: + # raise Exception(response.text) + + # print(response) + + response = requests.get(f"{litellm_url}/health/readiness") + if not response.ok: + raise Exception(response.text) + + print(response) + + pong = app.control.ping([f'celery@{socket.gethostname()}']) + if len(pong) == 0 or list(pong[0].values())[0].get('ok', None) is None: + raise Exception('ping failed with' + str(pong)) + + print(pong) + + response = requests.get(f"{vector_db_url}/healthz") + if not response.ok: + raise Exception(response.text) + + print(response) + + +if __name__ == "__main__": + is_ready() diff --git a/core/tasks/tasks.py b/core/tasks/tasks.py index 3bd6eba..a58578d 100644 --- a/core/tasks/tasks.py +++ b/core/tasks/tasks.py @@ -5,6 +5,16 @@ import sys from functools import partial +from typing import cast + +# Third Party +from core.tools.knowledge.vector_db.milvus.operations import add_texts, milvus_connection_alias +from langchain.text_splitter import RecursiveCharacterTextSplitter +from core.tools.knowledge.file_knowledge_tool import FileKnowledgeTool +from core.tools.web_browse.web_browse_tool import WebBrowseTool + +from pymilvus import connections + # Get the current working directory current_directory = os.getcwd() @@ -31,33 +41,29 @@ from openai import OpenAI from pymongo import MongoClient -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") -app.config_from_object("core.tasks.celery_config") -app.autodiscover_tasks(["core.tasks"]) # Explicitly discover tasks in 'app' package +import core.config as configs -# MongoDB Configuration -MONGODB_URL = f"mongodb://{mongodb_host}:27017" -DATABASE_NAME = "rubra_db" +from .is_ready import is_ready +from .celery_app import app # Global MongoDB client -mongo_client = None +mongo_client: MongoClient = None +redis_client = cast(redis.Redis, redis.Redis.from_url(configs.redis_url)) # annoyingly from_url returns None, not Self @signals.worker_process_init.connect -def setup_mongo_connection(*args, **kwargs): +def ensure_connections(*args, **kwargs): global mongo_client - mongo_client = MongoClient(f"mongodb://{mongodb_host}:27017") + mongo_client = MongoClient(configs.mongo_url) + mongo_client.admin.command('ping') + + is_ready() def create_assistant_message( thread_id, assistant_id, run_id, content_text, role=Role7.assistant.value ): - db = mongo_client[DATABASE_NAME] + db = mongo_client[configs.mongo_database] # Generate a unique ID for the message message_id = f"msg_{uuid.uuid4().hex[:6]}" @@ -175,10 +181,6 @@ def rubra_local_agent_chat_completion( def form_openai_tools(tools, assistant_id: str): - # Third Party - from core.tools.knowledge.file_knowledge_tool import FileKnowledgeTool - from core.tools.web_browse.web_browse_tool import WebBrowseTool - retrieval = FileKnowledgeTool() googlesearch = WebBrowseTool() res_tools = [] @@ -215,11 +217,12 @@ def form_openai_tools(tools, assistant_id: str): @shared_task def execute_chat_completion(assistant_id, thread_id, redis_channel, run_id): try: + db = mongo_client[configs.mongo_database] # OpenAI call can fail, so we need to get the db again + oai_client = OpenAI( - base_url=f"http://{litellm_host}:8002/v1/", - api_key="abc", # point to litellm server + base_url=configs.litellm_url, + api_key=os.getenv("LITELLM_MASTER_KEY"), # point to litellm server ) - db = mongo_client[DATABASE_NAME] # Fetch assistant and thread messages synchronously assistant = db.assistants.find_one({"id": assistant_id}) @@ -453,15 +456,10 @@ def execute_chat_completion(assistant_id, thread_id, redis_channel, run_id): @app.task def execute_asst_file_create(file_id: str, assistant_id: str): - # Standard Library - import json - - # Third Party - from core.tools.knowledge.vector_db.milvus.operations import add_texts - from langchain.text_splitter import RecursiveCharacterTextSplitter - try: - db = mongo_client[DATABASE_NAME] + if mongo_client is None: + raise Exception("MongoDB client not initialized yet") + db = mongo_client[configs.mongo_database] collection_name = assistant_id text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=0) parsed_text = "" diff --git a/core/tools/knowledge/file_knowledge_tool.py b/core/tools/knowledge/file_knowledge_tool.py index fc62637..dea2088 100644 --- a/core/tools/knowledge/file_knowledge_tool.py +++ b/core/tools/knowledge/file_knowledge_tool.py @@ -1,13 +1,12 @@ # Standard Library import json -import os + +import core.config as configs # Third Party import requests -VECTOR_DB_HOST = os.getenv("VECTOR_DB_HOST", "localhost") -VECTOR_DB_MATCH_URL = f"http://{VECTOR_DB_HOST}:8010/similarity_match" - +vector_db_url = f"{configs.vector_db_url}/similarity_match" class FileKnowledgeTool: name = "FileKnowledge" @@ -42,7 +41,7 @@ def file_knowledge_search_api(query: str, assistant_id: str): } ) - response = requests.post(VECTOR_DB_MATCH_URL, headers=headers, data=data) + response = requests.post(vector_db_url, headers=headers, data=data) res = response.json()["response"] txt = "" for r in res: diff --git a/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py b/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py index 085f281..74dd456 100644 --- a/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py +++ b/core/tools/knowledge/vector_db/milvus/custom_embeddigs.py @@ -1,14 +1,14 @@ # Standard Library import json -import os from typing import List # Third Party import requests from langchain.embeddings.base import Embeddings -HOST = os.getenv("EMBEDDING_HOST", "localhost") -EMBEDDING_URL = f"http://{HOST}:8020/embed_multiple" +import core.config as configs + +EMBEDDING_URL = f"{configs.embedding_url}/embed_multiple" def embed_text(texts: List[str]) -> List[List[float]]: diff --git a/core/tools/knowledge/vector_db/milvus/operations.py b/core/tools/knowledge/vector_db/milvus/operations.py index 430f29f..b456d49 100644 --- a/core/tools/knowledge/vector_db/milvus/operations.py +++ b/core/tools/knowledge/vector_db/milvus/operations.py @@ -9,12 +9,16 @@ from .custom_embeddigs import CustomEmbeddings from .query_milvus import Milvus -MILVUS_HOST = os.getenv("MILVUS_HOST", "localhost") - model = {} top_re_rank = 5 top_k_match = 10 +milvus_connection_alias = Milvus.create_connection_alias({ + "host": os.getenv("MILVUS_HOST", "localhost"), + "port": os.getenv("MILVUS_PORT", "19530"), + "user": os.getenv("MILVUS_USER", os.getenv("MILVUS_USERNAME", "")), + "password": os.getenv("MILVUS_PASS", os.getenv("MILVUS_PASSWORD", "")) +}) class Query(BaseModel): text: str @@ -27,17 +31,11 @@ class Query(BaseModel): def drop_collection(collection_name: str): load_collection(collection_name).drop_collection() - def load_collection(collection_name: str) -> Milvus: return Milvus( embedding_function=CustomEmbeddings(), collection_name=collection_name, - connection_args={ - "host": MILVUS_HOST, - "port": "19530", - "user": "username", - "password": "password", - }, + alias=milvus_connection_alias, index_params={ "metric_type": "IP", "index_type": "FLAT", diff --git a/core/tools/knowledge/vector_db/milvus/query_milvus.py b/core/tools/knowledge/vector_db/milvus/query_milvus.py index 4e7779c..725cbca 100644 --- a/core/tools/knowledge/vector_db/milvus/query_milvus.py +++ b/core/tools/knowledge/vector_db/milvus/query_milvus.py @@ -32,6 +32,7 @@ def __init__( embedding_function: Embeddings, collection_name: str = "DefaultCollection", connection_args: Optional[Dict[str, Any]] = None, + alias: Optional[str] = None, consistency_level: str = "Session", index_params: Optional[Dict[str, Any]] = None, search_params: Optional[Dict[str, Any]] = None, @@ -129,9 +130,14 @@ def __init__( self._vector_field = "vector" self.fields: list[str] = [] # Create the connection to the server - if connection_args is None: + if alias is not None: + self.alias = alias + elif connection_args is not None: connection_args = DEFAULT_MILVUS_CONNECTION - self.alias = self._create_connection_alias(connection_args) + self.alias = Milvus.create_connection_alias(connection_args) + else: + raise ValueError('alias or connection_args must be passed to Milvus construtor') + self.col: Optional[Collection] = None # Grab the existing colection if it exists @@ -154,11 +160,18 @@ def drop_collection(self): utility.drop_collection(collection_name=self.collection_name, using=self.alias) - def _create_connection_alias(self, connection_args: dict) -> str: + @staticmethod + def create_connection_alias(connection_args: dict) -> str: """Create the connection to the Milvus server.""" # Third Party from pymilvus import MilvusException, connections + if connection_args is None: + connection_args = DEFAULT_MILVUS_CONNECTION + else: + # fill anything not passed like "default" port + connection_args = {**connection_args, **DEFAULT_MILVUS_CONNECTION} + # Grab the connection arguments that are used for checking existing connection host: str = connection_args.get("host", None) port: Union[str, int] = connection_args.get("port", None) diff --git a/docker-compose.yml b/docker-compose.yml index ea091a7..01c74d2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -115,6 +115,7 @@ services: - EMBEDDING_HOST=text-embedding-api - VECTOR_DB_HOST=vector-db-api - MILVUS_HOST=milvus + - LITELLM_MASTER_KEY=abc depends_on: - redis - mongodb @@ -134,6 +135,7 @@ services: - REDIS_HOST=redis - MONGODB_HOST=mongodb - LITELLM_HOST=litellm + - MILVUS_HOST=milvus ports: - '8000:8000' depends_on: diff --git a/services/backend/api_server/Dockerfile b/services/backend/api_server/Dockerfile index 4a905e5..eaea120 100644 --- a/services/backend/api_server/Dockerfile +++ b/services/backend/api_server/Dockerfile @@ -3,9 +3,9 @@ FROM python:3.10.7-slim # Set the working directory in the container to /app WORKDIR /app -# Add the current directory contents into the container at /app -COPY . /app -COPY --from=core ./ /app/core +RUN apt-get update && apt-get install gcc g++ -y + +COPY requirements.txt /app # Install any needed packages specified in requirements.txt RUN pip install --no-cache-dir -r requirements.txt @@ -13,6 +13,10 @@ RUN spacy download en_core_web_sm RUN playwright install RUN playwright install-deps +# Add the current directory contents into the container at /app +COPY . /app +COPY --from=core ./ /app/core + # Make port 80 available to the world outside this container EXPOSE 8000 diff --git a/services/backend/api_server/app/backend.py b/services/backend/api_server/app/backend.py index 9d67d55..3fdab5c 100644 --- a/services/backend/api_server/app/backend.py +++ b/services/backend/api_server/app/backend.py @@ -1,14 +1,17 @@ # Standard Library import asyncio +import os import json import logging -import os import uuid from datetime import datetime -from typing import Any, Dict, Optional +from typing import Any, Dict, Optional, Union, Callable + +from pymongo.server_api import ServerApi -# Third Party import aioredis + +# Third Party import requests from beanie import init_beanie from celery import Celery @@ -87,7 +90,7 @@ delete_docs, drop_collection, ) -from fastapi import FastAPI, Form, HTTPException, UploadFile, WebSocket +from fastapi import FastAPI, Form, HTTPException, UploadFile, WebSocket, Response, status from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import StreamingResponse from fastapi.websockets import WebSocketState @@ -104,9 +107,7 @@ generate_thread_id, ) -litellm_host = os.getenv("LITELLM_HOST", "localhost") -redis_host = os.getenv("REDIS_HOST", "localhost") -mongodb_host = os.getenv("MONGODB_HOST", "localhost") +import core.config as configs app = FastAPI() @@ -125,23 +126,37 @@ ) # MongoDB Configurationget -MONGODB_URL = f"mongodb://{mongodb_host}:27017" -DATABASE_NAME = "rubra_db" -LITELLM_URL = f"http://{litellm_host}:8002" +LITELLM_URL = configs.litellm_url +LITELLM_MASTER_KEY = os.getenv("LITELLM_MASTER_KEY", "abc") # Litellm fails without this key HEADERS = {"accept": "application/json", "Content-Type": "application/json"} # Initialize MongoDB client -mongo_client = AsyncIOMotorClient(MONGODB_URL) -database = mongo_client[DATABASE_NAME] +mongo_client = AsyncIOMotorClient(configs.mongo_url, server_api=ServerApi("1")) +database = mongo_client[configs.mongo_database] -celery_app = Celery(broker=f"redis://{redis_host}:6379/0") +celery_app = Celery(broker=configs.redis_url) -logging.basicConfig(level=logging.INFO) +redis = aioredis.from_url(configs.redis_url, encoding="utf-8", decode_responses=True) +logging.basicConfig(level=logging.INFO) def get_database(): return database +async def full_check() -> None: + await redis.ping() + print("Redis connection is ready!") + + await mongo_client.admin.command("ping") + print("MongoDB connection is ready!") + + res = requests.get(f"{LITELLM_URL}/health/readiness", { }) + + if res.json().get("status", "") != "healthy": + raise Exception("litellm not ready: " + str(res.json())) + + print("litellm is ready!") + @app.on_event("startup") async def on_startup(): @@ -158,6 +173,8 @@ async def on_startup(): ], ) + await full_check() + available_models = [r.id for r in litellm_list_model().data] if not available_models: logging.warning("No models configured.") @@ -179,32 +196,29 @@ async def on_startup(): welcome_asst_instruction += tool_use_instruction # Create the Welcome Assistant if it doesn't exist - existing_assistant = await AssistantObject.find_one({"id": "asst_welcome"}) - if not existing_assistant: - logging.info("Creating Welcome Assistant") - assistant = AssistantObject( - assistant_id="asst_welcome", - object=Object20.assistant.value, - created_at=int(datetime.now().timestamp()), - name="Welcome Assistant", - description="Welcome Assistant", - model=welcome_asst_model, - instructions=welcome_asst_instruction, - tools=[{"type": Type824.retrieval.value}] - if welcome_asst_model in tool_enabled_model_pool - else [], # browser - file_ids=[], - metadata={}, - ) - await assistant.insert() + # existing_assistant = await AssistantObject.find_one({"id": "asst_welcome"}) + # if not existing_assistant: + # logging.info("Creating Welcome Assistant") + # assistant = AssistantObject( + # assistant_id="asst_welcome", + # object=Object20.assistant.value, + # created_at=int(datetime.now().timestamp()), + # name="Welcome Assistant", + # description="Welcome Assistant", + # model=welcome_asst_model, + # instructions=welcome_asst_instruction, + # tools=[{"type": Type824.retrieval.value}] + # if welcome_asst_model in tool_enabled_model_pool + # else [], # browser + # file_ids=[], + # metadata={}, + # ) + # await assistant.insert() @app.get("/get_api_key_status", tags=["API Keys"]) async def get_api_key_status(): try: - redis = await aioredis.from_url( - f"redis://{redis_host}:6379/0", encoding="utf-8", decode_responses=True - ) openai_key = await redis.get("OPENAI_API_KEY") anthropic_key = await redis.get("ANTHROPIC_API_KEY") @@ -225,10 +239,6 @@ async def get_api_key_status(): @app.post("/set_api_keys", tags=["API Keys"]) 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 - ) - logging.info("Setting API keys") logging.info(api_keys) @@ -751,12 +761,17 @@ 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 - ) pubsub = redis.pubsub() await pubsub.subscribe(channel) + # Check if the subscription was successful + channels = await redis.pubsub_channels() + logging.info(f"Channels: {channels}") + if channel in channels: + logging.info(f"Successfully subscribed to channel: {channel}") + else: + logging.error(f"Failed to subscribe to channel: {channel}") + while True: try: message = await asyncio.wait_for( @@ -778,12 +793,8 @@ async def listen_for_task_status( task_status_channel, status_update_event, thread_id, run_id ): logging.info(f"Listening for task status on channel: {task_status_channel}") - redis = None pubsub = None try: - redis = await aioredis.from_url( - f"redis://{redis_host}:6379/0", encoding="utf-8", decode_responses=True - ) pubsub = redis.pubsub() await pubsub.subscribe(task_status_channel) @@ -1023,7 +1034,7 @@ def convert_model_info_to_oai_model(obj, predefined_models): def litellm_list_model() -> ListModelsResponse: try: - client = OpenAI(base_url=LITELLM_URL, api_key="abc") + client = OpenAI(base_url=LITELLM_URL, api_key=LITELLM_MASTER_KEY) models_data = client.models.list().data models_data = sorted(models_data, key=lambda x: x.id) predefined_models = [convert_to_model(m) for m in models_data] @@ -1589,6 +1600,10 @@ async def chat_completion(body: CreateChatCompletionRequest): else: return response +@app.get("/healthz/liveness", status_code=status.HTTP_204_NO_CONTENT) +def ping(): + pass + def data_generator(response): """ diff --git a/services/backend/api_server/requirements.txt b/services/backend/api_server/requirements.txt index 9ac8f68..81a29e0 100644 --- a/services/backend/api_server/requirements.txt +++ b/services/backend/api_server/requirements.txt @@ -4,7 +4,7 @@ celery==5.3.6 fastapi==0.105.0 motor==3.3.2 openai==1.6.1 -pymilvus==2.3.4 +pymilvus==2.2.8 pydantic==1.10.9 python-multipart==0.0.6 redis==5.0.1 @@ -16,4 +16,4 @@ langchain==0.0.351 spacy==3.7.2 markdownify==0.11.6 playwright==1.39.0 -tiktoken==0.5.2 \ No newline at end of file +tiktoken==0.5.2 diff --git a/services/backend/task_executor/Dockerfile b/services/backend/task_executor/Dockerfile index 4844f47..8d8fce4 100644 --- a/services/backend/task_executor/Dockerfile +++ b/services/backend/task_executor/Dockerfile @@ -23,4 +23,4 @@ WORKDIR /app ENV OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES # Run app.py when the container launches -CMD ["celery", "-A", "core.tasks.tasks", "worker", "--loglevel=info"] +CMD ["sh", "-c", "celery -A core.tasks.tasks worker --loglevel=info -n celery@$(hostname)"] diff --git a/services/backend/task_executor/requirements.txt b/services/backend/task_executor/requirements.txt index 00a3ea2..958ecca 100644 --- a/services/backend/task_executor/requirements.txt +++ b/services/backend/task_executor/requirements.txt @@ -12,10 +12,10 @@ redis==5.0.1 requests==2.31.0 uvicorn==0.25.0 websockets==12.0 -pymilvus==2.3.4 +pymilvus==2.2.8 pypdf2==3.0.1 spacy==3.7.2 markdownify==0.11.6 playwright==1.39.0 tiktoken==0.5.2 -chardet==5.2.0 \ No newline at end of file +chardet==5.2.0 diff --git a/services/backend/vector_db_api/main.py b/services/backend/vector_db_api/main.py index 152d832..320605b 100644 --- a/services/backend/vector_db_api/main.py +++ b/services/backend/vector_db_api/main.py @@ -11,7 +11,7 @@ get_similar_match, load_collection, ) -from fastapi import FastAPI +from fastapi import FastAPI, status, Response model = {} top_re_rank = 5 @@ -19,11 +19,6 @@ app = FastAPI() -@app.on_event("startup") -async def app_startup(): - pass - - @app.post("/add_texts") async def add_texts_embeddings( collection_name: str,