Skip to main content

sim_lib_agent/
runner_projection.rs

1use std::sync::Arc;
2
3use sim_kernel::{CapabilityName, Cx, Expr, Result, Symbol, Value};
4use sim_lib_server::ServerAddress;
5
6use crate::{
7    ComponentKind, ModelRunner, components::AgentComponent, components::ComponentBackend,
8    components::RunnerBackend, components::component_value, installed_codecs,
9};
10
11/// Metadata needed to project an existing [`ModelRunner`] as an agent runner.
12pub struct ExternalRunnerSpec {
13    /// Component symbol used by `runner/card`, `runner/market`, and `realize`.
14    pub symbol: Symbol,
15    /// Model id advertised by the component wrapper.
16    pub model: String,
17    /// Component-level capabilities checked before runner execution.
18    pub capabilities: Vec<CapabilityName>,
19    /// Extra component metadata exposed through the runner card.
20    pub spec: Vec<(Symbol, Expr)>,
21    /// The underlying provider-neutral runner implementation.
22    pub runner: Arc<dyn ModelRunner>,
23}
24
25/// Wraps a provider-neutral [`ModelRunner`] in the existing agent runner value.
26pub fn external_runner_value(cx: &mut Cx, spec: ExternalRunnerSpec) -> Result<Value> {
27    let mut component_spec = vec![
28        (
29            Symbol::new("backend"),
30            Expr::Symbol(Symbol::new("external")),
31        ),
32        (Symbol::new("model"), Expr::String(spec.model)),
33    ];
34    component_spec.extend(spec.spec);
35    component_value(
36        cx,
37        AgentComponent {
38            symbol: spec.symbol,
39            kind: ComponentKind::Runner,
40            capabilities: spec.capabilities,
41            address: ServerAddress::Local,
42            codecs: installed_codecs(cx),
43            spec: component_spec,
44            backend: ComponentBackend::Runner(RunnerBackend::External {
45                runner: spec.runner,
46            }),
47        },
48    )
49}