---
title: Overview
description: Introduction to the Octavus Client SDK for building chat interfaces.
---

# Client SDK Overview

The `@octavus/client-sdk` package provides React hooks for building chat interfaces with Octavus agents. It handles streaming, message state, and real-time updates.

**Current version:** `{{VERSION:@octavus/client-sdk}}`

## Installation

```bash
npm install @octavus/client-sdk
```

## Basic Usage

```tsx
import { useOctavusChat, type UIMessage } from '@octavus/client-sdk';

function Chat({ sessionId }: { sessionId: string }) {
  const { messages, status, send } = useOctavusChat({
    onTrigger: async (triggerName, input) => {
      return fetch(`/api/trigger`, {
        method: 'POST',
        body: JSON.stringify({ sessionId, triggerName, input }),
      });
    },
  });

  const sendMessage = async (text: string) => {
    await send('user-message', { USER_MESSAGE: text }, {
      userMessage: { content: text },
    });
  };

  return (
    <div>
      {messages.map((msg) => (
        <MessageBubble key={msg.id} message={msg} />
      ))}
    </div>
  );
}

function MessageBubble({ message }: { message: UIMessage }) {
  return (
    <div>
      {message.parts.map((part, i) => {
        if (part.type === 'text') {
          return <p key={i}>{part.text}</p>;
        }
        return null;
      })}
    </div>
  );
}
```

## Key Features

### Unified Send Function

The `send` function handles both user message display and agent triggering in one call:

```tsx
const { send } = useOctavusChat({...});

// Add user message to UI and trigger agent
await send('user-message', { USER_MESSAGE: text }, {
  userMessage: { content: text },
});

// Trigger without adding a user message (e.g., button click)
await send('request-human');
```

### Message Parts

Messages contain ordered `parts` for rich content:

```tsx
const { messages } = useOctavusChat({...});

// Each message has typed parts
message.parts.map((part) => {
  switch (part.type) {
    case 'text':       // Text content
    case 'reasoning':  // Extended reasoning/thinking
    case 'tool-call':  // Tool execution
    case 'operation':  // Internal operations (set-resource, etc.)
  }
});
```

### Status Tracking

```tsx
const { status } = useOctavusChat({...});

// status: 'idle' | 'streaming' | 'error'
```

### Stop Streaming

```tsx
const { stop } = useOctavusChat({...});

// Stop current stream and finalize message
stop();
```

## Hook Reference

### useOctavusChat

```typescript
function useOctavusChat(options: UseOctavusChatOptions): UseOctavusChatReturn;

interface UseOctavusChatOptions {
  // Required: Function that calls your backend trigger endpoint
  onTrigger: TriggerFunction;
  
  // Optional: Pre-populate with existing messages (session restore)
  initialMessages?: UIMessage[];
  
  // Optional: Callbacks
  onError?: (error: Error) => void;
  onFinish?: () => void;
  onResourceUpdate?: (name: string, value: unknown) => void;
}

interface UseOctavusChatReturn {
  // State
  messages: UIMessage[];
  status: ChatStatus;  // 'idle' | 'streaming' | 'error'
  error: Error | null;
  
  // Actions
  send: (
    triggerName: string,
    input?: Record<string, unknown>,
    options?: { userMessage?: UserMessageInput }
  ) => Promise<void>;
  stop: () => void;
}

type TriggerFunction = (
  triggerName: string,
  input?: Record<string, unknown>,
) => Promise<Response>;

interface UserMessageInput {
  content: string;
}
```

## Next Steps

- [Messages](/docs/client-sdk/messages) — Working with message state
- [Streaming](/docs/client-sdk/streaming) — Building streaming UIs
- [Execution Blocks](/docs/client-sdk/execution-blocks) — Showing agent progress
