Foundry Hosted Agent Copilotkit
GitHubOfficialFirst committed by lordlinusDistributed by GitHub
- Skill
- Tool integration
- Automation and integrations
- MIT
- Low risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a framework for building agentic web applications that pair a CopilotKit React frontend with a Microsoft Agent Framework agent hosted on Microsoft Foundry. It details the architecture for connecting these components over the AG-UI protocol, emphasizing the use of native platform primitives for conversation management, tool approvals, and state persistence. The guide covers the full lifecycle from local development and deployment to debugging event streams and managing dependencies.
What it does
- Defines the architecture for connecting CopilotKit frontends to Foundry hosted agents
- Provides patterns for handling conversation history and durable tool approvals
- Outlines methods for managing background runs and multi-step workflows
- Explains how to implement generative UI and shared state using CopilotKit hooks
- Offers playbooks for building new apps and modifying existing agent tools
- Provides a structured approach for debugging communication between the frontend and the hosted agent
When to use it
- When building a new React or Next.js application using CopilotKit and Microsoft Foundry
- When integrating a Microsoft Agent Framework agent into an existing web application
- When implementing human-in-the-loop approval workflows for agent tools
- When troubleshooting connectivity or state synchronization issues between a frontend and a hosted agent
Advantages
- Reduces custom plumbing by utilizing native Foundry and AG-UI primitives
- Ensures conversation continuity and durable tool execution
- Supports complex agentic patterns like generative UI and human-in-the-loop approvals
- Provides clear guidance on deployment and environment management
Usage examples
- “How do I connect a CopilotKit frontend to a Microsoft Foundry hosted agent?”
- The agent provides a step-by-step guide on selecting the appropriate wiring, setting up the AG-UI gateway, and configuring the CopilotKit runtime to communicate with the hosted agent.
- “How can I implement human-in-the-loop approvals for my agent tools?”
- The agent explains how to use the approval_mode flag on tools and how to handle the resulting interrupts in the React frontend using the appropriate hooks.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/github/foundry-hosted-agent-copilotkit/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip foundry-hosted-agent-copilotkit.zip -d .agents/skills
Documentation by lordlinus
CopilotKit + AG-UI + Microsoft Foundry hosted agents
Use this skill when a React/Next.js app uses CopilotKit and talks over AG-UI to a Microsoft Agent Framework (MAF) agent hosted in Microsoft Foundry. This covers new builds and changes to existing apps. Foundry hosted agents are a paid Azure service.
Scaffold the agent with azd ai agent init and the frontend with your usual React/Next.js tooling. Then follow this skill for everything that connects them.
Mental model
React (CopilotKit v2) CopilotKitProvider / CopilotChat threadId=<conv_ id> / useInterrupt
│ HTTP
CopilotKit runtime CopilotRuntime({ agents: { default: new HttpAgent({ url }) } })
│ AG-UI (SSE)
AG-UI gateway (FastAPI) add_agent_framework_fastapi_endpoint(app, AgentFrameworkAgent(FoundryAgent(...),
use_service_session=True, service_session_id_from_thread_id=True)) ← keeps no thread state
│ OpenAI Responses + Entra token (https://ai.azure.com/.default)
Foundry hosted agent ResponsesHostServer(Agent(tools=[...])) ← deployed with azdA deployed hosted agent does not speak AG-UI. It exposes .../agents/<name>/endpoint/protocols/openai/responses (Responses protocol) or .../protocols/invocations. Translate with MAF's own adapter (FoundryAgent + agent-framework-ag-ui) instead of writing an SSE translator by hand. Browsers cannot hold the Entra token, so the gateway is always server-side.
Use the platform first
Before you write any plumbing, check this table. Each row is something older codebases built by hand.
| Need | Native primitive (don't hand-roll) |
|---|---|
| Conversation history across turns and restarts | Foundry conversations: create one per chat, use its conv_… ID as the AG-UI thread ID, and the gateway passes it through (no snapshot store) |
| Durable tool approvals | ResponsesHostServer persists approval requests by default (FoundryFunctionApprovalStore). The AG-UI adapter turns them into AG-UI interrupts and forwards decisions back to the hosted agent |
| Runs that survive browser disconnects | Responses background: true + store: true, then poll or reconnect (see wiring) |
| Durable multi-step workflows with gates | Invocations hosted agent + @multi_turn_task + FoundryStateStore |
| Per-user files for the agent | Session Files API; the agent reads $HOME with its own tools. Never inline large documents into the prompt |
| Long-term user memory | Foundry Memory Store (user scope) or FoundryMemoryProvider |
| Tool catalogs, web search, code interpreter | Foundry Toolbox (FoundryToolbox) with Tool Search, instead of listing every tool up front |
| Live docs while coding | The Microsoft Learn and Foundry MCP servers (bundled with this skill's plugin) |
Choose the wiring
| If the app needs… | Use | Gateway size |
|---|---|---|
| Hosted agent + chat + tools + approvals (default) | A. AG-UI gateway over a Responses hosted agent | ~50 lines of Python |
| Every state pattern, local prototype, no Foundry compute | B. In-process AG-UI (agent runs inside the FastAPI app) | ~15 lines |
| Background runs that keep going after disconnect, reconnect, per-user conversation lists | C. Background-runs gateway (custom AG-UI agent over Foundry conversations) | ~150 lines of TypeScript |
| Multi-step plan → approve → execute, irreversible steps that must not run twice | D. Invocations hosted agent alongside A or C | REST proxy |
Code for each is in references/wiring.md. In an existing codebase, identify the wiring before you change anything:
FoundryAgent(...)wrapped byadd_agent_framework_fastapi_endpointmeans A.Agent(client=...)wrapped directly means B.A custom
AbstractAgentcalling/responseswithbackgroundmeans C.protocol: invocationsinazure.yamlmeans D.
Workflow
Pick or identify the wiring (table above).
Use the latest release of every package (
@copilotkit/*,@ag-ui/*,agent-framework-*,azdand itsazure.ai.agentsextension). Then ground on live sources:the Microsoft Learn MCP server for MAF and Foundry
the Foundry MCP server for project state
docs.copilotkit.ai and the
.d.tsfiles bundled in the installed@copilotkit/*packagesdocs.ag-ui.com
APIs move between minor versions, so don't trust memorized names.
Build or change it with a playbook below.
Verify adversarially against the completion criteria. A compiling build, a started server, or one good chat reply is not proof.
Playbooks
Build a new app end to end (wiring A)
In a fresh directory, run
azd ai agent init --no-prompt ...against the project. Confirmazd env get-valuesshowsFOUNDRY_PROJECT_ENDPOINT, then write tools inmain.py(wiring §1).Run it locally with
azd ai agent run(port 8088) and smoke-test it withazd ai agent invoke --local "hi".azd deploy(each deploy creates a new agent version), thenazd ai agent invoke "hi".Add the AG-UI gateway exactly as in wiring §2, including the thread-ID-is-conversation-ID flags and the interop shim. Create a conversation, then test chat and an approve resume with
curl -Nusing itsconv_…ID asthreadIdbefore touching the UI.Add the conversation route, the CopilotKit runtime route and the React provider (wiring §3).
Add
useInterruptapproval UI and a tool renderer (hitl.md).Verify every completion criterion, first locally and then against the deployed agent.
Add or change an agent tool
Define it with
@tool(Python) orAIFunctionFactory.Create(.NET), using typed and described parameters.Keep parameter descriptions free of concrete example values for data the model must derive. Models copy literal examples.
Return compact values. Rich formatting belongs in the UI renderer.
Side-effecting tools get
approval_mode="always_require"(hitl.md).Redeploy the hosted agent. Tools live in the hosted agent, not the gateway.
Verify through the UI that
TOOL_CALL_*events stream, and that any component parsing the arguments still works.
Generative UI and shared state (CopilotKit v2 hooks)
| Pattern | Agent side | Frontend hook |
|---|---|---|
| Frontend tool (agent calls the UI) | none; arrives in RunAgentInput.tools | useFrontendTool |
| Render a backend tool call | normal @tool | useRenderTool / useRenderToolCall / useDefaultRenderTool |
| Human approval of a tool call | approval_mode="always_require" | useInterrupt → resolve({approved}) |
| Agent asks the user for input (frontend-resolved tool) | none | useHumanInTheLoop → respond(...) |
| Shared or predictive state | state_schema / predict_state_config on AgentFrameworkAgent | useAgent (read agent.state) |
State patterns emit STATE_SNAPSHOT/STATE_DELTA only when the adapter can see the agent's state:
Wiring B gets them natively.
Wiring A needs them declared on the gateway's
AgentFrameworkAgent. Test this before you promise the feature.Wiring C has no state events unless you synthesize them.
Debug a broken flow
Work from the lowest layer upward:
Call the hosted agent with
azd ai agent invokeorcurlagainst/responses.Call the gateway with a real conversation ID. A made-up thread ID returns HTTP 500 with this wiring:
CONV=$(curl -s -X POST "$FOUNDRY_PROJECT_ENDPOINT/agents/$FOUNDRY_AGENT_NAME/endpoint/protocols/openai/conversations?api-version=v1" \ -H "Authorization: Bearer $(az account get-access-token --resource https://ai.azure.com --query accessToken -o tsv)" \ -H 'content-type: application/json' -d '{}' | jq -r .id) curl -N -X POST <gateway>/ -H 'content-type: application/json' -d '{"threadId":"'$CONV'","runId":"r1","messages":[{"id":"m1","role":"user","content":"hi"}],"tools":[],"context":[],"state":{},"forwardedProps":{}}'Test the CopilotKit route.
Test the browser.
The first layer that fails owns the bug. Then match the symptom in troubleshooting.md. Use azd ai agent monitor for hosted-agent logs.
Upgrade dependencies
Follow the version rules in troubleshooting.md. Upgrade all packages together, then re-run the completion criteria live.
Completion criteria
A change is done only when all of these hold:
The chat path works through the real UI, not only through curl.
Every approval-gated tool was tested both ways:
Approve: the tool runs once on the server and the side effect is observable.
Reject: the tool does not run, and the agent acknowledges it.
After an approval, a follow-up turn in the same thread does not re-run the gated tool.
Tool and approval cards still render after
RUN_FINISHED, not only while streaming.For deployed changes, checks 1–4 passed against the deployed agent and gateway. A successful deployment proves nothing about behavior.
Files
- ATTRIBUTION.mdAdded by AutoGineer897 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md9.6 KiB
- references/hitl.md8.4 KiB
- references/troubleshooting.md7.7 KiB
- references/wiring.md18.2 KiB
Requirements and compatibility
Written for: GitHub Copilot
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an MCP server
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- First committed by
lordlinus
- Publisher
- GitHub (Official)
- Distributed by
- GitHub
- Source
- github/awesome-copilot · skills/foundry-hosted-agent-copilotkit · commit 797337f
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Contributors
- lordlinus
AutoGineer is not affiliated with or endorsed by lordlinus or GitHub.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download foundry-hosted-agent-copilotkit.zip