feat: add comfyui sdk
This commit is contained in:
169
cargos/comfyui-sdk/templates/workflow_instance.rs
Normal file
169
cargos/comfyui-sdk/templates/workflow_instance.rs
Normal file
@@ -0,0 +1,169 @@
|
||||
//! WorkflowInstance implementation for executing parameterized workflows
|
||||
|
||||
use std::collections::HashMap;
|
||||
use crate::types::{ComfyUIWorkflow, ParameterValues, ComfyUINode};
|
||||
use crate::templates::WorkflowTemplate;
|
||||
use crate::error::{ComfyUIError, Result};
|
||||
use crate::utils::template_parser::apply_parameters;
|
||||
|
||||
/// Represents a workflow instance with applied parameters
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WorkflowInstance {
|
||||
template: WorkflowTemplate,
|
||||
parameters: ParameterValues,
|
||||
resolved_workflow: ComfyUIWorkflow,
|
||||
}
|
||||
|
||||
impl WorkflowInstance {
|
||||
/// Creates a new WorkflowInstance
|
||||
pub fn new(template: WorkflowTemplate, parameters: ParameterValues) -> Result<Self> {
|
||||
// Apply parameters to the workflow
|
||||
let resolved_workflow = apply_parameters(template.workflow(), ¶meters)?;
|
||||
|
||||
Ok(Self {
|
||||
template,
|
||||
parameters,
|
||||
resolved_workflow,
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets the original template
|
||||
pub fn template(&self) -> &WorkflowTemplate {
|
||||
&self.template
|
||||
}
|
||||
|
||||
/// Gets the applied parameters
|
||||
pub fn parameters(&self) -> &ParameterValues {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
/// Gets the resolved workflow with parameters applied
|
||||
pub fn workflow(&self) -> &ComfyUIWorkflow {
|
||||
&self.resolved_workflow
|
||||
}
|
||||
|
||||
/// Gets the template ID
|
||||
pub fn template_id(&self) -> &str {
|
||||
self.template.id()
|
||||
}
|
||||
|
||||
/// Gets the template name
|
||||
pub fn template_name(&self) -> &str {
|
||||
self.template.name()
|
||||
}
|
||||
|
||||
/// Gets a specific parameter value
|
||||
pub fn get_parameter(&self, name: &str) -> Option<&serde_json::Value> {
|
||||
self.parameters.get(name)
|
||||
}
|
||||
|
||||
/// Updates a parameter value and re-resolves the workflow
|
||||
pub fn set_parameter(&mut self, name: String, value: serde_json::Value) -> Result<()> {
|
||||
// Check if parameter exists in template
|
||||
if !self.template.has_parameter(&name) {
|
||||
return Err(ComfyUIError::parameter_validation(
|
||||
format!("Parameter '{}' does not exist in template", name)
|
||||
));
|
||||
}
|
||||
|
||||
// Update parameter
|
||||
self.parameters.insert(name, value);
|
||||
|
||||
// Validate updated parameters
|
||||
let validation = self.template.validate(&self.parameters);
|
||||
if !validation.valid {
|
||||
let error_messages: Vec<String> = validation.errors
|
||||
.iter()
|
||||
.map(|e| format!("{}: {}", e.path, e.message))
|
||||
.collect();
|
||||
return Err(ComfyUIError::parameter_validation(
|
||||
format!("Invalid parameters after update: {}", error_messages.join(", "))
|
||||
));
|
||||
}
|
||||
|
||||
// Re-resolve workflow
|
||||
self.resolved_workflow = apply_parameters(self.template.workflow(), &self.parameters)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Updates multiple parameters at once
|
||||
pub fn set_parameters(&mut self, parameters: HashMap<String, serde_json::Value>) -> Result<()> {
|
||||
// Check if all parameters exist in template
|
||||
for name in parameters.keys() {
|
||||
if !self.template.has_parameter(name) {
|
||||
return Err(ComfyUIError::parameter_validation(
|
||||
format!("Parameter '{}' does not exist in template", name)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Update parameters
|
||||
for (name, value) in parameters {
|
||||
self.parameters.insert(name, value);
|
||||
}
|
||||
|
||||
// Validate updated parameters
|
||||
let validation = self.template.validate(&self.parameters);
|
||||
if !validation.valid {
|
||||
let error_messages: Vec<String> = validation.errors
|
||||
.iter()
|
||||
.map(|e| format!("{}: {}", e.path, e.message))
|
||||
.collect();
|
||||
return Err(ComfyUIError::parameter_validation(
|
||||
format!("Invalid parameters after update: {}", error_messages.join(", "))
|
||||
));
|
||||
}
|
||||
|
||||
// Re-resolve workflow
|
||||
self.resolved_workflow = apply_parameters(self.template.workflow(), &self.parameters)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets a specific node from the resolved workflow
|
||||
pub fn get_node(&self, node_id: &str) -> Option<&ComfyUINode> {
|
||||
self.resolved_workflow.get(node_id)
|
||||
}
|
||||
|
||||
/// Gets all node IDs in the workflow
|
||||
pub fn get_node_ids(&self) -> Vec<&str> {
|
||||
self.resolved_workflow.keys().map(|s| s.as_str()).collect()
|
||||
}
|
||||
|
||||
/// Checks if the workflow contains a specific node
|
||||
pub fn has_node(&self, node_id: &str) -> bool {
|
||||
self.resolved_workflow.contains_key(node_id)
|
||||
}
|
||||
|
||||
/// Gets the number of nodes in the workflow
|
||||
pub fn node_count(&self) -> usize {
|
||||
self.resolved_workflow.len()
|
||||
}
|
||||
|
||||
/// Converts the instance to a JSON-serializable workflow
|
||||
pub fn to_workflow_json(&self) -> Result<serde_json::Value> {
|
||||
serde_json::to_value(&self.resolved_workflow)
|
||||
.map_err(ComfyUIError::from)
|
||||
}
|
||||
|
||||
/// Creates a clone with different parameters
|
||||
pub fn with_parameters(&self, parameters: ParameterValues) -> Result<Self> {
|
||||
Self::new(self.template.clone(), parameters)
|
||||
}
|
||||
|
||||
/// Validates the current instance
|
||||
pub fn validate(&self) -> Result<()> {
|
||||
let validation = self.template.validate(&self.parameters);
|
||||
if !validation.valid {
|
||||
let error_messages: Vec<String> = validation.errors
|
||||
.iter()
|
||||
.map(|e| format!("{}: {}", e.path, e.message))
|
||||
.collect();
|
||||
return Err(ComfyUIError::parameter_validation(
|
||||
format!("Instance validation failed: {}", error_messages.join(", "))
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user