Spaces:
Paused
Paused
| import os | |
| import re | |
| import shlex | |
| import subprocess | |
| import gradio as gr | |
| # ββ 1. Commands dynamisch ermitteln ββββββββββββββββββββββββββββββ | |
| def discover_commands() -> list[str]: | |
| """ | |
| Ruft `openclaw --help` auf und extrahiert die Sub-Commands. | |
| FΓ€llt bei Problemen auf eine kleine Default-Liste zurΓΌck. | |
| """ | |
| try: | |
| res = subprocess.run( | |
| ["openclaw", "--help"], | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.STDOUT, | |
| text=True, | |
| timeout=30, | |
| ) | |
| commands, parsing = [], False | |
| for line in res.stdout.splitlines(): | |
| if re.match(r"^\s*Commands?:", line): | |
| parsing = True | |
| continue | |
| if parsing: | |
| m = re.match(r"^\s{2,}([a-zA-Z0-9_-]+)\s", line) | |
| if m: | |
| commands.append(m.group(1)) | |
| elif line.strip() == "": | |
| break # Ende des Command-Blocks | |
| return sorted(set(commands)) | |
| except Exception: | |
| # Fallback, falls openclaw nicht installiert oder Help-Format unbekannt | |
| return ["status", "onboard", "gateway", "tui", "dashboard"] | |
| COMMANDS = discover_commands() | |
| # ββ 2. AusgewΓ€hlten Befehl ausfΓΌhren βββββββββββββββββββββββββββββ | |
| def run_cmd(command: str, extra_args: str) -> str: | |
| """ | |
| FΓΌhrt `openclaw <command> [extra_args]` aus und gibt formatierten Output zurΓΌck. | |
| """ | |
| cmd = ["openclaw", command] + shlex.split(extra_args or "") | |
| try: | |
| res = subprocess.run( | |
| cmd, | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.STDOUT, | |
| text=True, | |
| timeout=120, | |
| cwd="/app", | |
| ) | |
| return f"$ {' '.join(cmd)}\n\nExit code: {res.returncode}\n\n{res.stdout}" | |
| except FileNotFoundError: | |
| return "Error: `openclaw` ist nicht im Container installiert." | |
| except subprocess.TimeoutExpired: | |
| return "Error: Befehl lief lΓ€nger als 120 s." | |
| except Exception as e: | |
| return f"Unerwarteter Fehler: {e}" | |
| # ββ 3. Minimales UI mit Gradio βββββββββββββββββββββββββββββββββββ | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# OpenClaw Docker Space β automatisiert") | |
| with gr.Row(): | |
| cmd_dd = gr.Dropdown( | |
| choices=COMMANDS, | |
| value=COMMANDS[0] if COMMANDS else None, | |
| label="OpenClaw-Command", | |
| ) | |
| extra_tb = gr.Textbox( | |
| label="Optionale Zusatz-Argumente", | |
| placeholder="z. B. --help oder --verbose", | |
| ) | |
| output_tb = gr.Textbox(lines=20, label="Ausgabe") | |
| run_btn = gr.Button("AusfΓΌhren") | |
| run_btn.click(run_cmd, inputs=[cmd_dd, extra_tb], outputs=output_tb) | |
| # Hugging Face setzt $PORT automatisch; Fallback 7860 fΓΌr Lokaltests | |
| demo.launch(server_name="0.0.0.0", | |
| server_port=int(os.environ.get("PORT", 7860))) |