langgraph-ui-components 0.0.25 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +412 -51
  2. package/dist/_virtual/index.cjs6.js +1 -1
  3. package/dist/_virtual/index.cjs8.js +1 -1
  4. package/dist/_virtual/index.es6.js +2 -2
  5. package/dist/_virtual/index.es8.js +2 -2
  6. package/dist/assets/langgraph-ui-components.css +1 -1
  7. package/dist/components/ChatBody.cjs.js +2 -2
  8. package/dist/components/ChatBody.cjs.js.map +1 -1
  9. package/dist/components/ChatBody.d.ts.map +1 -1
  10. package/dist/components/ChatBody.es.js +137 -98
  11. package/dist/components/ChatBody.es.js.map +1 -1
  12. package/dist/components/messages/AgentMessage.cjs.js +3 -1
  13. package/dist/components/messages/AgentMessage.cjs.js.map +1 -1
  14. package/dist/components/messages/AgentMessage.d.ts +3 -1
  15. package/dist/components/messages/AgentMessage.d.ts.map +1 -1
  16. package/dist/components/messages/AgentMessage.es.js +197 -112
  17. package/dist/components/messages/AgentMessage.es.js.map +1 -1
  18. package/dist/entries/components.cjs.js +1 -1
  19. package/dist/entries/components.d.ts.map +1 -1
  20. package/dist/entries/components.es.js +4 -5
  21. package/dist/entries/components.es.js.map +1 -1
  22. package/dist/entries/hooks.cjs.js +1 -1
  23. package/dist/entries/hooks.d.ts.map +1 -1
  24. package/dist/entries/hooks.es.js +5 -6
  25. package/dist/entries/hooks.es.js.map +1 -1
  26. package/dist/entries/providers.cjs.js +1 -1
  27. package/dist/entries/providers.d.ts +1 -1
  28. package/dist/entries/providers.d.ts.map +1 -1
  29. package/dist/entries/providers.es.js +18 -19
  30. package/dist/entries/providers.es.js.map +1 -1
  31. package/dist/index.cjs.js +1 -1
  32. package/dist/index.d.ts +1 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.es.js +28 -29
  35. package/dist/index.es.js.map +1 -1
  36. package/dist/node_modules/.pnpm/eventemitter3@4.0.7/node_modules/eventemitter3/index.cjs.js +1 -1
  37. package/dist/node_modules/.pnpm/eventemitter3@4.0.7/node_modules/eventemitter3/index.es.js +1 -1
  38. package/dist/node_modules/.pnpm/p-timeout@3.2.0/node_modules/p-timeout/index.cjs.js +1 -1
  39. package/dist/node_modules/.pnpm/p-timeout@3.2.0/node_modules/p-timeout/index.es.js +1 -1
  40. package/dist/node_modules/.pnpm/react-syntax-highlighter@16.1.0_react@19.2.3/node_modules/react-syntax-highlighter/dist/cjs/styles/prism/index.cjs.js +1 -1
  41. package/dist/node_modules/.pnpm/react-syntax-highlighter@16.1.0_react@19.2.3/node_modules/react-syntax-highlighter/dist/cjs/styles/prism/index.es.js +1 -1
  42. package/dist/providers/ChatProvider.cjs.js +1 -1
  43. package/dist/providers/ChatProvider.cjs.js.map +1 -1
  44. package/dist/providers/ChatProvider.d.ts +17 -1
  45. package/dist/providers/ChatProvider.d.ts.map +1 -1
  46. package/dist/providers/ChatProvider.es.js +18 -17
  47. package/dist/providers/ChatProvider.es.js.map +1 -1
  48. package/dist/providers/ChatRuntime.es.js +4 -4
  49. package/dist/providers/CustomComponentProvider.cjs.js +1 -1
  50. package/dist/providers/CustomComponentProvider.cjs.js.map +1 -1
  51. package/dist/providers/CustomComponentProvider.d.ts +11 -0
  52. package/dist/providers/CustomComponentProvider.d.ts.map +1 -1
  53. package/dist/providers/CustomComponentProvider.es.js +51 -35
  54. package/dist/providers/CustomComponentProvider.es.js.map +1 -1
  55. package/dist/providers/Stream.cjs.js +1 -1
  56. package/dist/providers/Stream.cjs.js.map +1 -1
  57. package/dist/providers/Stream.d.ts.map +1 -1
  58. package/dist/providers/Stream.es.js +113 -94
  59. package/dist/providers/Stream.es.js.map +1 -1
  60. package/dist/providers/Thread.cjs.js +1 -1
  61. package/dist/providers/Thread.cjs.js.map +1 -1
  62. package/dist/providers/Thread.d.ts +2 -1
  63. package/dist/providers/Thread.d.ts.map +1 -1
  64. package/dist/providers/Thread.es.js +19 -19
  65. package/dist/providers/Thread.es.js.map +1 -1
  66. package/dist/styles.css +1 -1
  67. package/package.json +1 -1
  68. package/src/components/ChatBody.tsx +88 -28
  69. package/src/components/messages/AgentMessage.tsx +281 -81
  70. package/src/entries/components.ts +0 -2
  71. package/src/entries/hooks.ts +0 -2
  72. package/src/entries/providers.ts +1 -3
  73. package/src/index.css +2 -2
  74. package/src/index.ts +1 -3
  75. package/src/providers/ChatProvider.tsx +18 -1
  76. package/src/providers/CustomComponentProvider.tsx +41 -0
  77. package/src/providers/Stream.tsx +34 -15
  78. package/src/providers/Thread.tsx +2 -2
  79. package/dist/components/ToolCallFunctions.cjs.js +0 -2
  80. package/dist/components/ToolCallFunctions.cjs.js.map +0 -1
  81. package/dist/components/ToolCallFunctions.es.js +0 -75
  82. package/dist/components/ToolCallFunctions.es.js.map +0 -1
package/README.md CHANGED
@@ -12,6 +12,7 @@ A React component library for building AI chat interfaces with LangChain/LangGra
12
12
  - 🧩 **Provider-based architecture** - Flexible state management with React Context
13
13
  - 📝 **TypeScript** - Full type definitions included
14
14
  - 🎨 **Tailwind CSS** - Pre-built styles, easy to customize
15
+ - 🛑 **Human-in-the-Loop (HITL)** - Built-in interrupt handling for agent approval flows
15
16
 
16
17
  ## Installation
17
18
 
@@ -136,8 +137,10 @@ import { Chat } from 'langgraph-ui-components/components';
136
137
 
137
138
  **Props:**
138
139
  - `enableToolCallIndicator?: boolean` - Show visual indicators when AI tools are being executed. Default: `false`
139
- - `callThisOnSubmit?: () => Promise<FileInfo[]>` - Custom callback executed before message submission, useful for uploading files to external storage
140
+ - `callThisOnSubmit?: () => Promise<CallThisOnSubmitResponse | void>` - Custom callback executed before message submission, useful for uploading files to external storage. Return `{ files, contextValues }` to attach files or inject context into the message.
140
141
  - `handleFileSelect?: (event: React.ChangeEvent<HTMLInputElement>) => void` - Custom file selection handler to override default behavior
142
+ - `inputFileAccept?: string` - File types accepted by the file input (e.g. `"image/*,.pdf"`)
143
+ - `chatBodyProps?: chatBodyProps` - Customize agent name, avatar, and font size (see [chatBodyProps](#chatbodyprops))
141
144
 
142
145
  ### Sidebar Component
143
146
 
@@ -164,27 +167,36 @@ import { Sidebar } from 'langgraph-ui-components/components';
164
167
  - `leftPanelContent?: React.ReactNode` - Custom content to display in the left expansion panel
165
168
  - `leftPanelOpen?: boolean` - External control for left panel open state
166
169
  - `setLeftPanelOpen?: (open: boolean) => void` - External setter for left panel open state
170
+ - `leftPanelInitialWidth?: number` - Initial width of the left panel in pixels
171
+ - `leftPanelClassName?: string` - CSS class name for the left panel container
172
+ - `banner?: React.ReactNode` - Optional banner rendered above the chat messages (e.g. an alert or notice)
173
+ - `filePreview?: (files: FileInfo[], setFileInput) => React.ReactNode` - Custom file preview renderer for selected files before submission
174
+ - `inputFileAccept?: string` - File types accepted by the file input (e.g. `"image/*,.pdf"`)
175
+ - `s3_upload?: boolean` - Enable S3 upload mode for file attachments
167
176
 
168
177
  ## Exported Providers
169
178
 
170
- - `ChatProvider` - Core chat state management
179
+ - `ChatProvider` - Core chat state management. Props: `apiUrl`, `assistantId`, `identity?`, `initialMode?` (`"single"` | `"multi"`, default `"single"`), `customComponents?`, `suspenseFallback?`
171
180
  - `ChatRuntimeProvider` - Runtime configuration
172
- - `ThreadProvider` - Conversation thread management
181
+ - `ThreadProvider` - Conversation thread management. Props: `initialMode?` (`"single"` | `"multi"`, default `"single"`)
173
182
  - `StreamProvider` - AI streaming responses
174
183
  - `FileProvider` - File upload handling
175
184
  - `CustomComponentProvider` - Custom component rendering
176
185
 
177
186
  ## Exported Hooks
178
187
 
179
- - `useThread()` - Access thread state (`langgraph-ui-components/providers`)
180
- - `useStreamContext()` - Access streaming state (`langgraph-ui-components/providers`)
181
- - `useChatRuntime()` - Access runtime config (`langgraph-ui-components/providers`)
182
- - `useFileProvider()` - Access file state (`langgraph-ui-components/providers`)
183
- - `useCustomComponents()` - Register custom components (`langgraph-ui-components/providers`)
184
- - `useChatSuggestions()` - Display contextual chat suggestions (`langgraph-ui-components/providers`)
185
- - `useTools()` - Access tool registration helpers (`langgraph-ui-components/hooks`)
186
- - `useToolsDefault` - Backward-compatible default export alias for `useTools` (`langgraph-ui-components/hooks`)
187
- - `useModels()` - Access configured model options (`langgraph-ui-components/hooks`)
188
+ All from `langgraph-ui-components/providers` unless noted:
189
+
190
+ | Hook | Description |
191
+ |------|-------------|
192
+ | `useStreamContext()` | Messages, loading state, sendMessage, stop, interrupt — [details](#usestreamcontext) |
193
+ | `useThread()` | Thread ID, thread list, deleteThread, updateThread, mode — [details](#usethread) |
194
+ | `useChatRuntime()` | apiUrl, assistantId, setAssistantId, identity — [details](#usechatruntime) |
195
+ | `useFileProvider()` | `fileInput: FileInfo[]` and `setFileInput` |
196
+ | `useCustomComponents()` | Register generative UI and interrupt components — [details](#custom-components) |
197
+ | `useChatSuggestions()` | Opt-in chat suggestions — [details](#usechatsuggestions-hook) |
198
+ | `useTools()` *(hooks)* | Sidebar tool buttons — [details](#usetools) |
199
+ | `useModels()` *(hooks)* | Model list and selection — [details](#usemodels) |
188
200
 
189
201
  ## useChatSuggestions Hook
190
202
 
@@ -200,7 +212,7 @@ The `useChatSuggestions` hook enables intelligent, opt-in chat suggestions for y
200
212
  ### Basic Usage
201
213
 
202
214
  ```tsx
203
- import { useChatSuggestions } from 'langgraph-ui-components/hooks';
215
+ import { useChatSuggestions } from 'langgraph-ui-components/providers';
204
216
 
205
217
  function MyComponent() {
206
218
  // Simply call the hook - it registers configuration internally
@@ -261,41 +273,246 @@ function ChatInterface() {
261
273
 
262
274
  When dependencies change, suggestions are regenerated to match the new context.
263
275
 
264
- ## sendMessage Function
276
+ ## useStreamContext
265
277
 
266
- The `sendMessage` function is available through the `useStreamContext()` hook and allows you to send messages programmatically to the AI agent.
278
+ Access the full streaming state and control functions from anywhere inside the provider tree.
267
279
 
268
- ### Parameters
280
+ ```tsx
281
+ import { useStreamContext } from 'langgraph-ui-components/providers';
282
+
283
+ const {
284
+ messages, // Message[] — all messages in the conversation
285
+ isLoading, // boolean — true while agent is streaming
286
+ interrupt, // interrupt payload when agent pauses for human input
287
+ sendMessage, // send a message programmatically
288
+ submitMessage, // low-level submit with stream control options
289
+ regenerateMessage, // regenerate an AI response by message ID
290
+ fetchCatalog, // fetch available agents from /agents/catalog
291
+ stop, // cancel the current stream
292
+ } = useStreamContext();
293
+ ```
269
294
 
270
- - `message` (Message | string): The message content. Can be a string for simple text messages or a full Message object for more control.
271
- - `options` (optional object):
272
- - `type` (Message["type"], optional): The message type to use when sending a string message. Defaults to "human" for user messages. Use "system" for agent-only messages.
273
- - `config` (any, optional): Additional configuration to pass to the agent.
295
+ ### sendMessage
274
296
 
275
- ### Usage Example
297
+ Send a message programmatically. The message is appended to the conversation and submitted to the agent.
276
298
 
277
299
  ```tsx
278
- import { useStreamContext } from 'langgraph-ui-components/hooks';
300
+ // Simple string
301
+ await sendMessage("Hello!");
302
+
303
+ // With options
304
+ await sendMessage("Hello!", {
305
+ type: "human", // message type, defaults to "human"
306
+ hidden: true, // hide from UI (useful for system-level triggers)
307
+ id: "custom-id", // custom message ID instead of auto-generated UUID
308
+ context: { key: "val" }, // extra context merged with identity
309
+ additional_kwargs: {}, // custom metadata attached to the message
310
+ });
311
+ ```
279
312
 
280
- function MyComponent() {
281
- const { sendMessage } = useStreamContext();
313
+ | Option | Type | Description |
314
+ |--------|------|-------------|
315
+ | `type` | `Message["type"]` | Message type (`"human"`, `"system"`, etc.). Default: `"human"` |
316
+ | `hidden` | `boolean` | If `true`, message is not shown in the chat UI |
317
+ | `id` | `string` | Custom message ID (auto-generated UUID if omitted) |
318
+ | `name` | `string` | Required for function/tool messages |
319
+ | `tool_call_id` | `string` | ID linking this message to a tool call |
320
+ | `tool_calls` | `ToolCall[]` | Tool calls to attach to the message |
321
+ | `additional_kwargs` | `Record<string, unknown>` | Custom metadata on the message |
322
+ | `ui` | `UIMessage[]` | UI components to display alongside the message |
323
+ | `context` | `Record<string, unknown>` | Context values merged with identity for this message |
282
324
 
283
- const handleSend = async () => {
284
- await sendMessage("Hello, AI!", { isAIMessage: false });
285
- };
325
+ ### submitMessage
326
+
327
+ Low-level submit with full control over streaming behavior. Use this when you need non-default stream modes.
328
+
329
+ ```tsx
330
+ await submitMessage(messageObject, {
331
+ streamMode: ["values", "updates"], // which stream modes to use
332
+ streamSubgraphs: true, // include subgraph updates
333
+ streamResumable: true, // allow stream resumption
334
+ contextValues: { user_role: "admin" }, // extra context for this call
335
+ });
336
+ ```
337
+
338
+ ### regenerateMessage
339
+
340
+ Regenerate an AI response. Resumes from the checkpoint before the given message ID.
341
+
342
+ ```tsx
343
+ await regenerateMessage(messageId);
344
+ ```
345
+
346
+ ### fetchCatalog
347
+
348
+ Fetch the list of available agents from your API's `/agents/catalog` endpoint.
349
+
350
+ ```tsx
351
+ const catalog = await fetchCatalog();
352
+ ```
353
+
354
+ ### stop
355
+
356
+ Cancel the currently active stream.
357
+
358
+ ```tsx
359
+ const { stop, isLoading } = useStreamContext();
360
+
361
+ <button onClick={stop} disabled={!isLoading}>Stop</button>
362
+ ```
363
+
364
+ ## useThread
365
+
366
+ Access and manage conversation threads.
367
+
368
+ ```tsx
369
+ import { useThread } from 'langgraph-ui-components/providers';
370
+
371
+ const {
372
+ threadId, // string | null — current thread ID
373
+ setThreadId, // switch to a different thread
374
+ threads, // Thread[] — list of all threads
375
+ getThreads, // fetch threads from API
376
+ setThreads, // directly update thread list
377
+ configuration, // ThreadConfiguration — config passed to LangGraph on each call
378
+ setConfiguration, // update thread configuration
379
+ mode, // "single" | "multi"
380
+ setMode, // switch between single and multi-thread modes
381
+ threadsLoading, // boolean — true while fetching thread list
382
+ deleteThread, // delete a thread by ID
383
+ updateThread, // update thread metadata
384
+ } = useThread();
385
+ ```
386
+
387
+ ### deleteThread
388
+
389
+ ```tsx
390
+ await deleteThread(threadId);
391
+ // Removes thread from list and clears current threadId if it was the active one
392
+ ```
393
+
394
+ ### updateThread
395
+
396
+ ```tsx
397
+ await updateThread(threadId, { title: "My conversation" });
398
+ // Updates metadata on the thread and refreshes the thread list
399
+ ```
400
+
401
+ ### Thread Configuration
402
+
403
+ `configuration` is a free-form object passed to the LangGraph API on every stream call. Use it to send per-thread settings your agent reads from `config.configurable`:
404
+
405
+ ```tsx
406
+ const { setConfiguration } = useThread();
407
+
408
+ setConfiguration({
409
+ temperature: 0.7,
410
+ system_prompt: "You are a helpful assistant.",
411
+ });
412
+ ```
413
+
414
+ ### URL-based Thread Loading
415
+
416
+ Append `?thread=<threadId>` to the page URL to automatically load a specific thread on mount:
417
+
418
+ ```
419
+ https://yourapp.com/chat?thread=abc123
420
+ ```
421
+
422
+ ## useChatRuntime
423
+
424
+ Access and update the core runtime configuration.
425
+
426
+ ```tsx
427
+ import { useChatRuntime } from 'langgraph-ui-components/providers';
428
+
429
+ const {
430
+ apiUrl, // string — base API URL
431
+ assistantId, // string — current assistant/graph ID
432
+ setAssistantId, // switch to a different assistant at runtime
433
+ identity, // ChatIdentity | null | undefined
434
+ } = useChatRuntime();
435
+ ```
436
+
437
+ `setAssistantId` is useful when your app lets users pick which agent to talk to:
438
+
439
+ ```tsx
440
+ const { setAssistantId } = useChatRuntime();
441
+
442
+ <button onClick={() => setAssistantId("support_agent")}>Switch to Support</button>
443
+ ```
444
+
445
+ ## useTools
446
+
447
+ Manage the sidebar tool buttons (the icon strip on the left panel).
448
+
449
+ ```tsx
450
+ import { useTools } from 'langgraph-ui-components/hooks';
451
+
452
+ const {
453
+ tool, // CustomTool[] — built-in tools (Search, Chat)
454
+ addTool, // add a custom tool button
455
+ userDefinedTools, // CustomTool[] — tools added via addTool
456
+ setUserDefinedTools, // directly replace user-defined tools
457
+ } = useTools();
458
+ ```
459
+
460
+ ### Adding a Custom Tool
461
+
462
+ ```tsx
463
+ import { useTools } from 'langgraph-ui-components/hooks';
464
+ import { Download } from 'lucide-react';
465
+
466
+ function MyApp() {
467
+ const { addTool } = useTools();
286
468
 
287
- return <button onClick={handleSend}>Send Message</button>;
469
+ useEffect(() => {
470
+ addTool({
471
+ label: "Export",
472
+ icon: <Download />,
473
+ alt: "Export conversation", // tooltip text
474
+ onClick: () => handleExport(),
475
+ });
476
+ }, []);
288
477
  }
289
478
  ```
290
479
 
291
- This will send a user-visible message "Hello, AI!" to the agent.
480
+ ### CustomTool Type
481
+
482
+ ```typescript
483
+ type CustomTool = {
484
+ label: string; // display name
485
+ icon: React.ReactElement; // icon component (e.g. from lucide-react)
486
+ alt?: string; // tooltip text
487
+ onClick: () => void; // click handler
488
+ };
489
+ ```
490
+
491
+ ## useModels
292
492
 
293
- For agent-only messages:
493
+ Fetch and manage model selection. Calls `GET /agents/models` on mount and persists the selection to `localStorage`.
494
+
495
+ ```tsx
496
+ import { useModels } from 'langgraph-ui-components/hooks';
497
+
498
+ const {
499
+ models, // ModelOption[] — available models
500
+ selectedModel, // string — currently selected model ID
501
+ setSelectedModel, // update selection (also persists to localStorage)
502
+ loading, // boolean — true while fetching
503
+ } = useModels();
504
+ ```
294
505
 
295
506
  ```tsx
296
- await sendMessage("Internal event occurred", { type: "system" });
507
+ // ModelOption type
508
+ type ModelOption = {
509
+ id: string;
510
+ name: string;
511
+ };
297
512
  ```
298
513
 
514
+ Models with "embed" or "rerank" in their ID are automatically filtered out. Selection persists under the localStorage key `"agent-chat:selected-model"` and is safe for SSR environments.
515
+
299
516
  ## Custom Components
300
517
 
301
518
  You can inject custom React components into chat messages using the `CustomComponentProvider`. Components are registered by name and can be referenced in message content.
@@ -327,7 +544,7 @@ function App() {
327
544
  Use the `registerComponent` method from the `useCustomComponents` hook:
328
545
 
329
546
  ```tsx
330
- import { useCustomComponents } from 'langgraph-ui-components/hooks';
547
+ import { useCustomComponents } from 'langgraph-ui-components/providers';
331
548
 
332
549
  function RegisterComponent() {
333
550
  const { registerComponent } = useCustomComponents();
@@ -345,28 +562,172 @@ function RegisterComponent() {
345
562
  - `registerComponents(components)`: Register multiple components at once.
346
563
  - `unregisterComponent(name)`: Remove a registered component.
347
564
 
565
+ ## Human-in-the-Loop (HITL) Interrupts
566
+
567
+ LangGraph agents can pause mid-execution and ask a human to review or approve an action before continuing. This library has built-in support for rendering these interrupt requests with custom UI.
568
+
569
+ ### How It Works
570
+
571
+ 1. Your agent raises an interrupt with an `actionRequests` payload
572
+ 2. The library detects `stream.interrupt` and looks up a registered interrupt component by **tool name**
573
+ 3. Your component receives the interrupt data and action callbacks
574
+ 4. Calling one of the action callbacks resumes the agent
575
+
576
+ ### Agent-side Interrupt Format
577
+
578
+ Your LangGraph agent should raise an interrupt with this shape:
579
+
580
+ ```python
581
+ from langgraph.types import interrupt
582
+
583
+ interrupt({
584
+ "actionRequests": [
585
+ {
586
+ "name": "send_email", # must match the name you register
587
+ "args": {"to": "user@example.com", "subject": "Hello"},
588
+ "description": "Send a welcome email" # optional
589
+ }
590
+ ],
591
+ "reviewConfigs": [
592
+ {
593
+ "actionName": "send_email",
594
+ "allowedDecisions": ["approve", "reject", "edit"]
595
+ }
596
+ ]
597
+ })
598
+ ```
599
+
600
+ ### Registering an Interrupt Component
601
+
602
+ Use `registerInterruptComponent` from `useCustomComponents()` to register a component for a specific tool name:
603
+
604
+ ```tsx
605
+ import { useCustomComponents } from 'langgraph-ui-components/providers';
606
+ import type { InterruptComponentProps } from 'langgraph-ui-components/providers';
607
+ import { useEffect } from 'react';
608
+
609
+ function SendEmailInterrupt({ interrupt, actions }: InterruptComponentProps) {
610
+ const request = interrupt.actionRequests[0];
611
+
612
+ return (
613
+ <div className="border rounded p-4">
614
+ <h3>Approve Action: {request.name}</h3>
615
+ <pre>{JSON.stringify(request.args, null, 2)}</pre>
616
+ <div className="flex gap-2 mt-3">
617
+ <button onClick={() => actions.approve()}>Approve</button>
618
+ <button onClick={() => actions.reject("Not needed")}>Reject</button>
619
+ <button onClick={() => actions.edit({ subject: "Updated subject" })}>
620
+ Edit & Approve
621
+ </button>
622
+ </div>
623
+ </div>
624
+ );
625
+ }
626
+
627
+ function App() {
628
+ const { registerInterruptComponent } = useCustomComponents();
629
+
630
+ useEffect(() => {
631
+ // Register for the tool name that matches your agent's interrupt
632
+ registerInterruptComponent('send_email', SendEmailInterrupt);
633
+ }, [registerInterruptComponent]);
634
+
635
+ return <Sidebar />;
636
+ }
637
+ ```
638
+
639
+ Or register via `ChatProvider`'s `customComponents` if you prefer props-based setup (note: this is for generative UI components — for interrupts, use `registerInterruptComponent` as above).
640
+
641
+ ### `InterruptComponentProps`
642
+
643
+ ```typescript
644
+ interface InterruptComponentProps {
645
+ interrupt: {
646
+ actionRequests: Array<{
647
+ name: string;
648
+ args: Record<string, unknown>;
649
+ description?: string;
650
+ }>;
651
+ reviewConfigs: Array<{
652
+ actionName: string;
653
+ allowedDecisions: string[];
654
+ argsSchema?: Record<string, unknown>;
655
+ }>;
656
+ };
657
+ actions: {
658
+ /** Resume the agent with approval */
659
+ approve: () => void;
660
+ /** Resume the agent with rejection */
661
+ reject: (reason?: string) => void;
662
+ /** Resume the agent with edited arguments */
663
+ edit: (editedArgs: Record<string, unknown>) => void;
664
+ };
665
+ }
666
+ ```
667
+
668
+ ### `useCustomComponents` — Interrupt Methods
669
+
670
+ - `registerInterruptComponent(toolName, component)` — Register a component to render when the agent interrupts for the given tool name
671
+ - `unregisterInterruptComponent(toolName)` — Remove a registered interrupt component
672
+
673
+ ### Accessing Interrupt State Directly
674
+
675
+ You can also access the raw interrupt from the stream context if you need to build custom logic:
676
+
677
+ ```tsx
678
+ import { useStreamContext } from 'langgraph-ui-components/providers';
679
+
680
+ function MyComponent() {
681
+ const { interrupt, isLoading } = useStreamContext();
682
+
683
+ if (!isLoading && interrupt) {
684
+ console.log('Agent paused:', interrupt.value);
685
+ }
686
+ }
687
+ ```
688
+
689
+ ## chatBodyProps
690
+
691
+ The `chatBodyProps` prop on both `Chat` and `Sidebar` customizes how agent messages are displayed:
692
+
693
+ ```tsx
694
+ <Sidebar
695
+ chatBodyProps={{
696
+ agentName: "Aria",
697
+ agentAvatarUrl: "https://example.com/avatar.png",
698
+ fontSize: "15px",
699
+ }}
700
+ />
701
+ ```
702
+
703
+ **Props:**
704
+ - `agentName?: string` — Display name shown above agent messages. Default: `"Agent"`
705
+ - `agentAvatarUrl?: string` — URL for the agent avatar image
706
+ - `fontSize?: string` — Font size for message text (e.g. `"14px"`, `"1rem"`)
707
+
348
708
  ## Types
349
709
 
350
710
  Full TypeScript definitions available for:
351
- - `ChatIdentity`
352
- - `ChatRuntimeContextValue`
353
- - `FileInfo`
354
- - `SuggestionsOptions`
355
- - `SuggestionConfig`
356
- - `ThreadMode`
357
- - `ThreadConfiguration`
358
- - `ThreadContextType`
359
- - `StateType`
360
- - `CustomComponentContextValue`
361
- - `CustomTool`
362
- - `ModelOption`
363
- - `ChatProps`
364
- - `ChatSidebarProps`
365
- - `ChatUIProps`
366
- - `CallThisOnSubmitResponse`
367
- - `chatBodyProps`
368
- - `headerProps`
369
- - `textToSpeechVoice`
711
+ - `ChatIdentity` — user/org identity + auth token
712
+ - `ChatRuntimeContextValue` — `useChatRuntime()` return type
713
+ - `FileInfo` — `{ fileName, fileType, file?, fileData?, metadata? }`
714
+ - `SuggestionsOptions` — options for `useChatSuggestions`
715
+ - `SuggestionConfig` — internal suggestion config shape
716
+ - `ThreadMode` — `"single" | "multi"`
717
+ - `ThreadConfiguration` — `Record<string, unknown>` passed to LangGraph config
718
+ - `ThreadContextType` — `useThread()` return type
719
+ - `StateType` — `{ messages, ui?, suggestions? }`
720
+ - `CustomComponentContextValue` — `useCustomComponents()` return type
721
+ - `InterruptComponentProps` — props for HITL interrupt components
722
+ - `CustomTool` — `{ label, icon, alt?, onClick }`
723
+ - `ModelOption` — `{ id, name }`
724
+ - `ChatProps` — base props shared by Chat and Sidebar
725
+ - `ChatSidebarProps` — Sidebar-specific props (extends ChatProps)
726
+ - `ChatUIProps` — Chat-specific props (extends ChatProps)
727
+ - `CallThisOnSubmitResponse` — `{ files?, contextValues? }`
728
+ - `chatBodyProps` — `{ agentName?, agentAvatarUrl?, fontSize? }`
729
+ - `headerProps` — `{ title?, logoUrl? }`
730
+ - `textToSpeechVoice` — `{ apiUrl, apiKey, model }`
370
731
 
371
732
  ## Keywords
372
733
 
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={exports:{}};exports.__module=e;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={};exports.__exports=e;
2
2
  //# sourceMappingURL=index.cjs6.js.map
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={};exports.__exports=e;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var e={exports:{}};exports.__module=e;
2
2
  //# sourceMappingURL=index.cjs8.js.map
@@ -1,5 +1,5 @@
1
- var e = { exports: {} };
1
+ var r = {};
2
2
  export {
3
- e as __module
3
+ r as __exports
4
4
  };
5
5
  //# sourceMappingURL=index.es6.js.map
@@ -1,5 +1,5 @@
1
- var r = {};
1
+ var e = { exports: {} };
2
2
  export {
3
- r as __exports
3
+ e as __module
4
4
  };
5
5
  //# sourceMappingURL=index.es8.js.map