> ## Documentation Index
> Fetch the complete documentation index at: https://agno-v2-docs-scavio-google-v2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Dash

> Self-learning data agent for teams that need grounded answers from company data, business rules, and proven query patterns.

**Dash is a self-learning data agent for teams that need grounded answers from company data, business rules, and proven query patterns.**

Data and analytics teams need answers that respect metric definitions, schema quirks, business rules, and queries that are known to work. Dash brings those inputs together as six layers of context and retains useful corrections through a learning loop.

Ask a question in English and Dash queries read-only company data, interprets the result, and explains it using your business context.

Chat with Dash in Slack, the terminal, or the [AgentOS UI](https://os.agno.com). The code is public at [agno-agi/dash](https://github.com/agno-agi/dash).

## How it works

Dash runs as an Agno team in coordinate mode, with a leader that routes each request to two specialists:

| Agent        | Role                                                              |
| ------------ | ----------------------------------------------------------------- |
| **Analyst**  | Reads company data (read-only), generates SQL, interprets results |
| **Engineer** | Builds reusable views and summary tables in the `dash` schema     |
| **Leader**   | Routes queries, coordinates the team, posts to Slack              |

**Schema boundaries:** Company data lives in the `public` schema; agent-created views and summary tables live in the `dash` schema. The Analyst connects with `default_transaction_read_only=on`, so PostgreSQL rejects any write it attempts. A SQLAlchemy event listener blocks Engineer writes that target `public`. These guardrails live in the infrastructure, so they hold regardless of what the model generates.

### Six layers of context

| Layer                       | Purpose                              | Source                      |
| --------------------------- | ------------------------------------ | --------------------------- |
| **Table Usage**             | Schema, columns, relationships       | `knowledge/tables/*.json`   |
| **Human Annotations**       | Metrics, definitions, business rules | `knowledge/business/*.json` |
| **Query Patterns**          | SQL that is known to work            | `knowledge/queries/*.sql`   |
| **Institutional Knowledge** | Docs, wikis, external references     | MCP (optional)              |
| **Learnings**               | Error patterns and discovered fixes  | Agno `Learning Machine`     |
| **Runtime Context**         | Live schema changes                  | `introspect_schema` tool    |

### Self-learning

Every query retrieves knowledge and learnings before generating SQL. When a query fails, Dash diagnoses the error, fixes it, and saves the fix as a learning. Two complementary systems make this work:

| System        | Stores                                           | How it evolves                                |
| ------------- | ------------------------------------------------ | --------------------------------------------- |
| **Knowledge** | Validated queries, table schemas, business rules | Curated by you and refined by Dash            |
| **Learnings** | Error patterns and discovered fixes              | Managed automatically by the Learning Machine |

When a churn query returns wrong numbers because it filtered on the `status` column instead of `ended_at IS NULL`, Dash saves the fix and doesn't make that mistake again. When your team defines MRR as the sum of active subscriptions excluding trials, that rule lives in `knowledge/business/` and every future query respects it.

### Insights you can act on

Dash reasons about what makes an answer useful. Ask "Which plan has the highest churn rate?" and you get the number, the comparison across plans, the trend behind it, and any caveats from your business rules.

## Run locally

```bash theme={null}
git clone https://github.com/agno-agi/dash.git && cd dash

cp example.env .env
# Edit .env and add your OPENAI_API_KEY

docker compose up -d --build

# Generate sample data and load knowledge
docker exec -it dash-api python scripts/generate_data.py
docker exec -it dash-api python scripts/load_knowledge.py
```

Confirm Dash is running at [http://localhost:8000/docs](http://localhost:8000/docs). The [Dash README](https://github.com/agno-agi/dash#quick-start) walks through this step by step.

### Connect to the AgentOS UI

1. Open [os.agno.com](https://os.agno.com) and log in.
2. Click **Connect OS**, choose **Local**, and enter `http://localhost:8000`.
3. Click **Connect**.

<Frame>
  <video autoPlay muted loop controls playsInline style={{ borderRadius: "0.5rem", width: "100%", height: "auto" }}>
    <source src="https://mintcdn.com/agno-v2-docs-scavio-google-v2/X5FlHx9mn-3MtKRB/videos/dash-ui-demo.mp4?fit=max&auto=format&n=X5FlHx9mn-3MtKRB&q=85&s=d72d418b0e6f8cada4015abe14fdcbfd" type="video/mp4" data-path="videos/dash-ui-demo.mp4" />
  </video>
</Frame>

<Check>Dash is running locally.</Check>

## Deploy to Railway

Railway deployment uses `.env.production` to keep production credentials separate from local dev.

```bash theme={null}
cp example.env .env.production
# Edit .env.production and set OPENAI_API_KEY
```

<Steps>
  <Step title="Deploy infrastructure">
    ```bash theme={null}
    railway login
    ./scripts/railway_up.sh
    ```

    This creates the Railway project, database, and app service. The app will crash-loop until the JWT key is added in the next step. That's expected.
  </Step>

  <Step title="Get your JWT key">
    Production requires a `JWT_VERIFICATION_KEY` from AgentOS. You need the Railway domain from step 1 to set this up.

    1. Copy your Railway domain from the output of step 1 (e.g. `dash-production-xxxx.up.railway.app`).
    2. Open [os.agno.com](https://os.agno.com) and log in.
    3. Click **Connect OS**, choose **Live**, and paste your Railway URL.
    4. Go to **Settings** → **OS & Security** and turn on **Token-Based Authorization (JWT)**. The UI generates a key pair and shows you the public key.
    5. Add the public key to `.env.production`, wrapped in single quotes:

    ```bash theme={null}
    JWT_VERIFICATION_KEY='-----BEGIN PUBLIC KEY-----
    MIIBIjANBgkq...
    -----END PUBLIC KEY-----'
    ```
  </Step>

  <Step title="Push environment and redeploy">
    ```bash theme={null}
    ./scripts/railway_env.sh
    ./scripts/railway_redeploy.sh
    ```

    `railway_env.sh` reads `.env.production` and sets each variable on the Railway service. It handles multiline values like PEM keys and is safe to run repeatedly.
  </Step>
</Steps>

<Check>Dash is live on Railway.</Check>

The [Dash README](https://github.com/agno-agi/dash#deploy-to-railway) covers this flow in more detail.

### Production operations

Database scripts must run inside Railway's network. The internal hostname `pgvector.railway.internal` is unreachable from your local machine, so SSH into the running container:

```bash theme={null}
railway ssh --service dash
# Inside the container:
python scripts/generate_data.py
python scripts/load_knowledge.py
```

Other operations run locally:

```bash theme={null}
railway logs --service dash
railway open
```

## Connect to Slack

Dash can receive DMs, @mentions, and thread replies, and can post to channels proactively. Each Slack thread maps to one Dash session.

1. Run Dash with a public URL (ngrok locally, or your Railway domain).
2. Create and install the Slack app from the manifest in `docs/SLACK_CONNECT.md`.
3. Set `SLACK_TOKEN` and `SLACK_SIGNING_SECRET`, then restart Dash.
4. In Slack, confirm Event Subscriptions shows verified, then send a DM or @mention to test.

See the [Slack setup guide](/agent-os/interfaces/slack/setup) for the manifest, ngrok commands, permissions, and troubleshooting.

## Example prompts

Try these on the sample SaaS metrics dataset:

* What's our current MRR?
* Which plan has the highest churn rate?
* Show me revenue trends by plan over the last 6 months
* Which customers are at risk of churning?

## Add your own data

Dash works best when it understands how your organization talks about data:

| Directory             | Content                                            |
| --------------------- | -------------------------------------------------- |
| `knowledge/tables/`   | Table meaning, column notes, data quality caveats  |
| `knowledge/queries/`  | Proven SQL patterns                                |
| `knowledge/business/` | Metric definitions, business rules, common gotchas |

Load or update knowledge at any time:

```bash theme={null}
python scripts/load_knowledge.py             # Upsert changes
python scripts/load_knowledge.py --recreate  # Fresh start
```

The [Dash README](https://github.com/agno-agi/dash#load-knowledge) covers loading your own data and scheduled proactive tasks.

## Run evals

Five eval categories using Agno's eval framework:

| Category       | Eval type                   | What it tests                              |
| -------------- | --------------------------- | ------------------------------------------ |
| **accuracy**   | `AccuracyEval` (1-10)       | Correct data and meaningful insights       |
| **routing**    | `ReliabilityEval`           | Team routes to the correct agent and tools |
| **security**   | `AgentAsJudgeEval` (binary) | No credential or secret leaks              |
| **governance** | `AgentAsJudgeEval` (binary) | Refuses destructive SQL operations         |
| **boundaries** | `AgentAsJudgeEval` (binary) | Schema access boundaries respected         |

```bash theme={null}
python -m evals                      # Run all evals
python -m evals --category accuracy  # Run specific category
python -m evals --verbose            # Show response details
```

## Source

Dash is public at [agno-agi/dash](https://github.com/agno-agi/dash). The README covers the full architecture, the data model, and the security setup.
