Spaces:
Running
Running
File size: 5,545 Bytes
1b2323a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | # Generation foundation
MediaRouter has a provider-neutral generation domain for image and video
workers. The audited optional WAN 2.2 and FLUX.2 Klein integrations are
documented in [`generation-wan.md`](generation-wan.md) and
[`generation-flux.md`](generation-flux.md). Each remains unavailable until its
trusted worker configuration and live readiness verification succeed. Other
models remain unregistered.
## Architecture
```text
REST / MCP / SDK / n8n (future transports)
|
GenerationService
|
GenerationProviderRegistry (verified adapters only)
|
GenerationRepository + authoritative tenancy + RLS
|
CanonicalMediaAsset references
```
`GenerationService` is the single transport-neutral orchestration boundary.
Provider adapters must supply strict typed validation and worker submission;
transports must not accept arbitrary provider payloads or worker URLs.
## Data and tenancy
The security database migration
[`0003_generation_domain_postgres.sql`](../app/security/migrations/0003_generation_domain_postgres.sql)
adds these workspace-scoped tables:
- `generation_requests`: immutable validated intent and its idempotency
fingerprint.
- `generation_jobs`: exactly one durable logical execution per request.
- `generation_job_attempts`: retry audit history, without creating a new job.
Input and output media are opaque IDs referencing `media_assets`. Client paths,
local paths, direct object-store URLs, and provider credentials are never
accepted or returned. Database triggers ensure request input assets and job
outputs belong to the same workspace as the request/job. PostgreSQL RLS uses
the already-established `app.workspace_id` and `app.user_id` session context.
[`0004_generation_provider_runtime_postgres.sql`](../app/security/migrations/0004_generation_provider_runtime_postgres.sql)
adds a unique provider/external-job binding so a remote worker identity cannot
be attached to jobs in more than one workspace.
## API
All endpoints require MediaRouter authentication and an authoritative active
workspace membership.
| Method | Endpoint | Scope | Purpose |
|---|---|---|---|
| `GET` | `/v1/generation/providers` | `generation:providers:read` | Capability discovery; no unavailable provider is advertised as usable. |
| `GET` | `/v1/generation/providers/{provider}` | `generation:providers:read` | One provider's public capabilities. |
| `GET` | `/v1/generation/models` | `generation:providers:read` | Server-owned model discovery; availability requires verified worker readiness. |
| `GET` | `/v1/generation/providers/{provider}/models/{model_id}` | `generation:providers:read` | One registered provider model. |
| `POST` | `/v1/generation/requests` | `generation:requests:create` | Create a durable job once an available adapter exists. Requires `Idempotency-Key`. |
| `GET` | `/v1/generation/requests` | `generation:requests:read` | List only caller-workspace requests. |
| `GET` | `/v1/generation/requests/{id}` | `generation:requests:read` | Read one caller-workspace request and job. |
| `GET` | `/v1/generation/jobs/{id}` | `generation:requests:read` | Read one caller-workspace job. |
| `POST` | `/v1/generation/jobs/{id}/cancel` | `generation:jobs:cancel` | Cancel queued work or request cancellation for active work. |
The strict foundation request envelope is:
```json
{
"provider": "future-provider",
"model_id": "verified-model-id",
"modality": "image",
"prompt": "A production-safe prompt",
"input_asset_id": "optional-canonical-media-asset-uuid"
}
```
Unknown JSON fields are rejected. Provider-specific controls are deliberately
not accepted unless the relevant adapter supplies a reviewed typed schema. WAN
uses the closed `wan` schema documented in
[`generation-wan.md`](generation-wan.md); FLUX uses the closed `flux` schema
documented in [`generation-flux.md`](generation-flux.md).
## Job semantics
The state machine is `queued → submitting → running → succeeded`, with
`retrying`, `failed`, `cancel_requested`, and `cancelled` paths. A retry
continues the original `generation_jobs` row; it never creates another logical
generation. Queued jobs cancel immediately. Active jobs become
`cancel_requested` until the configured provider confirms cancellation, so the API
does not make a false cancellation claim.
An `Idempotency-Key` is required for every submission. The database enforces
one key per workspace; MediaRouter fingerprints the normalized request and
returns `GENERATION_IDEMPOTENCY_CONFLICT` when a caller reuses a key with a
different payload.
## Deployment
For local SQLite development, metadata is created with the rest of the
security schema. PostgreSQL deployments must apply all security migrations in
order, including `0003_generation_domain_postgres.sql` and
`0004_generation_provider_runtime_postgres.sql`, before startup.
Relevant configuration:
```env
GENERATION_ENABLED=true
GENERATION_JOB_RETRY_LIMIT=3
AI_WORKER_CONNECT_TIMEOUT_SECONDS=10
AI_WORKER_REQUEST_TIMEOUT_SECONDS=60
AI_WORKER_READ_TIMEOUT_SECONDS=300
AI_WORKER_MAX_RETRIES=3
AI_WORKER_RETRY_BACKOFF_SECONDS=0.5
```
These settings provide shared worker transport defaults only. Provider URLs
and tokens stay backend-only and are documented with each verified provider.
The provider-runtime contract, worker transport, output handoff, and future
adapter requirements are documented in
[`generation-providers.md`](generation-providers.md). WAN and FLUX have
separately reviewed optional adapters.
|