1#![allow(clippy::all, clippy::pedantic, clippy::disallowed_methods)]
10#![allow(
11 unreachable_code,
12 unused_variables,
13 unused_imports,
14 dead_code,
15 unused_assignments
16)]
17
18use clap::{Parser, Subcommand, ValueEnum};
19use std::path::{Path, PathBuf};
20
21#[macro_use]
23#[allow(unused_macros, clippy::duplicated_attributes)]
24mod generated_contracts;
25
26mod commands;
27pub mod error;
28mod output;
29pub mod pipe;
30
31pub use error::CliError;
32
33pub mod qa_types {
35 pub use crate::commands::qa::{GateResult, QaReport, SystemInfo};
36}
37
38pub mod model_pull {
40 pub use crate::commands::pull::{list, run};
41}
42
43pub mod serve_auth {
47 #[cfg(feature = "inference")]
48 pub use crate::commands::serve::auth::layer;
49 pub use crate::commands::serve::auth::{apply, AuthGate};
50}
51
52#[cfg(feature = "inference")]
57pub mod serve_test_support {
58 pub use crate::commands::serve::handlers::build_demo_apr_cpu_router_for_test;
59 pub use crate::commands::serve::handlers::build_demo_streaming_apr_cpu_router_for_test;
63}
64
65#[cfg(feature = "inference")]
66pub mod federation;
67
68use commands::{
70 bench, canary, canary::CanaryCommands, cbtop, chat, compare_hf, compile, convert, data, debug,
71 diagnose, diff, distill, eval, explain, export, flow, hex, import, inspect, lint, mcp, merge,
72 oracle, pipeline, probar, profile, prune, publish, pull, qa, qualify, quantize, rosetta,
73 rosetta::RosettaCommands, run, serve, showcase, stamp, tensors, tokenize, trace, tree, tui,
74 validate, validate_manifest,
75};
76#[cfg(feature = "training")]
77use commands::{finetune, gpu, train, tune};
78
79#[cfg(feature = "training")]
80pub use commands::pretrain::PretrainMode;
81
82#[derive(Parser, Debug)]
87#[command(name = "apr")]
88#[command(author, version = concat!(env!("CARGO_PKG_VERSION"), " (", env!("APR_GIT_SHA"), ")"), about, long_about = None)]
89#[command(propagate_version = true)]
90pub struct Cli {
91 #[command(subcommand)]
92 pub command: Box<Commands>,
93
94 #[arg(long, global = true)]
96 pub json: bool,
97
98 #[arg(short, long, global = true)]
100 pub verbose: bool,
101
102 #[arg(short, long, global = true)]
104 pub quiet: bool,
105
106 #[arg(long, global = true)]
108 pub offline: bool,
109
110 #[arg(long, global = true)]
112 pub skip_contract: bool,
113}
114
115include!("commands_enum.rs");
116include!("model_ops_commands.rs");
117include!("extended_commands.rs");
118include!("tool_commands.rs");
119include!("data_commands.rs");
120#[cfg(feature = "training")]
121include!("train_commands.rs");
122include!("serve_commands.rs");
123include!("tokenize_commands.rs");
124include!("pipeline_commands.rs");
125include!("validate.rs");
126include!("dispatch_run.rs");
127include!("dispatch.rs");
128include!("dispatch_analysis.rs");
129include!("lib_07.rs");
130
131pub fn cli_main() -> std::process::ExitCode {
137 #[cfg(unix)]
139 #[allow(unsafe_code)]
140 unsafe {
141 libc::signal(libc::SIGPIPE, libc::SIG_DFL);
142 }
143
144 #[cfg(target_arch = "aarch64")]
146 #[allow(unsafe_code)]
147 unsafe {
148 let fpcr: u64;
149 core::arch::asm!("mrs {}, fpcr", out(reg) fpcr);
150 if fpcr & (1 << 19) != 0 {
151 let new_fpcr = fpcr & !(1 << 19);
152 core::arch::asm!("msr fpcr, {}", in(reg) new_fpcr);
153 }
154 }
155
156 let no_color = std::env::var("NO_COLOR").is_ok();
158 let is_tty = std::io::IsTerminal::is_terminal(&std::io::stdout());
159 if no_color || !is_tty {
160 colored::control::set_override(false);
161 }
162
163 let raw: Vec<String> = std::env::args().collect();
170 if raw.iter().any(|a| a == "--version") && raw.iter().any(|a| a == "--json") {
171 emit_version_json();
172 return std::process::ExitCode::SUCCESS;
173 }
174
175 let cli = Cli::parse();
176 match execute_command(&cli) {
177 Ok(()) => std::process::ExitCode::SUCCESS,
178 Err(e) => {
179 eprintln!("error: {e}");
180 e.exit_code()
181 }
182 }
183}
184
185pub fn emit_version_json() {
205 let cuda_feature = cfg!(feature = "cuda");
206
207 let cuda_runtime_available = std::process::Command::new("nvidia-smi")
211 .arg("-L")
212 .output()
213 .map(|o| o.status.success())
214 .unwrap_or(false);
215
216 let visible_devices: Vec<String> = if cuda_runtime_available {
220 std::process::Command::new("nvidia-smi")
221 .arg("-L")
222 .output()
223 .ok()
224 .and_then(|o| String::from_utf8(o.stdout).ok())
225 .map(|s| {
226 s.lines()
227 .filter_map(|line| {
228 line.strip_prefix("GPU ").and_then(|rest| {
230 rest.split_once(':').map(|(idx, _)| idx.trim().to_string())
231 })
232 })
233 .collect()
234 })
235 .unwrap_or_default()
236 } else {
237 Vec::new()
238 };
239
240 let body = serde_json::json!({
241 "name": "apr",
242 "version": env!("CARGO_PKG_VERSION"),
243 "git_sha": env!("APR_GIT_SHA"),
244 "cuda_feature": cuda_feature,
245 "cuda_runtime_available": cuda_runtime_available,
246 "visible_devices": visible_devices,
247 });
248
249 println!(
252 "{}",
253 serde_json::to_string_pretty(&body).expect("build version json")
254 );
255}