Skip to main content

codetether_agent/provider/tetherscript_provider/
runner.rs

1//! Thin Rust shell. Loads `.tether`, delegates every trait method.
2//!
3//! `LoadedPlugin` is `!Send`, so we create a fresh plugin per call
4//! inside `spawn_blocking`. The source and credentials are stored.
5
6use super::super::ModelInfo;
7use anyhow::{Context, Result};
8
9pub struct TetherScriptProvider {
10    name: String,
11    source: String,
12    api_key: String,
13    base_url: String,
14}
15
16impl Clone for TetherScriptProvider {
17    fn clone(&self) -> Self {
18        Self {
19            name: self.name.clone(),
20            source: self.source.clone(),
21            api_key: self.api_key.clone(),
22            base_url: self.base_url.clone(),
23        }
24    }
25}
26
27impl TetherScriptProvider {
28    pub fn new(source: &str, api_key: &str, base_url: &str, name: &str) -> Result<Self> {
29        Ok(Self {
30            name: name.into(),
31            source: source.into(),
32            api_key: api_key.into(),
33            base_url: base_url.into(),
34        })
35    }
36
37    pub(crate) fn make_plugin(&self) -> Result<tetherscript::plugin::LoadedPlugin> {
38        super::authority::host(&self.base_url, &self.api_key)
39            .load_source("p.tether", &self.source)
40            .context("load")
41    }
42
43    pub(crate) fn name_str(&self) -> &str {
44        &self.name
45    }
46
47    pub(crate) fn call_list_models(&self) -> Result<Vec<ModelInfo>> {
48        self.call_sync("list_models")
49            .and_then(|value| super::model_list::parse_models(value, &self.name))
50    }
51}