Spaces:
Running
Running
| # 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. | |