Skip to main content

multi-instance

Workflow for running multiple TD instances with Envoy, switching between them, and understanding the instance registry.

Quellinformationen

Repository
dylanroscover/Embody
Letzte Quellaktivität
6. September 2026 um 07:13
Erkannte Sprache von SKILL.md
Englisch
Sterne
182
Forks
11

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
multi-instance
description
Workflow for running multiple TD instances with Envoy, switching between them, and understanding the instance registry.
# Multi-Instance Workflow Envoy supports multiple TouchDesigner instances running simultaneously in the same git repo. Each instance gets its own port, and the bridge can switch between them on demand. ## Architecture ``` Claude Code <--> STDIO Bridge <--> Envoy (TD instance A, port 9870) | +---switch---> Envoy (TD instance B, port 9871) ``` - **One bridge process per SESSION** (spawned by each AI client's MCP client) - **Per-session pinning** - each bridge pins to an instance NAME and re-resolves its port from the registry every tick, so a pinned instance restarting on a new port still self-heals. The registry `active` field only seeds NEW bridges without a pin. - **Per-call addressing** - every Envoy tool accepts an optional `instance` argument; the bridge routes that one call to the named instance and leaves the pin alone (unknown or unreachable names fail only that call with `error_code` `envoy.instance.unknown` / `envoy.instance.unreachable`). Prefer it over switching when you only need one look at another instance. - **Switching is instant and session-local** - `switch_instance` re-pins THIS session's bridge in-memory; peers are untouched unless you pass `all_sessions=True` (writes the registry default and bumps `active_epoch`, which moves every session) - **Registration never re-routes running sessions** - a new instance takes the `active` default slot only when it is vacant or names a dead instance ## Instance Registry (`.embody/envoy.json`) Each Envoy instance registers itself in `.embody/envoy.json` at the git root on startup: ```json { "active": "Embody-5.257", "td_executable": "/Applications/TouchDesigner.app", "instances": { "Embody-5.257": { "toe_path": "dev/Embody-5.257.toe", "port": 9870, "td_pid": 12345 }, "MySecondProject": { "toe_path": "MySecondProject.toe", "port": 9871, "td_pid": 67890 } } } ``` | Field | Purpose | |-------|---------| | `active` | Default instance for NEWLY-spawned bridges (each bridge then pins per-session; only an `active_epoch` bump re-targets pinned bridges) | | `td_executable` | Path to TD app (used by `launch_td`) | | `instances.<name>.toe_path` | Relative path to the `.toe` file | | `instances.<name>.port` | Envoy HTTP port for this instance | | `instances.<name>.td_pid` | OS process ID of the TD process | Instances are added on Envoy startup and removed on graceful shutdown (`onDestroyTD`). ## Port Allocation Each instance picks a port from a 10-port range starting at the configured `Envoyport` parameter (default: `9870`): 1. Try the base port first 2. If occupied by **this** TD process's old server, force-close it and reclaim 3. If occupied by **another** process, scan `base+1` through `base+9` 4. First available port wins; if all 10 are taken, startup fails This means up to 10 simultaneous instances per base port. ## Workflow: Running Multiple Instances ### 1. Open the first `.toe` file Launch TD normally or via `launch_td`. Envoy starts on its configured port and registers in `.embody/envoy.json`. ### 2. Open additional `.toe` files Open them in separate TD instances (File > Open or double-click). Each Embody/Envoy auto-starts and claims the next available port. ### 3. List instances Call `switch_instance` with no parameters to see all registered instances and their status: ``` switch_instance() ``` Returns each instance's name, port, PID, reachability (PID alive + port responding), and whether it's the active target. ### 4. Switch to a different instance ``` switch_instance(instance="MySecondProject") ``` The bridge immediately redirects to the target instance's port. All subsequent MCP calls go to that TD process. ### 5. Switch back ``` switch_instance(instance="Embody-5.257") ``` ## Reachability Checks An instance is **reachable** only when: - Its registered PID is alive (`kill -0` / process table check) - Its registered port responds to a TCP connect Both conditions must be true. A dead PID with an open port means another instance reused that port - the entry is stale. `get_td_status` includes the full instance registry with reachability in its response. ## Stale Instance Cleanup Instances are deregistered on graceful TD shutdown. If TD crashes: - The PID becomes dead, so the instance shows as unreachable - The port may be freed, allowing a new instance to claim it - Stale entries remain in `.embody/envoy.json` but are filtered by reachability checks - Re-launching TD with the same `.toe` overwrites the stale entry ## Closing Instances **Preferred**: Close TD instances via Envoy by calling `execute_python` with `project.quit()`. This prompts the user to save unsaved changes, then triggers `onDestroyTD` for clean deregistration and port release. Works reliably across platforms. To close a specific instance, `switch_instance` to it first, then send the quit command: ```python switch_instance(instance="MySecondProject") # target the instance execute_python(code="project.quit()") # user gets save prompt in TD ``` **Never use `project.quit(force=True)`** unless the user has explicitly asked - it skips the save dialog and risks losing unsaved work. **Avoid**: `osascript -e 'quit app "TouchDesigner"'` and similar OS-level approaches are unreliable - they may not target the correct instance and don't guarantee clean Envoy shutdown. ## Common Scenarios | Scenario | Action | |----------|--------| | Test code in two `.toe` files side by side | Open both, `switch_instance` between them | | Test code in a secondary `.toe` | Open it, switch to it, perform work, switch back | | Check if a second TD is still running | `switch_instance()` (list mode) or `get_td_status` | | One instance crashed, want the other | `switch_instance` to the surviving instance | | Close a specific instance | `switch_instance` to it, then `execute_python` with `project.quit()` | ## Same-Project Instances When you open the same `.toe` file in multiple TD instances, Envoy auto-suffixes the registry key to avoid collisions. The first instance registers as `MyProject`, the second as `MyProject-2`, etc. Stale entries (dead PIDs) are automatically reclaimed. ## Limitations - The bridge connects to **one instance at a time** - no parallel MCP calls to multiple instances - Maximum **10 instances** per base port range - `.embody/envoy.json` is per git root - instances in different repos have separate registries - `launch_td` always launches the `.toe` configured in `.embody/envoy.json` top-level `toe_path` - use TD directly to open additional files - Opening the same `.toe` file in multiple instances auto-suffixes keys (`MyProject-2`, `-3`, etc.)
Auf GitHub ansehen