Skip to content

feat(gen_sim): add Scene Engine and Gradio workspace - #457

Open
XuanchaoPENG wants to merge 52 commits into
mainfrom
xuanchao/gradio
Open

feat(gen_sim): add Scene Engine and Gradio workspace#457
XuanchaoPENG wants to merge 52 commits into
mainfrom
xuanchao/gradio

Conversation

@XuanchaoPENG

Copy link
Copy Markdown
Collaborator

Description

This PR introduces an image-to-scene generation workflow for EmbodiChain, together with a Gradio-based workspace for running and previewing generative-simulation workflows.

Key changes:

  • Add Scene Engine, which reconstructs tabletop scenes from an input image by performing scene understanding, segmentation, geometry generation, layout refinement, and scene export.
  • Add embodichain scene-engine and embodichain preview-scene CLI commands.
  • Add a Gradio workspace with managed pipeline execution and Viser scene previews.
  • Add Scene Engine configuration through embodichain/gen_sim/.env and an example environment file.
  • Add the scene-engine optional dependency group; extend the gensim extra with Scene Engine dependencies.

Fixes # (issue)

Type of change

  • New feature (non-breaking change which adds functionality)

Checklist

  • I have run the black . command to format the code base.
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • Dependencies have been updated, if applicable.

MuziWong and others added 30 commits July 29, 2026 11:30
@yuecideng
yuecideng self-requested a review August 6, 2026 08:23
# Conflicts:
#	.github/workflows/main.yml
#	embodichain/gen_sim/scene_engine/pipeline/utils/scene_exporter.py
#	pyproject.toml
#	tests/gen_sim/scene_engine/test_scene_core_and_export.py
@greptile-apps

greptile-apps Bot commented Aug 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds shared GenSim environment loading and a Gradio workspace for Scene Engine, SimReady, Articraft generation, and Viser previews.

  • Adds Scene Engine and preview CLI registrations.
  • Adds managed subprocess workflows, generated-asset previews, and shared workspace state.
  • Adds Articraft checkout, generation, validation, packaging, and preview integration.
  • Adds environment examples and Scene Engine configuration tests.

Confidence Score: 4/5

The PR is not safe to merge until the missing-environment startup crash, cross-session process cancellation, unrelated-listener termination, and Codex credential exposure are fixed.

The default workspace startup fails when no local .env exists, and reachable Gradio callbacks currently share process ownership, signal unverified listeners, and expose the full server environment to a user-directed agent whose output is returned to the browser.

Files Needing Attention: embodichain/gen_sim/env.py, embodichain/gen_sim/gradio_ui/app_articraft.py, embodichain/gen_sim/gradio_ui/app_asset_engine.py, embodichain/gen_sim/gradio_ui/gradio_app.py

Security Review

Two security-boundary defects were identified: Articraft preview startup can terminate an unrelated same-user listener on its configured port, and user-directed Codex execution inherits server credentials while streaming its output to the browser.

Important Files Changed

Filename Overview
embodichain/gen_sim/env.py Adds shared dotenv parsing, but the missing-file path dereferences an implicit None and prevents normal startup.
embodichain/gen_sim/gradio_ui/app_articraft.py Adds the Articraft generation and preview workflow, including unsafe credential inheritance and unverified termination of occupied-port listeners.
embodichain/gen_sim/gradio_ui/app_asset_engine.py Adds SimReady UI execution, but global process ownership lets a queue-bypassing reset cancel another session's run.
embodichain/gen_sim/gradio_ui/gradio_app.py Launches the queued workspace on all interfaces without built-in authentication, making shared-state and agent-boundary defects reachable by multiple clients.
embodichain/main.py Registers the Scene Engine generation and preview commands through lazy CLI dispatch.

Sequence Diagram

sequenceDiagram
    participant User as Gradio user
    participant UI as Gradio workspace
    participant Env as Shared environment
    participant Job as Pipeline/Codex process
    participant Preview as Viser preview
    User->>UI: Submit image, asset, or prompt
    UI->>Env: Load GenSim configuration
    UI->>Job: Start managed generation process
    Job-->>UI: Stream logs and generated outputs
    UI->>Preview: Start scene or asset preview
    Preview-->>User: Embedded interactive visualization
    User->>UI: Reset workflow
    UI->>Job: Terminate globally tracked process
Loading

Fix All in Codex Fix All in Claude Code

Prompt To Fix All With AI
### Issue 1
embodichain/gen_sim/env.py:69-71
**Missing dotenv crashes startup**

When neither `EMBODICHAIN_ENV_FILE` nor the optional local `.env` exists, `find_gen_sim_env_file()` returns `None` and the loader calls `.is_file()` on it, causing the Gradio workspace to fail during import with an `AttributeError`.

```suggestion
    env_path = find_gen_sim_env_file()
    if env_path is None or not env_path.is_file():
        return None
```

### Issue 2
embodichain/gen_sim/gradio_ui/app_articraft.py:566
**Preview kills unowned listeners**

If another same-user service occupies `ARTICRAFT_VISER_PORT`, preview startup sends SIGTERM and potentially SIGKILL to every discovered listener without verifying application ownership, taking the unrelated service offline.

**How this was verified:** The occupied-port path leads from unfiltered listener PID discovery directly to `os.kill`.

### Issue 3
embodichain/gen_sim/gradio_ui/app_articraft.py:853-861
**Codex inherits server credentials**

When a workspace user instructs Codex to print an environment credential, the user-directed process receives the complete dotenv-populated `os.environ` and its combined output is streamed to the browser, disclosing the credential in the generation log.

**How this was verified:** The user prompt reaches a command-capable Codex process that inherits the full server environment and returns captured stdout to the UI.

### Issue 4
embodichain/gen_sim/gradio_ui/app_asset_engine.py:84-92
**Reset cancels another session**

If one session clicks Reset while another session has a SimReady or Articraft job running, the queue-bypassing callback clears module-global ownership state and terminates the shared process, causing the first session's generator to exit without its requested result.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "add log" | Re-trigger Greptile

Comment on lines +69 to +71
env_path = find_gen_sim_env_file()
if not env_path.is_file():
return None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Missing dotenv crashes startup

When neither EMBODICHAIN_ENV_FILE nor the optional local .env exists, find_gen_sim_env_file() returns None and the loader calls .is_file() on it, causing the Gradio workspace to fail during import with an AttributeError.

Suggested change
env_path = find_gen_sim_env_file()
if not env_path.is_file():
return None
env_path = find_gen_sim_env_file()
if env_path is None or not env_path.is_file():
return None
Prompt To Fix With AI
This is a comment left during a code review.
Path: embodichain/gen_sim/env.py
Line: 69-71

Comment:
**Missing dotenv crashes startup**

When neither `EMBODICHAIN_ENV_FILE` nor the optional local `.env` exists, `find_gen_sim_env_file()` returns `None` and the loader calls `.is_file()` on it, causing the Gradio workspace to fail during import with an `AttributeError`.

```suggestion
    env_path = find_gen_sim_env_file()
    if env_path is None or not env_path.is_file():
        return None
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex Fix in Claude Code

f"Port {self._port} is unavailable without a visible listener."
)

self._signal_listeners(listener_pids, signal.SIGTERM, "stop")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Preview kills unowned listeners

If another same-user service occupies ARTICRAFT_VISER_PORT, preview startup sends SIGTERM and potentially SIGKILL to every discovered listener without verifying application ownership, taking the unrelated service offline.

How this was verified: The occupied-port path leads from unfiltered listener PID discovery directly to os.kill.

Prompt To Fix With AI
This is a comment left during a code review.
Path: embodichain/gen_sim/gradio_ui/app_articraft.py
Line: 566

Comment:
**Preview kills unowned listeners**

If another same-user service occupies `ARTICRAFT_VISER_PORT`, preview startup sends SIGTERM and potentially SIGKILL to every discovered listener without verifying application ownership, taking the unrelated service offline.

**How this was verified:** The occupied-port path leads from unfiltered listener PID discovery directly to `os.kill`.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex Fix in Claude Code

Comment on lines +853 to +861
subprocess.Popen(
codex_command,
cwd=ARTICRAFT_ROOT,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1,
start_new_session=True,
env=os.environ.copy(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Codex inherits server credentials

When a workspace user instructs Codex to print an environment credential, the user-directed process receives the complete dotenv-populated os.environ and its combined output is streamed to the browser, disclosing the credential in the generation log.

How this was verified: The user prompt reaches a command-capable Codex process that inherits the full server environment and returns captured stdout to the UI.

Prompt To Fix With AI
This is a comment left during a code review.
Path: embodichain/gen_sim/gradio_ui/app_articraft.py
Line: 853-861

Comment:
**Codex inherits server credentials**

When a workspace user instructs Codex to print an environment credential, the user-directed process receives the complete dotenv-populated `os.environ` and its combined output is streamed to the browser, disclosing the credential in the generation log.

**How this was verified:** The user prompt reaches a command-capable Codex process that inherits the full server environment and returns captured stdout to the UI.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex Fix in Claude Code

Comment on lines +84 to +92
def reset_simready_asset():
"""Clear SimReady widgets and terminate the process group for its active run."""
global _simready_process, _simready_run_token
with _simready_run_lock:
process = _simready_process
_simready_process = None
_simready_run_token = None
if process is not None:
terminate_process_group(process)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Reset cancels another session

If one session clicks Reset while another session has a SimReady or Articraft job running, the queue-bypassing callback clears module-global ownership state and terminates the shared process, causing the first session's generator to exit without its requested result.

Prompt To Fix With AI
This is a comment left during a code review.
Path: embodichain/gen_sim/gradio_ui/app_asset_engine.py
Line: 84-92

Comment:
**Reset cancels another session**

If one session clicks Reset while another session has a SimReady or Articraft job running, the queue-bypassing callback clears module-global ownership state and terminates the shared process, causing the first session's generator to exit without its requested result.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex Fix in Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants