Compare commits

...
3 Commits
Author SHA1 Message Date
Mervin Praison 4f31ec9b63 Update PraisonAI and related dependencies to version 2.2.43 and praisonaiagents to version 0.0.116 across Dockerfiles, README, and project files for consistency and compatibility. 2025-07-09 00:37:21 +01:00
Mervin Praison abee86337d Merge pull request #774 from MervinPraison/claude/pr-773-20250708_232256
fix: add array schema validation to llm.py for MCP tools compatibility
2025-07-09 00:34:52 +01:00
claude[bot]andMervin Praison e6cf4ebfcd fix: add array schema validation to llm.py for MCP tools compatibility
- Add _fix_array_schemas method to recursively fix missing 'items' in array schemas
- Apply fix to pre-formatted tools in _format_tools_for_litellm
- Apply fix to generated tool definitions in _generate_tool_definition
- Ensures OpenAI compatibility for all tool types (MCP, pre-formatted, generated)
- Maintains backward compatibility by only adding missing fields

Related to PR #773

Co-authored-by: Mervin Praison <[email protected]>
2025-07-08 23:27:14 +00:00
12 changed files with 71 additions and 23 deletions

No files matched your search

+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
flask \
"praisonai>=2.2.42" \
"praisonai>=2.2.43" \
"praisonai[api]" \
gunicorn \
markdown
+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=2.2.42" \
"praisonai>=2.2.43" \
"praisonai[chat]" \
"embedchain[github,youtube]"
+1 -1
View File
@@ -20,7 +20,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=2.2.42" \
"praisonai>=2.2.43" \
"praisonai[ui]" \
"praisonai[chat]" \
"praisonai[realtime]" \
+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=2.2.42" \
"praisonai>=2.2.43" \
"praisonai[ui]" \
"praisonai[crewai]"
+2 -2
View File
@@ -121,7 +121,7 @@ healthcheck:
## 📦 Package Versions
All Docker images use consistent, up-to-date versions:
- PraisonAI: `>=2.2.42`
- PraisonAI: `>=2.2.43`
- PraisonAI Agents: `>=0.0.92`
- Python: `3.11-slim`
@@ -218,7 +218,7 @@ docker-compose up -d
### Version Pinning
To use specific versions, update the Dockerfile:
```dockerfile
RUN pip install "praisonai==2.2.42" "praisonaiagents==0.0.92"
RUN pip install "praisonai==2.2.43" "praisonaiagents==0.0.92"
```
## 🌐 Production Deployment
@@ -364,6 +364,46 @@ class LLM:
return messages, original_prompt
def _fix_array_schemas(self, schema: Dict) -> Dict:
"""
Recursively fix array schemas by adding missing 'items' attribute.
This ensures compatibility with OpenAI's function calling format which
requires array types to specify the type of items they contain.
Args:
schema: The schema dictionary to fix
Returns:
dict: The fixed schema
"""
if not isinstance(schema, dict):
return schema
# Create a copy to avoid modifying the original
fixed_schema = schema.copy()
# Fix array types at the current level
if fixed_schema.get("type") == "array" and "items" not in fixed_schema:
# Add a default items schema for arrays without it
fixed_schema["items"] = {"type": "string"}
# Recursively fix nested schemas in properties
if "properties" in fixed_schema and isinstance(fixed_schema["properties"], dict):
fixed_properties = {}
for prop_name, prop_schema in fixed_schema["properties"].items():
if isinstance(prop_schema, dict):
fixed_properties[prop_name] = self._fix_array_schemas(prop_schema)
else:
fixed_properties[prop_name] = prop_schema
fixed_schema["properties"] = fixed_properties
# Fix items schema if it exists
if "items" in fixed_schema and isinstance(fixed_schema["items"], dict):
fixed_schema["items"] = self._fix_array_schemas(fixed_schema["items"])
return fixed_schema
def _format_tools_for_litellm(self, tools: Optional[List[Any]]) -> Optional[List[Dict]]:
"""Format tools for LiteLLM - handles all tool formats.
@@ -389,7 +429,11 @@ class LLM:
# Validate nested dictionary structure before accessing
if 'function' in tool and isinstance(tool['function'], dict) and 'name' in tool['function']:
logging.debug(f"Using pre-formatted OpenAI tool: {tool['function']['name']}")
formatted_tools.append(tool)
# Fix array schemas in the tool parameters
fixed_tool = tool.copy()
if 'parameters' in fixed_tool['function']:
fixed_tool['function']['parameters'] = self._fix_array_schemas(fixed_tool['function']['parameters'])
formatted_tools.append(fixed_tool)
else:
logging.debug(f"Skipping malformed OpenAI tool: missing function or name")
# Handle lists of tools (e.g. from MCP.to_openai_tool())
@@ -399,7 +443,11 @@ class LLM:
# Validate nested dictionary structure before accessing
if 'function' in subtool and isinstance(subtool['function'], dict) and 'name' in subtool['function']:
logging.debug(f"Using pre-formatted OpenAI tool from list: {subtool['function']['name']}")
formatted_tools.append(subtool)
# Fix array schemas in the tool parameters
fixed_tool = subtool.copy()
if 'parameters' in fixed_tool['function']:
fixed_tool['function']['parameters'] = self._fix_array_schemas(fixed_tool['function']['parameters'])
formatted_tools.append(fixed_tool)
else:
logging.debug(f"Skipping malformed OpenAI tool in list: missing function or name")
elif callable(tool):
@@ -2153,7 +2201,7 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
"function": {
"name": function_name,
"description": docstring.split('\n\n')[0] if docstring else "No description available",
"parameters": parameters
"parameters": self._fix_array_schemas(parameters)
}
}
logging.debug(f"Generated tool definition: {tool_def}")
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "praisonaiagents"
version = "0.0.115"
version = "0.0.116"
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
requires-python = ">=3.10"
authors = [
+1 -1
View File
@@ -2375,7 +2375,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "0.0.115"
version = "0.0.116"
source = { editable = "." }
dependencies = [
{ name = "mcp" },
+2 -2
View File
@@ -3,8 +3,8 @@ class Praisonai < Formula
desc "AI tools for various AI applications"
homepage "https://github.com/MervinPraison/PraisonAI"
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.42.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.42.tar.gz | shasum -a 256`.split.first
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.43.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.43.tar.gz | shasum -a 256`.split.first
license "MIT"
depends_on "[email protected]"
+1 -1
View File
@@ -57,7 +57,7 @@ class CloudDeployer:
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.42 gunicorn markdown\n")
file.write("RUN pip install flask praisonai==2.2.43 gunicorn markdown\n")
file.write("EXPOSE 8080\n")
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
+4 -4
View File
@@ -1,6 +1,6 @@
[project]
name = "PraisonAI"
version = "2.2.42"
version = "2.2.43"
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 = ""
@@ -12,7 +12,7 @@ dependencies = [
"rich>=13.7",
"markdown>=3.5",
"pyparsing>=3.0.0",
"praisonaiagents>=0.0.115",
"praisonaiagents>=0.0.116",
"python-dotenv>=0.19.0",
"instructor>=1.3.3",
"PyYAML>=6.0",
@@ -95,7 +95,7 @@ autogen = ["pyautogen>=0.2.19", "praisonai-tools>=0.0.15", "crewai"]
[tool.poetry]
name = "PraisonAI"
version = "2.2.42"
version = "2.2.43"
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 = ""
@@ -113,7 +113,7 @@ python = ">=3.10,<3.13"
rich = ">=13.7"
markdown = ">=3.5"
pyparsing = ">=3.0.0"
praisonaiagents = ">=0.0.115"
praisonaiagents = ">=0.0.116"
python-dotenv = ">=0.19.0"
instructor = ">=1.3.3"
PyYAML = ">=6.0"
+5 -5
View File
@@ -3931,7 +3931,7 @@ wheels = [
[[package]]
name = "praisonai"
version = "2.2.42"
version = "2.2.43"
source = { editable = "." }
dependencies = [
{ name = "instructor" },
@@ -4073,7 +4073,7 @@ requires-dist = [
{ name = "plotly", marker = "extra == 'realtime'", specifier = ">=5.24.0" },
{ name = "praisonai-tools", marker = "extra == 'autogen'", specifier = ">=0.0.15" },
{ name = "praisonai-tools", marker = "extra == 'crewai'", specifier = ">=0.0.15" },
{ name = "praisonaiagents", specifier = ">=0.0.115" },
{ name = "praisonaiagents", specifier = ">=0.0.116" },
{ name = "pyautogen", marker = "extra == 'autogen'", specifier = ">=0.2.19" },
{ name = "pydantic", marker = "extra == 'chat'", specifier = "<=2.10.1" },
{ name = "pydantic", marker = "extra == 'code'", specifier = "<=2.10.1" },
@@ -4130,7 +4130,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "0.0.115"
version = "0.0.116"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "mcp" },
@@ -4139,9 +4139,9 @@ dependencies = [
{ name = "pydantic" },
{ name = "rich" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c4/f3/33062dc9811b44ac0dc760b88ca3f3ce52f205021f5392785b4959e695f0/praisonaiagents-0.0.115.tar.gz", hash = "sha256:67fc681325846eb56c82ae2aba8907e9a3c934b91a754729c6e37071418b9dd3", size = 172218 }
sdist = { url = "https://files.pythonhosted.org/packages/5e/3b/61a7b4b57817b2d5eabdac89df126ef39ba06c7a43d7b17786d7d6882f44/praisonaiagents-0.0.116.tar.gz", hash = "sha256:6e5de5ece6c2550fee9a59cf3d0c9a8da09cd22acfaf8037873b7649493962ca", size = 172642 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/92/ac/e4db3abf1acd9a0f9d24771ab3e71b70a11ca580bae1158287a1e5670ed5/praisonaiagents-0.0.115-py3-none-any.whl", hash = "sha256:7815f9882994fc512dacbc0808d7df2591f16189a1b044e361f01ae98719d6f1", size = 192799 },
{ url = "https://files.pythonhosted.org/packages/21/4f/5fbe1e129f5b0ab7386e17dbb4f7cc97ec896291db82b601605d4721616d/praisonaiagents-0.0.116-py3-none-any.whl", hash = "sha256:2449de40da7653100b247c3338afe0dcde3b0dc4227c3edd0111e24b4f5083ab", size = 193268 },
]
[[package]]