Skip to content

Conversation

butlfrazp
Copy link

Description

Thank you for opening a Pull Request!
Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

Fixes #<issue_number_goes_here> 🦕

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @butlfrazp, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

I've added a new "Hello World" sample for an Azure AI Foundry agent. This sample demonstrates the fundamental capabilities of an Azure AI agent, complete with a modern web interface for real-time chat, a command-line interface for various operations, and comprehensive documentation. It's designed to be a straightforward starting point for anyone looking to understand or build agents using Azure AI Foundry, offering both a fully functional Azure-connected mode and a convenient demo mode that doesn't require Azure credentials.

Highlights

  • New Sample Application: This pull request introduces a brand new "Hello World" sample for an Azure AI Foundry agent, providing a minimal yet complete example of how to build and interact with such an agent.
  • Interactive Web Interface: A modern web interface is included, built with Starlette, featuring real-time chat via WebSockets, responsive design for various devices, and visual feedback like typing indicators.
  • Enhanced Documentation: Comprehensive documentation has been added, including a detailed DEVELOPMENT.md for setup, testing, and deployment, and an updated README.md for quick understanding and usage.
  • CLI Tools for Management: The sample now includes a command-line interface (cli.py) for easy management, allowing users to run the web server, interact via a console demo, and check environment configurations.
  • Practical Usage Examples: A dedicated examples/ directory provides various usage scenarios, such as simple_chat.py for basic interaction, multi_turn.py for conversational flow, and error_handling.py to demonstrate robust error management.
  • Docker Integration: The sample is fully containerized with a Dockerfile and docker-compose.yml, enabling seamless development and deployment in Docker environments.
  • Demo Mode with Mock Agent: A mock_agent.py has been implemented, allowing the web UI to run in a demo mode without requiring actual Azure AI Foundry credentials, making it easier for new users to get started.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a comprehensive "Hello World" sample for the Azure AI Foundry Agent, complete with a Starlette web application, a real-time chat UI, a command-line interface, example scripts, Docker support, and tests. The project is well-structured and provides a solid foundation for users. My review focuses on enhancing correctness, maintainability, and addressing several inconsistencies in the documentation and configuration. The key recommendations include fixing the Docker health check which currently fails, replacing a blocking call in asynchronous code to prevent performance issues, and resolving module pathing problems to improve the project's robustness and ease of use.

WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y \
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

The HEALTHCHECK instruction relies on curl to check the application's health. However, the curl command is not available in the python:3.11-slim base image and is not installed in the preceding RUN command. This will cause the health check to fail, potentially leading Docker or container orchestrators to incorrectly terminate the container.

RUN apt-get update && apt-get install -y \
    build-essential \
    curl

and iterations < max_iterations
):
iterations += 1
time.sleep(1)
Copy link
Contributor

Choose a reason for hiding this comment

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

high

Using time.sleep() in an async function is a blocking operation that will halt the entire asyncio event loop. This can severely degrade the performance and responsiveness of the application, as no other concurrent tasks can execute during the sleep period. The non-blocking await asyncio.sleep() should be used instead.

Suggested change
time.sleep(1)
await asyncio.sleep(1)


```bash
# Development with auto-reload
docker-compose -f docker-compose.dev.yml up
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The documentation refers to a docker-compose.dev.yml file for running the application with auto-reload. However, this file is not included in the project. This will lead to an error for any developer attempting to follow this instruction.

Comment on lines +15 to +17
- `streaming_response.py` - Streaming responses (if supported)
- `context_management.py` - Managing conversation context
- `custom_instructions.py` - Using custom instructions
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The documentation for examples lists several advanced example files (streaming_response.py, context_management.py, custom_instructions.py) that are not present in the project. This could be confusing for users who are looking for these specific implementations.

Suggested change
- `streaming_response.py` - Streaming responses (if supported)
- `context_management.py` - Managing conversation context
- `custom_instructions.py` - Using custom instructions
- `simple_chat.py` - Simple one-off conversation
- `multi_turn.py` - Multi-turn conversation example
- `error_handling.py` - Error handling demonstration


try:
# Run the Starlette server
run_server(host="0.0.0.0", port=8000, reload=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The main entry point for the package hardcodes reload=True when running the server. While this is convenient for development, it's not ideal for a default execution mode, as reloading is less stable and consumes more resources. It's better to default to reload=False and allow development tools or the CLI to enable it explicitly.

Suggested change
run_server(host="0.0.0.0", port=8000, reload=True)
run_server(host="0.0.0.0", port=8000, reload=False)

from pathlib import Path

# Add the current directory to the Python path
sys.path.insert(0, str(Path(__file__).parent))
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This script modifies sys.path to handle imports, which is an anti-pattern that can make the import system fragile and dependent on the execution context. For a more robust solution, this script should be run as a module from the project root (e.g., python -m hello_world_agent.client), and the sys.path manipulation should be removed.

DEMO_MODE = os.getenv("DEMO_MODE", "false").lower() == "true"

# Global storage for agents and sessions
active_agents: Dict[str, HelloWorldAgent] = {}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The type hint for active_agents is Dict[str, HelloWorldAgent], but in demo mode, instances of MockAgent are stored in this dictionary. This creates a type inconsistency. Using typing.Any or a Union type would make the type hint accurate and prevent potential issues with static analysis tools.

Suggested change
active_agents: Dict[str, HelloWorldAgent] = {}
active_agents: Dict[str, Any] = {}

Comment on lines +7 to +8
<script src="https://unpkg.com/[email protected]"></script>
<script src="https://unpkg.com/htmx.org/dist/ext/ws.js"></script>
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This HTML file includes the htmx library and its WebSocket extension. However, the custom JavaScript in the <script> tag at the bottom of the file implements all the chat logic using the native WebSocket API and does not use htmx at all. These included scripts are unused dependencies and should be removed to reduce page load time and complexity.

from pathlib import Path

# Add the parent directory to the Python path for imports
sys.path.insert(0, str(Path(__file__).parent.parent))
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Manually modifying sys.path in test files is an anti-pattern. A better practice is to run tests using a test runner like pytest from the project's root directory. This allows the runner to handle path resolution correctly, especially if the project is installed in editable mode (pip install -e .).

assert "Hello World agent" in instructions
assert "friendly" in instructions.lower()

@patch('hello_agent.AgentsClient')
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The targets for patch are specified as relative paths (e.g., 'hello_agent.AgentsClient'). This is fragile and depends on sys.path being configured in a specific way. It's best practice to use the fully qualified path of the object where it is being looked up. In this case, it should be 'hello_world_agent.hello_agent.AgentsClient'. This applies to the other patches in this test class as well.

@patch('hello_world_agent.hello_agent.AgentsClient')

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.

1 participant