From 3eaa5a27b10eab88607da3c1a70ff14f11cace28 Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 8 Apr 2026 10:21:35 +0000 Subject: [PATCH 1/3] docs: Add clarifying documentation for FoundryAgent vs FoundryChatClient Add documentation explaining when to use FoundryAgent (connecting to existing Foundry agents) vs FoundryChatClient (direct model access). This addresses the confusion raised in issue #5160. --- docs/features/foundry/README.md | 120 ++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 docs/features/foundry/README.md diff --git a/docs/features/foundry/README.md b/docs/features/foundry/README.md new file mode 100644 index 0000000000..103b4b0b1b --- /dev/null +++ b/docs/features/foundry/README.md @@ -0,0 +1,120 @@ +# Azure AI Foundry Integration + +## Overview + +The Agent Framework provides two primary integration points for Azure AI Foundry: + +| Class | Purpose | When to Use | +| --- | --- | --- | +| `FoundryAgent` / `RawFoundryAgent` | Connect to **existing** Foundry agents | When you want to use an agent that's already configured in Foundry (PromptAgent or HostedAgent) | +| `FoundryChatClient` / `RawFoundryChatClient` | Create a chat client for **model deployments** | When you want direct chat access to a model through Foundry without using a pre-configured agent | + +## Key Differences + +### FoundryAgent — Connect to Existing Agents + +Use `FoundryAgent` (recommended) or `RawFoundryAgent` when: + +- You have an existing **PromptAgent** or **HostedAgent** in Foundry +- You want the agent's predefined behavior, tools, and instructions +- You need middleware, telemetry, and function invocation support + +**Required parameters:** +- `project_endpoint` — The Foundry project endpoint URL +- `agent_name` — The name of the existing Foundry agent to connect to +- `agent_version` — Required for PromptAgents, optional for HostedAgents +- `credential` — Azure credential for authentication + +**Example:** +```python +from agent_framework.foundry import FoundryAgent +from azure.identity import AzureCliCredential + +# Connect to a PromptAgent +agent = FoundryAgent( + project_endpoint="https://your-project.services.ai.azure.com", + agent_name="my-prompt-agent", + agent_version="1.0", + credential=AzureCliCredential(), +) +result = await agent.run("Hello!") + +# Connect to a HostedAgent (no version needed) +agent = FoundryAgent( + project_endpoint="https://your-project.services.ai.azure.com", + agent_name="my-hosted-agent", + credential=AzureCliCredential(), +) +``` + +### FoundryChatClient — Direct Model Access + +Use `FoundryChatClient` (recommended) or `RawFoundryChatClient` when: + +- You want to chat directly with a model deployment through Foundry +- You don't need a pre-configured agent — you provide the instructions +- You want full control over the chat interaction + +**Required parameters:** +- `project_endpoint` — The Foundry project endpoint URL +- `model` — The model deployment name +- `credential` — Azure credential for authentication + +**Example:** +```python +from agent_framework.foundry import FoundryChatClient +from azure.identity import AzureCliCredential + +client = FoundryChatClient( + project_endpoint="https://your-project.services.ai.azure.com", + model="gpt-4o", + credential=AzureCliCredential(), +) + +response = await client.complete(messages=["Hello!"]) +print(response.message.content) +``` + +## When to Use Each + +| Scenario | Recommended Class | +| --- | --- | +| Use a PromptAgent configured in Foundry with specific instructions, tools, and behavior | `FoundryAgent` | +| Use a HostedAgent (custom runtime agent) in Foundry | `FoundryAgent` | +| Chat directly with a model deployment without an agent wrapper | `FoundryChatClient` | +| Build a custom agent experience with your own instructions | `FoundryChatClient` + `Agent` | +| Need full middleware/telemetry support | Use `FoundryAgent` or `FoundryChatClient` (not raw variants) | +| Need minimal overhead, custom client subclass | Use `RawFoundryAgent` or `RawFoundryChatClient` | + +## Raw vs. Recommended Variants + +Each class has both a **raw** and **recommended** variant: + +| Recommended | Raw | Description | +| --- | --- | --- | +| `FoundryAgent` | `RawFoundryAgent` | Agent wrapper with full middleware and telemetry | +| `FoundryChatClient` | `RawFoundryChatClient` | Chat client with full middleware and telemetry | + +The raw variants (`RawFoundryAgent`, `RawFoundryChatClient`) omit: +- Chat or agent middleware layers +- Telemetry (OpenTelemetry) +- Function invocation support + +Use raw variants when you need to build a custom client with specific middleware layers via subclassing. + +## Environment Variables + +Both integrations support environment variable configuration: + +| Variable | Used By | Description | +| --- | --- | --- | +| `FOUNDRY_PROJECT_ENDPOINT` | Both | Foundry project endpoint URL | +| `FOUNDRY_AGENT_NAME` | `FoundryAgent` | Name of the Foundry agent | +| `FOUNDRY_AGENT_VERSION` | `FoundryAgent` | Version of the agent (PromptAgents) | +| `FOUNDRY_MODEL` | `FoundryChatClient` | Model deployment name | + +## Packages + +| Package | Source | +| --- | --- | +| `agent-framework-foundry` | [`python/packages/foundry`](../../../python/packages/foundry) | \ No newline at end of file From 28533cdbb57315b2c68f4573fcf21f367c7fb98f Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 8 Apr 2026 10:34:38 +0000 Subject: [PATCH 2/3] docs: Fix method name in FoundryChatClient example Use get_response() instead of complete() which is the correct method name from the base client class. --- docs/features/foundry/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/foundry/README.md b/docs/features/foundry/README.md index 103b4b0b1b..6cf775a7b9 100644 --- a/docs/features/foundry/README.md +++ b/docs/features/foundry/README.md @@ -71,7 +71,7 @@ client = FoundryChatClient( credential=AzureCliCredential(), ) -response = await client.complete(messages=["Hello!"]) +response = await client.get_response(messages=["Hello!"]) print(response.message.content) ``` From af9f22694e88ef054b3c64c33f7eb41e37828509 Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 8 Apr 2026 10:44:40 +0000 Subject: [PATCH 3/3] docs: Fix Copilot review comments - Fix FoundryChatClient example to use Message objects and response.text - Separate usage guidance for RawFoundryAgent and RawFoundryChatClient - Update Raw vs Recommended section to clarify actual layering - Fix scenario table to reference client_type parameter for raw agent --- docs/features/foundry/README.md | 40 ++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/docs/features/foundry/README.md b/docs/features/foundry/README.md index 6cf775a7b9..5d8ca52c0a 100644 --- a/docs/features/foundry/README.md +++ b/docs/features/foundry/README.md @@ -13,11 +13,16 @@ The Agent Framework provides two primary integration points for Azure AI Foundry ### FoundryAgent — Connect to Existing Agents -Use `FoundryAgent` (recommended) or `RawFoundryAgent` when: +Use `FoundryAgent` (recommended) when: - You have an existing **PromptAgent** or **HostedAgent** in Foundry - You want the agent's predefined behavior, tools, and instructions -- You need middleware, telemetry, and function invocation support +- You need agent-level middleware, telemetry, and function invocation support + +Use `RawFoundryAgent` when: + +- You want the lower-level agent wrapper without agent-level middleware/telemetry layers +- You want to provide a custom client via `client_type` parameter **Required parameters:** - `project_endpoint` — The Foundry project endpoint URL @@ -49,11 +54,17 @@ agent = FoundryAgent( ### FoundryChatClient — Direct Model Access -Use `FoundryChatClient` (recommended) or `RawFoundryChatClient` when: +Use `FoundryChatClient` (recommended) when: - You want to chat directly with a model deployment through Foundry - You don't need a pre-configured agent — you provide the instructions - You want full control over the chat interaction +- You need chat middleware, telemetry, and function invocation support + +Use `RawFoundryChatClient` when: + +- You want the lower-level chat client without wrapper layers +- You want to build a custom client via subclassing **Required parameters:** - `project_endpoint` — The Foundry project endpoint URL @@ -62,6 +73,7 @@ Use `FoundryChatClient` (recommended) or `RawFoundryChatClient` when: **Example:** ```python +from agent_framework import Message from agent_framework.foundry import FoundryChatClient from azure.identity import AzureCliCredential @@ -71,8 +83,8 @@ client = FoundryChatClient( credential=AzureCliCredential(), ) -response = await client.get_response(messages=["Hello!"]) -print(response.message.content) +response = await client.get_response(messages=[Message(user_content="Hello!")]) +print(response.text) ``` ## When to Use Each @@ -84,7 +96,7 @@ print(response.message.content) | Chat directly with a model deployment without an agent wrapper | `FoundryChatClient` | | Build a custom agent experience with your own instructions | `FoundryChatClient` + `Agent` | | Need full middleware/telemetry support | Use `FoundryAgent` or `FoundryChatClient` (not raw variants) | -| Need minimal overhead, custom client subclass | Use `RawFoundryAgent` or `RawFoundryChatClient` | +| Need minimal overhead, custom client subclass | Use `RawFoundryChatClient`, or for agent connections provide a raw agent chat client via `client_type=RawFoundryAgentChatClient` | ## Raw vs. Recommended Variants @@ -92,15 +104,17 @@ Each class has both a **raw** and **recommended** variant: | Recommended | Raw | Description | | --- | --- | --- | -| `FoundryAgent` | `RawFoundryAgent` | Agent wrapper with full middleware and telemetry | -| `FoundryChatClient` | `RawFoundryChatClient` | Chat client with full middleware and telemetry | +| `FoundryAgent` | `RawFoundryAgent` | Connects to an existing Foundry agent, but without the additional **agent-level** middleware and telemetry layers that `FoundryAgent` adds | +| `FoundryChatClient` | `RawFoundryChatClient` | Chat client variant without the recommended wrapper's middleware and telemetry layers | + +The raw variants are lower-level building blocks, but they are not identical: + +- `RawFoundryAgent` still defaults to an internal client stack that includes function invocation, chat middleware, and chat telemetry. Compared to `FoundryAgent`, it omits the extra **agent-level** middleware and telemetry layers. +- `RawFoundryChatClient` is the lower-level chat client variant when you do not want the recommended wrapper layers. -The raw variants (`RawFoundryAgent`, `RawFoundryChatClient`) omit: -- Chat or agent middleware layers -- Telemetry (OpenTelemetry) -- Function invocation support +If you truly need a raw Foundry agent chat client, use `client_type=RawFoundryAgentChatClient`. -Use raw variants when you need to build a custom client with specific middleware layers via subclassing. +Use raw variants when you need lower-level control or want to build a custom client composition via subclassing. ## Environment Variables