Follow-up from #226 MVP (PR #402 lands /v1/embeddings).
Problem
`/v1/images/generations`, `/v1/images/edits`, `/v1/images/variations` (OpenAI DALL-E shape image endpoints) do not emit `UsageEvent` to `ProxyState.usage_sink` on success. Same budget-ledger / /logs gap as embeddings.
Image endpoints are billed per-image (not per-token), and the response shape does not include a usage block. The `UsageEvent` shape will need adapting:
- `prompt_tokens` doesn't map. The natural counter is `n` (number of images requested) and the resolution / quality tier.
- Cost calculation cp-api-side relies on pricing catalog keyed on (model, resolution, quality) — DP only needs to surface enough metadata for that lookup.
Acceptance criteria
- On a successful 200 from /v1/images/*, exactly one `UsageEvent` arrives on the configured sink
- Image-count / resolution mapping documented in the PR (likely needs cp-api coordination)
- `model_id`, `api_key_id`, `inbound_protocol = "openai"` per chat.rs convention
References
Follow-up from #226 MVP (PR #402 lands /v1/embeddings).
Problem
`/v1/images/generations`, `/v1/images/edits`, `/v1/images/variations` (OpenAI DALL-E shape image endpoints) do not emit `UsageEvent` to `ProxyState.usage_sink` on success. Same budget-ledger / /logs gap as embeddings.
Image endpoints are billed per-image (not per-token), and the response shape does not include a usage block. The `UsageEvent` shape will need adapting:
Acceptance criteria
References