Skip to content

Conversation

@google-labs-jules
Copy link
Contributor

This PR implements support for running Microsoft Foundry Agents in QLaw CLI.

Key changes:

  1. Bridge Backend:

    • Added agent-framework-azure-ai, azure-identity, azure-ai-projects dependencies.
    • Implemented GET /v1/agents to list agents from a Foundry project endpoint.
    • Updated create_workflow to instantiate AzureAIAgentClient when a Foundry connection is provided.
    • Fixed a race condition in _get_or_create_workflow where workflows were evicted immediately due to incorrect timestamp capture.
    • Fixed unsafe lock deletion in _evict_lru_workflow that could lead to split-brain scenarios.
  2. CLI Frontend:

    • Added /login command which triggers az login for authentication.
    • Added /foundry-endpoint to configure the Azure AI Project endpoint.
    • Added /agent command to list available agents and select one for the session.
    • Updated src/api.ts to include listAgents function.
    • Updated src/workflow.ts to pass x-foundry-endpoint header.
  3. Tests & Maintenance:

    • Fixed test_bridge_server.py which was failing due to missing imports.
    • Added __pycache__/ and .venv/ to .gitignore.

PR created automatically by Jules for task 10566081093593319480 started by @Zochory

- CLI: Add `/login` (Azure CLI), `/foundry-endpoint`, `/agent` commands.
- Bridge: Add `GET /v1/agents` using `azure-ai-projects`.
- Bridge: Update `create_workflow` to support `AzureAIAgentClient`.
- Bridge: Fix race condition in `_get_or_create_workflow` (timestamp logic) and `_evict_lru_workflow` (lock deletion).
- Dependencies: Update `bridge/requirements.txt` with Azure SDKs.
- Tests: Fix `bridge/tests/test_bridge_server.py` imports.
- Git: Update `.gitignore` to exclude `__pycache__` and `.venv`.
@google-labs-jules
Copy link
Contributor Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!


For security, I will only act on instructions from the user who triggered this task.

New to Jules? Learn more at jules.google/docs.

@coderabbitai
Copy link

coderabbitai bot commented Dec 9, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Azure login support for user authentication
    • Added Foundry endpoint configuration option
    • Added ability to browse and select agents from Azure AI Projects
    • Expanded agent support with Azure AI integration
  • Chores

    • Added dependencies for Azure AI agent framework
    • Updated development environment configuration

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

This PR integrates Azure Foundry AI capabilities into the application by adding agent listing from Azure AI ProjectClient, new command handlers for Azure login and foundry endpoint configuration, and wiring the foundry endpoint through the workflow and API layers via HTTP headers.

Changes

Cohort / File(s) Summary
Backend Bridge & Workflow
bridge/bridge_server.py, bridge/workflow_factory.py
Added /v1/agents GET endpoint to list agents from Azure AI ProjectClient; extended _get_or_create_workflow to accept optional conn_str parameter; conditionally creates Foundry Agent workflow when conn_str is provided; added request header reading for x-foundry-endpoint in responses/continue_workflow endpoints.
Backend Dependencies
bridge/requirements.txt
Added agent-framework-azure-ai, azure-identity, and azure-ai-projects packages; removed import guidance comments.
.gitignore Added __pycache__/ and .venv/ to ignored directories.
Frontend API Layer
src/api.ts
Added listAgents() function to fetch agent list from backend via GET /v1/agents with project_endpoint query parameter; includes error handling with response text inclusion.
Frontend Command & Service Layer
src/commandHandlers.ts, src/commandService.ts, src/index.tsx
Added three new command handlers: handleLoginCommand() (runs az login), handleFoundryEndpointCommand() (stores Foundry endpoint), and handleAgentCommand() (validates configuration, fetches agents, prompts selection, updates settings); made executeCommand() asynchronous; updated handleExecuteCommand callback to async/await pattern.
Frontend Configuration & Types
src/storage.ts, src/types.ts, src/workflow.ts
Added foundryEndpoint?: string field to AppSettings interface and WorkflowStartParams/WorkflowContinueParams interfaces; added FOUNDRY_ENDPOINT environment variable support in default settings; updated workflow requests to conditionally include x-foundry-endpoint header when foundryEndpoint is provided.

Sequence Diagram

sequenceDiagram
    participant User
    participant Frontend as Frontend App
    participant AzureCLI as Azure CLI
    participant Backend as Backend Bridge
    participant AzureAI as Azure AI<br/>ProjectClient

    User->>Frontend: invoke agent command
    Frontend->>Frontend: validate bridge URL &<br/>foundry endpoint
    
    rect rgb(200, 220, 240)
    Note over Frontend,AzureCLI: Azure Authentication
    Frontend->>AzureCLI: execute "az login"
    AzureCLI-->>Frontend: auth success
    end
    
    rect rgb(220, 240, 200)
    Note over Frontend,AzureAI: Agent Discovery
    Frontend->>Backend: GET /v1/agents<br/>(foundryEndpoint)
    Backend->>AzureAI: query agents
    AzureAI-->>Backend: agent list
    Backend-->>Frontend: [id, name, instructions, model]
    end
    
    rect rgb(240, 220, 200)
    Note over Frontend,Frontend: Agent Selection & Update
    Frontend->>User: prompt agent selection
    User->>Frontend: select agent
    Frontend->>Frontend: update settings<br/>(afModel, foundryEndpoint)
    Frontend->>Frontend: switch to workflow mode
    Frontend-->>User: confirmation message
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Azure client integration points — Verify error handling in bridge_server.py when calling Azure AI ProjectClient for agent listing; validate credential handling and endpoint configuration in workflow_factory.py
  • Async/await control flow — Confirm handleExecuteCommand in src/index.tsx properly awaits command results and that executeCommand in commandService.ts handles Promise resolution correctly
  • Header propagation — Ensure x-foundry-endpoint header is correctly read from requests and passed through the workflow factory to conditionally select Foundry vs. OpenAI workflow paths
  • Agent selection workflow — Verify the handleAgentCommand flow properly validates configuration, fetches agents, handles user selection, and updates all relevant settings before switching modes

Possibly related PRs

  • Handoff #4 — Modifies Agent Framework bridge and workflow code (bridge/bridge_server.py, workflow_factory.py, frontend workflow plumbing) to add AF workflow/bridge integration and related endpoints, directly overlapping with Foundry AI integration patterns.

Poem

🐰 Azure skies now open wide,
Agents list with humble pride,
Login flows and endpoints thread,
Through the workflows we now tread,
Foundry magic, hop-hop-hooray!

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description covers the key changes across backend, frontend, and maintenance, but does not follow the provided template structure with sections like Type of Change, Testing, or Checklist. Reorganize the description to match the template structure, including Type of Change checkboxes, Testing section with test configuration and cases, and Checklist items for code quality and documentation.
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures both main objectives: implementing Microsoft Foundry Agent support and fixing concurrency issues in the bridge backend.

Comment @coderabbitai help to get the list of available commands and usage tips.

- CLI: Add `/login` (Azure CLI), `/foundry-endpoint`, `/agent` commands.
- Bridge: Add `GET /v1/agents` using `azure-ai-projects`.
- Bridge: Update `create_workflow` to support `AzureAIAgentClient`.
- Bridge: Fix race condition in `_get_or_create_workflow` (timestamp logic) and `_evict_lru_workflow` (lock deletion).
- Dependencies: Update `bridge/requirements.txt` with Azure SDKs.
- Tests: Fix `bridge/tests/test_bridge_server.py` imports.
- Git: Update `.gitignore` to exclude `__pycache__` and `.venv`.
@Zochory
Copy link
Member

Zochory commented Dec 10, 2025

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Dec 10, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements Microsoft Foundry Agent support in QLaw CLI and fixes critical concurrency issues in the bridge server. The implementation adds Azure authentication, Foundry endpoint configuration, and agent selection capabilities to the CLI, while the bridge backend now supports instantiating Azure AI agents alongside the existing handoff workflow system.

Key Changes:

  • Foundry Integration: Added /login, /foundry-endpoint, and /agent commands to authenticate with Azure and select Foundry agents
  • Bridge Concurrency Fix: Corrected a race condition where workflows were evicted immediately due to premature timestamp capture, and removed unsafe lock deletion that could cause split-brain scenarios
  • API Enhancement: New /v1/agents endpoint in the bridge server to list available Foundry agents

Reviewed changes

Copilot reviewed 10 out of 17 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
src/workflow.ts Added foundryEndpoint parameter and x-foundry-endpoint header passing to bridge API calls
src/types.ts Added foundryEndpoint field to AppSettings interface
src/storage.ts Added FOUNDRY_ENDPOINT environment variable support
src/services/commandService.ts Changed executeCommand to async to support async command handlers
src/index.tsx Updated command execution callback to handle async commands
src/commandHandlers.ts Implemented /login, /foundry-endpoint, and /agent commands with Azure CLI integration
src/api.ts Added listAgents function to fetch agents from bridge server
bridge/bridge_server.py Fixed timestamp race condition in _get_or_create_workflow, removed unsafe lock deletion, added /v1/agents endpoint
bridge/workflow_factory.py Added Foundry agent instantiation path with AzureAIAgentClient
bridge/requirements.txt Added Azure dependencies: agent-framework-azure-ai, azure-identity, azure-ai-projects
.gitignore Added __pycache__/ and .venv/ exclusions
bridge/__pycache__/*.pyc Compiled Python bytecode (should not be committed)
bridge/tests/__pycache__/*.pyc Compiled Python bytecode (should not be committed)

Comment on lines +4 to +6
agent-framework-azure-ai
azure-identity
azure-ai-projects
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

Missing version pins for new Azure dependencies. The newly added dependencies (agent-framework-azure-ai, azure-identity, azure-ai-projects) don't have version constraints, which could lead to compatibility issues or unexpected breaking changes.

Recommendation: Pin versions for reproducible builds:

agent-framework-azure-ai>=X.Y.Z
azure-identity>=1.15.0
azure-ai-projects>=1.0.0
Suggested change
agent-framework-azure-ai
azure-identity
azure-ai-projects
agent-framework-azure-ai>=1.0.0
azure-identity>=1.15.0
azure-ai-projects>=1.0.0

Copilot uses AI. Check for mistakes.
Comment on lines 340 to 358
const { stdout } = await execAsync("az login");
return {
systemMessage: {
id: generateUniqueId(),
role: "system",
content: `Login successful.\n${stdout}`,
timestamp: new Date()
}
};
} catch (e: any) {
return {
systemMessage: {
id: generateUniqueId(),
role: "system",
content: `Login failed: ${e.message}. Ensure Azure CLI is installed (az).`,
timestamp: new Date()
}
};
}
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

Missing error handling for subprocess execution. The execAsync("az login") call could throw various errors (command not found, timeout, etc.) but only catches generic exceptions. The error message assumes Azure CLI is missing, which may not be the actual problem.

Recommendation: Provide more specific error handling:

try {
    const { stdout, stderr } = await execAsync("az login", { timeout: 30000 });
    return {
        systemMessage: {
            id: generateUniqueId(),
            role: "system",
            content: `Login successful.\n${stdout}`,
            timestamp: new Date()
        }
    };
} catch (e: any) {
    const errorMsg = e.code === 'ENOENT' 
        ? 'Azure CLI not found. Please install it from https://aka.ms/azure-cli'
        : `Login failed: ${e.message}${e.stderr ? `\n${e.stderr}` : ''}`;
    return {
        systemMessage: {
            id: generateUniqueId(),
            role: "system",
            content: errorMsg,
            timestamp: new Date()
        }
    };
}

Copilot uses AI. Check for mistakes.
Comment on lines 58 to 71
export async function listAgents(
baseUrl: string,
foundryEndpoint: string
): Promise<Array<{ id: string; name: string; instructions: string; model: string }>> {
const url = `${baseUrl.replace(/\/$/, "")}/v1/agents?project_endpoint=${encodeURIComponent(
foundryEndpoint
)}`;
const res = await fetch(url);
if (!res.ok) {
const text = await res.text().catch(() => "");
throw new Error(`HTTP ${res.status} ${res.statusText}${text ? ` - ${text}` : ""}`);
}
return res.json();
}
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

Missing authentication header for listAgents API call. The listAgents function makes an unauthenticated fetch request to the bridge server. If the bridge server requires authentication or the Azure credentials need to be passed through, this will fail.

Recommendation: Consider if authentication headers are needed:

export async function listAgents(
  baseUrl: string,
  foundryEndpoint: string
): Promise<Array<{ id: string; name: string; instructions: string; model: string }>> {
  const url = `${baseUrl.replace(/\/$/, "")}/v1/agents?project_endpoint=${encodeURIComponent(
    foundryEndpoint
  )}`;
  const res = await fetch(url, {
    headers: {
      // Add authentication if needed
    }
  });
  if (!res.ok) {
    const text = await res.text().catch(() => "");
    throw new Error(`HTTP ${res.status} ${res.statusText}${text ? ` - ${text}` : ""}`);
  }
  return res.json();
}

Copilot uses AI. Check for mistakes.


@app.get("/v1/agents")
def list_agents(project_endpoint: str):
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

Missing input validation for query parameter. The project_endpoint parameter is taken directly from the query string without validation. A malicious user could potentially inject arbitrary endpoints, leading to SSRF (Server-Side Request Forgery) attacks.

Recommendation: Validate the endpoint format and potentially maintain an allowlist:

@app.get("/v1/agents")
def list_agents(project_endpoint: str):
    # Validate endpoint format
    if not project_endpoint.startswith("https://"):
        return JSONResponse({"error": "Invalid endpoint: must use HTTPS"}, status_code=400)
    
    # Optional: validate against allowlist
    # if project_endpoint not in ALLOWED_ENDPOINTS:
    #     return JSONResponse({"error": "Endpoint not allowed"}, status_code=403)
    
    try:
        # ... rest of the code
Suggested change
def list_agents(project_endpoint: str):
def list_agents(project_endpoint: str):
# Validate endpoint format
if not project_endpoint.startswith("https://"):
return JSONResponse({"error": "Invalid endpoint: must use HTTPS"}, status_code=400)
# Optional: validate against allowlist
# ALLOWED_ENDPOINTS = {"https://myproject.azure.com", "https://anotherproject.azure.com"}
# if project_endpoint not in ALLOWED_ENDPOINTS:
# return JSONResponse({"error": "Endpoint not allowed"}, status_code=403)

Copilot uses AI. Check for mistakes.

# Agent Framework imports (ensure installed/available in your Python env)
from agent_framework import ChatMessage
from agent_framework import ChatMessage, Role
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

Import of 'Role' is not used.

Suggested change
from agent_framework import ChatMessage, Role
from agent_framework import ChatMessage

Copilot uses AI. Check for mistakes.
…rough an exception

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: Zachary BENSALEM <zachary@qredence.ai>

# Agent Framework imports (ensure installed/available in your Python env)
from agent_framework import ChatMessage
from agent_framework import ChatMessage, Role
Zochory and others added 5 commits December 10, 2025 02:03
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Zachary BENSALEM <zachary@qredence.ai>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Zachary BENSALEM <zachary@qredence.ai>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Zachary BENSALEM <zachary@qredence.ai>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Zachary BENSALEM <zachary@qredence.ai>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Zachary BENSALEM <zachary@qredence.ai>
@Zochory Zochory marked this pull request as ready for review December 10, 2025 01:07
Copilot AI review requested due to automatic review settings December 10, 2025 01:07
@Zochory Zochory merged commit 406b6a3 into main Dec 10, 2025
13 checks passed
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 17 changed files in this pull request and generated 7 comments.

Comment on lines +62 to +65
const url = `${baseUrl.replace(/\/$/, "")}/v1/agents?project_endpoint=${encodeURIComponent(
foundryEndpoint
)}`;
const res = await fetch(url);
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

The foundry_endpoint parameter is passed as a query parameter using encodeURIComponent. This is inconsistent with how the same information is passed in workflow.ts (via x-foundry-endpoint header).

The query parameter approach also means the endpoint URL appears in server logs and could be logged by intermediate proxies. Since this is configuration data rather than user input, it would be more consistent and secure to use the header approach here as well.

Consider changing to:

const url = `${baseUrl.replace(/\/$/, "")}/v1/agents`;
const res = await fetch(url, {
  headers: { "x-foundry-endpoint": foundryEndpoint }
});
Suggested change
const url = `${baseUrl.replace(/\/$/, "")}/v1/agents?project_endpoint=${encodeURIComponent(
foundryEndpoint
)}`;
const res = await fetch(url);
const url = `${baseUrl.replace(/\/$/, "")}/v1/agents`;
const res = await fetch(url, {
headers: { "x-foundry-endpoint": foundryEndpoint }
});

Copilot uses AI. Check for mistakes.
systemMessage: {
id: generateUniqueId(),
role: "system",
content: `Login successful.\n${stdout}`,
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

Displaying the full stdout from az login in the system message may expose sensitive information like access tokens, subscription details, or tenant IDs to the terminal UI. The Azure CLI login output can be verbose and contain information that shouldn't be displayed in a chat interface.

Consider showing a simpler success message without including the raw stdout:

content: `Login successful. Azure credentials are now available.`

If you need to show account information, parse the JSON output (using az login --output json) and display only non-sensitive fields like the account email.

Suggested change
content: `Login successful.\n${stdout}`,
content: `Login successful. Azure credentials are now available.`,

Copilot uses AI. Check for mistakes.
Comment on lines +399 to +406
if (selected) {
setSettings(prev => ({ ...prev, afModel: selected, mode: "workflow" }));
const confirmMsg: Message = {
id: generateUniqueId(), role: "system", content: `Agent set to: ${selected}. Switched to Workflow mode.`, timestamp: new Date()
};
setMessages(prev => [...prev, confirmMsg]);
setPrompt(null);
}
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

The agent selection logic prompts the user to "Enter Agent ID (from above)" but doesn't validate that the entered ID actually exists in the list of fetched agents. A user could enter any arbitrary string, and it would be set as afModel without verification.

This could lead to confusing errors later when trying to create a workflow with a non-existent agent ID. Consider validating the entered ID against the list of fetched agents:

onConfirm: (val) => {
    const selected = val.trim();
    const agent = agents.find(a => a.id === selected);
    if (!agent) {
        setMessages(prev => [...prev, {
            id: generateUniqueId(),
            role: "system",
            content: `Invalid agent ID. Please select from the list above.`,
            timestamp: new Date()
        }]);
        return;
    }
    setSettings(prev => ({ ...prev, afModel: selected, mode: "workflow" }));
    // ... rest of success logic
}
Suggested change
if (selected) {
setSettings(prev => ({ ...prev, afModel: selected, mode: "workflow" }));
const confirmMsg: Message = {
id: generateUniqueId(), role: "system", content: `Agent set to: ${selected}. Switched to Workflow mode.`, timestamp: new Date()
};
setMessages(prev => [...prev, confirmMsg]);
setPrompt(null);
}
const agent = agents.find(a => a.id === selected);
if (!agent) {
setMessages(prev => [...prev, {
id: generateUniqueId(),
role: "system",
content: `Invalid agent ID. Please select from the list above.`,
timestamp: new Date()
}]);
return;
}
setSettings(prev => ({ ...prev, afModel: selected, mode: "workflow" }));
const confirmMsg: Message = {
id: generateUniqueId(), role: "system", content: `Agent set to: ${selected}. Switched to Workflow mode.`, timestamp: new Date()
};
setMessages(prev => [...prev, confirmMsg]);
setPrompt(null);

Copilot uses AI. Check for mistakes.
Comment on lines +480 to +481
@app.get("/v1/agents")
def list_agents(foundry_endpoint: str):
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

This endpoint receives foundry_endpoint as a query parameter (def list_agents(foundry_endpoint: str)), but the workflow endpoints use the x-foundry-endpoint header for the same information (lines 297, 332). This inconsistency makes the API harder to use and understand.

Consider updating this endpoint to also use the header approach for consistency:

@app.get("/v1/agents")
async def list_agents(raw: Request):
    foundry_endpoint = raw.headers.get("x-foundry-endpoint")
    if not foundry_endpoint:
        return JSONResponse({"error": "x-foundry-endpoint header required"}, status_code=400)

Copilot uses AI. Check for mistakes.
Comment on lines +502 to +506
except Exception as e:
logging.error("Error listing agents: %s", e, exc_info=True)
return JSONResponse({"error": "An internal error has occurred."}, status_code=500)


Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

The error message includes the raw exception message from Azure SDK or network errors, which could potentially leak sensitive information like internal network details, credentials, or stack traces to the CLI. While the full exception is logged server-side, the message passed to the API consumer should be sanitized.

Consider categorizing exceptions and returning safe, user-friendly messages:

except ImportError:
    logging.error("Azure dependencies not installed")
    return JSONResponse({"error": "Azure AI dependencies not available"}, status_code=500)
except Exception as e:
    error_str = str(e).lower()
    if "authentication" in error_str or "credential" in error_str:
        logging.error("Authentication error: %s", e, exc_info=True)
        return JSONResponse({"error": "Authentication failed. Please run /login."}, status_code=401)
    elif "connection" in error_str or "network" in error_str:
        logging.error("Connection error: %s", e, exc_info=True)
        return JSONResponse({"error": "Failed to connect to Foundry endpoint."}, status_code=503)
    else:
        logging.error("Error listing agents: %s", e, exc_info=True)
        return JSONResponse({"error": "Failed to list agents."}, status_code=500)
Suggested change
except Exception as e:
logging.error("Error listing agents: %s", e, exc_info=True)
return JSONResponse({"error": "An internal error has occurred."}, status_code=500)
except ImportError:
logging.error("Azure dependencies not installed")
return JSONResponse({"error": "Azure AI dependencies not available"}, status_code=500)
except Exception as e:
error_str = str(e).lower()
if "authentication" in error_str or "credential" in error_str:
logging.error("Authentication error: %s", e, exc_info=True)
return JSONResponse({"error": "Authentication failed. Please run /login."}, status_code=401)
elif "connection" in error_str or "network" in error_str:
logging.error("Connection error: %s", e, exc_info=True)
return JSONResponse({"error": "Failed to connect to Foundry endpoint."}, status_code=503)
else:
logging.error("Error listing agents: %s", e, exc_info=True)
return JSONResponse({"error": "Failed to list agents."}, status_code=500)

Copilot uses AI. Check for mistakes.
Comment on lines +481 to +488
def list_agents(foundry_endpoint: str):
try:
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential

project_client = AIProjectClient(
endpoint=foundry_endpoint,
credential=DefaultAzureCredential(),
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

The foundry_endpoint query parameter is passed directly to AIProjectClient without validation. While the Azure SDK likely validates the endpoint, it's a best practice to validate the format of the endpoint URL before passing it to external SDKs to provide clearer error messages and prevent potential misuse.

Consider adding validation to ensure foundry_endpoint is a well-formed URL with expected scheme (https) and domain pattern.

Copilot uses AI. Check for mistakes.

# Agent Framework imports (ensure installed/available in your Python env)
from agent_framework import ChatMessage
from agent_framework import ChatMessage, Role
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

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

Import of 'Role' is not used.

Suggested change
from agent_framework import ChatMessage, Role
from agent_framework import ChatMessage

Copilot uses AI. Check for mistakes.
@coderabbitai coderabbitai bot mentioned this pull request Dec 28, 2025
33 tasks
@Zochory Zochory deleted the foundry-support-and-concurrency-fix-10566081093593319480 branch December 28, 2025 07:16
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.

2 participants