Reasoning
Bloco de pensamento recolhível que abre durante o streaming, rastreia a duração e fecha discretamente ao terminar.
Visão geral
Reasoning expõe a chain-of-thought do modelo sem dominar a resposta. Ele abre automaticamente enquanto isStreaming é true, mede os segundos decorridos, e então se recolhe sozinho um segundo depois que o streaming termina. O trigger alterna entre um Shimmer ("Thinking...") e a duração registrada ("Thought for N seconds").
Use dentro de MessageContent para turnos do assistant cujo modelo expõe um trace de reasoning (o-series, Claude extended thinking, DeepSeek R1, etc.).
Preview
Ocioso
'use client';import { Reasoning, ReasoningContent, ReasoningTrigger } from '@gremorie/rx-ai';const REASONING_TEXT = `The user wants to add a registry item. I need to:1. Confirm the package the primitive lives in.2. Check registry.json for the existing schema.3. Add the item with registryDependencies pointing at its peers.`;export function ReasoningPreview() { return ( <Reasoning isStreaming={false} defaultOpen> <ReasoningTrigger /> <ReasoningContent>{REASONING_TEXT}</ReasoningContent> </Reasoning> );}Streaming
'use client';import { Reasoning, ReasoningContent, ReasoningTrigger } from '@gremorie/rx-ai';export function ReasoningStreamingPreview() { return ( <Reasoning isStreaming defaultOpen> <ReasoningTrigger /> <ReasoningContent> Considering whether to recommend rx-tool or rx-task for this case... </ReasoningContent> </Reasoning> );}Expandido
'use client';import { Reasoning, ReasoningContent, ReasoningTrigger } from '@gremorie/rx-ai';const REASONING_TEXT = `The user wants to add a registry item. I need to:1. Confirm the package the primitive lives in.2. Check registry.json for the existing schema.3. Add the item with registryDependencies pointing at its peers.`;export function ReasoningExpandedPreview() { return ( <Reasoning isStreaming={false} defaultOpen> <ReasoningTrigger /> <ReasoningContent>{REASONING_TEXT}</ReasoningContent> </Reasoning> );}Anatomia
Reasoning
├─ ReasoningTrigger label "Thinking…" (faz shimmer durante o streaming)
└─ ReasoningContent o texto de reasoning recolhívelInstalação
bash npx gremorie@latest add rx-reasoning bash pnpm dlx gremorie@latest add rx-reasoning bash yarn dlx gremorie@latest add rx-reasoning bash bunx --bun gremorie@latest add rx-reasoning Uso
import {
Reasoning,
ReasoningTrigger,
ReasoningContent,
} from "@gremorie/rx-ai";
export function Example({ status, thinking }) {
return (
<Reasoning isStreaming={status === "streaming"}>
<ReasoningTrigger />
<ReasoningContent>{thinking}</ReasoningContent>
</Reasoning>
);
}import { Component, input } from "@angular/core";
import {
Reasoning,
ReasoningTrigger,
ReasoningContent,
} from "@gremorie/ng-ai";
@Component({
selector: "app-example",
standalone: true,
imports: [Reasoning, ReasoningTrigger, ReasoningContent],
template: ` <reasoning [isStreaming]="status() === 'streaming'">
<reasoning-trigger />
<reasoning-content [text]="thinking()" />
</reasoning>
`,
})
export class ExampleComponent {
readonly status = input<"idle" | "streaming" | "done">("idle");
readonly thinking = input<string>("");
}
API
<Reasoning>
| Prop | Type | Default | Description |
|---|---|---|---|
isStreaming | boolean | false | Enquanto true, o bloco abre, o trigger mostra um "Thinking..." com shimmer e o timer de duração corre. |
open | boolean | - | Estado de abertura controlado. |
defaultOpen | boolean | true | Estado de abertura inicial não controlado. O auto-fechamento só dispara quando isto é true. |
onOpenChange | (open: boolean) => void | - | Notificação quando o usuário alterna o trigger. |
duration | number | - | Override externo de duração (segundos). Se omitido, Reasoning a mede a partir das transições de isStreaming. |
Estende ComponentProps<typeof Collapsible>.
<ReasoningTrigger>
| Prop | Type | Default | Description |
|---|---|---|---|
getThinkingMessage | (isStreaming: boolean, duration?: number) => ReactNode | builtin | Customiza o label do trigger. O padrão renderiza o Shimmer durante o streaming e "Thought for N seconds" ao terminar. |
children | ReactNode | - | Substitui completamente o conteúdo do trigger (ícone + label + chevron). |
<ReasoningContent>
| Prop | Type | Default | Description |
|---|---|---|---|
children | string | - | Markdown renderizado via Streamdown. |
useReasoning()
Retorna { isStreaming, isOpen, setIsOpen, duration }. Lança erro quando chamado fora de um limite <Reasoning>.
Composição
<Reasoning>detém o estado de open / streaming / duration e envolve umCollapsible.<ReasoningTrigger>renderiza o ícone de cérebro + label + chevron e alterna o collapsible.<ReasoningContent>renderiza o markdown com streaming sob demanda.
Variações
Dentro de uma mensagem do assistant
O pareamento típico - reasoning acima da resposta.
<Message from="assistant">
<MessageContent>
<Reasoning isStreaming={status === "streaming"}>
<ReasoningTrigger />
<ReasoningContent>{thinking}</ReasoningContent>
</Reasoning>
<MessageResponse>{answer}</MessageResponse>
</MessageContent>
</Message>Label de trigger customizado
Sobrescreva getThinkingMessage para localizar o texto ou expor metadados do modelo.
<Reasoning isStreaming={isStreaming}>
<ReasoningTrigger
getThinkingMessage={(streaming, duration) =>
streaming ? (
<Shimmer>Reasoning with o4-mini...</Shimmer>
) : (
<span>Reasoning took {duration ?? '?'}s</span>
)
}
/>
<ReasoningContent>{thinking}</ReasoningContent>
</Reasoning>Estado de abertura controlado
Quando a casca ao redor decide quando o reasoning está visível (por exemplo, um toggle "Hide reasoning" nas configurações).
const [open, setOpen] = useState(false);
<Reasoning open={open} onOpenChange={setOpen} isStreaming={false} duration={12}>
<ReasoningTrigger />
<ReasoningContent>{archivedThinking}</ReasoningContent>
</Reasoning>;Acessibilidade
- Teclado:
ReasoningTriggeré umCollapsibleTrigger, então alterna com Enter / Space e participa da ordem de Tab. - ARIA: o collapsible Radix subjacente conecta
aria-expandedearia-controlsno trigger edata-stateno content, então leitores de tela anunciam os estados aberto / fechado corretamente. - Leitores de tela: o label usa texto vivo ("Thinking..." -> "Thought for N seconds") para que a tecnologia assistiva narre a transição sem precisar de uma região live separada.
- Movimento reduzido: as animações de recolher / expandir vêm das animações data-state do Tailwind; elas degradam para transições instantâneas quando
prefers-reduced-motion: reduceestá definido.
Relacionados
- Message - o pai típico de
Reasoning - Chain of Thought - reasoning passo a passo quando você tem ações discretas para expor
- Shimmer - o affordance de loading usado dentro do trigger padrão