Skip to content

Add /enhance path to openapi.yaml (wave-gateway#799) - #44

Open
yakimoto wants to merge 7 commits into
mainfrom
enhance/openapi-799
Open

Add /enhance path to openapi.yaml (wave-gateway#799)#44
yakimoto wants to merge 7 commits into
mainfrom
enhance/openapi-799

Conversation

@yakimoto

@yakimoto yakimoto commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the missing OpenAPI entry for POST /v1/enhance — an AI video super-resolution route that
has been live-routed with no spec entry and no SDK method (closes the contract-drift gap flagged
against wave-gateway#799).

  • New Enhance tag + POST /enhance path, mirroring the existing Render/MoQ/AV Mux-Demux
    paths' style (x402 PaymentRequired idiom, binary in/out, per-job receipt headers).
  • v1 ships exactly one model, espcn (ESPCN super-resolution — a fixed exact 3x factor baked
    into the trained model weights, not a runtime parameter); any other model value 400s.
  • Auth: bearer API key, enhance:write scope. Unauthenticated → 402 with the same x402
    challenge shape used elsewhere in this spec ($ref: '#/components/responses/PaymentRequired').
  • Billing note: bills against the wave_enhance_minutes meter — the OUTPUT artifact's rendered
    duration, rounded up to the next whole minute. (I checked the actual spoke source before
    writing this: it does not currently apply a resolution-weighting factor to the minute
    count — that weighting is an open, undecided pricing question upstream, not shipped code — so
    the spec documents plain output-duration minutes rather than inventing a formula.)
  • Documents the request contract (raw body or ?url= fetch, 200 MiB cap), the per-job receipt
    response headers (x-enhance-model, x-enhance-scale-factor, x-enhance-*-dimensions,
    x-wave-meter, x-wave-usage-minutes), and the error shapes actually returned by the spoke
    (400/401/402/403/413/422/429/501/502/503).

Validation

Ran this repo's own CI checks locally (.github/workflows/foundation-gate.yml):

$ npx --yes @redocly/cli@2.40.0 lint openapi.yaml
openapi.yaml: validated in 90ms
Woohoo! Your API description is valid. 🎉
You have 53 warnings.

53 warnings is the exact pre-existing baseline this workflow's own comment documents (no new
warnings or errors introduced by this change).

$ node .github/scripts/assert-refs.mjs openapi.yaml
assert-refs: 204 $ref(s) in openapi.yaml, all resolve

CI on this PR may show as failed/cancelled due to the ongoing GitHub Actions "Service
Unavailable" incident — that is unrelated to this change; see the local runs above for the real
result.

Test plan

  • npx @redocly/cli lint openapi.yaml passes with the pre-existing warning count only
  • assert-refs.mjs confirms every $ref in the file still resolves
  • Operator merge (this PR is not merged by the agent that opened it — public repo, human-only merge)

Note

Low Risk
OpenAPI and changelog only; no gateway or spoke behavior changes. Low risk aside from ensuring the documented contract matches the deployed enhance spoke.

Overview
Documents the live POST /enhance route that was routed without an OpenAPI entry, closing contract drift so SDK/CLI clients can be generated.

Adds an Enhance tag and enhanceVideo (POST /enhance): synchronous ESPCN (espcn) super-resolution with optional raw video body or ?url= (https, public hosts only, 200 MiB cap). Auth is enhance:write bearer or unauthenticated x402 pay-per-call via the shared PaymentRequired 402 response. Success streams binary video with receipt headers (x-enhance-*, x-wave-meter, x-wave-usage-minutes) and bills wave_enhance_minutes (output duration, rounded up).

createEnhancement on POST /studio-ai/enhancements now points callers to POST /enhance for synchronous ad-hoc bytes vs async library jobs. CHANGELOG.md records the new surface under [Unreleased].

Reviewed by Cursor Bugbot for commit 4833622. Configure here.


View with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled.

Review in cubic

Note

Add POST /enhance endpoint for synchronous AI video super-resolution to openapi.yaml

  • Adds a new POST /enhance path to openapi.yaml with operationId enhanceVideo, supporting the espcn model for synchronous video super-resolution.
  • Accepts input as either a raw binary request body or an https URL via ?url= query parameter, with a 200 MiB size limit.
  • Returns the enhanced video as a binary stream with billing metadata headers (x-enhance-model, x-enhance-scale-factor, x-wave-meter, x-wave-usage-minutes, etc.).
  • Supports both BearerAuth and unauthenticated x402 pay-per-call billing against wave_enhance_minutes.
  • Updates the existing POST /studio-ai/enhancements description to distinguish it from the new synchronous endpoint.

Macroscope summarized bab8755.

The live-bound POST /v1/enhance route (ESPCN super-resolution, v1 ships
exactly one model) had no OpenAPI entry. Documents auth (bearer key,
enhance:write scope), the x402 402 challenge for unauthenticated callers
(mirrors the Render/MoQ PaymentRequired idiom), the raw-body-or-?url=
input contract, the per-job receipt headers (x-enhance-*), the
wave_enhance_minutes duration-billing note, and the 400/413/422/501/503
error shapes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yakimoto yakimoto added the rr:skip-coderabbit RF.P1 reviewer routing (#1039) label Aug 6, 2026
@cursor

cursor Bot commented Aug 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_9a7d1ce7-336e-40e3-bcfd-b76367566d57)

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are limited based on label configuration.

🚫 Excluded labels (none allowed) (1)
  • rr:skip-coderabbit

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c9bc4ad3-c818-49b9-b5b0-1a08460b75dd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Aug 6, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 6, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs human review

Unable to check for correctness in bab8755. This PR adds OpenAPI spec for an existing /enhance endpoint. While purely documentation changes owned by the author, 5 unresolved review comments identify inconsistencies with existing spec conventions (auth patterns, header prefixes, 402 handling) that affect SDK generation - the stated goal of this PR. These design decisions warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Document POST /v1/enhance in OpenAPI (AI super-resolution, x402)

✨ Enhancement 📝 Documentation 🕐 10-20 Minutes

Grey Divider

AI Description

• Add missing OpenAPI spec for POST /v1/enhance AI super-resolution route.
• Define auth scope, x402 PaymentRequired behavior, and duration-based billing headers.
• Document input modes (body or URL fetch), size limits, and expected error responses.
Diagram

graph TD
  client["API Client"] --> gw["Gateway \"/v1/enhance\""] --> enhance["Enhance Spoke"] --> resp["Binary Video + Receipt Headers"]
  enhance --> src{{"HTTPS Source (optional)"}}
  enhance --> meter[("Usage Meter \"wave_enhance_minutes\"")]

  subgraph Legend
    direction LR
    _c["Client"] ~~~ _s["Service"] ~~~ _e{{"External"}} ~~~ _d[("Meter/Store")]
  end
Loading
High-Level Assessment

The PR’s approach—documenting the already-live route directly in openapi.yaml and reusing existing shared response components (Unauthorized/PaymentRequired/Forbidden/UpstreamError)—is the simplest way to close contract drift without introducing new abstractions. Considered extracting shared header/parameter components, but this endpoint is currently singular and the added indirection would not materially improve maintainability yet.

Files changed (1) +143 / -0

Documentation (1) +143 / -0
openapi.yamlAdd Enhance tag and POST /enhance endpoint contract +143/-0

Add Enhance tag and POST /enhance endpoint contract

• Introduces a new 'Enhance' tag and documents 'POST /enhance' (served under /v1 via the server URL) for AI video super-resolution. Specifies model selection (v1 'espcn' only), body-or-URL input with a 200 MiB cap, binary streaming output, receipt/billing headers, and the full set of expected error responses including x402 PaymentRequired.

openapi.yaml

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 potential issues.

Open in Devin Review

Comment thread openapi.yaml
Comment thread openapi.yaml
Comment thread openapi.yaml
Comment on lines +1694 to +1695
'402':
$ref: '#/components/responses/PaymentRequired'

@devin-ai-integration devin-ai-integration Bot Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 402 handling differs from the other x402-payable endpoints

Other x402-payable operations (/render at openapi.yaml:145-161, /av/remux, /av/demux) define their 402 inline with a WWW-Authenticate challenge header and the Error schema, while /enhance reuses #/components/responses/PaymentRequired, whose documented body is X402PaymentRequired (error as a plain string, normalized error under error_detail) and which advertises the x-payment retry flow rather than WWW-Authenticate. Generated clients will therefore parse enhance 402s differently from render/av 402s; confirm which challenge form the enhance route actually returns.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified against wave-gateway source: unauthenticated /v1/enhance requests hit the gateway's paymentChallenge (x402-pay-lane.ts), which returns the X402PaymentRequired JSON envelope with no WWW-Authenticate header, so referencing #/components/responses/PaymentRequired is the accurate form. The inline WWW-Authenticate 402s on /render and /av/* are a pre-existing inconsistency in those entries, out of scope for this PR.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
@qodo-code-review

qodo-code-review Bot commented Aug 6, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Octet-stream response missing ✓ Resolved 🐞 Bug ≡ Correctness
Description
The /enhance 200 response claims it streams back using the same Content-Type as the source,
and the requestBody allows application/octet-stream, but the response only declares video/*.
This leaves application/octet-stream responses undocumented and may cause generated clients to
mishandle or reject that response type.
Code

openapi.yaml[R1680-1683]

+            video/*:
+              schema:
+                type: string
+                format: binary
Evidence
The spec explicitly allows application/octet-stream in the request body, and also says the
response uses the same content-type as the source, but the 200 response only declares video/* as
a possible media type.

openapi.yaml[1635-1648]
openapi.yaml[1650-1653]
openapi.yaml[1679-1684]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`POST /enhance` accepts `application/octet-stream` uploads and states that the response will be streamed back with the same content-type as the source, but the OpenAPI `200` response only declares `video/*`. This makes the contract internally inconsistent and leaves octet-stream responses undocumented.

## Issue Context
The requestBody explicitly allows `application/octet-stream`, so clients may legitimately send it. If the server mirrors that content-type back (as described), the OpenAPI response content types should include it.

## Fix Focus Areas
- openapi.yaml[1635-1684]

## Suggested fix
Under `responses: '200': content:`, add an `application/octet-stream` entry (same binary schema as `video/*`). If the implementation never returns octet-stream, instead adjust the description to match the actual fixed response content-type.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. openapi.yaml exceeds 500 lines 📘 Rule violation ⚙ Maintainability
Description
openapi.yaml is well over 500 lines, and this PR adds additional content to it. This violates the
rule limiting touched source files to 500 non-empty, non-comment lines.
Code

openapi.yaml[R75-78]

+  - name: Enhance
+    description: >-
+      AI video super-resolution. v1 ships one model, `espcn` (ESPCN, a fixed exact 3x upscale) —
+      unrecognized `model` values 400. Requires the `enhance:write` entitlement; x402-payable
Evidence
PR Compliance ID 2497975 requires each touched source file to be <= 500 non-empty, non-comment
lines. The PR modifies openapi.yaml, and the file’s current line numbering is far beyond 500
(e.g., lines in the 1700s exist), demonstrating it exceeds the limit.

Rule 2497975: Limit source file length to 500 lines of code
openapi.yaml[1691-1740]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The touched file `openapi.yaml` exceeds the 500 non-empty, non-comment line limit.

## Issue Context
This PR adds new `Enhance` tag/path content to `openapi.yaml`, which is already far beyond 500 lines.

## Fix Focus Areas
- openapi.yaml[75-80]
- openapi.yaml[1599-1616]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context used
✅ Compliance rules (platform): 1 rule
Review mode: ⚖️ Balanced: This adds a public API contract covering authentication, payment, SSRF-sensitive URL fetching, billing, binary handling, and many error paths; one careful complete review is warranted, but the logic is localized to a single endpoint rather than dense across independent sites.

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

qodo-code-review[bot]

This comment was marked as resolved.

@qodo-code-review

Copy link
Copy Markdown

Qodo Fixer

No findings are within the configured fix scope. To change which findings are fixed, adjust the setting on your Qodo configuration page.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

Open in Devin Review

Comment thread openapi.yaml
Comment on lines +1667 to +1691
headers:
x-enhance-model:
schema:
type: string
description: The model that ran, e.g. `espcn`.
x-enhance-scale-factor:
schema:
type: number
description: Upscale factor actually applied.
x-enhance-input-dimensions:
schema:
type: string
description: Input frame dimensions as `WIDTHxHEIGHT`, e.g. `1280x720`.
x-enhance-output-dimensions:
schema:
type: string
description: Output frame dimensions as `WIDTHxHEIGHT`, e.g. `672x672`.
x-wave-meter:
schema:
type: string
description: The meter this job billed against — `wave_enhance_minutes`.
x-wave-usage-minutes:
schema:
type: integer
description: Output-duration minutes billed for this job (rounded up).

@devin-ai-integration devin-ai-integration Bot Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Response headers use an x-enhance- prefix instead of the repo's x-wave- convention

Four of the six documented response headers use an x-enhance- prefix (x-enhance-model, x-enhance-scale-factor, x-enhance-input-dimensions, x-enhance-output-dimensions) while the metering headers on the same response use x-wave- (x-wave-meter, x-wave-usage-minutes), and other surfaces in this spec consistently use x-wave-* (e.g. x-wave-sha256 on /render at openapi.yaml:117, x-wave-moq-join at openapi.yaml:92). Worth confirming with the gateway implementation which prefix is actually emitted, since the spec is the SDK source of truth.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

Open in Devin Review

Comment thread openapi.yaml
Comment on lines +1709 to +1712
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'

@devin-ai-integration devin-ai-integration Bot Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Optional-auth pattern differs from other x402 routes in this spec

This operation declares security: [{}, {BearerAuth: []}], whereas the other x402-payable routes (/render at openapi.yaml:118, and the AV routes) use security: [] to disable the global bearer requirement. Both are valid OpenAPI, but the two forms generate different SDK/CLI auth handling (optional-auth vs no-auth). Worth aligning the convention across x402 routes so generated clients behave uniformly.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread openapi.yaml
Comment on lines +1653 to +1661
content:
video/*:
schema:
type: string
format: binary
application/octet-stream:
schema:
type: string
format: binary

@devin-ai-integration devin-ai-integration Bot Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Wildcard media type video/* in request/response content

The request body and 200 response use the media-type range video/* alongside application/octet-stream. OpenAPI 3.1 permits ranges, but many generators (openapi-generator, oazapfts, some Spectral rulesets) handle wildcard keys poorly or emit awkward method signatures — relevant because the stated motivation of this PR is enabling SDK/CLI generation. Worth verifying the generators used downstream produce a usable binary-body method for this operation.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Aug 6, 2026
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
@cursor

cursor Bot commented Aug 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_1a6e3fe0-9b47-4c10-8219-752aa83502f7)

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Aug 6, 2026
devin-ai-integration[bot]

This comment was marked as resolved.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rr:skip-coderabbit RF.P1 reviewer routing (#1039)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant