Headless / AI chat
Conversation
Compose ai conversation without managing the chat transport yourself.
138 public parts · 5examples
@slices.sh/ai-chat/headlessView as Markdown ↗Your design. Our behavior.
Explore the tree to see what each part controls. Gates reveal the relevant state; roots outline their scope.
Chat.Root · Scope
Installation
Choose what your component needs. Run these commands in an initialized Next.js app.
Before you start
The steps below run in a Next.js app with shadcn set up (it has a components.json). In an existing Next.js app, such as one from create-next-app, set shadcn up first:
npx shadcn@latest init -t next -b base -p novaOr start fresh: the slices CLI creates the app and sets it up.
npx slices.sh installInstall the service registry
Adds services/index.ts, which import "@/services" loads. A provider setup writes the same file, so skip this if your app has one.
npx add servicesInstall the headless library
npmAdd the React parts to your app, then compose them with your own elements.
npm install @slices.sh/ai-chat@^0.1.4 @slices.sh/composer@^0.1.4Import from @slices.sh/ai-chat/headless.
Install the service
Connect the parts to a provider. Skip this step if this service is already configured in your app.
npx add ai-chat.echoAdds service configuration and API routes to your app, with the provider dependencies. For a headless composition, add import "@/services" after "use client".
The slices CLI installs the service and provisions its required resources in one command.
Provider setup notes
- Echo needs nothing. When you want a model: npx shadcn@latest add @slices/ai-chat.vercel, then switch provider in services/ai-chat/default.config.ts.
Optional: Chat media parts
Before you start
The steps below run in a Next.js app with shadcn set up (it has a components.json). In an existing Next.js app, such as one from create-next-app, set shadcn up first:
npx shadcn@latest init -t next -b base -p novaOr start fresh: the slices CLI creates the app and sets it up.
npx slices.sh installInstall the headless library
npmAdd the React parts to your app, then compose them with your own elements.
npm install @slices.sh/chat-mediaImport from @slices.sh/chat-media/headless.
These parts run locally. No service installation or provisioning is needed.
Optional: Markdown rendering
Before you start
The steps below run in a Next.js app with shadcn set up (it has a components.json). In an existing Next.js app, such as one from create-next-app, set shadcn up first:
npx shadcn@latest init -t next -b base -p novaOr start fresh: the slices CLI creates the app and sets it up.
npx slices.sh installInstall the headless library
npmAdd the React parts to your app, then compose them with your own elements.
npm install @slices.sh/markdownImport from @slices.sh/markdown.
These parts run locally. No service installation or provisioning is needed.
Optional: Migrate chat attachments
Before you start
The steps below run in a Next.js app with shadcn set up (it has a components.json). In an existing Next.js app, such as one from create-next-app, set shadcn up first:
npx shadcn@latest init -t next -b base -p novaOr start fresh: the slices CLI creates the app and sets it up.
npx slices.sh installInstall the service registry
Adds services/index.ts, which import "@/services" loads. A provider setup writes the same file, so skip this if your app has one.
npx add servicesInstall the headless library
npmAdd the React parts to your app, then compose them with your own elements.
npm install @slices.sh/chat-attachmentsImport from @slices.sh/chat-attachments/headless.
Install the service
Connect the parts to a provider. Skip this step if this service is already configured in your app.
npx add file-storage.localAdds service configuration and API routes to your app, with the provider dependencies. For a headless composition, add import "@/services" after "use client".
The slices CLI installs the service and provisions its required resources in one command.
Provider setup notes
- Add .data/ to .gitignore: the bytes and the index live there.
- This store lives on one disk. A serverless deployment loses the files between requests, so deploy with @slices.sh/file-storage.s3.
- A screen works in a bucket, a private corner of the config ("files" by default). The config lists the ones its screens work in (`buckets`, which installs grow); list more, or a prefix such as "playground/", in `buckets` in services/file-storage/rules.ts. Any other is not-found.
- Set maxUploadBytes and accept in services/file-storage/default.config.ts: nothing is capped until you do.
Start small
Parts bring the behavior. Use their default elements, or supply your own with render.
"use client"// services/index.ts comes from https://slices.sh/r/services.json (or any provider setup)import "@/services"import { Chat } from "@slices.sh/ai-chat/headless"import { Composer } from "@slices.sh/composer"export function Example() { return ( <Chat.Root> <Chat.Transcript> <Chat.Thread> <Chat.Messages> <Chat.Message> <Chat.Parts> <Chat.PartText>{({ text }) => <p>{text}</p>}</Chat.PartText> </Chat.Parts> </Chat.Message> </Chat.Messages> </Chat.Thread> </Chat.Transcript> <Composer.Root> <Composer.Input aria-label="Message" /> <Composer.Submit>Send</Composer.Submit> </Composer.Root> </Chat.Root> )}Chat.Root receives Composer's messages. The echo provider lets you try this without a model key.
API reference
Every public part used by this experience is listed below. Gates render children without adding an element. Element parts accept native element props and render; function children receive the state declared in their props. Scopes provide context rather than a visual element.
Chat.StepBoundarygate
Messages repeats once per UIMessage and Message is its element: data-state user or assistant, aria-busy while it is the answer being written, data-invalid when it was cut off. Speaker says who spoke, for screen readers. Parts repeats once per SDK part in the order the model produced them, and each kind has its own gate: PartText is one run of prose, StepBoundary marks a new model step. Stopped renders only for a reply that was cut off, and Continue sends a follow-up prompt that resumes it.
Required scope
Chat.StepBoundary requires Chat.Parts.
Chat.StepBoundary requires Chat.Messages.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { number: number }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/step-boundary.tsx
Chat.Continueaction · <button>
Messages repeats once per UIMessage and Message is its element: data-state user or assistant, aria-busy while it is the answer being written, data-invalid when it was cut off. Speaker says who spoke, for screen readers. Parts repeats once per SDK part in the order the model produced them, and each kind has its own gate: PartText is one run of prose, StepBoundary marks a new model step. Stopped renders only for a reply that was cut off, and Continue sends a follow-up prompt that resumes it.
Required scope
Chat.Continue requires Chat.Root.
Chat.Continue requires Chat.Messages.
Props
3 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
promptRequired | string | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/continue.tsx
Chat.ReasoningTimercontent · <span>
PartReasoning gates a reasoning part and hands its children { text, streaming }. ReasoningDisclosure is a native details element, so a find in page can reveal a match. ReasoningTimer gives { seconds, streaming } for "Thought for 4s". Without the reasoning capability the model sends no reasoning parts, and the group renders nothing.
Capability: reasoning
Required scope
Chat.ReasoningTimer requires Chat.PartReasoning.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { seconds: number | null; streaming: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/reasoning-timer.tsx
Chat.ReasoningDisclosurecontent · <details>
Native details stays searchable and lets the browser reveal a found match.
Capability: reasoning
Required scope
Chat.ReasoningDisclosure requires Chat.PartReasoning.
Props
2 documented props · Native <details> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/reasoning-disclosure.tsx
Chat.ComposerRootscope
Reuses the containing chat, so embedding a composer never starts a second conversation.
Props
4 documented props
| Prop | Type | Default |
|---|---|---|
nameRequired | string | — |
chat | AiChat | — |
settings | ChatSettings | null | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/composer-root.tsx
Chat.ComposerStandalonegate
Today's chat composer parts. In v2 Chat.Root is a sink (whenBusy "queue") and the generic Composer from @slices.sh/composer writes into it. Chat.Composer becomes Composer.Root. Chat.Input becomes Composer.Input, a field named text, wrapped by Dictation.Field when dictation is wanted. Chat.Submit's sending half becomes Composer.Submit. Its stopping half is chat behaviour no generic part can express, so it stays a chat part, Chat.Stop (new in v2): it calls the SDK's stop, is disabled while nothing streams and never unmounts, so focus and layout stay put when a turn ends. Chat.ComposerRoot becomes a nested Chat.Root, which shares the outer conversation for the same config. Chat.ComposerStandalone has no replacement: a pattern that draws Chat.Settings only when it stands alone takes a prop for it.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/composer-standalone.tsx
Chat.Rootscope
Chat.Root publishes the SDK Chat itself, never a copy of its state, and provides a sink for Composer. submit(message) calls sendMessage with message.text and message.attachments as file parts. busy is true while a reply streams or a question or tool decision waits. whenBusy is "queue" unless queue={false}. accept.attachments follows the config's files capability: false for a config without files, so the attachment picker inside Composer renders nothing. A Chat.Root nested in another one with the same config and no chat shares the outer conversation.
Props
9 documented props
| Prop | Type | Default |
|---|---|---|
onFeedback | (feedback: ChatFeedback) => void | Promise<void> | — |
nameThe key in | string | — |
configThe config to talk to, | string | — |
enabledLeft out or | Enabled | — |
chatAn AI SDK | AiChat | — |
settingsFrom chatSession(client, name), bound to the supplied Chat transport. | ChatSettings | null | — |
queueThe sink's | boolean | true |
rememberApprovalsEnable explicit per-tool consent remembered only for this Chat instance. | boolean | true |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/root.tsx
Chat.Transcriptcontent · <div>
The scroller, and the only one. A second scroller inside it produces a transcript that follows an end nobody can see: the outer one is already at its bottom, and the words arrive somewhere off screen. `role="log"` with `tabIndex` is the pair the APG asks for and the pair this was missing: the role makes arriving messages announce themselves, and the tab stop is the only way a keyboard reaches a scrolling region whose contents — bubbles, avatars — are not focusable. The busy flag belongs on the message being written and not here. On the region it held back everything the region was for: a polite log defers what arrives inside a busy node, so the question the person just sent and the note saying an answer is coming were both announced late or not at all — the two announcements that matter most, suppressed to defer the one that already defers itself. → components/headless/ai-chat/message.tsx The reader's own wheel, touch, keys and scrollbar are what take the transcript away from where the scroller put it; the scroller's own moves never do. → hooks/ai-chat/use-follow.ts
Required scope
Chat.Transcript must be inside <Chat.Root>.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { following: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/transcript.tsx
Chat.Threadcontent · <div>
Custom renderers retain MessageScroller.Content so anchor children and resizing stay registered.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/thread.tsx
Chat.Messagesscope
The transcript's messages, each in its own scope, exactly as the AI SDK holds them. The repeat is a part rather than a `map` in the pattern, because a message is where the looks change most and the iteration never does: a skin decides what a row is, and this decides what the rows are.
Required scope
Chat.Messages must be inside <Chat.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/messages.tsx
Chat.Messagecontent · <div>
Messages repeats once per UIMessage and Message is its element: data-state user or assistant, aria-busy while it is the answer being written, data-invalid when it was cut off. Speaker says who spoke, for screen readers. Parts repeats once per SDK part in the order the model produced them, and each kind has its own gate: PartText is one run of prose, StepBoundary marks a new model step. Stopped renders only for a reply that was cut off, and Continue sends a follow-up prompt that resumes it.
Required scope
Chat.Message must be inside <Chat.Messages>.
Chat.Message must be inside <Chat.Root>.
Props
3 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
optimizeHistory | boolean | true |
childrenContent rendered inside this part. | ReactNode | ((state: MessageState) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/message.tsx
Chat.Speakercontent · <span>
Who said it, in words. Colour and alignment are the only thing that told the two apart, which is nothing at all to a screen reader and very little on a low-contrast theme. The default skin hides this visually and leaves it in the accessibility tree, where it is the difference between a conversation and a run of anonymous paragraphs.
Required scope
Chat.Speaker must be inside <Chat.Messages>.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { role: AiChatMessage["role"] }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/speaker.tsx
Chat.Partsscope
A message's parts, in the order the model produced them, exactly as the AI SDK holds them. The order is the content. Reasoning before an answer, a tool call between two halves of one, a citation after both — a transcript that grouped by kind would say the model did things in an order it did not. Each kind gates itself inside here, and a kind no gate draws — a step boundary, an app's own `data-*` part — draws nothing. → docs/rules/states-gate-themselves.md
Required scope
Chat.Parts must be inside <Chat.Messages>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/parts.tsx
Chat.PartTextgate
One run of prose, the SDK's `text` part. A message has several when something happened between them. The role comes with it because whose text this is decides whether it is markup: a model writes markdown and means it, and a person who types `2 * 3 * 4` means three numbers.
Required scope
Chat.PartText must be inside <Chat.Parts>.
Chat.PartText must be inside <Chat.Messages>.
Chat.PartText requires Chat.Root.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: PartTextState) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/part-text.tsx
Chat.PartReasoninggate
A model thinking out loud, the SDK's `reasoning` part, and whether it has stopped. `streaming` is what lets one block be open while it fills and closed once the answer starts, which is the convention every product settled on: the trace is interesting while it is the only thing happening and noise the moment it is not. A trace the SDK still holds as `streaming` on an answer nobody is writing was cut off, and is over too.
Capability: reasoning
Required scope
Chat.PartReasoning must be inside <Chat.Parts>.
Chat.PartReasoning must be inside <Chat.Messages>.
Chat.PartReasoning must be inside <Chat.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: PartReasoningState) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/part-reasoning.tsx
Chat.Usagegate
What the turn cost, where the provider said: the SDK's usage, as the route put it on the message's metadata when the turn finished. Nothing at all where it did not: this field went years declared and never written, and the website that needed it estimated from the length of the text. An estimate on screen is a number people plan against. → docs/rules/capability-honesty.md
Capability: usage
Required scope
Chat.Usage must be inside <Chat.Messages>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { usage: LanguageModelUsage }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/usage.tsx
Chat.ContextUsagegate
Model, Timing and Usage read what the route wrote into the message metadata: which model answered, how long it took, the SDK's LanguageModelUsage. ContextUsage gives { tokens, capacity, percent } for the last request while the chat is idle. Each one is null, and renders nothing, when the provider did not report the value.
Capability: usage
Required scope
Chat.ContextUsage must be inside <Chat.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: UsageState) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/context-usage.tsx
Chat.Modelgate
Model, Timing and Usage read what the route wrote into the message metadata: which model answered, how long it took, the SDK's LanguageModelUsage. ContextUsage gives { tokens, capacity, percent } for the last request while the chat is idle. Each one is null, and renders nothing, when the provider did not report the value.
Capability: usage
Required scope
Chat.Model must be inside <Chat.Messages>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { model: string }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/model.tsx
Chat.Timinggate
Model, Timing and Usage read what the route wrote into the message metadata: which model answered, how long it took, the SDK's LanguageModelUsage. ContextUsage gives { tokens, capacity, percent } for the last request while the chat is idle. Each one is null, and renders nothing, when the provider did not report the value.
Capability: usage
Required scope
Chat.Timing must be inside <Chat.Messages>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { timing: NonNullable<AiChatMetadata["timing"]> }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/timing.tsx
Chat.Stoppedgate
This reply was cut off, and somebody should be told in words. Fading the text was the whole account of it before, which is a contrast regression that says nothing: the reader could not tell whether they had stopped it, the model had, or the network went. → components/headless/ai-chat/writing.ts
Required scope
Chat.Stopped must be inside <Chat.Messages>.
Chat.Stopped must be inside <Chat.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { reason: "length" | "interrupted" }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/stopped.tsx
Chat.Composeraction · <form>
Today's chat composer parts. In v2 Chat.Root is a sink (whenBusy "queue") and the generic Composer from @slices.sh/composer writes into it. Chat.Composer becomes Composer.Root. Chat.Input becomes Composer.Input, a field named text, wrapped by Dictation.Field when dictation is wanted. Chat.Submit's sending half becomes Composer.Submit. Its stopping half is chat behaviour no generic part can express, so it stays a chat part, Chat.Stop (new in v2): it calls the SDK's stop, is disabled while nothing streams and never unmounts, so focus and layout stay put when a turn ends. Chat.ComposerRoot becomes a nested Chat.Root, which shares the outer conversation for the same config. Chat.ComposerStandalone has no replacement: a pattern that draws Chat.Settings only when it stands alone takes a prop for it.
Required scope
Chat.Composer must be inside <Chat.Root>.
Props
2 documented props · Native <form> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/composer.tsx
Chat.Inputinput · <textarea>
A textarea rather than an input, because Shift+Enter has to mean something. No `rows`: the skin sizes it with `field-sizing: content`, so it grows with the message and stops at a maximum. A fixed row locked every paragraph anyone ever wrote into a thirty-six pixel slit, with the browser's own resize handle taken away.
Required scope
Chat.Input must be inside <Chat.Root>.
Props
2 documented props · Native <textarea> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/input.tsx
Chat.Submitaction · <button>
One control that sends, and stops what it sent with the SDK's `stop`. The composer's only submit, and the only button that ever occupies this spot. A separate stop button had to appear between send and its neighbour mid-turn, which moved the most used control in the component under a cursor already on its way down; it also unmounted itself the instant the turn ended, dropping focus to the body if anyone had tabbed to it. Morphing solves both: the element is the same element, and it is `type="submit"` only while submitting is what it does. → docs/rules/one-submit-per-form.md It stops an answer while there is nothing to send, and sends while there is — which is the only reading that leaves the queue reachable by touch. Otherwise the one button beside the box said "stop" the whole time an answer was arriving, so a follow-up typed on a phone could be sent only from the software keyboard's own return key, and the control right next to it did something else. Where the composer refuses a second message outright (`queue` off) there is nothing to send by definition, so this is stop again.
Required scope
Chat.Submit must be inside <Chat.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { stopping: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/submit.tsx
Chat.Stopaction · <button>
Stops a reply that is streaming. Stopping is the chat's own behaviour, so it is not a mode of `Composer.Submit`: no generic part can express it. It is disabled while nothing streams, never unmounted: a button that came and went with every turn moved the controls beside it under a cursor already on its way, and dropped focus to the body when the turn ended with it focused.
Required scope
Chat.Stop must be inside <Chat.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/stop.tsx
Chat.Suggestionsgate
Starters, and only on an empty transcript. Once there is a conversation they are no longer suggestions, they are a row of buttons competing with what the person was about to type.
Required scope
Chat.Suggestions must be inside <Chat.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/suggestions.tsx
Chat.FollowUpsgate
Only the last completed answer can suggest what comes next in the active branch.
Required scope
Chat.FollowUps requires Chat.Root.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { prompts: string[] }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/follow-ups.tsx
Chat.Suggestionaction · <button>
Sends its own text. It goes through the composer rather than the chat, so a suggestion queued behind a running turn waits exactly as a typed message does.
Required scope
Chat.Suggestion must be inside <Chat.Root>.
Props
3 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
textRequired | string | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/suggestion.tsx
Chat.JumpToLatestaction · <button>
Rendered only once the reader has scrolled the transcript away from its end.
Required scope
Chat.JumpToLatest must be inside <Chat.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/jump-to-latest.tsx
Chat.Emptygate
Nothing has been said yet. Where a greeting and the starters go.
Required scope
Chat.Empty must be inside <Chat.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/empty.tsx
Chat.Waitinggate
Sent, and nothing back yet: the SDK's `submitted`. Its own gate rather than a flag on a wider one, so the condition lives where the rule wants it and the pattern never writes `waiting ? … : null`. Once the words start arriving they are the answer to "is anything happening", and this renders nothing. → docs/rules/states-gate-themselves.md It belongs inside `Chat.Transcript`, whose `role="log"` announces what arrives in it. A second live region around this note would have a screen reader say it twice.
Required scope
Chat.Waiting must be inside <Chat.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/waiting.tsx
Chat.Failedgate
The turn was refused — the SDK's `error` status — and the child is told which refusal it was. The slug reaches the screen because the common ones want different things: a quota refusal wants an upgrade link, an outage wants the retry button, and an unknown chat wants a developer to open `services/ai-chat/config.ts`. One banner for all three would be three lies. → docs/rules/capability-honesty.md
Required scope
Chat.Failed must be inside <Chat.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { error: ChatErrorSlug; retryIn: number }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/failed.tsx
Chat.TryAgainaction · <button>
One gate per state of the conversation, so pattern code never branches on status. Empty: nothing has been said. Waiting: the SDK's submitted, sent with nothing back yet; it belongs inside Chat.Transcript, whose log announces it. Failed: the SDK's error status with the refusal slug (unauthorized, quota-exceeded, unknown-chat…); it belongs outside the scroller so a refusal never renders below the fold. TryAgain: regenerate() from inside Failed. Unavailable: the one part that renders when Chat.Root is enabled="optional" and ai-chat is not configured, for a sentence saying so.
Required scope
Chat.TryAgain must be inside <Chat.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/try-again.tsx
Chat.ToolErrorgate
PartTool gates one tool-<name> or dynamic-tool part over the SDK's seven states and hands { toolName, state }. ToolRenderer lets the app draw a tool's body from a renderers map; approval controls stay outside it. ToolInput, ToolOutput and ToolError gate the input, the output and the error text. A config without tools never produces these parts.
Capability: tools
Required scope
Chat.ToolError requires Chat.Parts.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { value: string }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/tool-error.tsx
Chat.ToolOutputgate
PartTool gates one tool-<name> or dynamic-tool part over the SDK's seven states and hands { toolName, state }. ToolRenderer lets the app draw a tool's body from a renderers map; approval controls stay outside it. ToolInput, ToolOutput and ToolError gate the input, the output and the error text. A config without tools never produces these parts.
Capability: tools
Required scope
Chat.ToolOutput requires Chat.Parts.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { value: unknown }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/tool-output.tsx
Chat.ToolInputgate
PartTool gates one tool-<name> or dynamic-tool part over the SDK's seven states and hands { toolName, state }. ToolRenderer lets the app draw a tool's body from a renderers map; approval controls stay outside it. ToolInput, ToolOutput and ToolError gate the input, the output and the error text. A config without tools never produces these parts.
Capability: tools
Required scope
Chat.ToolInput requires Chat.Parts.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { value: unknown }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/tool-input.tsx
Chat.ToolRendererscope
Render only the tool body; approval controls stay outside the app's renderer.
Capability: tools
Required scope
Chat.ToolRenderer requires Chat.Parts.
Props
2 documented props
| Prop | Type | Default |
|---|---|---|
renderers | ToolRenderers | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/tool-renderer.tsx
Chat.ForgetApprovalaction · <button>
For a tool declared with needsApproval. PartApproval is the request, with ApprovalReason, Approve, Deny and AlwaysAllow (only with rememberApprovals). Answering calls the SDK's addToolApprovalResponse. ApprovalError says the answer did not reach the server. ApprovalReceipt replaces the controls once answered, RememberedApproval marks a call allowed by a remembered consent, and ForgetApproval takes that consent back. While a decision is pending the queue waits for it.
Capability: toolApproval
Required scope
Chat.ForgetApproval requires Chat.Root.
Chat.ForgetApproval requires Chat.Parts.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/forget-approval.tsx
Chat.RememberedApprovalcontent · <span>
For a tool declared with needsApproval. PartApproval is the request, with ApprovalReason, Approve, Deny and AlwaysAllow (only with rememberApprovals). Answering calls the SDK's addToolApprovalResponse. ApprovalError says the answer did not reach the server. ApprovalReceipt replaces the controls once answered, RememberedApproval marks a call allowed by a remembered consent, and ForgetApproval takes that consent back. While a decision is pending the queue waits for it.
Capability: toolApproval
Required scope
Chat.RememberedApproval requires Chat.Root.
Chat.RememberedApproval requires Chat.Parts.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/remembered-approval.tsx
Chat.AlwaysAllowaction · <button>
For a tool declared with needsApproval. PartApproval is the request, with ApprovalReason, Approve, Deny and AlwaysAllow (only with rememberApprovals). Answering calls the SDK's addToolApprovalResponse. ApprovalError says the answer did not reach the server. ApprovalReceipt replaces the controls once answered, RememberedApproval marks a call allowed by a remembered consent, and ForgetApproval takes that consent back. While a decision is pending the queue waits for it.
Capability: toolApproval
Required scope
Chat.AlwaysAllow requires Chat.PartApproval.
Chat.AlwaysAllow requires Chat.Root.
Chat.AlwaysAllow requires Chat.Parts.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/always-allow.tsx
Chat.ApprovalReceiptcontent · <p>
For a tool declared with needsApproval. PartApproval is the request, with ApprovalReason, Approve, Deny and AlwaysAllow (only with rememberApprovals). Answering calls the SDK's addToolApprovalResponse. ApprovalError says the answer did not reach the server. ApprovalReceipt replaces the controls once answered, RememberedApproval marks a call allowed by a remembered consent, and ForgetApproval takes that consent back. While a decision is pending the queue waits for it.
Capability: toolApproval
Required scope
Chat.ApprovalReceipt requires Chat.Parts.
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { approved: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/approval-receipt.tsx
Chat.ApprovalErrorcontent · <p>
For a tool declared with needsApproval. PartApproval is the request, with ApprovalReason, Approve, Deny and AlwaysAllow (only with rememberApprovals). Answering calls the SDK's addToolApprovalResponse. ApprovalError says the answer did not reach the server. ApprovalReceipt replaces the controls once answered, RememberedApproval marks a call allowed by a remembered consent, and ForgetApproval takes that consent back. While a decision is pending the queue waits for it.
Capability: toolApproval
Required scope
Chat.ApprovalError requires Chat.PartApproval.
Chat.ApprovalError requires Chat.Parts.
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/approval-error.tsx
Chat.ApprovalReasoncontent · <p>
For a tool declared with needsApproval. PartApproval is the request, with ApprovalReason, Approve, Deny and AlwaysAllow (only with rememberApprovals). Answering calls the SDK's addToolApprovalResponse. ApprovalError says the answer did not reach the server. ApprovalReceipt replaces the controls once answered, RememberedApproval marks a call allowed by a remembered consent, and ForgetApproval takes that consent back. While a decision is pending the queue waits for it.
Capability: toolApproval
Required scope
Chat.ApprovalReason requires Chat.Parts.
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/approval-reason.tsx
Chat.Denyaction · <button>
For a tool declared with needsApproval. PartApproval is the request, with ApprovalReason, Approve, Deny and AlwaysAllow (only with rememberApprovals). Answering calls the SDK's addToolApprovalResponse. ApprovalError says the answer did not reach the server. ApprovalReceipt replaces the controls once answered, RememberedApproval marks a call allowed by a remembered consent, and ForgetApproval takes that consent back. While a decision is pending the queue waits for it.
Capability: toolApproval
Required scope
Chat.Deny requires Chat.PartApproval.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { pending: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/deny.tsx
Chat.Approveaction · <button>
For a tool declared with needsApproval. PartApproval is the request, with ApprovalReason, Approve, Deny and AlwaysAllow (only with rememberApprovals). Answering calls the SDK's addToolApprovalResponse. ApprovalError says the answer did not reach the server. ApprovalReceipt replaces the controls once answered, RememberedApproval marks a call allowed by a remembered consent, and ForgetApproval takes that consent back. While a decision is pending the queue waits for it.
Capability: toolApproval
Required scope
Chat.Approve requires Chat.PartApproval.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { pending: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/approve.tsx
Chat.PartApprovalcontent · <div>
For a tool declared with needsApproval. PartApproval is the request, with ApprovalReason, Approve, Deny and AlwaysAllow (only with rememberApprovals). Answering calls the SDK's addToolApprovalResponse. ApprovalError says the answer did not reach the server. ApprovalReceipt replaces the controls once answered, RememberedApproval marks a call allowed by a remembered consent, and ForgetApproval takes that consent back. While a decision is pending the queue waits for it.
Capability: toolApproval
Required scope
Chat.PartApproval requires Chat.Parts.
Chat.PartApproval requires Chat.Root.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/part-approval.tsx
Chat.PartToolgate
One tool call, the SDK's `tool-<name>` or `dynamic-tool` part, wherever it has got to. The state reaches the screen because the seven of them want different things: an input still arriving is a shimmer, an output is a disclosure, a denial is a sentence and an error is a different sentence. One "called a tool" card for all seven would be six lies. `toolName` is the SDK's own reading of the part's type, beside everything the part holds. → docs/rules/capability-honesty.md
Capability: tools
Required scope
Chat.PartTool must be inside <Chat.Parts>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: PartToolState) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/part-tool.tsx
Chat.QuestionReceiptgate
The askQuestions tool: a form the model asks the person to fill in. PartQuestion is the form, Questions hands the questionnaire, QuestionItem is one fieldset with Answer per choice and OtherAnswer plus QuestionOther for a free answer. ClearAnswer takes an optional pick back. QuestionProgress, QuestionBack and QuestionNext step through several questions, and QuestionInvalid says why Next is refused. SubmitAnswers sends, SkipQuestions writes a skipped output the model reads, QuestionError reports a failed write, and QuestionReceipt takes the form's place once answered.
Capability: tools
Required scope
Chat.QuestionReceipt requires Chat.Parts.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: Receipt) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/question-receipt.tsx
Chat.QuestionErrorcontent · <p>
The askQuestions tool: a form the model asks the person to fill in. PartQuestion is the form, Questions hands the questionnaire, QuestionItem is one fieldset with Answer per choice and OtherAnswer plus QuestionOther for a free answer. ClearAnswer takes an optional pick back. QuestionProgress, QuestionBack and QuestionNext step through several questions, and QuestionInvalid says why Next is refused. SubmitAnswers sends, SkipQuestions writes a skipped output the model reads, QuestionError reports a failed write, and QuestionReceipt takes the form's place once answered.
Capability: tools
Required scope
Chat.QuestionError requires Chat.PartQuestion.
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/question-error.tsx
Chat.SubmitAnswersaction · <button>
On the last question only: before it, Next is the way on.
Capability: tools
Required scope
Chat.SubmitAnswers requires Chat.PartQuestion.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/submit-answers.tsx
Chat.SkipQuestionsaction · <button>
Dismisses the open question without answering it. The queue decides what the model hears next: the message the person typed meanwhile, as their reply, or else a nudge to carry on.
Capability: tools
Required scope
Chat.SkipQuestions requires Chat.Root.
Chat.SkipQuestions requires Chat.PartQuestion.
Chat.SkipQuestions requires Chat.Parts.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/skip-questions.tsx
Chat.QuestionOtherinput · <input>
The field of the "Other" row, inline with its control.
Capability: tools
Required scope
Chat.QuestionOther requires Chat.PartQuestion.
Props
3 documented props · Native <input> attributes supported
| Prop | Type | Default |
|---|---|---|
nameRequired | string | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/question-other.tsx
Chat.OtherAnswerinput · <input>
The control of the "Other" row, last in the same group as the choices: it replaces the pick of a single question and adds to a multiple one.
Capability: tools
Required scope
Chat.OtherAnswer requires Chat.PartQuestion.
Props
3 documented props · Native <input> attributes supported
| Prop | Type | Default |
|---|---|---|
nameRequired | string | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/other-answer.tsx
Chat.ClearAnsweraction · <button>
Takes a pick back, which a radio cannot do by itself. An optional question only: a required one is changed, not emptied.
Capability: tools
Required scope
Chat.ClearAnswer requires Chat.PartQuestion.
Props
3 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
nameRequired | string | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/clear-answer.tsx
Chat.QuestionProgresscontent · <p>
"2 of 3": the place in a form of several questions, and nothing in a form of one.
Capability: tools
Required scope
Chat.QuestionProgress requires Chat.PartQuestion.
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: Progress) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/question-progress.tsx
Chat.QuestionBackaction · <button>
The askQuestions tool: a form the model asks the person to fill in. PartQuestion is the form, Questions hands the questionnaire, QuestionItem is one fieldset with Answer per choice and OtherAnswer plus QuestionOther for a free answer. ClearAnswer takes an optional pick back. QuestionProgress, QuestionBack and QuestionNext step through several questions, and QuestionInvalid says why Next is refused. SubmitAnswers sends, SkipQuestions writes a skipped output the model reads, QuestionError reports a failed write, and QuestionReceipt takes the form's place once answered.
Capability: tools
Required scope
Chat.QuestionBack requires Chat.PartQuestion.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/question-back.tsx
Chat.QuestionNextaction · <button>
Goes on once this question's answer is good; the last question has Send answers instead.
Capability: tools
Required scope
Chat.QuestionNext requires Chat.PartQuestion.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/question-next.tsx
Chat.QuestionInvalidcontent · <p>
What is missing from one question's answer, once the person tried to go on without it.
Capability: tools
Required scope
Chat.QuestionInvalid requires Chat.PartQuestion.
Props
3 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
nameRequired | string | — |
childrenContent rendered inside this part. | ReactNode | ((state: { problem: QuestionProblem }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/question-invalid.tsx
Chat.Answerinput · <input>
One choice: a radio in a single question and a checkbox in a multiple one, so the kind is plain before anything is touched.
Capability: tools
Required scope
Chat.Answer requires Chat.PartQuestion.
Props
4 documented props · Native <input> attributes supported
| Prop | Type | Default |
|---|---|---|
nameRequired | string | — |
valueRequired | string | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/answer.tsx
Chat.QuestionItemcontent · <fieldset>
One question: a radiogroup when the answer is one choice, a group when it is several. Only the question of the current step is drawn. Number shortcuts stay inside it and never intercept typing.
Capability: tools
Required scope
Chat.QuestionItem requires Chat.PartQuestion.
Props
3 documented props · Native <fieldset> attributes supported
| Prop | Type | Default |
|---|---|---|
nameRequired | string | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/question-item.tsx
Chat.Questionsgate
The askQuestions tool: a form the model asks the person to fill in. PartQuestion is the form, Questions hands the questionnaire, QuestionItem is one fieldset with Answer per choice and OtherAnswer plus QuestionOther for a free answer. ClearAnswer takes an optional pick back. QuestionProgress, QuestionBack and QuestionNext step through several questions, and QuestionInvalid says why Next is refused. SubmitAnswers sends, SkipQuestions writes a skipped output the model reads, QuestionError reports a failed write, and QuestionReceipt takes the form's place once answered.
Capability: tools
Required scope
Chat.Questions requires Chat.PartQuestion.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: Questionnaire) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/questions.tsx
Chat.PartQuestionaction · <form>
The askQuestions tool: a form the model asks the person to fill in. PartQuestion is the form, Questions hands the questionnaire, QuestionItem is one fieldset with Answer per choice and OtherAnswer plus QuestionOther for a free answer. ClearAnswer takes an optional pick back. QuestionProgress, QuestionBack and QuestionNext step through several questions, and QuestionInvalid says why Next is refused. SubmitAnswers sends, SkipQuestions writes a skipped output the model reads, QuestionError reports a failed write, and QuestionReceipt takes the form's place once answered.
Capability: tools
Required scope
Chat.PartQuestion requires Chat.Parts.
Chat.PartQuestion requires Chat.Root.
Props
2 documented props · Native <form> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/part-question.tsx
Chat.CitationRootscope
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/citation-root.tsx
Chat.CitationContentcontent · <div>
The skin's surface preserves the corresponding Motion primitive adapter.
Capability: sources
Required scope
Chat.CitationContent requires Chat.CitationRoot.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/citation-content.tsx
Chat.CitationTriggeraction · <button>
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/citation-trigger.tsx
Chat.CitationTitlecontent · <h2>
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Props
2 documented props · Native <h2> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/citation-title.tsx
Chat.CitationDescriptioncontent · <p>
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/citation-description.tsx
Chat.SourceSheetRootscope
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/source-sheet-root.tsx
Chat.SourceSheetContentcontent · <div>
The skin's surface preserves the corresponding Motion primitive adapter.
Capability: sources
Required scope
Chat.SourceSheetContent requires Chat.SourceSheetRoot.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/source-sheet-content.tsx
Chat.SourceSheetTriggeraction · <button>
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/source-sheet-trigger.tsx
Chat.SourceSheetTitlecontent · <h2>
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Props
2 documented props · Native <h2> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/source-sheet-title.tsx
Chat.SourceSheetDescriptioncontent · <p>
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/source-sheet-description.tsx
Chat.SourceSheetCloseaction · <button>
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/source-sheet-close.tsx
Chat.Referencesgate
URL and document references in native transcript order, deduplicated by source identity.
Capability: sources
Required scope
Chat.References requires Chat.Messages.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { sources: readonly ChatSource[] }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/references.tsx
Chat.PartSourcegate
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Required scope
Chat.PartSource requires Chat.Messages.
Chat.PartSource requires Chat.Parts.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { source: ChatSource }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/part-source.tsx
Chat.SourceRootscope
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Props
2 documented props
| Prop | Type | Default |
|---|---|---|
sourceRequired | ChatSource | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/source-root.tsx
Chat.SourceLinkcontent · <a>
Sources collects a message's source-url parts. References numbers and deduplicates every source of the message, and PartSource renders the first occurrence of one in place. SourceRoot scopes one source for SourceLink (a validated http(s) link) and SourceUnavailable. CitationRoot and its Trigger, Content, Title and Description are a popover for one citation; SourceSheetRoot and its parts are a modal list of all of them. Nothing renders for an answer without sources, which is most answers from most models.
Capability: sources
Required scope
Chat.SourceLink requires Chat.SourceRoot.
Props
2 documented props · Native <a> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/source-link.tsx
Chat.Sourcesgate
What the answer was drawn from, the SDK's `source-url` parts, collected. A footer rather than a part in the flow: citations arrive interleaved with the prose and read as an appendix, and a reader who wants them wants all of them at once. A document source has no URL to open, and a citation nobody can follow is a row that looks like a link and is not one. Nothing is rendered where the backend sent none, which is most backends.
Capability: sources
Required scope
Chat.Sources must be inside <Chat.Messages>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { sources: SourceUrlUIPart[] }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/sources.tsx
Chat.FileRootscope
PartFile gates a file part. FileRoot validates one FileUIPart and owns its load error. FileKind gates by media kind, FileImage, FileAudio and FileVideo render the media with the source locked, FileLink is an http(s) link only, and FileUnavailable covers a bad source or a failed load. These parts display files the conversation already holds. Sending files is Composer's attachments field, and grouped previews are the chat-media parts.
Capability: files
Props
2 documented props
| Prop | Type | Default |
|---|---|---|
fileRequired | FileUIPart | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/file-root.tsx
Chat.FileKindgate
PartFile gates a file part. FileRoot validates one FileUIPart and owns its load error. FileKind gates by media kind, FileImage, FileAudio and FileVideo render the media with the source locked, FileLink is an http(s) link only, and FileUnavailable covers a bad source or a failed load. These parts display files the conversation already holds. Sending files is Composer's attachments field, and grouped previews are the chat-media parts.
Capability: files
Required scope
Chat.FileKind requires Chat.FileRoot.
Props
2 documented props
| Prop | Type | Default |
|---|---|---|
kindRequired | "image" | "audio" | "video" | "file" | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/file-kind-gate.tsx
Chat.FileImagecontent · <img>
PartFile gates a file part. FileRoot validates one FileUIPart and owns its load error. FileKind gates by media kind, FileImage, FileAudio and FileVideo render the media with the source locked, FileLink is an http(s) link only, and FileUnavailable covers a bad source or a failed load. These parts display files the conversation already holds. Sending files is Composer's attachments field, and grouped previews are the chat-media parts.
Capability: files
Required scope
Chat.FileImage requires Chat.FileRoot.
File media requires Chat.FileRoot.
Props
2 documented props · Native <img> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/file-img.tsx
Chat.FileAudiocontent · <audio>
PartFile gates a file part. FileRoot validates one FileUIPart and owns its load error. FileKind gates by media kind, FileImage, FileAudio and FileVideo render the media with the source locked, FileLink is an http(s) link only, and FileUnavailable covers a bad source or a failed load. These parts display files the conversation already holds. Sending files is Composer's attachments field, and grouped previews are the chat-media parts.
Capability: files
Required scope
Chat.FileAudio requires Chat.FileRoot.
File media requires Chat.FileRoot.
Props
2 documented props · Native <audio> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/file-audio.tsx
Chat.FileVideocontent · <video>
PartFile gates a file part. FileRoot validates one FileUIPart and owns its load error. FileKind gates by media kind, FileImage, FileAudio and FileVideo render the media with the source locked, FileLink is an http(s) link only, and FileUnavailable covers a bad source or a failed load. These parts display files the conversation already holds. Sending files is Composer's attachments field, and grouped previews are the chat-media parts.
Capability: files
Required scope
Chat.FileVideo requires Chat.FileRoot.
File media requires Chat.FileRoot.
Props
2 documented props · Native <video> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/file-video.tsx
Chat.FileLinkcontent · <a>
Data and blob media render in their element; only web links navigate away.
Capability: files
Required scope
Chat.FileLink requires Chat.FileRoot.
Props
2 documented props · Native <a> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/file-link.tsx
Chat.PartFilegate
A native file stays visible in history even when the rich media viewer is not installed.
Capability: files
Required scope
Chat.PartFile requires Chat.Parts.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { file: FileUIPart }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/part-file.tsx
Chat.EditedAttachmentsgate
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.EditedAttachments requires Chat.Messages.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { files: readonly FileUIPart[] }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/edited-attachments.tsx
Chat.BranchPreviousaction · <button>
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.BranchPrevious requires Chat.Root.
Chat.BranchPrevious requires Chat.Messages.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/branch-previous.tsx
Chat.BranchNextaction · <button>
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.BranchNext requires Chat.Root.
Chat.BranchNext requires Chat.Messages.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/branch-next.tsx
Chat.BranchPagecontent · <span>
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.BranchPage requires Chat.Root.
Chat.BranchPage requires Chat.Messages.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { index: number; total: number }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/branch-page.tsx
Chat.MessageEditRootscope
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.MessageEditRoot requires Chat.Messages.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/message-edit-root.tsx
Chat.MessageEditinggate
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.MessageEditing requires Chat.MessageEditRoot.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/message-editing.tsx
Chat.MessageReadinggate
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.MessageReading requires Chat.MessageEditRoot.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/message-reading.tsx
Chat.Editaction · <button>
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.Edit requires Chat.Root.
Chat.Edit requires Chat.Messages.
Chat.Edit requires Chat.MessageEditRoot.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/edit.tsx
Chat.MessageEditoraction · <form>
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.MessageEditor requires Chat.Root.
Chat.MessageEditor requires Chat.Messages.
Chat.MessageEditor requires Chat.MessageEditRoot.
Props
2 documented props · Native <form> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/message-editor.tsx
Chat.EditedInputinput · <textarea>
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.EditedInput requires Chat.Root.
Chat.EditedInput requires Chat.MessageEditRoot.
Props
2 documented props · Native <textarea> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/edited-input.tsx
Chat.CancelEditaction · <button>
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.CancelEdit requires Chat.MessageEditRoot.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/cancel-edit.tsx
Chat.SaveEditaction · <button>
BranchNavigation, BranchPrevious, BranchNext and BranchPage ({ index, total }) step through the alternatives Regenerate and edits create. MessageEditRoot wraps a message's content, and MessageReading and MessageEditing gate the two modes. Edit opens the editor. Editing a sent message is chat behaviour, so the editor stays a chat part: in v2 MessageEditor provides its own sink (whenBusy "hold", submit creates a branch) and renders a Composer with the message's text as defaultValue. EditedInput and SaveEdit map to Composer.Input and Composer.Submit inside it. EditedAttachments exposes the files the edited message keeps, and CancelEdit leaves history unchanged.
Required scope
Chat.SaveEdit requires Chat.Root.
Chat.SaveEdit requires Chat.Messages.
Chat.SaveEdit requires Chat.MessageEditRoot.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/save-edit.tsx
Chat.Copyaction · <button>
Puts this message's text on the clipboard, and says so. The text and nothing else: a reader copying an answer wants the answer, not the reasoning trace above it or the JSON of a tool call beside it. Runs of prose a tool call separated stay separate paragraphs.
Required scope
Chat.Copy must be inside <Chat.Messages>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { copied: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/copy.tsx
Chat.FeedbackRootscope
MessageFooter holds a turn's actions and is data-active on the latest answer. Copy puts the text parts on the clipboard. ReadAloud speaks the answer. Regenerate renders only on the last assistant message. FeedbackRoot, Feedback rating="up" or "down" and FeedbackError call onFeedback and render nothing without it.
Required scope
Chat.FeedbackRoot requires Chat.Root.
Chat.FeedbackRoot requires Chat.Messages.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/feedback-root.tsx
Chat.Feedbackaction · <button>
MessageFooter holds a turn's actions and is data-active on the latest answer. Copy puts the text parts on the clipboard. ReadAloud speaks the answer. Regenerate renders only on the last assistant message. FeedbackRoot, Feedback rating="up" or "down" and FeedbackError call onFeedback and render nothing without it.
Required scope
Chat.Feedback requires Chat.FeedbackRoot.
Props
3 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
ratingRequired | "up" | "down" | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/feedback.tsx
Chat.FeedbackErrorgate
MessageFooter holds a turn's actions and is data-active on the latest answer. Copy puts the text parts on the clipboard. ReadAloud speaks the answer. Regenerate renders only on the last assistant message. FeedbackRoot, Feedback rating="up" or "down" and FeedbackError call onFeedback and render nothing without it.
Required scope
Chat.FeedbackError requires Chat.FeedbackRoot.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/feedback-error.tsx
Chat.ReadAloudaction · <button>
MessageFooter holds a turn's actions and is data-active on the latest answer. Copy puts the text parts on the clipboard. ReadAloud speaks the answer. Regenerate renders only on the last assistant message. FeedbackRoot, Feedback rating="up" or "down" and FeedbackError call onFeedback and render nothing without it.
Required scope
Chat.ReadAloud requires Chat.Messages.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { playing: boolean; failed: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/read-aloud.tsx
Chat.Regenerateaction · <button>
An older answer is safe to regenerate once its entire tail is preserved as a branch.
Required scope
Chat.Regenerate requires Chat.Root.
Chat.Regenerate requires Chat.Messages.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/regenerate.tsx
Chat.ToggleToolaction · <button>
Settings gates a toolbar that exists only when the config publishes a catalog. Models hands the models on offer and ModelPicker is a native select. OptionalTools hands the catalog, or with selected the active subset, and ToggleTool tool={id} is a pressed/unpressed button. Choices belong to this conversation and the server checks every one.
Required scope
Chat.ToggleTool requires Chat.Root.
Props
3 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
toolRequired | string | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/toggle-tool.tsx
Chat.OptionalToolsgate
Settings gates a toolbar that exists only when the config publishes a catalog. Models hands the models on offer and ModelPicker is a native select. OptionalTools hands the catalog, or with selected the active subset, and ToggleTool tool={id} is a pressed/unpressed button. Choices belong to this conversation and the server checks every one.
Required scope
Chat.OptionalTools requires Chat.Root.
Props
2 documented props
| Prop | Type | Default |
|---|---|---|
selected | boolean | false |
childrenContent rendered inside this part. | ReactNode | ((state: { tools: NonNullable<ChatChoices["tools"]> }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/optional-tools.tsx
Chat.ModelPickerinput · <select>
Settings gates a toolbar that exists only when the config publishes a catalog. Models hands the models on offer and ModelPicker is a native select. OptionalTools hands the catalog, or with selected the active subset, and ToggleTool tool={id} is a pressed/unpressed button. Choices belong to this conversation and the server checks every one.
Required scope
Chat.ModelPicker requires Chat.Root.
Props
2 documented props · Native <select> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/model-picker.tsx
Chat.Modelsgate
Settings gates a toolbar that exists only when the config publishes a catalog. Models hands the models on offer and ModelPicker is a native select. OptionalTools hands the catalog, or with selected the active subset, and ToggleTool tool={id} is a pressed/unpressed button. Choices belong to this conversation and the server checks every one.
Required scope
Chat.Models requires Chat.Root.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { models: NonNullable<ChatChoices["models"]> }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/models.tsx
Chat.Settingsgate
Settings gates a toolbar that exists only when the config publishes a catalog. Models hands the models on offer and ModelPicker is a native select. OptionalTools hands the catalog, or with selected the active subset, and ToggleTool tool={id} is a pressed/unpressed button. Choices belong to this conversation and the server checks every one.
Required scope
Chat.Settings requires Chat.Root.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/settings.tsx
Chat.SendNowaction · <button>
The queue belongs to the sink: with whenBusy "queue", Chat.Root accepts a message while a reply streams and holds it until the chat is ready. These parts show it. Queued hands { count, waitingFor } where waitingFor is "turn", "question" or "approval", and belongs inside a region mounted from the first render. QueueItems repeats the waiting messages, QueueItem is one, QueuePreview shows its text and files. EditQueued opens QueueEditing with QueuedInput, SaveQueued and CancelQueueEdit. CancelQueued drops one. SendNow stops the running answer and sends this one first; with a question open, it skips the question and sends the message as the reply.
Required scope
Chat.SendNow requires Chat.Root.
Chat.SendNow requires Chat.QueueItems.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/send-now.tsx
Chat.CancelQueuedaction · <button>
The queue belongs to the sink: with whenBusy "queue", Chat.Root accepts a message while a reply streams and holds it until the chat is ready. These parts show it. Queued hands { count, waitingFor } where waitingFor is "turn", "question" or "approval", and belongs inside a region mounted from the first render. QueueItems repeats the waiting messages, QueueItem is one, QueuePreview shows its text and files. EditQueued opens QueueEditing with QueuedInput, SaveQueued and CancelQueueEdit. CancelQueued drops one. SendNow stops the running answer and sends this one first; with a question open, it skips the question and sends the message as the reply.
Required scope
Chat.CancelQueued requires Chat.Root.
Chat.CancelQueued requires Chat.QueueItems.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/cancel-queued.tsx
Chat.CancelQueueEditaction · <button>
The queue belongs to the sink: with whenBusy "queue", Chat.Root accepts a message while a reply streams and holds it until the chat is ready. These parts show it. Queued hands { count, waitingFor } where waitingFor is "turn", "question" or "approval", and belongs inside a region mounted from the first render. QueueItems repeats the waiting messages, QueueItem is one, QueuePreview shows its text and files. EditQueued opens QueueEditing with QueuedInput, SaveQueued and CancelQueueEdit. CancelQueued drops one. SendNow stops the running answer and sends this one first; with a question open, it skips the question and sends the message as the reply.
Required scope
Chat.CancelQueueEdit requires Chat.Root.
Chat.CancelQueueEdit requires Chat.QueueItems.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/cancel-queue-edit.tsx
Chat.SaveQueuedaction · <button>
The queue belongs to the sink: with whenBusy "queue", Chat.Root accepts a message while a reply streams and holds it until the chat is ready. These parts show it. Queued hands { count, waitingFor } where waitingFor is "turn", "question" or "approval", and belongs inside a region mounted from the first render. QueueItems repeats the waiting messages, QueueItem is one, QueuePreview shows its text and files. EditQueued opens QueueEditing with QueuedInput, SaveQueued and CancelQueueEdit. CancelQueued drops one. SendNow stops the running answer and sends this one first; with a question open, it skips the question and sends the message as the reply.
Required scope
Chat.SaveQueued requires Chat.Root.
Chat.SaveQueued requires Chat.QueueItems.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/save-queued.tsx
Chat.EditQueuedaction · <button>
The queue belongs to the sink: with whenBusy "queue", Chat.Root accepts a message while a reply streams and holds it until the chat is ready. These parts show it. Queued hands { count, waitingFor } where waitingFor is "turn", "question" or "approval", and belongs inside a region mounted from the first render. QueueItems repeats the waiting messages, QueueItem is one, QueuePreview shows its text and files. EditQueued opens QueueEditing with QueuedInput, SaveQueued and CancelQueueEdit. CancelQueued drops one. SendNow stops the running answer and sends this one first; with a question open, it skips the question and sends the message as the reply.
Required scope
Chat.EditQueued requires Chat.Root.
Chat.EditQueued requires Chat.QueueItems.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/edit-queued.tsx
Chat.QueuedInputinput · <textarea>
The queue belongs to the sink: with whenBusy "queue", Chat.Root accepts a message while a reply streams and holds it until the chat is ready. These parts show it. Queued hands { count, waitingFor } where waitingFor is "turn", "question" or "approval", and belongs inside a region mounted from the first render. QueueItems repeats the waiting messages, QueueItem is one, QueuePreview shows its text and files. EditQueued opens QueueEditing with QueuedInput, SaveQueued and CancelQueueEdit. CancelQueued drops one. SendNow stops the running answer and sends this one first; with a question open, it skips the question and sends the message as the reply.
Required scope
Chat.QueuedInput requires Chat.Root.
Chat.QueuedInput requires Chat.QueueItems.
Props
2 documented props · Native <textarea> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/queued-input.tsx
Chat.QueueEditinggate
The queue belongs to the sink: with whenBusy "queue", Chat.Root accepts a message while a reply streams and holds it until the chat is ready. These parts show it. Queued hands { count, waitingFor } where waitingFor is "turn", "question" or "approval", and belongs inside a region mounted from the first render. QueueItems repeats the waiting messages, QueueItem is one, QueuePreview shows its text and files. EditQueued opens QueueEditing with QueuedInput, SaveQueued and CancelQueueEdit. CancelQueued drops one. SendNow stops the running answer and sends this one first; with a question open, it skips the question and sends the message as the reply.
Required scope
Chat.QueueEditing requires Chat.QueueItems.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { text: string }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/queue-editing.tsx
Chat.QueuePreviewgate
The queue belongs to the sink: with whenBusy "queue", Chat.Root accepts a message while a reply streams and holds it until the chat is ready. These parts show it. Queued hands { count, waitingFor } where waitingFor is "turn", "question" or "approval", and belongs inside a region mounted from the first render. QueueItems repeats the waiting messages, QueueItem is one, QueuePreview shows its text and files. EditQueued opens QueueEditing with QueuedInput, SaveQueued and CancelQueueEdit. CancelQueued drops one. SendNow stops the running answer and sends this one first; with a question open, it skips the question and sends the message as the reply.
Required scope
Chat.QueuePreview requires Chat.QueueItems.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { text: string; files: readonly FileUIPart[] }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/queue-preview.tsx
Chat.QueueItemcontent · <div>
The queue belongs to the sink: with whenBusy "queue", Chat.Root accepts a message while a reply streams and holds it until the chat is ready. These parts show it. Queued hands { count, waitingFor } where waitingFor is "turn", "question" or "approval", and belongs inside a region mounted from the first render. QueueItems repeats the waiting messages, QueueItem is one, QueuePreview shows its text and files. EditQueued opens QueueEditing with QueuedInput, SaveQueued and CancelQueueEdit. CancelQueued drops one. SendNow stops the running answer and sends this one first; with a question open, it skips the question and sends the message as the reply.
Required scope
Chat.QueueItem requires Chat.QueueItems.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/queue-item.tsx
Chat.QueueItemsscope
The queue belongs to the sink: with whenBusy "queue", Chat.Root accepts a message while a reply streams and holds it until the chat is ready. These parts show it. Queued hands { count, waitingFor } where waitingFor is "turn", "question" or "approval", and belongs inside a region mounted from the first render. QueueItems repeats the waiting messages, QueueItem is one, QueuePreview shows its text and files. EditQueued opens QueueEditing with QueuedInput, SaveQueued and CancelQueueEdit. CancelQueued drops one. SendNow stops the running answer and sends this one first; with a question open, it skips the question and sends the message as the reply.
Required scope
Chat.QueueItems requires Chat.Root.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/queue-items.tsx
Chat.Queuedgate
How many messages are waiting, and for what: the running turn, an open question or a tool decision. A reason is always given, because a queue that holds without saying why looks broken. The queue was computed, returned and thrown away, so typing during an answer cleared the box and showed nothing: three follow-ups looked like three sends that did not work, and then arrived minutes later in an order nobody could predict. This is a gate and not a live region, and the difference matters: a region announces what appears *inside* it, so one that arrives already holding its sentence announces nothing. The region is the composer's, mounted from the first render; this puts a sentence into it.
Required scope
Chat.Queued must be inside <Chat.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { count: number; waitingFor: "turn" | "question" | "approval" }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/queued.tsx
ChatMedia.Rootscope
Root scopes one message and registers its media with Quick Look, so previous and next move through this message's files. ImageRun gates a run of consecutive images and hands { images, remaining }. More count={n} renders only when a run holds more images than are drawn, for a +N tile that opens the rest. OtherFile gates any other file and hands { file, id } so it keeps its name and media type, with a native player for audio and video.
Required scope
ChatMedia.Root requires Chat.Messages.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/chat-media/src/headless/root.tsx
ChatMedia.ImageRungate
Root scopes one message and registers its media with Quick Look, so previous and next move through this message's files. ImageRun gates a run of consecutive images and hands { images, remaining }. More count={n} renders only when a run holds more images than are drawn, for a +N tile that opens the rest. OtherFile gates any other file and hands { file, id } so it keeps its name and media type, with a native player for audio and video.
Required scope
ChatMedia.ImageRun requires Chat.Messages.
ChatMedia.ImageRun requires Chat.Parts.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: ChatImageRun) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/chat-media/src/headless/image-run.tsx
ChatMedia.OtherFilegate
Root scopes one message and registers its media with Quick Look, so previous and next move through this message's files. ImageRun gates a run of consecutive images and hands { images, remaining }. More count={n} renders only when a run holds more images than are drawn, for a +N tile that opens the rest. OtherFile gates any other file and hands { file, id } so it keeps its name and media type, with a native player for audio and video.
Required scope
ChatMedia.OtherFile requires Chat.Messages.
ChatMedia.OtherFile requires Chat.Parts.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { file: FileUIPart; id: string }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/chat-media/src/headless/other-file.tsx
ChatMedia.Moregate
Root scopes one message and registers its media with Quick Look, so previous and next move through this message's files. ImageRun gates a run of consecutive images and hands { images, remaining }. More count={n} renders only when a run holds more images than are drawn, for a +N tile that opens the rest. OtherFile gates any other file and hands { file, id } so it keeps its name and media type, with a native player for audio and video.
Props
2 documented props
| Prop | Type | Default |
|---|---|---|
countRequired | number | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/chat-media/src/headless/more.tsx
Markdowncontent · Generic
Model output as markdown, safely, while it is still arriving. Two of these are not things to write by hand, which is why there is a dependency here at all. Completing half-streamed markdown: a fence, a bold run or a link that the next token will finish must render as what it is becoming, or every answer flickers through its own source. And sanitising: this text came from a model that reads the web, so a link is untrusted input and an `<img onerror>` is a real thing to receive — the renderer hardens the tree and this narrows what a URL may start with. Nothing here is styled: the caller's `components` and `className` are the looks, so there is no stylesheet to import and no class that Tailwind was never shown.
Props
7 documented props
| Prop | Type | Default |
|---|---|---|
extensions | readonly ("math" | "diagrams")[] | — |
labelsRequired | MarkdownLabels | — |
className | string | — |
streaming | boolean | false |
components | MarkdownComponents | — |
cursorShown after the text while it is still arriving; it is decoration, so it is hidden from a screen reader. | ReactElement<ComponentProps<"span">> | — |
childrenRequired | string | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/markdown/src/markdown-view.tsx
ChatAttachments.Rootscope
Missing storage leaves a fully functional text composer with no attachment controls.
Required scope
Chat.AttachmentsRoot requires Chat.Root.
Chat.AttachmentsRoot requires Upload.Root.
Props
4 documented props
| Prop | Type | Default |
|---|---|---|
bucket | string | — |
maxSize | number | — |
accept | string | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/chat-attachments/src/headless/attachments-root.tsx
ChatAttachments.Availablegate
ChatAttachments.Available conditionally renders its children.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/chat-attachments/src/headless/attachments-available.tsx
ChatAttachments.Surfacecontent · <div>
Paste and drop share the upload guard and queue.
Props
3 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
longPasteThresholdCharacters; false keeps all pasted text inline. | number | false | 2000 |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/chat-attachments/src/headless/attachment-surface.tsx
ChatAttachments.Errorgate
ChatAttachments.Error conditionally renders its children.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/chat-attachments/src/headless/attachment-error.tsx
ChatAttachments.Retryaction · <button>
ChatAttachments.Retry renders a button element.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/chat-attachments/src/headless/retry-attachments.tsx
ChatDictation.Rootscope
The existing dictation engine writes into the same draft as the native chat composer.
Required scope
ChatDictation.Root requires Chat.Root.
ChatDictation requires Chat.Root.
ChatDictation requires Dictation.Root.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/chat-dictation/root.tsx
ChatDictation.Inputinput · <textarea>
Dictation.Field remains the sole owner of editing and caret restoration.
Required scope
ChatDictation.Input requires ChatDictation.Root.
Props
2 documented props · Native <textarea> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/chat-dictation/input.tsx
ChatDictation.Voicecontent · <div>
Keep AnimatePresence mounted across the recording-to-text transition.
Required scope
ChatDictation.Voice requires ChatDictation.Root.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/chat-dictation/voice.tsx
ChatDictation.Textcontent · <div>
Keep the actual field mounted so its caret owner survives the voice surface.
Required scope
ChatDictation.Text requires ChatDictation.Root.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/chat-dictation/text.tsx
ChatDictation.Confirmaction · <button>
ChatDictation.Confirm renders a button element.
Required scope
ChatDictation.Confirm requires ChatDictation.Root.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/ai-chat/src/headless/chat-dictation/confirm.tsx
Upload.Rootscope
The queue, its limits, and its field registration when it has a name inside a Composer.
Props
12 documented props
| Prop | Type | Default |
|---|---|---|
nameThe key of this value in a Composer's message. With a name, inside a Composer, the uploader is a field: its value is the finished files, and it holds the submit while one uploads. Without one, or outside a Composer, it is a plain uploader. | string | — |
enabledLeft out or | Enabled | — |
configThe file-storage config, | string | — |
bucket | string | — |
pathThe directory files land in. | string | "/" |
maxSizeBytes. A larger file is turned away before anything is sent. The server's own limit, in
| number | — |
maxFiles | number | — |
acceptAn | string | — |
multipartFiles from 5 MiB go up in resumable parts wherever the backend has them, so a large file survives a dropped connection and can be paused. On unless turned off: a screen that had to opt in sent a 2 GB file as one request. A backend without parts is sent whole. | boolean | true |
includeHiddenHidden files inside a folder ( | boolean | false |
ifExistsWhat a name that is taken does: replace, keep both, refuse, or | IfExists | "ask" | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/upload-root.tsx
When something is missing
- No service configuration
- Install the ai-chat setup below and import "@/services". Required service roots report missing setup; gates do not replace that configuration.
- Missing capability or parent scope
- Follow each part’s context requirements and the example composition. Capability-aware controls hide when the provider cannot perform their action.