Python: Refine samples and upgrade packages (#5261)

* Refine samples and upgrade pacakges

* Upgrade to a new package that fixes a bug

* Update model env var
This commit is contained in:
Tao Chen
2026-04-15 10:46:19 -07:00
committed by GitHub
Unverified
parent 0402b1aac4
commit 383a2afca2
42 changed files with 285 additions and 517 deletions
@@ -0,0 +1,2 @@
FOUNDRY_PROJECT_ENDPOINT="..."
MODEL_DEPLOYMENT_NAME="..."
@@ -1,12 +1,6 @@
# Basic example of hosting an agent with the `responses` API
## Running the server locally
Run the following command to start the server:
```bash
python main.py
```
This agent only contains an instruction (personal). It's the most basic agent with an LLM and no tools.
## Interacting with the agent
@@ -16,7 +10,11 @@ Send a POST request to the server with a JSON body containing a "message" field
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}'
```
The server will respond with a JSON object containing the response text and a response ID. You can use this response ID to continue the conversation in subsequent requests.
### Invoke with `azd`
```bash
azd ai agent invoke --local "Hi"
```
## Multi-turn conversation
@@ -26,10 +24,10 @@ To have a multi-turn conversation with the agent, include the previous response
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "How are you?", "previous_response_id": "REPLACE_WITH_PREVIOUS_RESPONSE_ID"}'
```
## Deploying to Foundry
Invoke with `azd`:
TODO
```bash
azd ai agent invoke --local "Hi!" --conversation-id "my_conv"
## Using the deployed agent in Agent Framework
TODO
azd ai agent invoke --local "How are you?" --conversation-id "my_conv"
```
@@ -3,6 +3,7 @@ description: >
A basic Agent Framework agent hosted by Foundry.
metadata:
tags:
- Agent Framework
- AI Agent Hosting
- Azure AI AgentServer
- Responses Protocol
@@ -12,4 +13,11 @@ template:
kind: hosted
protocols:
- protocol: responses
version: v0.1.0
version: 1.0.0
environment_variables:
- name: MODEL_DEPLOYMENT_NAME
value: "{{MODEL_DEPLOYMENT_NAME}}"
resources:
- kind: model
id: gpt-4.1-mini
name: MODEL_DEPLOYMENT_NAME
@@ -16,7 +16,7 @@ load_dotenv()
def main():
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
model=os.environ["MODEL_DEPLOYMENT_NAME"],
credential=AzureCliCredential(),
)
@@ -0,0 +1,2 @@
FOUNDRY_PROJECT_ENDPOINT="..."
MODEL_DEPLOYMENT_NAME="..."
@@ -1,13 +1,23 @@
# Basic example of hosting an agent with the `responses` API and local tools
Run the following command to start the server:
This agent is equipped with with a function tool and a local shell tool.
```bash
python main.py
```
> We recommend deploying this sample on a local container or to Foundry Hosting because the agent has access to a local shell tool, which can run arbitrary commands on the machine.
## Interacting with the agent
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
```bash
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "What is the weather in Seattle?"}'
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "List the files in the current directory."}'
```
Invoke with `azd`:
```bash
azd ai agent invoke --local "What is the weather in Seattle?"
azd ai agent invoke --local "List the files in the current directory."
```
@@ -1,8 +1,9 @@
name: agent-framework-agent-with-local-tools
description: >
An Agent Framework agent with local toolshosted by Foundry.
An Agent Framework agent with local tools hosted by Foundry.
metadata:
tags:
- Agent Framework
- AI Agent Hosting
- Azure AI AgentServer
- Responses Protocol
@@ -12,4 +13,11 @@ template:
kind: hosted
protocols:
- protocol: responses
version: v0.1.0
version: 1.0.0
environment_variables:
- name: MODEL_DEPLOYMENT_NAME
value: "{{MODEL_DEPLOYMENT_NAME}}"
resources:
- kind: model
id: gpt-4.1-mini
name: MODEL_DEPLOYMENT_NAME
@@ -1,6 +1,7 @@
# Copyright (c) Microsoft. All rights reserved.
import os
import subprocess
from random import randint
from agent_framework import Agent, tool
@@ -25,17 +26,41 @@ def get_weather(
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
@tool(approval_mode="always_require")
def run_bash(command: str) -> str:
"""Execute a shell command locally and return stdout, stderr, and exit code."""
try:
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
timeout=30,
)
parts: list[str] = []
if result.stdout:
parts.append(result.stdout)
if result.stderr:
parts.append(f"stderr: {result.stderr}")
parts.append(f"exit_code: {result.returncode}")
return "\n".join(parts)
except subprocess.TimeoutExpired:
return "Command timed out after 30 seconds"
except Exception as e:
return f"Error executing command: {e}"
def main():
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
model=os.environ["MODEL_DEPLOYMENT_NAME"],
credential=AzureCliCredential(),
)
agent = Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
tools=[get_weather],
tools=[get_weather, run_bash],
# History will be managed by the hosting infrastructure, thus there
# is no need to store history by the service. Learn more at:
# https://developers.openai.com/api/reference/resources/responses/methods/create
@@ -0,0 +1,4 @@
FOUNDRY_PROJECT_ENDPOINT="..."
MODEL_DEPLOYMENT_NAME="..."
FOUNDRY_AGENT_TOOLBOX_NAME="..."
GITHUB_PAT="..."
@@ -1,13 +1,19 @@
# Basic example of hosting an agent with the `responses` API and a remote MCP
Run the following command to start the server:
This agent is equipped with a GitHub MCP server and a Foundry Toolbox, which are both remote MCPs.
```bash
python main.py
```
> Note that there are other ways to interact with Foundry toolboxes. Using it as a MCP is just one of the options.
## Interacting with the agent
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
```bash
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "List all the repositories I own on GitHub."}'
```
Invoke with `azd`:
```bash
azd ai agent invoke --local "List all the repositories I own on GitHub."
```
@@ -3,6 +3,7 @@ description: >
An Agent Framework agent with remote MCP tools hosted by Foundry.
metadata:
tags:
- Agent Framework
- AI Agent Hosting
- Azure AI AgentServer
- Responses Protocol
@@ -12,4 +13,15 @@ template:
kind: hosted
protocols:
- protocol: responses
version: v0.1.0
version: 1.0.0
environment_variables:
- name: MODEL_DEPLOYMENT_NAME
value: "{{MODEL_DEPLOYMENT_NAME}}"
- name: GITHUB_PAT
value: ${GITHUB_PAT}
- name: FOUNDRY_AGENT_TOOLBOX_NAME
value: ${FOUNDRY_AGENT_TOOLBOX_NAME}
resources:
- kind: model
id: gpt-4.1-mini
name: MODEL_DEPLOYMENT_NAME
@@ -2,7 +2,8 @@
import os
from agent_framework import Agent
import httpx
from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.ai.agentserver.responses import InMemoryResponseProvider
@@ -13,14 +14,37 @@ from dotenv import load_dotenv
load_dotenv()
class ToolboxAuth(httpx.Auth):
"""httpx Auth that injects a fresh bearer token on every request."""
def auth_flow(self, request: httpx.Request):
credential = AzureCliCredential()
token = credential.get_token("https://ai.azure.com/.default").token
request.headers["Authorization"] = f"Bearer {token}"
yield request
def main():
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
model=os.environ["MODEL_DEPLOYMENT_NAME"],
credential=AzureCliCredential(),
)
github_pat = os.getenv("GITHUB_PAT")
# Foundry Toolbox as a MCP tool
project_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
toolbox_name = os.environ["FOUNDRY_AGENT_TOOLBOX_NAME"]
toolbox_endpoint = f"{project_endpoint.rstrip('/')}/toolboxes/{toolbox_name}/mcp?api-version=v1"
http_client = httpx.AsyncClient(auth=ToolboxAuth(), headers={"Foundry-Features": "Toolboxes=V1Preview"})
foundry_mcp_tool = MCPStreamableHTTPTool(
name="toolbox",
url=toolbox_endpoint,
http_client=http_client,
load_prompts=False,
)
# GitHub MCP server
github_pat = os.environ["GITHUB_PAT"]
if not github_pat:
raise ValueError(
"GITHUB_PAT environment variable must be set. Create a token at https://github.com/settings/tokens"
@@ -38,7 +62,7 @@ def main():
agent = Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
tools=[github_mcp_tool],
tools=[foundry_mcp_tool, github_mcp_tool],
# History will be managed by the hosting infrastructure, thus there
# is no need to store history by the service. Learn more at:
# https://developers.openai.com/api/reference/resources/responses/methods/create
@@ -0,0 +1,2 @@
FOUNDRY_PROJECT_ENDPOINT="..."
MODEL_DEPLOYMENT_NAME="..."
@@ -1,13 +1,17 @@
# Basic example of hosting an agent with the `responses` API and a workflow
Run the following command to start the server:
This sample demonstrates how to host a workflow using the `responses` API.
```bash
python main.py
```
## Interacting with the agent
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
```bash
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Create a slogan for a new electric SUV that is affordable and fun to drive."}'
```
Invoke with `azd`:
```bash
azd ai agent invoke --local "List all the repositories I own on GitHub."
```
@@ -3,6 +3,7 @@ description: >
An Agent Framework workflow hosted by Foundry.
metadata:
tags:
- Agent Framework
- AI Agent Hosting
- Azure AI AgentServer
- Responses Protocol
@@ -12,4 +13,11 @@ template:
kind: hosted
protocols:
- protocol: responses
version: v0.1.0
version: 1.0.0
environment_variables:
- name: MODEL_DEPLOYMENT_NAME
value: "{{MODEL_DEPLOYMENT_NAME}}"
resources:
- kind: model
id: gpt-4.1-mini
name: MODEL_DEPLOYMENT_NAME
@@ -24,7 +24,7 @@ def round_robin_selector(state: GroupChatState) -> str:
def main():
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
model=os.environ["MODEL_DEPLOYMENT_NAME"],
credential=AzureCliCredential(),
)
@@ -1,6 +0,0 @@
.venv
__pycache__
*.pyc
*.pyo
*.pyd
.Python
@@ -1,16 +0,0 @@
FROM python:3.12-slim
WORKDIR /app/user_agent
COPY wheels/ /tmp/wheels/
COPY requirements.txt .
RUN pip install --no-cache-dir --find-links /tmp/wheels/ -r requirements.txt && rm -rf /tmp/wheels/
COPY . .
RUN useradd -r appuser
USER appuser
EXPOSE 8088
CMD ["python", "main.py"]
@@ -1,43 +0,0 @@
# Agent Framework Agent with Local Shell
> Note: This agent can execute local shell commands. We recommend running it in an isolated environment for security reasons.
## Running the server in a Docker container
Build the Docker image:
```bash
docker build -t agent-framework-agent-with-local-shell .
```
Run the Docker container:
```bash
docker run -p 8088:8088 --env-file .env agent-framework-agent-with-local-shell
```
## Interacting with the agent
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
```bash
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}'
```
The server will respond with a JSON object containing the response text and a response ID. You can use this response ID to continue the conversation in subsequent requests.
## Multi-turn conversation
To have a multi-turn conversation with the agent, include the previous response id in the request body. For example:
```bash
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "How are you?", "previous_response_id": "REPLACE_WITH_PREVIOUS_RESPONSE_ID"}'
```
## Deploying to Foundry
TODO
## Using the deployed agent in Agent Framework
TODO
@@ -1,15 +0,0 @@
name: agent-framework-agent-with-local-shell
description: >
An Agent Framework agent that can execute local shell commands hosted by Foundry.
metadata:
tags:
- AI Agent Hosting
- Azure AI AgentServer
- Responses Protocol
- Streaming
template:
name: agent-framework-agent-with-local-shell
kind: hosted
protocols:
- protocol: responses
version: v0.1.0
@@ -1,8 +0,0 @@
kind: hosted
name: agent-framework-agent-with-local-shell
protocols:
- protocol: responses
version: v0.1.0
resources:
cpu: "0.25"
memory: 0.5Gi
@@ -1,63 +0,0 @@
# Copyright (c) Microsoft. All rights reserved.
import os
import subprocess
from agent_framework import Agent, tool
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.ai.agentserver.responses import InMemoryResponseProvider
from azure.identity import AzureCliCredential
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
@tool(approval_mode="always_require")
def run_bash(command: str) -> str:
"""Execute a shell command locally and return stdout, stderr, and exit code."""
try:
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
timeout=30,
)
parts: list[str] = []
if result.stdout:
parts.append(result.stdout)
if result.stderr:
parts.append(f"stderr: {result.stderr}")
parts.append(f"exit_code: {result.returncode}")
return "\n".join(parts)
except subprocess.TimeoutExpired:
return "Command timed out after 30 seconds"
except Exception as e:
return f"Error executing command: {e}"
def main():
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
credential=AzureCliCredential(),
)
agent = Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
tools=[run_bash],
# History will be managed by the hosting infrastructure, thus there
# is no need to store history by the service. Learn more at:
# https://developers.openai.com/api/reference/resources/responses/methods/create
default_options={"store": False},
)
server = ResponsesHostServer(agent, store=InMemoryResponseProvider())
server.run()
if __name__ == "__main__":
main()
@@ -1,2 +0,0 @@
agent-framework-core
agent-framework-foundry-hosting
@@ -1,6 +0,0 @@
.venv
__pycache__
*.pyc
*.pyo
*.pyd
.Python
@@ -1,16 +0,0 @@
FROM python:3.12-slim
WORKDIR /app
COPY . user_agent/
WORKDIR /app/user_agent
RUN if [ -f requirements.txt ]; then \
pip install -r requirements.txt; \
else \
echo "No requirements.txt found"; \
fi
EXPOSE 8088
CMD ["python", "main.py"]
@@ -1,35 +0,0 @@
# Agent Framework Agent with Evaluation
## Running the server locally
Run the following command to start the server:
```bash
python main.py
```
## Interacting with the agent
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
```bash
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}'
```
The server will respond with a JSON object containing the response text and a response ID. You can use this response ID to continue the conversation in subsequent requests.
## Multi-turn conversation
To have a multi-turn conversation with the agent, include the previous response id in the request body. For example:
```bash
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "How are you?", "previous_response_id": "REPLACE_WITH_PREVIOUS_RESPONSE_ID"}'
```
## Deploying to Foundry
TODO
## Using the deployed agent in Agent Framework
TODO
@@ -1,15 +0,0 @@
name: agent-framework-agent-with-eval
description: >
An Agent Framework agent is evaluated on each response hosted by Foundry.
metadata:
tags:
- AI Agent Hosting
- Azure AI AgentServer
- Responses Protocol
- Streaming
template:
name: agent-framework-agent-with-eval
kind: hosted
protocols:
- protocol: responses
version: v0.1.0
@@ -1,8 +0,0 @@
kind: hosted
name: agent-framework-agent-with-eval
protocols:
- protocol: responses
version: v0.1.0
resources:
cpu: "0.25"
memory: 0.5Gi
@@ -1,50 +0,0 @@
# Copyright (c) Microsoft. All rights reserved.
import os
from random import randint
from agent_framework import Agent, tool
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.ai.agentserver.responses import InMemoryResponseProvider
from azure.identity import AzureCliCredential
from dotenv import load_dotenv
from pydantic import Field
from typing_extensions import Annotated
# Load environment variables from .env file
load_dotenv()
@tool(approval_mode="never_require")
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
def main():
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
credential=AzureCliCredential(),
)
agent = Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
tools=[get_weather],
# History will be managed by the hosting infrastructure, thus there
# is no need to store history by the service. Learn more at:
# https://developers.openai.com/api/reference/resources/responses/methods/create
default_options={"store": False},
)
server = ResponsesHostServer(agent, store=InMemoryResponseProvider())
server.run()
if __name__ == "__main__":
main()
@@ -1,2 +0,0 @@
agent-framework
agent-framework-foundry-hosting
@@ -1,6 +0,0 @@
.venv
__pycache__
*.pyc
*.pyo
*.pyd
.Python
@@ -1,16 +0,0 @@
FROM python:3.12-slim
WORKDIR /app
COPY . user_agent/
WORKDIR /app/user_agent
RUN if [ -f requirements.txt ]; then \
pip install -r requirements.txt; \
else \
echo "No requirements.txt found"; \
fi
EXPOSE 8088
CMD ["python", "main.py"]
@@ -1,35 +0,0 @@
# Agent Framework Agent with Foundry Memory
## Running the server locally
Run the following command to start the server:
```bash
python main.py
```
## Interacting with the agent
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
```bash
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}'
```
The server will respond with a JSON object containing the response text and a response ID. You can use this response ID to continue the conversation in subsequent requests.
## Multi-turn conversation
To have a multi-turn conversation with the agent, include the previous response id in the request body. For example:
```bash
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "How are you?", "previous_response_id": "REPLACE_WITH_PREVIOUS_RESPONSE_ID"}'
```
## Deploying to Foundry
TODO
## Using the deployed agent in Agent Framework
TODO
@@ -1,15 +0,0 @@
name: agent-framework-agent-with-foundry-memory
description: >
An Agent Framework agent with memory support hosted by Foundry.
metadata:
tags:
- AI Agent Hosting
- Azure AI AgentServer
- Responses Protocol
- Streaming
template:
name: agent-framework-agent-with-foundry-memory
kind: hosted
protocols:
- protocol: responses
version: v0.1.0
@@ -1,8 +0,0 @@
kind: hosted
name: agent-framework-agent-with-foundry-memory
protocols:
- protocol: responses
version: v0.1.0
resources:
cpu: "0.25"
memory: 0.5Gi
@@ -1,91 +0,0 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import logging
import os
from datetime import datetime, timezone
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryMemoryProvider
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.ai.agentserver.responses import InMemoryResponseProvider
from azure.ai.projects.aio import AIProjectClient
from azure.ai.projects.models import (
MemoryStoreDefaultDefinition,
MemoryStoreDefaultOptions,
)
from azure.identity import AzureCliCredential
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
logging.basicConfig(level=logging.INFO)
async def _create_memory_store(project_client: AIProjectClient) -> FoundryMemoryProvider:
memory_store_name = f"hosted_agent_memory_{datetime.now(timezone.utc).strftime('%Y%m%d')}"
options = MemoryStoreDefaultOptions(
chat_summary_enabled=True,
user_profile_enabled=True,
user_profile_details=(
"Avoid irrelevant or sensitive data, such as age, financials, precise location, and credentials"
),
)
memory_store_definition = MemoryStoreDefaultDefinition(
chat_model=os.environ["FOUNDRY_MODEL"],
embedding_model=os.environ["AZURE_OPENAI_EMBEDDING_MODEL"],
options=options,
)
memory_store = await project_client.beta.memory_stores.create(
name=memory_store_name,
description="Memory store for Agent Framework with FoundryMemoryProvider",
definition=memory_store_definition,
)
return FoundryMemoryProvider(
project_client=project_client,
memory_store_name=memory_store.name,
# Scope memories to a specific user, if not set, the session_id
# will be used as scope, which means memories are only shared within the same session
scope="demo",
# Do not wait to update memories after each interaction (for demo purposes)
# In production, consider setting a delay to batch updates and reduce costs
update_delay=0,
)
async def _delete_memory_store(project_client: AIProjectClient, memory_store_name: str):
await project_client.beta.memory_stores.delete(name=memory_store_name)
async def main():
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
credential=AzureCliCredential(),
)
# Create the memory store
memory_provider = await _create_memory_store(client.project_client)
agent = Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
context_providers=[memory_provider],
# History will be managed by the hosting infrastructure, thus there
# is no need to store history by the service. Learn more at:
# https://developers.openai.com/api/reference/resources/responses/methods/create
default_options={"store": False},
)
server = ResponsesHostServer(agent, store=InMemoryResponseProvider())
try:
await server.run_async()
finally:
await _delete_memory_store(client.project_client, memory_provider.memory_store_name)
if __name__ == "__main__":
asyncio.run(main())
@@ -1,2 +0,0 @@
agent-framework
agent-framework-foundry-hosting
@@ -0,0 +1,65 @@
# Hosting agents with Foundry Hosting and the `responses` API
This folder contains a list of samples that show how to host agents using the `responses` API and deploy them to Foundry Hosting.
| Sample | Description |
| --- | --- |
| [01_basic](./01_basic) | A basic example of hosting an agent with the `responses` API and carrying on a multi-turn conversation. |
| [02_local_tools](./02_local_tools) | An example of hosting an agent with the `responses` API and local tools including a function tool and a local shell tool. |
| [03_remote_mcp](./03_remote_mcp) | An example of hosting an agent with the `responses` API and remote MCPs, including a GitHub MCP server and a Foundry Toolboox. |
| [04_workflows](./04_workflows) | An example of hosting a workflow with the `responses` API. |
## Running the server locally
Navigate to the sample directory and run the following command to start the server:
```bash
python main.py
```
## Interacting with the agent
There two ways to interact with the agent: sending HTTP requests to the server or using the `azd` CLI:
### Invoke with `azd`
```bash
azd ai agent invoke --local "Hi"
```
### Sending HTTP requests
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
```bash
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}'
```
> See the individual samples for more examples of interacting with the agent.
## Deploying to a Docker container
Navigate to the sample directory and build the Docker image:
```bash
docker build -t hosted-agent-sample .
```
Run the container, passing in the required environment variables:
```bash
docker run -p 8088:8088 \
-e FOUNDRY_PROJECT_ENDPOINT=<your-endpoint> \
-e FOUNDRY_MODEL=<your-model> \
hosted-agent-sample
```
The server will be available at `http://localhost:8088`. You can send requests using the same `curl` command shown above.
## Deploying to Foundry
TODO
## Using the deployed agent in Agent Framework
After deploying the agent, you can also try to use the agent in Agent Framework. Refer to the [using_deployed_agent.py](./using_deployed_agent.py) sample for an example of how to do this.
@@ -0,0 +1,50 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import Agent, AgentResponse, AgentResponseUpdate, ResponseStream
from agent_framework.openai import OpenAIChatClient
from typing_extensions import Any
"""
This script demonstrates how to talk to a deployed agent using the OpenAIChatClient.
Depending on where you have deployed your agent (local or Foundry Hosting), you may
need to change the base_url when initializing the OpenAIChatClient.
"""
async def print_streaming_response(streaming_response: ResponseStream[AgentResponseUpdate, AgentResponse[Any]]) -> None:
async for chunk in streaming_response:
if chunk.text:
print(chunk.text, end="", flush=True)
async def main() -> None:
agent = Agent(client=OpenAIChatClient(base_url="http://localhost:8088"))
session = agent.create_session()
# First turn
query = "Hi!"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
streaming_response = agent.run(query, session=session, stream=True)
await print_streaming_response(streaming_response)
# Second turn
query = "You name is Javis. What can you do?"
print(f"\nUser: {query}")
print("Agent: ", end="", flush=True)
streaming_response = agent.run(query, session=session, stream=True)
await print_streaming_response(streaming_response)
# Third turn
query = "What is your name?"
print(f"\nUser: {query}")
print("Agent: ", end="", flush=True)
streaming_response = agent.run(query, session=session, stream=True)
await print_streaming_response(streaming_response)
if __name__ == "__main__":
asyncio.run(main())