CodeVetter · Repo Unpack · Behavior traces
AUTOMATIC1111/stable-diffusion-webui
Three flows were traced end-to-end. Startup is a two-stage boot: launch.py environment prep, then webui.py UI/API bring-up with a restartable inner loop. txt2img generation flows UI/API → processing dataclass → script-runner hooks → sampler → VAE decode → save. Extension install flows Extensions tab → git clone → arbitrary install.py execution → rescan.
- STARTUP (shell): webui.sh sources webui-user.sh (and webui-macos-env.sh on darwin), creates/activates venv unless venv_dir='-', then execs 'python launch.py'; launch.main() → launch_utils.prepare_environment() → (pip installs, git clones, run_extensions_installers runs each extension's install.py) → start() → import webui → webui.webui().
- STARTUP (python): webui.webui() → initialize.initialize() → initialize_util fixups → sd_models.setup_model() → codeformer_model.setup_model/gfpgan_model.setup_model → initialize_rest(): sd_samplers.set_samplers → extensions.list_extensions → restore_config_state_file → sd_models.list_models → localization.list_localizations → scripts.load_scripts (exec_modules every scripts/*.py and extension scripts) → modelloader.load_upscalers → sd_vae.refresh_vae_list → sd_hijack.list_optimizers → sd_unet.list_unets → background Thread(load_model) → ui_extra_networks.initialize/register_default_pages → extra_networks.register_default_extra_networks.
- STARTUP (server): ui.create_ui() builds all gr.Blocks → shared.demo.queue(64) → demo.launch(server_name/port/share/auth/tls/subpath) → CORS middleware stripped (app.user_middleware filtered to remove CORSMiddleware, comment cites RyotaK attack) → initialize_util.setup_middleware → progress.setup_progress_api → ui.setup_ui_api → create_api(app) if --api → ui_extra_networks.add_pages_to_demo → app_started_callback → wait_for_server_command loop.
- TXT2IMG (UI): Generate button → wrap_gradio_gpu_call (acquires queue_lock, state.begin, progress.start_task) → txt2img() → txt2img_create_processing() → p.scripts.run (returns None if no selectable script) → processing.process_images(p) → processed.js() returned to gallery/HTML outputs; errors are caught into an HTML error div by wrap_gradio_call.
- TXT2IMG (inner): process_images() → scripts.before_process → apply override_settings → process_images_inner() → p.init(all_prompts,seeds,subseeds) → loop n_iter: before_process_batch → parse_extra_network_prompts → extra_networks.activate → process_batch → setup_conds → write params.txt (n==0) → p.sample() [Txt2Img: sampler.sample → optional sample_hr_pass for hires fix] → post_sample → decode_latent_batch → postprocess_batch/postprocess_batch_list → per-image postprocess_image → save_image → image_grid → postprocess → Processed.
- IMG2IMG/INPAINT: img2img() collects init_images/mask/sketch from the six sub-tabs → StableDiffusionProcessingImg2Img.init() encodes init image to latent (latent_image), builds mask (image_mask/inpainting conditioning), p.sample() runs sampler at denoising_strength with img2img_fix_steps; on_mask_blend/postprocess_maskoverlay hooks fire for inpaint compositing before save.
- API GENERATION: POST /sdapi/v1/txt2img → Api.text2imgapi (behind Depends(self.auth) if --api-auth) → apply_infotext fills unset request fields → get_selectable_script resolves script_name → validate_sampler_name → init_script_args builds flat args (index 0 = selectable script idx+1) → with queue_lock: StableDiffusionProcessingTxt2Img(**args) → p.scripts.run or process_images → base64 images + info JSON in TextToImageResponse.
- EXTENSION INSTALL: Extensions tab → install_extension_from_url(dirname,url) → check_access() asserts not cmd_opts.disable_extension_access → git.Repo.clone_from(url, tmpdir, filter=['blob:none']) + submodule.update → os.rename/shutil.move to extensions_dir → launch.run_extension_installer executes the extension's install.py → extensions.list_extensions() rescans; apply_and_restart triggers restart_program/stop_program.
- SETTINGS WRITE: UI settings component change → shared.opts.<key> = value → Options.__setattr__ validates against freeze-settings flags, restricted component_args, frozen sections/keys → data[key]=value → onchange callbacks via opts.set() → opts.save(config_filename) writes config.json; at boot Options.load() runs version migrations (sd_vae_as_default→sd_vae_overrides_per_model_preferences, quicksettings→quicksettings_list, ui_reorder→ui_reorder_list).
- MODEL RELOAD: override_settings.sd_model_checkpoint or /sdapi/v1/reload-checkpoint → sd_models.reload_model_weights → get_checkpoint_state_dict (safetensors.load_file or monkeypatched torch.load via safe.load) → send_model_to_trash old model → load_model_weights → LoadStateDictOnMeta streams weights → send_model_to_device → model_hijack.hijack + embedding_db.load_textual_inversion_embeddings(force_reload).