feat: merge opus comfyui and login updates

This commit is contained in:
boos
2026-05-21 16:32:04 +02:00
parent c16479da7c
commit 9c84759498
105 changed files with 20160 additions and 1034 deletions
@@ -0,0 +1,78 @@
## ADDED Requirements
### Requirement: Per-user container lifecycle
The system SHALL maintain at most one ComfyUI container per authenticated user. The container SHALL be started lazily on the user's first request to `/comfy/*` or `/api/video-agent/*` and SHALL be reaped after 60 minutes of inactivity.
#### Scenario: First request starts the container
- **WHEN** an authenticated user with no running container makes a request to `/comfy/*`
- **THEN** the system starts a container named `comfyui-user-<user_id>`, allocates a port from 8200–8299, records `last_used_at = now`, and forwards the request once the container's HTTP port is reachable
#### Scenario: Subsequent request reuses the container
- **WHEN** the same user makes another request within 60 minutes
- **THEN** the system reuses the existing container, updates `last_used_at = now`, and forwards the request without restarting
#### Scenario: Idle container is reaped
- **WHEN** a container's `last_used_at` is older than 60 minutes AND it has no active WebSocket connections
- **THEN** the system stops the container via the runtime's `stop` method and releases its port back to the pool
### Requirement: Concurrency cap
The system SHALL refuse to start a new container when 30 are already running.
#### Scenario: 31st user is rejected
- **WHEN** 30 containers are running and a 31st distinct user requests `/comfy/*`
- **THEN** the system responds with HTTP 503 and a `Retry-After: 60` header, and does NOT evict any existing container
#### Scenario: Cap frees on idle reap
- **WHEN** any of the 30 containers is reaped
- **THEN** the next pending user request that arrives starts a fresh container in the freed slot
### Requirement: Resource limits
Each container SHALL run with `--cpus=2`, `--memory=2g`, `--memory-swap=2g`, `--pids-limit=512`, `--read-only` rootfs, `--cap-drop=ALL`, and `--security-opt=no-new-privileges`.
#### Scenario: Container respects CPU and memory caps
- **WHEN** a new container is started
- **THEN** `docker inspect` shows `HostConfig.NanoCpus = 2000000000`, `HostConfig.Memory = 2147483648`, `HostConfig.MemorySwap = 2147483648`
#### Scenario: Container has no extra capabilities
- **WHEN** a new container is started
- **THEN** `docker inspect` shows `HostConfig.CapDrop` contains `ALL` and `HostConfig.SecurityOpt` contains `no-new-privileges`
### Requirement: Persistent per-user volumes
Each container SHALL mount the host directory `/data/comfyui-users/<user_id>/` so that custom workflows, inputs, and outputs survive container restarts.
#### Scenario: Workflow saved in one session is visible after restart
- **WHEN** a user saves a workflow file to ComfyUI's `user/` directory, then triggers a container restart (idle reap + new request)
- **THEN** the workflow file is still present in the new container's `user/` directory
#### Scenario: Volume is per-user
- **WHEN** user A saves a file and user B starts their own container
- **THEN** user B's container does NOT see user A's file
### Requirement: Built-in API key injection
Each container SHALL receive `BOOSAPI_BUILTIN_KEY`, `BOOSAPI_BASE`, and `BOOSAPI_KEY` as environment variables so ComfyUI's built-in OpenAI nodes (via the patched `_helpers.py`) and the `bosapi_comfy_nodes.py` custom nodes both authenticate successfully.
#### Scenario: Internal OpenAI node authenticates
- **WHEN** a workflow uses a built-in ComfyUI OpenAI node and the container has `BOOSAPI_BUILTIN_KEY` set
- **THEN** the node's outbound request to the BoosAPI shim includes `Authorization: Bearer <BOOSAPI_BUILTIN_KEY>`
#### Scenario: Custom BoosAPI node authenticates
- **WHEN** a workflow uses `BoosAPITextGen` from `bosapi_comfy_nodes.py` and the container has `BOOSAPI_KEY` set
- **THEN** the node's request to `BOOSAPI_BASE` includes `Authorization: Bearer <BOOSAPI_KEY>`
### Requirement: Container state observable to callers
The pool SHALL expose each container's state as `starting`, `ready`, or `stopped` so the frontend can render a loading UI during cold start.
#### Scenario: Status reflects starting then ready
- **WHEN** a user's first request triggers a container start
- **THEN** `pool.state(user_id)` returns `starting` until the HTTP port is reachable, then `ready`
#### Scenario: Status reflects stopped after reap
- **WHEN** a container has been idle-reaped
- **THEN** `pool.state(user_id)` returns `stopped`
### Requirement: Reconcile on startup
On API restart, the pool SHALL list all `comfyui-user-*` containers from the runtime and reconstruct its in-memory map (user_id, port, last_used_at).
#### Scenario: Existing containers are adopted
- **WHEN** the API process restarts while a `comfyui-user-42` container is still running
- **THEN** the new pool's map contains an entry for user 42 with the original container's port, and the next request from user 42 reuses it