SharpOMatic.AGUI
10.0.4-alpha.10
dotnet add package SharpOMatic.AGUI --version 10.0.4-alpha.10
NuGet\Install-Package SharpOMatic.AGUI -Version 10.0.4-alpha.10
<PackageReference Include="SharpOMatic.AGUI" Version="10.0.4-alpha.10" />
<PackageVersion Include="SharpOMatic.AGUI" Version="10.0.4-alpha.10" />
<PackageReference Include="SharpOMatic.AGUI" />
paket add SharpOMatic.AGUI --version 10.0.4-alpha.10
#r "nuget: SharpOMatic.AGUI, 10.0.4-alpha.10"
#:package SharpOMatic.AGUI@10.0.4-alpha.10
#addin nuget:?package=SharpOMatic.AGUI&version=10.0.4-alpha.10&prerelease
#tool nuget:?package=SharpOMatic.AGUI&version=10.0.4-alpha.10&prerelease
SharpOMatic.AGUI
Optional SharpOMatic extension that exposes an AG-UI compatible endpoint for running SharpOMatic workflows over SSE. It supports both stateless workflow runs and conversation-enabled workflows.
Usage
Register the package in your ASP.NET Core host:
builder.Services.AddSharpOMaticAgUi();
That defaults to /sharpomatic/api/agui.
In the DemoServer that is exposed as https://localhost:9001/sharpomatic/api/agui.
Choose a different base path if needed:
builder.Services.AddSharpOMaticAgUi("/banana");
Or override both the base path and the AG-UI child path:
builder.Services.AddSharpOMaticAgUi("/banana", "/integrations/chat");
The package adds POST on the combined path.
Request requirements
threadIdis required.forwardedPropsmust contain exactly one ofworkflowIdorworkflowName.workflowNamemust match exactly one workflow.
The endpoint resolves the matching SharpOMatic workflow, chooses the correct execution mode, and streams SSE events translated from workflow stream events until the run completes, suspends, or fails.
SSE event mapping
SharpOMatic translates workflow stream events into AG-UI SSE events:
TEXT_MESSAGE_START,TEXT_MESSAGE_CONTENT,TEXT_MESSAGE_ENDSTEP_STARTED,STEP_FINISHEDSTATE_SNAPSHOT,STATE_DELTAREASONING_START,REASONING_MESSAGE_START,REASONING_MESSAGE_CONTENT,REASONING_MESSAGE_END,REASONING_ENDTOOL_CALL_START,TOOL_CALL_ARGS,TOOL_CALL_END,TOOL_CALL_RESULTACTIVITY_SNAPSHOT,ACTIVITY_DELTARUN_STARTED,RUN_FINISHED,RUN_ERROR
TOOL_CALL_RESULT preserves both the result messageId and the linked toolCallId.
TOOL_CALL_START includes the tool name and can include parentMessageId when the model output supplies it.
Reasoning events use AG-UI-specific messageId values prefixed with reason: so they do not collide with assistant text messages when a model/provider reuses one response id for both.
Tool result messages use AG-UI-specific messageId values prefixed with tool: so tool messages stay distinct too, while the linked toolCallId remains unchanged.
Activity messages use AG-UI-specific messageId values prefixed with activity: so activity updates stay distinct from assistant, reasoning, and tool messages.
When batch-mode model calls are replayed without provider message ids, SharpOMatic synthesizes separate assistant messageId values for each distinct assistant text lifecycle and seeds them from the stream sequence so they remain unique across conversation turns.
Code-node stream-event helpers can mark events as silent, which keeps them in SharpOMatic stream history while suppressing their live AG-UI SSE emission.
Workflow selection
The recommended request shape is:
{
"threadId": "support-chat-001",
"messages": [],
"state": {},
"context": [],
"forwardedProps": {
"sharpomatic": {
"workflowId": "11230021-5144-471a-8ec7-9b460354b745"
}
}
}
workflowName can be used instead of workflowId:
{
"threadId": "support-chat-001",
"forwardedProps": {
"sharpomatic": {
"workflowName": "Support Chat"
}
}
}
For compatibility, the selector can also live directly under forwardedProps, but forwardedProps.sharpomatic is the preferred convention.
Execution modes
SharpOMatic resolves the target workflow first:
- non-conversation workflows are treated as stateless AG-UI targets
- conversation-enabled workflows use normal SharpOMatic conversation storage
For non-conversation workflows:
- the client must send the full AG-UI message history on every call
- SharpOMatic rebuilds
input.chatfrom that history for the current run, except for the latest user text message exposed asagent.latestUserMessage threadIdremains protocol metadata only
For conversation-enabled workflows:
- the first call uses
threadIdas the SharpOMaticconversationId - later calls with the same
threadIdcontinue or resume that conversation - later AG-UI calls must be incremental only and send only the new message
- the controller exposes only the latest incoming AG-UI message at
agent.messagesand does not append it intoinput.chat
Workflow context
The controller maps selected request data into workflow context under agent:
agent.latestUserMessage: the final item inmessages, but only when that item is a user text messageagent.latestToolResult: the final item inmessages, but only when that item is a tool result message. Itscontentstays as the original string, and if that string is non-empty JSON then SharpOMatic also stores the parsed payload inagent.latestToolResult.value.agent.messages: for non-conversation workflows, the full incoming AG-UImessagesarray; for conversation-enabled workflows, only the latest incoming messageagent.state: the incoming AG-UIstatevalueagent.context: the incoming AG-UIcontextvalueagent._hidden.state: a hidden deep copy of the incoming AG-UIstate, used as the baseline forAddStateSyncAsync()and theState Syncnode
These values are passed through as structured JSON-compatible data, not as a single raw JSON string.
On each AG-UI start or resume, SharpOMatic updates the agent object.
If the workflow context already contains agent, the incoming AG-UI agent object replaces it entirely.
For non-conversation workflows, the controller converts supported AG-UI messages into provider-neutral ChatMessage entries at input.chat for the current run.
For conversation workflows, input.chat is canonical model history owned by workflow nodes.
Use it as the recommended source for ModelCall.ChatInputPath, and set ModelCall.ChatOutputPath to input.chat when model responses should be replayed across turns.
The components that can create or change input.chat are:
- the AG-UI controller, only for non-conversation workflows, from the incoming
messagesarray - the Model Call node, when Chat Output Path is set, usually to
input.chat - the Frontend Tool Call node, only when Chat Persistence is not
None - the Backend Tool Call node, only when Chat Persistence is not
None
The AG-UI controller does not append incoming user text or frontend tool results to conversation input.chat.
Incoming user text is stored as silent stream history for conversation turns, but it is not a ChatMessage.
Frontend tool results are persisted by the Frontend Tool Call node according to its chat persistence setting, which defaults to None for new frontend tool-call nodes.
Supported input.chat conversion in this version:
system→ChatRole.Systemdeveloper→ChatRole.Systemuser→ChatRole.User, except the latest user text message when it is exposed asagent.latestUserMessageassistanttext and tool calls →ChatRole.Assistanttoolresults →ChatRole.Tool
AG-UI reasoning and activity messages are ignored for chat conversion in this version.
Unsupported multimodal or non-string message content is rejected with RUN_ERROR.
SharpOMatic also includes protocol-aware workflow nodes for common AG-UI patterns:
- Frontend Tool Call for frontend-driven tool results that suspend and later resume the workflow
- Backend Tool Call for tool-call rendering when the workflow already knows the result
- Activity Sync and State Sync for structured activity or state updates
- Step Start and Step End for simple progress markers
Use the dedicated node and AG-UI docs for the detailed behavior of each node.
Frontend and backend tool-call nodes always emit AG-UI tool-call stream events for display.
Those stream events are separate from chat persistence.
With Chat Persistence set to None, the frontend can still render the tool call from stream history, but later model calls do not receive it through input.chat.
The Suspend node stores and resumes a checkpoint only.
It does not write input.chat and does not emit stream events.
On AG-UI resume, agent is updated with the latest user message or latest tool result before downstream nodes continue.
For conversation turns, SharpOMatic automatically stores agent.latestUserMessage as user text stream events before workflow nodes run.
Those events are marked with the transient silent flag for the current live AG-UI SSE stream, so the caller does not render its submitted message twice.
The underlying stream events are still persisted in SharpOMatic history, and the flag itself is not stored in the database.
Code nodes can also emit AG-UI tool-call, activity, state, step, and custom events through the Events.Add* helpers.
For the higher-level activity/state sync helpers and the full helper surface, see the AG-UI and Code Node docs.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- SharpOMatic.Engine (>= 10.0.4-alpha.10)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.0.4-alpha.10 | 0 | 4/26/2026 |