AI
Reasoning
A collapsible block that shows how an agent reached its answer, with the reasoning streamed in as markdown.
Guidelines#
Use it for the "thinking" part of an agent reply: which signals it weighed before proposing a meeting time or a next step. Keep the answer itself outside the block.
What you provide: Reasoning (open/onOpenChange to control it; uncontrolled it starts open), ReasoningTrigger (its children are the label), ReasoningContent (the collapsing region, className for the rule or spacing), and inside it ReasoningResponse with text (a string or AsyncIterable<string>) and the ResponseStream options: speed (default 20), mode (default typewriter), onComplete, fadeDuration, segmentDelay, characterChunkSize.
Anatomy: the trigger is a button with an 8px gap, the label in text-primary and a 16px chevron that turns 180° when open. The response renders Markdown in text-sm text-muted-foreground; its prose classes have no effect in Crew OS (no typography plugin), so style lists and emphasis through className.
Behaviour: the content animates max-height over 300ms ease-out between 0 and its measured height (a ResizeObserver follows the growing text). The response fades between opacity 0 and 1 over 300ms with the open state.
Don't put the final answer or actions inside the block, or open several reasoning blocks at once in one reply.
Facts#
| Group | AI |
|---|---|
| Product | Crew OS |
| Global | window.DigitalCrew.Reasoning |
| Source | digitalcrew-orchestrator: components/ui/reasoning.tsx |
| Import in the app | import { Reasoning } from "@/components/ui/reasoning"; |
API#
TypeScript declarations emitted from components/ui/reasoning.tsx (the module also exports Reasoning, ReasoningTrigger, ReasoningContent, ReasoningResponse).
export type ReasoningProps = {
children: React.ReactNode;
className?: string;
open?: boolean;
onOpenChange?: (open: boolean) => void;
};
declare function Reasoning({ children, className, open, onOpenChange, }: ReasoningProps): any;
export type ReasoningTriggerProps = {
children: React.ReactNode;
className?: string;
} & React.HTMLAttributes<HTMLButtonElement>;
declare function ReasoningTrigger({ children, className, ...props }: ReasoningTriggerProps): any;
export type ReasoningContentProps = {
children: React.ReactNode;
className?: string;
} & React.HTMLAttributes<HTMLDivElement>;
declare function ReasoningContent({ children, className, ...props }: ReasoningContentProps): any;
export type ReasoningResponseProps = {
text: string | AsyncIterable<string>;
className?: string;
speed?: number;
mode?: Mode;
onComplete?: () => void;
fadeDuration?: number;
segmentDelay?: number;
characterChunkSize?: number;
};
declare function ReasoningResponse({ text, className, speed, mode, onComplete, fadeDuration, segmentDelay, characterChunkSize, }: ReasoningResponseProps): any;
export { Reasoning, ReasoningTrigger, ReasoningContent, ReasoningResponse };Example#
The code of the preview above: plain React.createElement against window.DigitalCrew, with realistic data.
<div id="root" class="p-6"></div>
<script>
(function () {
var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
var thinking = "Claire opened the last two emails but has not replied. Her calendar shows the Northwind budget review on **14 October**.\n\n- Tuesday 14:30 has the best acceptance rate for CFOs in her region\n- Wednesday clashes with her board prep\n\nSo I will propose Tuesday 14:30, Paris time.";
function App() {
return h("div", { className: "grid max-w-xl gap-4" },
h("div", { className: "ml-auto max-w-sm rounded-2xl bg-secondary px-4 py-2.5 text-sm text-secondary-foreground" }, "When should we follow up with Claire Dubois?"),
h("div", { className: "grid gap-3 rounded-xl border bg-card p-4" },
h(DC.Reasoning, null,
h(DC.ReasoningTrigger, { className: "text-sm" }, "Show reasoning"),
h(DC.ReasoningContent, { className: "mt-2 border-l-2 pl-3" },
h(DC.ReasoningResponse, { text: thinking, speed: 60, className: "space-y-2 [&_strong]:font-semibold [&_ul]:list-disc [&_ul]:pl-5" }))),
h("p", { className: "text-sm" }, "Propose Tuesday 14:30 (Paris). I have drafted the email in your outbox.")));
}
ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>