Transform Daeva into a Dual-Mode Engine to seamlessly support both custom automation (via the internal job queue) and generic, off-the-shelf native integrations (like OpenClaw's comfy provider) that expect to talk directly to the underlying service API.
The original POST /jobs architecture remains. This is for custom integrations that want to submit background jobs, track state asynchronously, and handle explicit pod management.
A transparent HTTP/WebSocket proxy layer exposed at /proxy/:podId/*.
This allows generic clients to point their baseUrl to Daeva (e.g., http://razerblade.local:8787/proxy/comfyapi).
To the generic client, it looks exactly like the target service. Under the hood, Daeva acts as an API-aware Queueing Proxy:
- Intercept: Catch incoming HTTP/WS requests on the proxy route.
- Queue / Lock: Acquire the GPU exclusivity lock (waiting if the GPU is currently used by another pod, like Whisper).
- Wake: Ensure the requested pod (
:podId) is running (starting it viapod-controllerif it's currently stopped). - Proxy: Forward the raw traffic to the pod's internal
baseUrl. - Release: Once the connection closes (or the request completes), release the GPU lock so other queued pods can spin up.
- Hook into the Fastify server (
src/server.ts) to add a catch-all proxy route. - Use a proxy library (like
@fastify/http-proxyor standard Node HTTP proxying) to pipe the requests. - Integrate with
job-manager.tsorpod-controller.tsto request and hold the execution lock for the duration of the proxy request. - Ensure WebSocket upgrades are supported (critical for ComfyUI's
/wsendpoint). - Keep it transparent: headers, query params, and body must pass through unchanged.