sim_lib_openai_server/runtime/
runners.rs1use std::{fmt, sync::Arc};
2
3use sim_kernel::{Cx, Error, Result};
4use sim_lib_agent_runner_core::{ModelCard, ModelRequest, ModelResponse, ModelRunner};
5
6#[derive(Clone, Default)]
8pub struct OpenAiRunnerRegistry {
9 entries: Vec<OpenAiRunnerEntry>,
10}
11
12#[derive(Clone)]
13struct OpenAiRunnerEntry {
14 model: String,
15 runner: Arc<dyn ModelRunner>,
16}
17
18impl fmt::Debug for OpenAiRunnerRegistry {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 f.debug_struct("OpenAiRunnerRegistry")
21 .field(
22 "models",
23 &self
24 .entries
25 .iter()
26 .map(|entry| entry.model.as_str())
27 .collect::<Vec<_>>(),
28 )
29 .finish()
30 }
31}
32
33impl OpenAiRunnerRegistry {
34 pub fn new() -> Self {
36 Self::default()
37 }
38
39 pub fn with_runner(mut self, model: impl Into<String>, runner: Arc<dyn ModelRunner>) -> Self {
41 self.register(model, runner);
42 self
43 }
44
45 pub fn register(&mut self, model: impl Into<String>, runner: Arc<dyn ModelRunner>) {
47 self.entries.push(OpenAiRunnerEntry {
48 model: model.into(),
49 runner,
50 });
51 }
52
53 pub fn cards(&self) -> Vec<ModelCard> {
59 self.entries
60 .iter()
61 .map(|entry| {
62 let mut card = entry.runner.card();
63 if card.model != entry.model {
64 card.extra.push((
65 sim_kernel::Expr::Symbol(sim_kernel::Symbol::new("runner-model")),
66 sim_kernel::Expr::String(card.model.clone()),
67 ));
68 card.model = entry.model.clone();
69 }
70 card
71 })
72 .collect()
73 }
74
75 pub fn infer(&self, cx: &mut Cx, model: &str, request: ModelRequest) -> Result<ModelResponse> {
79 let runner = self
80 .entries
81 .iter()
82 .find(|entry| entry.model == model)
83 .map(|entry| entry.runner.clone())
84 .ok_or_else(|| Error::Eval(format!("model_not_found: {model}")))?;
85 runner.infer(cx, request)
86 }
87
88 pub fn is_empty(&self) -> bool {
90 self.entries.is_empty()
91 }
92}