Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion src/backend/app_kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from services.json_service import JsonService

# Updated import for KernelArguments
from utils_kernel import initialize_runtime_and_context, rai_success
from utils_kernel import initialize_runtime_and_context, rai_success, rai_validate_team_config


# Check if the Application Insights Instrumentation Key is set in the environment variables
Expand Down Expand Up @@ -1476,6 +1476,34 @@ async def upload_team_config_endpoint(request: Request, file: UploadFile = File(
status_code=400, detail=f"Invalid JSON format: {str(e)}"
)

# Validate content with RAI before processing
rai_valid, rai_error = await rai_validate_team_config(json_data)
if not rai_valid:
# Track RAI validation failure
track_event_if_configured(
"Team configuration RAI validation failed",
{
"status": "failed",
"user_id": user_id,
"filename": file.filename,
"reason": rai_error,
},
)
raise HTTPException(
status_code=400,
detail=rai_error
)

# Track successful RAI validation
track_event_if_configured(
"Team configuration RAI validation passed",
{
"status": "passed",
"user_id": user_id,
"filename": file.filename,
},
)

# Initialize memory store and service
kernel, memory_store = await initialize_runtime_and_context("", user_id)
json_service = JsonService(memory_store)
Expand Down
65 changes: 65 additions & 0 deletions src/backend/utils_kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,68 @@ async def rai_success(description: str, is_task_creation: bool) -> bool:
logging.error(f"Error in RAI check: {str(e)}")
# Default to blocking the operation if RAI check fails for safety
return False


async def rai_validate_team_config(team_config_json: dict) -> tuple[bool, str]:
"""
Validates team configuration JSON content for RAI compliance.

Args:
team_config_json: The team configuration JSON data to validate

Returns:
Tuple of (is_valid, error_message)
- is_valid: True if content passes RAI checks, False otherwise
- error_message: Simple error message if validation fails
"""
try:
# Extract all text content from the team configuration
text_content = []

# Extract team name and description
if "name" in team_config_json:
text_content.append(team_config_json["name"])
if "description" in team_config_json:
text_content.append(team_config_json["description"])

# Extract agent information
if "agents" in team_config_json:
for agent in team_config_json["agents"]:
if isinstance(agent, dict):
if "name" in agent:
text_content.append(agent["name"])
if "description" in agent:
text_content.append(agent["description"])
if "role" in agent:
text_content.append(agent["role"])
if "capabilities" in agent and isinstance(agent["capabilities"], list):
text_content.extend(agent["capabilities"])

# Extract starting tasks
if "starting_tasks" in team_config_json:
for task in team_config_json["starting_tasks"]:
if isinstance(task, str):
text_content.append(task)
elif isinstance(task, dict):
if "name" in task:
text_content.append(task["name"])
if "prompt" in task:
text_content.append(task["prompt"])

# Combine all text content for validation
combined_content = " ".join(text_content)

if not combined_content.strip():
return False, "Team configuration contains no readable text content"

# Use existing RAI validation function
rai_result = await rai_success(combined_content, False)

if not rai_result:
return False, "Team configuration contains inappropriate content and cannot be uploaded."

return True, ""

except Exception as e:
logging.error(f"Error validating team configuration with RAI: {str(e)}")
return False, "Unable to validate team configuration content. Please try again."
3 changes: 2 additions & 1 deletion src/frontend/src/api/apiService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Step,
StepStatus,
AgentType,
AgentTypeString,
PlanMessage
} from '../models';

Expand Down Expand Up @@ -468,7 +469,7 @@ export class APIService {
* @param agentType Agent type to filter by
* @returns Array of steps for the specified agent
*/
getStepsForAgent(plan: PlanWithSteps, agentType: AgentType): Step[] {
getStepsForAgent(plan: PlanWithSteps, agentType: AgentTypeString): Step[] {
return plan.steps.filter(step => step.agent === agentType);
}

Expand Down
Loading
Loading