From cd45124a78f09cdb12b2fbf37f9b6e9d74621e2d Mon Sep 17 00:00:00 2001
From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com>
Date: Wed, 15 Jul 2026 00:43:36 +0000
Subject: [PATCH] docs: document AI agents as code
---
docs.json | 3 +-
guides/ai-agents.mdx | 3 +
guides/ai-agents/agents-as-code.mdx | 172 ++++++++++++++++++++++++
guides/developer/dashboards-as-code.mdx | 6 +
references/lightdash-cli.mdx | 34 +++++
5 files changed, 217 insertions(+), 1 deletion(-)
create mode 100644 guides/ai-agents/agents-as-code.mdx
diff --git a/docs.json b/docs.json
index d9d95a6e..f23a9a06 100644
--- a/docs.json
+++ b/docs.json
@@ -164,7 +164,8 @@
"guides/ai-agents/ai-writeback",
"guides/ai-agents/content-tools",
"guides/ai-agents/mcp-servers",
- "guides/ai-agents/autopilot"
+ "guides/ai-agents/autopilot",
+ "guides/ai-agents/agents-as-code"
]
},
"references/integrations/lightdash-mcp",
diff --git a/guides/ai-agents.mdx b/guides/ai-agents.mdx
index c538085f..a092e2bb 100644
--- a/guides/ai-agents.mdx
+++ b/guides/ai-agents.mdx
@@ -51,6 +51,9 @@ This guide covers everything you need to know about AI agents in Lightdash:
+
+
+
diff --git a/guides/ai-agents/agents-as-code.mdx b/guides/ai-agents/agents-as-code.mdx
new file mode 100644
index 00000000..ab061cd3
--- /dev/null
+++ b/guides/ai-agents/agents-as-code.mdx
@@ -0,0 +1,172 @@
+---
+title: "AI agents as code"
+sidebarTitle: "Agents as code"
+description: "Download AI agents to YAML, review them in Git, and promote them between projects using the same content-as-code workflow as charts and dashboards."
+---
+
+You can serialize a project's AI agents to YAML with the Lightdash CLI, keep them under version control, and promote them between environments — preview, staging, production — using the standard `lightdash download` / `lightdash upload` flow.
+
+Use agents as code when you want to:
+
+- Review agent instructions, tags, and model settings in pull requests before they reach production
+- Copy a working agent from one project to another (for example, from a preview into production) without recreating it in the UI
+- Roll agent config back to a known-good version using Git history
+- Bootstrap new projects with the same set of agents you use elsewhere
+
+Agent config as code is **opt-in**. A bare `lightdash download` does not include agents — you have to ask for them with `--include-agents` or `--agents`.
+
+
+This is part of the same content-as-code system as [dashboards as code](/guides/developer/dashboards-as-code). The same disposable-vs-Git-managed tradeoff and CI patterns apply.
+
+
+## On-disk layout
+
+Agent files live under `lightdash/ai-agents/` next to your `charts/` and `dashboards/` folders. Each agent is a single `.yml` file named after its slug:
+
+```text
+lightdash/
+├── ai-agents/
+│ ├── orders-support-agent.yml
+│ └── revenue-analyst.yml
+├── charts/
+└── dashboards/
+```
+
+`lightdash upload` automatically picks up every `.yml` (or `.yaml`) file in `lightdash/ai-agents/` and syncs it to the [selected project](/references/lightdash-cli#lightdash-config-set-project).
+
+## Downloading agents
+
+Use one of the two flags below to include agents in a download. Neither is set by default.
+
+Download every AI agent in the project (paginated automatically by the CLI):
+
+```bash
+lightdash download --include-agents
+```
+
+Download only specific agents by slug or UUID:
+
+```bash
+lightdash download --agents orders-support-agent revenue-analyst
+```
+
+You can combine agent flags with the usual `--charts`, `--dashboards`, `--project`, and `-p / --path` flags on [`lightdash download`](/references/lightdash-cli#lightdash-download).
+
+## Uploading agents
+
+`lightdash upload` uploads every agent file in `lightdash/ai-agents/` by default. Uploads are **idempotent**: the server creates missing agents, updates existing agents by slug, and leaves unchanged agents alone.
+
+Upload every agent along with charts and dashboards:
+
+```bash
+lightdash upload
+```
+
+Upload only specific agents by slug:
+
+```bash
+lightdash upload --agents orders-support-agent
+```
+
+Skip agent uploads entirely, even when files exist under `lightdash/ai-agents/`:
+
+```bash
+lightdash upload --skip-agents
+```
+
+
+Unlike charts and dashboards, you do **not** need `--force` to create a new agent. Uploading a file whose `slug` does not exist in the target project creates the agent; changing the `slug` in an existing file creates a new agent under the new slug (the old one is not deleted).
+
+
+### Exit codes and validation
+
+The CLI validates each agent file before uploading. Invalid YAML, missing required fields, wrong `contentType`, or duplicate slugs across files cause `lightdash upload` to exit with a non-zero status, which is what you want in CI so bad config fails the build.
+
+## YAML schema
+
+Every agent file uses the following top-level shape. The schema is versioned independently from the runtime engine — `version` describes the as-code file format, and `agentVersion` records which runtime version the agent uses.
+
+```yaml lightdash/ai-agents/orders-support-agent.yml
+contentType: ai_agent
+version: 1
+agentVersion: 2
+slug: orders-support-agent
+name: Orders Support Agent
+description: Answers questions about orders, fulfillment, and refunds.
+imageUrl: null
+instruction: |
+ You are a support analyst for the ecommerce team. Use the orders and
+ shipments explores to answer questions about order status, refunds, and
+ fulfillment SLAs. Always report totals in GBP.
+tags:
+ - ai
+ - orders
+enableDataAccess: true
+enableSelfImprovement: true
+enableContentTools: false
+enableUserContext: true
+modelConfig:
+ modelName: gpt-4o
+ modelProvider: openai
+ reasoning: false
+```
+
+### Field reference
+
+| Field | Type | Description |
+| --- | --- | --- |
+| `contentType` | string | Always `ai_agent`. The CLI refuses to upload files with any other value. |
+| `version` | number | Schema version of the file itself. Currently `1`. |
+| `agentVersion` | `1` \| `2` | Runtime version of the agent. Both v1 and v2 round-trip through download and upload. |
+| `slug` | string | Stable identifier used to match against agents in the target project. Changing the slug creates a new agent on upload. |
+| `name` | string | Human-readable name shown in the UI. |
+| `description` | string \| null | Short description. |
+| `imageUrl` | string \| null | URL for the agent's avatar. Uploaded-avatar provenance is preserved across environments. |
+| `instruction` | string \| null | The agent's system prompt / instructions. See [getting started](/guides/ai-agents/getting-started#instructions) for guidance on what to include. |
+| `tags` | string[] \| null | Semantic tags used for [data access control](/guides/ai-agents/data-access#limiting-access-to-specific-explores-and-fields). |
+| `enableDataAccess` | boolean | Whether the agent can execute queries and read actual data. See [data access](/guides/ai-agents/data-access). |
+| `enableSelfImprovement` | boolean | Whether the agent captures corrections into [agent memory](/guides/ai-agents/agent-memory). |
+| `enableContentTools` | boolean | Whether the agent can create and edit charts and dashboards. See [creating & editing content](/guides/ai-agents/content-tools). |
+| `enableUserContext` | boolean | Whether the agent receives the asking user's identity for [personalized answers](/guides/ai-agents/data-access#personalizing-answers-to-who-is-asking). |
+| `modelConfig` | object \| null | Default model settings: `modelName`, `modelProvider`, and optional `reasoning` flag. When `null`, the agent inherits the [organization default](/guides/ai-agents/getting-started#set-an-organization-default-ai-model). |
+
+## What is not versioned
+
+Some pieces of an agent are runtime state and are deliberately kept out of the YAML file — they stay in the target environment and are preserved across create/update/no-op uploads:
+
+- **Conversations and threads.** Chat history is runtime state and never written to YAML. Uploading a change to an agent does not touch existing threads.
+- **User and group access lists.** Access control is project-specific and stays managed in the target environment. See [user and group access](/guides/ai-agents/getting-started#user-and-group-access-optional).
+- **Slack integrations.** Slack channel bindings are per-environment and are not serialized.
+- **MCP server references.** [MCP server](/guides/ai-agents/mcp-servers) references stay in the target project.
+- **Uploaded knowledge documents.** Uploaded [documents](/guides/ai-agents/getting-started#knowledge-documents-optional) are preserved across upload but are not written into the YAML file itself.
+
+This split lets you promote agent behavior (instructions, tags, model config, capability flags) through Git while still letting each environment own the things that don't make sense to copy — production Slack channels, per-project MCP servers, per-environment access lists.
+
+## Lifecycle examples
+
+Assuming a file at `lightdash/ai-agents/orders-support-agent.yml`:
+
+- **Create.** The target project has no agent with slug `orders-support-agent`. `lightdash upload` creates it.
+- **Update.** The target project already has `orders-support-agent`. Editing `instruction` or `tags` in the file and running `lightdash upload` updates the existing agent in place.
+- **No-op.** Nothing has changed since the last upload. The CLI reports the agent as skipped and makes no API call.
+- **Rename by slug.** Changing `slug: orders-support-agent` to `slug: orders-support-agent-v2` and uploading creates a new agent under the new slug. The original agent is untouched.
+- **Per-project isolation.** Uploading with `--project ` only affects that project — the same slug in different projects refers to different agents.
+
+## API
+
+The CLI is a thin wrapper around two permission-gated project endpoints:
+
+- **`GET /api/v1/projects/{projectUuid}/aiAgents/code`** — paginated download of agents as code. Accepts repeated `ids` query params (slug or UUID) to filter, and an `offset` for pagination.
+- **`POST /api/v1/projects/{projectUuid}/aiAgents/code`** — idempotent create-or-update by slug for one or more agents. Accepts a `force` query flag. Returns a summary of `created`, `updated`, `unchanged`, and `deleted` slugs.
+
+Both endpoints require project-level permission to manage AI agents. See the [API reference](/api-reference/v1/introduction) for the full request and response schema.
+
+## CI/CD
+
+Because upload is idempotent and returns a non-zero exit code on invalid files, agents as code fits the same CI patterns as [Git-managed dashboards](/guides/developer/dashboards-as-code#git-managed-dashboards):
+
+1. Store `lightdash/ai-agents/` in Git.
+2. On PR, run `lightdash upload --skip-charts --skip-dashboards --agents ` against a [preview project](/guides/developer/preview-projects) to sanity-check the change.
+3. On merge to `main`, run `lightdash upload` against production.
+
+Lock down agent editing in the UI (via role permissions) if you want the YAML files to be the definitive source of truth for agent config.
diff --git a/guides/developer/dashboards-as-code.mdx b/guides/developer/dashboards-as-code.mdx
index bcc3c1b9..dc993f38 100644
--- a/guides/developer/dashboards-as-code.mdx
+++ b/guides/developer/dashboards-as-code.mdx
@@ -783,6 +783,12 @@ And the matching tile entry on a dashboard:
tileSlug: orders-by-status
```
+## AI agents as code
+
+AI agent configuration can also be managed as code and promoted between projects with the same `lightdash download` / `lightdash upload` workflow used for charts and dashboards. This is useful for keeping agent instructions and tags under review in Git, and for copying a working agent from a preview or staging project into production.
+
+Agent config as code is **opt-in**: a bare `lightdash download` does not include agents. See [AI agents as code](/guides/ai-agents/agents-as-code) for the full guide, including the YAML schema, CLI flags, and what runtime state stays in the target environment.
+
## Editing with AI agents
You can use AI coding assistants like Cursor, Claude Code, and Codex to create and edit charts using natural language instead of clicking through the UI.
diff --git a/references/lightdash-cli.mdx b/references/lightdash-cli.mdx
index 9bf6f1c2..c803355d 100644
--- a/references/lightdash-cli.mdx
+++ b/references/lightdash-cli.mdx
@@ -704,6 +704,11 @@ You can make changes to the code and upload these changes back to your Lightdash
- `--skip-dashboards`
- (default: false)
- skip downloading dashboards
+- `--agents `
+ - opt-in flag to also download specific AI agents as code. Pass one or more agent slugs or UUIDs. Files are written to `lightdash/ai-agents/.yml`. See [AI agents as code](/guides/ai-agents/agents-as-code) for the YAML schema and lifecycle rules.
+- `--include-agents`
+ - (default: false)
+ - opt-in flag to download every AI agent in the project as code. The endpoint is paginated, so the CLI walks all pages automatically. Agent files are written to `lightdash/ai-agents/`. Bare `lightdash download` does not include agents.
**Examples:**
@@ -769,6 +774,18 @@ Download just one data app and nothing else.
lightdash download --apps-only --apps 8f2b1c4d-1111-2222-3333-444455556666
```
+Download every AI agent in the project alongside charts and dashboards.
+
+```bash
+lightdash download --include-agents
+```
+
+Download only a specific AI agent by slug (or UUID).
+
+```bash
+lightdash download --agents orders-support-agent
+```
+
### `lightdash upload`
@@ -812,6 +829,11 @@ If there have been changes made to a chart or dashboard in the application that
- `--create-new`
- (default: false)
- always create a new data app from the uploaded source instead of appending a new version to the app referenced by `lightdash-app.yml`. Combine with `--apps` and `--project` when copying an app to a different project or instance in a non-interactive shell.
+- `--agents `
+ - upload only the AI agent files matching these slugs from `lightdash/ai-agents/`. Omit to upload every agent file in that folder. Upload is idempotent — the server creates missing agents, updates existing agents by slug, and leaves unchanged agents alone. See [AI agents as code](/guides/ai-agents/agents-as-code).
+- `--skip-agents`
+ - (default: false)
+ - skip uploading AI agents even when `lightdash/ai-agents/` contains files. Use this to keep an agents folder in your repo without pushing changes on every `lightdash upload`.
**Examples:**
@@ -877,6 +899,18 @@ Copy a data app to a different project as a brand-new app (non-interactive).
lightdash upload --apps --project 21eef0b9-5bae-40f3-851e-9554588e71a6 --create-new
```
+Upload every AI agent file under `lightdash/ai-agents/` (creates missing agents, updates existing ones by slug).
+
+```bash
+lightdash upload
+```
+
+Upload only a specific AI agent by slug.
+
+```bash
+lightdash upload --agents orders-support-agent
+```
+
### `lightdash rename`