.NET: Add source (ZIP) deploy oriented hosted agent samples - #7372
Merged
rogerbarreto merged 23 commits intoJul 29, 2026
Conversation
Migrate the sample to Foundry source (ZIP) deployment as the default: add azure.yaml with codeConfiguration (remote_build, dotnet_10) and the tool-generated .agentignore, make the csproj self-contained (single target, CPM off, published PackageReferences), and simplify Program.cs to the pristine end-user hosting path. Container files are kept for now; contributor and remaining samples handled in follow-ups.
…ed-ChatClientAgent to source (ZIP) Foundry.Hosting: AddFoundryResponses now binds Kestrel to FoundryEnvironment.Port (the PORT env var, default 8088) for a plain WebApplication.CreateBuilder (Tier 3) host, mirroring AgentHostBuilder. This lets a source/ZIP-deployed .NET agent pass the readiness probe with no Dockerfile. It respects an explicit ASPNETCORE_URLS override and is idempotent. Adds FoundryListenPortTests plus a serialized env-var collection. Hosted-ChatClientAgent: migrate to source (ZIP) deploy as the default. Add azure.yaml with codeConfiguration (remote_build, dotnet_10) and the tool-generated .agentignore, make the csproj self-contained (single target, CPM off) with a local Directory.Packages.props, embed the local-dev per-agent route so the Using-Samples REPL can reach the local server, and rewrite the README around the azd flow. Documents AZURE_TOKEN_CREDENTIALS=dev for local runs. Using-Samples/SimpleAgent: fix the per-agent endpoint scheme rewrite so the local HTTP dev port is preserved (the policy now lives on the per-agent ProjectOpenAIClientOptions that actually serves the request).
…and the local-only agent route Zip/code deploy runs the sample as a plain ASP.NET app, so the Foundry readiness port was never bound and every invoke returned HTTP 424 session_not_ready. The first attempt skipped the binding when ASPNETCORE_URLS was already set, but the .NET base image always sets it to port 80, so the skip always tripped. Kestrel ListenAnyIP overrides ASPNETCORE_URLS, so the binding is now unconditional and PORT stays the only knob. Sample cleanup for zip deploy: * Remove Dockerfile, Dockerfile.contributor, agent.manifest.yaml and agent.yaml. Source deploy needs none of them. * Remove LocalDevEndpoint.cs and the invented per-agent local route. The local server already serves the standard POST /responses route, so the client can reach it directly. * Trim .env.example: the port and environment variables are no longer needed. * Exclude .checkpoints/ from the upload so local session state does not ship. SimpleAgent now asks at startup whether to chat with the local server or the deployed agent, the same choice azd ai agent invoke exposes through --local. Local uses an OpenAI responses client pointed at http://localhost:8088; Foundry uses the per-agent endpoint. Add scripts/New-ContributorStage.ps1, which stages a sample to a temp folder with the local Agent Framework source packed into a feed inside the upload, so contributors can deploy framework changes through the same azd flow end users run.
rogerbarreto
temporarily deployed
to
github-app-auth
July 28, 2026 19:56 — with
GitHub Actions
Inactive
rogerbarreto
temporarily deployed
to
github-app-auth
July 28, 2026 19:56 — with
GitHub Actions
Inactive
rogerbarreto
temporarily deployed
to
github-app-auth
July 28, 2026 19:56 — with
GitHub Actions
Inactive
Contributor
There was a problem hiding this comment.
Pull request overview
Reorients the .NET Foundry hosted-agent samples around source (ZIP/code) deployment (now the default path), while preserving a parallel container/Dockerfile-based sample for scenarios requiring image control. It also updates the Foundry hosting library to bind Kestrel to the Foundry runtime port so source-deployed agents pass readiness probing without requiring a Dockerfile.
Changes:
- Updated
AddFoundryResponsesto configure Kestrel to listen onFoundryEnvironment.Port, with new unit tests covering port binding behavior and idempotency. - Reworked
Hosted-ChatClientAgentsample to use unifiedazure.yamlsource deploy and added a siblingHosted-ChatClientAgent-Dockerfilesample for container deploy. - Added contributor scripts to pack and inject a local Agent Framework NuGet feed into scaffolded (azd-initialized) hosted-agent folders; updated the SimpleAgent REPL to support
--local/--remotetargeting.
Reviewed changes
Copilot reviewed 39 out of 39 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/FoundryListenPortTests.cs | Adds tests verifying Kestrel listen-port binding behavior from AddFoundryResponses. |
| dotnet/tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/AspNetCoreUrlsEnvFixture.cs | Serializes tests that mutate ASPNETCORE_URLS to prevent flakiness. |
| dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/ServiceCollectionExtensions.cs | Applies Foundry listen-port binding via KestrelServerOptions when registering Responses hosting. |
| dotnet/samples/04-hosting/FoundryHostedAgents/scripts/Add-LocalFrameworkFeed.ps1 | Adds PowerShell helper to pack local framework and inject a folder feed + nuget.config into a scaffolded agent. |
| dotnet/samples/04-hosting/FoundryHostedAgents/scripts/add-local-framework-feed.sh | Adds bash helper mirroring the PowerShell local-feed wiring flow. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Using-Samples/SimpleAgent/SimpleAgent.csproj | Updates dependencies to support local targeting via OpenAI Responses client and adds OpenAI project reference. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Using-Samples/SimpleAgent/README.md | Documents local vs Foundry targeting and adds azd ai agent invoke stale-conversation troubleshooting. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Using-Samples/SimpleAgent/Program.cs | Adds --local/--remote selection and implements local target via POST /responses using OpenAI Responses client. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Using-Samples/README.md | Expands guidance on local HTTP dev and clarifies scheme-rewrite behavior. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Workflow-Simple/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Workflow-Handoff/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ToolboxMcpSkills/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Toolbox/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Toolbox-AuthPaths/README.md | Adds troubleshooting row for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-TextRag/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-Observability/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-McpTools/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-LocalTools/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-LocalCodeAct/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-FoundryAgent/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/README.md | Rewrites the sample for source/ZIP deploy flow, adds contributor local-feed section and troubleshooting. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/Program.cs | Updates sample host to use DefaultAzureCredential and model selection via non-blank env var fallback. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/HostedChatClientAgent.csproj | Makes the project ZIP-deploy friendly (self-contained, explicit versions, central package mgmt disabled). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/Dockerfile.contributor | Removes contributor-only Dockerfile path from the source-deploy sample. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/Dockerfile | Removes container-based Dockerfile from the source-deploy sample. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/azure.yaml | Adds unified azure.yaml for hosted agent source/ZIP deploy configuration. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/agent.yaml | Removes deprecated hosted-agent spec file from the sample. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/agent.manifest.yaml | Removes deprecated manifest-based init path from the sample. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/.env.example | Updates local configuration template (deployment name + local dev credential guidance). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/.agentignore | Adds ZIP upload ignore rules for code deploy (excluding secrets/build output, keeping contributor feed files). |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent-Dockerfile/README.md | Introduces container-deploy variant sample documentation and flow. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent-Dockerfile/Program.cs | Adds container-deploy variant agent host using Responses protocol. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent-Dockerfile/HostedChatClientAgentDocker.csproj | Adds container-deploy variant self-contained project definition. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent-Dockerfile/Dockerfile | Adds container image build/publish steps and pins listen port to 8088. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent-Dockerfile/azure.yaml | Adds unified azure.yaml selecting docker/container deploy mode. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent-Dockerfile/.env.example | Adds container variant local configuration template. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent-Dockerfile/.dockerignore | Prevents local secrets/build artifacts from entering the Docker build context. |
| dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-AzureSearchRag/README.md | Adds troubleshooting note for azd ai agent invoke conversation reuse (404). |
| dotnet/agent-framework-dotnet.slnx | Adds the new container-deploy sample project to the solution structure. |
Comments suppressed due to low confidence (2)
dotnet/samples/04-hosting/FoundryHostedAgents/scripts/Add-LocalFrameworkFeed.ps1:88
- $packagePropsPath is constructed with a Windows-only child path ('nuget\nuget-package.props'), and the VersionPrefix parse assumes Select-String always matches (Matches[0]). If the file path is wrong or the XML changes, this throws an unhelpful index error. Build the path with Join-Path segments and add a clear failure when VersionPrefix cannot be read.
dotnet/samples/04-hosting/FoundryHostedAgents/scripts/Add-LocalFrameworkFeed.ps1:99 - $projectPath is built with an embedded backslash ("$project$project.csproj"), which breaks on PowerShell 7 on macOS/Linux because '' is not a path separator there. Construct the path using Join-Path segments so it works cross-platform.
rogerbarreto
temporarily deployed
to
github-app-auth
July 28, 2026 20:28 — with
GitHub Actions
Inactive
rogerbarreto
temporarily deployed
to
github-app-auth
July 28, 2026 20:29 — with
GitHub Actions
Inactive
peibekwe
reviewed
Jul 29, 2026
peibekwe
reviewed
Jul 29, 2026
peibekwe
reviewed
Jul 29, 2026
SergeyMenshykh
approved these changes
Jul 29, 2026
rogerbarreto
temporarily deployed
to
github-app-auth
July 29, 2026 09:36 — with
GitHub Actions
Inactive
westey-m
approved these changes
Jul 29, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Jul 29, 2026
peibekwe
approved these changes
Jul 29, 2026
This was referenced Jul 30, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation & Context
Source (code / ZIP) deploy is now the default for Python and .NET hosted agents: you upload your sources and the platform builds and runs them, with no Dockerfile to author and no container registry to manage. The .NET samples still only showed the container path, so this change reorients them around ZIP deploy and makes deploying an Agent Framework hosted agent a much simpler experience.
Description & Review Guide
What are the major changes?
Hosted-ChatClientAgentnow deploys from source through a single unifiedazure.yaml, and a siblingHosted-ChatClientAgent-Dockerfilekeeps the container path for anyone who needs control over the runtime image.Along the way, a few quality and simplicity improvements:
AddFoundryResponsesbinds Kestrel toFoundryEnvironment.Port(PORT, default 8088). Without it a source deploy listens on the ASP.NET default and every invoke returns HTTP 424session_not_ready.agent.yamlandagent.manifest.yaml, plus both Dockerfiles, from the source-deploy sample.scripts/Add-LocalFrameworkFeed.ps1andscripts/add-local-framework-feed.sh: contributors follow the same flow as end users and deploy their own framework build in a single extra step.SimpleAgentREPL gained--localand--remote, and now reaches a local server through the standardPOST /responsesroute.azd ai agent invoke.What is the impact of these changes?
Inside a Foundry container, a plain
WebApplicationhost callingAddFoundryResponsesnow listens onFoundryEnvironment.Port. Override withPORT. Hosts usingAgentHostBuilderalready behaved this way, and a host running outside Foundry keeps the addresses it resolved from configuration.What do you want reviewers to focus on?
The listen-port gate: it keys off
FOUNDRY_HOSTING_ENVIRONMENT, read directly rather than through the cachedFoundryEnvironment.IsHosted. Inside Foundry it cannot be guarded onASPNETCORE_URLS(the .NET base image always sets it to port 80) nor on the presence ofPORT(the platform sets that only for a non-default port).Contribution Checklist