# who_calls

> Every place that calls this function, plus calls we can't see.

Your agent asks it before it edits a function, to find what the edit could break.

## What it takes

| Input | Type | What it is |
| --- | --- | --- |
| symbol | text, required | function, method or class name, path:line, or a w-handle |
| expand | text, optional | A w-handle from this session to list in full, or reset. |
| format | text or json, optional | — |
| family | yes, no or unsure, optional | family: your answer to 'are all subclasses of these types inside this repository?' yes, no or unsure (default unsure). It sets the [a] assumption in answers. |

## Example

Your agent asks: `who_calls(symbol: "Store.save")`

The engine's answer, captured on the example project:

```text
llmgraph · who_calls Store.save (app/store.py:2): 1 certain, 1 in a set, 1 open
  ✓ certain app/admin.py:3 reset w3
  ◇ within_these, one of 3 app/service.py:4 persist -> {Store.save, PgStore.save, MemStore.save} (closed: repo only) [a] w4
  ⚠ maybe_more app/service.py:8 persist_any (open: type unknown) w5
  ⚠ plus dynamic calls elsewhere that could reach anything w6
  – ruled out: 2 same-name calls (proven: other target) [a] w7
  assumes [a]: all subclasses are in this repo (project setting)
```

Each line explained: [Reading an answer](https://beta.llmgraph.in/docs/answers/reading-an-answer.md).

## How fast

After you ask about a function, LLMGRAPH confirms its callers with the type checker in the background. Asking again a moment later shows the stronger labels as the checker confirms them.

## What it cannot tell you

- Calls built while the program runs.
- Callers in code we could not read.
- Callers outside the project.

It lists direct callers. For everything further out, ask [what_breaks_if_changed](https://beta.llmgraph.in/docs/questions/what_breaks_if_changed.md).
