# Modes API

A plugin can add its own [modes](/docs/ai/agent/modes.md) to the Agent. A mode is
declared in PHP with `Agent::registerMode()`, and a script can extend it in
the browser with files, tools and an instruction built at run time. The
built-in Block Editor mode is made exactly this way.

## Registering a mode

Register the mode once SleekAI has booted, on the `sleekAi/init` action:

```php
add_action('sleekAi/init', function () {
    \SleekAi\Agent\Agent::registerMode([
        'id' => 'product-writer',
        'label' => 'Product writer',
        'description' => 'Writes product descriptions',
        'category' => 'Shop',
        'detection' => ['bodyClass' => 'post-type-product'],
        'agent' => [
            'systemInstruction' => './product-writer.md',
            'executeJs' => true,
        ],
        'script' => plugins_url('product-writer.js', __FILE__),
    ]);
});
```

| Key                       | Meaning                                                                                                                                                                                                                                                                                                               |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                      | Required. A unique identifier, in lowercase letters and hyphens.                                                                                                                                                                                                                                                      |
| `label`                   | The name in the mode list. Defaults to the `id`.                                                                                                                                                                                                                                                                      |
| `description`             | The line under the name in the mode list.                                                                                                                                                                                                                                                                             |
| `category`                | The group in the mode list. Defaults to `General`; a new name makes a new group.                                                                                                                                                                                                                                      |
| `detection`               | Limits the mode to matching screens. `bodyClass` matches a class of the page's `body`, `elementSelector` an element on the page, and `context` a [context](/docs/ai/agent/context.md) by its id; a mode that names the screen's own context is also chosen there by default. Without it, the mode is offered everywhere. |
| `requiresCapability`      | An Agent role capability the user needs. The Agent knows only `useAgent` in this release, so any other value hides the mode.                                                                                                                                                                                          |
| `toolbar`                 | A toolbar the mode shows. A mode with the `plugin` toolbar is not offered in this release.                                                                                                                                                                                                                            |
| `agent.systemInstruction` | The mode's instruction. A string, or a path starting with `./` to a Markdown file beside the file that registers the mode.                                                                                                                                                                                            |
| `agent.canvas`            | Gives the Agent virtual files, which a script provides.                                                                                                                                                                                                                                                               |
| `agent.executeJs`         | Lets the Agent run JavaScript in the page.                                                                                                                                                                                                                                                                            |
| `agent.isolated`          | Makes the mode the only one where it is detected, as the page builder modes are.                                                                                                                                                                                                                                      |
| `agent.claude`            | `enabled` and `claudeMd`, the instructions for a [coding agent](/docs/ai/agent/coding-agents.md) terminal. Terminals also need `canvas`.                                                                                                                                                                                 |
| `script`, `scripts`       | URLs of scripts the Agent loads before it starts, to extend the mode.                                                                                                                                                                                                                                                 |

The Markdown file of `systemInstruction` and `claudeMd` must lie inside the
directory of the registering file; a path outside it gives an empty
instruction.

## Extending a mode in the browser

A mode's script calls `window.sleekAiAgent.extendMode()` with the mode's id.
Whatever it passes under `agent` is merged into the mode. The script runs in
the Agent's own document, not in the page on the right;
`window.sleekAiAgent.iframeEl()` returns the frame that holds the page:

```js
window.sleekAiAgent = window.sleekAiAgent || {}
const page = () => window.sleekAiAgent.iframeEl().contentDocument

window.sleekAiAgent.extendMode("product-writer", {
  agent: {
    systemInstruction: () =>
      "You write product descriptions for " + page().title,
    tools: [
      {
        name: "get_product_title",
        description: "Returns the title of the product being edited.",
        schema: { type: "object", properties: {}, required: [] },
        execute: () => ({ title: page().title }),
      },
    ],
  },
})
```

- `systemInstruction` may be a function, called for every request, so the
  instruction can describe the current state of the page.
- `tools` are offered to the model by `name`. A tool's `schema` is a JSON
  Schema of its input, and `execute` receives that input and returns a
  JSON-compatible result. A tool may not reuse the name of another tool: the
  request fails if one does.
- `fileSystem`, with `canvas`, provides the virtual files. `getInitialFiles()`
  returns an object of paths and contents at the start of each request, and
  `onFileChange(path, content)` applies a file the Agent wrote to the page.
  `onBeforeRead(path)` returns the current content of a file when a coding
  agent reads it.

The built-in Block Editor mode, in SleekAI's
`includes/agents/modes/block-editor/script.js`, is a complete example: every
block is a `blocks/<clientId>/block.json` file, a written file updates the
block's attributes or replaces it, and `get_selected_block` names the block
you selected.

## Contexts

A context tells the Agent which kind of screen it is on, so that `detection`
can name it. [Context](/docs/ai/agent/context.md) describes the built-in ones and
`Agent::registerContext()`.
