Keep the AG-UI .NET SDK at feature and wire-format PARITY with the canonical reference SDKs (TypeScript is the source of truth; Python is types/encoder only). USE FOR: porting a feature/event/behavior that landed in the TS (or Python) SDK into .NET, verifying the .NET wire format (JSON, SSE, protobuf) matches the reference, locating where the reference implementation and compatibility fixtures live, mapping a TS concept to the .NET event/client/encoder model, resolving an upstream protocol fix (e.g. a Microsoft.Extensions.AI / Microsoft Agent Framework issue) that needs a .NET counterpart, deciding which .NET package owns a change. DO NOT USE FOR: the mechanics of writing a specific test (use agui-dotnet-unit-tests for serialization round-trips, agui-dotnet-integration-tests for cross-language / E2E harness mechanics, agui-dotnet-wire-types for JSON/proto type rules, agui-dotnet-transport for SSE/HTTP transport details). This skill is about the PARITY PROCESS and where the reference lives, not test authoring.
The .NET SDK implements an upstream, multi-language protocol. This skill encodes the parity process: which SDK is authoritative, where its reference and fixtures live, how to map reference concepts onto the .NET model, and how parity is guarded.
core (types/events) and an encoder,
but no client run-loop and no protobuf (sdks/python/ag_ui/ has core/ and
encoder/ but no client/ or proto/). Use it only as a secondary check on
type/JSON shape — never for run-loop or proto questions.| Concern | TypeScript reference (source of truth) | .NET package it maps to |
|---|---|---|
| Event & type definitions | sdks/typescript/packages/core/src/events.ts, types.ts, event-factories.ts | sdks/dotnet/src/AGUI.Abstractions/Events/, Messages/ |
| Client run-loop / transport | sdks/typescript/packages/client/src/run/, apply/, agent/, transform/ | sdks/dotnet/src/AGUI.Client/ (AGUIChatClient.cs, AGUIHttpTransport.cs, EventStreamConverter.cs, ToolCallBuilder.cs) |
| SSE / JSON wire framing | sdks/typescript/packages/encoder/src/encoder.ts | sdks/dotnet/src/AGUI.Formatting/, AGUI.Abstractions/Serialization/ |
| Protobuf wire format | sdks/typescript/packages/proto/src/proto/events.proto, types.proto, patch.proto | sdks/dotnet/src/AGUI.Protobuf/ (ProtoEventMapper.cs, ProtoMessageMapper.cs) |
The src/ packages are AGUI.Abstractions, AGUI.Formatting, AGUI.Protobuf, AGUI.Client,
AGUI.Server; sdks/dotnet/AGENTS.md and docs/architecture.md are the canonical
description of the layout and conventions.
packages/core (a new event/type),
packages/client (run-loop / event-application behavior), or
packages/proto+encoder (wire framing). Read the TS implementation and its tests
to capture the exact contract — field names, ordering, optionality, coalescing rules.packages/core/src/events.ts.AGUI.Abstractions; run-loop → AGUI.Client; SSE/JSON framing → AGUI.Formatting;
protobuf → AGUI.Protobuf. Follow the .NET conventions in AGENTS.md (one class
per file, sealed, source-generated JSON context, PublicAPI.Unshipped.txt).AGENTS.md (class in Events/, AGUIEventTypes constant,
[JsonSerializable], BaseEventJsonConverter case, PublicAPI entry).tests/AGUI.Abstractions.UnitTests/Compatibility/ and/or a cross-language test in
tests/CrossLanguage.Vitest/tests/.sdks/dotnet/AGENTS.md, docs/architecture.md, and
docs/cross-language-testing.md if the change alters the model, package layout, or the
set of wire-supported events.Three independent layers catch drift; add to whichever layer the change touches.
tests/AGUI.Abstractions.UnitTests/Compatibility/ holds TS-produced JSON fixtures
(*-events.json) loaded via FixtureLoader and deserialized into .NET types
({Category}CompatibilityTest.cs, e.g. RunEventsCompatibilityTest,
ToolCallEventsCompatibilityTest). A new/changed event shape needs a fixture entry.tests/CrossLanguage.TestServer/ (C# server) and tests/CrossLanguage.Vitest/
(TS client driving it) proves real interop — see sdks/dotnet/docs/cross-language-testing.md.
Scenario specs live in tests/CrossLanguage.Vitest/tests/ (e.g.
parallel-tool-calls.test.ts, state-events.test.ts, protobuf-parity.test.ts).protobuf-parity.test.ts plus
tests/AGUI.Protobuf.UnitTests/ verify the binary encoding matches the TS proto output.The protobuf schema covers a subset of events by design. .NET-only events
(Reasoning*, Activity*, ToolCallResult) are not in the proto wire format and
throw NotSupportedException when mapped — see ProtoEventMapper.cs (the default
case lists the 16 supported events: RUN_STARTED/FINISHED/ERROR, STEP_STARTED/FINISHED,
TEXT_MESSAGE_START/CONTENT/END, TOOL_CALL_START/ARGS/END, STATE_SNAPSHOT/DELTA,
MESSAGES_SNAPSHOT, RAW, CUSTOM) and ProtoMessageMapper.cs. This is a deliberate,
documented boundary — do not "fix" it by inventing proto messages that don't exist in
events.proto. JSON/SSE remains the full-fidelity wire; protobuf is the constrained one.
packages/core /
packages/client first..NET-only event (Reasoning*, Activity*,
ToolCallResult). The NotSupportedException is intentional.This skill governs what to port and where the reference is — delegate test mechanics:
34c3e0c
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.