Skip to main content

switchyard_runner/
algorithm_factory.rs

1// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Algorithm construction from deployment TOML without provider clients.
5
6use std::collections::BTreeMap;
7use std::sync::Arc;
8
9use libsy::{Algorithm, RuntimeModels};
10
11use crate::RunnerError;
12use crate::config::DeploymentConfig;
13
14pub(crate) type AlgorithmAndModels = (Arc<dyn Algorithm>, RuntimeModels);
15
16/// Parsed deployment configuration for building algorithms with host-owned execution.
17pub struct AlgorithmFactory {
18    pub(crate) config: DeploymentConfig,
19}
20
21impl AlgorithmFactory {
22    /// Parses deployment TOML without resolving credentials or constructing provider clients.
23    /// Invalid TOML returns a configuration error; routing settings are checked by [`Self::build`].
24    pub fn from_toml(source: &str) -> Result<Self, RunnerError> {
25        let config = toml::from_str(source).map_err(|error| {
26            RunnerError::configuration_source(format!("failed to parse TOML: {error}"), error)
27        })?;
28        Ok(Self { config })
29    }
30
31    /// Builds algorithms and their model groups, keyed by configured route `id`.
32    ///
33    /// LLM calls and outcomes use target names; the host resolves their provider IDs and
34    /// owns target prompts, provider settings and transport. Decision calls use provider IDs.
35    /// Reuse the returned algorithms across requests to retain algorithm-owned state.
36    pub fn build(&self) -> Result<BTreeMap<String, AlgorithmAndModels>, RunnerError> {
37        self.config.validate()?;
38        if self.config.requires_target_admission() {
39            return Err(RunnerError::configuration(
40                "target eligibility requires Runner admission; use Runner instead of AlgorithmFactory",
41            ));
42        }
43        self.config
44            .build_algorithms()
45            .map(|entry| {
46                let (_, config, algorithm) = entry?;
47                Ok((config.id.to_string(), algorithm))
48            })
49            .collect()
50    }
51}