feat(dotnet): add Hashbrown.DotNet ASP.NET Core adapter#466
feat(dotnet): add Hashbrown.DotNet ASP.NET Core adapter#466boomerman wants to merge 1 commit intoliveloveapp:mainfrom
Conversation
Introduces a new .NET package that exposes a streaming ASP.NET Core endpoint compatible with Hashbrown React and Angular clients. - Add MapHashbrownAgent() minimal API extension for one-line endpoint registration - Add AddHashbrown() DI extension that registers IHashbrownAgentService - Implement HashbrownAgentService with generate and load-thread operations - Implement FrameEncoder with big-endian length-prefix binary framing - Add CompletionCreateParams, Message, Frame, and related models - Support tool calling via AIFunctionFactory.CreateDeclaration - Support structured output via ChatResponseFormat.ForJsonSchema - Add HashbrownSample demonstrating Azure OpenAI integration - Add unit tests for FrameEncoder, models, DI extensions, and service - Add comprehensive README with integration guide
|
View your CI Pipeline Execution ↗ for commit ddd5255
☁️ Nx Cloud last updated this comment at |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ddd525537b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| var invokingContext = new InvokingContext(agent, null!, null!); | ||
| IEnumerable<ChatMessage> messages = await messageStore.InvokingAsync(invokingContext, cancellationToken); |
There was a problem hiding this comment.
Pass requested thread ID into thread loading
This path validates that request.ThreadId is present, but the actual load call never uses it and instead constructs InvokingContext with null! values. In any provider that stores multiple threads, load-thread cannot reliably fetch the caller’s thread and may return incorrect history (or fail if the provider expects non-null context metadata). Thread loading should be keyed by the requested thread id.
Useful? React with 👍 / 👎.
| List<ChatMessage> conversation = new(); | ||
|
|
||
| // Build conversation from request messages | ||
| foreach (var msg in request.Messages) | ||
| { |
There was a problem hiding this comment.
Load persisted context before generate with threadId
Generation builds conversation only from request.Messages and never hydrates prior messages from messageStore when request.ThreadId is set. In Hashbrown’s threaded flow, follow-up generate calls typically send only message deltas (see generateMessage in packages/core/src/effects/generate-message.effects.ts), so skipping server-side load drops prior context and breaks conversation continuity.
Useful? React with 👍 / 👎.
| await WriteFrame(context, new Frame | ||
| { | ||
| Type = "thread-save-success", | ||
| ThreadId = threadId | ||
| }, cancellationToken); |
There was a problem hiding this comment.
Persist thread before sending thread-save-success
When messageStore is configured, this block emits thread-save-start and then immediately reports thread-save-success without calling any persistence API, so clients are told the thread was saved even though no data was written. Subsequent load-thread requests can return stale or empty history despite a success frame.
Useful? React with 👍 / 👎.
|
|
Introduces a new .NET package that exposes a streaming ASP.NET Core endpoint compatible with Hashbrown React and Angular clients.
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Closes #
What is the new behavior?
Does this PR introduce a breaking change?
Other information