Skip to main content

soma_provider_adapters/
static_rust.rs

1//! The generic, declarative `static-rust` provider kind: a drop-in manifest
2//! with no external process, sidecar, or upstream call, whose tools either
3//! echo a canned `meta.result` value or, absent one, echo their own call
4//! shape back for inspection/testing. Ported from the private `FileProvider`
5//! struct in Soma's filesystem loader (originally `soma-service`, now
6//! `crates/soma/application`), which is the actual product-neutral "static
7//! Rust provider abstraction" referenced by the architecture plan — Soma's
8//! own concrete built-in-actions provider (also historically named
9//! `static_rust.rs`) is a distinct, product-specific instance that dispatches
10//! into `SomaService` and stays in `crates/soma/application`.
11
12use std::{path::PathBuf, sync::Arc};
13
14use async_trait::async_trait;
15use serde_json::json;
16use soma_provider_core::{Provider, ProviderCall, ProviderCatalog, ProviderError, ProviderOutput};
17
18#[derive(Clone)]
19pub struct StaticEchoProvider {
20    path: PathBuf,
21    catalog: ProviderCatalog,
22}
23
24impl StaticEchoProvider {
25    pub fn new(path: PathBuf, catalog: ProviderCatalog) -> Self {
26        Self { path, catalog }
27    }
28
29    pub fn arc(path: PathBuf, catalog: ProviderCatalog) -> Arc<Self> {
30        Arc::new(Self::new(path, catalog))
31    }
32}
33
34#[async_trait]
35impl Provider for StaticEchoProvider {
36    fn catalog(&self) -> ProviderCatalog {
37        self.catalog.clone()
38    }
39
40    async fn call(&self, call: ProviderCall) -> Result<ProviderOutput, ProviderError> {
41        let tool = self
42            .catalog
43            .tools
44            .iter()
45            .find(|tool| tool.name == call.action)
46            .ok_or_else(|| {
47                ProviderError::validation(
48                    &self.catalog.provider.name,
49                    &call.action,
50                    "unknown_file_provider_action",
51                    format!(
52                        "provider file `{}` does not expose this action",
53                        self.path.display()
54                    ),
55                )
56            })?;
57
58        if let Some(result) = tool.meta.get("result").cloned() {
59            return Ok(ProviderOutput::json(result));
60        }
61
62        Ok(ProviderOutput::json(json!({
63            "kind": "file_provider_result",
64            "schema_version": 1,
65            "provider": self.catalog.provider.name,
66            "provider_kind": self.catalog.provider.kind.as_str(),
67            "action": call.action,
68            "params": call.params,
69            "source": self.path.display().to_string(),
70        })))
71    }
72}
73
74#[cfg(test)]
75#[path = "static_rust_tests.rs"]
76mod tests;