ResponseView
模型正在输出的回复:带低调光标的 Markdown,推理放在“思考中”折叠区内,停止和失败状态保持平静。
Subject: Your order #4471 is on its way — and we’re sorry it’s late
Hi Maya,
Your order #4471 left our warehouse on time, but a delay with our carrier held it up for three days. That’s not the experience we want for you, and I’m sorry.
It’s moving again and should arrive by Thursday. As a thank-you for your patience, your next order ships free — the code is applied to your account automatically.
Warmly,
The Northwind team
- 首个 Token
- 1.18 s
- 总计
- 6.12 s
function Stream() {
const [state, setState] = useState<{ status: ResponseStatus; text: string; reasoning: string; took?: number; started?: number; total?: number }>({
status: "done",
text: gpt.text,
reasoning: gpt.reasoning!,
took: 3800,
total: 6120,
});
const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
useEffect(() => () => clearTimeout(timer.current), []);
const play = () => {
clearTimeout(timer.current);
const started = Date.now();
let r = 0;
let t = 0;
let took: number | undefined;
setState({ status: "pending", text: "", reasoning: "", started });
const tick = () => {
if (r < gpt.reasoning!.length) r += 8;
else {
took ??= Date.now() - started;
t += 6;
}
const done = t >= gpt.text.length;
setState({
status: done ? "done" : "streaming",
reasoning: gpt.reasoning!.slice(0, r),
text: gpt.text.slice(0, t),
started,
...(took !== undefined ? { took } : {}),
...(done ? { total: Date.now() - started } : {}),
});
if (!done) timer.current = setTimeout(tick, 24);
};
timer.current = setTimeout(tick, 700);
};
return (
<div className="flex w-full max-w-560 flex-col gap-16">
<div>
<Button size="sm" onClick={play} disabled={state.status === "pending" || state.status === "streaming"}>
Stream it again
</Button>
</div>
<ResponseView
aria-label="GPT-5 response"
status={state.status}
text={state.text}
reasoning={state.reasoning}
{...(state.took !== undefined ? { reasoningDuration: state.took } : {})}
footer={
<ResponseMetrics
reasoning
live={state.status === "pending" || state.status === "streaming"}
startedAt={state.started}
duration={state.total}
timeToFirstToken={state.status === "pending" ? undefined : 1180}
/>
}
/>
</div>
);
}import { ResponseView, UserMessage, Thread } from "@logicplanes/kaeso-ui/playground";属性
aria-labelstring回复的无障碍名称(对比时如“GPT-5 回复”)。默认为 LocaleProvider 语言中的“回复”。
defaultReasoningOpenboolean推理过程是否初始展开。
footerReactNode回复下方:数据和操作。
onReasoningOpenChange((open: boolean) => void)推理过程展开或收起时调用。
onRetry(() => void)重新发送本轮;出错或停止时显示。
reasoningstring目前为止的推理摘要,为 Markdown。由“思考中”折叠区显示,默认收起。
reasoningDurationnumber模型推理的时长(毫秒):“思考了 4.2 秒”。
reasoningOpenboolean受控时,推理过程是否展开。
status"done" | "error" | "streaming" | "pending" | "stopped" = done回复所处的状态:等待中、流式输出中、已完成、已停止或失败。
textstring目前为止的输出文本,为 Markdown。