Project operating instructions for AI assistants working in this repository.
- At the start of each new task or thread involving this repository, read this file before inspecting files, running commands, making a plan, or taking any other project action.
- Treat follow-up replies in the same continuous task as part of that task. Do not reread this file unless the repository or working directory changes, this file is modified, or its instructions are no longer available in context.
- Treat this file as the shared project memory for AI assistants.
- Do not rely on vendor-specific, proprietary, or hidden memory systems for project facts, preferences, or operating instructions. (except to remember to ALWAYS read this file first before doing anything. Remember that.)
- Update this file with important repo-specific information learned during work, including build commands, test commands, conventions, decisions, pitfalls, and current project preferences.
- Keep this file accurate and current. Remove or correct stale, misleading, or incorrect information when discovered.
- If information is temporary or uncertain, label it clearly rather than presenting it as permanent fact.
Scope policy: this file holds cross-cutting rules, workflows, and gotchas that most sessions need, plus a feature index. Keep it around 30 KB. Feature deep-dives live in docs/<topic>.md (aichat.md, automation_bridge.md, llm_providers.md, media_import.md, settings.md, workflows.md, minimax_h3.md, web_media.md, audio_generation.md): before working on a feature listed in the index, read its doc; when finishing feature work, update that doc and keep the index entry here to one or two lines (where it lives + the non-obvious constraint). Cross-cutting rules and new gotchas still land here directly. When a change makes anything stale, here or in a linked doc, update it in the same change.
- When possible, design automated tests for new features and bug fixes.
- Run relevant automated tests after finishing changes to guard against regressions.
- If tests cannot be run or do not exist, state that clearly in the handoff and describe any manual verification performed.
- Never commit sensitive data, including credentials, tokens, passwords, private keys, cookies, customer data, personal data, or machine-specific authentication material.
- If an AI assistant needs authentication data or other secrets for local work, use
agents_secret.mdfor those notes. agents_secret.mdmust stay ignored by git and must not be committed.aichat/skills/local_*.mdis gitignored on purpose: AI Chat skill files that describe a machine-local generation server (thegenerate_music/generate_sfx/generate_speechprompting rules and voice list for the audio gateway). Keep server-specific skill text there; the generic code, Settings fields, anddocs/audio_generation.mdare what the repo ships.BuildWin64.batdeletesbuild\win\aichat\skills\local_*.mdbefore zipping (added 2026-09-13 after the 3.06 zip shipped them;UpdateBuildDirConfigFiles.batcopies the wholeaichatfolder).- Server- and machine-specific facts are local-only too, not just credentials: hostnames, ports, GPU/cluster layout, SSH targets, server-side file paths, restart/launcher scripts, and which servers have which models installed. Keep them in
agents_secret.md, never in tracked files (AGENTS.md, docs/, READMEs, code comments, workflow JSON). Tracked docs must stay generic ("the ComfyUI server", "the wedged instance") - other people don't have this hardware. Example hostnames in docs use placeholders likegpu-box.lan. - Do not put secrets in commit messages, logs, issue text, pull request descriptions, generated docs, or other tracked files.
- Before committing, review staged changes for accidental secrets.
- Never add OpenAI/Codex/Claude etc as a co-author on git commits.
- Committing locally is allowed and expected (Seth, 2026-09-13): commit each self-contained change once it compiles, one logical change per commit with a descriptive message, instead of one big mixed commit that is hard to follow. Never commit secrets or the ignored local files (see Security).
- NEVER
git push(and do notgit pull) unless explicitly told to. "Commit" means commit locally only; committing is never permission to push.
Update this file when a change touches any of:
- Build/run commands, build scripts, or what they copy/produce (the "Essential Commands" section).
- App version, Unity version, main scene, or other "Current local facts".
- Architecture: renamed/added/removed core scripts, renderers (
RTRendererType), LLM providers (LLMProvider), job-script directives/placeholders, AI Chat flow, automation control endpoints, or experiment folders. - Hard rules, directory layout, or CLI capabilities/limits.
When the user asks to commit, or when you finish a task, do a quick self-check: "did anything I changed make a statement in AGENTS.md wrong?" If yes, fix it here (and keep CLAUDE.md consistent). If you are unsure whether a fact is still true, verify against the code rather than copying the old claim forward. Keep edits concise and factual - this file is read at the start of every task, so brevity matters.
Seth's AI Tools is a Unity 6 Windows application that provides a native front-end for ComfyUI workflows, image/video generation, LLM-assisted workflows, AI chat, and several interactive experiments.
Current local facts:
- Unity editor version:
6000.6.0f1(ProjectSettings/ProjectVersion.txt) - App version in code/version metadata:
3.06 - Main scene:
Assets/Main.unity - Primary platform: Windows desktop; a limited Python CLI (Windows + Linux) also exists under
cli/
When the user says "bump the version", update ALL of these in the same task (do not stop after the code change):
Assets/_Script/Config.cs-m_versionfloat (e.g.3.02f).latest_version_checker.json(repo root) -latest_versionnumber.- This file's "App version in code/version metadata" line above.
README.md- the# Downloadline (version number, date, and the zip size in MB) AND add a new### V<x.yz> (<date>)entry at the top of## Recent changessummarizing what changed since the last release (derive it fromgit log <last-version-bump>..HEAD).
Use the current date for README date strings. The download zip size changes per build; check the freshly built SethsAIToolsWindows.zip size and match it.
- Never push to or pull from git without explicit user directions. Local commits are allowed and expected (see "Git").
- Do not read or edit files starting with
test_,Test_, orTEST_unless the user explicitly names them or asks to work with test files. - Treat ignored config and debug files as local/private unless the user explicitly asks for them. This includes
config.txt,config_llm.txt,config_preferences.txt,log.txt, generated*_json_*files,comfyui_workflow_to_send_api.json, and cached ComfyUI API files. - Do not revert unrelated work. This repo may already contain user edits in many files.
- Writing style: no em-dashes or en-dashes used as em-dashes in any prose (this file, docs, skill/prompt text, commit messages, chat replies). Use a colon, a comma, parentheses, a spaced hyphen (the house style here), or two sentences. Seth's standing rule; the prose files were swept clean on 2026-08-31.
- Keep this file current: if a change you make invalidates anything documented here, update AGENTS.md in the same task (see "Keeping this file current").
BuildWin64.batBuilds the Windows release. It calls app_info_setup.bat, deletes/recreates build/win, invokes Unity with Win64Builder.BuildRelease and Assets/Settings/Build Profiles/ReleaseBuildProfile.asset, copies runtime folders with UpdateBuildDirConfigFiles.bat, signs binaries, and creates SethsAIToolsWindows.zip.
Build timestamps are stamped automatically by Assets/RT/Editor/BuildTimestampWriter.cs (IPreprocessBuildWithReport), which writes Assets/Resources/build_date.txt (gitignored, folder auto-created) at the start of every player build regardless of build path (editor Build menu, Build Profiles window, batchmode). RTBuildInfo.Timestamp loads it at runtime and falls back to the current time in the editor. There is no GenerateBuildDate.bat anymore.
UpdateBuildDirConfigFiles.batUpdateBuildDirConfigFiles.bat copies utils, web, Adventure, AIGuide, ComfyUI, Presets, aichat, and local config files into build/win. utils includes runtime helper EXEs such as RTClip and the bundled FFmpeg/ffprobe helpers under utils/ffmpeg/bin/; those third-party FFmpeg binaries are copied as data and are not signed by the build scripts.
AI-harness note for running BuildWin64.bat from a tool shell: run it from the repo root, clear NoDefaultCurrentDirectoryInExePath first (Claude Code sets it to 1, which makes cmd's bare call app_info_setup.bat lines fail with "not recognized" even in the right directory), set NO_PAUSE=1 so the final pause doesn't hang a background run, and disable sandboxing (the script needs the parent-folder ..\base_setup.bat, registry queries to find Unity, and the %RT_UTIL% / %RT_PROJECTS% tool folders; local specifics live in agents_secret.md). Working invocation from PowerShell in the repo root: Remove-Item Env:\NoDefaultCurrentDirectoryInExePath; $env:NO_PAUSE='1'; cmd /c .\BuildWin64.bat. On failure the script pops notepad with log.txt and pauses; check build\win\aitools_client.exe exists to confirm success. Do not run it while the editor automation bridge is active (a second Unity instance fights the project lock).
There is no current root BuildWebGL.bat. WebGL build support is present in Assets/RT/Editor/WebGLBuilder.cs, and upload scripts exist (UploadWebGLRSync*.bat), but do not document or call a missing WebGL build script unless it is reintroduced.
For editor development, open Assets/Main.unity in Unity and enter Play mode.
For the Python CLI subset:
python cli/aitools_cli.py "<prompt>" output.png -p "Prompt To Image (Z-Image)"On Windows, use cli\aitools_cli.bat instead - the first run creates cli\venv\ and installs dependencies automatically.
The CLI uses cli/config.txt, ../ComfyUI, and ../Presets. Dependencies are requests, websocket-client, and Pillow (cli/requirements.txt). See cli/README.md before changing CLI behavior.
AI agents (Claude, Codex, etc.) can and should use this CLI themselves - on Windows or Linux - to generate images and verify workflow/preset changes end-to-end against the user's ComfyUI servers, e.g.:
cli\aitools_cli.bat "a cat" out.png -p "Prompt To Image (Z-Image)" -v
cli\aitools_cli.bat "make the sky red" out.png -p "Image To Image Klein Edit 1 Input" -i input.png
cli\aitools_cli.bat "she waves and says hi" out.mp4 -p "Image To Video (MiniMax H3) 5s" -i start.png --duration 8
cli\aitools_cli.bat "<Picture 1> dances like <Video 1>" out.mp4 -p "Reference Video To Video (MiniMax H3) 5s" --video clip.mp4 -i face.png
cli\aitools_cli.bat "test" out.mp4 -p "Prompt To Video (MiniMax H3) 5s" --width 1152 --height 640 --dry-runText-to-image, single-step image presets, and all four MiniMax H3 movie modes work (t2v / i2v start frame / reference photos / reference video+photos). Repeatable -i/--video/--audio reference inputs, --width/--height/--duration (H3 grid-snapped, unclamped), start-frame aspect auto-fit, ffprobe silent-clip pruning, @upload|...|optional| slot pruning, per-run AITOOLS_UNIQUE_ID substitution, --dry-run (writes <output>.api.json with zero server contact: use it to validate preset/workflow changes offline) and the --alpha-key/--alpha-from-luma/--sprite-sheet VFX post-processing are all documented in cli/README.md ("Generating movies (MiniMax H3)", "Transparent-background movies", "Preset support"). Multi-step chains and LLM presets error out by design.
Assets/_Script/GameLogic.csis the central UI/state coordinator. It owns prompts, negative prompts, generation parameters, selected renderer, preset/job-list text, temp image slots, global variables, and normal vs experiment mode.Assets/_Script/Config.csloadsconfig.txtandconfig_cam.txt, managesGPUInfoserver entries, renderer selection, server busy state, per-server overrides, and the generated top-right server status rows.Assets/_Script/ImageGenerator.csowns the global generation loop, GPU event queues, server selection, continuous generation, and throttling when job scripts start with LLM work before GPU work.Assets/_Script/GUI/AppSettingsPanel.csis the unified Settings window (General, ComfyUI Settings =AppSettingsTab.Configuration, Audio, Web; the "LLM Settings" tab is a launcher that opens the standaloneLLMSettingsPaneldialog). Its tabs write the modern subset ofconfig.txtthroughConfig.BuildModernConfigText, which REGENERATES the whole file: every parsedset_*/add_serverkey must be re-emitted there or Settings Apply wipes it (the Brave, STT and audio-gateway keys included). Tabs, keys, server priority order, forced reconnect and the compact/manual Tools panel controller:docs/settings.md.Assets/_Script/PresetManager.csreads and writesPresets/*.txtfiles usingCOMMAND_START|...COMMAND_ENDblocks andCOMMAND_SET|...lines.Assets/_Script/VariableManager.csimplements%variable%substitution for job scripts. Variables are local to aPicMainunless prefixed withglobal_.
Assets/_Script/Pic/PicMain.csis the main per-image controller. It stores textures, masks, temp images, job queues, job history, undo state, LLM manager references, and the job-script interpreter.Assets/_Script/Pic/PicTextToImage.csloads ComfyUI workflow JSON, calls the ComfyUI workflow-to-API converter when needed, writes cached API JSON, applies@replaceand placeholder substitution, sends/prompt, tracks progress, and writes debug JSON on errors.- Every post-submit failure path in
PicTextToImagemust end inFinishUpEverything(false)and go throughPicMain.ReportRenderFailure(frees the GPU, clearsm_waitingForPicJob, tells the AI Chat model); while/historyis empty the poll probes/queueand gives up on a lost job; a multi-input job line pins its ComfyUI server (m_uploadPinnedServerID) from the first upload throughrun_workflow. Details and history:docs/workflows.md. Assets/_Script/Pic/PicGenerator.cshandles continuous img2img/inpaint generation from an existing pic.- Other
Pic/*components are focused tools: mask editing, inpaint, upscale, interrogation, movie display, text-to-image status, info panels, size/menu nav, and target rectangles.
RTRendererType currently includes:
ComfyUI- legacy/compatibility values:
Any_Local,A1111,AI_Tools,AI_Tools_or_A1111
The renderer dropdown currently exposes only ComfyUI. The legacy API image renderer path was removed; OpenAI LLM support is separate and still lives under the LLM provider stack. A1111 and AI Tools server support are legacy compatibility paths, not active primary targets.
ComfyUI servers must be reachable over HTTP and should be started with --listen or equivalent network binding. Current workflows are normal ComfyUI workflows in ComfyUI/; API-format cached files are generated beside them as *_cached_api_version.json.
- Bundled helper EXEs, copied with
utilsbyUpdateBuildDirConfigFiles.batand not signed:utils/RTClip.*(clipboard image/file helper; source inutils/RTClip.zip, withAssets/RT/RTClipboardFileList.csreading real clipboard file lists in-process),utils/yt-dlp/yt-dlp.exe(behindweb_video,docs/web_media.md) andutils/ffmpeg/bin/ffmpeg.exe+ffprobe.exe(GPL v3 with libx264: keeputils/ffmpeg/NOTICE.txtandlicenses/beside them). Clipboard paste (Ctrl+V in the workspace and in AI Chat) accepts files and videos, not just bitmaps.FfmpegTool,PicMovieand the Media Foundation seek/playback rules (verify withPOST /movie_state, never screenshots), preview proxies, clip import and the clip chooser:docs/media_import.md.
ComfyUI/*.jsoncontains the workflow files used by the app. There is no currentComfyUI/FullWorkflowVersions/folder.Presets/*.txtcontains job scripts and default prompt settings. AutoPic presets are namedAutoPic*.txtand are used by Adventure/AI-assisted flows.- Placeholders
<AITOOLS_PROMPT>,<AITOOLS_NEGATIVE_PROMPT>,<AITOOLS_AUDIO_PROMPT>,<AITOOLS_SEGMENTATION_PROMPT>,<AITOOLS_INPUT_1..14>(PicJob.MAX_INPUT_SLOTS),<AITOOLS_PROMPT_1..8>and the per-renderAITOOLS_UNIQUE_IDtoken (put it in save-nodefilename_prefixes so concurrent renders can't collide); directives@replace,@upload(sourcesimage/image1..image10,temp1..3,video/video1,video2,audio1..3, trailing|optional|prunes the loader when the source is missing),@resize,@resize_if_larger,@copy,@add,@set,@setimage,@clear,@fill_mask_if_blank,@invert_alpha,@no_undo,@stopjob,@lock_gpu,@llm_*,@llm_add_image,@parse_llm_prompts,@prune_input;@start/@endblocks; built-in variables such as%video_fps%/%rife_output_fps%. Full reference:docs/workflows.mdandcli/README.md("Preset support", the most complete human-facing list; the rootREADME.mdno longer documents directives). Verify againstPicMain.cswhen behavior matters. - Two pitfalls every preset author must know (mechanism and history in
docs/workflows.md): job-script variables are per-PicMain and SHARED by chained presets, so any preset that can be chained after another needs uniquely prefixed variables (%vid_width%, never%width%, whichPrompt To Image (Z-Image).txtsets to 1024); and host dimension/frame-count overrides target the preset@replace's REPLACEMENT half (raw%var%="N"or the compiledcommand @set|%var%|N|form), so PREFER a preset default equal to the workflow literal. Range-clamping model-supplied numbers is a forbidden gate (see AI Chat). - Model-specific workflow notes (Bernini-R image/video edit,
Video Remove Background (BiRefNet), WAN/RIFE interpolation and therife_videoutility preset):docs/workflows.md. MiniMax H3 (AI Chat's default video route, FL2VA vs Ref2VA reference presets, turbo/cache variants, 9 photo + 2 clip + 3 audio reference slots, the official prompt format minus the<d>dialog markup, costs):docs/minimax_h3.md. Non-obvious constraints: the executor keys H3 reference behavior on preset-name substrings ("Reference Video To Video", "Reference To Video", "Reference To Image"), H3 has no negative-prompt path,duration="N"is UNCLAMPED on every H3 preset (nearest 17k+5 grid), and H3 models may be installed on only some servers (agents_secret.md).
Assets/_Script/LLM/LLMSettingsData.cs,LLMSettingsManager.cs, andLLMInstanceManager.csmanageconfig_llm.txt, active providers, multiple LLM instances, replicas, model lists, context limits, and sampling/reasoning settings.- Per-instance job routing is two orthogonal axes:
jobMode(text-job size only:Any/BigJobsOnly/SmallJobsOnly) plussupportsVision(can accept image jobs) andvisionOnly(reserve for vision - no text). Vision jobs route tovisionOnlyinstances first, then anysupportsVisioninstance. New OpenAI/Anthropic/Gemini instances defaultsupportsVisionon; new llama.cpp/Ollama/OpenAI-compatible instances default it off because local text servers often reject image input unless a real vision model/mmproj is loaded.config_llm.txtcarries aschemaVersion; pre-decoupling configs (where vision was encoded injobModevia the legacyVisionJobsOnly/NonVisionOnlyvalues) are migrated once on load byLLMInstanceManager.MigrateJobModes(). The AI Chat caption sidecar warns in-chat when an image needs vision but no active instance hassupportsVision, and surfaces backend failure details when a marked-vision instance rejects the request. - LLM requests do not impose an optional output-token budget: OpenAI/OpenAI-compatible, llama.cpp, Ollama, and Gemini requests omit their output-limit field, including AI Chat sidecars, PicMain
call_llm, Adventure, and AI Guide. Legacy llama.cpp/Ollamamax_tokens,max_new_tokens,max_output_tokens,max_completion_tokens,n_predict, andnum_predictprovider parameters are ignored. Anthropic's Messages API requiresmax_tokens, so it receives the known per-model maximum. Model context/output ceilings and server-side generation configuration still apply. - AI Chat main turns send
temperatureONLY when the instance's sampling override is ticked (LLM Settings sampling section); otherwise the field is omitted so the server's model default applies, on every provider (Anthropic/Gemini builders takeincludeTemperature, the OpenAI/OpenAI-compatible builder already had it, llama.cpp/Ollama only ever read thetemperatureparm). Until 2026-09-05 AI Chat borrowedAdventureLogic.GetExtractor().Temperature, which is 0 (greedy) until an Adventure config is parsed in the session - so every AI Chat turn ran at temperature 0 unless Adventure had been opened. DeepSeek keeps its model-card values when not overridden; sidecars/one-shots keep their fixed 0.4. AI Guide, Adventure, and PicMaincall_llmkeep their own explicit temperature sources (their config files / job script). LLMProvidercurrently supportsOpenAI,Anthropic,LlamaCpp,Ollama,Gemini, andOpenAICompatible.- Request URL building (
LLMModelNotFound.BuildChatCompletionsUrl/JoinApiPath: never append/v1/chat/completionsto a base that already ends in a version segment), the stale-model auto-switch (LLMModelAutoSwitch, OpenAI Compatible only), the streaming download handlers (stateful UTF-8 decoder, newline-terminated SSE parsing) and the per-family reasoning/thinking wiring (DeepSeek-V4, GLM-5.3, Qwen Flash-Next, the Z.ai / DeepSeek hosted shapes):docs/llm_providers.md. Rules that hold everywhere: resolve thinking throughLLMRequestProfile.ResolveCompatReasoning, never hand-roll per-site ternaries; adding a family = extendIsXxxModel+HasConfigurableReasoningEffort+ the wire mapping inLLMRequestProfile, the branch inOpenAITextCompletionManager.BuildChatCompleteJSON(andTexGenWebUITextCompletionManagerfor llama.cpp), andLLMProviderUI.RebuildReasoningEffortOptions;LLMReasoningEffortis Off/Low/Medium/High/Max ("xhigh" parses to High) and a NEW OpenAI Compatible / llama.cpp instance starts at Off (GLM-5.3 clamps that to Low). model_data.jsonsupplies shipped cloud model lists and default endpoints.Assets/RT/AI/contains provider/runtime managers: OpenAI text, Anthropic text, Gemini text, generic OpenAI-compatible/TextGen WebUI, ComfyUI file upload, speech-to-text, TTS, streaming download handlers, and main-thread dispatch.
Assets/_Script/LLM/AIChatPanel.csbuilds the programmatic chat UI and routes chat requests through the same LLM instance/provider stack.- Deep-dive:
docs/aichat.md(attachments and drops, clip import, Main LLM override, Compact, skill autoload delivery, parser tolerance and deferral, thinking window, extract_still / rife_video / stitch_video, prompt-cache preservation, inspect_image, context menus, thegpu=soft hint, debugging log). Related:docs/web_media.md(the five web_* skills),docs/audio_generation.md(generate_* and set_video_audio),docs/minimax_h3.md(video routing and prompting),docs/media_import.md(clip chooser, playback). - Debugging AI Chat: read
llm_aichat_log.json(working dir; one chronological JSON array ofrequest/response/action/noteevents, truncated per play session) FIRST when a chat output is wrong: it shows exactly which Pic each action targeted and what the model emitted. Provider-agnostic last request/response/error files are split by job size (llm_last_request_sent_big.jsonfor AI Chat / AI Guide / Adventure,..._small.jsonfor sidecars andcall_llm). Details:docs/aichat.md"Debugging". - Prompt-cache invariant: the stable prefix (pre/main/post prompt + skill summaries) must not change mid-conversation and NOTHING may
AddInteraction("system")mid-chat;BuildPromptChatfolds system-role lines into the FRONT message, which invalidates the server-side prompt cache for the whole history (a ~40 s re-prefill on long llama.cpp chats). Volatile state goes in the per-turn CURRENT STATE tail; runtime notes, autoloaded skill bodies and full captions travel in the info-recap tail of the next user message (IChatHost.AddSystemInjectionAndBubble); the only mid-conversation system line is the tagged compact summary. The exact text last sent per history line is cached onGTPChatLineand only a real user edit invalidates it. - Error visibility: real backend/LLM failures on the main turn render as an always-visible red
Errorbubble (AddErrorBubbleinAIChatPanel.cs) and cloud dispatch never silently substitutes a default model; sidecar failures and local notices are debug-gatedInfobubbles ("Show debug stuff"). Every web fetch renders an always-visible "Web" bubble by design, COMPACT since 2026-09-13: title +AppendSummaryLineoutcome lines + status + thumbnails; everything else is the full trace behind the bubble's[details]marker (opens in the floatingChatThinkingWindow, live). New trace lines default to details-only; useAppendSummaryLinefor outcomes the user must see (docs/web_media.md"Trace bubble format"). - Stop:
ShouldStopBeInteractable()inAIChatPanel.csis the single Stop-enable rule (streaming, forced-main wait, inspections and a pending inspect resume, pending auto-resumes, web work, audio generation, a running Compact, parkedstitch_video/set_video_audiosource waits);SetBusyUImust never compute its own, and every state listed has a cancel path inOnStopClicked. Continue turns requested by waits that outlive the reply (stitch, set_video_audio, audio generation) are dropped when a newer turn is current. Known gap: the video-import gate (_videoImportCount: clip imports,set_video_audio) blocks Send but has no Stop path. - Web rules: model
url=values must passWebMediaDownloader.IsAllowedPublicHttpUrl(public http/https only; redirects followed by hand and re-gated; no raw quote/backslash/whitespace because the URL reaches yt-dlp's command line, which gets it after a--terminator); the Brave key lives inconfig.txtand MUST stay emitted byConfig.BuildModernConfigText; the header "Web" checkbox gates all five web skills. Real people and named characters go throughweb_image+ anchors, never rendered from memory; a voice sample in chat is used via the H3audio=reference andref_voicecloning is never offered as an alternative. - Audio: an Audio bubble IS a Movie bubble (
IsChatImageMovieis true for it; code that must tell video from sound checksIChatHost.IsChatImageAudio); the threegenerate_*skills are hidden from the prompt until a gateway URL is configured. - Anchors and refs: a
chat_image*/source_chat_imageanchor name that doesn't resolve aborts the action immediately; chained actions carryinganchor=re-point the registry to the chained Pic; correction notes must namechat_imagenumbers, never attachment indexes; Movie-targetedimage_to_image/image_to_movierequires explicitmovie_frame="true". Assets/_Script/LLM/AIChat/Skills/SkillManager.csloadsaichat/skills/*.mdplus prompt files inaichat/.- Do NOT add new deterministic executor gates that block actions over PROMPT-QUALITY judgments (missing quoted dialog, style rules, etc.) - Seth's explicit rule (2026-08-30): "they just cause pain later". Put such rules in skill text/frontmatter instead. The existing structural gates (reference tag mismatch, movie_frame, web preflight) stay; the bar for new ones is a structural/wiring error, not a prompt-writing one. Range-CLAMPING model-supplied numeric parameters counts as a forbidden gate too (2026-08-31: the H3 duration 124..362 clamp silently blocked 1s clips that render fine); pass values through with only structural math like grid snapping, and beware substring preset-name gates going stale when preset variants are added (the exact-"(MiniMax H3)" match missed the Quality/Turbo Cache names).
- Skill autoload keyword triggers miss real phrasings easily, so routing-critical rules must ALSO appear in each skill's
summary:/template:frontmatter.video_to_videoadditionally has media-aware autoload: when the newest live chat medium is a Movie, deictic scene-edit and speech/audio-edit phrasing loads its full body even without the words video/clip/movie. Movie-targetedimage_to_image/image_to_movierequires explicitmovie_frame="true"; otherwise the executor blocks and auto-continues. Bernini v2v is silent, so generated/replaced dialogue/audio/sound is likewise blocked and redirected to H3 Ref2VA. When AI Chat's preset prefix is active (for exampletest_), unprefixed requested preset names first try the prefixed file and fall back to the bare production file only if no prefixed preset exists. Preset names then resolve case-insensitively, then by unique punctuation/spacing-only canonicalization, before the conservative fuzzy fallback emits a correction bubble. ChatPicMirror.csmirrors generated pics into chat image bubbles so later actions can referencechat_image="N".
A loopback HTTP control server lets external tools (AI agents, scripts) drive the editor and AI Chat for automated end-to-end testing. It survives C# domain reloads and play stop/start, so an external loop can edit code, recompile, and re-test without anyone clicking Play.
Prefer this automation bridge for Unity/editor validation whenever it is enabled. Before launching a separate Unity batch/editor process, check GET /status; if the bridge is ready, use it to compile (/rebuild), drive the app (/play, /stop, /settings, /llm_settings, /open_chat, /chat, /chat_import_video, /click, /scroll, /pic_cancel, ...) and capture evidence (/screenshot, /save, /chat_images, /movie_state, /chat_thinking, /chat_web_trace). For UI/AI Chat work, verify with screenshots whenever possible rather than relying only on code inspection. Do not start a second Unity editor/batchmode instance against this project while the editor lockfile/server is active unless the bridge is unavailable or the task specifically requires batchmode.
If a change cannot be validated because the bridge lacks a needed command, add a narrow loopback-only automation endpoint or driver capability in the same task when practical, then document the new endpoint in docs/automation_bridge.md (and keep the one-line pointer here current). Keep new automation commands deterministic, local-only, and scoped to testing/inspection; avoid broad privileged operations.
- Files:
Assets/_Script/Automation/AutomationBridge.cs(runtime seam shared by editor and play-mode driver),AutomationDriver.cs(runtime MonoBehaviour; self-spawns in standalone builds with-enable_automation),Editor/AutomationController.cs([InitializeOnLoad], rawTcpListeneronhttp://127.0.0.1:8772/, rebuild state machine persisted inSessionState). OFF by default: enable with Tools > RT Automation > Enable Control Server (EditorPrefs-persisted). Requests carrying anOriginheader, or aHostthat is not loopback, get 403 (browser / cross-site protection). The full endpoint catalogue with body keys, theidlesemantics (it ANDs every AI Chat busy gate plus any chat-generatedPicMainstill rendering) and the async file-write notes:docs/automation_bridge.md. Recommended editor pref: Script Changes While Playing = Stop Playing And Recompile.
Experiment code lives in Assets/Experiments/:
Adventure/- interactive story, quiz, Twine/HTML export, AutoPic flowsShootingGallery/- paintball/gallery target experimentPizza/- pizza generator experimentBreakout/- Breakout experimentCrazyCam/- older camera/photobooth code; README notes CrazyCam is currently disabled/replaced in practice by SpookyCam-style presets
Prompt/template text for higher-level modes also exists in root Adventure/ and AIGuide/.
The cli/ folder is a separate Python command-line front-end for ComfyUI generation (Windows + Linux). It intentionally implements only a subset of the Unity app:
aitools_cli.py- argparse entry pointaitools_cli.bat- Windows launcher (auto-createscli/venv/, installsrequirements.txt)config.py-cli/config.txtparserpresets.py- subset parser forPresets/*.txtworkflow.py- workflow load/convert/cache, replacements, placeholders, seed overrideservers.py,comfy_api.py,progress.py,images.py,util.py- server probing, ComfyUI HTTP/WebSocket calls, image/video upload, image resizing, output save
Do not assume every Unity job-script feature works in the CLI. Multi-step chains, temp slots, most LLM commands, and many Unity-only image operations deliberately error or are unsupported there. Movie generation (all four MiniMax H3 modes), repeatable -i/--video/--audio reference inputs, --width/--height/--duration overrides, start-frame aspect auto-fit, ffprobe silent-clip auto-pruning, per-run AITOOLS_UNIQUE_ID substitution, --dry-run offline validation, and a WS-drop /history-polling fallback for long renders are supported; cli/README.md "Generating movies (MiniMax H3)" is the reference.
Assets/_Script/- main app logicAssets/_Script/Pic/- per-image workflow, image editing, job executionAssets/_Script/GUI/- app UI panels and controlsAssets/_Script/LLM/- LLM settings, AI Chat, chat skills, model fetchersAssets/RT/- reusable runtime toolkit, editor builders, third-party utilitiesAssets/RT/AI/- API/service integration managersAssets/Experiments/- Adventure, ShootingGallery, Pizza, Breakout, CrazyCamAssets/Settings/Build Profiles/- Unity build profilesComfyUI/- source workflows plus generated cached API workflow filesPresets/- preset/job scriptsdocs/- feature deep-dives referenced from this file (aichat.md,automation_bridge.md,llm_providers.md,media_import.md,settings.md,workflows.md,minimax_h3.md,web_media.md,audio_generation.md)aichat/- editable AI Chat prompts and skill markdown filescli/- Python CLI subset (Windows + Linux)web/,utils/,Packaging/- runtime/package support files, including bundled helper EXEs underutils(RTClip,ffmpeg/bin,yt-dlp)Media/- README screenshots and media
Generated or local-only folders include Library/, Temp/, Logs/, build/, output/, UserSettings/, Images/, OldVersions/, and TestFiles/.
- Prefer existing Unity/C# patterns in the repo: MonoBehaviours, TextMeshPro UI,
UnityWebRequest,SimpleJSON, and the existing RT utility classes. - Unity 6000.6 / uGUI 2.6 treats
TMP_Text.enableWordWrappingas a compile error (CS0619). UsetextWrappingMode = TextWrappingModes.NormalorTextWrappingModes.NoWrap; do not retain legacy setters alongside the modern property. - Programmatic UI is common in the LLM panels and AI Chat. Match the local style when extending those panels.
- Runtime-built
TMP_InputFields (e.g. viaTMP_DefaultControls.CreateInputField) runOnEnablebeforetextComponentis wired, so TMP never creates the caret/selection renderer: typing works but the caret, mouse highlight, and wheel-scroll forwarding are dead. CallTMPInputFieldCaretFix.Apply(input)(Assets/RT/TMPInputFieldCaretFix.cs) after the field is fully wired AND parented; AI Chat's ownAIChatCaretFixeralready handles its fields. - When adding or moving Unity assets, keep
.metafiles with them. - Normal ComfyUI workflow files are the source of truth; cached API JSON files are generated artifacts and should generally not be hand-edited.
- Build scripts and packaging scripts are Windows-oriented and may delete/recreate build output directories.
- No reliable automated test command was found. If validation is needed, prefer focused C# compile/build checks or targeted Unity editor validation requested by the user.