> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirage.strukto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Weights & Biases

> Read experiment runs, configuration, summaries, history, and run files.

```typescript theme={null}
import { Workspace, MountMode, WandbResource, normalizeWandbConfig } from '@struktoai/mirage-node'

const ws = new Workspace({
  '/wandb': new WandbResource(normalizeWandbConfig({
    entities: ['my-team'],
    api_key: process.env.WANDB_API_KEY,
  })),
}, { mode: MountMode.READ })
```

The resource also ships in `@struktoai/mirage-browser`; its implementation uses
standard `fetch`. Browser access depends on the service's CORS configuration.

The mount exposes `/<entity>/<project>/<run-id>/` with `run.json`,
`config.json`, `summary.json`, `history.jsonl`, and `files/`.
Configure one or more entities explicitly; project and run listings are fetched
on demand and follow service pagination. Run IDs identify directories; duplicate
display names remain separate runs.

`run.json` contains the run metadata exposed by the supported W\&B API fields:

| Fields                                             | Contents                                                                       |
| -------------------------------------------------- | ------------------------------------------------------------------------------ |
| `entity`, `project`, `run`, `path`                 | Run identity and its `entity/project/run-id` path                              |
| `storage_id`, `display_name`, `state`              | W\&B's opaque storage ID, display name, and reported state                     |
| `tags`, `sweep_name`, `group`, `job_type`          | Experiment organization                                                        |
| `commit`, `created_at`, `heartbeat_at`             | Source revision, creation time, and last heartbeat                             |
| `description`, `notes`, `user`                     | Run description, notes, and creator's `id`/`name`/`username`/`email`           |
| `read_only`                                        | W\&B's reported edit permission; the Mirage mount remains read-only            |
| `system_metrics`                                   | Latest system metrics decoded as JSON, retaining nested values                 |
| `history_line_count`, `history_keys`, `file_count` | History row count, metric-key metadata including the last step, and file count |

For example, the synthetic integration fixture renders this complete `run.json`:

```json theme={null}
{
  "entity": "lab",
  "project": "experiments",
  "run": "run-a",
  "path": "lab/experiments/run-a",
  "storage_id": "synthetic-storage-id-a",
  "display_name": "duplicate",
  "state": "finished",
  "tags": [
    "baseline",
    "café"
  ],
  "sweep_name": "sweep-01",
  "group": "ablation",
  "job_type": "train",
  "commit": "0123456789abcdef0123456789abcdef01234567",
  "read_only": false,
  "created_at": "2026-01-01T00:00:00Z",
  "heartbeat_at": "2026-01-01T00:05:00Z",
  "description": "Synthetic experiment metadata",
  "notes": "First line\nSecond line: café",
  "user": {
    "id": "synthetic-user-id-bob",
    "name": "Bob Example",
    "username": "bob",
    "email": "bob@example.com"
  },
  "system_metrics": {
    "cpu": 0,
    "gpu.0.memoryAllocated": 128.5,
    "nested": {
      "missing": null
    }
  },
  "history_line_count": 4,
  "history_keys": {
    "lastStep": 5,
    "keys": {
      "score": {
        "type": "number",
        "count": 3
      },
      "train_step": {
        "type": "number",
        "count": 4
      }
    }
  },
  "file_count": 4
}
```

Unavailable metadata is `null`; empty tags, zero counts, false permissions, and
original timestamp strings are preserved. These fields are fetched only when
reading `run.json`, in one run query. Listing and stat do not fetch them.
The `user` is the run's creator, not the identity associated with the API key.
When the creator exists, `user` has `id`, `name`, `username`, and `email`;
W\&B requires the creator's ID and name, while username/email may be null.
A missing creator is `user: null`.
Reading these fields does not query the authenticated viewer or discover teams.
Machine/runtime details are available at `files/wandb-metadata.json` when uploaded;
reading `run.json` does not download that file.

`config.json` unwraps W\&B's configuration `value` envelopes. `summary.json`
contains the stored summary, which may differ from the best value in history.
These documents have run-defined keys rather than a fixed Mirage field list.
Nested objects, arrays, metric names containing `/` or `.`, and null values remain
intact. For this fixture, they are `{"lr": 0.01, "label": "café"}` and `{"score": 0.4}`.
`history.jsonl` scans full history in `_step` windows using the public SDK's
unsampled scan protocol. It retains row order, missing keys, nulls, and logged
training-step fields. `_step` and a training-step metric are separate values.
An empty window does not end a scan. The last step is captured when a read begins;
rows appended later are visible on a subsequent read.
One-step query windows are widened to two steps to avoid a live API edge case;
results are filtered to the original range without duplicates or later rows.

Run files retain their relative paths and are downloaded as raw bytes. Listing
and stat do not download histories or files. Rendered JSON and history have
unknown sizes; raw file sizes come from W\&B's file metadata.

Directory metadata uses Mirage's index cache (600 seconds by default). A project
listing also establishes its runs' existence; a file catalog populates all nested
directories, so traversing them reuses the same metadata. Config, summary, and
history reads request their own fields. Downloads resolve the exact filename for
a fresh URL on each read. File content and download URLs are not cached in the index.

Reads and downloads stream, so `head` can stop before fetching the entire history.
`page_size` defaults to 100 (maximum 1000); `max_pages` defaults to 10000.
Exhausting a page budget raises an error instead of returning a complete-looking
partial result. Recursive `du` is capped at 1000 entries; glob expansion uses
Mirage's standard traversal limit. API keys use host configuration and are
redacted from resource state. No write operations or W\&B CLI are registered.
