Skip to content

Writer API

This package wraps the built-in Writer API. It adds session reuse, streaming, and optional result caching. For React, see useWriter.

Before shipping, review the Production checklist for safe rendering, progress, reversible suggestions, user control, and cache freshness.

Use prepareWriter to warm a session on user intent and release it when the feature closes. See the Session lifecycle guide.

import { write } from "@web-ai-sdk/writer";
const result = await write({
input: "An inquiry to my bank about how to enable wire transfers.",
context: "I'm a longstanding customer.",
tone: "formal",
length: "medium",
onUpdate: (text) => console.log("partial", text),
});
console.log(result.output, result.cached);

result.output is the generated text (trimmed), or null when the input is empty. result.cached tells you whether the response came from the cache without invoking the model.

interface WriteOptions {
input: string; // the writing task / prompt
context?: string; // per-call background info
language?: string; // BCP-47; drives input/output hints when supported
supportedLanguages?: readonly string[];
tone?: "formal" | "neutral" | "casual";
format?: "markdown" | "plain-text";
length?: "short" | "medium" | "long";
sharedContext?: string;
monitor?: (m: CreateMonitor) => void;
cache?: "session" | "local" | { get, set };
cacheKey?: string;
cacheTtl?: number; // built-in shortcut TTL in ms; default 1 hour
cacheRefresh?: boolean; // skip the cache read, write the fresh result
onUpdate?: (text: string) => void;
signal?: AbortSignal;
}
Name Type Description
input required string The writing task / prompt. Empty / whitespace resolves to { output: null }.
context string Optional per-call background information for the model.
language string BCP-47 language for input + output hints. Falls back to omitting hints if unsupported.
supportedLanguages readonly string[] Languages the model supports for hints. Defaults to ["en", "es", "ja"].
tone "formal" | "neutral" | "casual" Writing tone. Defaults to "neutral".
format "markdown" | "plain-text" Output format. Defaults to "markdown".
length "short" | "medium" | "long" Output length. Defaults to "short".
sharedContext string A hint shared across multiple write tasks.
monitor (m) => void Observe the first-call model download.
cache "session" | "local" | { get, set } Opt-in result cache.
cacheKey string Override the default cache key.
cacheTtl number TTL in milliseconds for entries written by the built-in "session" / "local" shortcuts. Defaults to one hour. Ignored by custom { get, set } caches.
cacheRefresh boolean Skip the cache read and replace the cached value after a successful run. The refreshed run reports cached: false.
onUpdate (text: string) => void Streaming update callback. Receives the cumulative buffer, not deltas.
signal AbortSignal Abort signal.
interface WriteResult {
output: string | null;
cached: boolean;
}
  1. Trim and cache check. Whitespace-only input short-circuits to null. If a cache is configured and has the key, return immediately.
  2. Cache Writer.create() sessions by create-options. First call pays the cold start; later same-config calls reuse the warm session.
  3. Stream writeStreaming() when the instance supports it, falling back to one-shot write(). Chunks are merged (delta or cumulative) and pushed to onUpdate as the cumulative buffer.
  4. Optionally cache the final output when you pass a cache. Off by default. Built-in "session" / "local" entries expire after one hour by default. Pass cacheTtl (milliseconds) to change the TTL per call. Pass cacheRefresh: true to skip the read and replace the cached value after a successful run. Custom { get, set } caches own their expiry policy.

The wrapper trims leading/trailing whitespace only, so internal markdown formatting and line breaks the model produces stay intact.

The vanilla write() throws WriterUnavailableError when the API is missing:

import { write, WriterUnavailableError } from "@web-ai-sdk/writer";
try {
const result = await write({ input: task });
} catch (err) {
if (err instanceof WriterUnavailableError) return;
throw err;
}

AbortSignal is supported. Aborting mid-stream resolves cleanly; an opt-in result cache is not written for aborted runs.