# Observe Changes

Keep an agent informed when someone changes the UI.

`agent.subscribe` reports changes to ui-sdk components. Collect them between turns so the agent knows what changed since it last read the page.

Reuse the bridge from the [Guide](/docs/agents/connect-an-agent/guide). The examples below go in a module that runs when your app starts.

## Collect Changes

This subscription collects changes made outside the bridge. That includes a person's interactions and changes made by your application:

```ts
import type { ObservedChange } from "@ui-sdk/react/observe"
import { agent } from "./agent"

const changes: ObservedChange[] = []

const stop = agent.subscribe((change) => {
  if (change.source !== "agent") {
    changes.push(change)
  }
})
```

Before the agent's next turn, take the queued changes:

```ts
const recentChanges = changes.splice(0)
```

Include `recentChanges` in the context you send to your model. `splice(0)` returns the collected changes and empties the queue. Leave out the source check above if you want to collect the agent's changes too.

A change a Button's handler makes after an `await` reports `"programmatic"`, even when the agent pressed the button, unless the handler passes the press's source on with `withSource`. [Observe](/docs/core/observe#keep-the-source-after-an-await) shows how.

## Read a Change

Choosing **North America** in the Guide's Select produces a change that includes:

```json
{
  "label": "Region",
  "key": "value",
  "previous": "europe",
  "value": "north-america",
  "reason": "item-press",
  "source": "mouse"
}
```

This describes clicking the option while Europe was selected. Its `ref` identifies the component in a snapshot and can be used in an `act` step. The [Reference](/docs/agents/connect-an-agent/reference#subscribelistener) lists all the fields.

Changes canceled with `details.cancel()` aren't reported. For a controlled component, the notification reports the requested change before the owner passes the value back. It isn't confirmation that the owner accepted it.

Password, card and one-time-code fields report `"[redacted]"` for both `value` and `previous`.

## When Changes Arrive

A slider drag reports one change when it finishes, with `previous` set to the value before the drag. State that doesn't commit, such as a text field's input, reports each change. Changes made by the agent or application arrive immediately.

The subscription gives you one stream of changes. It doesn't emit a separate commit notification. For intermediate steps or a subscription limited to part of the page, use [Observe](/docs/core/observe).

## Stop Listening

When you no longer need the subscription, call the function it returned:

```ts
stop()
```

To record changes you can step back through, see [History and Undo](/docs/agents/connect-an-agent/history-and-undo).
