---
title: "useComposer"
description: "useComposer(selector) is available only inside a hosted composer-panel and throws elsewhere. Import it from @sota/core/hooks. Select only the field a component needs so unrelate…"
url: "https://sotaagents.ai/manual/developer-guide/use-composer"
generated_by: "sotaagents-ldp"
docs_index: "https://sotaagents.ai/manual/llms.txt"
locale: "en"
---

# useComposer

`useComposer(selector)` is available only inside a hosted `composer-panel` and throws elsewhere. Import it from `@sota/core/hooks`. Select only the field a component needs so unrelated draft changes do not force work.

| Field | Contract |
| --- | --- |
| `value` | Plain-text view of the current draft. |
| `content` | Structured text and `app-reference` nodes. |
| `references` | Resolved slash, conversation, and lane-scoped app references. |
| `pendingToolResults` | Deferred tool results belonging to this panel's exact app execution. |
| `applyEdit(edit)` | One undoable editor transaction in `replace`, `insert-at-cursor`, or `append` mode. |
| `focus()` | Moves focus to the composer editor. |
| `acquireLock()` | Disables send, draft edits, existing-message edits, and queued auto-send while held; returns an idempotent release function. |

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>;
}
```

Locks are reference-counted: multiple panels or pending operations can hold them independently. Core auto-releases a lock when its surface unmounts, but app code should still return the release function from its effect. Preserve structured `content`; rebuilding from `value` flattens references.

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>;
}
```

`pendingToolResults` items contain `operationId`, `toolCallId`, canonical `toolName`, collision-resolved `modelToolName`, optional opaque `data`, and exact `execution`. Narrow app-owned `data` at runtime before rendering it. The `pendingToolResults`/`acquireLock` fields require platform contract `1.3.0` or newer.
