← Toute la documentation
IA / Serveur

Fournisseurs, streaming et export DOCX

Des compléments côté serveur à l’AI Toolkit, tous fournis dans le package NuGet RichTextBox.AspNetCore (1.0.0-preview.11+). Une ligne d’injection de dépendances pour brancher un vrai fournisseur, du streaming SSE de bout en bout, et un point de terminaison HTML → DOCX.

Résolveurs de fournisseurs intégrés

Trois implémentations prêtes à l’emploi d'IRichTextBoxAiResolver, qui utilisent HttpClientFactory, l’annulation et ILogger<T>. Choisissez-en une et enregistrez-la dans Program.cs :

using RichTextBox.AiResolvers;

builder.Services.AddRichTextBox();
builder.Services.AddRichTextBoxOpenAiResolver(opts =>
{
    opts.ApiKey = builder.Configuration["OpenAI:ApiKey"];
    opts.Model  = "gpt-6-luna";
});

Remplacez AddRichTextBoxOpenAiResolver par AddRichTextBoxAnthropicResolver ou AddRichTextBoxAzureOpenAiResolver. Les trois partagent AiResolverOptions :

public class AiResolverOptions
{
    public string  ApiKey        { get; set; }       // required
    public string? Model         { get; set; }       // provider-specific default
    public string? BaseUrl       { get; set; }       // for proxies / Ollama / Groq
    public int     MaxTokens     { get; set; } = 1024;
    public double  Temperature   { get; set; } = 0.4;
    public string? SystemSuffix  { get; set; }       // appended to every mode's system prompt
    public TimeSpan Timeout      { get; set; } = 60s;
}

Azure a trois options supplémentaires sur AzureOpenAiResolverOptions : Endpoint (https://my-resource.openai.azure.com), DeploymentName (et non le modèle) et ApiVersion (facultatif).

OpenAiResolver fonctionne avec n’importe quel point de terminaison compatible OpenAI — redéfinissez BaseUrl pour Groq, Together.ai ou un Ollama local.

Réponses en streaming (Server-Sent Events)

MapRichTextBoxUploads() déclare aussi POST /richtextbox/ai/stream (configurable via RichTextBoxOptions.AiStreamEndpoint). Les résolveurs OpenAI et Anthropic implémentent IStreamingRichTextBoxAiResolver ; les fournisseurs sans streaming se rabattent de façon transparente sur une seule trame de données.

Format des échanges

data: <json-encoded delta string>\n\n
data: <json-encoded delta string>\n\n
...
event: response
data: { ...RichTextBoxAiResponse payload... }\n\n
event: done
data: {}\n\n

Client

var stream = editor.aiToolkit.streamRequest({
    url: "/richtextbox/ai/stream",
    body: { mode: "rewrite", selectionText: "..." },
    onDelta:    function (chunk, full) { /* render progressively */ },
    onResponse: function (payload)     { /* final structured result */ },
    onDone:     function (fullText)    { },
    onError:    function (err)         { }
});
// stream.abort()  — cancel mid-response
// stream.promise  — resolves with the concatenated full text

La fonction utilitaire utilise fetch + ReadableStream. Les navigateurs sans streaming se rabattent automatiquement sur une XHR vers le point de terminaison sans streaming.

Export DOCX

MapRichTextBoxUploads() déclare aussi POST /richtextbox/export/docx (configurable via DocxExportEndpoint). Repose sur DocumentFormat.OpenXml, sous licence MIT. Aucun service externe.

Requête

POST /richtextbox/export/docx
Content-Type: application/json

{
    "html": "<h1>Memo</h1><p>Body.</p>",
    "title": "Memo",
    "fileName": "memo.docx"
}

Réponse

Un flux binaire avec Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document et Content-Disposition: attachment; filename=memo.docx.

HTML pris en charge

  • Paragraphes, h1–h6, blockquote, pre, hr
  • Listes ordonnées et non ordonnées imbriquées
  • Tableaux (avec lignes d’en-tête)
  • En ligne : b/strong, i/em, u, s/del, sub, sup, code, br
  • Liens hypertexte, images en ligne (URI data uniquement — les URL externes sont ignorées par sécurité)
  • Attributs de style : font-weight, font-style, text-decoration, color, background-color, text-align

Fonction utilitaire côté client

editor.aiToolkit.exportDocx({
    url:      "/richtextbox/export/docx",
    fileName: "report.docx",
    title:    "Quarterly report"
});

Résolveurs personnalisés

Pour Bedrock, Gemini, votre propre modèle ou n’importe quoi d’autre, implémentez IRichTextBoxAiResolver (et éventuellement IStreamingRichTextBoxAiResolver) et enregistrez votre classe. Le reste de l’AI Toolkit est indépendant du fournisseur.

public sealed class MyBedrockResolver : IRichTextBoxAiResolver
{
    public async ValueTask<RichTextBoxAiResponse> ResolveAsync(
        RichTextBoxAiRequest request, CancellationToken cancellationToken = default)
    {
        // ...call Bedrock, map response to RichTextBoxAiResponseBuilder...
    }
}

builder.Services.AddRichTextBox();
builder.Services.AddSingleton<IRichTextBoxAiResolver, MyBedrockResolver>();