okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
61c43ca
main
cache TTL table
The prompt-cache TTL table is the prior the cache-warmth estimate starts from: how long each provider keeps a cached prefix, what a write costs, and whether a hit restarts the clock. It answers lookup(extension, host, model) in src/albedo/harness/cache_ttl.gleam until a session's provider requests have measured the real thing (robot-docs/provider-requests.md); after that the measurements win.
The table is data, not code: priv/cache-ttl.json ships with the daemon, and nothing about a provider is hardcoded anywhere else.
format
A file is {"version": 1, "entries": [...]}. One entry:
id— unique within a layer. Layers replace entries by it.match— which requests the entry describes:extension(albedo's extension name: claude, codex, openai, antigravity, alibaba, ...),host(endpoint host),model(model id). Each is one string or a list; each string is a glob where only*is special: it matches any run of Unicode graphemes, case-insensitively. Matching has bounded polynomial work even for repeated wildcards. An absent field matches anything; a list matches if any element does.policy—refresh(every hit restarts the lifetime),fixed(lifetime runs from the write),evict(no clock, best-effort, only survival windows are known), orunknown.clock—requestorresponse(defaultresponse): whether a lifetime counts from request start or response end. Anthropic counts from request start, so streaming time uses the cache up.tiers— the TTLs a request can ask for, each{seconds, write}with the write-price multiplier.read— the read-price multiplier, when the provider charges for hits.survival—{typical, max?}seconds, forevictandunknownentries.evidence—documented,measured,implemented,folklore, orunknown.source(url),checked(date),note(text).
Unknown fields are ignored, so a newer file stays readable. An entry without a string id, or with an invalid policy, evidence, or other field, is skipped with a logged reason. An absent match matches anything. Repeated string ids within one layer reject that layer, even when one of the entries would fail semantic decoding; the layer keeps its last good entries. The same id in different layers is a valid override.
Values marked folklore or unknown are placeholders. Session request measurements supersede these estimates when available.
layers
Three layers merge by id:
default— the shippedpriv/cache-ttl.json.remote— a copy fetched by default from this repo'spriv/cache-ttl.jsononmain, cached at$ALBEDO_HOME/cache-ttl-remote.json. In$ALBEDO_HOME/extensions.json, setcacheTtl.urlto another JSON file to override it, ornullto disable remote fetching.refreshHoursdefaults to 24;0disables the background refresh (but not explicit/reload). Onlyhttps, orhttpon the loopback host, is fetched, the response is capped at 1 MiB, and the write is a rename — a failed fetch keeps the previous copy.local—$ALBEDO_HOME/cache-ttl.json, for hand edits.
A later layer replaces an entry with the same id in place, and puts entries with new ids before all earlier-layer entries, so a local override can shadow a general default while the shipped specific-to-general order survives underneath. Merging lives in src/albedo/harness/cache_ttl.gleam; file reads, fetching, and revision caching stay in albedo_cache_ttl.erl. Entries are merged before full decoding, so an invalid same-id override shadows the earlier entry and is then skipped. Within the merged table, first match wins a lookup: the files list specific entries before general ones, and that order is the precedence.
reload
Each layer file is parsed once per revision (size + mtime), including malformed JSON, invalid table shapes, and duplicate-id failures. The merged decoded Gleam table is cached; a changed file is picked up on the next lookup without a restart. A malformed layer file keeps that layer's last good entries and reports the reason in GET /models?view=cache-policy; fixing the file at a new revision is live again. Transient file-read errors are retried on the next read and retain last good entries. HTTP responses encode the cached table only when serving it.
The remote copy refreshes in the background when it is stale, the same cadence as the models catalog. /reload (no target) re-fetches it immediately, alongside the models catalog: the command returns after the copy is atomically replaced, or with the fetch failure. A fetched layer with duplicate ids is rejected before replacing the file. A confirmed replacement invalidates the parsed layer and merged table even when size and timestamp stay unchanged.
HTTP API
GET /models?view=cache-policy is read-only and requires the daemon bearer token:
- no parameters —
{"entries": [...], "layers": [{"name": "default"|"remote"|"local", "path", "loaded", "error"?}]}, each entry carrying the layer it came from and every field above it decoded. &extension=&host=&model=returnsmatched, the resolved entry ornull, using the same lookup.
layers is the state of each file: loaded false with an error means that layer's last good entries are still merged in (or it was never readable). An absent local override or unconfigured remote url is simply not loaded, with no error.
1# cache TTL table 2 3The prompt-cache TTL table is the prior the cache-warmth estimate starts from: how long each provider keeps a cached prefix, what a write costs, and whether a hit restarts the clock. It answers `lookup(extension, host, model)` in `src/albedo/harness/cache_ttl.gleam` until a session's provider requests have measured the real thing (robot-docs/provider-requests.md); after that the measurements win. 4 5The table is data, not code: `priv/cache-ttl.json` ships with the daemon, and nothing about a provider is hardcoded anywhere else. 6 7## format 8 9A file is `{"version": 1, "entries": [...]}`. One entry: 10 11- `id` — unique within a layer. Layers replace entries by it. 12- `match` — which requests the entry describes: `extension` (albedo's extension name: claude, codex, openai, antigravity, alibaba, ...), `host` (endpoint host), `model` (model id). Each is one string or a list; each string is a glob where only `*` is special: it matches any run of Unicode graphemes, case-insensitively. Matching has bounded polynomial work even for repeated wildcards. An absent field matches anything; a list matches if any element does. 13- `policy` — `refresh` (every hit restarts the lifetime), `fixed` (lifetime runs from the write), `evict` (no clock, best-effort, only survival windows are known), or `unknown`. 14- `clock` — `request` or `response` (default `response`): whether a lifetime counts from request start or response end. Anthropic counts from request start, so streaming time uses the cache up. 15- `tiers` — the TTLs a request can ask for, each `{seconds, write}` with the write-price multiplier. 16- `read` — the read-price multiplier, when the provider charges for hits. 17- `survival` — `{typical, max?}` seconds, for `evict` and `unknown` entries. 18- `evidence` — `documented`, `measured`, `implemented`, `folklore`, or `unknown`. 19- `source` (url), `checked` (date), `note` (text). 20 21Unknown fields are ignored, so a newer file stays readable. An entry without a string `id`, or with an invalid `policy`, `evidence`, or other field, is skipped with a logged reason. An absent `match` matches anything. Repeated string ids within one layer reject that layer, even when one of the entries would fail semantic decoding; the layer keeps its last good entries. The same id in different layers is a valid override. 22 23**Values marked `folklore` or `unknown` are placeholders.** Session request measurements supersede these estimates when available. 24 25## layers 26 27Three layers merge by id: 28 291. `default` — the shipped `priv/cache-ttl.json`. 302. `remote` — a copy fetched by default from [this repo's `priv/cache-ttl.json` on `main`](https://api.next.tangled.org/xrpc/org.tangled.temp.git.getBlob?repo=did%3Aplc%3Al7hhzcbqqvpcquau5waryzdu&ref=main&path=priv%2Fcache-ttl.json), cached at `$ALBEDO_HOME/cache-ttl-remote.json`. In `$ALBEDO_HOME/extensions.json`, set `cacheTtl.url` to another JSON file to override it, or `null` to disable remote fetching. `refreshHours` defaults to 24; `0` disables the background refresh (but not explicit `/reload`). Only `https`, or `http` on the loopback host, is fetched, the response is capped at 1 MiB, and the write is a rename — a failed fetch keeps the previous copy. 313. `local` — `$ALBEDO_HOME/cache-ttl.json`, for hand edits. 32 33A later layer replaces an entry with the same id in place, and puts entries with new ids **before** all earlier-layer entries, so a local override can shadow a general default while the shipped specific-to-general order survives underneath. Merging lives in `src/albedo/harness/cache_ttl.gleam`; file reads, fetching, and revision caching stay in `albedo_cache_ttl.erl`. Entries are merged before full decoding, so an invalid same-id override shadows the earlier entry and is then skipped. Within the merged table, **first match wins** a lookup: the files list specific entries before general ones, and that order is the precedence. 34 35## reload 36 37Each layer file is parsed once per revision (size + mtime), including malformed JSON, invalid table shapes, and duplicate-id failures. The merged decoded Gleam table is cached; a changed file is picked up on the next lookup without a restart. A malformed layer file keeps that layer's last good entries and reports the reason in `GET /models?view=cache-policy`; fixing the file at a new revision is live again. Transient file-read errors are retried on the next read and retain last good entries. HTTP responses encode the cached table only when serving it. 38 39The remote copy refreshes in the background when it is stale, the same cadence as the models catalog. `/reload` (no target) re-fetches it immediately, alongside the models catalog: the command returns after the copy is atomically replaced, or with the fetch failure. A fetched layer with duplicate ids is rejected before replacing the file. A confirmed replacement invalidates the parsed layer and merged table even when size and timestamp stay unchanged. 40 41## HTTP API 42 43`GET /models?view=cache-policy` is read-only and requires the daemon bearer token: 44 45- no parameters — `{"entries": [...], "layers": [{"name": "default"|"remote"|"local", "path", "loaded", "error"?}]}`, each entry carrying the layer it came from and every field above it decoded. 46- `&extension=&host=&model=` returns `matched`, the resolved entry or `null`, using the same lookup. 47 48`layers` is the state of each file: `loaded` false with an `error` means that layer's last good entries are still merged in (or it was never readable). An absent local override or unconfigured remote url is simply not loaded, with no error.