Summary
GET /ai-gateway/anthropic/v1/models implements Anthropic's cursor pagination for
limit, after_id and has_more, but it always returns first_id: null and
last_id: null — including when has_more is true. The Models API contract defines
last_id as the cursor a client feeds back as after_id ("Last ID in the data list.
Can be used as the after_id for the next page."), so a client written against the
documented contract stops after the first page and silently sees a truncated model list.
Only a client that reaches into data[-1].id can walk the list.
Observed
Workspace with 9 advertised Anthropic models; ug 0.1.0+161.gf26daf3.
| Request |
Response |
?limit=2 |
2 models, has_more: true, first_id: null, last_id: null |
?limit=2&after_id=<data[-1].id> |
the next 2 models, no overlap with page 1 |
walk with limit=2, cursor taken from data[-1].id |
5 pages, 9 unique ids — matches the unpaged read |
| no query parameters |
9 models, has_more: false |
curl -s -H "Authorization: Bearer $(databricks auth token --profile <profile> | jq -r .access_token)" \
"https://<workspace-host>/ai-gateway/anthropic/v1/models?limit=2" \
| jq '{has_more, first_id, last_id, n: (.data|length)}'
# => { "has_more": true, "first_id": null, "last_id": null, "n": 2 }
Expected
When data is non-empty, first_id is the first id in data and last_id is the last,
per the contract, so after_id / before_id walks work without reading into data.
Why it matters for ug
ug's own discovery read this endpoint once with no limit and ignored has_more
(_get_anthropic_models_json in src/ucode/databricks.py), so on a workspace advertising
more models than the endpoint's default limit of 20, every model after the first page was
invisible to ug configure, the model pickers and discover_claude_models. I have a patch
that walks the pages; because last_id is null it has to take the cursor from
data[-1].id, which is why this is worth fixing on the gateway side as well.
Reference: List Models — https://platform.claude.com/docs/en/api/models/list
Summary
GET /ai-gateway/anthropic/v1/modelsimplements Anthropic's cursor pagination forlimit,after_idandhas_more, but it always returnsfirst_id: nullandlast_id: null— including whenhas_moreistrue. The Models API contract defineslast_idas the cursor a client feeds back asafter_id("Last ID in thedatalist.Can be used as the
after_idfor the next page."), so a client written against thedocumented contract stops after the first page and silently sees a truncated model list.
Only a client that reaches into
data[-1].idcan walk the list.Observed
Workspace with 9 advertised Anthropic models; ug 0.1.0+161.gf26daf3.
?limit=2has_more: true,first_id: null,last_id: null?limit=2&after_id=<data[-1].id>limit=2, cursor taken fromdata[-1].idhas_more: falseExpected
When
datais non-empty,first_idis the first id indataandlast_idis the last,per the contract, so
after_id/before_idwalks work without reading intodata.Why it matters for ug
ug's own discovery read this endpoint once with no
limitand ignoredhas_more(
_get_anthropic_models_jsoninsrc/ucode/databricks.py), so on a workspace advertisingmore models than the endpoint's default
limitof 20, every model after the first page wasinvisible to
ug configure, the model pickers anddiscover_claude_models. I have a patchthat walks the pages; because
last_idis null it has to take the cursor fromdata[-1].id, which is why this is worth fixing on the gateway side as well.Reference: List Models — https://platform.claude.com/docs/en/api/models/list