Skip to main content

loa_core/
constants.rs

1//! Global constants and configuration defaults for the agent
2
3use once_cell::sync::OnceCell;
4
5/// Default heartbeat interval (seconds) - matches DEFAULT_TIER_0 in API
6///
7/// This is the Tier 0 heartbeat interval (5 minutes).
8/// Used as fallback when config fetch fails or before config is loaded.
9pub const DEFAULT_HEARTBEAT_INTERVAL_SECS: u64 = 300;
10
11/// Default API URL for backend communication (production)
12///
13/// Can be overridden at build time with the API_URL environment variable.
14/// For local development, set API_URL=http://localhost:8787
15pub const DEFAULT_API_URL: &str = "https://api.loa.sh";
16
17/// Global runtime API URL (set via builder.api_url())
18///
19/// This takes precedence over compile-time API_URL when set.
20static RUNTIME_API_URL: OnceCell<String> = OnceCell::new();
21
22/// Initialize the global runtime API URL
23///
24/// This should be called once during agent startup if a custom API URL is configured.
25/// Called from AgentBuilder when .api_url() is set.
26pub fn init_global_api_url(url: String) {
27    // Use get_or_init to allow multiple calls (idempotent)
28    RUNTIME_API_URL.get_or_init(|| url);
29}
30
31/// Get the API URL (runtime > compile-time > default)
32///
33/// Priority:
34/// 1. Runtime URL (set via builder.api_url() / --dev flag)
35/// 2. Compile-time API_URL environment variable
36/// 3. Default production URL
37///
38/// # Examples
39///
40/// ```
41/// let url = loa_core::constants::api_url();
42/// println!("Using API: {}", url);
43/// ```
44pub fn api_url() -> String {
45    // Check runtime URL first (set by --dev flag or builder.api_url())
46    if let Some(url) = RUNTIME_API_URL.get() {
47        return url.clone();
48    }
49    // Fall back to compile-time or default
50    option_env!("API_URL")
51        .unwrap_or(DEFAULT_API_URL)
52        .to_string()
53}
54
55/// Returns true if running under `cargo run` (in development)
56pub fn is_cargo_run() -> bool {
57    std::env::var("CARGO").is_ok()
58}
59
60/// Get the Ingest URL derived from API URL
61///
62/// Transforms the API URL to the ingest URL:
63/// - api.loa.sh → ingest.loa.sh
64/// - loa-api.*.workers.dev → loa-ingest.*.workers.dev
65/// - localhost:8787 → localhost:8788
66pub fn ingest_url() -> String {
67    let api = api_url();
68    if api.contains("localhost") {
69        api.replace(":8787", ":8788")
70    } else if api.contains("workers.dev") {
71        // Dev environment: loa-api.*.workers.dev → loa-ingest.*.workers.dev
72        api.replace("loa-api", "loa-ingest")
73    } else {
74        // Prod: api.loa.sh → ingest.loa.sh
75        api.replace("api.", "ingest.")
76    }
77}