> For the complete documentation index, see [llms.txt](https://dnotifier.gitbook.io/product-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dnotifier.gitbook.io/product-docs/workflows-and-agents/workflow-context.md).

# WorkflowContext reference

`WorkflowContext` (`ctx`) is passed to the workflow **`entry`** function and each agent's **`run`** handler. Use it for input, shared state, calling other agents, and SDK methods (AI, search, documents).

## Properties

| Member          | Description                                                                            |
| --------------- | -------------------------------------------------------------------------------------- |
| `ctx.input`     | Workflow input from `runWorkflow`, or overridden when you call `runAgent` with `input` |
| `ctx.state`     | Shared mutable object for this run — use it to pass data between agents                |
| `ctx.agentName` | Name of the agent currently running (inside an agent `run` handler)                    |
| `ctx.senderId`  | Sender id used for SDK calls inside the workflow                                       |
| `ctx.workflow`  | Parent workflow definition                                                             |
| `ctx.notifier`  | Underlying notifier instance (advanced use)                                            |

## Methods

| Method                                                                                          | Description                                                                                                                                     |
| ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `ctx.runAgent(name, { input? })`                                                                | Run one registered agent. Optional `input` overrides `ctx.input` for that agent.                                                                |
| `ctx.runAgents(spec)`                                                                           | Run multiple agents in parallel. Returns `{ results }`.                                                                                         |
| `ctx.waitForMessage({ timeoutMs? })` / `wait_for_message`                                       | Wait for the next inbound realtime message (WebSocket).                                                                                         |
| `ctx.sendAI({ message, saveHistory?, sessionId?, provider?, model?, label? })`                  | Call the AI API. Optional `provider` / `model` override project defaults (or agent defaults). Optional `label` names the step in the dashboard. |
| `ctx.fetchAIHistory({ label? })`                                                                | Fetch AI history for `senderId`.                                                                                                                |
| `ctx.search({ query, limit?, minSimilarity?, filterbySource?, label? })`                        | Semantic search over the knowledge base.                                                                                                        |
| `ctx.addDocument(opts)` / `updateDocument` / `deleteDocument` / `listDocuments` / `getDocument` | Knowledge-base document helpers.                                                                                                                |
| `ctx.recordStep({ label, input?, output?, status? })`                                           | Record a custom step when observability is enabled.                                                                                             |

Python names use snake\_case: `run_agent`, `run_agents`, `send_ai`, `fetch_ai_history`, etc.

## Call one agent

{% tabs %}
{% tab title="JavaScript" %}

```js
const draft = await ctx.runAgent("content-creator");

const refined = await ctx.runAgent("clarity-editor", {
  input: { content: draft.content },
});
```

{% endtab %}

{% tab title="Python" %}

```python
draft = await ctx.run_agent("content-creator")
refined = await ctx.run_agent(
    "clarity-editor",
    input_data={"content": draft["content"]},
)
```

{% endtab %}

{% tab title="Dart" %}

```dart
final draft = await ctx.runAgent('content-creator');
final refined = await ctx.runAgent(
  'clarity-editor',
  input: {'content': (draft as Map)['content']},
);
```

{% endtab %}
{% endtabs %}

## Call agents in parallel

{% tabs %}
{% tab title="JavaScript" %}

```js
const { results } = await ctx.runAgents([
  { name: "outline-planner" },
  { name: "keyword-researcher" },
]);
const [outline, keywords] = results;
```

{% endtab %}

{% tab title="Python" %}

```python
out = await ctx.run_agents([
    {"name": "outline-planner"},
    {"name": "keyword-researcher"},
])
outline, keywords = out["results"]
```

{% endtab %}

{% tab title="Dart" %}

```dart
final out = await ctx.runAgents([
  {'name': 'outline-planner'},
  {'name': 'keyword-researcher'},
]);
final results = out['results'] as List;
final outline = results[0];
final keywords = results[1];
```

{% endtab %}
{% endtabs %}

More patterns: [**Parallel agents & shared state**](/product-docs/workflows-and-agents/step-graph.md).

## Shared state

```js
async run(ctx) {
  ctx.state.draft = "markdown content...";
  ctx.state.stage = "draft";
  return { content: ctx.state.draft };
}

// Later in the same run:
const article = ctx.state.draft;
```

## Observability

When `observability: true` on the workflow, calls like `sendAI`, `search`, `runAgent`, and `recordStep` show up as steps in the dashboard. You do not need extra setup beyond enabling the flag and connecting the client.

## Errors

```js
import { DNotifier } from "@dnotifier-realtime/dnotifier";

if (!ctx.input?.topic) {
  throw new DNotifier.WorkflowError("content-creator: topic is required", {
    agentName: "content-creator",
  });
}
```

## Language notes

| Language | Import                                                       |
| -------- | ------------------------------------------------------------ |
| JS / TS  | `@dnotifier-realtime/dnotifier` — `runAgent`, `runAgents`    |
| Dart     | `package:dnotifier/dnotifier.dart` — same camelCase API      |
| Python   | `from dnotifier import Workflow` — `run_agent`, `run_agents` |

## Next steps

* [**Parallel agents & shared state**](/product-docs/workflows-and-agents/step-graph.md)
* [**Build a workflow**](/product-docs/workflows-and-agents/build-workflow.md)
* [**Workflow observability**](/product-docs/workflows-and-agents/observability.md)
