Skip to Content
ExamplesMS Agent Framework

Microsoft Agent Framework

donkey.agent_framework.chat_client("…") builds an OpenAIChatClient (verified against 1.19.0, where the keyword is model=) that calls /responses. It sends through the SDK’s shared HTTP client, so the run id reaches the proxy and last_call is set in the task that made the call. Refusals come back typed — Agent Framework wraps the openai error in ChatClientException, and the response rides on __cause__.

#ScriptShowsNeeds
01basic-gw.pyAn Agent on the governed chat clientProxy credentials
02typed-refusals-live.pyPIIDetected, UpstreamRequestError, AuthErrorProxy + PII policy
03start-gateway.pyTwo tickets over the local simulator[local]

Install

Follow the examples setup first, then:

python -m pip install -e "../donkey-development-kit/python[llm,local,agent_framework]" set -a; source .env.local; set +a

01 — A governed agent

python "demos/human-made/agent-framework/01 - basic-gw.py"
donkey = Donkey.from_env() agent = Agent( client=donkey.agent_framework.chat_client("gpt-4o"), name="greeter", instructions="Answer in one short sentence.", ) result = asyncio.run(agent.run("Say hello in exactly three words.")) print(result.text) print("total tokens", result.usage_details["total_token_count"]) print("last_call ", donkey.last_call.status.value, donkey.last_call.surface)

You should see: the reply, total tokens from Agent Framework’s usage_details, and last_call unavailable …. asyncio.run(...) runs the call in its own context, so the script’s read is a cold one, and a cold read on this adapter reports unavailable rather than unobserved (#740 ). Read usage from the framework here, or read last_call inside the coroutine that made the call.

02 — Typed refusals, live

python "demos/human-made/agent-framework/02 - typed-refusals-live.py"

Three cases, each with its own Donkey: a contact record for PIIDetected, a model that does not exist for UpstreamRequestError, and wrong credentials for AuthError. The one Agent Framework-specific line is where the response is read from:

try: asyncio.run(agent.run(prompt)) print(name, "NO REFUSAL") except ChatClientException as err: error = classify(err.__cause__.response) print(name, "->", type(error).__name__, getattr(error, "entities", None))

Needs: llm-pii-detection-policy with Email and action Reject for the first case. You should see: <case> -> <Type> <entities> per case, or <case> NO REFUSAL.

03 — Two tickets over the local simulator

python "demos/human-made/agent-framework/03 - start-gateway.py"

No gateway and no credentials. start_gateway() with pii_block:every=2: the first ticket gets the simulator’s canned completion, the second is the captured PII 403, unwrapped from ChatClientException and classified.

gw = start_gateway() gw.set_scenarios("pii_block:every=2") donkey = Donkey(DonkeyConfig(llm_proxy_url=gw.url, llm_proxy_client_id=..., llm_proxy_client_secret=...)) for ticket in TICKETS: agent = Agent(client=donkey.agent_framework.chat_client("gpt-4o"), instructions="Reply in one sentence.") try: print("ok ", asyncio.run(agent.run(ticket)).text[:60]) except ChatClientException as err: error = classify(err.__cause__.response) print("refused", type(error).__name__, error.entities)
Output
ok A sleepy unicorn named Luma painted soft silver stars across refused PIIDetected ['Email'] requests 2

TypeError … model_id means an older Agent Framework; the scripts target the 1.19.0 model= keyword.

Learn more: MS Agent Framework

Source: demos/human-made/agent-framework/

Last updated on