156 Commits
Author SHA1 Message Date
Sylvester Meighan f3ef985305 feat(rife): add RifeStreamVFI node for chunked frame interpolation
- Add rife_chunked.py with RifeStreamVFI ComfyUI node that downloads a
  video from a presigned URL and runs RIFE N× interpolation in temporal
  chunks (default chunk_size=64, 1-frame overlap at boundaries)
- Peak RAM scales with chunk_size instead of total frame count:
  OLED 3840×2160: ~18 GB/chunk vs ~137 GB full-video
  LED_Wall 6144×1952: ~24 GB/chunk vs ~200+ GB full-video
- Uses ComfyUI NODE_CLASS_MAPPINGS['RIFE VFI'] via lazy import so load
  order with ComfyUI-Frame-Interpolation is not constrained
- Register node in __init__.py

Made-with: Cursor
2026-03-16 08:39:39 -07:00
Sylvester Meighan bce3daf80e fix(media-stream): avoid double-peak RAM when loading large videos
Replace torch.stack(frames) with a pre-allocated tensor filled in-place.
torch.stack keeps the full frame list alive while allocating a second
equally-sized tensor, doubling peak RAM. The new approach keeps peak at
~1× the output tensor size, allowing 482-frame 4K video to fit within
machine RAM limits.

Made-with: Cursor
2026-03-14 18:13:35 -07:00
Sebastian Monroy 207de4487c fix(worker_consumer): propagate submit failures to retry/DLQ and emit failed status
- raise a dedicated JobSubmissionError when ComfyUI prompt submission fails
- re-raise submission failures in process_message so consume loop does not delete SQS messages
- emit failed status updates on submit-time errors using status_policy.fail_status fallback
- remove failed-status dedupe guard so each retry attempt remains observable
- align parse-error logging with retry behavior ("Message will be retried")
2026-02-17 15:40:02 +00:00
Sebastian Monroy c36846c008 Merge branch 'main' into develop 2026-02-17 12:47:45 +00:00
Sebastian Monroy ab7792c8ed add NilorUserInput_Seed node with robust randomization (#14)
Add NilorUserInput_Seed with sentinel-based randomization, modulo normalization for invalid values, cache-busting via IS_CHANGED, and isolated RNG state to avoid global random pollution.
2026-02-16 15:21:22 +00:00
Sebastian Monroy aa594e80d6 Merge branch 'develop' 2026-01-16 18:15:07 +00:00
Sebastian Monroy 62b71b2978 moved NILOR_WORKFLOW_OS_NORMALIZATION_ENABLED param to config 2026-01-15 22:52:37 +00:00
Sebastian Monroy d266978e49 Merge branch 'main' into develop 2026-01-15 21:46:27 +00:00
Sebastian Monroy 552252b84c worker consumer normalizes incoming workflows based on operating system 2026-01-15 21:17:35 +00:00
Sebastian Monroy 66c66f045f Fix websocket client crash on websockets 15.x by removing read_limit
Nilor-Nodes worker websocket listener was failing with:
TypeError: BaseEventLoop.create_connection() got an unexpected keyword argument 'read_limit'
On Python 3.12 with websockets>=15, passing read_limit to websockets.connect() ends up forwarding it to asyncio’s loop.create_connection(), which doesn’t accept that kwarg.
This change removes the read_limit argument from ComfyUILocalClient.ws_connect() while keeping max_size=None and existing ping settings, restoring websocket connectivity and preventing reconnect exhaustion.
2026-01-13 20:36:41 +00:00
Sebastian Monroy 266fe598c6 tweaks to config.json5 and .env.example 2026-01-07 13:00:46 +00:00
Sebastian Monroy ef20c72aff Merge branch 'develop' 2025-12-15 18:42:41 +00:00
Sebastian Monroy 527e8dc4ab 663 implement comfyui memory guardian to prevent oom errors (#12)
* feat(config): add Memory Hygiene config scaffolding and defaults for nilor-nodes

- introduce MemoryHygieneConfig and wire into NilorNodesConfig
- parse NILOR_MEMORY_HYGIENE_* from JSON5 and apply env overrides
- add validation for thresholds, policy, cooldowns, retries, and durations
- extend config.json5 with sane Memory Guardian defaults
- update .env.example

* feat(client): add ComfyUI capability detection and supports_hygiene cache

- add one-time probe for /system_stats and /free, cached per session
- expose supports_hygiene() that logs a single warning when unsupported
- use short timeouts and no retries; mark false only on 404/405
- leave transient failures retryable by keeping capability as unknown

* feat(memory): add MemoryHygiene module with typed skeleton and API

- introduce RemediationAction and RemediationResult dataclass
- add MemoryHygiene class with DI for client/config/logger
- implement check_and_remediate skeleton with enablement/capability checks
- add safe stats helper; defer policy/remediation to later commits
- export public symbols via all

* feat(memory): add metrics collector with usage pct and vram_total

- extend SystemStats with vram_total and parse from /system_stats
- add DerivedStats and collect_metrics() computing vram/ram used pct (0–100)
- integrate metrics collection in check_and_remediate skeleton
- safe math with clamping and None handling for incomplete stats

* feat(memory): implement policy engine thresholds, cooldown, and action selection

- add cooldown handling and respect it in check_and_remediate
- detect pressure via percent or absolute MB thresholds for vram/ram
- normalize policy and choose staged initial action (auto => free)
- return actionable RemediationResult with reason; no remediation yet
- helper functions for conversions and comparisons

* feat(memory): add remediation loop with retries, time caps, and cooldown

- implement remediate_cycle with free/unload flags and staged auto escalation
- respect MAX_RETRIES, SLEEP_BETWEEN_ATTEMPTS_SECONDS, MAX_CYCLE_DURATION_SECONDS
- set cooldown after cycle; return after-stats, attempts, action, and outcome reason
- integrate cycle into check_and_remediate; keep helpers in module

* feat(worker): wire MemoryHygiene into idle and post-completion paths

- initialize MemoryHygiene with comfy client and config in consume_jobs
- run hygiene before polling when idle and after prompt finalize with 1s debounce
- guard remediation by setting is_busy to block new intake; reset after
- keep websocket listener unaffected; schedule post-completion hygiene as background task

* feat(worker): throttle hygiene checks and add cadence tracking

- throttle idle hygiene by cfg.hygiene.idle_poll_seconds using monotonic clock
- add last_hygiene_check_ts to avoid overly frequent checks
- keep is_busy gating and post-completion debounce execution

* chore(memory): add structured logs for decisions and remediation

- log disabled/unsupported/cooldown/no-pressure branches
- log start/end of remediation cycles with before/after VRAM/RAM stats
- log each /free invocation flags; guard logging to avoid exceptions

* fix(memory): harden hygiene with session disable and single-warning on unsupported

- add _capability_disabled to short-circuit future runs after unsupported endpoints
- emit a single warning then quietly skip further cycles for the session
- preserve existing retry/backoff/cooldown and safe exception handling

* .env.example update

* improved get_system_stats and added more logging

* improve logging formatting for comfyui_client and memory_hygiene

* feat(nilor-nodes): add startup hygiene summary log; convert hygiene lambda to class method

- add WorkerConsumer._run_memory_hygiene() async method; remove late-bound lambda injection
- delegate to guarded helper to respect busy gate and optional debounce
- emit startup hygiene summary with effective thresholds from _CFG.hygiene
  (enabled, idle_poll_s, vram/ram pct caps, min_free_mb, policy, retries, cooldown,
  sleep_between, max_cycle)
- keep existing call sites in consume_loop() and _finalize_prompt() using the new method
- no functional changes to remediation logic; new log improves observability at boot

* got rid of redundant .env loading in worker_consumer

* chore(config): simplify global config caching

- keep process-wide _CONFIG singleton for shared configuration instance
- no functional behavior change to config loading paths

* fixed valueerror logging in media_stream
2025-10-20 13:56:38 +01:00
Sebastian Monroy 5d05aeaf68 added a concise startup config log in worker_consumer.py 2025-10-16 20:56:06 +01:00
Sebastian Monroy 5668e09a79 removed legacy code that only existed for controlling rollout, idc bout dat 2025-10-16 20:51:03 +01:00
Sebastian Monroy a94c1a9d60 update .env.example and config.json5 2025-10-16 20:39:33 +01:00
Sebastian Monroy 675fce6a16 update logger to use NILOR_LOG_LEVEL instead of LOG_LEVEL 2025-10-16 20:39:22 +01:00
Sebastian Monroy c1f5eb352c update .env.example 2025-10-16 20:00:28 +01:00
Sebastian Monroy 0f22deb027 fixed config.json5 2025-10-16 20:00:21 +01:00
Sebastian Monroy 58ff7a0bce chore(flag): simplify websocket path to client iterator only
- use client.ws_connect exclusively; if disabled/not constructed, sleep and retry
- keep event parsing semantics and state transitions unchanged
- retain HTTP fallback gating; WS path now simplified for maintainability
2025-10-16 19:45:41 +01:00
Sebastian Monroy c33b06a092 refactor(worker/ws): consume websocket events via ComfyUILocalClient iterator
- replace manual websockets.connect loop with client.ws_connect iterator
- preserve parsing/side-effects for status/progress/executed/executing/success/error
- keep busy state, prompt_id mapping, and finalize logic unchanged
- rely on client’s bounded reconnect; log and retry on unexpected errors
2025-10-16 19:28:24 +01:00
Sebastian Monroy d5109ae0b3 refactor(worker): use ComfyUILocalClient for prompt submission
- import ComfyUILocalClient and ComfyUIClientError into worker
- construct a shared ComfyUILocalClient with the shared aiohttp session on startup
- replace direct POST to /prompt with client.submit_prompt(payload)
- preserve client_id injection, prompt_id mapping, and busy/current state updates
- catch ComfyUIClientError in submission error handling alongside aiohttp errors
2025-10-16 19:25:07 +01:00
Sebastian Monroy 63b44ebff4 chore(config): add NILOR_COMFY_* settings and surface via typed config
- create config.json5 with client enable flag, HTTP retry, and WS reconnect defaults
- extend ComfyApiConfig to include client_enabled, retry, and websocket policy fields
- update loader to parse new keys and honor env overrides (env > file)
- add validations for backoff and reconnect parameters; keep existing fields unchanged
2025-10-16 19:20:39 +01:00
Sebastian Monroy 3476fbfbf9 feat(client/lifecycle): add session ownership, context mgmt, and health probe
- implement context-managed internal session (create/close when no external session)
- update HTTP calls to reuse owned session when available
- add async probe() with short timeout and no retries for /system_stats
- extend client protocol to include probe(); keep cooperative cancellation semantics
2025-10-16 19:18:16 +01:00
Sebastian Monroy aafaf87d18 feat(client/ws): add websocket connect with bounded reconnection and events
- implement ws_connect(client_id) using websockets with large-frame defaults
- add bounded reconnection (max 5 attempts, capped 30s total backoff) with jitter
- map websocket errors to ComfyUIClientWsClosed/ComfyUIClientError per plan
- yield parsed JSON events as WsEvent; wrap non-JSON as text/binary events
- add ws policy fields to client; keep cancellation propagation intact
2025-10-16 19:15:28 +01:00
Sebastian Monroy 790a3ce38e feat(client/http): add HTTP methods with idempotent retries and error mapping
- implement submit_prompt, get_system_stats, and free in ComfyUI client
- add exponential backoff + jitter for idempotent routes; no retry for /prompt
- normalize errors to ComfyUIClientError family with safe response snippets
- validate prompt_id contract and tolerant parsing of SystemStats fields
- create ephemeral sessions when no external session is provided (lifecycle later)
2025-10-16 19:12:26 +01:00
Sebastian Monroy 114a3d661f feat(client): scaffold ComfyUI thin client protocol, DTOs, and exceptions
- add `comfyui_client.py` with `ComfyUIClientProtocol` and `ComfyUILocalClient` constructor
- define DTOs: `SystemStats` and `WsEvent` with typed fields and docstrings
- add exception hierarchy: `ComfyUIClientError`, `ComfyUIClientTimeout`, `ComfyUIClientWsClosed`
- leave protocol methods unimplemented (raise NotImplementedError); behavior to follow in next commits
- export public surface via __all__; keep imports lightweight and typing-friendly
2025-10-16 19:07:25 +01:00
Sebastian Monroy b6bf6c1b6c update .env.example 2025-10-16 18:25:19 +01:00
Sebastian Monroy 3c0bf2222c fix crash from mutating fields on frozen dataclasses during env overrides 2025-10-16 18:06:19 +01:00
Sebastian Monroy ff0c7f1209 feat(nilor-nodes-config): add NILOR_SQS_ENABLED and wire into startup gate
- add NILOR_SQS_ENABLED to config.json5 with default false
- extend NilorNodesConfig with sqs_enabled; apply env override when allowed
- update __init__.py to gate worker startup via cfg.sqs_enabled instead of raw env
2025-10-16 17:52:19 +01:00
Sebastian Monroy 75a632b2e5 refactor(nilor-nodes): drop redundant dotenv loading in media_stream 2025-10-16 17:46:25 +01:00
Sebastian Monroy 2f707ebc48 docs(nilor-nodes): document configuration precedence and runtime usage in README
- add README section describing env>JSON5 precedence and no hot-reload model
- show pseudocode with load_nilor_nodes_config and typed fields used by components
- note integrations in worker_consumer and media_stream utilizing the loader
2025-10-16 17:43:03 +01:00
Sebastian Monroy 14862c1712 chore(nilor-nodes-config): finalize JSON5 defaults and document key consumers
- annotate config.json5 keys with consuming modules and usage patterns
- clarify Comfy HTTP/WS suffixes and SQS usage across worker and media_stream
- state that AWS secret must come from .env; keep allow_env_override true
2025-10-16 17:41:37 +01:00
Sebastian Monroy 7320a15d08 refactor(nilor-nodes): remove os.getenv usage in media_stream in favor of config
- load shared NilorNodesConfig in media_stream and use cfg.worker for SQS client
- replace endpoint/credentials/region env reads with typed config fields
- keep logger LOG_LEVEL and package SQS_ENABLED gate unchanged by design
2025-10-16 17:39:18 +01:00
Sebastian Monroy 4a56d4dff5 feat(nilor-nodes): integrate typed config loader into worker_consumer
- load Config once with env>JSON5 precedence and pass cfg into WorkerConsumer
- replace direct os.getenv reads with cfg.comfy and cfg.worker values
- compute Comfy HTTP/WS endpoints from cfg and reuse single aiohttp session
- keep behavior identical; no new features introduced
2025-10-16 17:36:42 +01:00
Sebastian Monroy 5e579b1aed feat(nilor-nodes-config): implement loader merge, compat mapping, and validation
- implement Config.load with env>JSON5 precedence and JSON5 reading
- add typed parsing into dataclasses
- validate URL schemes, timeouts, poll wait bounds, and positive integers
- auto-generate NILOR_WORKER_CLIENT_ID from hostname with base36 suffix
2025-10-16 17:07:27 +01:00
Sebastian Monroy 9883728f55 feat(nilor-nodes-config): add JSON5 defaults and typed config scaffolding
- add config/config.json5 with non-secret defaults and allow_env_override flag
- introduce config/config.py with ComfyApiConfig, WorkerConfig, NilorNodesConfig
- define Config.load(env, json5_path) API; implementation deferred to next commit
- add types.py with ConfigSource enum for future integration
- add json5 to requirements.txt
2025-10-16 17:00:12 +01:00
Sebastian Monroy bfba7b0265 fix(nilor-nodes): prevent ComfyUI websocket 1009 disconnects by allowing large frames
- Accept large preview frames from ComfyUI without dropping the socket.
- Binary preview frames are still ignored by the consumer; this change stops the
  connection from closing with code 1009 (message too big).
- Impact: keeps workers from getting stuck "busy" and allows long video job
  queues to finish reliably.

Notes:
- To reduce bandwidth instead of disabling client handling, start ComfyUI with
  --preview-method none or a smaller --preview-size.
2025-10-16 11:40:36 +01:00
Sebastian Monroy a093a51291 hide "job_type" input of MediaStreamOutput node 2025-10-14 15:06:27 +01:00
Sebastian Monroy 848899298c update the worker consumer to poll jobs_to_process-comfyui and include job_type data 2025-10-14 14:57:19 +01:00
Sebastian Monroy 2333a0d45d refactor worker_consumer to never allow the consumption of other jobs while a job is already running. implemented robust prompt completion detection. reduced console noise. 2025-10-08 19:23:51 +01:00
Sebastian Monroy 87b846069e remove logging import in nilornodes.py 2025-10-08 15:33:44 +01:00
Sebastian Monroy 6d17e664bb added handling for ClientError in worker_consumer 2025-10-08 15:32:46 +01:00
Sebastian Monroy c541bc18dd commented out .env.example params that fall-back to same value already by default 2025-10-08 15:32:24 +01:00
Sebastian Monroy 7beda857c8 added SQS_POLL_WAIT_TIME to .env 2025-10-08 15:31:42 +01:00
Sebastian Monroy 4fa9710aea forgot to include in last commit 2025-10-08 15:30:46 +01:00
Sebastian Monroy e8c0d451d9 added logger class 2025-10-08 15:30:09 +01:00
Sebastian Monroy a491e6463c added comfyui-kjnodes prerequisite to README 2025-10-01 17:16:52 +01:00
Sebastian Monroy 5b8184cc33 make mediastreamoutput node have an output pin for the url it uploaded to 2025-10-01 17:15:02 +01:00
Sebastian Monroy 6b2b482b89 tweak log messages for NilorImageResizeV2 node 2025-10-01 15:37:25 +01:00