AmberPen Get started

Streaming mode

Streaming returns proofreading edits as soon as complete sections of a document are ready. Unlike token streaming, every value is a complete, validated edit array with offsets into the full text you submitted. You never need to reconstruct partial JSON or partial replacements.

Stream corrections

Use proofreadStream as an async iterator. Correct mode yields complete TextEdit[] batches in document order. Without a cached textId snapshot, the complete document is sent in one model request; stable prefixes of its streamed response are diffed as they arrive. Accumulating every batch produces the same edits as a regular correct-mode request.

import { applyEdits, createAmberPenClient } from "@amber-pen/sdk";

const amberPen = createAmberPenClient({ apiKey });
const edits = [];

for await (const batch of amberPen.proofreadStream({
	text,
	textId: "chapter-1",
	mode: "correct",
})) {
	// Each batch is a complete TextEdit[].
	edits.push(...batch);
}

// All offsets refer to the original text.
const correctedText = applyEdits(text, edits);

Keep the original text unchanged while consuming the stream. Every start and end offset refers to that original text; applying one batch immediately would shift the offsets needed by later batches. Accumulate the edits and apply them together, or represent them as editor decorations anchored to the original document.

Stream evaluated edits

With mode: "evaluate", AmberPen streams correction proposals from the same whole-document request. As soon as five proposals are available, they are sent through the high-reasoning evaluation pass and the complete EvaluatedEdit[] result is streamed back. The final group is evaluated even when it contains fewer than five edits. Evaluate mode is billed at twice the character usage of correct mode.

const evaluations = [];

for await (const batch of amberPen.proofreadStream({
	text,
	mode: "evaluate",
})) {
	// Each batch is a complete EvaluatedEdit[]: rejected proposals
	// are already dropped, so every edit is worth applying.
	for (const edit of batch) {
		console.log(edit.category, edit.explanation, edit.possibleReplacements);
	}
	evaluations.push(...batch);
}

const correctedText = applyEdits(text, evaluations);

Each evaluated edit lists its valid replacements in possibleReplacements, ranked by relevance, along with its category and a one-sentence explanation in the language of the submitted text. Proposals the evaluator rejects are left out of the stream entirely.

Ordering and batching

  • Correct mode sends the entire source text on a non-incremental request.
  • Incomplete response tokens remain buffered until the diff prefix is stable.
  • Evaluate mode consumes the same stable correction edits in groups of five.
  • Edit batches are still emitted in document order with globally sequential IDs.
  • Evaluation requests run concurrently, while completed results are emitted in proposal order.
  • Batches with no edits are omitted from the public iterator.

Cancel a stream

Pass an AbortSignal in the request options. Aborting stops the response and propagates cancellation to pending correction or evaluation requests. When a textId is present, an aborted stream does not replace the last successfully completed cached snapshot.

const controller = new AbortController();
cancelButton.addEventListener("click", () => controller.abort());

for await (const edits of amberPen.proofreadStream(
	{ text, textId: "chapter-1", mode: "correct" },
	{ signal: controller.signal },
)) {
	consume(edits);
}

Stream incremental updates

Pass a stable textId to combine streaming with incremental proofreading. The first request streams the whole text. Later requests stream only changed chunks and carry edits from untouched text into the result, still in document order with full-text offsets. The SDK caches the new snapshot only after every required chunk reaches its terminal [] marker; failed, cancelled, and partially consumed streams are never cached.

Use the HTTP API directly

Set stream: true and request application/x-ndjson. Every non-empty line is a complete edit array. A final empty array, [], marks successful completion and lets clients detect a truncated connection. Errors that occur after streaming starts are sent as a structured error object instead of an edit array.

curl -N https://api.amberpen.dev/proofread \
	-H "authorization: Bearer $AMBER_PEN_API_KEY" \
	-H "content-type: application/json" \
	-H "accept: application/x-ndjson" \
	-d '{ "text": "This are a sentnce.", "mode": "correct", "stream": true }'

[{"id":0,"start":5,"end":8,"original":"are","replacement":"is"}]
[{"id":1,"start":11,"end":18,"original":"sentnce","replacement":"sentence"}]
[]