feat: merge opus comfyui and login updates
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user