NewHeap.Platform.AI.Chat.AspNet
7.6.0
dotnet add package NewHeap.Platform.AI.Chat.AspNet --version 7.6.0
NuGet\Install-Package NewHeap.Platform.AI.Chat.AspNet -Version 7.6.0
<PackageReference Include="NewHeap.Platform.AI.Chat.AspNet" Version="7.6.0" />
<PackageVersion Include="NewHeap.Platform.AI.Chat.AspNet" Version="7.6.0" />
<PackageReference Include="NewHeap.Platform.AI.Chat.AspNet" />
paket add NewHeap.Platform.AI.Chat.AspNet --version 7.6.0
#r "nuget: NewHeap.Platform.AI.Chat.AspNet, 7.6.0"
#:package NewHeap.Platform.AI.Chat.AspNet@7.6.0
#addin nuget:?package=NewHeap.Platform.AI.Chat.AspNet&version=7.6.0
#tool nuget:?package=NewHeap.Platform.AI.Chat.AspNet&version=7.6.0
NewHeap.Platform.AI.Chat.AspNet
ASP.NET Core assistant endpoints with server-sent event streaming and approval decisions for NewHeap AI.
Registration
Register the application's AI services and AddNewHeapPlatformAIAspNet first, then
the assistant, and map the endpoints:
services.AddNewHeapPlatformAIAspNet(ai => ai.AddActiveDivisionScope("app.active-division.project.view"));
services.AddNewHeapAssistant(assistant => assistant
.UsePostgreSql(connectionString, options => { options.Schema = "nhai"; options.RunMigrations = true; })
.UseAccessPolicy("app.assistant.access")
.UseChatProfile("project-assistant-chat")
.UseAdminPolicy("app.assistant.admin")
.UseDefaultApplicationContext(applicationContextAsset)
.UseTimeZone("Europe/Amsterdam")
.UseTurnContextProvider<ApplicationTurnContextProvider>()
.ConfigureMcp(mcp => mcp.AllowedHosts.Add("planning.example.com"))
.AddAgent(agent)
.AddToolPresenter<ApplicationAssistantToolPresenter>()
.AddBusinessAuditSink<ApplicationAssistantAuditSink>()
.WithLimits(limits => limits.MaxToolCallsPerTurn = 8));
endpoints.MapNewHeapAssistant("/api/assistant");
Startup fails when the ASP.NET AI integration, the access or admin policy, an agent profile or
policy is missing, or when the invocation gate or a durable manager was replaced after
the assistant. AddNewHeapAssistant is idempotent. The assistant relies on the
registered INhAiAuthenticatedInvocationContextResolver; a replaced resolver is used
as is, and no tenant claim is required.
INhAssistantToolPresenter is optional. Use it for application-localized names and
approval explanations sourced from authorized server-side data. Presentation is
persisted beside, but never substituted for, the exact proposal evidence. The API
returns it as optional approval.presentation; clients must support null for old
approvals and tools without a presenter.
Configuration
| Key | Default | Meaning |
|---|---|---|
NewHeap:AI:Assistant:Enabled |
false |
Kill switch. Off: GET status returns { enabled: false, agents: [] }, all other endpoints 404. |
NewHeap:AI:Assistant:AccessPolicy |
app.assistant.access |
Policy every endpoint requires, unless UseAccessPolicy sets one. |
NewHeap:AI:Assistant:AdminPolicy |
app.assistant.admin |
Additional policy for admin/*, unless UseAdminPolicy sets one. |
NewHeap:AI:Assistant:Mcp:RequireHttps |
true |
MCP servers must use https; plain http is allowed only to loopback in Development. |
NewHeap:AI:Assistant:Mcp:AllowedHosts |
empty (any public host) | Optional allow-list of MCP hosts. Link-local and metadata addresses are always blocked. |
NewHeap:AI:Assistant:Mcp:ForwardUserTokenHosts |
empty | Exact hosts that may receive the caller's token (forward-user-token). |
NewHeap:AI:Assistant:Mcp:ToolListCacheDuration |
00:05:00 |
Cache duration of remote tool lists. |
NewHeap:AI:Assistant:Mcp:ConnectTimeout |
00:00:10 |
Connect timeout for MCP servers. |
Endpoints
| Method and path | Response |
|---|---|
GET status |
AssistantStatus |
GET agents |
agents whose required policy the caller satisfies |
GET conversations?page=&itemsPerPage= |
{ items, total } |
POST conversations { agentId, title? } |
201 conversation |
GET conversations/{id} |
conversation with messages and pending approval |
DELETE conversations/{id} |
204; the conversation is archived and hidden |
POST conversations/{id}/messages { text, clientMessageId, clientContext? } |
text/event-stream; 409 when the conversation is not idle |
POST conversations/{id}/approvals/{approvalId}/decide { decision, expectedProposalHash, reason? } |
text/event-stream of the resumed turn |
POST conversations/{id}/cancel |
202 |
GET / PUT preferences |
the caller's style preferences |
Administration endpoints additionally require the admin policy:
| Method and path | Response |
|---|---|
GET / PUT context, GET context/versions |
application context; PUT takes expectedVersion |
GET tools |
local and bridge tools that selectors can match |
GET / POST agents, PUT / DELETE agents/{id}, POST agents/{id}/reset |
code and admin agents; updates take expectedVersion, code agents are reset instead of deleted |
GET / POST mcp-servers, PUT / DELETE mcp-servers/{id} |
MCP servers; secrets are write-only (hasSecret) |
POST mcp-servers/{id}/test, POST mcp-servers/{id}/sync |
connection test and tool sync; sync returns 502 when the server is unreachable or rejects the credentials |
GET mcp-servers/{id}/tools, PUT mcp-servers/{id}/tools/{remoteName} |
synced tools; activate them and set their effect |
Every error of preferences and admin/* has the body { code, messageKey, errors? }.
Validation errors return 400 with code assistant-validation and errors keyed by
camelCase field name (values required, invalid, too-long, not-found); blocked
hosts return 400 with assistant-mcp-host-blocked. A caller without the admin policy
receives 403 with assistant-forbidden, unknown objects 404 with a specific
*-not-found code and stale versions 409. MCP secrets are protected with ASP.NET Data Protection; persist the key
ring across restarts and nodes.
clientContext is { route, title?, entities?: [{ type, id, label? }] } (route 200,
title 120, five entities, dash-case type, id 64, label 120 characters). The server cuts
off long text and ignores a value of the wrong shape instead of answering 400.
JSON is camelCase through one source-generated NhAssistantJsonSerializerContext.
Errors outside the stream use { code, messageKey } with messageKey = nh-assistant.errors.<code>. Conversations are visible to their owner only; other
callers receive 404.
Streaming
Each event is written as event: <name>, data: <json> and an empty line:
turn.started, message.delta, tool.started, tool.completed,
approval.required, turn.completed or error. A : keep-alive comment follows
every 15 seconds without events, and the stream closes after turn.completed or
error. Response buffering is disabled and X-Accel-Buffering: no is set for
reverse proxies. A client disconnect cancels the turn and releases the conversation.
Browser clients use fetch streaming, because EventSource cannot send an
Authorization header.
| 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
- NewHeap.Platform.AI.AspNet.Common (>= 7.6.0)
- NewHeap.Platform.AI.Chat (>= 7.6.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.