Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions spec/router-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ paths:
$ref: '#/components/responses/RouterRequestError'
post:
summary: Run a partner model synchronously by canonical model ID.
description: 'Comfy Router''s canonical, model-ID-addressed entry point. The request body is the partner model''s own native JSON input and the success response is that model''s own native JSON output: Router forwards both unchanged instead of imposing a Comfy-shaped envelope, so a caller can move between the partner''s API and Router by changing the host. This is the synchronous path: the response carries the finished result.'
description: 'Comfy Router''s canonical, model-ID-addressed entry point. The request body is the partner model''s own native JSON input and the success response is that model''s own native output — JSON for most models, but the partner''s raw bytes (for example `audio/mpeg` for a text-to-speech model) for a model whose partner answers with a binary body: Router forwards both without imposing a Comfy-shaped envelope, so for most models a caller can move between the partner''s API and Router by changing the host. The exception is a model whose partner operation takes an identifier in its request path: Router has the caller name it as a top-level body field and moves it into the partner path, so that request needs that one adaptation. This is the synchronous path: the response carries the finished result.'
operationId: runRouterModel
tags:
- Comfy Router
Expand Down Expand Up @@ -842,7 +842,7 @@ components:
- detail
responses:
RouterConcurrencyLimited:
description: 'The caller is holding as much in-flight capacity as they are allowed and the request was refused before it reached the model. The bucket is `concurrency_limit_exceeded` in either case and `detail` says which bound was hit: the number of concurrent calls, or the committed spend of the calls still in flight, whose refusal also carries the `X-Committed-Spend-Limit`, `X-Committed-Spend-Current` and `X-Committed-Spend-Remaining` headers (USD cents). Retry once one of the caller''s own in-flight calls finishes. The body is `RouterErrorResponse` and the bucket is repeated on `X-Comfy-Error-Type`.'
description: 'The caller is holding as much in-flight capacity as they are allowed and the request was refused before it reached the model. The bucket is `concurrency_limit_exceeded` in every case and `detail` says which bound was hit: the number of concurrent calls; the number of concurrent calls to models classed expensive, a quarter of the concurrent-call limit shared with partner-node calls, whose refusal also carries the `X-Model-Concurrency-Limit`, `X-Model-Concurrency-Current` and `X-Model-Concurrency-Remaining` headers; or the committed spend of the calls still in flight, whose refusal also carries the `X-Committed-Spend-Limit`, `X-Committed-Spend-Current` and `X-Committed-Spend-Remaining` headers (USD cents). Retry once one of the caller''s own in-flight calls finishes - for the expensive-model bound, one of their calls to an expensive model, which may be a partner-node call. The body is `RouterErrorResponse` and the bucket is repeated on `X-Comfy-Error-Type`.'
headers:
X-Comfy-Error-Type:
$ref: '#/components/headers/RouterErrorTypeHeader'
Expand All @@ -854,6 +854,12 @@ components:
$ref: '#/components/headers/CommittedSpendCurrentHeader'
X-Committed-Spend-Remaining:
$ref: '#/components/headers/CommittedSpendRemainingHeader'
X-Model-Concurrency-Limit:
$ref: '#/components/headers/ModelConcurrencyLimitHeader'
X-Model-Concurrency-Current:
$ref: '#/components/headers/ModelConcurrencyCurrentHeader'
X-Model-Concurrency-Remaining:
$ref: '#/components/headers/ModelConcurrencyRemainingHeader'
content:
application/json:
schema:
Expand Down Expand Up @@ -1080,6 +1086,30 @@ components:
format: int64
minimum: 0
example: 400
ModelConcurrencyCurrentHeader:
description: The caller's concurrent calls to models classed expensive, as counted by the gate that refused this call. Present alongside `X-Model-Concurrency-Limit`.
required: false
schema:
type: integer
format: int64
minimum: 0
example: 1
ModelConcurrencyLimitHeader:
description: The most concurrent calls to models classed expensive the caller may hold at once, a quarter of the concurrent-call limit, shared with partner-node calls. Present on a `429` raised by that bound.
required: false
schema:
type: integer
format: int64
minimum: 0
example: 1
ModelConcurrencyRemainingHeader:
description: The expensive-model calls the caller may still start; `0` on the `429`. Present alongside `X-Model-Concurrency-Limit`.
required: false
schema:
type: integer
format: int64
minimum: 0
example: 0
RouterCapacityRetryAfterHeader:
description: Seconds to wait before re-sending the same request, unchanged. It is present only when Router refused the request body for capacity - the in-flight request-body budget was full, or no slot was free to scan an oversized body - and a capacity refusal submitted nothing and charged nothing, so re-sending the identical call once the interval has passed is the whole remedy. There is no `Idempotency-Key` to collect under and no queued request to poll for; this is the one `Retry-After` on Router that means simply "send it again later". It is absent on the dependency-fault `503`s that share this status - a credential rail, an idempotency store or a policy decision point that could not answer - because none of them knows when it will, and a wrong number is worse than none against a dependency that is already failing.
required: false
Expand Down
Loading