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" },