> ## Documentation Index
> Fetch the complete documentation index at: https://docs.viamoss.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Hooks

> Moss 어시스턴트를 프로그래밍 방식으로 제어하기 위한 React Hooks

# React Hooks

Moss SDK는 어시스턴트 UI를 프로그래밍 방식으로 제어할 수 있는 React Hooks를 제공합니다. 선언적인 `data-moss-trigger` 속성보다 더 세밀한 제어가 필요할 때 사용하세요.

## useAgent

Moss 어시스턴트와 상호작용하기 위한 주요 Hook입니다. 반드시 `AgentProvider` 내에서 사용해야 합니다.

```tsx theme={null}
import { useAgent } from '@viamoss/moss-sdk';

function MyComponent() {
  const {
    isChatOpen,
    openChat,
    closeChat,
    toggleChat,
    messages,
    sendMessage,
    isConnected,
    isWaitingForResponse,
  } = useAgent();

  return (
    <button onClick={() => openChat()}>
      어시스턴트 열기
    </button>
  );
}
```

***

## 반환 값

`useAgent()`는 다음 속성과 메서드를 포함하는 `AgentState` 객체를 반환합니다:

### 상태 속성

| 속성                     | 타입                  | 설명                           |
| ---------------------- | ------------------- | ---------------------------- |
| `isConnected`          | `boolean`           | SDK가 백엔드에 연결되어 있는지 여부        |
| `isChatOpen`           | `boolean`           | 채팅 모달이 현재 열려 있는지 여부          |
| `messages`             | `ChatMessage[]`     | 현재 대화의 메시지 배열                |
| `isWaitingForResponse` | `boolean`           | 어시스턴트가 응답을 처리 중인지 여부         |
| `chatMode`             | `'chat' \| 'guide'` | 현재 대화 모드                     |
| `suggestsGuideMode`    | `boolean`           | 어시스턴트가 가이드 모드로 전환을 제안했는지 여부  |
| `useVision`            | `boolean`           | 비전(스크린샷 분석) 기능이 활성화되어 있는지 여부 |
| `debugMode`            | `boolean`           | 디버그 모드가 활성화되어 있는지 여부         |

### 채팅 제어 메서드

#### `openChat(position?)`

채팅 모달을 엽니다. 이미 열려 있으면 아무 동작도 하지 않습니다.

```tsx theme={null}
const { openChat } = useAgent();

// 기본 위치로 열기
openChat();

// 사용자 지정 위치로 열기
openChat({ x: 100, y: 100, width: 400, height: 600 });
```

| 매개변수       | 타입                     | 설명               |
| ---------- | ---------------------- | ---------------- |
| `position` | `DefaultModalPosition` | 선택사항. 초기 위치 및 크기 |

***

#### `closeChat()`

채팅 모달을 닫습니다. 이미 닫혀 있으면 아무 동작도 하지 않습니다.

```tsx theme={null}
const { closeChat } = useAgent();

closeChat();
```

***

#### `toggleChat(position?)`

채팅 모달을 열거나 닫습니다.

```tsx theme={null}
const { toggleChat } = useAgent();

// 기본 위치로 토글
toggleChat();

// 사용자 지정 위치로 토글 (열 때 적용)
toggleChat({ x: 100, y: 100, width: 400, height: 600 });
```

| 매개변수       | 타입                     | 설명               |
| ---------- | ---------------------- | ---------------- |
| `position` | `DefaultModalPosition` | 선택사항. 열 때 적용할 위치 |

***

#### `sendMessage(text)`

어시스턴트에게 프로그래밍 방식으로 메시지를 보냅니다.

```tsx theme={null}
const { sendMessage } = useAgent();

await sendMessage('새 프로젝트는 어떻게 만드나요?');
```

| 매개변수   | 타입       | 설명     |
| ------ | -------- | ------ |
| `text` | `string` | 보낼 메시지 |

**반환:** `Promise<void>`

***

#### `startNewChat()`

현재 대화를 지우고 새 채팅 세션을 시작합니다.

```tsx theme={null}
const { startNewChat } = useAgent();

await startNewChat();
```

**반환:** `Promise<void>`

***

### 가이드 모드 메서드

#### `continueGuide()`

가이드 모드에서 다음 단계로 진행합니다. "다음" 버튼을 클릭하는 것과 동일합니다.

```tsx theme={null}
const { continueGuide, chatMode } = useAgent();

if (chatMode === 'guide') {
  await continueGuide();
}
```

**반환:** `Promise<void>`

***

#### `acceptGuideSuggestion()`

어시스턴트의 가이드 모드 전환 제안을 수락합니다. "가이드 시작" 버튼을 클릭하는 것과 동일합니다.

```tsx theme={null}
const { acceptGuideSuggestion, suggestsGuideMode } = useAgent();

if (suggestsGuideMode) {
  await acceptGuideSuggestion();
}
```

**반환:** `Promise<void>`

***

### 디버그 메서드

#### `captureContext()`

현재 페이지 컨텍스트(스크린샷 및 DOM)를 수동으로 캡처합니다. 디버깅 용도로만 유용합니다.

```tsx theme={null}
const { captureContext, debugMode } = useAgent();

if (debugMode) {
  const context = await captureContext();
  console.log(context?.screenshotDataUrl);
  console.log(context?.pageText);
}
```

**반환:** `Promise<{ screenshotDataUrl: string | null; pageText: string | null } | null>`

***

## 예제

### 커스텀 도움말 버튼

```tsx theme={null}
import { useAgent } from '@viamoss/moss-sdk';

function HelpButton() {
  const { openChat, isChatOpen } = useAgent();

  return (
    <button
      onClick={() => openChat()}
      disabled={isChatOpen}
    >
      {isChatOpen ? '채팅 열림' : '도움이 필요하세요?'}
    </button>
  );
}
```

### 키보드 단축키

```tsx theme={null}
import { useEffect } from 'react';
import { useAgent } from '@viamoss/moss-sdk';

function KeyboardShortcut() {
  const { toggleChat } = useAgent();

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      // Cmd/Ctrl + K로 채팅 토글
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
        e.preventDefault();
        toggleChat();
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [toggleChat]);

  return null;
}
```

### 메시지 카운터 배지

```tsx theme={null}
import { useAgent } from '@viamoss/moss-sdk';

function MessageBadge() {
  const { messages, openChat } = useAgent();
  const unreadCount = messages.filter(m => m.sender === 'assistant').length;

  return (
    <button onClick={() => openChat()} className="relative">
      도움말
      {unreadCount > 0 && (
        <span className="badge">{unreadCount}</span>
      )}
    </button>
  );
}
```

### 로딩 상태와 함께 메시지 보내기

```tsx theme={null}
import { useState } from 'react';
import { useAgent } from '@viamoss/moss-sdk';

function QuickQuestion() {
  const { sendMessage, openChat, isWaitingForResponse } = useAgent();
  const [question, setQuestion] = useState('');

  const handleSubmit = async () => {
    if (!question.trim()) return;
    openChat();
    await sendMessage(question);
    setQuestion('');
  };

  return (
    <div>
      <input
        value={question}
        onChange={(e) => setQuestion(e.target.value)}
        placeholder="빠른 질문하기..."
        disabled={isWaitingForResponse}
      />
      <button
        onClick={handleSubmit}
        disabled={isWaitingForResponse || !question.trim()}
      >
        {isWaitingForResponse ? '전송 중...' : '질문하기'}
      </button>
    </div>
  );
}
```

***

## 참고사항

<Warning>
  `useAgent()`는 반드시 `AgentProvider` 내에서 호출해야 합니다. 외부에서 호출하면 오류가 발생합니다.
</Warning>

<Info>
  이 Hook은 안정적인 함수 참조를 반환합니다. 의존성 배열에 안전하게 포함할 수 있으며 불필요한 리렌더링을 유발하지 않습니다.
</Info>
