Bitzsoft.Integrations.AI.AspNetCore 1.1.0

dotnet add package Bitzsoft.Integrations.AI.AspNetCore --version 1.1.0
                    
NuGet\Install-Package Bitzsoft.Integrations.AI.AspNetCore -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Bitzsoft.Integrations.AI.AspNetCore" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Bitzsoft.Integrations.AI.AspNetCore" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Bitzsoft.Integrations.AI.AspNetCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Bitzsoft.Integrations.AI.AspNetCore --version 1.1.0
                    
#r "nuget: Bitzsoft.Integrations.AI.AspNetCore, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Bitzsoft.Integrations.AI.AspNetCore@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Bitzsoft.Integrations.AI.AspNetCore&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Bitzsoft.Integrations.AI.AspNetCore&version=1.1.0
                    
Install as a Cake Tool

Bitzsoft.Integrations.AI.AspNetCore

面向企业多租户 ASP.NET Core AI 宿主的零 ORM 依赖、原生 AOT 兼容 HTTP 传输、错误治理与全业务端点辅助库。统一封装 SSE / NDJSON 零缓冲流式写出、RFC 9457 问题详情脱敏映射、已认证调用者租户 Fail-Closed 绑定、对话/后台长任务/多模态(STT/TTS/图像)Minimal API 与控制器辅助,以及面向存量 MVC 控制器的显式反射候选工具发现承接包。

版本与兼容性

dotnet add package Bitzsoft.Integrations.AI.AspNetCore
  • 目标框架:net8.0;net10.0;
  • 项目依赖:Bitzsoft.Integrations.AI.Abstractions、Bitzsoft.Integrations.AI.Conversation、Bitzsoft.Integrations.McpServer;
  • 框架依赖:FrameworkReference Include="Microsoft.AspNetCore.App";
  • 原生 AOT 策略:工程启用 <IsAotCompatible>true</IsAotCompatible>,核心链路全量采用 AIAspNetCoreJsonContext 源生成序列化与零反射 RequestDelegate;仅存量 MVC 反射扫描扩展类显式标注 [RequiresUnreferencedCode] 与 [RequiresDynamicCode],不干扰纯原生 AOT 宿主零 IL 警告交付。

核心模块与设计边界

模块 核心类型与扩展 工程能力与安全边界
A. 原生 AOT 源生成序列化上下文 AIAspNetCoreJsonContext(.Default / .Relaxed) 为 AIStreamFrame、BitzAIProblemDetailsResponse、BitzAICallerContext、后台长任务及 STT/TTS/图像强类型契约生成零反射 JSON 元数据,.Relaxed 开启中文非转义、camelCase 与忽略 null 字段
B. RFC 9457 异常映射与统一中间件 BitzAIProblemDetailsMapper、MapToProblemDetails、UseBitzAIExceptionHandler 统一将 IAIDomainException(SuggestedHttpStatusCode、ErrorCode、IsRetryable、RetryAfter、TraceId)、IntegrationException、AIStreamIdleTimeoutException 与运行时异常映射为脱敏 application/problem+json;自动写出 Retry-After 与 X-Error-Code 响应头并剔除密钥与本机路径
C. 租户与用户安全上下文绑定器 BitzAICallerHttpContextResolver、IBitzAICallerHttpContextResolver、BitzAICallerContext 严格仅从已认证 ClaimsPrincipal 声明(及 McpInProcessContextScope)解析 TenantId、UserId、角色与权限,彻底免疫 X-Tenant-Id / X-User-Id 请求头伪造,缺省身份或租户即 Fail-Closed 抛出 401/403 AIDomainException
D. 零缓冲流式写出器与状态帧扩展 IAIStreamResponseWriter、AIStreamResponseWriter、AIStreamResponseWriterExtensions 禁用响应缓冲并按帧即时 FlushAsync 输出 SSE / NDJSON;WriteStreamWithPrefetchAsync 支持首帧异常前切回 RFC 9457 错误响应;提供 CreateHitlApprovalFrame、CreateHitlSuspendedFrame、CreateDryRunPreviewFrame、CreateContinuationStatusFrame 与 CreateFinOpsUsageFrame 辅助
E. 对话、后台任务与多模态端点辅助 BitzAIConversationEndpointHelper、BitzAIBackgroundJobEndpointHelper、BitzAIMultimodalEndpointHelper 统一复用调用者绑定与 RFC 9457 错误出口:ExecuteOrchestratedTurnStreamAsync 自动压入 McpInProcessContextScope;MapBitzAIBackgroundJobEndpoints 提供 GET /{jobId} 与 POST /{jobId}/cancel 并校验租户/用户归属;MapBitzAIMultimodalEndpoints 覆盖 /stt、/stt/stream、/tts、/tts/audio 与 /images;FetchSafeRemoteImageBytesAsync 提供公网 IP / DNS 重绑定 ConnectCallback、最多 3 跳手动重定向、字节上限与光栅魔数校验
F. MVC 控制器只读反射发现(非 AOT 可选) McpMvcCandidateDiscoverySource、AddBitzMcpMvcCandidateDiscovery、McpActionReadOnlyClassifier、McpControllerActionToolBuilder 从 McpServer 剥离下沉 ASP.NET MVC 反射依赖,对接 IMcpCandidateDiscoverySource 与 McpInProcessContextScope.Push;每次调用创建并释放独立 AsyncServiceScope,请求头按安全白名单与身份前缀阻断转发,提供 ResolveReadOnlyActionMethod / BindActionParameters(含值类型 DTO);无权限注解候选默认拒绝(SuggestedPermissionCodes == null),反射入口均显式标注 [RequiresUnreferencedCode] / [RequiresDynamicCode]

一站式装配与异常中间件

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddBitzsoftAIAspNetCore(
    configureStreamWriter: o => o.DefaultFormat = AIStreamFormat.Sse,
    configureCallerResolution: o => o.AllowFallbackTenantZero = false,
    configureProblemDetails: o => o.IncludeExceptionDetails = builder.Environment.IsDevelopment());

// 若存量 MVC 宿主需自动扫描只读控制器动作作为 MCP 候选工具(非 AOT 场景):
// builder.Services.AddBitzMcpGovernanceCore();
// builder.Services.AddBitzMcpMvcCandidateDiscovery();

var app = builder.Build();
app.UseBitzAIExceptionHandler();
app.MapBitzAIBackgroundJobEndpoints("/api/ai/jobs").RequireAuthorization();
app.MapBitzAIMultimodalEndpoints("/api/ai/multimodal").RequireAuthorization();

完整最小示例

以下独立示例演示注入 ASP.NET Core AI 传输层服务、映射 AIDomainException 为脱敏 RFC 9457 详情、绑定已认证 HTTP 调用者上下文,以及零缓冲输出 HITL 审批、FDE 试运行预览与 FinOps 用量帧:

using System.Security.Claims;
using System.Text;
using System.Text.Json;
using Bitzsoft.Integrations.AI.Abstractions;
using Bitzsoft.Integrations.AI.AspNetCore;
using Bitzsoft.Integrations.AI.Conversation;
using Bitzsoft.Integrations.AI.Governance;
using Bitzsoft.Integrations.Core;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddBitzsoftAIAspNetCore();
await using ServiceProvider provider = services.BuildServiceProvider(
    new ServiceProviderOptions { ValidateOnBuild = true, ValidateScopes = true });

// 1. 解析并 Fail-Closed 校验已认证调用者租户与身份(免疫 X-Tenant-Id 请求头伪造)。
var httpContext = new DefaultHttpContext
{
    RequestServices = provider,
    TraceIdentifier = "trace-demo-01",
    User = new ClaimsPrincipal(new ClaimsIdentity(
    [
        new Claim(ClaimTypes.NameIdentifier, "lawyer-1001"),
        new Claim("TenantId", "tenant-sh-01"),
        new Claim("permission", "contracts:review"),
    ], "Bearer")),
};
httpContext.Request.Headers["X-Tenant-Id"] = "attacker-tenant";

var callerResolver = provider.GetRequiredService<IBitzAICallerHttpContextResolver>();
BitzAICallerContext caller = callerResolver.Resolve(httpContext);

// 2. 将领域异常统一映射为脱敏 RFC 9457 响应模型(支持 RetryAfter 与 TraceId)。
var problemMapper = provider.GetRequiredService<BitzAIProblemDetailsMapper>();
var rateLimitEx = new AIDomainException(
    errorCode: AIExecutionErrorCodes.RateLimited,
    message: "上游模型限流,请退避后重试",
    suggestedHttpStatusCode: StatusCodes.Status429TooManyRequests,
    provider: "deepseek",
    failureKind: IntegrationFailureKind.RateLimited,
    isRetryable: true,
    retryAfter: TimeSpan.FromSeconds(10));
BitzAIProblemDetailsResponse problem = problemMapper.MapToResponse(rateLimitEx, httpContext);

// 3. 构造 HITL 挂起、DryRun 试运行预览与 FinOps 计费终结帧并零缓冲写出 SSE。
var checkpoint = new AIHitlCheckpointState(
    PendingActionId: "act-demo-1",
    TenantId: caller.TenantId,
    UserId: caller.UserId,
    SessionId: "sess-demo-1",
    RequestId: "req-demo-1",
    TurnId: "turn-1",
    AgentCode: "contract-agent",
    ToolCallId: "call-1",
    ToolName: "seal_contract",
    ArgumentsJson: """{"contractId":"c-01"}""",
    ArgumentsHash: "hash-c01",
    SuspendedStateJson: null,
    Status: AIHitlSuspendStatus.Suspended,
    CreatedAt: DateTimeOffset.UtcNow,
    ExpiresAt: DateTimeOffset.UtcNow.AddMinutes(15));

AIStreamFrame[] frames =
[
    AIStreamResponseWriterExtensions.CreateHitlApprovalFrame(checkpoint),
    AIStreamResponseWriterExtensions.CreateDryRunPreviewFrame("call-2", "update_status", wouldMutate: true, message: "预览:将更新 1 条记录"),
    AIStreamResponseWriterExtensions.CreateFinOpsUsageFrame(new AIFinOpsUsageRecord
    {
        TenantId = caller.TenantId,
        UserId = caller.UserId,
        SessionId = "sess-demo-1",
        RequestId = "req-demo-1",
        ModelId = "deepseek-chat",
        InputTokens = 500,
        OutputTokens = 120,
        EstimatedCost = 0.0042m,
    }),
];

await using var responseStream = new MemoryStream();
httpContext.Response.Body = responseStream;
var writer = provider.GetRequiredService<IAIStreamResponseWriter>();
await writer.WriteStreamWithPrefetchAsync(httpContext, ToAsyncFrames(frames), problemMapper, AIStreamFormat.Sse);

string sseOutput = Encoding.UTF8.GetString(responseStream.ToArray());
string problemJson = JsonSerializer.Serialize(problem, AIAspNetCoreJsonContext.Relaxed.BitzAIProblemDetailsResponse);
Console.WriteLine($"租户={caller.TenantId},错误码={problem.ErrorCode},SSE长度={sseOutput.Length},RFC9457={problemJson}");

static async IAsyncEnumerable<AIStreamFrame> ToAsyncFrames(AIStreamFrame[] items)
{
    foreach (AIStreamFrame item in items)
    {
        yield return item;
        await Task.Yield();
    }
}
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.1.0 0 11/14/2026
1.0.5 101 11/7/2026