AI chat
A streaming chat page with zero client JavaScript. No /api/chat route, no EventSource, no client state library — the tokens are a server-side loop writing to this.answer, and @task streams the field. Cancel aborts the generation itself, not just the UI.
@expose prompt = "";
@expose answer = "";
@task async ask() { // streaming, cancellable, server-side
this.answer = "";
for await (const chunk of Ai.stream({
prompt: this.prompt,
system: "Answer in two or three sentences.",
signal: this.signal, // $flow.cancel() aborts the generation
})) {
if (chunk.type === "text") this.answer += chunk.text; // → streams to the browser
}
}
<input bind={this.prompt} />
<button onClick={this.ask} loadingAttr="disabled">Ask</button>
<button onClick={() => $flow.cancel()} showOnLoading>Cancel</button>
<div text={this.answer} />