1use crate::error::{
2 ConfigAccessError, ConfigNotFoundError, InvalidConfigError, LlmixError, LlmixResult,
3 SecurityError,
4};
5use serde_json::{Map, Value};
6use snoai_mda_config::{
7 load_mda_source_from_bytes, DidWebVerifier, LoadMdaSourceOptions, MdaConfigError, RekorClient,
8 SigstoreVerifier, TrustPolicy,
9};
10use std::env;
11use std::fs;
12use std::path::{Component, Path, PathBuf};
13
14const DEFAULT_ENV_VAR: &str = "LLMIX_CONFIG_DIR";
15const DEFAULT_RELATIVE_PATH: &str = "./config/llm";
16const MAX_NAME_LEN: usize = 64;
17const MIN_VERSION: u32 = 1;
18const MAX_VERSION: u32 = 9999;
19const LLMIX_MDA_NAMESPACE: &str = "snoai-llmix";
20const VALID_PROVIDERS: &[&str] = &[
21 "openai",
22 "anthropic",
23 "google",
24 "deepseek",
25 "openrouter",
26 "sno-gpu",
27 "deepinfra",
28 "novita",
29 "together",
30];
31const VALID_CACHE_STRATEGIES: &[&str] = &[
32 "native",
33 "gateway",
34 "disabled",
35 "redis",
36 "redis-or-memory",
37 "memory",
38];
39const OPENAI_REASONING_EFFORTS: &[&str] = &["minimal", "low", "medium", "high", "xhigh"];
40const LOCKFILES_TS: &[&str] = &[
41 "bun.lock",
42 "pnpm-lock.yaml",
43 "package-lock.json",
44 "yarn.lock",
45];
46const LOCKFILES_PY: &[&str] = &["uv.lock", "poetry.lock", "Pipfile.lock", "pdm.lock"];
47const DANGEROUS_PARTS: &[&str] = &["/", "\\", "..", "~", "$", "`"];
48
49#[derive(Debug, Clone, PartialEq, Eq, Default)]
50pub struct LlmixPathConfig {
51 pub config_dir: Option<PathBuf>,
52 pub env_var: Option<String>,
53 pub default_path: Option<PathBuf>,
54 pub project_root: Option<PathBuf>,
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq)]
58pub enum ConfigDirSource {
59 Explicit,
60 Env,
61 Default,
62}
63
64#[derive(Debug, Clone, PartialEq, Eq)]
65pub struct ResolvedConfigDir {
66 pub config_dir: PathBuf,
67 pub source: ConfigDirSource,
68}
69
70#[derive(Default, Clone)]
71pub struct MdaConfigLoadOptions<'a> {
72 pub verify_integrity: bool,
73 pub verify_signatures: bool,
74 pub trusted_runtime: bool,
75 pub enforce_requires: bool,
76 pub allowed_networks: Vec<String>,
77 pub trust_policy: Option<TrustPolicy>,
78 pub rekor_client: Option<&'a dyn RekorClient>,
79 pub sigstore_verifier: Option<&'a dyn SigstoreVerifier>,
80 pub did_web_verifier: Option<&'a dyn DidWebVerifier>,
81}
82
83mod loader;
84mod names;
85mod paths;
86mod validation;
87
88pub use loader::{
89 load_config, load_config_preset, load_config_preset_with_options, load_config_with_options,
90};
91pub use names::{validate_module, validate_preset, validate_version};
92pub use paths::resolve_config_dir;