> 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/define-agent.md).

# Define an agent

An **agent** is a named async function that receives `WorkflowContext` and returns a result. Define agents with **`DNotifier.defineAgent`** (JavaScript) or **`defineAgent`** (Dart), then register them on a workflow.

## Agent shape

```js
const myAgent = DNotifier.defineAgent({
  name: "my-agent",           // unique within the workflow
  provider: "open_ai",        // optional — default for ctx.sendAI in this agent
  model: "gpt-4o",            // optional — default for ctx.sendAI in this agent
  async run(ctx) {
    // ctx.input — workflow or runAgent input
    // ctx.state — shared across agents
    // ctx.sendAI, ctx.search, ctx.runAgent, ...
    return { done: true };
  },
});
```

Optional `provider` / `model` on the agent are applied automatically to `ctx.sendAI` unless the call passes its own values.

## Rules

| Rule               | Detail                                                 |
| ------------------ | ------------------------------------------------------ |
| **Unique name**    | Each agent on a workflow must have a distinct `name`   |
| **`run` is async** | Return a Promise (or `async function`)                 |
| **Return value**   | Passed to caller of `ctx.runAgent("my-agent")`         |
| **Errors**         | Throw `WorkflowError` for expected validation failures |

## What agents can do

Inside `run(ctx)`:

* Call **`ctx.sendAI`** for model steps
* Call **`ctx.search`** for RAG retrieval
* Read/write **`ctx.state`** for pipeline data
* Call **`ctx.runAgent`** to delegate (uncommon inside agents — usually done in `entry`)
* **`ctx.recordStep`** for custom observability

{% hint style="info" %}
Agents do not connect or authenticate themselves. The parent `DNotifier` must `connect()` before `runWorkflow`.
{% endhint %}

## Registration

Agents are registered on the workflow — not globally:

```js
const workflow = new DNotifier.Workflow({
  name: "my-pipeline",
  entry: async (ctx) => { /* ... */ },
}).registerAgents({
  "my-agent": myAgent,
});
```

## Language guides

| Language                | Guide                                                                                                |
| ----------------------- | ---------------------------------------------------------------------------------------------------- |
| JavaScript / TypeScript | [javascript-typescript.md](/product-docs/workflows-and-agents/define-agent/javascript-typescript.md) |
| Dart / Flutter          | [dart-flutter.md](/product-docs/workflows-and-agents/define-agent/dart-flutter.md)                   |

## Next steps

* [**Build a workflow**](/product-docs/workflows-and-agents/build-workflow.md)
* [**WorkflowContext reference**](/product-docs/workflows-and-agents/workflow-context.md)
