Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
75 changes: 75 additions & 0 deletions data/agent_teams/RFP_Analysis_team.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"id": "1",
"team_id": "team-clm-1",
"name": "RFP Team",
"status": "visible",
"created": "",
"created_by": "",
"description": "A specialized multi-agent team that analyzes RFP and contract documents to summarize content, identify potential risks, check compliance gaps, and provide action plans for contract improvement.",
"logo": "",
"plan": "",
"agents": [
{
"input_key": "",
"type": "summary",
"name": "SummaryAgent",
"deployment_name": "gpt-4.1-mini",
"icon": "",
"system_message":"You are the Summary Agent. Your role is to read and synthesize RFP or proposal documents into clear, structured executive summaries. Focus on key clauses, deliverables, evaluation criteria, pricing terms, timelines, and obligations. Organize your output into sections such as Overview, Key Clauses, Deliverables, Terms, and Notable Conditions. Highlight unique or high-impact items that other agents (Risk or Compliance) should review. Be concise, factual, and neutral in tone.",
"description": "Summarizes RFP and contract documents into structured, easy-to-understand overviews.",
"use_rag": true,
"use_mcp": false,
"use_bing": false,
"use_reasoning": false,
"index_name": "pdf-index",
"index_foundry_name": "",
"index_endpoint": "",
"coding_tools": false
},
{
"input_key": "",
"type": "risk",
"name": "RiskAgent",
"deployment_name": "gpt-4.1-mini",
"icon": "",
"system_message": "You are the Risk Agent. Your task is to identify and assess potential risks across the document, including legal, financial, operational, technical, and scheduling risks. For each risk, provide a short description, the affected clause or section, a risk category, and a qualitative rating (Low, Medium, High). Focus on material issues that could impact delivery, compliance, or business exposure. Summarize findings clearly to support decision-making and escalation.",
"description": "Analyzes the dataset for risks such as delivery, financial, operational, and compliance-related vulnerabilities.",
"use_rag": true,
"use_mcp": false,
"use_bing": false,
"use_reasoning": false,
"index_name": "pdf-index",
"index_foundry_name": "",
"index_endpoint": "",
"coding_tools": false
},
{
"input_key": "",
"type": "compliance",
"name": "ComplianceAgent",
"deployment_name": "gpt-4.1-mini",
"icon": "",
"system_message": "You are the Compliance Agent. Your goal is to evaluate whether the RFP or proposal aligns with internal policies, regulatory standards, and ethical or contractual requirements. Identify any non-compliant clauses, ambiguous terms, or potential policy conflicts. For each issue, specify the related policy area (e.g., data privacy, labor, financial controls) and classify it as Mandatory or Recommended for review. Maintain a professional, objective tone and emphasize actionable compliance insights.",
"description": "Checks for compliance gaps against regulations, policies, and standard contracting practices.",
"use_rag": true,
"use_mcp": false,
"use_bing": false,
"use_reasoning": false,
"index_name": "pdf-index",
"index_foundry_name": "",
"index_endpoint": "",
"coding_tools": false
}
],
"protected": false,
"starting_tasks": [
{
"id": "task-1",
"name": "RFP Document Summary",
"prompt": "I would like to review the Woodgrove Bank RFP response from Contoso",
"created": "",
"creator": "",
"logo": ""
}
]
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/DeploymentGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -496,4 +496,4 @@ To debug the python server in the frontend directory (frontend_server.py) and re
"args": ["frontend_server:app", "--port", "3000", "--reload"],
"jinja": true
}
```
```
168 changes: 62 additions & 106 deletions infra/scripts/Process-Sample-Data.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,11 @@ param(
)

# Get parameters from azd env, if not provided
if (-not $StorageAccount) {
$StorageAccount = $(azd env get-value AZURE_STORAGE_ACCOUNT_NAME)
}

if (-not $BlobContainer) {
$BlobContainer = $(azd env get-value AZURE_STORAGE_CONTAINER_NAME)
}

if (-not $AiSearch) {
$AiSearch = $(azd env get-value AZURE_AI_SEARCH_NAME)
}

if (-not $AiSearchIndex) {
$AiSearchIndex = $(azd env get-value AZURE_AI_SEARCH_INDEX_NAME)
}

if (-not $ResourceGroup) {
$ResourceGroup = $(azd env get-value AZURE_RESOURCE_GROUP)
}
if (-not $StorageAccount) { $StorageAccount = $(azd env get-value AZURE_STORAGE_ACCOUNT_NAME) }
if (-not $BlobContainer) { $BlobContainer = $(azd env get-value AZURE_STORAGE_CONTAINER_NAME) }
if (-not $AiSearch) { $AiSearch = $(azd env get-value AZURE_AI_SEARCH_NAME) }
if (-not $AiSearchIndex) { $AiSearchIndex = $(azd env get-value AZURE_AI_SEARCH_INDEX_NAME) }
if (-not $ResourceGroup) { $ResourceGroup = $(azd env get-value AZURE_RESOURCE_GROUP) }

if (-not $AzSubscriptionId) {
$AzSubscriptionId = $(azd env get-value AZURE_SUBSCRIPTION_ID)
Expand Down Expand Up @@ -67,13 +53,8 @@ if ($currentSubscriptionId -ne $AzSubscriptionId) {
if ($confirmation.ToLower() -ne "y") {
Write-Host "Fetching available subscriptions..."
$availableSubscriptions = (az account list --query "[?state=='Enabled']" | ConvertFrom-Json -AsHashtable)

# Create a cleaner array of subscription objects
$subscriptionArray = $availableSubscriptions | ForEach-Object {
[PSCustomObject]@{
Name = $_.name
Id = $_.id
}
[PSCustomObject]@{ Name = $_.name; Id = $_.id }
}

do {
Expand All @@ -90,17 +71,13 @@ if ($currentSubscriptionId -ne $AzSubscriptionId) {

if ($subscriptionIndex -ge 1 -and $subscriptionIndex -le $subscriptionArray.Count) {
$selectedSubscription = $subscriptionArray[$subscriptionIndex-1]
$selectedSubscriptionName = $selectedSubscription.Name
$selectedSubscriptionId = $selectedSubscription.Id

# Set the selected subscription
$result = az account set --subscription $selectedSubscriptionId
$result = az account set --subscription $selectedSubscription.Id
if ($LASTEXITCODE -eq 0) {
Write-Host "Switched to subscription: $selectedSubscriptionName ( $selectedSubscriptionId )"
Write-Host "Switched to subscription: $($selectedSubscription.Name) ( $($selectedSubscription.Id) )"
break
}
else {
Write-Host "Failed to switch to subscription: $selectedSubscriptionName ( $selectedSubscriptionId )."
Write-Host "Failed to switch to subscription: $($selectedSubscription.Name) ( $($selectedSubscription.Id) )."
}
}
else {
Expand All @@ -120,19 +97,16 @@ else {

$stIsPublicAccessDisabled = $false
$srchIsPublicAccessDisabled = $false

# Enable public access for resources
if ($ResourceGroup) {
$stPublicAccess = $(az storage account show --name $StorageAccount --resource-group $ResourceGroup --query "publicNetworkAccess" -o tsv)
if ($stPublicAccess -eq "Disabled") {
$stIsPublicAccessDisabled = $true
Write-Host "Enabling public access for storage account: $StorageAccount"
az storage account update --name $StorageAccount --public-network-access enabled --default-action Allow --output none
if ($LASTEXITCODE -ne 0) {
Write-Host "Error: Failed to enable public access for storage account."
exit 1
}
}
else {
if ($LASTEXITCODE -ne 0) { Write-Host "Error: Failed to enable public access for storage account."; exit 1 }
} else {
Write-Host "Public access is already enabled for storage account: $StorageAccount"
}

Expand All @@ -141,116 +115,98 @@ if ($ResourceGroup) {
$srchIsPublicAccessDisabled = $true
Write-Host "Enabling public access for search service: $AiSearch"
az search service update --name $AiSearch --resource-group $ResourceGroup --public-network-access enabled --output none
if ($LASTEXITCODE -ne 0) {
Write-Host "Error: Failed to enable public access for search service."
exit 1
}
}
else {
if ($LASTEXITCODE -ne 0) { Write-Host "Error: Failed to enable public access for search service."; exit 1 }
} else {
Write-Host "Public access is already enabled for search service: $AiSearch"
}
}

# Upload CSV files
Write-Host "Uploading CSV files to blob storage..."
az storage blob upload-batch --account-name $StorageAccount --destination $BlobContainer --source "data/datasets" --auth-mode login --pattern "*.csv" --overwrite --output none
az storage blob upload-batch --account-name $StorageAccount --destination $BlobContainer --source "data/datasets" --auth-mode login --pattern "*.json" --overwrite --output none
if ($LASTEXITCODE -ne 0) { Write-Host "Error: Failed to upload CSV files."; exit 1 }
Write-Host "CSV files uploaded successfully."

# Upload sample files to blob storage
Write-Host "Uploading sample files to blob storage..."
$result = az storage blob upload-batch --account-name $StorageAccount --destination $BlobContainer --source "data/datasets" --auth-mode login --pattern "*" --overwrite --output none
# Upload PDF files
Write-Host "Uploading PDF files from RFP_dataset to blob storage..."
az storage blob upload-batch --account-name $StorageAccount --destination $BlobContainer --source "data/datasets/RFP_dataset" --auth-mode login --pattern "*.pdf" --overwrite --output none
if ($LASTEXITCODE -ne 0) { Write-Host "Error: Failed to upload PDF files."; exit 1 }
Write-Host "PDF files uploaded successfully."

if ($LASTEXITCODE -ne 0) {
Write-Host "Error: Failed to upload files to blob storage."
exit 1
# Detect file types
Write-Host "Detecting file types in blob container..."
$fileList = az storage blob list --account-name $StorageAccount --container-name $BlobContainer --query "[].name" -o tsv --auth-mode login
$hasPdf = $false
$hasCsv = $false
foreach ($file in $fileList) {
if ($file -match "\.pdf$") { $hasPdf = $true }
if ($file -match "\.csv$") { $hasCsv = $true }
}
Write-Host "Files uploaded successfully to blob storage."

# Determine the correct Python command
$pythonCmd = $null

try {
$pythonVersion = (python --version) 2>&1
if ($pythonVersion -match "Python \d") {
$pythonCmd = "python"
}
}
catch {
# Do nothing, try python3 next
}

if ($pythonVersion -match "Python \d") { $pythonCmd = "python" }
} catch {}
if (-not $pythonCmd) {
try {
$pythonVersion = (python3 --version) 2>&1
if ($pythonVersion -match "Python \d") {
$pythonCmd = "python3"
}
}
catch {
Write-Host "Python is not installed on this system or it is not added in the PATH."
if ($pythonVersion -match "Python \d") { $pythonCmd = "python3" }
} catch {
Write-Host "Python is not installed or not in PATH."
exit 1
}
}
if (-not $pythonCmd) { Write-Host "Python is not installed or not in PATH."; exit 1 }

if (-not $pythonCmd) {
Write-Host "Python is not installed on this system or it is not added in the PATH."
exit 1
}

# Create virtual environment
# Virtual environment
$venvPath = "infra/scripts/scriptenv"
if (Test-Path $venvPath) {
Write-Host "Virtual environment already exists. Skipping creation."
}
else {
} else {
Write-Host "Creating virtual environment"
& $pythonCmd -m venv $venvPath
}

# Activate the virtual environment
$activateScript = ""
if (Test-Path (Join-Path -Path $venvPath -ChildPath "bin/Activate.ps1")) {
$activateScript = Join-Path -Path $venvPath -ChildPath "bin/Activate.ps1"
}
elseif (Test-Path (Join-Path -Path $venvPath -ChildPath "Scripts/Activate.ps1")) {
$activateScript = Join-Path -Path $venvPath -ChildPath "Scripts/Activate.ps1"
}

if ($activateScript) {
Write-Host "Activating virtual environment"
. $activateScript # Use dot sourcing to run in the current scope
}
else {
# Activate venv
if (Test-Path (Join-Path $venvPath "bin/Activate.ps1")) {
. (Join-Path $venvPath "bin/Activate.ps1")
} elseif (Test-Path (Join-Path $venvPath "Scripts/Activate.ps1")) {
. (Join-Path $venvPath "Scripts/Activate.ps1")
} else {
Write-Host "Error activating virtual environment. Requirements may be installed globally."
}

# Install the requirements
# Install requirements
Write-Host "Installing requirements"
pip install --quiet -r infra/scripts/requirements.txt
Write-Host "Requirements installed"

# Run the Python script to index data
Write-Host "Running the python script to index data"
$process = Start-Process -FilePath $pythonCmd -ArgumentList "infra/scripts/index_datasets.py", $StorageAccount, $BlobContainer, $AiSearch, $AiSearchIndex -Wait -NoNewWindow -PassThru

if ($process.ExitCode -ne 0) {
Write-Host "Error: Indexing python script execution failed."
exit 1
# Run indexing scripts
if ($hasCsv) {
Write-Host "Running the python script to index CSV data"
& $pythonCmd "infra/scripts/index_datasets.py" $StorageAccount $BlobContainer $AiSearch $AiSearchIndex
if ($LASTEXITCODE -ne 0) { Write-Host "Error: CSV indexing script failed."; exit 1 }
}
# if ($hasPdf) {
# Write-Host "Running the python script to index PDF data"
# & $pythonCmd "infra/scripts/index_rfp_data.py" $StorageAccount $BlobContainer $AiSearch $AiSearchIndex
# if ($LASTEXITCODE -ne 0) { Write-Host "Error: PDF indexing script failed."; exit 1 }
# }
if (-not $hasCsv -and -not $hasPdf) {
Write-Host "No CSV or PDF files found to index."
}

#disable public access for resources
# Disable public access again
if ($stIsPublicAccessDisabled) {
Write-Host "Disabling public access for storage account: $StorageAccount"
az storage account update --name $StorageAccount --public-network-access disabled --default-action Deny --output none
if ($LASTEXITCODE -ne 0) {
Write-Host "Error: Failed to disable public access for storage account."
exit 1
}
}

if ($srchIsPublicAccessDisabled) {
Write-Host "Disabling public access for search service: $AiSearch"
az search service update --name $AiSearch --resource-group $ResourceGroup --public-network-access disabled --output none
if ($LASTEXITCODE -ne 0) {
Write-Host "Error: Failed to disable public access for search service."
exit 1
}
}

Write-Host "Script executed successfully. Sample Data Processed Successfully."
Loading
Loading