Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ controlnet_test_*
demo/realtime-img2img/uploads/
.cgw.conf

# Local-only git workflow tooling (cgw scripts, hooks, example — never committed)
scripts/git/
hooks/cc-block-dangerous-git.sh
.githooks/
cgw.conf.example

# Local Claude / session state (per-user, never committed)
.claude/

Expand Down Expand Up @@ -261,3 +267,6 @@ SESSION_LOG.md

# Profiling/audit CSV exports (Nsight summaries, kernel stats — generated artifacts)
audit_reports/

# Quality harness run outputs (generated; goldens/ is committed, outputs/ is not)
tests/quality/outputs/
37 changes: 21 additions & 16 deletions demo/realtime-img2img/app_config.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,52 @@
"""
Application configuration and settings for realtime-img2img
"""
import yaml

import logging
from pathlib import Path

import yaml


def load_controlnet_registry():
"""Load ControlNet registry from config file"""
try:
registry_path = Path(__file__).parent / "controlnet_registry.yaml"
with open(registry_path, 'r') as f:
with open(registry_path, "r") as f:
config_data = yaml.safe_load(f)

# Extract the available_controlnets section
return config_data.get('available_controlnets', {})
return config_data.get("available_controlnets", {})
except Exception as e:
logging.exception(f"load_controlnet_registry: Failed to load ControlNet registry: {e}")
# Fallback to empty registry
return {}


def load_default_settings():
"""Load default settings from YAML config file"""
try:
registry_path = Path(__file__).parent / "controlnet_registry.yaml"
with open(registry_path, 'r') as f:
with open(registry_path, "r") as f:
config_data = yaml.safe_load(f)
return config_data.get('defaults', {})

return config_data.get("defaults", {})
except Exception as e:
logging.exception(f"load_default_settings: Failed to load default settings: {e}")
# Fallback to hardcoded defaults
return {
'guidance_scale': 1.1,
'delta': 0.7,
'num_inference_steps': 50,
'seed': 2,
't_index_list': [35, 45],
'ipadapter_scale': 1.0,
'normalize_prompt_weights': True,
'normalize_seed_weights': True,
'prompt': "Portrait of The Joker halloween costume, face painting, with , glare pose, detailed, intricate, full of colour, cinematic lighting, trending on artstation, 8k, hyperrealistic, focused, extreme details, unreal engine 5 cinematic, masterpiece"
"guidance_scale": 1.1,
"delta": 0.7,
"num_inference_steps": 50,
"seed": 2,
"t_index_list": [35, 45],
"ipadapter_scale": 1.0,
"normalize_prompt_weights": True,
"normalize_seed_weights": True,
"prompt": "Portrait of The Joker halloween costume, face painting, with , glare pose, detailed, intricate, full of colour, cinematic lighting, trending on artstation, 8k, hyperrealistic, focused, extreme details, unreal engine 5 cinematic, masterpiece",
}


# Load configuration at module level
AVAILABLE_CONTROLNETS = load_controlnet_registry()
DEFAULT_SETTINGS = load_default_settings()
6 changes: 2 additions & 4 deletions demo/realtime-img2img/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import NamedTuple
import argparse
import os
from typing import NamedTuple


class Args(NamedTuple):
Expand Down Expand Up @@ -45,9 +45,7 @@ def pretty_print(self):
parser.add_argument("--host", type=str, default=default_host, help="Host address")
parser.add_argument("--port", type=int, default=default_port, help="Port number")
parser.add_argument("--reload", action="store_true", help="Reload code on change")
parser.add_argument(
"--mode", type=str, default=default_mode, help="App Inferece Mode: txt2img, img2img"
)
parser.add_argument("--mode", type=str, default=default_mode, help="App Inferece Mode: txt2img, img2img")
parser.add_argument(
"--max-queue-size",
dest="max_queue_size",
Expand Down
14 changes: 7 additions & 7 deletions demo/realtime-img2img/connection_manager.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import asyncio
import logging
from types import SimpleNamespace
from typing import Dict, Union
from uuid import UUID
import asyncio

from fastapi import WebSocket
from starlette.websockets import WebSocketState
import logging
from types import SimpleNamespace


Connections = Dict[UUID, Dict[str, Union[WebSocket, asyncio.Queue]]]

Expand All @@ -20,9 +22,7 @@ def __init__(self):
self.active_connections: Connections = {}
self.latest_data: Dict[UUID, SimpleNamespace] = {} # Store latest parameters for HTTP streaming

async def connect(
self, user_id: UUID, websocket: WebSocket, max_queue_size: int = 0
):
async def connect(self, user_id: UUID, websocket: WebSocket, max_queue_size: int = 0):
await websocket.accept()
user_count = self.get_user_count()
print(f"User count: {user_count}")
Expand Down Expand Up @@ -61,7 +61,7 @@ async def get_latest_data(self, user_id: UUID) -> SimpleNamespace:
return await queue.get()
except asyncio.QueueEmpty:
return None

def get_latest_data_sync(self, user_id: UUID) -> SimpleNamespace:
"""Get the latest data without consuming it from the queue (for HTTP streaming)"""
return self.latest_data.get(user_id)
Expand Down
Loading