diff --git a/.github/workflows/pytest_and_coverage.yml b/.github/workflows/pytest_and_coverage.yml index bddc5a7c..15aa9547 100644 --- a/.github/workflows/pytest_and_coverage.yml +++ b/.github/workflows/pytest_and_coverage.yml @@ -34,9 +34,8 @@ jobs: # API keys for various LLM providers PROMETHEUS_ANTHROPIC_API_KEY: anthropic_api_key PROMETHEUS_GEMINI_API_KEY: gemini_api_key - PROMETHEUS_OPENAI_API_KEY: openai_api_key - PROMETHEUS_OPENROUTER_API_KEY: openrouter_api_key - PROMETHEUS_DEEPSEEK_API_KEY: deepseek_api_key + PROMETHEUS_OPENAI_FORMAT_API_KEY: openai_format_api_key + PROMETHEUS_OPENAI_FORMAT_BASE_URL: https://api.openai.com/v1/chat/completions # Model settings PROMETHEUS_MAX_INPUT_TOKENS: 64000 @@ -49,11 +48,6 @@ jobs: # DATABASE settings PROMETHEUS_DATABASE_URL: postgresql://postgres:password@localhost:5432/postgres?sslmode=disable - # Superuser settings - PROMETHEUS_SUPERUSER_USERNAME: admin - PROMETHEUS_SUPERUSER_PASSWORD: admin_password - PROMETHEUS_SUPERUSER_EMAIL: admin@outlook.com - steps: - name: Check out code uses: actions/checkout@v4 diff --git a/docker-compose.win_mac.yml b/docker-compose.win_mac.yml index 2b762426..8eeec133 100644 --- a/docker-compose.win_mac.yml +++ b/docker-compose.win_mac.yml @@ -33,28 +33,42 @@ services: ports: - "9002:9002" environment: + # Logging - PROMETHEUS_LOGGING_LEVEL=${PROMETHEUS_LOGGING_LEVEL} + + # Neo4j settings - PROMETHEUS_NEO4J_URI=${PROMETHEUS_NEO4J_URI} - PROMETHEUS_NEO4J_USERNAME=${PROMETHEUS_NEO4J_USERNAME} - PROMETHEUS_NEO4J_PASSWORD=${PROMETHEUS_NEO4J_PASSWORD} - PROMETHEUS_NEO4J_BATCH_SIZE=${PROMETHEUS_NEO4J_BATCH_SIZE} + + # Knowledge Graph settings - PROMETHEUS_KNOWLEDGE_GRAPH_MAX_AST_DEPTH=${PROMETHEUS_KNOWLEDGE_GRAPH_MAX_AST_DEPTH} - PROMETHEUS_KNOWLEDGE_GRAPH_CHUNK_SIZE=${PROMETHEUS_KNOWLEDGE_GRAPH_CHUNK_SIZE} - PROMETHEUS_KNOWLEDGE_GRAPH_CHUNK_OVERLAP=${PROMETHEUS_KNOWLEDGE_GRAPH_CHUNK_OVERLAP} - PROMETHEUS_MAX_TOKEN_PER_NEO4J_RESULT=${PROMETHEUS_MAX_TOKEN_PER_NEO4J_RESULT} + - PROMETHEUS_WORKING_DIRECTORY=${PROMETHEUS_WORKING_DIRECTORY} + + # LLM model settings - PROMETHEUS_ADVANCED_MODEL=${PROMETHEUS_ADVANCED_MODEL} - PROMETHEUS_BASE_MODEL=${PROMETHEUS_BASE_MODEL} + + # API keys for various LLM providers - PROMETHEUS_ANTHROPIC_API_KEY=${PROMETHEUS_ANTHROPIC_API_KEY} - PROMETHEUS_GEMINI_API_KEY=${PROMETHEUS_GEMINI_API_KEY} - - PROMETHEUS_OPENAI_API_KEY=${PROMETHEUS_OPENAI_API_KEY} - - PROMETHEUS_OPENROUTER_API_KEY=${PROMETHEUS_OPENROUTER_API_KEY} - - PROMETHEUS_DEEPSEEK_API_KEY=${PROMETHEUS_DEEPSEEK_API_KEY} + - PROMETHEUS_OPENAI_FORMAT_API_KEY=${PROMETHEUS_OPENAI_FORMAT_API_KEY} + - PROMETHEUS_OPENAI_FORMAT_BASE_URL=${PROMETHEUS_OPENAI_FORMAT_BASE_URL} + + # Model settings - PROMETHEUS_MAX_INPUT_TOKENS=${PROMETHEUS_MAX_INPUT_TOKENS} - PROMETHEUS_MAX_OUTPUT_TOKENS=${PROMETHEUS_MAX_OUTPUT_TOKENS} - PROMETHEUS_TEMPERATURE=${PROMETHEUS_TEMPERATURE} - - PROMETHEUS_WORKING_DIRECTORY=${PROMETHEUS_WORKING_DIRECTORY} + + # GitHub settings - PROMETHEUS_GITHUB_ACCESS_TOKEN=${PROMETHEUS_GITHUB_ACCESS_TOKEN} - - PROMETHEUS_DATABASE_URI=${PROMETHEUS_DATABASE_URL} + + # Database settings + - PROMETHEUS_DATABASE_URL=${PROMETHEUS_DATABASE_URL} networks: - prometheus_network volumes: diff --git a/docker-compose.yml b/docker-compose.yml index a431ccbb..03fb66f3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -54,28 +54,42 @@ services: ports: - "9002:9002" environment: + # Logging - PROMETHEUS_LOGGING_LEVEL=${PROMETHEUS_LOGGING_LEVEL} + + # Neo4j settings - PROMETHEUS_NEO4J_URI=${PROMETHEUS_NEO4J_URI} - PROMETHEUS_NEO4J_USERNAME=${PROMETHEUS_NEO4J_USERNAME} - PROMETHEUS_NEO4J_PASSWORD=${PROMETHEUS_NEO4J_PASSWORD} - PROMETHEUS_NEO4J_BATCH_SIZE=${PROMETHEUS_NEO4J_BATCH_SIZE} + + # Knowledge Graph settings - PROMETHEUS_KNOWLEDGE_GRAPH_MAX_AST_DEPTH=${PROMETHEUS_KNOWLEDGE_GRAPH_MAX_AST_DEPTH} - PROMETHEUS_KNOWLEDGE_GRAPH_CHUNK_SIZE=${PROMETHEUS_KNOWLEDGE_GRAPH_CHUNK_SIZE} - PROMETHEUS_KNOWLEDGE_GRAPH_CHUNK_OVERLAP=${PROMETHEUS_KNOWLEDGE_GRAPH_CHUNK_OVERLAP} - PROMETHEUS_MAX_TOKEN_PER_NEO4J_RESULT=${PROMETHEUS_MAX_TOKEN_PER_NEO4J_RESULT} + - PROMETHEUS_WORKING_DIRECTORY=${PROMETHEUS_WORKING_DIRECTORY} + + # LLM model settings - PROMETHEUS_ADVANCED_MODEL=${PROMETHEUS_ADVANCED_MODEL} - PROMETHEUS_BASE_MODEL=${PROMETHEUS_BASE_MODEL} + + # API keys for various LLM providers - PROMETHEUS_ANTHROPIC_API_KEY=${PROMETHEUS_ANTHROPIC_API_KEY} - PROMETHEUS_GEMINI_API_KEY=${PROMETHEUS_GEMINI_API_KEY} - - PROMETHEUS_OPENAI_API_KEY=${PROMETHEUS_OPENAI_API_KEY} - - PROMETHEUS_OPENROUTER_API_KEY=${PROMETHEUS_OPENROUTER_API_KEY} - - PROMETHEUS_DEEPSEEK_API_KEY=${PROMETHEUS_DEEPSEEK_API_KEY} + - PROMETHEUS_OPENAI_FORMAT_API_KEY=${PROMETHEUS_OPENAI_FORMAT_API_KEY} + - PROMETHEUS_OPENAI_FORMAT_BASE_URL=${PROMETHEUS_OPENAI_FORMAT_BASE_URL} + + # Model settings - PROMETHEUS_MAX_INPUT_TOKENS=${PROMETHEUS_MAX_INPUT_TOKENS} - - PROMETHEUS_TEMPERATURE=${PROMETHEUS_TEMPERATURE} - PROMETHEUS_MAX_OUTPUT_TOKENS=${PROMETHEUS_MAX_OUTPUT_TOKENS} - - PROMETHEUS_WORKING_DIRECTORY=${PROMETHEUS_WORKING_DIRECTORY} + - PROMETHEUS_TEMPERATURE=${PROMETHEUS_TEMPERATURE} + + # GitHub settings - PROMETHEUS_GITHUB_ACCESS_TOKEN=${PROMETHEUS_GITHUB_ACCESS_TOKEN} - - PROMETHEUS_DATABASE_URI=${PROMETHEUS_DATABASE_URL} + + # Database settings + - PROMETHEUS_DATABASE_URL=${PROMETHEUS_DATABASE_URL} volumes: - .:/app - /var/run/docker.sock:/var/run/docker.sock diff --git a/example.env b/example.env index 2d31b25a..5caa86ad 100644 --- a/example.env +++ b/example.env @@ -14,16 +14,15 @@ PROMETHEUS_KNOWLEDGE_GRAPH_CHUNK_SIZE=10000 PROMETHEUS_KNOWLEDGE_GRAPH_CHUNK_OVERLAP=1000 PROMETHEUS_MAX_TOKEN_PER_NEO4J_RESULT=10000 -# LLM API keys and model settings +# LLM model settings PROMETHEUS_ADVANCED_MODEL=gpt-4o PROMETHEUS_BASE_MODEL=gpt-4o # API keys for various LLM providers PROMETHEUS_ANTHROPIC_API_KEY=anthropic_api_key PROMETHEUS_GEMINI_API_KEY=gemini_api_key -PROMETHEUS_OPENAI_API_KEY=openai_api_key -PROMETHEUS_OPENROUTER_API_KEY=openrouter_api_key -PROMETHEUS_DEEPSEEK_API_KEY=deepseek_api_key +PROMETHEUS_OPENAI_FORMAT_BASE_URL=https://api.openai.com/v1 +PROMETHEUS_OPENAI_FORMAT_API_KEY=your_api_key # Model settings PROMETHEUS_MAX_INPUT_TOKENS=64000 @@ -33,10 +32,5 @@ PROMETHEUS_MAX_OUTPUT_TOKENS=15000 # GitHub settings PROMETHEUS_GITHUB_ACCESS_TOKEN=github_access_token -# DATABASE settings +# Database settings PROMETHEUS_DATABASE_URL=postgresql://postgres:password@localhost:5432/postgres?sslmode=disable - -# Superuser settings -PROMETHEUS_SUPERUSER_USERNAME=admin -PROMETHEUS_SUPERUSER_PASSWORD=admin_password -PROMETHEUS_SUPERUSER_EMAIL=admin@outlook.com \ No newline at end of file diff --git a/prometheus/app/dependencies.py b/prometheus/app/dependencies.py index 7e0a7ec4..5b3986d1 100644 --- a/prometheus/app/dependencies.py +++ b/prometheus/app/dependencies.py @@ -37,11 +37,10 @@ def initialize_services() -> ServiceCoordinator: llm_service = LLMService( settings.ADVANCED_MODEL, settings.BASE_MODEL, - getattr(settings, "OPENAI_API_KEY", None), + getattr(settings, "OPENAI_FORMAT_API_KEY", None), + getattr(settings, "OPENAI_FORMAT_BASE_URL", None), getattr(settings, "ANTHROPIC_API_KEY", None), getattr(settings, "GEMINI_API_KEY", None), - getattr(settings, "OPENROUTER_API_KEY", None), - getattr(settings, "DEEPSEEK_API_KEY", None), getattr(settings, "TEMPERATURE", None), getattr(settings, "MAX_OUTPUT_TOKENS", None), ) diff --git a/prometheus/app/services/llm_service.py b/prometheus/app/services/llm_service.py index 991f0cae..e23c0ba1 100644 --- a/prometheus/app/services/llm_service.py +++ b/prometheus/app/services/llm_service.py @@ -17,31 +17,28 @@ def __init__( self, advanced_model_name: str, base_model_name: str, - openai_api_key: Optional[str] = None, + openai_format_api_key: Optional[str] = None, + openai_format_base_url: Optional[str] = None, anthropic_api_key: Optional[str] = None, gemini_api_key: Optional[str] = None, - open_router_api_key: Optional[str] = None, - deepseek_api_key: Optional[str] = None, temperature: float = 0.0, max_output_tokens: int = 15000, ): self.advanced_model = get_model( advanced_model_name, - openai_api_key, + openai_format_api_key, + openai_format_base_url, anthropic_api_key, gemini_api_key, - open_router_api_key, - deepseek_api_key, 0.0, max_output_tokens, ) self.base_model = get_model( base_model_name, - openai_api_key, + openai_format_api_key, + openai_format_base_url, anthropic_api_key, gemini_api_key, - open_router_api_key, - deepseek_api_key, temperature, max_output_tokens, ) @@ -49,37 +46,19 @@ def __init__( def get_model( model_name: str, - openai_api_key: Optional[str] = None, + openai_format_api_key: Optional[str] = None, + openai_format_base_url: Optional[str] = None, anthropic_api_key: Optional[str] = None, gemini_api_key: Optional[str] = None, - open_router_api_key: Optional[str] = None, - deepseek_api_key: Optional[str] = None, temperature: float = 0.0, max_output_tokens: int = 15000, ) -> BaseChatModel: - if "/" in model_name: - return CustomChatOpenAI( - model=model_name, - api_key=open_router_api_key, - base_url="https://openrouter.ai/api/v1", - temperature=temperature, - max_tokens=max_output_tokens, - max_retries=3, - ) - elif "claude" in model_name: + if "claude" in model_name: return ChatAnthropic( - model=model_name, + model_name=model_name, api_key=anthropic_api_key, temperature=temperature, - max_tokens=max_output_tokens, - max_retries=3, - ) - elif "gpt" in model_name: - return CustomChatOpenAI( - model=model_name, - api_key=openai_api_key, - temperature=temperature, - max_tokens=max_output_tokens, + max_tokens_to_sample=max_output_tokens, max_retries=3, ) elif "gemini" in model_name: @@ -90,14 +69,12 @@ def get_model( max_tokens=max_output_tokens, max_retries=3, ) - elif "deepseek" in model_name: + else: return CustomChatOpenAI( model=model_name, - api_key=deepseek_api_key, - base_url="https://api.deepseek.com", + api_key=openai_format_api_key, + base_url=openai_format_base_url, temperature=temperature, max_tokens=max_output_tokens, max_retries=3, ) - else: - raise ValueError(f"Unknown model name: {model_name}") diff --git a/prometheus/script/test_llm_service.py b/prometheus/script/test_llm_service.py new file mode 100644 index 00000000..9919714b --- /dev/null +++ b/prometheus/script/test_llm_service.py @@ -0,0 +1,37 @@ +from langchain_core.messages import HumanMessage + +from prometheus.app.services.llm_service import LLMService +from prometheus.configuration.config import settings + + +def test_model_response(): + llm_service = LLMService( + advanced_model_name=settings.ADVANCED_MODEL, + base_model_name=settings.BASE_MODEL, + openai_format_api_key=settings.OPENAI_FORMAT_API_KEY, + openai_format_base_url=settings.OPENAI_FORMAT_BASE_URL, + anthropic_api_key=settings.ANTHROPIC_API_KEY, + gemini_api_key=settings.GEMINI_API_KEY, + temperature=0.3, + max_output_tokens=55000, + ) + + # Test base model + chat_model = llm_service.base_model + print(f"\nTesting model Base Model: {chat_model.model_name}") + + # Run a simple chat generation + response = chat_model.invoke([HumanMessage(content="Hello! Tell me a fun fact about space.")]) + print("Response:", response.content) + + # Test advanced model + chat_model = llm_service.advanced_model + print(f"\nTesting model Advanced Model: {chat_model.model_name}") + # Run a simple chat generation + response = chat_model.invoke([HumanMessage(content="Hello! Tell me a fun fact about space.")]) + print("Response:", response.content) + print("Test completed successfully!") + + +if __name__ == "__main__": + test_model_response() diff --git a/tests/app/services/test_llm_service.py b/tests/app/services/test_llm_service.py index 31d413e3..06a5f43f 100644 --- a/tests/app/services/test_llm_service.py +++ b/tests/app/services/test_llm_service.py @@ -6,12 +6,6 @@ from prometheus.configuration.config import settings -@pytest.fixture -def mock_chat_openai(): - with patch("prometheus.app.services.llm_service.ChatOpenAI") as mock: - yield mock - - @pytest.fixture def mock_custom_chat_openai(): with patch("prometheus.app.services.llm_service.CustomChatOpenAI") as mock: @@ -41,7 +35,8 @@ def test_llm_service_init(mock_custom_chat_openai, mock_chat_anthropic): service = LLMService( advanced_model_name="gpt-4", base_model_name="claude-2.1", - openai_api_key="openai-key", + openai_format_api_key="openai-key", + openai_format_base_url="https://api.openai.com/v1", anthropic_api_key="anthropic-key", ) @@ -51,22 +46,27 @@ def test_llm_service_init(mock_custom_chat_openai, mock_chat_anthropic): mock_custom_chat_openai.assert_called_once_with( model="gpt-4", api_key="openai-key", + base_url="https://api.openai.com/v1", temperature=0.0, max_tokens=settings.MAX_OUTPUT_TOKENS, max_retries=3, ) mock_chat_anthropic.assert_called_once_with( - model="claude-2.1", + model_name="claude-2.1", api_key="anthropic-key", temperature=0.0, - max_tokens=settings.MAX_OUTPUT_TOKENS, + max_tokens_to_sample=settings.MAX_OUTPUT_TOKENS, max_retries=3, ) -def test_get_model_openrouter(mock_custom_chat_openai): +def test_get_openai_format_model(mock_custom_chat_openai): # Exercise - get_model(model_name="openrouter/model", open_router_api_key="openrouter-key") + get_model( + model_name="openrouter/model", + openai_format_api_key="openrouter-key", + openai_format_base_url="https://openrouter.ai/api/v1", + ) # Verify mock_custom_chat_openai.assert_called_once_with( @@ -85,24 +85,10 @@ def test_get_model_claude(mock_chat_anthropic): # Verify mock_chat_anthropic.assert_called_once_with( - model="claude-2.1", + model_name="claude-2.1", api_key="anthropic-key", temperature=0.0, - max_tokens=settings.MAX_OUTPUT_TOKENS, - max_retries=3, - ) - - -def test_get_model_gpt(mock_custom_chat_openai): - # Exercise - get_model(model_name="gpt-4", openai_api_key="openai-key") - - # Verify - mock_custom_chat_openai.assert_called_once_with( - model="gpt-4", - api_key="openai-key", - temperature=0.0, - max_tokens=settings.MAX_OUTPUT_TOKENS, + max_tokens_to_sample=settings.MAX_OUTPUT_TOKENS, max_retries=3, ) @@ -121,27 +107,6 @@ def test_get_model_gemini(mock_chat_google): ) -def test_get_model_deepseek(mock_custom_chat_openai): - # Exercise - get_model(model_name="deepseek-chat", deepseek_api_key="deepseek-key") - - # Verify - mock_custom_chat_openai.assert_called_once_with( - model="deepseek-chat", - api_key="deepseek-key", - base_url="https://api.deepseek.com", - temperature=0.0, - max_tokens=settings.MAX_OUTPUT_TOKENS, - max_retries=3, - ) - - -def test_get_model_unknown(): - # Exercise & Verify - with pytest.raises(ValueError, match="Unknown model name: unknown-model"): - get_model("unknown-model") - - def test_custom_chat_openai_bind_tools(): # Setup model = CustomChatOpenAI(api_key="test-key")