# Contributing (/contributing)

Cuelo is Apache 2.0 and built in the open at
[thoughtsinc/cues-harness](https://github.com/thoughtsinc/cues-harness).
Providers, turn-taking models, docs and bug reports are all welcome.

## Set up [#set-up]

You need Node 24.11+, pnpm 10, Python 3.12+ with [uv](https://docs.astral.sh/uv/), and Go.

```bash
git clone https://github.com/thoughtsinc/cues-harness && cd cues-harness
make setup          # install everything
make check          # lint, typecheck and test, the same as CI
source .bashrc      # optional: a dev shell with the locally built cuelo on PATH
```

`make` lists every target. The ones you'll use:

| Target        |                                                                                    |
| ------------- | ---------------------------------------------------------------------------------- |
| `make check`  | lint, typecheck, test. Run it before every PR.                                     |
| `make fmt`    | format everything                                                                  |
| `make schema` | copy `schema/` into the engine and CLI (after editing the schema or model catalog) |
| `make cuelo`  | build `bin/cuelo` with the dashboard embedded                                      |
| `make dist`   | build the wheel for this machine into `dist/`                                      |

## The repo [#the-repo]

| Path        | What                                                                     | Tooling                      |
| ----------- | ------------------------------------------------------------------------ | ---------------------------- |
| `engine/`   | Python runtime: providers, controllers, harness, server                  | Ruff, Pyright, pytest        |
| `cli/`      | Go `cuelo` CLI: config parsing, `cuelo generate`, templates              | gofmt, go vet, golangci-lint |
| `observer/` | The dashboard (Vite and React)                                           | Biome                        |
| `docs/`     | This site (Fumadocs)                                                     | Biome                        |
| `schema/`   | `config.cuelo.schema.json` and `models.json`, the shared source of truth | Prettier                     |
| `mcp/`      | MCP server for coding agents                                             | Go                           |
| `sdk/`      | Developer SDKs                                                           | Python                       |

Inside `engine/src/cuelo/`:

| Module                  |                                                                  |
| ----------------------- | ---------------------------------------------------------------- |
| `stt/`, `tts/`, `llms/` | providers, one file per vendor, each next to its `interface.py`  |
| `controllers/`          | turn-taking controllers and their model loading (`weights.py`)   |
| `policies/`             | turn-taking policy, the talker (LLM loop and tools), the thinker |
| `runtime/`              | harness, sessions, audio, events, tools, recordings              |
| `endpoint/`             | OpenAI Realtime, PCM WebSocket, dashboard API, auth              |
| `agents/`               | the default agent                                                |
| `config/`               | schema loading and the provider registry                         |
| `third_party/`          | vendored code (MaAI), with its license                           |

## Rules of the road [#rules-of-the-road]

- **The schema is shared.** Edit only `schema/config.cuelo.schema.json`, then
  run `make schema`. Tests fail if the copies in `engine/` and `cli/` drift.
- **Slot interfaces are public API.** Changing `STT`, `LLM`, `TTS`,
  `Controller` or `TurnTakingPolicy` needs a docs update and an issue first.
- **No credentials in `config.cuelo`.** They belong in `.env`. The schema
  enforces `${VAR}` where it can.
- **Formatters:** Biome for TS and JSON, Ruff for Python, gofmt for Go, Prettier
  for Markdown and YAML.
- **Tests for behavior changes.** Provider tests run against local fake
  servers. CI never calls real APIs.

## Pull requests [#pull-requests]

- One focused change per PR.
- Open an issue first for new features or anything that changes a public
  interface: the config schema, slot interfaces, CLI flags or the server API.
- Conventional Commit titles, scoped by component: `feat(engine): add Gladia STT`,
  `fix(cli): keep comments on voices use`.
- Update these docs when user-facing behavior changes.

## Guides [#guides]

<Cards>
<Card title="Add a provider" href="/contributing/providers">
STT, TTS or LLM: the class, the registry entry, tests and docs.
</Card>

<Card title="Add a turn-taking model" href="/contributing/controllers">
A controller, a catalog entry and verified weights.
</Card>

<Card title="Write docs" href="/contributing/docs">
Run this site locally and add a page.
</Card>
</Cards>