Compare commits

...
9 Commits
Author SHA1 Message Date
Mervin Praison b02449dfdb chore: bump praisonai to v2.2.60 and praisonaiagents to v0.0.134 2025-07-15 09:55:35 +01:00
Mervin Praison c4c0c1c146 Merge pull request #923 from MervinPraison/claude/issue-919-20250715_061529
fix: Add support for Gemini internal tools in tool formatting
2025-07-15 09:52:47 +01:00
Mervin Praison aa2d7e4c31 Merge pull request #924 from Dhivya-Bharathy/kimi2-agents-final
Add Kimi2_Intelligent_Agents: 10 specialized AI agents
2025-07-15 09:51:35 +01:00
Dhivya-Bharathy b339c5b3aa Add Kimi2_Intelligent_Agents: 10 specialized AI agents 2025-07-15 12:57:48 +05:30
github-actions[bot]andMervin Praison e535f98f4e refactor: optimize Gemini tools handling with shared utilities
- Extract GEMINI_INTERNAL_TOOLS constant to eliminate loop recreation
- Create shared is_gemini_internal_tool() utility function
- Remove code duplication between llm.py and openai_client.py
- Improve maintainability and performance based on reviewer feedback

Co-authored-by: Mervin Praison <[email protected]>
2025-07-15 06:40:42 +00:00
Mervin Praison bc349ad09f feat: restrict review comments to PRs only and update Claude bot instructions 2025-07-15 07:38:32 +01:00
Mervin Praison 5b8da1180e chore: clarify Claude review instructions to specify branch context 2025-07-15 07:29:21 +01:00
github-actions[bot]andMervin Praison 8f6d8f0a48 fix: Add support for Gemini internal tools in tool formatting
- Add explicit handling for Gemini internal tools (googleSearch, urlContext, codeExecution)
- Update docstrings to document new capability
- Resolves issue where Gemini internal tools were skipped with ''unsupported type'' error
- Maintains backward compatibility with existing tool formats

Closes #919

Co-authored-by: Mervin Praison <[email protected]>
2025-07-15 06:23:32 +00:00
Mervin Praison 7f3810ed98 chore: add gh tool permission and update claude review comment with PR creation request 2025-07-15 07:19:48 +01:00
26 changed files with 2240 additions and 2081 deletions

No files matched your search

+1 -1
View File
@@ -22,5 +22,5 @@ jobs:
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '@claude review this issue and do a detailed analysis and fix this if the existing code doesn\'t have the solution implemented. Making sure it has backward compatibility, no existing features removed. After making those changes, again review the applied changes. Use @web to search if you dont know any information or to find the latest documentation or to find the latest version. Run the code if you think you need to run it to test it. Minimal code change to start with if required any changes. **Please create a PR with your changes**.'
body: '@claude review this issue and do a detailed analysis and fix this if the existing code doesn\'t have the solution implemented. Making sure it has backward compatibility, no existing features removed. After making those changes, again review the applied changes. Use @web to search if you dont know any information or to find the latest documentation or to find the latest version. Run the code if you think you need to run it to test it. Minimal code change to start with if required any changes. **Please create a PR using gh tool with your changes**.'
})
+20 -10
View File
@@ -42,6 +42,7 @@ jobs:
Bash(pip:*)
Bash(conda:*)
Bash(pytest:*)
Bash(gh:*)
Bash(python -m pytest:*)
Bash(python -m pip:*)
Bash(poetry:*)
@@ -129,23 +130,32 @@ jobs:
github-token: ${{ secrets.GH_TOKEN }}
script: |
let issueNumber;
let isPR = false;
// Determine issue/PR number based on event type
// Determine issue/PR number and type based on event type
if (context.eventName === 'pull_request_review_comment' || context.eventName === 'pull_request_review') {
issueNumber = context.payload.pull_request?.number || context.issue.number;
isPR = true;
} else if (context.eventName === 'issue_comment' && context.payload.issue.pull_request) {
// This is a comment on a PR (not an issue)
issueNumber = context.payload.issue.number;
isPR = true;
} else {
// This is a regular issue
// This is a regular issue - don't post review comment
issueNumber = context.issue.number;
isPR = false;
}
console.log(`Posting review comment on issue/PR #${issueNumber}`);
await github.rest.issues.createComment({
issue_number: issueNumber,
owner: context.repo.owner,
repo: context.repo.repo,
body: '@claude review if the changes made are as per the requirements and make changes if issues still exist.'
});
// Only post review comment on PRs, not regular issues
if (isPR) {
console.log(`Posting review comment on PR #${issueNumber}`);
await github.rest.issues.createComment({
issue_number: issueNumber,
owner: context.repo.owner,
repo: context.repo.repo,
body: '@claude review if the changes made in the above branch are as per the requirements and make changes to the above branch if issues still exist.'
});
} else {
console.log(`Skipping review comment for regular issue #${issueNumber}`);
}
+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.59" \
"praisonai>=2.2.60" \
"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.59" \
"praisonai>=2.2.60" \
"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.59" \
"praisonai>=2.2.60" \
"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.59" \
"praisonai>=2.2.60" \
"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.59`
- PraisonAI: `>=2.2.60`
- 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.59" "praisonaiagents==0.0.92"
RUN pip install "praisonai==2.2.60" "praisonaiagents==0.0.92"
```
## 🌐 Production Deployment
@@ -0,0 +1,11 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are an audio tour creation AI agent. "
"Help users create engaging audio tours, guided experiences, and interactive storytelling content. "
"Provide guidance on script writing, audio production, location-based content, and immersive experiences.",
llm="openrouter/moonshotai/kimi-k2"
)
response = agent.start("Hello! I'm your audio tour creation assistant. "
"How can I help you create captivating audio experiences today?")
@@ -0,0 +1,11 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are a chess AI agent. "
"Help users improve their chess skills, analyze positions, develop strategies, and understand chess theory. "
"Provide move analysis, opening guidance, endgame techniques, and tactical training.",
llm="openrouter/moonshotai/kimi-k2"
)
response = agent.start("Hello! I'm your chess assistant. "
"How can I help you improve your chess game today?")
@@ -0,0 +1,11 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are a creative writing AI agent. "
"Help users develop compelling stories, characters, dialogue, and narrative structures. "
"Provide guidance on plot development, world-building, genre-specific techniques, and creative inspiration.",
llm="openrouter/moonshotai/kimi-k2"
)
response = agent.start("Hello! I'm your creative writing assistant. "
"How can I help you bring your stories and ideas to life today?")
@@ -0,0 +1,11 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are a cybersecurity AI agent. "
"Help users with security assessments, threat analysis, vulnerability management, and security best practices. "
"Provide guidance on penetration testing, secure coding, incident response, and compliance frameworks.",
llm="openrouter/moonshotai/kimi-k2"
)
response = agent.start("Hello! I'm your cybersecurity assistant. "
"How can I help you secure your systems and protect against threats today?")
@@ -0,0 +1,11 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are a data visualization AI agent. "
"Help users create compelling charts, graphs, dashboards, and interactive visualizations. "
"Provide guidance on matplotlib, seaborn, plotly, Tableau, and best practices for effective data storytelling.",
llm="openrouter/moonshotai/kimi-k2"
)
response = agent.start("Hello! I'm your data visualization assistant. "
"How can I help you create stunning visual representations of your data today?")
@@ -0,0 +1,11 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are a 3D PyGame development AI agent. "
"Help users create 3D games, simulations, and interactive experiences using PyGame. "
"Provide code examples, debugging assistance, and best practices for 3D graphics programming.",
llm="openrouter/moonshotai/kimi-k2"
)
response = agent.start("Hello! I'm your 3D PyGame development assistant. "
"How can I help you create amazing 3D games today?")
@@ -0,0 +1,11 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are a self-evolving AI agent. "
"Continuously learn from interactions, adapt your responses, and improve your capabilities. "
"Help users with complex problem-solving, creative tasks, and provide insights that evolve based on context and user needs.",
llm="openrouter/moonshotai/kimi-k2"
)
response = agent.start("Hello! I'm your self-evolving AI assistant. "
"How can I help you today, and how can I learn and improve from our interaction?")
@@ -0,0 +1,11 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are a startup insight AI agent. "
"Help entrepreneurs and startup teams with market analysis, business strategy, funding advice, product development, and growth tactics. "
"Provide actionable insights for building successful startups.",
llm="openrouter/moonshotai/kimi-k2"
)
response = agent.start("Hello! I'm your startup insight assistant. "
"How can I help you build and grow your startup today?")
@@ -0,0 +1,11 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are a system architecture AI agent. "
"Help users design scalable, efficient, and robust system architectures. "
"Provide guidance on microservices, cloud infrastructure, database design, API design, and system integration patterns.",
llm="openrouter/moonshotai/kimi-k2"
)
response = agent.start("Hello! I'm your system architecture assistant. "
"How can I help you design and optimize your system architecture today?")
@@ -0,0 +1,11 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are a web scraping AI agent. "
"Help users create efficient and ethical web scrapers, data extraction tools, and automation scripts. "
"Provide guidance on BeautifulSoup, Selenium, Scrapy, and best practices for responsible web scraping.",
llm="openrouter/moonshotai/kimi-k2"
)
response = agent.start("Hello! I'm your web scraping assistant. "
"How can I help you extract and analyze web data today?")
@@ -16,6 +16,7 @@ from ..main import (
ReflectionOutput,
execute_sync_callback,
)
from .model_capabilities import is_gemini_internal_tool
from rich.console import Console
from rich.live import Live
@@ -542,6 +543,7 @@ class LLM:
- Lists of pre-formatted tools
- Callable functions
- String function names
- Gemini internal tools ({"googleSearch": {}}, {"urlContext": {}}, {"codeExecution": {}})
Args:
tools: List of tools in various formats
@@ -588,6 +590,11 @@ class LLM:
tool_def = self._generate_tool_definition(tool)
if tool_def:
formatted_tools.append(tool_def)
# Handle Gemini internal tools (e.g., {"googleSearch": {}}, {"urlContext": {}}, {"codeExecution": {}})
elif is_gemini_internal_tool(tool):
tool_name = next(iter(tool.keys()))
logging.debug(f"Using Gemini internal tool: {tool_name}")
formatted_tools.append(tool)
else:
logging.debug(f"Skipping tool of unsupported type: {type(tool)}")
@@ -104,4 +104,27 @@ def supports_streaming_with_tools(model_name: str) -> bool:
"""
# For now, use the same logic as structured outputs
# In the future, this could be a separate list if needed
return supports_structured_outputs(model_name)
return supports_structured_outputs(model_name)
# Supported Gemini internal tools
GEMINI_INTERNAL_TOOLS = {'googleSearch', 'urlContext', 'codeExecution'}
def is_gemini_internal_tool(tool) -> bool:
"""
Check if a tool is a Gemini internal tool and should be included in formatted tools.
Gemini internal tools are single-key dictionaries with specific tool names.
Examples: {"googleSearch": {}}, {"urlContext": {}}, {"codeExecution": {}}
Args:
tool: The tool to check
Returns:
bool: True if the tool is a recognized Gemini internal tool, False otherwise
"""
if isinstance(tool, dict) and len(tool) == 1:
tool_name = next(iter(tool.keys()))
return tool_name in GEMINI_INTERNAL_TOOLS
return False
@@ -18,6 +18,7 @@ from dataclasses import dataclass
from rich.console import Console
from rich.live import Live
import inspect
from .model_capabilities import is_gemini_internal_tool
# Constants
LOCAL_SERVER_API_KEY_PLACEHOLDER = "not-needed"
@@ -360,6 +361,7 @@ class OpenAIClient:
- Callable functions
- String function names
- MCP tools
- Gemini internal tools ({"googleSearch": {}}, {"urlContext": {}}, {"codeExecution": {}})
Args:
tools: List of tools in various formats
@@ -404,6 +406,11 @@ class OpenAIClient:
tool_def = self._generate_tool_definition_from_name(tool)
if tool_def:
formatted_tools.append(tool_def)
# Handle Gemini internal tools (e.g., {"googleSearch": {}}, {"urlContext": {}}, {"codeExecution": {}})
elif is_gemini_internal_tool(tool):
tool_name = next(iter(tool.keys()))
logging.debug(f"Using Gemini internal tool: {tool_name}")
formatted_tools.append(tool)
else:
logging.debug(f"Skipping tool of unsupported type: {type(tool)}")
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "praisonaiagents"
version = "0.0.133"
version = "0.0.134"
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
requires-python = ">=3.10"
authors = [
+2052 -2050
View File
File diff suppressed because it is too large. Load diff
+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.59.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.59.tar.gz | shasum -a 256`.split.first
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.60.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.60.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.59 gunicorn markdown\n")
file.write("RUN pip install flask praisonai==2.2.60 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.59"
version = "2.2.60"
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.133",
"praisonaiagents>=0.0.134",
"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.59"
version = "2.2.60"
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.133"
praisonaiagents = ">=0.0.134"
python-dotenv = ">=0.19.0"
instructor = ">=1.3.3"
PyYAML = ">=6.0"
+5 -5
View File
@@ -3932,7 +3932,7 @@ wheels = [
[[package]]
name = "praisonai"
version = "2.2.59"
version = "2.2.60"
source = { editable = "." }
dependencies = [
{ name = "instructor" },
@@ -4074,7 +4074,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.133" },
{ name = "praisonaiagents", specifier = ">=0.0.134" },
{ 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" },
@@ -4132,7 +4132,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "0.0.133"
version = "0.0.134"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aiohttp" },
@@ -4142,9 +4142,9 @@ dependencies = [
{ name = "pydantic" },
{ name = "rich" },
]
sdist = { url = "https://files.pythonhosted.org/packages/90/b6/fed716f4b72dce4bb9d0f86c291eaa49f1a82cb4a22ea0897074a85a3ecb/praisonaiagents-0.0.133.tar.gz", hash = "sha256:6242bedc1d5df13e05bf4884a64df56b08691d2e32efca3cebb911012bcc6d70", size = 200408, upload-time = "2025-07-15T06:12:25.239Z" }
sdist = { url = "https://files.pythonhosted.org/packages/d9/66/82e37c0c6d74a8abae69f243ab4adaf038943716d5f94894c77031a974a0/praisonaiagents-0.0.134.tar.gz", hash = "sha256:8d408b761012bc8c66b6d567036c054d29d4caaa7d8160e513f2eec3274d0f72", size = 200773, upload-time = "2025-07-15T08:54:22.249Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f8/42/3741a07cbbfc29f81827ed096c0d12d4d71a316c0e250fd94b4ac2e0bb18/praisonaiagents-0.0.133-py3-none-any.whl", hash = "sha256:60b9994c07482364de10d49c16fe3c4c280c35b1d50355ef461a8d6d0ed9070f", size = 220312, upload-time = "2025-07-15T06:12:23.711Z" },
{ url = "https://files.pythonhosted.org/packages/41/0e/b2ec13f4d3e6f53cbfbe1b26138882b792d5441bd7eefa122a7edb64339c/praisonaiagents-0.0.134-py3-none-any.whl", hash = "sha256:b956e79411eace9c4005ae241d06b40ae07c1680f1d1c9fb5c3f009192a13900", size = 220808, upload-time = "2025-07-15T08:54:20.773Z" },
]
[[package]]