---
title: "useComposer"
description: "useComposer(selector) chỉ chạy trong hosted composer-panel và throw ở nơi khác. Import từ @sota/core/hooks. Chỉ select field component cần để thay đổi không liên quan không gây…"
url: "https://sotaagents.ai/vi/manual/developer-guide/use-composer"
generated_by: "sotaagents-ldp"
docs_index: "https://sotaagents.ai/manual/llms.txt"
locale: "vi"
---

# useComposer

`useComposer(selector)` chỉ chạy trong hosted `composer-panel` và throw ở nơi khác. Import từ `@sota/core/hooks`. Chỉ select field component cần để thay đổi không liên quan không gây thêm work.

| Field | Contract |
| --- | --- |
| `value` | Plain-text view của draft hiện tại. |
| `content` | Structured text và node `app-reference`. |
| `references` | Slash, conversation và app reference theo lane đã resolve. |
| `pendingToolResults` | Deferred tool results thuộc exact app execution của panel. |
| `applyEdit(edit)` | Một editor transaction có undo, với mode `replace`, `insert-at-cursor` hoặc `append`. |
| `focus()` | Focus composer editor. |
| `acquireLock()` | Disable send, edit draft, edit message cũ và queued auto-send khi đang giữ; trả release function idempotent. |

TSX

```
import { useEffect } from 'react';
import { useComposer } from '@sota/core/hooks';

export function PendingActionPanel() {
  const pending = useComposer((composer) => composer.pendingToolResults);
  const acquireLock = useComposer((composer) => composer.acquireLock);
  const active = pending.find((item) => item.toolName === 'readCalendar');

  useEffect(() => {
    if (!active) return;
    return acquireLock();
  }, [acquireLock, active]);

  if (!active) return null;
  return <p>Complete the app action to continue.</p>;
}
```

Lock được reference-count: nhiều panel hoặc operation giữ độc lập. Core auto-release khi surface unmount, nhưng app vẫn nên return release từ effect. Giữ structured `content`; dựng lại từ `value` sẽ làm phẳng reference.

TSX

```
import { useComposer } from '@sota/core/hooks';

export function InsertReportButton() {
  const applyEdit = useComposer((composer) => composer.applyEdit);
  return <button type="button" onClick={() => applyEdit({
    mode: 'insert-at-cursor',
    content: [
      { kind: 'text', text: 'Review ' },
      {
        kind: 'app-reference',
        referenceType: 'report',
        referenceId: 'report-42',
        label: 'Q3 report',
        fallbackText: 'Q3 report',
      },
    ],
  })}>Insert report</button>;
}
```

Mỗi `pendingToolResults` item có `operationId`, `toolCallId`, canonical `toolName`, collision-resolved `modelToolName`, `data` opaque tùy chọn và exact `execution`. Phải narrow `data` ở runtime. Hai field `pendingToolResults`/`acquireLock` cần platform contract `1.3.0` trở lên.
