Skip to content

.NET: valkey streaming support dotnet - #5576

Open
Matthias Howell (MatthiasHowellYopp) wants to merge 3 commits into
microsoft:mainfrom
MatthiasHowellYopp:issue-5544
Open

Matthias Howell (MatthiasHowellYopp) wants to merge 3 commits into
microsoft:mainfrom
MatthiasHowellYopp:issue-5544

Conversation

@MatthiasHowellYopp

Copy link
Copy Markdown
Contributor

Motivation and Context

The Microsoft.Agents.AI.Valkey package provides ValkeyChatHistoryProvider and ValkeyContextProvider for persistent conversation history and memory context. However, the framework currently has no storage-backed resumable streaming component — if a client disconnects during a streamed agent response (RunStreamingAsync), partial output is lost and must be regenerated. This is the final piece of the Valkey integration story, delivering parity with the Python agent-framework-valkey package.

Valkey Streams (XADD/XRANGE) are a natural fit: each entry gets an auto-generated ID that serves as a continuation token, entries are append-only and durable, and XRANGE with an exclusive start ID gives exact resume-from-here semantics — all with core commands, no modules required.

Fixes issue #5544

Description

Adds ValkeyStreamBuffer to the Microsoft.Agents.AI.Valkey package — a resumable streaming buffer backed by Valkey Streams.

The component writes serialized AgentResponseUpdate chunks to a Valkey Stream via XADD and replays missed entries via XRANGE from a caller-provided entry ID. The stream entry ID returned by each AppendAsync call serves as the continuation token for resumption.

Public API:

  • AppendAsync(responseId, update) — writes a chunk, returns the entry ID
  • ReadAsync(responseId, afterEntryId) — replays entries after a given ID as IAsyncEnumerable
  • GetEntryCountAsync(responseId) — returns stream length
  • DeleteStreamAsync(responseId) — removes a stream
  • MaxLength property — caps stream size via approximate XTRIM after each XADD

Follows the same patterns as the existing Valkey providers: dual constructors (connection string + IConnectionMultiplexer for DI), IAsyncDisposable with disposed-state guard, CancellationToken forwarding, malformed JSON resilience, trimming/AOT attributes, and ILogger integration at appropriate levels (Debug for per-request, Warning for skipped entries).

Includes a self-contained sample (AgentWithMemory_Step06_ResumableStreamingWithValkey) that demonstrates the full workflow — stream, disconnect, resume, full replay — against a live Valkey instance with no LLM or cloud credentials required.

64 unit tests passing, covering constructor validation, append/read round-trips, entry ID incrementing, MaxLength pass-through, malformed entry handling, cancellation, disposal guards, and empty stream edge cases.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Copilot AI review requested due to automatic review settings April 29, 2026 19:13
@moonbox3 Evan Mattson (moonbox3) added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs .NET Usage: [Issues, PRs], Target: .Net labels Apr 29, 2026
@github-actions github-actions Bot changed the title valkey streaming support dotnet .NET: valkey streaming support dotnet Apr 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@MatthiasHowellYopp

Copy link
Copy Markdown
Contributor Author

westey (@westey-m) Hoping I can get a review on this this week, tks

@MatthiasHowellYopp

Copy link
Copy Markdown
Contributor Author

westey (@westey-m) Hoping I can get a review this week on this, thanks.

Adds ValkeyStreamBuffer — a resumable streaming buffer backed by Valkey
Streams (XADD/XRANGE). Enables clients to disconnect and reconnect
mid-stream without data loss using entry ID-based continuation tokens.

- ValkeyStreamBuffer with AppendAsync, ReadAsync, GetEntryCountAsync, DeleteStreamAsync
- ValkeyStreamBufferOptions (KeyPrefix, MaxLength, JsonSerializerOptions)
- Uses Valkey.Glide with type-safe JSON serialization
- Unit tests with mocked client
- Sample demonstrating append, disconnect, and resume workflow

Signed-off-by: Matthias Howell <matthias.howell@improving.com>
Signed-off-by: Matthias Howell <matthias.howell@improving.com>
Upstream added AgentWithMemory_Step08_MemoryUsingCosmosNoSql, which
collides with this sample's step number. Bump to Step09 to avoid the
naming conflict.

Signed-off-by: MatthiasHowellYopp <matthias.howell@improving.com>

This branch was successfully deployed

1 active deployment
github-app-auth — 02f0b5ff Deployed Oct 20, 2026 by MatthiasHowellYopp via add_label #25817
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs .NET Usage: [Issues, PRs], Target: .Net

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants