Skip to main content
Glama
input_sources.rs6.2 kB
use std::collections::VecDeque; use serde::{ Deserialize, Serialize, }; use thiserror::Error; use crate::{ DalContext, InputSocket, InputSocketId, OutputSocket, OutputSocketId, Prop, PropId, PropKind, SchemaVariant, SchemaVariantError, SchemaVariantId, WorkspaceSnapshotError, prop::PropError, socket::{ input::InputSocketError, output::OutputSocketError, }, }; #[remain::sorted] #[derive(Error, Debug)] pub enum InputSourcesError { #[error("input socket error: {0}")] InputSocket(#[from] InputSocketError), #[error("output socket error: {0}")] OutputSocket(#[from] OutputSocketError), #[error("prop error: {0}")] Prop(#[from] PropError), #[error("schema variant error: {0}")] SchemaVariant(#[from] SchemaVariantError), #[error("workspace snapshot error: {0}")] WorkspaceSnapshot(#[from] WorkspaceSnapshotError), } type InputSourcesResult<T> = Result<T, InputSourcesError>; #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "camelCase")] pub struct InputSocketView { pub schema_variant_id: SchemaVariantId, pub input_socket_id: InputSocketId, pub name: String, } #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "camelCase")] pub struct OutputSocketView { pub schema_variant_id: SchemaVariantId, pub output_socket_id: OutputSocketId, pub name: String, } #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "camelCase")] pub struct InputSourceProp { pub schema_variant_id: SchemaVariantId, pub prop_id: PropId, pub kind: PropKind, pub name: String, pub path: String, pub eligible_for_output: bool, } #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "camelCase")] pub struct InputSources { pub input_sockets: Vec<InputSocketView>, pub output_sockets: Vec<OutputSocketView>, pub props: Vec<InputSourceProp>, } impl InputSources { /// Assemble [`InputSources`] for all [`SchemaVariants`](SchemaVariant) in the workspace. pub async fn assemble_for_all_schema_variants(ctx: &DalContext) -> InputSourcesResult<Self> { let all_schema_variant_ids = SchemaVariant::list_default_ids(ctx).await?; let mut input_socket_views = Vec::new(); let mut output_socket_views = Vec::new(); for schema_variant_id in &all_schema_variant_ids { let (input_socket_views_for_schema_variant, output_socket_views_for_schema_variant) = Self::assemble_socket_views(ctx, *schema_variant_id).await?; input_socket_views.extend(input_socket_views_for_schema_variant); output_socket_views.extend(output_socket_views_for_schema_variant); } let mut input_source_props = Vec::new(); for schema_variant_id in all_schema_variant_ids { let input_source_props_for_schema_variant = Self::assemble_input_source_props(ctx, schema_variant_id).await?; input_source_props.extend(input_source_props_for_schema_variant); } Ok(Self { input_sockets: input_socket_views, output_sockets: output_socket_views, props: input_source_props, }) } /// Assemble [`InputSources`] for the provided [`SchemaVariantId`](SchemaVariant) in the workspace. pub async fn assemble( ctx: &DalContext, schema_variant_id: SchemaVariantId, ) -> InputSourcesResult<Self> { let (input_socket_views, output_socket_views) = Self::assemble_socket_views(ctx, schema_variant_id).await?; let input_source_props = Self::assemble_input_source_props(ctx, schema_variant_id).await?; Ok(Self { input_sockets: input_socket_views, output_sockets: output_socket_views, props: input_source_props, }) } async fn assemble_socket_views( ctx: &DalContext, schema_variant_id: SchemaVariantId, ) -> InputSourcesResult<(Vec<InputSocketView>, Vec<OutputSocketView>)> { let input_sockets = InputSocket::list(ctx, schema_variant_id).await?; let output_sockets = OutputSocket::list(ctx, schema_variant_id).await?; let input_socket_views = input_sockets .iter() .map(|socket| InputSocketView { schema_variant_id, input_socket_id: socket.id(), name: socket.name().to_owned(), }) .collect(); let output_socket_views = output_sockets .iter() .map(|socket| OutputSocketView { schema_variant_id, output_socket_id: socket.id(), name: socket.name().to_owned(), }) .collect(); Ok((input_socket_views, output_socket_views)) } async fn assemble_input_source_props( ctx: &DalContext, schema_variant_id: SchemaVariantId, ) -> InputSourcesResult<Vec<InputSourceProp>> { let root_prop_id = SchemaVariant::get_root_prop_id(ctx, schema_variant_id).await?; let root_prop = Prop::get_by_id(ctx, root_prop_id).await?; let mut work_queue = VecDeque::new(); work_queue.push_back(root_prop); let mut input_socket_props = Vec::new(); while let Some(prop) = work_queue.pop_front() { // Only descend on object props. if PropKind::Object == prop.kind { work_queue.extend(Prop::direct_child_props_ordered(ctx, prop.id).await?); } let path = prop.path(ctx).await?.with_replaced_sep_and_prefix("/"); let eligible_for_output = path == "/root/resource_value" || path == "/root/si/color" || path.starts_with("/root/domain/") || path.starts_with("/root/resource_value/"); input_socket_props.push(InputSourceProp { schema_variant_id, prop_id: prop.id, kind: prop.kind, name: prop.name.to_owned(), path, eligible_for_output, }) } Ok(input_socket_props) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server