Skip to content

Commit cc9039e

Browse files
feat: added support for remote server policy execution (#33)
1 parent 1b95070 commit cc9039e

3 files changed

Lines changed: 70 additions & 28 deletions

File tree

examples/4_rollout_neuracore_policy.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -661,26 +661,27 @@ def update_visualization(
661661
default=None,
662662
help="IP address of Meta Quest device (optional, defaults to None for auto-discovery)",
663663
)
664-
parser.add_argument(
664+
policy_group = parser.add_mutually_exclusive_group(required=True)
665+
policy_group.add_argument(
665666
"--train-run-name",
666667
type=str,
667668
default=None,
668-
help="Name of the training run to load policy from (for cloud training). Mutually exclusive with --model-path.",
669+
help="Name of the training run to load policy from (for cloud training).",
669670
)
670-
parser.add_argument(
671+
policy_group.add_argument(
671672
"--model-path",
672673
type=str,
673674
default=None,
674-
help="Path to local model file to load policy from. Mutually exclusive with --train-run-name.",
675+
help="Path to local model file to load policy from.",
676+
)
677+
policy_group.add_argument(
678+
"--remote-endpoint-name",
679+
type=str,
680+
default=None,
681+
help="Name of remote Neuracore policy endpoint.",
675682
)
676683
args = parser.parse_args()
677684

678-
# Validate that exactly one of train-run-name or model-path is provided
679-
if (args.train_run_name is None) == (args.model_path is None):
680-
parser.error(
681-
"Exactly one of --train-run-name or --model-path must be provided (not both, not neither)"
682-
)
683-
684685
print("=" * 60)
685686
print("PIPER ROBOT TEST WITH NEURACORE POLICY")
686687
print("=" * 60)
@@ -722,7 +723,19 @@ def update_visualization(
722723
for data_type, names in model_output_order.items():
723724
print(f" {data_type.name}: {names}")
724725

725-
if args.train_run_name is not None:
726+
if args.remote_endpoint_name is not None:
727+
print(
728+
f"\n🤖 Connecting to remote policy endpoint: {args.remote_endpoint_name}..."
729+
)
730+
try:
731+
policy = nc.policy_remote_server(args.remote_endpoint_name)
732+
except nc.EndpointError:
733+
print(
734+
f"❌ Endpoint '{args.remote_endpoint_name}' not available. "
735+
"Please start it from the Neuracore dashboard."
736+
)
737+
sys.exit(1)
738+
elif args.train_run_name is not None:
726739
print(f"\n🤖 Loading policy from training run: {args.train_run_name}...")
727740
policy = nc.policy(
728741
train_run_name=args.train_run_name,

examples/5_rollout_neuracore_policy_minimal.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -178,17 +178,24 @@ def execute_horizon(
178178

179179
if __name__ == "__main__":
180180
parser = argparse.ArgumentParser(description="Minimal Piper Policy Test")
181-
parser.add_argument(
181+
policy_group = parser.add_mutually_exclusive_group(required=True)
182+
policy_group.add_argument(
182183
"--train-run-name",
183184
type=str,
184185
default=None,
185-
help="Name of the training run to load policy from (for cloud training). Mutually exclusive with --model-path.",
186+
help="Name of the training run to load policy from (for cloud training).",
186187
)
187-
parser.add_argument(
188+
policy_group.add_argument(
188189
"--model-path",
189190
type=str,
190191
default=None,
191-
help="Path to local model file to load policy from. Mutually exclusive with --train-run-name.",
192+
help="Path to local model file to load policy from.",
193+
)
194+
policy_group.add_argument(
195+
"--remote-endpoint-name",
196+
type=str,
197+
default=None,
198+
help="Name of remote Neuracore policy endpoint.",
192199
)
193200
parser.add_argument(
194201
"--frequency",
@@ -204,12 +211,6 @@ def execute_horizon(
204211
)
205212
args = parser.parse_args()
206213

207-
# Validate that exactly one of train-run-name or model-path is provided
208-
if (args.train_run_name is None) == (args.model_path is None):
209-
parser.error(
210-
"Exactly one of --train-run-name or --model-path must be provided (not both, not neither)"
211-
)
212-
213214
print("=" * 60)
214215
print("PIPER POLICY ROLLOUT")
215216
print("=" * 60)
@@ -244,7 +245,19 @@ def execute_horizon(
244245
for data_type, names in model_output_order.items():
245246
print(f" {data_type.name}: {names}")
246247

247-
if args.train_run_name is not None:
248+
if args.remote_endpoint_name is not None:
249+
print(
250+
f"\n🤖 Connecting to remote policy endpoint: {args.remote_endpoint_name}..."
251+
)
252+
try:
253+
policy = nc.policy_remote_server(args.remote_endpoint_name)
254+
except nc.EndpointError:
255+
print(
256+
f"❌ Endpoint '{args.remote_endpoint_name}' not available. "
257+
"Please start it from the Neuracore dashboard."
258+
)
259+
sys.exit(1)
260+
elif args.train_run_name is not None:
248261
print(f"\n🤖 Loading policy from training run: {args.train_run_name}...")
249262
policy = nc.policy(
250263
train_run_name=args.train_run_name,

examples/6_visualize_policy_from_dataset.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,24 @@
4040
description="Visualize policy predictions from dataset"
4141
)
4242
parser.add_argument("--dataset-name", type=str, required=True, help="Dataset name")
43-
parser.add_argument(
43+
policy_group = parser.add_mutually_exclusive_group(required=True)
44+
policy_group.add_argument(
4445
"--train-run-name", type=str, default=None, help="Training run name"
4546
)
46-
parser.add_argument("--model-path", type=str, default=None, help="Model file path")
47+
policy_group.add_argument(
48+
"--model-path", type=str, default=None, help="Model file path"
49+
)
50+
policy_group.add_argument(
51+
"--remote-endpoint-name",
52+
type=str,
53+
default=None,
54+
help="Name of remote Neuracore policy endpoint to use instead of a local policy.",
55+
)
4756
parser.add_argument(
4857
"--frequency", type=int, default=100, help="Frequency of visualization"
4958
)
5059
args = parser.parse_args()
5160

52-
if (args.train_run_name is None) == (args.model_path is None):
53-
parser.error("Exactly one of --train-run-name or --model-path must be provided")
54-
5561
# Connect to Neuracore
5662
print("🔧 Initializing Neuracore...")
5763
nc.login()
@@ -68,7 +74,17 @@
6874
DataType.PARALLEL_GRIPPER_TARGET_OPEN_AMOUNTS: [GRIPPER_LOGGING_NAME],
6975
}
7076

71-
if args.train_run_name:
77+
if args.remote_endpoint_name:
78+
print(f"🤖 Connecting to remote policy endpoint: {args.remote_endpoint_name}...")
79+
try:
80+
policy = nc.policy_remote_server(args.remote_endpoint_name)
81+
except nc.EndpointError:
82+
print(
83+
f"❌ Endpoint '{args.remote_endpoint_name}' not available. "
84+
"Please start it from the Neuracore dashboard."
85+
)
86+
sys.exit(1)
87+
elif args.train_run_name:
7288
print(f"🤖 Loading policy from training run: {args.train_run_name}...")
7389
policy = nc.policy(
7490
train_run_name=args.train_run_name,

0 commit comments

Comments
 (0)