# Configuration

ThinkThen reads flags, environment variables, question files and one configuration file. It never writes the configuration file.

## Which value wins

The typed value wins, then the environment, then the question file, then the configuration file, then the built-in default. A setting skips the tiers it has no home in.

The [Settings page](/install/settings/#which-value-wins) gives the order for each setting, and every default.

*config/thinkthen/config.json, a configuration file*

```
{
  "schema": "thinkthen.config/1",
  "backend": "liquid"
}
```

*The file names liquid. THINKTHEN_BACKEND outranks the file and names ollama.*

```
export XDG_CONFIG_HOME="$PWD/config"

thinkthen status --json |
jq .backend.name

export THINKTHEN_BACKEND=ollama
thinkthen status --json |
jq .backend.name
```

*Output*

```
"liquid"
"ollama"
```

*exit 0*

## The environment

| Variable | What it does |
| --- | --- |
| [`THINKTHEN_API_KEY`](/install/settings/#key) | The key when no backend is named. |
| [`THINKTHEN_BASE_URL`](/install/settings/#address) | The server address. --url outranks it. |
| [`THINKTHEN_BACKEND`](/install/settings/#backend) | A built-in backend, or an entry of the configuration file. --backend outranks it. |
| [`LIQUIDAI_API_KEY`](/install/settings/#backend-key), then [`LIQUID_API_KEY`](/install/settings/#backend-key) | The key of the liquid backend. |
| [`OLLAMA_API_KEY`](/install/settings/#backend-key) | The key of the ollama backend. |
| [`TYPESAFE_API_KEY`](/install/settings/#backend-key) | The key of the typesafe backend. |
| [`THINKTHEN_CACHE`](/install/settings/#answer-cache) | Another folder for the answer cache. It turns the cache on, and it never moves the usage totals. |
| [`THINKTHEN_BATCH`](/install/settings/#batch) | The most records one request carries. |
| [`THINKTHEN_CA_BUNDLE`](/install/settings/#private-tls-roots) | An absolute PEM file of certificates that replaces the built-in roots. |
| [`THINKTHEN_REQUESTS_PER_MINUTE`](/install/settings/#requests-a-minute) | The most requests one process starts each minute. It outranks the configuration file. |
| [`THINKTHEN_MAX_ESTIMATED_INPUT_TOKENS_TOTAL`](/install/settings/#estimated-input-admission-total) | The most estimated input tokens one process admits on the asking commands and on check. |
| [`THINKTHEN_MAX_REQUEST_BYTES`](/install/settings/#request-size) | The most bytes one batched request holds. |
| [`XDG_CONFIG_HOME`](#locations) | The folder above the configuration file, on Linux. It counts only when absolute. |
| [`XDG_CACHE_HOME`](#locations) | The folder above the answer cache, on Linux. It counts only when absolute. |
| [`XDG_STATE_HOME`](#locations) | The folder above the usage totals, on Linux. It counts only when absolute. |
| [`HOME`](#locations) | The folder every location falls back to. It counts only when absolute. |
| `ALL_PROXY`, `HTTPS_PROXY`, `HTTP_PROXY`, `NO_PROXY` | Read in upper and lower case. A proxy carries https requests. Under http every proxy is ignored. |

A blank variable counts as unset. `SSL_CERT_FILE` is not read.

## Where the files live

| File | System | Path |
| --- | --- | --- |
| Configuration file | Linux | `$XDG_CONFIG_HOME/thinkthen/config.json`, else `$HOME/.config/thinkthen/config.json` |
| Configuration file | macOS | `$HOME/Library/Application Support/thinkthen/config.json` |
| Answer cache | Linux | `$XDG_CACHE_HOME/thinkthen`, else `$HOME/.cache/thinkthen` |
| Answer cache | macOS | `$HOME/Library/Caches/thinkthen` |
| Usage totals | Linux | `$XDG_STATE_HOME/thinkthen`, else `$HOME/.local/state/thinkthen` |
| Usage totals | macOS | `$HOME/Library/Application Support/thinkthen/usage` |

ThinkThen has no home-folder variable of its own. `HOME` and the three XDG variables decide every location.

*With no XDG variable, all three paths sit under HOME.*

```
export HOME=/home/reader
unset XDG_CONFIG_HOME XDG_CACHE_HOME XDG_STATE_HOME

thinkthen status --json |
jq '{configuration: .configuration.path,
  cache: .cache.path,
  usage: .usage.path}'
```

*Output*

```
{
  "configuration": "/home/reader/.config/thinkthen/config.json",
  "cache": "/home/reader/.cache/thinkthen",
  "usage": "/home/reader/.local/state/thinkthen"
}
```

*exit 0*

On Linux, set `XDG_CONFIG_HOME`, `XDG_CACHE_HOME` or `XDG_STATE_HOME` to move the files. Each counts only when it is an absolute path. A relative path is ignored, and the location falls back to `HOME`. macOS ignores the XDG variables.

*Absolute XDG variables move the configuration file, the cache, and the usage totals.*

```
export HOME=/home/reader
export XDG_CONFIG_HOME=/home/reader/settings
export XDG_CACHE_HOME=/home/reader/scratch
export XDG_STATE_HOME=/home/reader/state

thinkthen status --json |
jq '{configuration: .configuration.path,
  cache: .cache.path,
  usage: .usage.path}'
```

*Output*

```
{
  "configuration": "/home/reader/settings/thinkthen/config.json",
  "cache": "/home/reader/scratch/thinkthen",
  "usage": "/home/reader/state/thinkthen"
}
```

*exit 0*

*A relative XDG_CONFIG_HOME does not count. The path falls back to HOME.*

```
export HOME=/home/reader
export XDG_CONFIG_HOME=settings

thinkthen status --json |
jq .configuration.path
```

*Output*

```
"/home/reader/.config/thinkthen/config.json"
```

*exit 0*

`THINKTHEN_CACHE` moves only the answer cache. The usage totals stay in the state folder.

## The configuration file

The file is optional. It holds one JSON object with `"schema": "thinkthen.config/1"`. ThinkThen never creates it and never edits it.

- `url` and `model` name the default address and model.
- `backend` names the default backend, and `backends` adds named servers or paces the built-ins. The [System One page](/install/backends/system-one/) shows an entry.
- `cache` turns the answer cache on or off. `cache_bytes` sets the size [`cache prune`](/install/settings/#prune-target) trims to.
- `usd_per_million_input` and `usd_per_million_output` together price the reported tokens. The price is your own estimate, never a bill.

Any other field is refused. The file never holds a key. `key_env` in a `backends` entry names the variable that holds one.

Whoever can write the file decides where the key and the evidence go. On Linux and macOS ThinkThen warns when another user owns the file, or when every user may write it. A group-write bit alone draws no warning. A file that draws the warning and holds `backends` is refused with exit 5. Keep the file writable by its owner alone.

## The usage totals

The usage folder holds one file for each UTC month. It counts requests sent, retries, input tokens, output tokens and answers from the answer cache. An answer from a replay or record folder never counts as a cache answer. It holds no request, no reply, no address, no model, no price and no key. Clearing the cache never resets it, and `--no-cache` never turns it off. It counts what this machine saw, and the backend's bill is the real cost.

## See it all

`thinkthen status` prints the resolved configuration path, backend, address, model and key variable, and where each value came from. It also prints whether a key is set, the cache path and size, the usage path, and the usage this month and in all. It opens no connection. `status --json` prints the same facts as one `thinkthen.status/2` object. The [recording specification](https://github.com/botassembly/thinkthen/blob/main/specification/recording.md#the-options) lists its fields.

[Every setting and its default](/install/settings/) · [Backends](/install/backends/) · [Reference](/reference/)

On GitHub: [github.com/botassembly/thinkthen](https://github.com/botassembly/thinkthen)
