Skip to content

Python: Add more types - #5377

Closed
Tao Chen (TaoChenOSU) wants to merge 13 commits into
mainfrom
taochen/python-foundry-hosted-agent-add-more-types
Closed

Python: Add more types#5377
Tao Chen (TaoChenOSU) wants to merge 13 commits into
mainfrom
taochen/python-foundry-hosted-agent-add-more-types

Conversation

@TaoChenOSU

Copy link
Copy Markdown
Contributor

Motivation and Context

Description

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

* Experiment

* Update dependency and add non streaming

* Add more samples

* Rename samples

* Add invocations

* Comments 1

* Comments 2

* Comments 3

* Improve README

* Add local shell sample

* WIP: Add eval and memory samples

* Update user agent prefix

* Update user agent prefix doc
* Add tests

* fix tests and sample

* Fix formatting

* Remove function approval contents
* Refine samples and upgrade pacakges

* Upgrade to a new package that fixes a bug

* Update model env var
* Upgrade agentserver packages

* Fix new types
* Add special handling for workflows

* Address comments
Copilot AI review requested due to automatic review settings April 21, 2026 00:44
@moonbox3 Evan Mattson (moonbox3) added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python labels Apr 21, 2026
@github-actions github-actions Bot changed the title Add more types Python: Add more types Apr 21, 2026
@moonbox3

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework
   _telemetry.py28196%81
packages/foundry_hosting/agent_framework_foundry_hosting
   _invocations.py342429%34, 36–37, 39–42, 46–47, 49–55, 57, 59, 61–63, 65, 71–72
   _responses.py43614267%129–130, 139–140, 144, 149, 171–173, 193–195, 210–212, 223–225, 245–246, 248–250, 252–254, 258–261, 264–269, 276, 281, 284, 290–291, 293–294, 296, 298, 300–303, 305–307, 310, 314, 316–323, 326–327, 329–331, 339–344, 416–417, 522–523, 545, 809–811, 813, 831–860, 862, 880, 883, 918–922, 926–932, 939–943, 949–955, 962, 968, 971
TOTAL28945347088% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
5730 30 💤 0 ❌ 0 🔥 1m 35s ⏱️

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 expands the Python side of the Agent Framework repo by adding a new Foundry Hosting integration package, updating core telemetry User-Agent handling, and replacing older “hosted agent” end-to-end samples with a new set of Foundry Hosted Agents samples (Responses + Invocations).

Changes:

  • Add new agent-framework-foundry-hosting package (ResponsesHostServer / InvocationsHostServer) plus HTTP round-trip tests for Responses.
  • Update core telemetry to support adding hosting-layer prefixes to the framework User-Agent.
  • Restructure hosting samples: remove older 05-end-to-end/hosted_agents/* samples and add new 04-hosting/foundry-hosted-agents/* sample set (code + manifests + Docker assets).

Reviewed changes

Copilot reviewed 81 out of 85 changed files in this pull request and generated 29 comments.

Show a summary per file
File Description
python/uv.lock Adds workspace member and locks new Foundry Hosting/Azure AgentServer dependencies.
python/pyproject.toml Registers agent-framework-foundry-hosting as a workspace package.
python/.cspell.json Adds agentserver to spellchecker dictionary.
python/packages/core/agent_framework/_telemetry.py Adds support for User-Agent prefix stacking for hosting layers.
python/packages/foundry_hosting/pyproject.toml New package metadata, dependencies, and test/tooling configuration.
python/packages/foundry_hosting/agent_framework_foundry_hosting/init.py Exposes ResponsesHostServer and InvocationsHostServer.
python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py Implements Responses API hosting bridge and content/event conversions.
python/packages/foundry_hosting/agent_framework_foundry_hosting/_invocations.py Implements Invocations API hosting bridge.
python/packages/foundry_hosting/tests/test_responses.py Adds comprehensive HTTP round-trip tests for ResponsesHostServer.
python/packages/foundry_hosting/README.md Introduces package README (currently placeholder content).
python/packages/foundry_hosting/LICENSE Adds MIT license for the new package.
python/samples/04-hosting/foundry-hosted-agents/README.md New top-level README for Foundry Hosted Agents samples.
python/samples/04-hosting/foundry-hosted-agents/responses/README.md Adds Responses API sample index + “using_deployed_agent.py” helper script.
python/samples/04-hosting/foundry-hosted-agents/responses/using_deployed_agent.py Demonstrates calling a deployed agent via OpenAIChatClient.
python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/requirements.txt Sample requirements for basic Responses-hosted agent.
python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/main.py Basic Responses-hosted agent server sample.
python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/agent.yaml Hosted agent definition for Responses basic sample.
python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/agent.manifest.yaml Deployable manifest for Responses basic sample.
python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/README.md How-to for the Responses basic sample.
python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/Dockerfile Container build for the Responses basic sample.
python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/.env.example Example env vars for the Responses basic sample.
python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/.dockerignore Build context excludes for the Responses basic sample.
python/samples/04-hosting/foundry-hosted-agents/responses/02_local_tools/requirements.txt Sample requirements for Responses + local tools.
python/samples/04-hosting/foundry-hosted-agents/responses/02_local_tools/main.py Responses-hosted agent demonstrating local tools (incl. shell tool).
python/samples/04-hosting/foundry-hosted-agents/responses/02_local_tools/agent.yaml Hosted agent definition for local tools sample.
python/samples/04-hosting/foundry-hosted-agents/responses/02_local_tools/agent.manifest.yaml Deployable manifest for local tools sample.
python/samples/04-hosting/foundry-hosted-agents/responses/02_local_tools/README.md How-to for local tools sample.
python/samples/04-hosting/foundry-hosted-agents/responses/02_local_tools/Dockerfile Container build for local tools sample.
python/samples/04-hosting/foundry-hosted-agents/responses/02_local_tools/.env.example Example env vars for local tools sample.
python/samples/04-hosting/foundry-hosted-agents/responses/02_local_tools/.dockerignore Build context excludes for local tools sample.
python/samples/04-hosting/foundry-hosted-agents/responses/03_remote_mcp/requirements.txt Sample requirements for Responses + remote MCP tools.
python/samples/04-hosting/foundry-hosted-agents/responses/03_remote_mcp/main.py Responses-hosted agent demonstrating Foundry toolbox MCP + GitHub MCP.
python/samples/04-hosting/foundry-hosted-agents/responses/03_remote_mcp/agent.yaml Hosted agent definition for remote MCP sample.
python/samples/04-hosting/foundry-hosted-agents/responses/03_remote_mcp/agent.manifest.yaml Deployable manifest for remote MCP sample.
python/samples/04-hosting/foundry-hosted-agents/responses/03_remote_mcp/README.md How-to for remote MCP sample.
python/samples/04-hosting/foundry-hosted-agents/responses/03_remote_mcp/Dockerfile Container build for remote MCP sample.
python/samples/04-hosting/foundry-hosted-agents/responses/03_remote_mcp/.env.example Example env vars for remote MCP sample.
python/samples/04-hosting/foundry-hosted-agents/responses/03_remote_mcp/.dockerignore Build context excludes for remote MCP sample.
python/samples/04-hosting/foundry-hosted-agents/responses/04_workflows/requirements.txt Sample requirements for Responses-hosted workflow.
python/samples/04-hosting/foundry-hosted-agents/responses/04_workflows/main.py Responses-hosted workflow sample using Agent Framework workflows.
python/samples/04-hosting/foundry-hosted-agents/responses/04_workflows/agent.yaml Hosted agent definition for workflow sample.
python/samples/04-hosting/foundry-hosted-agents/responses/04_workflows/agent.manifest.yaml Deployable manifest for workflow sample.
python/samples/04-hosting/foundry-hosted-agents/responses/04_workflows/README.md How-to for workflow sample.
python/samples/04-hosting/foundry-hosted-agents/responses/04_workflows/Dockerfile Container build for workflow sample.
python/samples/04-hosting/foundry-hosted-agents/responses/04_workflows/.env.example Example env vars for workflow sample.
python/samples/04-hosting/foundry-hosted-agents/responses/04_workflows/.dockerignore Build context excludes for workflow sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/README.md Adds Invocations API sample index.
python/samples/04-hosting/foundry-hosted-agents/invocations/01_basic/requirements.txt Sample requirements for basic Invocations-hosted agent.
python/samples/04-hosting/foundry-hosted-agents/invocations/01_basic/main.py Basic Invocations-hosted agent server sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/01_basic/agent.yaml Hosted agent definition for Invocations basic sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/01_basic/agent.manifest.yaml Deployable manifest for Invocations basic sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/01_basic/README.md How-to for Invocations basic sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/01_basic/Dockerfile Container build for Invocations basic sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/01_basic/.env.example Example env vars for Invocations basic sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/01_basic/.dockerignore Build context excludes for Invocations basic sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/02_break_glass/requirements.txt Sample requirements for Invocations “break glass” scenario.
python/samples/04-hosting/foundry-hosted-agents/invocations/02_break_glass/main.py Invocations sample with custom invoke handler and session store.
python/samples/04-hosting/foundry-hosted-agents/invocations/02_break_glass/agent.yaml Hosted agent definition for “break glass” sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/02_break_glass/agent.manifest.yaml Deployable manifest for “break glass” sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/02_break_glass/README.md How-to for “break glass” sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/02_break_glass/Dockerfile Container build for “break glass” sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/02_break_glass/.env.example Example env vars for “break glass” sample.
python/samples/04-hosting/foundry-hosted-agents/invocations/02_break_glass/.dockerignore Build context excludes for “break glass” sample.
python/samples/05-end-to-end/hosted_agents/README.md Removes older hosted agent sample index under 05-end-to-end.
python/samples/05-end-to-end/hosted_agents/agents_in_workflow/requirements.txt Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agents_in_workflow/main.py Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agents_in_workflow/agent.yaml Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_text_search_rag/requirements.txt Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_text_search_rag/main.py Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_text_search_rag/agent.yaml Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_local_tools/requirements.txt Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_local_tools/main.py Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_local_tools/agent.yaml Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_local_tools/README.md Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_local_tools/.env.sample Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_local_tools/.dockerignore Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_hosted_mcp/requirements.txt Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_hosted_mcp/main.py Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/agent_with_hosted_mcp/agent.yaml Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/writer_reviewer_agents_in_workflow/requirements.txt Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/writer_reviewer_agents_in_workflow/main.py Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/writer_reviewer_agents_in_workflow/agent.yaml Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/writer_reviewer_agents_in_workflow/README.md Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/writer_reviewer_agents_in_workflow/.env.sample Removes older end-to-end hosted agent sample assets.
python/samples/05-end-to-end/hosted_agents/writer_reviewer_agents_in_workflow/.dockerignore Removes older end-to-end hosted agent sample assets.

Comment on lines +21 to +22
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

This README says requests should include a JSON body with a "message" field, but the Responses API (and the curl examples below) uses the "input" field. Please update the text to avoid confusing users.

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +43
# Foundry Toolbox as a MCP tool
project_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
toolbox_name = os.environ["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,
)

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

http_client = httpx.AsyncClient(...) is created but never closed. Since this sample runs as a long-lived server, this can leak connections/resources; consider using a lifespan/shutdown hook to aclose() the client or manage it with an async context manager.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,2 @@
FOUNDRY_PROJECT_ENDPOINT= "..."

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

There is an extra space after = in FOUNDRY_PROJECT_ENDPOINT= "...", which can result in the value containing a leading space depending on the dotenv parser. Please remove the extra space (and keep quoting consistent with the other examples).

Suggested change
FOUNDRY_PROJECT_ENDPOINT= "..."
FOUNDRY_PROJECT_ENDPOINT="..."

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +36
query = "You name is Javis. What can you do?"
print(f"\nUser: {query}")

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

The sample prompt has a grammatical typo: "You name is ..." should be "Your name is ..." (and confirm whether the intended name is "Jarvis"). This is user-facing sample text and will be copied verbatim by readers.

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +69
if stream:

async def stream_response() -> AsyncGenerator[str]:
async for update in self._agent.run(user_message, session=session, stream=True):
yield update.text

return StreamingResponse(
stream_response(),
media_type="text/event-stream",
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"},
)

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

The streaming path sets media_type="text/event-stream" but yields raw text chunks (update.text) without SSE framing (data: ...\n\n). If clients interpret this as SSE, they may fail to parse the stream. Consider either formatting each chunk as a proper SSE event, or change the content-type to text/plain/chunked text if SSE isn’t intended.

Copilot uses AI. Check for mistakes.
```bash
docker run -p 8088:8088 \
-e FOUNDRY_PROJECT_ENDPOINT=<your-endpoint> \
-e FOUNDRY_MODEL=<your-model> \

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

The top-level README uses FOUNDRY_MODEL in the docker run example, but the samples’ code (and .env.example files) expect MODEL_DEPLOYMENT_NAME. Please align the documented env var names to what the code actually reads to avoid startup failures.

Suggested change
-e FOUNDRY_MODEL=<your-model> \
-e MODEL_DEPLOYMENT_NAME=<your-model> \

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +21
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:

```bash

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

This README says requests should include a JSON body with a "message" field, but the Responses API (and the curl example below) uses the "input" field. Please update the text to avoid confusing users.

Copilot uses AI. Check for mistakes.
| Sample | Description |
| --- | --- |
| [01_basic](./01_basic) | A basic example of hosting an agent with the `invocations` API and carrying on a multi-turn conversation. |
| [02_break_glass](./02-break-glass) | An example of hosting an agent with the `invocations` API and a "break glass" scenario where you can create your own `invoke_handler` to handle specific types of invocations. |

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

The link target uses ./02-break-glass, but the folder added in this PR is 02_break_glass. Please update the README link so it resolves correctly.

Suggested change
| [02_break_glass](./02-break-glass) | An example of hosting an agent with the `invocations` API and a "break glass" scenario where you can create your own `invoke_handler` to handle specific types of invocations. |
| [02_break_glass](./02_break_glass) | An example of hosting an agent with the `invocations` API and a "break glass" scenario where you can create your own `invoke_handler` to handle specific types of invocations. |

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +11
# Foundry Hosting

This package provides the integration of Agent Framework agents and workflows with the Foundry Agent Server, which can be hosted on Foundry infrastructure.

## Responses

TODO

## Invocations

TODO

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

This package README still contains placeholder "TODO" sections. Since this is a new published workspace package, please replace the TODOs with at least minimal usage examples (how to host an agent via ResponsesHostServer/InvocationsHostServer) and any required environment variables.

Copilot uses AI. Check for mistakes.
Comment on lines +162 to +170
async def _handler(
self,
request: CreateResponse,
context: ResponseContext,
cancellation_signal: asyncio.Event,
) -> AsyncIterable[ResponseStreamEvent | dict[str, Any]]:
"""Handle the creation of a response."""
if self._is_workflow_agent:
# Workflow agents are handled differently because they require checkpoint restoration

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

cancellation_signal is accepted by _handler / _handle_workflow_agent but never checked. If the hosting layer sets this event on client disconnect/cancel, the current implementation will keep running the agent/workflow unnecessarily. Consider periodically checking cancellation_signal.is_set() (especially inside the streaming loops) and stopping early / closing builders.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants