Trigger a single RL training step on the running MetaClaw instance. Sends a request to the running proxy's admin endpoint and waits for the training step to complete. Requires MetaClaw to be running in RL/auto mode. Useful for bench-driven experiments or manual control.
(port: int | None, timeout: int)
| 447 | help="Timeout in seconds (default: 600).", |
| 448 | ) |
| 449 | def train_step(port: int | None, timeout: int): |
| 450 | """Trigger a single RL training step on the running MetaClaw instance. |
| 451 | |
| 452 | Sends a request to the running proxy's admin endpoint and waits for the |
| 453 | training step to complete. Requires MetaClaw to be running in RL/auto |
| 454 | mode. Useful for bench-driven experiments or manual control. |
| 455 | """ |
| 456 | import json |
| 457 | import urllib.request |
| 458 | import urllib.error |
| 459 | |
| 460 | if port is None: |
| 461 | cs = ConfigStore() |
| 462 | port = cs.get("proxy.port") or 30000 |
| 463 | |
| 464 | url = f"http://localhost:{port}/v1/admin/train_step" |
| 465 | req = urllib.request.Request( |
| 466 | url, |
| 467 | data=b"{}", |
| 468 | headers={"Content-Type": "application/json"}, |
| 469 | method="POST", |
| 470 | ) |
| 471 | try: |
| 472 | with urllib.request.urlopen(req, timeout=timeout) as resp: |
| 473 | result = json.loads(resp.read().decode()) |
| 474 | except urllib.error.HTTPError as e: |
| 475 | body = e.read().decode() if e.fp else "" |
| 476 | click.echo(f"Error ({e.code}): {body}", err=True) |
| 477 | sys.exit(1) |
| 478 | except urllib.error.URLError as e: |
| 479 | click.echo( |
| 480 | f"Cannot connect to MetaClaw at port {port}: {e.reason}\n" |
| 481 | "Is MetaClaw running? Try: metaclaw status", |
| 482 | err=True, |
| 483 | ) |
| 484 | sys.exit(1) |
| 485 | except Exception as e: |
| 486 | click.echo(f"Error: {e}", err=True) |
| 487 | sys.exit(1) |
| 488 | |
| 489 | status = result.get("status", "unknown") |
| 490 | if status == "ok": |
| 491 | click.echo( |
| 492 | f"Train step #{result.get('step', '?')} complete: " |
| 493 | f"samples={result.get('samples', '?')} " |
| 494 | f"mean_reward={result.get('mean_reward', '?')} " |
| 495 | f"success_rate={result.get('success_rate', '?')}" |
| 496 | ) |
| 497 | elif status == "skipped": |
| 498 | click.echo(f"Skipped: {result.get('message', 'no samples')}") |
| 499 | else: |
| 500 | click.echo(f"Error: {result.get('message', 'unknown error')}", err=True) |
| 501 | sys.exit(1) |
| 502 | |
| 503 | |
| 504 | @metaclaw.command(name="config") |
nothing calls this directly
no test coverage detected