React UI
Completion
Build prompt-to-text completion surfaces with @anvia/react-ui.
CompletionProvider binds a useCompletion(...) controller to completion primitives. Use it for
prompt-to-text panels, draft generators, rewrite tools, and other one-shot text generation flows.
Use completion when the UI has one prompt and one generated text result. Use
Chat and composer when the user expects a multi-turn transcript, tools,
attachments, suggestions, or human review. CompletionProvider only supports Completion.*
primitives; it does not provide Thread, Composer, Message, or HumanInput contexts.
import { useCompletion } from "@anvia/react";
import { Completion, CompletionProvider } from "@anvia/react-ui";
export function CompletionPanel() {
const completion = useCompletion({ endpoint: "http://localhost:8787/api/completion" });
return (
<CompletionProvider controller={completion}>
<Completion.Root className="completion">
<Completion.Output className="completion-output" />
<Completion.Form className="completion-form">
<Completion.Input placeholder="Draft a product update..." />
<Completion.Stop>Stop</Completion.Stop>
<Completion.Submit>Generate</Completion.Submit>
</Completion.Form>
</Completion.Root>
</CompletionProvider>
);
}.completion {
width: min(760px, 100%);
display: grid;
gap: 16px;
}
.completion-output {
min-height: 220px;
border: 1px solid #3f3f46;
border-radius: 12px;
background: #18181b;
padding: 16px;
white-space: pre-wrap;
}
.completion-form {
display: grid;
gap: 10px;
}
.completion-form textarea {
min-height: 120px;
resize: vertical;
}import { useCompletion } from "@anvia/react";
import { Completion, CompletionProvider } from "@anvia/react-ui";
export function CompletionPanel() {
const completion = useCompletion({ endpoint: "http://localhost:8787/api/completion" });
return (
<CompletionProvider controller={completion}>
<Completion.Root className="grid w-full max-w-3xl gap-4">
<Completion.Output className="min-h-56 whitespace-pre-wrap rounded-xl border border-zinc-700 bg-zinc-900 p-4" />
<Completion.Form className="grid gap-2.5">
<Completion.Input className="min-h-32 resize-y rounded-xl border border-zinc-700 bg-zinc-950 p-3 outline-none" placeholder="Draft a product update..." />
<div className="flex gap-2">
<Completion.Stop>Stop</Completion.Stop>
<Completion.Submit>Generate</Completion.Submit>
</div>
</Completion.Form>
</Completion.Root>
</CompletionProvider>
);
}The endpoint uses the same React request shape as chat:
import { createCompletionStream, type UIStreamRequest } from "@anvia/core";
import { createEventStream } from "@anvia/server";
export async function POST(request: Request) {
const body = (await request.json()) as UIStreamRequest;
return createEventStream(
createCompletionStream(model, {
instructions: "Draft concise release notes.",
messages: body.messages,
}),
);
}
Custom output
Completion.Output renders plain output by default. Use a child function when your app needs a
custom empty, loading, or result view.
<Completion.Output>
{(output) => (
<article className="completion-result" aria-live="polite">
{output.length > 0 ? output : "Your draft will appear here."}
</article>
)}
</Completion.Output>
Form controls
Completion.Form submits through the controller. Completion.Input tracks prompt text,
Completion.Submit disables when the prompt cannot be submitted, and Completion.Stop stops a
streaming completion.
<Completion.Form className="completion-form">
<Completion.Input placeholder="Write a launch note..." />
<Completion.Stop>Stop</Completion.Stop>
<Completion.Submit>Generate</Completion.Submit>
</Completion.Form>
For a complete completion panel, see Completion panel.
