> For the complete documentation index, see [llms.txt](https://docs.sail.money/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sail.money/sailor/sdk/agent.md).

# The Agent interface

A Sailor agent is a small object: a name, a description, and a `tick()` that the runner calls on every scheduled execution. `tick()` returns the dispatches it made.

```ts
export type Agent = {
  name: string;
  description: string;
  tick(ctx: AgentContext): Promise<Dispatch[]>;
};
```

Export one as the default from your strategy module; `sailor run` imports and ticks it. Keep the financial bounds in the [permission](/sailor/guides/build-a-mandate.md), and keep timing/selection in `tick()` — see [on-chain vs off-chain](/sailor/concepts/on-chain-off-chain.md).

## AgentContext

Every `tick()` receives a fully-wired context:

```ts
type AgentContext = {
  safe: Address;            // the SMA address
  account: Address;         // alias of `safe`
  chainId: number;
  blockNumber: bigint;
  timestamp: number;        // unix seconds
  now: Date;                // wall-clock time of this tick
  client: ISailorClient;    // a ready SailorClient (see SailorClient)
  publicClient: PublicClient; // viem client for arbitrary reads (QuoterV2, custom views, multicall)
  manager: ILocalKeyring;   // the manager keyring used to sign dispatches
  log: (msg: string) => void; // console + appends to .sail/activity.jsonl
  data: Record<string, unknown>; // your own data slot (see below)
  read: {
    balance:   (token: Address | "native") => Promise<bigint>;
    allowance: (token: Address, owner: Address, spender: Address) => Promise<bigint>;
    decimals:  (token: Address) => Promise<number>;
  };
};
```

| Field                                 | Use it for                                                        |
| ------------------------------------- | ----------------------------------------------------------------- |
| `account` / `safe`                    | the SMA you operate; pass to `client.*` calls                     |
| `client`                              | high-level dispatch/strategy/mandate operations                   |
| `publicClient`                        | any on-chain read `ctx.read` doesn't cover                        |
| `manager`                             | signing — pass to `client.dispatch.*` / `client.strategy.*`       |
| `read.balance / allowance / decimals` | quick SMA state reads (`decimals` is cached for the process)      |
| `log`                                 | activity logging that shows in the dashboard and `activity.jsonl` |
| `data`                                | your inputs (see below)                                           |

### The `data` slot

Sailor bakes in **no** third-party data sources. `ctx.data` is an open slot for your own: populate it inside your agent, or seed it from a JSON file via the `SAILOR_DATA` environment variable. It defaults to an empty object. Use it for price feeds, signals, or any external input your strategy needs — you own that integration.

## A minimal tick

```ts
import type { Agent, AgentContext, Dispatch } from "@sail.money/sailor/sdk";

const agent: Agent = {
  name: "rebalance-guard",
  description: "Tops up WETH when the SMA's balance drops below a floor.",
  async tick(ctx: AgentContext): Promise<Dispatch[]> {
    const weth = await ctx.read.balance("0xWETH");
    if (weth >= 1_000_000_000_000_000_000n) return []; // ≥ 1 WETH, nothing to do
    const { swap } = await ctx.client.strategy.swap(
      ctx.account,
      { from: "0xUSDC", to: "0xWETH", amount: 50_000_000n, swapPermission: "0xSwapPermission" },
      ctx.manager,
    );
    ctx.log(`topped up WETH via ${swap.txHash}`);
    return [swap];
  },
};

export default agent;
```

Return the `Dispatch[]` you executed (or `[]` for a no-op tick). Anything outside the mandate is rejected on-chain — see [Run a strategy & dispatch](/sailor/guides/run-a-strategy.md) for what a denial looks like.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.sail.money/sailor/sdk/agent.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
