-
-
Notifications
You must be signed in to change notification settings - Fork 687
feat: Refactor Claude Code integration to use PraisonAI Agents #635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Replace litellm direct usage with praisonaiagents framework - Implement Claude Code as a custom tool that agents can decide to use - Add --claudecode CLI flag support: `praisonai code --claudecode` - Create intelligent agent that chooses when to use Claude Code vs regular responses - Maintain full backward compatibility with litellm fallback - Add UI toggle switch for enabling/disabling Claude Code - Implement git operations with automatic branch creation and PR URLs - Add comprehensive error handling and streaming support - Include test script and detailed documentation Key improvements: - Agent-driven decision making instead of manual detection logic - Better tool coordination and flexibility - Minimal code changes with maintained compatibility - Enhanced user experience with intelligent tool selection Co-Authored-By: MervinPraison <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @MervinPraison, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request significantly changes how Claude Code is integrated into the PraisonAI Code UI. Instead of detecting user intent and calling Claude Code directly, the system now leverages the praisonaiagents
framework. Claude Code is exposed as a tool to the agent, allowing the agent to decide when file modifications or coding tasks are required and delegate them to the Claude Code tool. This enhances the intelligence and flexibility of the interaction while maintaining compatibility with the previous approach.
Highlights
- Core Refactor: The Claude Code integration has been refactored to utilize the
praisonaiagents
framework, moving away from directlitellm
usage for this specific functionality. - Agent Tool: Claude Code is now implemented as a custom tool (
claude_code_tool
) that the PraisonAI agent can intelligently decide to use based on the user's request, rather than relying on manual detection logic. - Configuration Options: Added support for enabling Claude Code via a new
--claudecode
CLI flag, a UI toggle switch in the chat settings, and an environment variable (PRAISONAI_CLAUDECODE_ENABLED
). The CLI flag takes precedence. - Backward Compatibility: The system includes a fallback mechanism to the previous
litellm
-based handling if thepraisonaiagents
library is not available, ensuring existing functionality is preserved. - Enhanced Git Integration: The
claude_code_tool
now includes logic for automatic git branch creation, committing changes made by Claude Code, pushing to the remote, and generating a GitHub PR URL if git is available and configured. - Documentation and Testing: A comprehensive markdown document (
CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md
) detailing the integration, architecture, usage, and troubleshooting has been added. A new test script (test_claude_code_integration.py
) is included to verify the setup and basic tool execution.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command>
or @gemini-code-assist <command>
. Below is a summary of the supported commands.
Feature | Command | Description |
---|---|---|
Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/
folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configureGemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
Warning Rate limit exceeded@MervinPraison has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 5 minutes and 59 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughThe changes introduce Claude Code integration into the PraisonAI UI, allowing AI agents to autonomously invoke the Claude Code CLI for file modifications and coding tasks. This includes adding a CLI flag, UI toggle, agent-based routing, git automation, error handling, and comprehensive documentation and tests for the new functionality. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant PraisonAI UI
participant PraisonAI Agent
participant Claude Code Tool
participant Git
participant Pull Request Service
User->>PraisonAI UI: Sends message (e.g., "Modify file X")
PraisonAI UI->>PraisonAI Agent: Forwards message
PraisonAI Agent->>Claude Code Tool: Invokes tool if modification needed
Claude Code Tool->>Git: (Optional) Create branch, commit, push
Claude Code Tool->>Claude Code Tool: Run CLI with --dangerously-skip-permissions, --continue
Claude Code Tool->>Pull Request Service: Create PR and get URL
Claude Code Tool-->>PraisonAI Agent: Return output and PR URL
PraisonAI Agent-->>PraisonAI UI: Stream output to frontend
PraisonAI UI-->>User: Displays streamed response, PR URL
Assessment against linked issues
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request refactors the Claude Code integration to utilize praisonaiagents
, transforming Claude Code into a custom tool that agents can intelligently select. Key additions include a --claudecode
CLI flag, a UI toggle for this feature, and enhanced git operations like automatic branch creation. The changes are comprehensive and introduce significant new functionality. My review focuses on the security implications of executing external commands, the robustness of the new git features, context management for Claude Code, and test coverage for the new capabilities. Overall, the refactoring is well-structured, but critical attention to security is paramount.
git_available = False | ||
|
||
# Build Claude Code command | ||
claude_cmd = ["claude", "--dangerously-skip-permissions", "-p", query] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The claude_code_tool
executes the claude
CLI with --dangerously-skip-permissions
and passes the user-provided query
directly as an argument. This is a significant security concern. If the claude
CLI has any vulnerabilities related to argument parsing, or if a crafted query
could be misinterpreted by claude
to perform unintended actions, this could lead to arbitrary code execution or unauthorized file modifications. The --dangerously-skip-permissions
flag bypasses built-in safeguards, amplifying the risk.
Consider the following:
- Thoroughly validate and sanitize the
query
before passing it to theclaude
command. - If
claude
supports it, pass thequery
via standard input instead of as a command-line argument to reduce the risk of argument injection. - Explore if there are less permissive ways to achieve the desired functionality with the
claude
CLI. - At a minimum, log a prominent security warning when this tool is invoked, highlighting the risk.
# SECURITY WARNING: The 'query' variable is passed directly to an external command
# with '--dangerously-skip-permissions'. This is a significant security risk.
# Ensure 'query' is from a trusted source or thoroughly sanitized if it can be influenced by untrusted user input.
logger.warning(f"Executing claude_code_tool with --dangerously-skip-permissions. Query (first 100 chars): {query[:100]}...")
claude_cmd = ["claude", "--dangerously-skip-permissions", "-p", query]
) | ||
|
||
# Set context for future requests | ||
cl.user_session.set("claude_code_context", True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The claude_code_context
session variable is set to True
here to enable the --continue
flag for subsequent claude
CLI calls. However, it appears this variable is never reset to False
. This means that after the first use of claude_code_tool
in a session, all subsequent calls will use --continue
, regardless of whether the user intends to continue the previous interaction or start a new one. This could lead to unexpected behavior and merged contexts.
Consider implementing a mechanism to reset claude_code_context
to False
, for example:
- After a certain period of inactivity.
- When the user explicitly indicates they are starting a new task.
- Based on analysis of the new query's relationship to the previous one.
|
||
### 🔧 Claude Code as a Custom Tool | ||
- Claude Code is implemented as a tool function for PraisonAI Agents | ||
- Executes `claude --dangerously-skip-permissions -p "query"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation mentions the use of claude --dangerously-skip-permissions
. Given the security implications of this flag, especially when combined with user-provided queries, it would be beneficial to emphasize this risk more prominently. Consider adding a dedicated warning note or expanding on the potential security considerations to ensure users are fully aware.
subprocess.run( | ||
["git", "push", "-u", "origin", branch_name], | ||
cwd=repo_path, | ||
check=True | ||
) | ||
|
||
# Generate PR URL (assuming GitHub) | ||
remote_url = subprocess.run( | ||
["git", "config", "--get", "remote.origin.url"], | ||
cwd=repo_path, | ||
capture_output=True, | ||
text=True | ||
) | ||
|
||
if remote_url.returncode == 0: | ||
repo_url = remote_url.stdout.strip() | ||
if repo_url.endswith(".git"): | ||
repo_url = repo_url[:-4] | ||
if "github.com" in repo_url: | ||
pr_url = f"{repo_url}/compare/main...{branch_name}?quick_pull=1" | ||
output += f"\n\n📋 **Pull Request Created:**\n{pr_url}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The git push operation (line 142) assumes origin
as the remote name. Similarly, the PR URL generation (line 161) assumes main
as the default base branch for comparison. These assumptions might not hold true for all repository configurations.
Consider making the remote name and base branch configurable (e.g., via environment variables or settings) or attempting to detect them dynamically from the local git configuration if possible.
output += f"\n\n🌲 **Branch created:** {branch_name} (push manually if needed)" | ||
|
||
except subprocess.CalledProcessError as e: | ||
output += f"\n\nGit operations failed: {e}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When git operations fail, the error message includes the exception e
. To aid in debugging, it would be helpful to also include the stdout
and stderr
from the failed subprocess.CalledProcessError
object, as these often contain specific error messages from git itself.
output += f"\n\nGit operations failed: {e}\nStdout: {e.stdout}\nStderr: {e.stderr}"
test_claude_code_integration.py
Outdated
async def test_claude_code_tool_execution(): | ||
"""Test basic Claude Code tool execution (simple query)""" | ||
try: | ||
from praisonai.ui.code import claude_code_tool | ||
|
||
# Test with a simple query that shouldn't modify files | ||
test_query = "What is the current directory?" | ||
result = await claude_code_tool(test_query) | ||
|
||
print(f"✅ Claude Code tool executed successfully") | ||
print(f"Query: {test_query}") | ||
print(f"Result (first 100 chars): {str(result)[:100]}...") | ||
return True | ||
except Exception as e: | ||
print(f"❌ Claude Code tool execution failed: {e}") | ||
return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test_claude_code_tool_execution
function provides a basic check that the claude_code_tool
can be called. However, it uses a query ("What is the current directory?"
) that is unlikely to trigger file modifications or git operations, which are key features of the tool.
To improve test coverage, consider adding more specific test cases that:
- Verify the git branch creation logic (e.g., by mocking
subprocess.run
or using a temporary git repository). - Test the commit message formatting.
- Check PR URL generation for different repository URLs (if feasible).
- Test scenarios where git is not available or fails, ensuring graceful error handling.
- (Optionally, with careful sandboxing) Test a scenario where a simple, safe file modification occurs and verify the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
test_claude_code_integration.py (1)
66-66
: Remove unnecessary f-string prefixes.These strings don't contain any placeholders, so the
f
prefix is not needed.- print(f"✅ Claude Code tool executed successfully") + print("✅ Claude Code tool executed successfully")- print(f"\n🔍 Claude Code Tool Execution:") + print("\n🔍 Claude Code Tool Execution:")Also applies to: 111-111
🧰 Tools
🪛 Ruff (0.11.9)
66-66: f-string without any placeholders
Remove extraneous
f
prefix(F541)
CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md (1)
38-50
: Add language specifiers to fenced code blocks for better syntax highlighting.Several code blocks are missing language specifiers which prevents proper syntax highlighting in markdown renderers.
For the instruction block at line 38:
-``` +```text You are a helpful AI assistant. Use the available tools when needed to provide comprehensive responses.For the output example at line 140:
-``` +```text 📋 **Pull Request Created:**For the file structure at line 161:
-``` +```text src/praisonai/praisonai/Also applies to: 140-143, 161-166
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
38-38: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
src/praisonai/praisonai/ui/code.py (2)
454-457
: Simplify conditional assignment with ternary operator.- if hasattr(result, 'raw'): - response_text = result.raw - else: - response_text = str(result) + response_text = result.raw if hasattr(result, 'raw') else str(result)🧰 Tools
🪛 Ruff (0.11.9)
454-457: Use ternary operator
response_text = result.raw if hasattr(result, 'raw') else str(result)
instead ofif
-else
-blockReplace
if
-else
-block withresponse_text = result.raw if hasattr(result, 'raw') else str(result)
(SIM108)
449-451
: Consider implementing proper streaming when PraisonAI agents support it.The current implementation simulates streaming by outputting character-by-character. This works but true streaming would provide better performance.
Would you like me to create an issue to track the implementation of proper streaming support once PraisonAI agents add this capability?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md
(1 hunks)src/praisonai/praisonai/cli.py
(2 hunks)src/praisonai/praisonai/ui/code.py
(10 hunks)test_claude_code_integration.py
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/praisonai/praisonai/ui/code.py (3)
src/praisonai/praisonai/ui/db.py (1)
DatabaseManager
(59-290)src/praisonai/praisonai/ui/realtime.py (3)
load_setting
(148-155)save_setting
(134-146)start
(230-251)src/praisonai/praisonai/ui/chat.py (4)
load_setting
(56-58)save_setting
(52-54)tavily_web_search
(65-98)start
(147-162)
🪛 Ruff (0.11.9)
test_claude_code_integration.py
11-11: unittest
imported but unused
Remove unused import: unittest
(F401)
19-19: praisonai.ui.code.claude_code_tool
imported but unused; consider using importlib.util.find_spec
to test for availability
(F401)
29-29: praisonaiagents.Agent
imported but unused; consider using importlib.util.find_spec
to test for availability
(F401)
66-66: f-string without any placeholders
Remove extraneous f
prefix
(F541)
111-111: f-string without any placeholders
Remove extraneous f
prefix
(F541)
src/praisonai/praisonai/ui/code.py
454-457: Use ternary operator response_text = result.raw if hasattr(result, 'raw') else str(result)
instead of if
-else
-block
Replace if
-else
-block with response_text = result.raw if hasattr(result, 'raw') else str(result)
(SIM108)
🪛 Pylint (3.3.7)
test_claude_code_integration.py
[refactor] 41-46: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
src/praisonai/praisonai/ui/code.py
[refactor] 65-65: Too many branches (13/12)
(R0912)
[refactor] 75-177: Too many nested blocks (7/5)
(R1702)
[refactor] 409-409: Too many arguments (6/5)
(R0913)
[refactor] 409-409: Too many positional arguments (6/5)
(R0917)
[refactor] 409-409: Too many local variables (16/15)
(R0914)
[refactor] 482-482: Too many local variables (23/15)
(R0914)
[refactor] 482-482: Too many branches (20/12)
(R0912)
[refactor] 482-482: Too many statements (71/50)
(R0915)
🪛 LanguageTool
CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md
[uncategorized] ~11-~11: The noun “Decision-Making” (= the process of deciding something) is spelled with a hyphen.
Context: .... ## Key Features ### 🤖 Agent-Driven Decision Making - AI agent intelligently decides when t...
(DECISION_MAKING)
[uncategorized] ~121-~121: You might be missing the article “the” here.
Context: ...rmational Request User: "How does fibonacci algorithm work?" Agent Decision: R...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[style] ~209-~209: This phrase is redundant (‘I’ stands for ‘interfaces’). Use simply “CLIs”.
Context: ...ent intelligence 2. Maintains same UI/CLI interfaces for easy migration 3. **Preserves all...
(ACRONYM_TAUTOLOGY)
[uncategorized] ~267-~267: You might be missing the article “the” here.
Context: ... praisonai code --claudecode Check environment:
python import os print("Claude Code...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
🪛 markdownlint-cli2 (0.17.2)
CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md
38-38: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
140-140: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
161-161: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: quick-test
🔇 Additional comments (3)
src/praisonai/praisonai/cli.py (1)
532-532
: LGTM! Clean CLI flag implementation.The
--claudecode
flag is properly integrated into the argument parser and follows the established pattern for feature flags in the codebase.Also applies to: 554-556
src/praisonai/praisonai/ui/code.py (2)
65-177
: Well-implemented Claude Code tool with comprehensive git integration.The function properly handles Claude CLI execution, conversation continuity, and git operations including automatic branch creation and PR URL generation. The complexity is justified by the functionality provided, and error handling is thorough.
🧰 Tools
🪛 Pylint (3.3.7)
[refactor] 65-65: Too many branches (13/12)
(R0912)
[refactor] 75-177: Too many nested blocks (7/5)
(R1702)
239-256
: Excellent settings management with proper precedence.The implementation correctly prioritizes the CLI flag (
PRAISONAI_CLAUDECODE_ENABLED
) over the database setting, and the UI toggle is well-integrated into the chat settings across all handlers.Also applies to: 274-280, 638-654
test_claude_code_integration.py
Outdated
import os | ||
import sys | ||
import asyncio | ||
import unittest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused import.
The unittest
module is imported but never used in this test script.
-import unittest
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import unittest |
🧰 Tools
🪛 Ruff (0.11.9)
11-11: unittest
imported but unused
Remove unused import: unittest
(F401)
🤖 Prompt for AI Agents
In test_claude_code_integration.py at line 11, the unittest module is imported
but not used anywhere in the file. Remove the import statement for unittest to
clean up the code and avoid unnecessary imports.
…st_claude_code_integration.py
CI Feedback 🧐(Feedback updated until commit 8d81318)A test triggered by this PR failed. Here is an AI-generated analysis of the failure:
|
User description
This PR refactors the Claude Code integration to use
praisonaiagents
instead oflitellm
, making Claude Code a custom tool that agents can intelligently decide to use.Key Features:
Fixes #634
Generated with Claude Code
PR Type
Enhancement
Description
• Refactor Claude Code integration to use PraisonAI Agents framework
• Add --claudecode CLI flag and UI toggle for enabling file modifications
• Implement intelligent agent-driven tool selection with backward compatibility
• Add comprehensive git operations with auto-branch creation and PR URLs
Changes walkthrough 📝
cli.py
Add --claudecode CLI flag support
src/praisonai/praisonai/cli.py
• Add --claudecode CLI argument for enabling Claude Code integration
•
Set PRAISONAI_CLAUDECODE_ENABLED environment variable when flag is
used
code.py
Refactor to use PraisonAI Agents with Claude Code tool
src/praisonai/praisonai/ui/code.py
• Replace litellm direct usage with praisonaiagents framework
•
Implement
claude_code_tool
function for file modifications and codingtasks
• Add UI toggle switch for enabling/disabling Claude Code
•
Create agent-driven decision making with intelligent tool selection
•
Add git operations with automatic branch creation and PR URL
generation
• Maintain backward compatibility with litellm fallback
•
Add comprehensive error handling and streaming support
test_claude_code_integration.py
Add integration test script
test_claude_code_integration.py
• Create comprehensive test script for Claude Code integration
• Test
imports, CLI availability, and tool execution
• Verify environment
variables and agent functionality
CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md
Add comprehensive integration documentation
CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md
• Provide detailed documentation for Claude Code integration
• Include
architecture overview, usage examples, and troubleshooting guide
•
Document agent instructions, tool functions, and git integration
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests