Skip to main content
You want CI to run each eval 5 times and local runs only once, without committing an API key to the repository. NiceEval splits values into two kinds, each in its own place:
  • Configuration goes in code: CLI flags, Experiment files under experiments/, and niceeval.config.ts at the root. Attempts, timeouts, concurrency, and which model the Judge uses all live here, and none of them have a matching environment variable.
  • Secrets go in environment variables: API keys and Provider tokens, plus settings that describe the current terminal, such as NO_COLOR.
So each value has exactly one source. What niceeval exp --dry prints is the value that really takes effect; no environment variable changes it behind your back. CLI and runtime text is in English; niceeval view in the browser can switch between Chinese and English.

Configuration: choose the layer by how long the value should live

First decide how widely the value should apply, then decide which layer to write it in. When the same value appears in several layers, it is taken in the order CLI flag → Experiment → eval → config → built-in default; once an earlier layer has a value, later ones are not consulted. The config only supplies defaults and never overrides other layers: a timeoutMs declared by an eval itself is not replaced by the project default. Different only this once: write it on the command.
Always this way for this experiment: write it in the Experiment file.
agent, model, and flags can only be written here; there is no matching CLI flag. To switch Agent or model, copy an Experiment file. That way, which Agent and model each run used is recorded in the results and can be reproduced later. Shared across the whole project: write it in niceeval.config.ts.

What niceeval.config.ts can hold

Each field’s type and full description are in the defineConfig reference. The full flag table is in the CLI reference.

Environment variables: only secrets and the terminal

Put secrets in the environment variables below. These are all the environment variables NiceEval reads; each Agent, Sandbox, and Judge only recognizes its own few names and never reads other keys. To have the Judge read its key from a different variable name, spell out the variable name in the config:
When the gateway address should not be committed to the repository either, read an environment variable yourself in the config. The config is code, and .env has already loaded by the time it is read:
The only difference: the variable name is decided by your project, not a name built into NiceEval that it guesses from the environment. For local development, put secrets in a .env file in the current directory. The CLI loads it automatically at startup without overriding environment variables that already exist, so you do not need to export every time:
.env is only for secrets; it is not a second configuration file. Writing variables like NICEEVAL_TIMEOUT into it has no effect. CI likewise passes only secrets:

Which layer to write in when tuning these values

Configuration has no environment variable layer, so each item below can only be written in these places: Each Judge Provider reads only its own default key variable, or the variable named explicitly by the factory’s apiKeyEnv. It never borrows keys from other Providers or from the application under test.

defineConfig reference

Type and full description of each configuration field.

CLI reference

Commands, full flag table, and exit codes.

Write experiments

Which values belong to one specific run.

CI integration

Pass secrets in CI.