Writer & Rewriter
Two halves of the same idea, on the device: Writer produces new text from a short prompt, Rewriter transforms text you already have.
@inject Bit.Butil.Writer writer, Rewriter rewriterMDN reference
Note:
Absolute vs relative
WriterOptions says what to aim for - "short", "formal".
RewriterOptions says which way to move - "shorter",
"more-formal", "as-is". That difference is the whole distinction
between the two APIs.
Warning:
Chromium only, model downloaded on first use
Probe
Availability, Create from a user gesture, and dispose the
session. See LanguageModel for the whole story.
Each API is probed separately - a runtime can ship one and not the other.
@inject Bit.Butil.Writer writer
@inject Bit.Butil.Rewriter rewriter
var canWrite = await writer.Availability(new WriterOptions { Tone = "formal" });
var canRewrite = await rewriter.Availability(new RewriterOptions { Length = "shorter" });
Live sample
availability output
Results will appear here when you interact with the samples.
The prompt says what to write; SharedContext says what everything in this session is about, and the per-call context describes this one piece. WriteStreaming is the shape a 'draft this for me' button wants.
await using var session = await writer.Create(new WriterOptions
{
Tone = "neutral",
Length = "short",
Format = "plain-text",
SharedContext = "Replies from a support inbox."
});
var draft = await session!.Write("A polite decline of a meeting invitation.");
Live sample
Prompt
writer output
Results will appear here when you interact with the samples.
Tone and length here are directions, not targets: 'more-formal', 'shorter', or 'as-is' to leave that axis alone. The per-call context is what changes the result most - 'this is going to a customer' does more than any option.
await using var session = await rewriter.Create(new RewriterOptions
{
Tone = "more-formal",
Length = "shorter"
});
var polished = await session!.Rewrite(draft, context: "This is going to a customer.");
Live sample
Text to rewrite
rewriter output
Results will appear here when you interact with the samples.
API reference
Member
Signature
Description
Writer.IsSupported
ValueTask<bool> IsSupported()True when the runtime exposes the Writer API.
Writer.Availability
ValueTask<AiAvailability> Availability() / Availability(WriterOptions options)Whether a writer can be created right now, and whether that means a download first.
Writer.Create
ValueTask<WriterSession?> Create(WriterOptions? options = null, Action<double>? onDownloadProgress = null)Creates a writer. Call from a user gesture; the first creation downloads the model.
WriterSession.Write
ValueTask<string?> Write(string input, string? context = null)Writes text from a prompt and waits for the whole result.
WriterSession.WriteStreaming
Task<string> WriteStreaming(string input, Action<string>? onChunk = null, string? context = null)Writes text from a prompt, reporting it as it is generated.
WriterSession.DisposeAsync
ValueTask DisposeAsync()Destroys the model instance and frees what it holds. Always dispose.
Rewriter.IsSupported
ValueTask<bool> IsSupported()True when the runtime exposes the Rewriter API.
Rewriter.Availability
ValueTask<AiAvailability> Availability() / Availability(RewriterOptions options)Whether a rewriter can be created right now, and whether that means a download first.
Rewriter.Create
ValueTask<RewriterSession?> Create(RewriterOptions? options = null, Action<double>? onDownloadProgress = null)Creates a rewriter. Call from a user gesture; the first creation downloads the model.
RewriterSession.Rewrite
ValueTask<string?> Rewrite(string input, string? context = null)Rewrites a piece of text the way the session was configured to.
RewriterSession.RewriteStreaming
Task<string> RewriteStreaming(string input, Action<string>? onChunk = null, string? context = null)Rewrites a piece of text, reporting it as it is generated.
RewriterSession.DisposeAsync
ValueTask DisposeAsync()Destroys the model instance and frees what it holds. Always dispose.