Skip to content
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

Add github issues and PR tool #257

Merged
merged 4 commits into from
Feb 12, 2025
Merged

Add github issues and PR tool #257

merged 4 commits into from
Feb 12, 2025

Conversation

dhirenmathur
Copy link
Contributor

@dhirenmathur dhirenmathur commented Feb 12, 2025

Summary by CodeRabbit

  • New Features

    • Integrated GitHub functionality across several agents, enabling enhanced retrieval and analysis of GitHub content (issues, pull requests, etc.) when properly configured.
    • Added capabilities to fetch code from multiple nodes to improve code impact analysis.
  • Refactor

    • Revised agent roles and tool activation logic for more effective and flexible execution of code analysis, generation, debugging, testing, and design evaluation.

Copy link
Contributor

coderabbitai bot commented Feb 12, 2025

Warning

Rate limit exceeded

@dhirenmathur has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 19 minutes and 55 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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.

📥 Commits

Reviewing files that changed from the base of the PR and between edaf42f and a3799ce.

📒 Files selected for processing (1)
  • app/modules/intelligence/tools/web_tools/github_tool.py (1 hunks)

Walkthrough

The changes integrate a new GitHub tool across multiple agent classes and services. Each agent now conditionally initializes a GitHub tool instance if the GITHUB_APP_ID environment variable is present. In addition, the BlastRadiusAgent has been enhanced with a new code retrieval tool for multiple node IDs and an updated role description. The ToolService has been modified to register the GitHub tool, and a new module is introduced to handle GitHub interactions through synchronous and asynchronous methods, including input validation and error handling.

Changes

File(s) Change Summary
app/.../agents/agents/blast_radius_agent.py Updated role and goal to "Blast Radius Analyzer"; added initialization for get_code_from_multiple_node_ids tool and conditionally initialized github_tool based on GITHUB_APP_ID.
app/.../agents/agents/code_gen_agent.py, app/.../agents/agents/debug_rag_agent.py, app/.../agents/agents/integration_test_agent.py, app/.../agents/agents/low_level_design_agent.py, app/.../agents/agents/rag_agent.py, app/.../agents/agents/unit_test_agent.py Added conditional initialization and inclusion of github_tool in the create_agents methods; adjusted tools list formation and, in the case of UnitTestAgent, renamed a parameter from max_iter to max_iterations.
app/.../tools/tool_service.py Integrated github_tool in the ToolService by adding a new import, initializing it in the constructor, and including it in the tools dictionary conditionally.
app/.../tools/web_tools/github_tool.py New module implementing GithubTool with both synchronous (run) and asynchronous (arun) methods, input validation via Pydantic, and GitHub content fetching logic.
app/.../tools/kg_based_tools/get_code_from_multiple_node_ids_tool.py Added method to facilitate code retrieval from multiple node IDs.

Sequence Diagram(s)

sequenceDiagram
    participant Agent
    participant Env
    participant GitHubTool
    Agent->>Env: Check for GITHUB_APP_ID
    alt GITHUB_APP_ID exists
        Agent->>GitHubTool: Initialize github_tool
        Agent-->>Agent: Add github_tool to tools list
    else
        Agent-->>Agent: Skip github_tool initialization
    end
    Agent->>GitHubTool: Invoke tool functionality (if available)
Loading
sequenceDiagram
    participant BlastRadiusAgent
    participant CodeFetcher
    participant GitHubTool
    BlastRadiusAgent->>CodeFetcher: Retrieve code from multiple node IDs
    Note right of BlastRadiusAgent: (Uses GetCodeFromMultipleNodeIdsTool)
    alt GITHUB_APP_ID exists
        BlastRadiusAgent->>GitHubTool: Utilize GitHub-related analysis
    end
Loading

Possibly related PRs

  • Firecrawl tool for accessing web pages  #251: The changes in the main PR are related to the modifications in the retrieved PR as both involve the conditional initialization of tools based on the presence of environment variables, specifically integrating the github_tool and webpage_extractor_tool respectively in their respective agent classes.

Poem

I’m a nimble rabbit, leaping through code,
Hopping over logic on a winding road.
GitHub tools now join my joyful sprint,
Fetching data with a digital glint.
With node IDs and new features in view,
I celebrate these changes—hip, hip, woo!
🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (5)
app/modules/intelligence/agents/agents/unit_test_agent.py (1)

48-50: Consider refactoring for better readability.

The list concatenation split across multiple lines could be simplified for better readability.

Consider this more concise approach:

-                self.get_code_from_probable_node_name,
-            ] + ([self.webpage_extractor_tool] if hasattr(self, 'webpage_extractor_tool') else [])
-              + ([self.github_tool] if hasattr(self, 'github_tool') else []),
+                self.get_code_from_probable_node_name
+            ] + [
+                tool for tool in [self.webpage_extractor_tool, self.github_tool]
+                if hasattr(self, tool.__class__.__name__.lower())
+            ],
app/modules/intelligence/tools/web_tools/github_tool.py (1)

72-95: Handle non-200 responses more gracefully.

While an exception is raised when a non-200 status code occurs, consider providing clearer user feedback about the specific error encountered (e.g., a 404 for a non-existent repository or a 403 for insufficient permissions). Logging is good, but spearheading user guidance in the return message might improve the developer experience.

app/modules/intelligence/agents/agents/blast_radius_agent.py (1)

20-20: Remove unused import GetCodeFromMultipleNodeIdsTool.

You import the class GetCodeFromMultipleNodeIdsTool, but it is never directly referenced (you use only the function factory get_code_from_multiple_node_ids_tool). Removing the unused class import will eliminate the static analysis warning and keep the code tidy.

- from app.modules.intelligence.tools.kg_based_tools.get_code_from_multiple_node_ids_tool import (
-     GetCodeFromMultipleNodeIdsTool,
    get_code_from_multiple_node_ids_tool,
)
+ from app.modules.intelligence.tools.kg_based_tools.get_code_from_multiple_node_ids_tool import (
+     get_code_from_multiple_node_ids_tool,
+ )
🧰 Tools
🪛 Ruff (0.8.2)

20-20: app.modules.intelligence.tools.kg_based_tools.get_code_from_multiple_node_ids_tool.GetCodeFromMultipleNodeIdsTool imported but unused

Remove unused import: app.modules.intelligence.tools.kg_based_tools.get_code_from_multiple_node_ids_tool.GetCodeFromMultipleNodeIdsTool

(F401)

app/modules/intelligence/agents/agents/integration_test_agent.py (2)

47-51: Consider using a more maintainable tools list construction pattern.

The current list concatenation with multiple ternary operations could become harder to maintain as more tools are added.

Consider refactoring to a more readable pattern:

-        tools = [
-            self.get_code_from_probable_node_name,
-            self.get_code_from_multiple_node_ids,
-        ] + ([self.webpage_extractor_tool] if hasattr(self, 'webpage_extractor_tool') else []) \
-          + ([self.github_tool] if hasattr(self, 'github_tool') else [])
+        tools = [
+            self.get_code_from_probable_node_name,
+            self.get_code_from_multiple_node_ids,
+        ]
+        
+        # Add optional tools if available
+        optional_tools = {
+            'webpage_extractor_tool': self.webpage_extractor_tool,
+            'github_tool': self.github_tool
+        }
+        
+        tools.extend(tool for name, tool in optional_tools.items() 
+                    if hasattr(self, name))

41-42: Consider adding error handling for GitHub tool initialization.

The GitHub tool initialization should handle potential configuration errors gracefully.

Consider adding error handling:

-        if os.getenv("GITHUB_APP_ID"):
-            self.github_tool = github_tool(sql_db, user_id)
+        try:
+            if os.getenv("GITHUB_APP_ID"):
+                self.github_tool = github_tool(sql_db, user_id)
+        except Exception as e:
+            # Log the error but don't fail agent initialization
+            print(f"Failed to initialize GitHub tool: {e}")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fa48009 and d6b7680.

📒 Files selected for processing (9)
  • app/modules/intelligence/agents/agents/blast_radius_agent.py (2 hunks)
  • app/modules/intelligence/agents/agents/code_gen_agent.py (3 hunks)
  • app/modules/intelligence/agents/agents/debug_rag_agent.py (3 hunks)
  • app/modules/intelligence/agents/agents/integration_test_agent.py (2 hunks)
  • app/modules/intelligence/agents/agents/low_level_design_agent.py (3 hunks)
  • app/modules/intelligence/agents/agents/rag_agent.py (3 hunks)
  • app/modules/intelligence/agents/agents/unit_test_agent.py (2 hunks)
  • app/modules/intelligence/tools/tool_service.py (2 hunks)
  • app/modules/intelligence/tools/web_tools/github_tool.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
app/modules/intelligence/tools/web_tools/github_tool.py

5-5: typing.List imported but unused

Remove unused import: typing.List

(F401)

app/modules/intelligence/agents/agents/blast_radius_agent.py

20-20: app.modules.intelligence.tools.kg_based_tools.get_code_from_multiple_node_ids_tool.GetCodeFromMultipleNodeIdsTool imported but unused

Remove unused import: app.modules.intelligence.tools.kg_based_tools.get_code_from_multiple_node_ids_tool.GetCodeFromMultipleNodeIdsTool

(F401)

🪛 GitHub Actions: Pre-commit
app/modules/intelligence/tools/web_tools/github_tool.py

[warning] 120-120: Code does not adhere to PEP 8 standards. Please format the code using Black.

🔇 Additional comments (15)
app/modules/intelligence/agents/agents/unit_test_agent.py (3)

21-21: LGTM!

The import statement follows the established pattern and is correctly placed with other tool imports.


38-39: LGTM!

The initialization follows the established pattern and correctly passes required parameters.


54-54: LGTM!

The parameter rename improves consistency with the class attribute name.

app/modules/intelligence/agents/agents/low_level_design_agent.py (3)

36-36: LGTM!

The import statement follows the established pattern and is correctly placed with other tool imports.


102-103: LGTM!

The conditional tool inclusion is well-implemented using hasattr and follows the established pattern.


86-87: Verify the environment variable configuration.

The initialization looks good and follows the established pattern. However, let's verify that the GITHUB_APP_ID environment variable is properly documented and configured.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Description: Check for documentation of GITHUB_APP_ID environment variable

# Search for GITHUB_APP_ID in documentation files
echo "Searching for GITHUB_APP_ID documentation..."
rg -i "GITHUB_APP_ID" --type md

Length of output: 276


Environment Variable Configuration Verified

The documentation in GETTING_STARTED.md confirms that the GITHUB_APP_ID environment variable is properly mentioned and used, and the conditional initialization in the code follows the established patterns.

app/modules/intelligence/tools/web_tools/github_tool.py (1)

50-52: Confirm thread usage.

asyncio.to_thread is being used to wrap the synchronous run method. This approach is acceptable, but ensure there's no shared-state mutation that may require additional synchronization. Also, confirm that you actually need asynchronous behavior here, as wrapping a potentially long-running I/O-bound method with an async interface can introduce complexity.

app/modules/intelligence/tools/tool_service.py (1)

48-49: Conditional initialization logic looks good.

Conditionally creating github_tool when credentials are available is a clean approach to optional tooling. The code appropriately checks for None before adding it to tools. This ensures minimal overhead and avoids runtime errors in environments that lack the GitHub app credentials.

Also applies to: 74-78

app/modules/intelligence/agents/agents/blast_radius_agent.py (1)

41-45: Well-structured tool injection.

Using environment variable checks for FIRECRAWL_API_KEY and GITHUB_APP_ID neatly gates optional features. The logic cleanly ensures that tools are added only if they are valid. The updated agent role and goal accurately reflect the extended functionality, making the code more descriptive and cohesive.

Also applies to: 47-58

app/modules/intelligence/agents/agents/rag_agent.py (2)

110-111: Same tools list construction pattern needs improvement.

The same tools list construction pattern is used here. Please refer to the previous comment about making it more maintainable.


80-81: Same GitHub tool initialization needs error handling.

The same GitHub tool initialization pattern is used here. Please refer to the previous comment about adding error handling.

app/modules/intelligence/agents/agents/debug_rag_agent.py (2)

110-111: Same tools list construction pattern needs improvement.

The same tools list construction pattern is used here. Please refer to the previous comment about making it more maintainable.


79-80: Same GitHub tool initialization needs error handling.

The same GitHub tool initialization pattern is used here. Please refer to the previous comment about adding error handling.

app/modules/intelligence/agents/agents/code_gen_agent.py (2)

90-91: Same tools list construction pattern needs improvement.

The same tools list construction pattern is used here. Please refer to the previous comment about making it more maintainable.


58-59: Same GitHub tool initialization needs error handling.

The same GitHub tool initialization pattern is used here. Please refer to the previous comment about adding error handling.

allow_delegation=False,
verbose=True,
llm=self.llm,
max_iter=self.max_iter,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add max_iter parameter to design_planner agent for consistency.

The max_iter parameter is added to codebase_analyst but not to design_planner. For consistency, consider adding it to both agents.

Apply this diff to add max_iter to design_planner:

             verbose=True,
             llm=self.llm,
+            max_iter=self.max_iter,
         )

Also applies to: 126-127

Comment on lines 96 to 160
def _fetch_github_content(self, repo_name: str, issue_number: Optional[int], is_pull_request: bool) -> Optional[Dict[str, Any]]:
try:
github = self._get_github_client(repo_name)
repo = github.get_repo(repo_name)

if issue_number is None:
# Fetch all issues/PRs
if is_pull_request:
items = list(repo.get_pulls(state='all')[:10]) # Limit to 10 most recent
else:
items = list(repo.get_issues(state='all')[:10]) # Limit to 10 most recent

return {
"success": True,
"content": [{
"number": item.number,
"title": item.title,
"state": item.state,
"created_at": item.created_at.isoformat(),
"updated_at": item.updated_at.isoformat(),
"body": item.body,
"url": item.html_url,
} for item in items],
"metadata": {
"repo": repo_name,
"type": "pull_requests" if is_pull_request else "issues",
"count": len(items)
}
}
else:
# Fetch specific issue/PR
if is_pull_request:
item = repo.get_pull(issue_number)
diff = item.get_files()
changes = [{
"filename": file.filename,
"status": file.status,
"additions": file.additions,
"deletions": file.deletions,
"changes": file.changes,
"patch": file.patch if file.patch else None
} for file in diff]
else:
item = repo.get_issue(issue_number)
changes = None

return {
"success": True,
"content": {
"number": item.number,
"title": item.title,
"state": item.state,
"created_at": item.created_at.isoformat(),
"updated_at": item.updated_at.isoformat(),
"body": item.body,
"url": item.html_url,
"changes": changes
},
"metadata": {
"repo": repo_name,
"type": "pull_request" if is_pull_request else "issue",
"number": issue_number
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Validate issue/PR existence & ensure PEP 8 compliance.

  1. If the specified issue or pull request does not exist, repo.get_pull() or repo.get_issue() could raise exceptions. Consider catching these exceptions to provide more descriptive error messages.
  2. A pipeline warning notes that code around line 120 may not adhere to PEP 8 formatting. Running a code formatter (e.g., Black) on this file will help ensure stylistic consistency.
🧰 Tools
🪛 GitHub Actions: Pre-commit

[warning] 120-120: Code does not adhere to PEP 8 standards. Please format the code using Black.

import asyncio
import logging
import requests
from typing import Dict, Any, Optional, List
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove unused typing.List.

Static analysis indicates that List is not used anywhere within this file. Removing it helps maintain code cleanliness and conform to linting standards.

- from typing import Dict, Any, Optional, List
+ from typing import Dict, Any, Optional
📝 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.

Suggested change
from typing import Dict, Any, Optional, List
from typing import Dict, Any, Optional
🧰 Tools
🪛 Ruff (0.8.2)

5-5: typing.List imported but unused

Remove unused import: typing.List

(F401)

@dhirenmathur dhirenmathur merged commit 241ea27 into main Feb 12, 2025
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant