diff --git a/docker/Dockerfile b/docker/Dockerfile index 585d777ce..971143136 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,6 +1,6 @@ FROM python:3.11-slim WORKDIR /app COPY . . -RUN pip install flask praisonai==2.2.12 gunicorn markdown +RUN pip install flask praisonai==2.2.13 gunicorn markdown EXPOSE 8080 CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"] diff --git a/docker/Dockerfile.chat b/docker/Dockerfile.chat index 320772556..5645aeada 100644 --- a/docker/Dockerfile.chat +++ b/docker/Dockerfile.chat @@ -13,7 +13,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ RUN pip install --no-cache-dir \ praisonaiagents>=0.0.4 \ praisonai_tools \ - "praisonai==2.2.12" \ + "praisonai==2.2.13" \ "praisonai[chat]" \ "embedchain[github,youtube]" diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index 9e61a2c6e..b759fdfa9 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ RUN pip install --no-cache-dir \ praisonaiagents>=0.0.4 \ praisonai_tools \ - "praisonai==2.2.12" \ + "praisonai==2.2.13" \ "praisonai[ui]" \ "praisonai[chat]" \ "praisonai[realtime]" \ diff --git a/docker/Dockerfile.ui b/docker/Dockerfile.ui index 2f284bbfa..36de7e1d1 100644 --- a/docker/Dockerfile.ui +++ b/docker/Dockerfile.ui @@ -13,7 +13,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ RUN pip install --no-cache-dir \ praisonaiagents>=0.0.4 \ praisonai_tools \ - "praisonai==2.2.12" \ + "praisonai==2.2.13" \ "praisonai[ui]" \ "praisonai[crewai]" diff --git a/docs/api/praisonai/deploy.html b/docs/api/praisonai/deploy.html index 389cacb63..2fb81bd1e 100644 --- a/docs/api/praisonai/deploy.html +++ b/docs/api/praisonai/deploy.html @@ -110,7 +110,7 @@

Raises

file.write("FROM python:3.11-slim\n") file.write("WORKDIR /app\n") file.write("COPY . .\n") - file.write("RUN pip install flask praisonai==2.2.12 gunicorn markdown\n") + file.write("RUN pip install flask praisonai==2.2.13 gunicorn markdown\n") file.write("EXPOSE 8080\n") file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n') diff --git a/docs/developers/local-development.mdx b/docs/developers/local-development.mdx index 53a1e7323..cffdda1dc 100644 --- a/docs/developers/local-development.mdx +++ b/docs/developers/local-development.mdx @@ -27,7 +27,7 @@ WORKDIR /app COPY . . -RUN pip install flask praisonai==2.2.12 watchdog +RUN pip install flask praisonai==2.2.13 watchdog EXPOSE 5555 diff --git a/docs/ui/chat.mdx b/docs/ui/chat.mdx index 4bc03d2a9..3f95c2932 100644 --- a/docs/ui/chat.mdx +++ b/docs/ui/chat.mdx @@ -155,7 +155,7 @@ To facilitate local development with live reload, you can use Docker. Follow the COPY . . - RUN pip install flask praisonai==2.2.12 watchdog + RUN pip install flask praisonai==2.2.13 watchdog EXPOSE 5555 diff --git a/docs/ui/code.mdx b/docs/ui/code.mdx index 98099020c..a506787c9 100644 --- a/docs/ui/code.mdx +++ b/docs/ui/code.mdx @@ -208,7 +208,7 @@ To facilitate local development with live reload, you can use Docker. Follow the COPY . . - RUN pip install flask praisonai==2.2.12 watchdog + RUN pip install flask praisonai==2.2.13 watchdog EXPOSE 5555 diff --git a/praisonai/cli.py b/praisonai/cli.py index 6911f70bd..d5d731ad7 100644 --- a/praisonai/cli.py +++ b/praisonai/cli.py @@ -113,11 +113,15 @@ def __init__(self, agent_file="agents.yaml", framework="", auto=False, init=Fals Initialize the PraisonAI object with default parameters. """ self.agent_yaml = agent_yaml + # Create config_list with AutoGen compatibility + api_key = os.environ.get("OPENAI_API_KEY") self.config_list = [ { 'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4o"), 'base_url': os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1"), - 'api_key': os.environ.get("OPENAI_API_KEY") + 'api_key': api_key, + 'openai_api_key': api_key, # AutoGen sometimes expects this field name + 'api_type': 'openai' # AutoGen expects this field } ] self.agent_file = agent_file diff --git a/praisonai/deploy.py b/praisonai/deploy.py index c90de92d7..7eb2107ae 100644 --- a/praisonai/deploy.py +++ b/praisonai/deploy.py @@ -56,7 +56,7 @@ def create_dockerfile(self): file.write("FROM python:3.11-slim\n") file.write("WORKDIR /app\n") file.write("COPY . .\n") - file.write("RUN pip install flask praisonai==2.2.12 gunicorn markdown\n") + file.write("RUN pip install flask praisonai==2.2.13 gunicorn markdown\n") file.write("EXPOSE 8080\n") file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n') diff --git a/pyproject.toml b/pyproject.toml index 573141802..c6eea8ca4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "PraisonAI" -version = "2.2.12" +version = "2.2.13" description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration." readme = "README.md" license = "" @@ -89,7 +89,7 @@ autogen = ["pyautogen>=0.2.19", "praisonai-tools>=0.0.15", "crewai"] [tool.poetry] name = "PraisonAI" -version = "2.2.12" +version = "2.2.13" description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration." authors = ["Mervin Praison"] license = "" diff --git a/tests/test.py b/tests/test.py index 5e3c4e089..bffa77072 100644 --- a/tests/test.py +++ b/tests/test.py @@ -18,10 +18,15 @@ def test_main_with_agents_advanced(self): result = praisonai.run() self.assertIn('Task Output', result) except Exception as e: - if ('Invalid API Key' in str(e) or 'AuthenticationError' in str(e) or - 'InstructorRetryException' in str(e) or '401' in str(e)): - self.skipTest(f"Skipping due to API authentication: {e}") + # Only skip if no API key provided or using test/fallback key + api_key = os.environ.get('OPENAI_API_KEY', '') + if (not api_key or + api_key.startswith('sk-test-') or + api_key == 'nokey' or + 'fallback' in api_key): + self.skipTest(f"Skipping due to no valid API key provided: {e}") else: + # Real API key provided - test should fail, not skip raise def test_main_with_autogen_framework(self): @@ -30,10 +35,15 @@ def test_main_with_autogen_framework(self): result = praisonai.run() self.assertTrue('Task Output' in result or '### Output ###' in result) except Exception as e: - if ('Invalid API Key' in str(e) or 'AuthenticationError' in str(e) or - 'InstructorRetryException' in str(e) or '401' in str(e)): - self.skipTest(f"Skipping due to API authentication: {e}") + # Only skip if no API key provided or using test/fallback key + api_key = os.environ.get('OPENAI_API_KEY', '') + if (not api_key or + api_key.startswith('sk-test-') or + api_key == 'nokey' or + 'fallback' in api_key): + self.skipTest(f"Skipping due to no valid API key provided: {e}") else: + # Real API key provided - test should fail, not skip raise def test_main_with_custom_framework(self): @@ -42,10 +52,15 @@ def test_main_with_custom_framework(self): result = praisonai.run() self.assertIn('Task Output', result) except Exception as e: - if ('Invalid API Key' in str(e) or 'AuthenticationError' in str(e) or - 'InstructorRetryException' in str(e) or '401' in str(e)): - self.skipTest(f"Skipping due to API authentication: {e}") + # Only skip if no API key provided or using test/fallback key + api_key = os.environ.get('OPENAI_API_KEY', '') + if (not api_key or + api_key.startswith('sk-test-') or + api_key == 'nokey' or + 'fallback' in api_key): + self.skipTest(f"Skipping due to no valid API key provided: {e}") else: + # Real API key provided - test should fail, not skip raise def test_main_with_internet_search_tool(self): @@ -54,10 +69,15 @@ def test_main_with_internet_search_tool(self): result = praisonai.run() self.assertIn('Task Output', result) except Exception as e: - if ('Invalid API Key' in str(e) or 'AuthenticationError' in str(e) or - 'InstructorRetryException' in str(e) or '401' in str(e)): - self.skipTest(f"Skipping due to API authentication: {e}") + # Only skip if no API key provided or using test/fallback key + api_key = os.environ.get('OPENAI_API_KEY', '') + if (not api_key or + api_key.startswith('sk-test-') or + api_key == 'nokey' or + 'fallback' in api_key): + self.skipTest(f"Skipping due to no valid API key provided: {e}") else: + # Real API key provided - test should fail, not skip raise def test_main_with_built_in_tool(self): @@ -66,10 +86,15 @@ def test_main_with_built_in_tool(self): result = praisonai.run() self.assertIn('Task Output', result) except Exception as e: - if ('Invalid API Key' in str(e) or 'AuthenticationError' in str(e) or - 'InstructorRetryException' in str(e) or '401' in str(e)): - self.skipTest(f"Skipping due to API authentication: {e}") + # Only skip if no API key provided or using test/fallback key + api_key = os.environ.get('OPENAI_API_KEY', '') + if (not api_key or + api_key.startswith('sk-test-') or + api_key == 'nokey' or + 'fallback' in api_key): + self.skipTest(f"Skipping due to no valid API key provided: {e}") else: + # Real API key provided - test should fail, not skip raise @@ -88,19 +113,29 @@ def run_command(self, command): def test_praisonai_command(self): command = "praisonai --framework autogen --auto create movie script about cat in mars" result = self.run_command(command) - # Handle API authentication errors in command line output - if ('Invalid API Key' in result or 'AuthenticationError' in result or - 'InstructorRetryException' in result or '401' in result): - self.skipTest(f"Skipping due to API authentication in command output") + # Only skip if no API key provided or using test/fallback key + api_key = os.environ.get('OPENAI_API_KEY', '') + if (not api_key or + api_key.startswith('sk-test-') or + api_key == 'nokey' or + 'fallback' in api_key): + if ('Invalid API Key' in result or 'AuthenticationError' in result or + 'InstructorRetryException' in result or '401' in result): + self.skipTest(f"Skipping due to no valid API key provided") self.assertIn('TERMINATE', result) def test_praisonai_init_command(self): command = "praisonai --framework autogen --init create movie script about cat in mars" result = self.run_command(command) - # Handle API authentication errors in command line output - if ('Invalid API Key' in result or 'AuthenticationError' in result or - 'InstructorRetryException' in result or '401' in result): - self.skipTest(f"Skipping due to API authentication in command output") + # Only skip if no API key provided or using test/fallback key + api_key = os.environ.get('OPENAI_API_KEY', '') + if (not api_key or + api_key.startswith('sk-test-') or + api_key == 'nokey' or + 'fallback' in api_key): + if ('Invalid API Key' in result or 'AuthenticationError' in result or + 'InstructorRetryException' in result or '401' in result): + self.skipTest(f"Skipping due to no valid API key provided") self.assertIn('created successfully', result) class TestExamples(unittest.TestCase): @@ -119,10 +154,15 @@ def test_basic_example(self): f"Expected meaningful result, got: {result}" ) except Exception as e: - if ('Invalid API Key' in str(e) or 'AuthenticationError' in str(e) or - 'InstructorRetryException' in str(e) or '401' in str(e)): - self.skipTest(f"Skipping due to API authentication: {e}") + # Only skip if no API key provided or using test/fallback key + api_key = os.environ.get('OPENAI_API_KEY', '') + if (not api_key or + api_key.startswith('sk-test-') or + api_key == 'nokey' or + 'fallback' in api_key): + self.skipTest(f"Skipping due to no valid API key provided: {e}") else: + # Real API key provided - test should fail, not skip raise def test_advanced_example(self): @@ -140,10 +180,15 @@ def test_advanced_example(self): f"Expected meaningful result, got: {result}" ) except Exception as e: - if ('Invalid API Key' in str(e) or 'AuthenticationError' in str(e) or - 'InstructorRetryException' in str(e) or '401' in str(e)): - self.skipTest(f"Skipping due to API authentication: {e}") + # Only skip if no API key provided or using test/fallback key + api_key = os.environ.get('OPENAI_API_KEY', '') + if (not api_key or + api_key.startswith('sk-test-') or + api_key == 'nokey' or + 'fallback' in api_key): + self.skipTest(f"Skipping due to no valid API key provided: {e}") else: + # Real API key provided - test should fail, not skip raise def test_auto_example(self): @@ -161,10 +206,15 @@ def test_auto_example(self): f"Expected meaningful result, got: {result}" ) except Exception as e: - if ('Invalid API Key' in str(e) or 'AuthenticationError' in str(e) or - 'InstructorRetryException' in str(e) or '401' in str(e)): - self.skipTest(f"Skipping due to API authentication: {e}") + # Only skip if no API key provided or using test/fallback key + api_key = os.environ.get('OPENAI_API_KEY', '') + if (not api_key or + api_key.startswith('sk-test-') or + api_key == 'nokey' or + 'fallback' in api_key): + self.skipTest(f"Skipping due to no valid API key provided: {e}") else: + # Real API key provided - test should fail, not skip raise if __name__ == '__main__': diff --git a/uv.lock b/uv.lock index df891e85d..276b7bd7e 100644 --- a/uv.lock +++ b/uv.lock @@ -3614,7 +3614,7 @@ wheels = [ [[package]] name = "praisonai" -version = "2.2.12" +version = "2.2.13" source = { editable = "." } dependencies = [ { name = "instructor" },