Deterministic pill replies (greet / remember / weekend) were emitted as
AgentRunResponseUpdate with Contents only and no Role. The AG-UI .NET host
maps assistant text into TEXT_MESSAGE_* only when Role == Assistant, so the
client showed empty chat while the server still ran.
Set Role = ChatRole.Assistant on those updates, harden LatestUserText via
message.Text, and broaden pill matching for the staging suggestion copy.
Root cause across nearly every ChatClientAgent: system prompts were passed as
`description:` (agent metadata) instead of `instructions:` (the actual system
message). ChatClientAgent(instructions, name, description, …) therefore ran
with null instructions, so models ignored tool guidance and BYOC JSON demos
emitted prose.
Fixes reported staging failures:
- shared-state-read-write pills: instructions now reach the model + stronger set_notes guidance
- declarative-hashbrown / declarative-json-render: instructions + ChatResponseFormat.Json (LGP parity)
- declarative-gen-ui: catalog-specific design prompt (no DashboardCard), stronger outer agent
- shared-state-streaming: feature was demo-only in the manifest → shell "Backend fixture unavailable"; added to features
Verified: unit suite 79/79 in Docker SDK 9.
Staging click-through on ms-agent-dotnet / ms-agent-harness-dotnet hit
several GOTCHAS #8 defects: aimock D6 was green while live LLMs failed.
A2UI (beautiful-chat sales dashboard, declarative-gen-ui pills):
- Force the page-registered catalogId (models invent "sales_dashboard").
- Sanitize/normalize flat components; salvage type-as-key nests; drop
entries missing id/component (SummaryCard without id, charts without type).
- Strengthen secondary design prompts with the flat catalog contract.
Shared state + subagents side panels:
- Tool invocation drops AsyncLocal set by SetActiveThread, so writes landed
in the global slot while snapshots keyed by AgentSession/AgentThread.
Mirror writes and fall back on read (same pattern as D5ParityAgents).
- Wire the dead TryBuildDeterministicReply path for the "Remember something"
pill so notes update without relying on the model calling set_notes.
Open generative UI advanced + beautiful-chat calculator:
- Prompt for clickable keypad (not form/submit) and notifyHost ping wiring.
Verified: ms-agent-dotnet unit suite 79/79 green in Docker SDK 9; harness
agent builds clean and cvdiag tests 5/5.
Port ms-agent-harness-dotnet's ApiKeyResolver into ms-agent-dotnet so the 15
agent factories resolve the OpenAI credential as OPENAI_API_KEY (env) ->
config[OPENAI_API_KEY] -> GitHubToken, and the endpoint via OPENAI_BASE_URL ->
default, instead of hardcoding configuration["GitHubToken"] per agent.
Previously ms-agent-dotnet's main chat clients authenticated only with the
GitHub token. On a fixture-miss fall-through, aimock proxies to real
api.openai.com, which rejects the GitHub token (invalid_api_key, surfaced as
502). ms-agent-harness-dotnet already works because it resolves OPENAI_API_KEY
first; this brings ms-agent-dotnet to parity so its fall-through returns 200.
Interim showcase-side mitigation while the aimock cross-provider guard
(PNI-108, CopilotKit/aimock#340) is deferred.
- Copy agent/ApiKeyResolver.cs verbatim from ms-agent-harness-dotnet (code
copy, no new dependency)
- Rewire 15 factories + A2uiSecondaryToolCaller to ResolveApiKey/ResolveEndpoint;
drop the dead per-file DefaultOpenAiEndpoint const
- Add tests/ApiKeyResolverTests.cs (precedence, mock-endpoint fallback,
non-mock fail-fast)
Verified: dotnet build 0/0, dotnet test 76/76, whitespace format clean, and a
live OpenAI call through the resolver returned 200.