Commit Graph

2 Commits

Author SHA1 Message Date
Rdmclin2 e85ae51880 ✨ feat(openapi): add eval read routes for runs, datasets and topics (#19423)
* 🐛 fix(openapi): exempt heterogeneous relay routes from spec parity

`POST /api/v1/anthropic/v1/messages` and `POST /api/v1/openai/v1/responses`
are registered without `describeRoute`, so the generator's parity check has
been failing since #18558 and `openapi.yml` could no longer be regenerated.

Both relays speak the upstream Anthropic/OpenAI wire formats and are gated by
`requireHeteroModelInvocation` (operation JWT), so no API key holder can reach
them and their schemas are not LobeHub's to publish. Exempt them the same way
the documentation-serving routes already are, instead of describing endpoints
that are not part of the public API surface.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmyR6qUiKJX9VteSJR1hiu

* ✨ feat(openapi): add eval read routes for runs, datasets and topics

`/api/v1/eval` could create a run and read that one run back, but offered no
way to discover what already exists, so API consumers had to know a run id out
of band. Add the four missing read endpoints:

- `GET /eval/runs` (paginated, filterable by dataset and status)
- `GET /eval/datasets`
- `GET /eval/datasets/:id`
- `GET /eval/runs/:id/topics`

All four reuse the domain's existing posture: `AGENT_READ` RBAC, mandatory
pagination, and public-field allowlists so internal columns never reach the
response. Cross-tenant reads stay 404 rather than 403 so the endpoints do not
confirm the existence of other tenants' rows.

The models gain only the read primitives the routes need (count + paginated
list); no schema or migration changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmyR6qUiKJX9VteSJR1hiu

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 12:28:50 +08:00
Rdmclin2 3ea7afd5d8 ✨ feat(openapi): generate openapi.yml from routes via hono-openapi (#17944)
* ✨ feat(openapi): generate openapi.yml from routes via hono-openapi

- add src/common/validator.ts: drop-in zValidator built on hono-openapi so
  every request schema registers into the spec while keeping the exact
  @hono/zod-validator 400 response shape
- describe the four validator-less routes (users/me, agent-groups list,
  file upload, batch upload incl. multipart bodies) and /health
- add scripts/generate-openapi.ts: runtime spec generation with
  route-vs-spec parity check, --check mode for CI, placeholder responses
- commit the generated openapi.yml (79 operations / 38 paths) and guard
  it with scripts/generate-openapi.test.ts
- ignore the generated file in eslint/prettier so formatters don't fight
  the generator output

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ✨ feat(openapi): serve API docs at /api/v1/docs via Scalar

- extract spec assembly into src/spec.ts, shared by the generator script
  and the new runtime endpoint so both always emit the same document
- GET /api/v1/openapi.json: build spec from live routes on first request,
  cached in memory
- GET /api/v1/docs: Scalar interactive reference reading that endpoint
- exempt the two docs routes from the generator parity check (real
  endpoints, deliberately not part of the described API surface)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* 💄 style(openapi): match docs site theme to the app's neutral monochrome style

- add src/docs-theme.ts: Scalar CSS variable overrides — black accent on
  light, white accent on true-black dark, antd system font stack
- theme: 'none' so the runtime bundle doesn't inject its default theme
  stylesheet after our customCss (which silently overrode every variable)
- reuse the app favicon

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* 🌐 feat(openapi): localize docs UI following the app's language preference

Resolve the Scalar UI locale per request with the same priority the main
app uses (?hl query > LOBE_LOCALE cookie > Accept-Language), mapped to
Scalar's built-in translations (zh-CN, de, fr, es, ru, ar; zh-* all map
to zh-CN). English stays the default for unsupported locales.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 22:48:08 -07:00