|
4 | 4 |
|
5 | 5 | A powerful command-line interface for querying and analyzing Langfuse LLM observability data. Built with Ruby and designed for developers who prefer working in the terminal. |
6 | 6 |
|
7 | | -[](https://badge.fury.io/rb/lf-cli) |
| 7 | +[](https://rubygems.org/gems/lf-cli) |
| 8 | +[](https://rubygems.org/gems/lf-cli) |
8 | 9 | [](https://opensource.org/licenses/MIT) |
9 | 10 |
|
10 | 11 | ## Disclaimer |
@@ -294,6 +295,192 @@ Configuration is loaded in this order (highest to lowest priority): |
294 | 295 | 3. Config file (`~/.langfuse/config.yml`) |
295 | 296 | 4. Defaults |
296 | 297 |
|
| 298 | +## LLM Reference (llms-full) |
| 299 | + |
| 300 | +This section mirrors the depth of a `llms-full.txt` so AI assistants can answer detailed questions about `lf-cli` without inspecting the source. |
| 301 | + |
| 302 | +### CLI Metadata |
| 303 | + |
| 304 | +| Item | Details | |
| 305 | +| --- | --- | |
| 306 | +| Binary names | `lf` (preferred), `langfuse` (legacy alias used in docs) | |
| 307 | +| Entry point | `bin/lf` → `Langfuse::CLI::Main.start(ARGV)` | |
| 308 | +| Ruby compatibility | Ruby >= 2.7.0 (same as gemspec requirement) | |
| 309 | +| Default API host | `https://cloud.langfuse.com` | |
| 310 | +| Config path | `~/.langfuse/config.yml` (`0600` permissions) | |
| 311 | +| Source namespace | `Langfuse::CLI` with command classes under `lib/langfuse/cli/commands` | |
| 312 | +| HTTP stack | Faraday + JSON middleware, 2s open/read timeouts, retry with exponential backoff on `429/5xx` | |
| 313 | +| Logging | Set `DEBUG=1` to enable Faraday request/response logging | |
| 314 | + |
| 315 | +### Authentication & Configuration |
| 316 | + |
| 317 | +1. Credentials (`public_key`, `secret_key`) plus `host` are mandatory for all API calls. |
| 318 | +2. Resolution order: CLI flags → environment variables → profile in `~/.langfuse/config.yml` → defaults. |
| 319 | +3. Profiles let you store multiple environments (e.g., `default`, `staging`, `production`) inside the same YAML file. |
| 320 | +4. The `config setup` command validates keys before saving by hitting `/api/public/traces` with `limit=1`. |
| 321 | + |
| 322 | +**Environment variable matrix** |
| 323 | + |
| 324 | +| Variable | Purpose | Required | Notes | |
| 325 | +| --- | --- | --- | --- | |
| 326 | +| `LANGFUSE_PUBLIC_KEY` | Public API key | ✅ | Required for non-interactive `config setup` and all other commands if no profile is configured. | |
| 327 | +| `LANGFUSE_SECRET_KEY` | Secret API key | ✅ | Same priority rules as the public key. | |
| 328 | +| `LANGFUSE_HOST` | Override API base URL | Optional | Use for self-hosted Langfuse instances. | |
| 329 | +| `LANGFUSE_PROFILE` | Profile name | Optional | Overrides the profile selected via `-P/--profile`. | |
| 330 | +| `LANGFUSE_PROJECT_NAME` | Used by `config setup` to show the correct settings URL. | Optional | Only needed for UX hints. | |
| 331 | +| `DEBUG` | When set to `1`, logs Faraday requests/responses to stdout. | Optional | Useful for diagnosing API issues. | |
| 332 | + |
| 333 | +### Global Flags & Behavior |
| 334 | + |
| 335 | +| Flag | Description | Notes | |
| 336 | +| --- | --- | --- | |
| 337 | +| `-P, --profile PROFILE` | Selects a saved profile. | Defaults to `default`. | |
| 338 | +| `--public-key KEY` / `--secret-key KEY` | Inject credentials without touching config files. | Highest priority source. | |
| 339 | +| `--host URL` | Override Langfuse host. | Combine with `--profile` to temporarily test another region. | |
| 340 | +| `-f, --format FORMAT` | `table` (default), `json`, `csv`, `markdown`. | Applies to every command; CSV/Markdown require structured arrays. | |
| 341 | +| `-o, --output PATH` | Write output to a file. | Respects format; prints “Output written…” when `--verbose`. | |
| 342 | +| `-l, --limit N` | Caps number of records pulled per command. | Pagination helper, defaults to API `limit` (50) when omitted. | |
| 343 | +| `-p, --page N` | Start from an explicit page. | Useful when you know an offset. | |
| 344 | +| `--from`, `--to` | ISO 8601 or natural language timestamps. | Natural language parsing uses `chronic` if installed; otherwise the string is sent as-is. | |
| 345 | +| `-v, --verbose` | Prints extra logs (e.g., file paths). | Some commands emit status lines prefixed with emojis. | |
| 346 | +| `--no-color` | Forces monochrome table output. | Forwarded to formatters that support color. | |
| 347 | + |
| 348 | +Pagination strategy: the client keeps fetching pages until it collects the requested `limit` or no more pages remain. `limit` therefore caps the total combined size, not per-page size. |
| 349 | + |
| 350 | +### Output & Files |
| 351 | + |
| 352 | +- `table` renders ASCII tables via `Formatters::TableFormatter`. |
| 353 | +- `json` streams `JSON.pretty_generate` for direct piping to `jq`. |
| 354 | +- `csv` and `markdown` use dedicated formatters and require array-like data (single hashes are wrapped automatically). |
| 355 | +- `--output` writes the formatted string verbatim; combine with `--format json` for scripts. |
| 356 | +- Use `lf ... --format json | jq ...` for automation recipes. |
| 357 | + |
| 358 | +### Command Reference |
| 359 | + |
| 360 | +Each command inherits the global flags above. API errors exit with status code `1`. |
| 361 | + |
| 362 | +#### `config` (profile management) |
| 363 | + |
| 364 | +| Subcommand | Synopsis | Notes | |
| 365 | +| --- | --- | --- | |
| 366 | +| `lf config setup` | Interactive wizard; supports env-variable non-interactive mode. | Tests credentials before saving. | |
| 367 | +| `lf config set PROFILE --public-key ... --secret-key ... [--host ...]` | Writes/updates a profile directly. | Does not hit the API. | |
| 368 | +| `lf config show [PROFILE]` | Prints the resolved profile (keys masked). | Reads from YAML + ENV. | |
| 369 | +| `lf config list` | Shows every profile name plus masked public key/host. | Warns if file missing. | |
| 370 | + |
| 371 | +#### `traces` |
| 372 | + |
| 373 | +| Subcommand | Purpose | |
| 374 | +| --- | --- | |
| 375 | +| `lf traces list` | Lists traces with filters/pagination. | |
| 376 | +| `lf traces get TRACE_ID [--with-observations]` | Fetches a single trace. The `--with-observations` flag is accepted for forward compatibility but currently behaves the same as the default API payload. | |
| 377 | + |
| 378 | +`traces list` options: |
| 379 | + |
| 380 | +| Flag | Type | Description | |
| 381 | +| --- | --- | --- | |
| 382 | +| `--name NAME` | String | Filter by trace name. | |
| 383 | +| `--user-id USER_ID` | String | Filter by Langfuse user identifier. | |
| 384 | +| `--session-id SESSION_ID` | String | Filter by session. | |
| 385 | +| `--tags TAG1 TAG2` | Array | Matches traces containing all provided tags. | |
| 386 | +| `--from`, `--to` | String | Time boundaries; accepts ISO 8601 or relative strings. | |
| 387 | +| `--limit`, `--page` | Numeric | Override pagination per request. | |
| 388 | + |
| 389 | +Sample workflow: |
| 390 | + |
| 391 | +```bash |
| 392 | +latest_trace_id=$(lf traces list --format json --limit 1 | jq -r '.[0].id') |
| 393 | +lf traces get "$latest_trace_id" --format json > trace.json |
| 394 | +``` |
| 395 | + |
| 396 | +#### `sessions` |
| 397 | + |
| 398 | +| Subcommand | Purpose | |
| 399 | +| --- | --- | |
| 400 | +| `lf sessions list` | Enumerates sessions. | |
| 401 | +| `lf sessions show SESSION_ID [--with-traces]` | Shows a session and optionally its traces (flag reserved for future enrichments). | |
| 402 | + |
| 403 | +Options mirror trace pagination: `--from`, `--to`, `--limit`, `--page`. |
| 404 | + |
| 405 | +#### `observations` |
| 406 | + |
| 407 | +| Subcommand | Purpose | |
| 408 | +| --- | --- | |
| 409 | +| `lf observations list` | Lists generations, spans, or events. | |
| 410 | +| `lf observations get OBSERVATION_ID` | Fetches a single observation. | |
| 411 | + |
| 412 | +`list` filters: |
| 413 | + |
| 414 | +| Flag | Values | Description | |
| 415 | +| --- | --- | --- | |
| 416 | +| `--type` | `generation`, `span`, `event` | Restrict to an observation type. | |
| 417 | +| `--trace-id` | Trace ID | Only observations under a specific trace. | |
| 418 | +| `--name` | String | Filter by observation name. | |
| 419 | +| `--user-id` | String | Filter by associated user. | |
| 420 | +| `--from`, `--to`, `--limit`, `--page` | As described earlier. | |
| 421 | + |
| 422 | +#### `scores` |
| 423 | + |
| 424 | +| Subcommand | Purpose | |
| 425 | +| --- | --- | |
| 426 | +| `lf scores list` | Lists evaluation scores. | |
| 427 | +| `lf scores get SCORE_ID` | Fetches a single score document. | |
| 428 | + |
| 429 | +Filters: `--name`, `--from`, `--to`, `--limit`, `--page`. |
| 430 | + |
| 431 | +#### `metrics` |
| 432 | + |
| 433 | +Single subcommand: `lf metrics query`. |
| 434 | + |
| 435 | +Required flags: |
| 436 | + |
| 437 | +| Flag | Allowed values | Description | |
| 438 | +| --- | --- | --- | |
| 439 | +| `--view` | `traces`, `observations`, `scores-numeric`, `scores-categorical` | Which metrics view to query. | |
| 440 | +| `--measure` | `count`, `latency`, `value`, `tokens`, `cost` | Base metric. | |
| 441 | +| `--aggregation` | `count`, `sum`, `avg`, `p50`, `p95`, `p99`, `min`, `max`, `histogram` | Aggregation function. | |
| 442 | + |
| 443 | +Optional flags: |
| 444 | + |
| 445 | +| Flag | Description | |
| 446 | +| --- | --- | |
| 447 | +| `--dimensions field1 field2` | Array of dimension field names (e.g., `name`, `userId`, `sessionId`, `model`). | |
| 448 | +| `--from`, `--to` | Time range. | |
| 449 | +| `--granularity` | `minute`, `hour`, `day`, `week`, `month`, `auto`. Controls the time bucket. | |
| 450 | +| `--limit` | Defaults to `100` for metrics; caps the number of buckets/rows returned. | |
| 451 | + |
| 452 | +The CLI builds a payload matching the Langfuse metrics API (`metrics` array, `timeDimension` etc.) via `Langfuse::CLI::Types::MetricsQuery`. |
| 453 | + |
| 454 | +### Data Model Cheat Sheet |
| 455 | + |
| 456 | +- **Trace**: `id`, `name`, `userId`, `sessionId`, `timestamp`, `durationMs`, `tags[]`, `metadata` (object), `observations[]` (optional when using `get`), `scores[]`. |
| 457 | +- **Session**: `id`, `userId`, `name`, `createdAt`, `updatedAt`, `traceIds[]`, `metadata`. |
| 458 | +- **Observation**: `id`, `traceId`, `type` (`generation/span/event`), `name`, `status`, `model`, `input`, `output`, `metrics` (latency, usage), `level`, `parentObservationId`. |
| 459 | +- **Score**: `id`, `name`, `value` (number/string), `type` (`numeric`/`categorical`), `traceId`, `observationId`, `timestamp`, `metadata`, `comment`. |
| 460 | +- **Metrics response**: Usually `{ "data": [ { "dimensions": {...}, "metrics": {...} } ], "meta": {...} }`. The CLI automatically unwraps `data` before formatting. |
| 461 | + |
| 462 | +Fields are passed through verbatim from the Langfuse Public API; the CLI never renames keys. |
| 463 | + |
| 464 | +### Error Handling & Exit Codes |
| 465 | + |
| 466 | +- Success exits with code `0`. |
| 467 | +- Any `Langfuse::CLI::Client::*Error` results in exit code `1` after printing a human-readable message. |
| 468 | +- Specific messages: |
| 469 | + - `Authentication Error` for `401`. |
| 470 | + - `Rate limit exceeded` for `429`. |
| 471 | + - `Trace/session/... not found` for `404`. |
| 472 | + - `Request timed out` when Faraday raises a timeout (usually after 2s). |
| 473 | +- Use `--verbose` or `DEBUG=1` for deeper context (e.g., stack traces, Faraday logs). |
| 474 | + |
| 475 | +### Troubleshooting & Automation Tips |
| 476 | + |
| 477 | +- **Network issues**: verify `LANGFUSE_HOST` by running `lf config show` and hitting `/health` with `curl`. |
| 478 | +- **Time parsing**: install the `chronic` gem to enable natural language ranges; otherwise pass ISO 8601 timestamps. |
| 479 | +- **CSV exports**: always provide `--output file.csv` to avoid large terminal dumps. |
| 480 | +- **Scripting**: prefer `--format json` to keep machine-readable structures. Most commands return arrays, so piping to `jq '.[].id'` works consistently. |
| 481 | +- **Profiles**: store CI credentials under `LANGFUSE_PROFILE=ci` and load them via `lf ... -P ci` to keep human/dev credentials untouched. |
| 482 | +- **Retries**: built-in Faraday retry middleware already backs off (`max: 3`). For long-running scripts, wrap commands with shell retries instead of adding loops inside the CLI. |
| 483 | + |
297 | 484 | ## Development |
298 | 485 |
|
299 | 486 | ### Setup |
|
0 commit comments