npm package: @optilogic/chat
Description: Chat UI components for Optilogic - AgentResponse and related components for LLM interactions
Latest version: 1.3.2

# @optilogic/chat

Chat UI components for opti-ui - Components for displaying LLM/AI agent interactions.

## Installation

```bash
npm install @optilogic/chat @optilogic/core @optilogic/editor slate slate-react slate-history
```

## Setup

Make sure you have configured `@optilogic/core` with the Tailwind preset and CSS variables.

## Usage

### AgentResponse

Display AI agent responses with thinking indicators, tool calls, and feedback actions:

```tsx
import { AgentResponse, useAgentResponseAccumulator } from '@optilogic/chat';

function ChatView() {
  const { state, handlers } = useAgentResponseAccumulator({
    onComplete: (response) => console.log('Response complete:', response),
  });

  return (
    <AgentResponse
      {...state}
      onCopy={() => navigator.clipboard.writeText(state.content)}
      onFeedback={(value) => console.log('Feedback:', value)}
    />
  );
}
```

### UserPrompt

Display user messages in the chat:

```tsx
import { UserPrompt } from '@optilogic/chat';

function ChatMessage() {
  return (
    <UserPrompt
      content="What is the weather today?"
      timestamp={new Date()}
    />
  );
}
```

### UserPromptInput

Input component for user messages:

```tsx
import { UserPromptInput } from '@optilogic/chat';

function ChatInput() {
  return (
    <UserPromptInput
      onSubmit={(text) => console.log('Submitted:', text)}
      placeholder="Type your message..."
    />
  );
}
```

### HITLQuestionPanel

Display an interactive panel for human-in-the-loop clarifying questions. Replaces the input area when the agent needs user clarification:

```tsx
import { HITLQuestionPanel, type HITLQuestion } from '@optilogic/chat';

const question: HITLQuestion = {
  reason: "I need clarification before proceeding with the data mapping.",
  questions: [
    "Which table should I load the shipment data into?",
    "Should I overwrite existing rows or append?",
  ],
  options: {
    "Which table should I load the shipment data into?": ["Customers", "Demand", "Shipments"],
    "Should I overwrite existing rows or append?": ["Overwrite", "Append"],
  },
  context: "Source file has 1,200 rows with columns: origin, destination, quantity, date",
  timeoutSeconds: 300,
  receivedAt: Date.now(),
};

function ChatInput() {
  return (
    <HITLQuestionPanel
      question={question}
      onSubmit={(response) => console.log('Response:', response)}
      onStop={() => console.log('Agent stopped')}
    />
  );
}
```

### HITLInteractionRecord

Display a completed HITL Q&A interaction in the chat history:

```tsx
import { HITLInteractionRecord, type HITLInteraction } from '@optilogic/chat';

const interaction: HITLInteraction = {
  question: { /* HITLQuestion object */ },
  response: "Q: Which table?\nA: Shipments",
  respondedAt: Date.now(),
};

function CompletedInteraction() {
  return <HITLInteractionRecord interaction={interaction} />;
}
```

### AgentResponse with HITL Interactions

HITL interactions can also be displayed as a collapsible section within AgentResponse:

```tsx
import { AgentResponse, type HITLInteraction } from '@optilogic/chat';

function ChatView() {
  const hitlInteractions: HITLInteraction[] = [/* completed interactions */];

  return (
    <AgentResponse
      state={state}
      hitlInteractions={hitlInteractions}
      defaultHITLExpanded={false}
    />
  );
}
```

### AgentResponse with Status Content

Display ephemeral status messages in the metadata row during agent processing:

```tsx
import { AgentResponse, TruncatedMessage } from '@optilogic/chat';

function ChatView() {
  const [statusMessage, setStatusMessage] = useState<string>();

  // Parent controls when to show/clear status content
  // e.g., set during processing, clear on completion

  return (
    <AgentResponse
      state={state}
      statusContent={
        statusMessage
          ? <TruncatedMessage message={statusMessage} />
          : undefined
      }
    />
  );
}
```

### TruncatedMessage

Standalone component that renders a single-line string with CSS-based truncation:

```tsx
import { TruncatedMessage } from '@optilogic/chat';

<TruncatedMessage message="Searching the knowledge base for relevant documents..." />
```

## Components

### AgentResponse
Main component for displaying AI agent responses with:
- Streaming content support
- Thinking/reasoning indicators
- Tool call visualization
- Copy and feedback actions
- Metadata display (tokens, timing)
- Ephemeral status content slot in metadata row
- Optional collapsible HITL interaction history

### UserPrompt
Component for displaying user messages in the chat interface.

### UserPromptInput
Input component for composing user messages with tag support.

### HITLQuestionPanel
Interactive panel for displaying agent clarifying questions with:
- Predefined option buttons (toggleable selection)
- Free-form text input
- Countdown timer with visual warning state
- Keyboard support (Enter to submit, Shift+Enter for newlines)

### HITLInteractionRecord
Read-only display of a completed HITL Q&A interaction with:
- Per-question inline answers
- Context display
- Fallback for non-structured response formats

### HITLSection
Collapsible sub-component for rendering HITL interactions within AgentResponse. Follows the same expand/collapse pattern as ThinkingSection.

### TruncatedMessage
Standalone utility component for single-line text truncation with:
- CSS-based ellipsis truncation
- Native title tooltip for full text on hover
- Designed for use in MetadataRow status slot or anywhere else

## Hooks

### useAgentResponseAccumulator
Manages state for streaming agent responses, handling incremental updates and message accumulation.

### useThinkingTimer
Tracks elapsed time during agent thinking phases.

## Utilities

### buildResponseString
Combines selected options and free-form text into a single formatted string for the backend. Used internally by HITLQuestionPanel and can be used to construct responses programmatically.

## License

MIT