This commit is contained in:
Binary file not shown.
Binary file not shown.
+12
-53
@@ -6,7 +6,6 @@ from .context import resolve_context
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
# Import the crews
|
||||
from crews.code_review_crew.code_review_crew import CodeReviewCrew
|
||||
from crews.security_review_crew.security_review_crew import SecurityReviewCrew
|
||||
from crews.infra_review_crew.infra_review_crew import InfraReviewCrew
|
||||
@@ -16,51 +15,27 @@ from crews.summariser_crew.summariser_crew import SummariserCrew
|
||||
class CodeReviewFlow(Flow[PRReviewState]):
|
||||
|
||||
@start()
|
||||
def receive_pr(self, inputs):
|
||||
"""Initialize the PR review state with input data."""
|
||||
print(f"Received PR review request for PR #{inputs.get('pr_id')}")
|
||||
|
||||
# Initialize the state
|
||||
self.state.pr_id = inputs.get("pr_id", "")
|
||||
self.state.pr_title = inputs.get("pr_title", "")
|
||||
self.state.pr_description = inputs.get("pr_description", "")
|
||||
self.state.pr_url = inputs.get("pr_url", "")
|
||||
self.state.repo_name = inputs.get("repo_name", "")
|
||||
self.state.repo_url = inputs.get("repo_url", "")
|
||||
self.state.branch = inputs.get("branch", "")
|
||||
self.state.base_branch = inputs.get("base_branch", "")
|
||||
# Convert files from list of dicts to list of FileInfo objects if needed
|
||||
files_input = inputs.get("files", [])
|
||||
if files_input and isinstance(files_input[0], dict):
|
||||
# Convert dicts to FileInfo objects
|
||||
def receive_pr(self):
|
||||
print(f"Received PR review request for PR #{self.state.pr_id}")
|
||||
|
||||
if isinstance(self.state.files, list) and self.state.files and isinstance(self.state.files[0], dict):
|
||||
from .state import FileInfo
|
||||
self.state.files = [FileInfo(**file_dict) for file_dict in files_input]
|
||||
else:
|
||||
self.state.files = files_input
|
||||
|
||||
# Handle context_overrides
|
||||
context_overrides_input = inputs.get("context_overrides")
|
||||
if context_overrides_input and isinstance(context_overrides_input, dict):
|
||||
self.state.files = [FileInfo(**file_dict) for file_dict in self.state.files]
|
||||
|
||||
context_input = self.state.context_overrides
|
||||
if isinstance(context_input, dict):
|
||||
from .state import ContextOverrides
|
||||
self.state.context_overrides = ContextOverrides(**context_overrides_input)
|
||||
else:
|
||||
self.state.context_overrides = context_overrides_input
|
||||
|
||||
self.state.context_overrides = ContextOverrides(**context_input)
|
||||
|
||||
self.state.started_at = datetime.now()
|
||||
|
||||
# Resolve context
|
||||
self.state.resolved_context = resolve_context(self.state)
|
||||
|
||||
|
||||
return self.state
|
||||
|
||||
@listen(receive_pr)
|
||||
def run_code_review(self):
|
||||
"""Run the code review crew."""
|
||||
print("Starting code review...")
|
||||
|
||||
# Instantiate and run the code review crew
|
||||
code_crew = CodeReviewCrew()
|
||||
# The crew's kickoff method expects inputs matching the task template variables
|
||||
inputs = {
|
||||
"pr_title": self.state.pr_title,
|
||||
"pr_description": self.state.pr_description,
|
||||
@@ -70,15 +45,11 @@ class CodeReviewFlow(Flow[PRReviewState]):
|
||||
result = code_crew.crew().kickoff(inputs=inputs)
|
||||
self.state.code_review_results = str(result)
|
||||
print("Code review completed.")
|
||||
|
||||
return self.state
|
||||
|
||||
@listen(receive_pr)
|
||||
def run_security_review(self):
|
||||
"""Run the security review crew."""
|
||||
print("Starting security review...")
|
||||
|
||||
# Instantiate and run the security review crew
|
||||
security_crew = SecurityReviewCrew()
|
||||
inputs = {
|
||||
"pr_title": self.state.pr_title,
|
||||
@@ -89,15 +60,11 @@ class CodeReviewFlow(Flow[PRReviewState]):
|
||||
result = security_crew.crew().kickoff(inputs=inputs)
|
||||
self.state.security_review_results = str(result)
|
||||
print("Security review completed.")
|
||||
|
||||
return self.state
|
||||
|
||||
@listen(receive_pr)
|
||||
def run_infra_review(self):
|
||||
"""Run the infrastructure review crew."""
|
||||
print("Starting infrastructure review...")
|
||||
|
||||
# Instantiate and run the infrastructure review crew
|
||||
infra_crew = InfraReviewCrew()
|
||||
inputs = {
|
||||
"pr_title": self.state.pr_title,
|
||||
@@ -108,15 +75,11 @@ class CodeReviewFlow(Flow[PRReviewState]):
|
||||
result = infra_crew.crew().kickoff(inputs=inputs)
|
||||
self.state.infra_review_results = str(result)
|
||||
print("Infrastructure review completed.")
|
||||
|
||||
return self.state
|
||||
|
||||
@listen(and_(run_code_review, run_security_review, run_infra_review))
|
||||
def summarise(self):
|
||||
"""Summarize the review results."""
|
||||
print("Starting summarisation...")
|
||||
|
||||
# Instantiate and run the summariser crew
|
||||
summariser_crew = SummariserCrew()
|
||||
inputs = {
|
||||
"code_review_results": self.state.code_review_results,
|
||||
@@ -128,15 +91,11 @@ class CodeReviewFlow(Flow[PRReviewState]):
|
||||
self.state.review_summary = str(result)
|
||||
self.state.completed_at = datetime.now()
|
||||
print("Summarisation completed.")
|
||||
|
||||
return self.state
|
||||
|
||||
@listen(summarise)
|
||||
def format_response(self):
|
||||
"""Format the final response."""
|
||||
print("Formatting final response...")
|
||||
|
||||
# Return the final state as the response
|
||||
return {
|
||||
"pr_id": self.state.pr_id,
|
||||
"pr_title": self.state.pr_title,
|
||||
@@ -147,4 +106,4 @@ class CodeReviewFlow(Flow[PRReviewState]):
|
||||
"started_at": self.state.started_at.isoformat() if self.state.started_at else None,
|
||||
"completed_at": self.state.completed_at.isoformat() if self.state.completed_at else None,
|
||||
"error": self.state.error
|
||||
}
|
||||
}
|
||||
|
||||
+25
-12
@@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import os
|
||||
from fastapi import FastAPI, HTTPException, Request
|
||||
from fastapi.responses import JSONResponse
|
||||
import uvicorn
|
||||
@@ -54,6 +55,8 @@ async def review_pr(request: Request) -> Dict[str, Any]:
|
||||
except Exception:
|
||||
raise HTTPException(status_code=422, detail="Invalid JSON payload")
|
||||
|
||||
logger.info(f"Payload keys: {payload.keys() if isinstance(payload, dict) else 'Not a dict'}")
|
||||
|
||||
# Validate and extract required fields according to the API specification
|
||||
# Request schema:
|
||||
# {
|
||||
@@ -94,11 +97,16 @@ async def review_pr(request: Request) -> Dict[str, Any]:
|
||||
title = payload.get("title")
|
||||
description = payload.get("description")
|
||||
|
||||
logger.info(f"pr_id from payload: {pr_id}")
|
||||
logger.info(f"title from payload: {title}")
|
||||
|
||||
# Extract repo information
|
||||
repo_data = payload.get("repo", {})
|
||||
repo_name = repo_data.get("name")
|
||||
repo_url = repo_data.get("url")
|
||||
|
||||
logger.info(f"repo_name from payload: {repo_name}")
|
||||
|
||||
# Extract source information
|
||||
source_data = payload.get("source", {})
|
||||
source_branch = source_data.get("branch")
|
||||
@@ -158,6 +166,22 @@ async def review_pr(request: Request) -> Dict[str, Any]:
|
||||
infra_review=context_data.get("infra_review")
|
||||
)
|
||||
|
||||
# Debug: Print the inputs being passed to the flow
|
||||
flow_inputs = {
|
||||
"pr_id": pr_id,
|
||||
"pr_title": title,
|
||||
"pr_description": description,
|
||||
"pr_url": f"{repo_url}/pull/{pr_id}", # Construct PR URL
|
||||
"repo_name": repo_name,
|
||||
"repo_url": repo_url,
|
||||
"branch": source_branch, # Using source branch as the active branch
|
||||
"base_branch": target_branch, # Using target branch as base
|
||||
"files": [file.dict() for file in files], # Convert to dict for flow
|
||||
"context_overrides": context_overrides.dict() if context_overrides else None
|
||||
}
|
||||
logger.info(f"Flow inputs: {flow_inputs}")
|
||||
logger.info(f"Flow inputs keys: {flow_inputs.keys()}")
|
||||
|
||||
# Initialize and run the flow with timeout
|
||||
flow = CodeReviewFlow()
|
||||
|
||||
@@ -169,18 +193,7 @@ async def review_pr(request: Request) -> Dict[str, Any]:
|
||||
flow_result = await asyncio.wait_for(
|
||||
loop.run_in_executor(
|
||||
pool,
|
||||
lambda: flow.kickoff(inputs={
|
||||
"pr_id": pr_id,
|
||||
"pr_title": title,
|
||||
"pr_description": description,
|
||||
"pr_url": f"{repo_url}/pull/{pr_id}", # Construct PR URL
|
||||
"repo_name": repo_name,
|
||||
"repo_url": repo_url,
|
||||
"branch": source_branch, # Using source branch as the active branch
|
||||
"base_branch": target_branch, # Using target branch as base
|
||||
"files": [file.dict() for file in files], # Convert to dict for flow
|
||||
"context_overrides": context_overrides.dict() if context_overrides else None
|
||||
})
|
||||
lambda: flow.kickoff(inputs=flow_inputs)
|
||||
),
|
||||
timeout=TOTAL_FLOW_TIMEOUT
|
||||
)
|
||||
|
||||
@@ -23,14 +23,14 @@ class ContextOverrides(BaseModel):
|
||||
class PRReviewState(BaseModel):
|
||||
"""State of the PR review process."""
|
||||
# Input fields
|
||||
pr_id: str
|
||||
pr_title: str
|
||||
pr_id: str = ""
|
||||
pr_title: str = ""
|
||||
pr_description: Optional[str] = None
|
||||
pr_url: Optional[str] = None
|
||||
repo_name: str
|
||||
repo_url: str
|
||||
branch: str
|
||||
base_branch: str
|
||||
repo_name: str = ""
|
||||
repo_url: str = ""
|
||||
branch: str = ""
|
||||
base_branch: str = ""
|
||||
files: List[FileInfo] = Field(default_factory=list)
|
||||
context_overrides: Optional[ContextOverrides] = None
|
||||
# Internal fields
|
||||
|
||||
Reference in New Issue
Block a user