useThreads()
List, create, rename, and delete threads.
useThreads is the sidebar. It lists saved conversations for the current identity and lets you create, rename, and delete them.
Requires Pai.Provider. Does not require ThreadProvider.
function Sidebar() {
const threads = Assistant.useThreads();
const client = Assistant.useClient();
return (
<ul>
{threads.items.map((thread) => (
<li key={thread.threadId}>
<a href={`/chat/${thread.threadId}`}>{thread.title ?? "Untitled"}</a>
</li>
))}
<button
type="button"
onClick={() => {
window.location.assign(`/chat/${client.newThreadId()}`);
}}
>
New chat
</button>
</ul>
);
}Empty ids are fine. The server row appears on the first send.
Import
const threads = Assistant.useThreads();Signature
function useThreads(options?: UseThreadsOptions): ThreadsController<TContract>;Parameters
options?: UseThreadsOptions
List query plus onThreadCreated.
limit?: number
pageToken?: string
category?: string
parentThreadId?: ThreadId
onThreadCreated?: (thread, { refresh }) => void | Promise<void>
Called when a new thread appears in this runtime scope.
Returns
ThreadsController
Includes the current ThreadListResult (items, …).
hasMore: boolean
Another page is available.
loading: boolean
Initial list or a manual refresh() is in flight. Becomes true again on
every refresh — unlike useChat().loading.
loadingMore: boolean
Next page is being appended.
deleting: boolean
renaming: boolean
error: Error | null
Last list or mutation error caught by the hook.
watchError: Error | null
Terminal failure from the thread-head watch.
watchStatus: WatchStatus
Head-subscription lifecycle. List reads have their own loading / error.
refresh: () => Promise<ThreadListResult>
loadMore: () => Promise<ThreadListResult | null>
create: (options?) => Thread<TContract>
Fresh local handle. The server row appears on the first send.
rename: (threadId, title) => Promise<ThreadRenameResult>
delete: (threadId) => Promise<void>
newThreadId() on useClient() is the usual “New chat” path.