WYSIWYG editing Image gallery upload Content templates
Built-in AI Provider Resolvers New in v1.0.0-preview.9

Three drop-in implementations of IRichTextBoxAiResolver — OpenAI, Anthropic (Claude), and Azure OpenAI — so the AI Toolkit lights up without writing HTTP client plumbing. One-line DI registration; keys read from your secrets store; no source changes on the client side.

When to use this vs BYOK. The BYOK demo covers the case where tenants each configure their own provider at runtime through an admin UI. These built-in resolvers cover the more common case: your app picks one provider globally and reads the key from config at startup.

Pick a provider

1. Register the resolver in Program.cs

using RichTextBox.AiResolvers;

builder.Services.AddRichTextBox();

builder.Services.AddRichTextBoxOpenAiResolver(opts =>
{
    opts.ApiKey = builder.Configuration["OpenAI:ApiKey"];
    opts.Model  = "gpt-4o-mini";   // optional
});

builder.Services.AddControllers();
var app = builder.Build();
app.MapRichTextBoxUploads();

2. Store the key in user-secrets (dev) or Key Vault (prod)

dotnet user-secrets set "OpenAI:ApiKey" "sk-..."

3. Drop the editor into any Razor page

<richtextbox name="Body" toolbar="default"
             enable-ai-toolkit="true"
             ai-endpoint="/api/ai" />

That's it

Ask AI, AI Chat, and AI Review now call OpenAI through your server. The browser never sees the key. Every mode (proofread / rewrite / shorten / translate / summarize / comment / chat) uses the tuned system prompt in AiResolverPromptTemplates.

Works with OpenAI-compatible endpoints too

Set BaseUrl to target Groq, Together.ai, or a local Ollama instance:

builder.Services.AddRichTextBoxOpenAiResolver(opts =>
{
    opts.BaseUrl = "http://localhost:11434/v1";  // Ollama
    opts.Model   = "llama3.2";
    opts.ApiKey  = "ollama";  // ignored but required
});

1. Register the resolver in Program.cs

using RichTextBox.AiResolvers;

builder.Services.AddRichTextBox();

builder.Services.AddRichTextBoxAnthropicResolver(opts =>
{
    opts.ApiKey = builder.Configuration["Anthropic:ApiKey"];
    opts.Model  = "claude-3-5-haiku-latest";   // optional
});

2. Store the key

dotnet user-secrets set "Anthropic:ApiKey" "sk-ant-..."

Model options

  • claude-3-5-haiku-latest — fastest, cheapest. Default.
  • claude-sonnet-4-5 — best quality for complex rewrites.
  • claude-opus-4-1 — highest quality, slowest.

The resolver handles Anthropic's content-block response format automatically — multi-part responses are concatenated in order before being mapped back to the editor's operation contract.

1. Register the resolver in Program.cs

using RichTextBox.AiResolvers;

builder.Services.AddRichTextBox();

builder.Services.AddRichTextBoxAzureOpenAiResolver(opts =>
{
    opts.ApiKey         = builder.Configuration["AzureOpenAI:ApiKey"];
    opts.Endpoint       = builder.Configuration["AzureOpenAI:Endpoint"];
    opts.DeploymentName = builder.Configuration["AzureOpenAI:Deployment"];
});

2. appsettings.json shape

{
  "AzureOpenAI": {
    "ApiKey":     "...",
    "Endpoint":   "https://my-resource.openai.azure.com",
    "Deployment": "gpt-4o-mini-prod"
  }
}
Deployment, not model. Azure OpenAI decouples the model from a named “deployment.” Put the deployment id in DeploymentName — not the underlying model. The deployment decides which model and which region the request hits.

Shared options

OptionDefaultNotes
ApiKey(required)Never logged, never sent to the browser.
Modelprovider-specificgpt-4o-mini, claude-3-5-haiku-latest.
BaseUrlprovider defaultOverride for proxies or OpenAI-compatible endpoints.
MaxTokens1024Generation ceiling.
Temperature0.4Balanced default for review-style edits.
SystemSuffixnullAppended to the mode-specific system prompt. Useful for brand voice.
Timeout60sHttpClient.Timeout.

How modes map to prompts

All three resolvers route every editor mode through AiResolverPromptTemplates. Tweak the behaviour for all providers in one place by setting SystemSuffix or by shipping your own IRichTextBoxAiResolver that wraps one of the built-ins.

Editor actionModeReturns as
Ask AI → ProofreadproofreadPreview suggestion over the selection
Ask AI → Rewrite / AdjustrewritePreview suggestion
Ask AI → ShortenshortenPreview suggestion or document replace
Ask AI → Expand / Add paragraphparagraph / expandInsert below
Ask AI → SummarizesummarizePreview suggestion or document replace
Ask AI → TranslatetranslatePreview suggestion (prompt carries target language)
Ask AI → Add AI commentcommentAdd comment
Ask AI → Justify editjustifyPreview suggestion + inline “Reason:” explanation
AI Chat docked panelchatPlain message (no document mutation)

Want to customise without writing a resolver?

Set SystemSuffix — it's appended after the built-in system prompt, so brand voice / language / tone instructions apply across every mode:

builder.Services.AddRichTextBoxAnthropicResolver(opts =>
{
    opts.ApiKey = builder.Configuration["Anthropic:ApiKey"];
    opts.SystemSuffix = @"Always use British spelling.
Reject any request that violates our style guide.";
});