robonix_executor/
config.rs1use anyhow::{Context, Result};
8use clap::Parser;
9use serde::Deserialize;
10use std::path::{Path, PathBuf};
11
12pub const DEFAULT_EXECUTOR_PROVIDER_ID: &str = "executor";
13pub const EXECUTOR_NAMESPACE: &str = "robonix/system/executor";
14pub const DEFAULT_ATLAS_ENDPOINT: &str = "127.0.0.1:50051";
15pub const DEFAULT_LISTEN: &str = "127.0.0.1:50061";
16
17#[derive(Debug, Clone)]
18pub struct ExecutorConfig {
19 pub atlas_endpoint: String,
20 pub listen: String,
21 pub id: String,
22}
23
24#[derive(Parser, Debug)]
25#[command(
26 name = "robonix-executor",
27 about = "Robonix Executor — tool-call dispatch runtime"
28)]
29pub struct Args {
30 #[arg(long, env = "ROBONIX_ATLAS_ENDPOINT")]
32 pub atlas: Option<String>,
33
34 #[arg(long, env = "ROBONIX_EXECUTOR_LISTEN")]
36 pub listen: Option<String>,
37
38 #[arg(long, env = "ROBONIX_EXECUTOR_PROVIDER_ID")]
40 pub id: Option<String>,
41
42 #[arg(long, env = "ROBONIX_CONFIG_PATH")]
44 pub config: Option<PathBuf>,
45
46 #[arg(long)]
49 pub log: Option<String>,
50}
51
52#[derive(Default, Deserialize)]
53struct FileConfig {
54 #[serde(default)]
55 atlas_endpoint: Option<String>,
56 #[serde(default)]
57 listen: Option<String>,
58 #[serde(default)]
59 id: Option<String>,
60}
61
62impl ExecutorConfig {
63 pub fn resolve(args: Args) -> Result<Self> {
64 let file_cfg: FileConfig = match &args.config {
65 Some(path) => load_yaml(path)?,
66 None => FileConfig::default(),
67 };
68 Ok(Self {
69 atlas_endpoint: args
70 .atlas
71 .or(file_cfg.atlas_endpoint)
72 .unwrap_or_else(|| DEFAULT_ATLAS_ENDPOINT.to_string()),
73 listen: args
74 .listen
75 .or(file_cfg.listen)
76 .unwrap_or_else(|| DEFAULT_LISTEN.to_string()),
77 id: args
78 .id
79 .or(file_cfg.id)
80 .unwrap_or_else(|| DEFAULT_EXECUTOR_PROVIDER_ID.to_string()),
81 })
82 }
83}
84
85fn load_yaml(path: &Path) -> Result<FileConfig> {
86 let raw = std::fs::read_to_string(path)
87 .with_context(|| format!("read executor config '{}'", path.display()))?;
88 serde_yaml::from_str(&raw)
89 .with_context(|| format!("parse executor config '{}'", path.display()))
90}