catalog-contract: add response-decomposition fields (audio_field, timestamps_field, audio_format_field)
asset_engine consumer needed to render kokoro-captioned, whose wire
shape is a JSON envelope carrying base64-encoded audio plus a
structured timestamps array. Modeling it as response.type=json
would force either a per-service-id renderer (forbidden by
brief §1.7) or extending the closed response-type vocabulary
(forbidden by brief §2.2 without a coordinated bump).
Resolution (per althing thread 01KRCF4W66X3): keep response.type
closed at the existing six values and decompose at the response
*field* level instead — the same flexibility seam already used by
mime / mime_from_field / output_field. Adds three optional keys:
- audio_field: JSON key holding base64-encoded audio bytes
- audio_format_field: JSON key holding the decoded audio MIME
- timestamps_field: JSON key holding a structured timestamps array
(independent of type, declared by any service emitting time-
aligned markers)
Validators in CatalogResponse enforce sane combinations:
- audio_field requires response.type=audio
- audio_field forbids mime_from_field
- audio_format_field requires audio_field
This is additive and backward-compatible — no catalog_version bump,
existing services parse unchanged. CATALOG-CONTRACT.md updated with
the new rows in the response-field table and a versioning-policy
row codifying that adding optional keys to response: doesn't bump.
kokoro-captioned re-shaped to use the new schema:
response:
type: audio
audio_field: audio
audio_format_field: audio_format
timestamps_field: timestamps
And marked status: experimental until the asset_engine consumer's
audio-with-timestamps renderer ships.
JSON Schema regenerated to reflect the new Pydantic shape.
Pydantic-model side of this change lives in the asset_engine repo
at src/asset_engine/catalog.py — committed there separately.
This commit is contained in:
@@ -46,10 +46,13 @@ reproducibility_audit: [Audit] # one entry per service
|
||||
| `model.revision` | string \| null | no | SHA when known |
|
||||
| `model.image` | string | yes | container image ref this is hosted from |
|
||||
| `fields` | list[Field] | no | request parameters; empty for catalog-deferred |
|
||||
| `response.type` | enum: audio, image, video, text, json, file | yes | response renderer hint |
|
||||
| `response.mime` | string | no | static response MIME |
|
||||
| `response.mime_from_field` | string | no | name of a field whose value determines the MIME |
|
||||
| `response.output_field` | string | no | for JSON responses, the key holding the asset |
|
||||
| `response.type` | enum: audio, image, video, text, json, file | yes | renderer dispatch (closed vocabulary) |
|
||||
| `response.mime` | string | no | static response MIME (raw-bytes wire) |
|
||||
| `response.mime_from_field` | string | no | name of a field whose value determines the MIME (raw-bytes wire) |
|
||||
| `response.output_field` | string | no | for text/json responses, JSON key holding the asset |
|
||||
| `response.audio_field` | string | no | for `type: audio` with JSON-envelope wire, JSON key holding base64-encoded audio bytes |
|
||||
| `response.audio_format_field` | string | no | for `type: audio` with JSON-envelope wire, JSON key holding the decoded audio MIME (e.g. "audio/wav") |
|
||||
| `response.timestamps_field` | string | no | JSON key holding a structured timestamps array — independent of type, declared by any service that emits time-aligned markers alongside its primary output |
|
||||
| `reproducibility.seedable` | bool | yes | does the endpoint accept a seed? |
|
||||
| `reproducibility.deterministic` | bool | yes | same params → same bytes? |
|
||||
| `reproducibility.notes` | string | no | gotchas |
|
||||
@@ -91,6 +94,7 @@ Same change-management as field types.
|
||||
|----------------------------------------------|-----------------------|
|
||||
| Add a new service | nothing |
|
||||
| Add a non-required field to an existing service | service `version:` |
|
||||
| Add an optional key to the `response:` schema (e.g. audio_field, timestamps_field) | nothing — additive, backward-compatible |
|
||||
| Change a field's type, range, or default | service `version:` |
|
||||
| Remove a service | service `version:` (sentinel: removed=true), then drop in next catalog_version bump |
|
||||
| Add a new entry to the field-type vocabulary | `catalog_version:` |
|
||||
|
||||
Reference in New Issue
Block a user