fix for commenting on chat, and updating docs.
All checks were successful
Enterprise AI Code Review / ai-review (pull_request) Successful in 20s
All checks were successful
Enterprise AI Code Review / ai-review (pull_request) Successful in 20s
This commit is contained in:
@@ -11,9 +11,9 @@ import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
import requests
|
||||
from clients.llm_client import ToolCall
|
||||
|
||||
from agents.base_agent import AgentContext, AgentResult, BaseAgent
|
||||
from clients.llm_client import ToolCall
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -114,8 +114,10 @@ Repository context: {owner}/{repo}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._searxng_url = self.config.get("agents", {}).get("chat", {}).get(
|
||||
"searxng_url", os.environ.get("SEARXNG_URL", "")
|
||||
self._searxng_url = (
|
||||
self.config.get("agents", {})
|
||||
.get("chat", {})
|
||||
.get("searxng_url", os.environ.get("SEARXNG_URL", ""))
|
||||
)
|
||||
|
||||
def can_handle(self, event_type: str, event_data: dict) -> bool:
|
||||
@@ -133,7 +135,13 @@ Repository context: {owner}/{repo}
|
||||
# Check if this is a chat request (any @ai-bot mention that isn't a specific command)
|
||||
if mention_prefix in comment_body:
|
||||
# Check it's not another specific command
|
||||
specific_commands = ["summarize", "explain", "suggest", "security", "codebase"]
|
||||
specific_commands = [
|
||||
"summarize",
|
||||
"explain",
|
||||
"suggest",
|
||||
"security",
|
||||
"codebase",
|
||||
]
|
||||
body_lower = comment_body.lower()
|
||||
for cmd in specific_commands:
|
||||
if f"{mention_prefix} {cmd}" in body_lower:
|
||||
@@ -150,18 +158,24 @@ Repository context: {owner}/{repo}
|
||||
"""Execute the chat agent."""
|
||||
self.logger.info(f"Starting chat for {context.owner}/{context.repo}")
|
||||
|
||||
# Extract user message
|
||||
# Extract user message and author
|
||||
if context.event_type == "issue_comment":
|
||||
user_message = context.event_data.get("comment", {}).get("body", "")
|
||||
issue_index = context.event_data.get("issue", {}).get("number")
|
||||
# Remove the @ai-bot prefix
|
||||
comment_author = (
|
||||
context.event_data.get("comment", {})
|
||||
.get("user", {})
|
||||
.get("login", "user")
|
||||
)
|
||||
# Remove the @codebot prefix
|
||||
mention_prefix = self.config.get("interaction", {}).get(
|
||||
"mention_prefix", "@ai-bot"
|
||||
"mention_prefix", "@codebot"
|
||||
)
|
||||
user_message = user_message.replace(mention_prefix, "").strip()
|
||||
else:
|
||||
user_message = context.event_data.get("message", "")
|
||||
issue_index = context.event_data.get("issue_number")
|
||||
comment_author = None
|
||||
|
||||
if not user_message:
|
||||
return AgentResult(
|
||||
@@ -191,13 +205,10 @@ Repository context: {owner}/{repo}
|
||||
|
||||
# Post response if this is an issue comment
|
||||
if issue_index:
|
||||
comment_body = self._format_response(response_content)
|
||||
self.upsert_comment(
|
||||
context.owner,
|
||||
context.repo,
|
||||
issue_index,
|
||||
comment_body,
|
||||
marker=self.CHAT_AI_MARKER,
|
||||
comment_body = self._format_response(response_content, comment_author)
|
||||
# Create a new comment instead of upserting to make conversation flow better
|
||||
self.gitea.create_issue_comment(
|
||||
context.owner, context.repo, issue_index, comment_body
|
||||
)
|
||||
actions_taken.append("Posted chat response")
|
||||
|
||||
@@ -230,21 +241,23 @@ Repository context: {owner}/{repo}
|
||||
return response.content, tools_used
|
||||
|
||||
# Add assistant message with tool calls
|
||||
messages.append({
|
||||
"role": "assistant",
|
||||
"content": response.content or "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": tc.id,
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": tc.name,
|
||||
"arguments": str(tc.arguments),
|
||||
},
|
||||
}
|
||||
for tc in response.tool_calls
|
||||
],
|
||||
})
|
||||
messages.append(
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": response.content or "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": tc.id,
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": tc.name,
|
||||
"arguments": str(tc.arguments),
|
||||
},
|
||||
}
|
||||
for tc in response.tool_calls
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
# Execute each tool call
|
||||
for tool_call in response.tool_calls:
|
||||
@@ -252,11 +265,13 @@ Repository context: {owner}/{repo}
|
||||
tools_used.append(tool_call.name)
|
||||
|
||||
# Add tool result to messages
|
||||
messages.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call.id,
|
||||
"content": tool_result,
|
||||
})
|
||||
messages.append(
|
||||
{
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call.id,
|
||||
"content": tool_result,
|
||||
}
|
||||
)
|
||||
|
||||
# If we hit max iterations, make one final call without tools
|
||||
self._rate_limit()
|
||||
@@ -357,15 +372,38 @@ Repository context: {owner}/{repo}
|
||||
|
||||
# Code extensions to search
|
||||
code_extensions = {
|
||||
".py", ".js", ".ts", ".go", ".rs", ".java", ".rb",
|
||||
".php", ".c", ".cpp", ".h", ".cs", ".swift", ".kt",
|
||||
".md", ".yml", ".yaml", ".json", ".toml",
|
||||
".py",
|
||||
".js",
|
||||
".ts",
|
||||
".go",
|
||||
".rs",
|
||||
".java",
|
||||
".rb",
|
||||
".php",
|
||||
".c",
|
||||
".cpp",
|
||||
".h",
|
||||
".cs",
|
||||
".swift",
|
||||
".kt",
|
||||
".md",
|
||||
".yml",
|
||||
".yaml",
|
||||
".json",
|
||||
".toml",
|
||||
}
|
||||
|
||||
# Patterns to ignore
|
||||
ignore_patterns = [
|
||||
"node_modules/", "vendor/", ".git/", "__pycache__/",
|
||||
".venv/", "dist/", "build/", ".min.js", ".min.css",
|
||||
"node_modules/",
|
||||
"vendor/",
|
||||
".git/",
|
||||
"__pycache__/",
|
||||
".venv/",
|
||||
"dist/",
|
||||
"build/",
|
||||
".min.js",
|
||||
".min.css",
|
||||
]
|
||||
|
||||
def traverse(path: str = ""):
|
||||
@@ -397,6 +435,7 @@ Repository context: {owner}/{repo}
|
||||
def _match_pattern(self, filepath: str, pattern: str) -> bool:
|
||||
"""Check if filepath matches a simple glob pattern."""
|
||||
import fnmatch
|
||||
|
||||
return fnmatch.fnmatch(filepath, pattern)
|
||||
|
||||
def _tool_read_file(self, context: AgentContext, filepath: str) -> str:
|
||||
@@ -458,13 +497,22 @@ Repository context: {owner}/{repo}
|
||||
except requests.exceptions.RequestException as e:
|
||||
return f"Web search failed: {e}"
|
||||
|
||||
def _format_response(self, content: str) -> str:
|
||||
def _format_response(self, content: str, user: str | None = None) -> str:
|
||||
"""Format the chat response with disclaimer."""
|
||||
lines = [
|
||||
f"{self.AI_DISCLAIMER}",
|
||||
"",
|
||||
"---",
|
||||
"",
|
||||
content,
|
||||
]
|
||||
lines = []
|
||||
|
||||
# Add user mention if available
|
||||
if user:
|
||||
lines.append(f"@{user}")
|
||||
lines.append("")
|
||||
|
||||
lines.extend(
|
||||
[
|
||||
f"{self.AI_DISCLAIMER}",
|
||||
"",
|
||||
"---",
|
||||
"",
|
||||
content,
|
||||
]
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
@@ -153,14 +153,17 @@ class IssueAgent(BaseAgent):
|
||||
comment = context.event_data.get("comment", {})
|
||||
issue_index = issue.get("number")
|
||||
comment_body = comment.get("body", "")
|
||||
comment_author = comment.get("user", {}).get("login", "user")
|
||||
|
||||
# Parse command from mention
|
||||
command = self._parse_command(comment_body)
|
||||
|
||||
if command:
|
||||
response = self._handle_command(context, issue, command)
|
||||
# Add user mention at the top
|
||||
response_with_mention = f"@{comment_author}\n\n{response}"
|
||||
self.gitea.create_issue_comment(
|
||||
context.owner, context.repo, issue_index, response
|
||||
context.owner, context.repo, issue_index, response_with_mention
|
||||
)
|
||||
return AgentResult(
|
||||
success=True,
|
||||
|
||||
Reference in New Issue
Block a user