mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-05 08:10:39 +00:00
Extract fabro-graphviz crate from fabro-workflows
Move the self-contained graph/ and parser/ modules into a new fabro-graphviz crate so the Graphviz DOT parser can be used without pulling in the full workflow engine. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
eb7089ece9
commit
b822a76f79
46 changed files with 140 additions and 99 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
|
@ -1284,6 +1284,7 @@ dependencies = [
|
|||
"fabro-db",
|
||||
"fabro-exe",
|
||||
"fabro-github",
|
||||
"fabro-graphviz",
|
||||
"fabro-llm",
|
||||
"fabro-types",
|
||||
"fabro-util",
|
||||
|
|
@ -1469,6 +1470,15 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fabro-graphviz"
|
||||
version = "0.174.0"
|
||||
dependencies = [
|
||||
"nom",
|
||||
"serde",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fabro-linear"
|
||||
version = "0.174.0"
|
||||
|
|
@ -1671,6 +1681,7 @@ dependencies = [
|
|||
"fabro-exe",
|
||||
"fabro-git-storage",
|
||||
"fabro-github",
|
||||
"fabro-graphviz",
|
||||
"fabro-llm",
|
||||
"fabro-mcp",
|
||||
"fabro-ssh",
|
||||
|
|
@ -1680,7 +1691,6 @@ dependencies = [
|
|||
"hex",
|
||||
"indicatif",
|
||||
"mockito",
|
||||
"nom",
|
||||
"predicates",
|
||||
"rand 0.8.5",
|
||||
"regex",
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ doctest = false
|
|||
|
||||
[dependencies]
|
||||
fabro-config = { path = "../fabro-config" }
|
||||
fabro-graphviz = { path = "../fabro-graphviz" }
|
||||
fabro-workflows = { path = "../fabro-workflows", features = ["exedev"] }
|
||||
fabro-github = { path = "../fabro-github" }
|
||||
fabro-agent = { path = "../fabro-agent" }
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ impl<T: serde::Serialize> ListResponse<T> {
|
|||
/// Snapshot of a managed run.
|
||||
struct ManagedRun {
|
||||
dot_source: String,
|
||||
graph: fabro_workflows::graph::Graph,
|
||||
graph: fabro_graphviz::graph::Graph,
|
||||
status: RunStatus,
|
||||
error: Option<String>,
|
||||
created_at: chrono::DateTime<chrono::Utc>,
|
||||
|
|
|
|||
14
lib/crates/fabro-graphviz/Cargo.toml
Normal file
14
lib/crates/fabro-graphviz/Cargo.toml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "fabro-graphviz"
|
||||
edition.workspace = true
|
||||
version.workspace = true
|
||||
license.workspace = true
|
||||
description = "Graphviz DOT parser and typed graph data model"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
nom = "7"
|
||||
serde = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
7
lib/crates/fabro-graphviz/src/error.rs
Normal file
7
lib/crates/fabro-graphviz/src/error.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum GraphvizError {
|
||||
#[error("Parse error: {0}")]
|
||||
Parse(String),
|
||||
}
|
||||
3
lib/crates/fabro-graphviz/src/lib.rs
Normal file
3
lib/crates/fabro-graphviz/src/lib.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
pub mod error;
|
||||
pub mod graph;
|
||||
pub mod parser;
|
||||
|
|
@ -3,7 +3,7 @@ pub mod grammar;
|
|||
pub mod lexer;
|
||||
pub mod semantic;
|
||||
|
||||
use crate::error::FabroError;
|
||||
use crate::error::GraphvizError;
|
||||
use crate::graph::types::Graph;
|
||||
|
||||
use self::ast::DotGraph;
|
||||
|
|
@ -17,14 +17,14 @@ use self::ast::DotGraph;
|
|||
///
|
||||
/// Returns an error if the input is not valid DOT syntax or contains
|
||||
/// trailing content after the graph definition.
|
||||
pub fn parse_ast(input: &str) -> Result<DotGraph, FabroError> {
|
||||
pub fn parse_ast(input: &str) -> Result<DotGraph, GraphvizError> {
|
||||
let stripped = lexer::strip_comments(input);
|
||||
let (rest, dot_graph) = grammar::parse_dot_graph(&stripped)
|
||||
.map_err(|e| FabroError::Parse(format!("grammar error: {e}")))?;
|
||||
.map_err(|e| GraphvizError::Parse(format!("grammar error: {e}")))?;
|
||||
|
||||
let remaining = rest.trim();
|
||||
if !remaining.is_empty() {
|
||||
return Err(FabroError::Parse(format!(
|
||||
return Err(GraphvizError::Parse(format!(
|
||||
"unexpected trailing content: {:?}",
|
||||
&remaining[..remaining.len().min(50)]
|
||||
)));
|
||||
|
|
@ -42,7 +42,7 @@ pub fn parse_ast(input: &str) -> Result<DotGraph, FabroError> {
|
|||
///
|
||||
/// Returns an error if the input is not valid DOT syntax or contains
|
||||
/// trailing content after the graph definition.
|
||||
pub fn parse(input: &str) -> Result<Graph, FabroError> {
|
||||
pub fn parse(input: &str) -> Result<Graph, GraphvizError> {
|
||||
let dot_graph = parse_ast(input)?;
|
||||
semantic::ast_to_graph(&dot_graph)
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::error::FabroError;
|
||||
use crate::error::GraphvizError;
|
||||
use crate::graph::types::{AttrValue, Edge, Graph, Node};
|
||||
use crate::parser::ast::{AstValue, AttrBlock, DotGraph, Statement};
|
||||
|
||||
|
|
@ -267,7 +267,7 @@ impl SemanticState {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the AST cannot be converted to a valid graph.
|
||||
pub fn ast_to_graph(dot: &DotGraph) -> Result<Graph, FabroError> {
|
||||
pub fn ast_to_graph(dot: &DotGraph) -> Result<Graph, GraphvizError> {
|
||||
let mut state = SemanticState::new(dot.name.clone());
|
||||
let empty = HashMap::new();
|
||||
state.process_statements(&dot.statements, None, &empty, &empty);
|
||||
|
|
@ -21,6 +21,7 @@ clap.workspace = true
|
|||
anyhow.workspace = true
|
||||
dotenvy.workspace = true
|
||||
fabro-agent = { path = "../fabro-agent" }
|
||||
fabro-graphviz = { path = "../fabro-graphviz" }
|
||||
fabro-devcontainer = { path = "../fabro-devcontainer" }
|
||||
fabro-exe = { path = "../fabro-exe", optional = true }
|
||||
fabro-ssh = { path = "../fabro-ssh" }
|
||||
|
|
@ -39,7 +40,6 @@ rand.workspace = true
|
|||
async-trait.workspace = true
|
||||
futures.workspace = true
|
||||
chrono = { workspace = true, features = ["serde"] }
|
||||
nom = "7"
|
||||
toml.workspace = true
|
||||
dirs = "6"
|
||||
dialoguer.workspace = true
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ use fabro_llm::provider::Provider;
|
|||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::WorkflowRunEvent;
|
||||
use crate::graph::Node;
|
||||
use crate::handler::agent::{CodergenBackend, CodergenResult};
|
||||
use crate::outcome::StageUsage;
|
||||
use fabro_graphviz::graph::Node;
|
||||
|
||||
fn build_profile(model: &str, provider: Provider) -> Box<dyn ProviderProfile> {
|
||||
match provider {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ use fabro_llm::provider::Provider;
|
|||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::{EventEmitter, WorkflowRunEvent};
|
||||
use crate::graph::Node;
|
||||
use crate::handler::agent::{CodergenBackend, CodergenResult};
|
||||
use crate::outcome::StageUsage;
|
||||
use fabro_graphviz::graph::Node;
|
||||
|
||||
/// Maps a provider to its corresponding CLI tool metadata.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
|
|
@ -796,7 +796,7 @@ impl CodergenBackend for BackendRouter {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::AttrValue;
|
||||
use fabro_graphviz::graph::AttrValue;
|
||||
|
||||
// -- AgentCli --
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ pub fn parse_command(args: &ParseArgs) -> anyhow::Result<()> {
|
|||
fn parse_command_to(args: &ParseArgs, mut out: impl Write) -> anyhow::Result<()> {
|
||||
let (dot_path, _cfg) = super::project_config::resolve_workflow(&args.workflow)?;
|
||||
let source = read_workflow_file(&dot_path)?;
|
||||
let ast = crate::parser::parse_ast(&source)?;
|
||||
let ast = fabro_graphviz::parser::parse_ast(&source)?;
|
||||
serde_json::to_writer_pretty(&mut out, &ast)?;
|
||||
writeln!(out)?;
|
||||
Ok(())
|
||||
|
|
@ -24,7 +24,7 @@ fn parse_command_to(args: &ParseArgs, mut out: impl Write) -> anyhow::Result<()>
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::parser::ast::DotGraph;
|
||||
use fabro_graphviz::parser::ast::DotGraph;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use git2::{Oid, Repository, Signature};
|
|||
|
||||
use crate::checkpoint::Checkpoint;
|
||||
use crate::git::MetadataStore;
|
||||
use crate::graph::types::Graph;
|
||||
use fabro_graphviz::graph::types::Graph;
|
||||
|
||||
/// Rewind a workflow run to an earlier checkpoint.
|
||||
#[derive(Debug, Args)]
|
||||
|
|
@ -484,7 +484,7 @@ pub fn load_parallel_map(store: &Store, run_id: &str) -> HashMap<String, String>
|
|||
_ => return HashMap::new(),
|
||||
};
|
||||
let dot_source = String::from_utf8_lossy(&graph_bytes);
|
||||
let graph = match crate::parser::parse(&dot_source) {
|
||||
let graph = match fabro_graphviz::parser::parse(&dot_source) {
|
||||
Ok(g) => g,
|
||||
Err(_) => return HashMap::new(),
|
||||
};
|
||||
|
|
@ -708,50 +708,50 @@ mod tests {
|
|||
#[test]
|
||||
fn parallel_interior_detection() {
|
||||
let mut graph = Graph::new("test");
|
||||
let mut parallel_node = crate::graph::types::Node::new("parallel1");
|
||||
let mut parallel_node = fabro_graphviz::graph::types::Node::new("parallel1");
|
||||
parallel_node.attrs.insert(
|
||||
"shape".to_string(),
|
||||
crate::graph::types::AttrValue::String("component".to_string()),
|
||||
fabro_graphviz::graph::types::AttrValue::String("component".to_string()),
|
||||
);
|
||||
graph.nodes.insert("parallel1".to_string(), parallel_node);
|
||||
|
||||
let mut fan_in = crate::graph::types::Node::new("fan_in1");
|
||||
let mut fan_in = fabro_graphviz::graph::types::Node::new("fan_in1");
|
||||
fan_in.attrs.insert(
|
||||
"shape".to_string(),
|
||||
crate::graph::types::AttrValue::String("tripleoctagon".to_string()),
|
||||
fabro_graphviz::graph::types::AttrValue::String("tripleoctagon".to_string()),
|
||||
);
|
||||
graph.nodes.insert("fan_in1".to_string(), fan_in);
|
||||
|
||||
let mut a = crate::graph::types::Node::new("a");
|
||||
let mut a = fabro_graphviz::graph::types::Node::new("a");
|
||||
a.attrs.insert(
|
||||
"shape".to_string(),
|
||||
crate::graph::types::AttrValue::String("box".to_string()),
|
||||
fabro_graphviz::graph::types::AttrValue::String("box".to_string()),
|
||||
);
|
||||
graph.nodes.insert("a".to_string(), a);
|
||||
|
||||
let mut b = crate::graph::types::Node::new("b");
|
||||
let mut b = fabro_graphviz::graph::types::Node::new("b");
|
||||
b.attrs.insert(
|
||||
"shape".to_string(),
|
||||
crate::graph::types::AttrValue::String("box".to_string()),
|
||||
fabro_graphviz::graph::types::AttrValue::String("box".to_string()),
|
||||
);
|
||||
graph.nodes.insert("b".to_string(), b);
|
||||
|
||||
graph.edges.push(crate::graph::types::Edge {
|
||||
graph.edges.push(fabro_graphviz::graph::types::Edge {
|
||||
from: "parallel1".to_string(),
|
||||
to: "a".to_string(),
|
||||
attrs: HashMap::new(),
|
||||
});
|
||||
graph.edges.push(crate::graph::types::Edge {
|
||||
graph.edges.push(fabro_graphviz::graph::types::Edge {
|
||||
from: "parallel1".to_string(),
|
||||
to: "b".to_string(),
|
||||
attrs: HashMap::new(),
|
||||
});
|
||||
graph.edges.push(crate::graph::types::Edge {
|
||||
graph.edges.push(fabro_graphviz::graph::types::Edge {
|
||||
from: "a".to_string(),
|
||||
to: "fan_in1".to_string(),
|
||||
attrs: HashMap::new(),
|
||||
});
|
||||
graph.edges.push(crate::graph::types::Edge {
|
||||
graph.edges.push(fabro_graphviz::graph::types::Edge {
|
||||
from: "b".to_string(),
|
||||
to: "fan_in1".to_string(),
|
||||
attrs: HashMap::new(),
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ fn resolve_cli_goal(
|
|||
/// Apply goal to the graph from TOML config or CLI flag.
|
||||
/// Precedence: CLI `--goal` / `--goal-file` > TOML `goal` > DOT `graph [goal="..."]`.
|
||||
fn apply_goal_override(
|
||||
graph: &mut crate::graph::types::Graph,
|
||||
graph: &mut fabro_graphviz::graph::types::Graph,
|
||||
cli_goal: Option<&str>,
|
||||
toml_goal: Option<&str>,
|
||||
) {
|
||||
|
|
@ -68,7 +68,7 @@ fn apply_goal_override(
|
|||
debug!(goal = %goal, "overriding graph goal");
|
||||
graph.attrs.insert(
|
||||
"goal".to_string(),
|
||||
crate::graph::types::AttrValue::String(goal.to_string()),
|
||||
fabro_graphviz::graph::types::AttrValue::String(goal.to_string()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ fn resolve_model_provider(
|
|||
cli_provider: Option<&str>,
|
||||
run_cfg: Option<&WorkflowRunConfig>,
|
||||
run_defaults: &RunDefaults,
|
||||
graph: &crate::graph::types::Graph,
|
||||
graph: &fabro_graphviz::graph::types::Graph,
|
||||
) -> (String, Option<String>) {
|
||||
let toml_model = run_cfg
|
||||
.and_then(|c| c.llm.as_ref())
|
||||
|
|
@ -403,13 +403,13 @@ pub async fn run_command(
|
|||
apply_goal_override(&mut graph, cli_goal.as_deref(), toml_goal);
|
||||
|
||||
// Inline @file references in the (possibly overridden) goal
|
||||
if let Some(crate::graph::types::AttrValue::String(goal)) = graph.attrs.get("goal") {
|
||||
if let Some(fabro_graphviz::graph::types::AttrValue::String(goal)) = graph.attrs.get("goal") {
|
||||
let fallback = dirs::home_dir().map(|h| h.join(".fabro"));
|
||||
let resolved = crate::transform::resolve_file_ref(goal, dot_dir, fallback.as_deref());
|
||||
if resolved != *goal {
|
||||
graph.attrs.insert(
|
||||
"goal".to_string(),
|
||||
crate::graph::types::AttrValue::String(resolved),
|
||||
fabro_graphviz::graph::types::AttrValue::String(resolved),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1928,7 +1928,7 @@ fn print_assets(run_dir: &std::path::Path, styles: &Styles) {
|
|||
/// a styled check report.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn run_preflight(
|
||||
graph: &crate::graph::types::Graph,
|
||||
graph: &fabro_graphviz::graph::types::Graph,
|
||||
run_cfg: &Option<run_config::WorkflowRunConfig>,
|
||||
args: &RunArgs,
|
||||
run_defaults: &RunDefaults,
|
||||
|
|
@ -2113,7 +2113,7 @@ async fn run_preflight(
|
|||
// Collect all distinct (model, provider) pairs from LLM nodes
|
||||
let mut model_providers = std::collections::BTreeSet::new();
|
||||
for node in graph.nodes.values() {
|
||||
if !crate::graph::types::is_llm_handler_type(node.handler_type()) {
|
||||
if !fabro_graphviz::graph::types::is_llm_handler_type(node.handler_type()) {
|
||||
continue;
|
||||
}
|
||||
let node_model = node.model().unwrap_or(&model);
|
||||
|
|
@ -2501,7 +2501,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn apply_goal_override_cli_wins_over_toml() {
|
||||
use crate::graph::types::{AttrValue, Graph};
|
||||
use fabro_graphviz::graph::types::{AttrValue, Graph};
|
||||
let mut graph = Graph::new("test");
|
||||
graph.attrs.insert(
|
||||
"goal".to_string(),
|
||||
|
|
@ -2513,7 +2513,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn apply_goal_override_toml_wins_over_dot() {
|
||||
use crate::graph::types::{AttrValue, Graph};
|
||||
use fabro_graphviz::graph::types::{AttrValue, Graph};
|
||||
let mut graph = Graph::new("test");
|
||||
graph.attrs.insert(
|
||||
"goal".to_string(),
|
||||
|
|
@ -2525,7 +2525,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn apply_goal_override_noop_when_none() {
|
||||
use crate::graph::types::{AttrValue, Graph};
|
||||
use fabro_graphviz::graph::types::{AttrValue, Graph};
|
||||
let mut graph = Graph::new("test");
|
||||
graph.attrs.insert(
|
||||
"goal".to_string(),
|
||||
|
|
@ -2558,7 +2558,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn resolve_model_provider_defaults() {
|
||||
let graph = crate::graph::types::Graph::new("test");
|
||||
let graph = fabro_graphviz::graph::types::Graph::new("test");
|
||||
let defaults = RunDefaults::default();
|
||||
let (model, provider) = resolve_model_provider(None, None, None, &defaults, &graph);
|
||||
assert_eq!(model, "claude-opus-4-6");
|
||||
|
|
@ -2568,7 +2568,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn resolve_model_provider_cli_overrides_toml() {
|
||||
let graph = crate::graph::types::Graph::new("test");
|
||||
let graph = fabro_graphviz::graph::types::Graph::new("test");
|
||||
let defaults = RunDefaults::default();
|
||||
let cfg = run_config::WorkflowRunConfig {
|
||||
version: 1,
|
||||
|
|
@ -2603,8 +2603,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn resolve_model_provider_toml_overrides_graph() {
|
||||
use crate::graph::types::AttrValue;
|
||||
let mut graph = crate::graph::types::Graph::new("test");
|
||||
use fabro_graphviz::graph::types::AttrValue;
|
||||
let mut graph = fabro_graphviz::graph::types::Graph::new("test");
|
||||
graph.attrs.insert(
|
||||
"default_model".to_string(),
|
||||
AttrValue::String("graph-model".to_string()),
|
||||
|
|
@ -2642,8 +2642,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn resolve_model_provider_graph_attrs_used_as_fallback() {
|
||||
use crate::graph::types::AttrValue;
|
||||
let mut graph = crate::graph::types::Graph::new("test");
|
||||
use fabro_graphviz::graph::types::AttrValue;
|
||||
let mut graph = fabro_graphviz::graph::types::Graph::new("test");
|
||||
graph.attrs.insert(
|
||||
"default_model".to_string(),
|
||||
AttrValue::String("gpt-5.2".to_string()),
|
||||
|
|
@ -2661,7 +2661,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn resolve_model_provider_alias_expansion() {
|
||||
let graph = crate::graph::types::Graph::new("test");
|
||||
let graph = fabro_graphviz::graph::types::Graph::new("test");
|
||||
let defaults = RunDefaults::default();
|
||||
let (model, provider) = resolve_model_provider(Some("opus"), None, None, &defaults, &graph);
|
||||
assert_eq!(model, "claude-opus-4-6");
|
||||
|
|
@ -2670,7 +2670,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn resolve_model_provider_run_defaults_used() {
|
||||
let graph = crate::graph::types::Graph::new("test");
|
||||
let graph = fabro_graphviz::graph::types::Graph::new("test");
|
||||
let defaults = RunDefaults {
|
||||
llm: Some(run_config::LlmConfig {
|
||||
model: Some("default-model".to_string()),
|
||||
|
|
@ -2686,7 +2686,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn resolve_model_provider_toml_overrides_run_defaults() {
|
||||
let graph = crate::graph::types::Graph::new("test");
|
||||
let graph = fabro_graphviz::graph::types::Graph::new("test");
|
||||
let defaults = RunDefaults {
|
||||
llm: Some(run_config::LlmConfig {
|
||||
model: Some("default-model".to_string()),
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ mod tests {
|
|||
let content =
|
||||
fs::read_to_string(tmp.path().join("fabro/workflows/test-wf/workflow.fabro")).unwrap();
|
||||
|
||||
let graph = crate::parser::parse(&content).expect("generated .fabro should parse");
|
||||
let graph = fabro_graphviz::parser::parse(&content).expect("generated .fabro should parse");
|
||||
let diagnostics = crate::validation::validate(&graph, &[]);
|
||||
let errors: Vec<_> = diagnostics
|
||||
.iter()
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@ use crate::context;
|
|||
use crate::context::Context;
|
||||
use crate::error::{FabroError, FailureClass, FailureSignature, Result};
|
||||
use crate::event::{EventEmitter, WorkflowRunEvent};
|
||||
use crate::graph::{Edge, Graph, Node};
|
||||
use crate::handler::{EngineServices, HandlerRegistry};
|
||||
use crate::hook::{HookContext, HookDecision, HookEvent, HookRunner};
|
||||
use crate::interviewer::Interviewer;
|
||||
use crate::millis_u64;
|
||||
use crate::outcome::{Outcome, StageStatus};
|
||||
use crate::preamble::build_preamble;
|
||||
use fabro_graphviz::graph::{Edge, Graph, Node};
|
||||
|
||||
/// Classify the failure mode of a completed outcome.
|
||||
///
|
||||
|
|
@ -2499,10 +2499,10 @@ impl WorkflowRunEngine {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::AttrValue;
|
||||
use crate::handler::start::StartHandler;
|
||||
use crate::handler::Handler as HandlerTrait;
|
||||
use async_trait::async_trait;
|
||||
use fabro_graphviz::graph::AttrValue;
|
||||
use std::time::Duration;
|
||||
|
||||
fn local_env() -> Arc<dyn Sandbox> {
|
||||
|
|
|
|||
|
|
@ -417,6 +417,14 @@ impl From<SdkError> for FabroError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<fabro_graphviz::error::GraphvizError> for FabroError {
|
||||
fn from(e: fabro_graphviz::error::GraphvizError) -> Self {
|
||||
match e {
|
||||
fabro_graphviz::error::GraphvizError::Parse(msg) => FabroError::Parse(msg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, FabroError>;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ use crate::context::keys;
|
|||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::EventEmitter;
|
||||
use crate::graph::{Graph, Node};
|
||||
use crate::outcome::{Outcome, StageUsage};
|
||||
use fabro_graphviz::graph::{Graph, Node};
|
||||
|
||||
use super::{EngineServices, Handler};
|
||||
|
||||
|
|
@ -375,7 +375,7 @@ impl Handler for AgentHandler {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use crate::event::EventEmitter;
|
||||
use crate::graph::AttrValue;
|
||||
use fabro_graphviz::graph::AttrValue;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn make_services() -> EngineServices {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ use async_trait::async_trait;
|
|||
use crate::context::keys;
|
||||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::graph::{Graph, Node};
|
||||
use crate::outcome::Outcome;
|
||||
use fabro_graphviz::graph::{Graph, Node};
|
||||
|
||||
use super::{EngineServices, Handler};
|
||||
|
||||
|
|
@ -177,8 +177,8 @@ impl Handler for CommandHandler {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::AttrValue;
|
||||
use crate::outcome::StageStatus;
|
||||
use fabro_graphviz::graph::AttrValue;
|
||||
use std::time::Duration;
|
||||
|
||||
fn make_services() -> EngineServices {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use async_trait::async_trait;
|
|||
|
||||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::graph::{Graph, Node};
|
||||
use crate::outcome::Outcome;
|
||||
use fabro_graphviz::graph::{Graph, Node};
|
||||
|
||||
use super::{EngineServices, Handler};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use async_trait::async_trait;
|
|||
|
||||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::graph::{Graph, Node};
|
||||
use crate::outcome::Outcome;
|
||||
use fabro_graphviz::graph::{Graph, Node};
|
||||
|
||||
use super::{EngineServices, Handler};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ use crate::context::keys;
|
|||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::EventEmitter;
|
||||
use crate::graph::{Graph, Node};
|
||||
use crate::outcome::Outcome;
|
||||
use fabro_graphviz::graph::{Graph, Node};
|
||||
|
||||
use super::agent::{CodergenBackend, CodergenResult};
|
||||
use super::{EngineServices, Handler};
|
||||
|
|
@ -402,7 +402,7 @@ mod tests {
|
|||
let mut node = Node::new("fan_in");
|
||||
node.attrs.insert(
|
||||
"prompt".to_string(),
|
||||
crate::graph::AttrValue::String("Pick the best branch".to_string()),
|
||||
fabro_graphviz::graph::AttrValue::String("Pick the best branch".to_string()),
|
||||
);
|
||||
let context = Context::new();
|
||||
context.set(
|
||||
|
|
@ -461,7 +461,7 @@ mod tests {
|
|||
let mut node = Node::new("fan_in");
|
||||
node.attrs.insert(
|
||||
"prompt".to_string(),
|
||||
crate::graph::AttrValue::String("Pick the best branch".to_string()),
|
||||
fabro_graphviz::graph::AttrValue::String("Pick the best branch".to_string()),
|
||||
);
|
||||
let context = Context::new();
|
||||
context.set(
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ use crate::context::keys;
|
|||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::{EventEmitter, WorkflowRunEvent};
|
||||
use crate::graph::{Graph, Node};
|
||||
use crate::interviewer::{
|
||||
Answer, AnswerValue, Interviewer, Question, QuestionOption, QuestionType,
|
||||
};
|
||||
use crate::millis_u64;
|
||||
use crate::outcome::Outcome;
|
||||
use fabro_graphviz::graph::{Graph, Node};
|
||||
|
||||
use super::{EngineServices, Handler};
|
||||
|
||||
|
|
@ -327,9 +327,9 @@ fn answer_text(answer: &Answer) -> String {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::{AttrValue, Edge};
|
||||
use crate::interviewer::auto_approve::AutoApproveInterviewer;
|
||||
use crate::interviewer::recording::RecordingInterviewer;
|
||||
use fabro_graphviz::graph::{AttrValue, Edge};
|
||||
|
||||
fn make_services() -> EngineServices {
|
||||
EngineServices::test_default()
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ use crate::context::keys;
|
|||
use crate::context::Context;
|
||||
use crate::engine::{RunConfig, WorkflowRunEngine};
|
||||
use crate::error::FabroError;
|
||||
use crate::graph::{Graph, Node};
|
||||
use crate::outcome::{Outcome, StageStatus};
|
||||
use crate::validation;
|
||||
use crate::workflow::{prepare_from_file, prepare_from_source};
|
||||
use fabro_graphviz::graph::{Graph, Node};
|
||||
|
||||
use super::{EngineServices, Handler};
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ impl Handler for SubWorkflowHandler {
|
|||
let poll_interval = node
|
||||
.attrs
|
||||
.get("manager.poll_interval")
|
||||
.and_then(super::super::graph::types::AttrValue::as_duration)
|
||||
.and_then(fabro_graphviz::graph::types::AttrValue::as_duration)
|
||||
.unwrap_or_else(|| {
|
||||
let raw = node
|
||||
.attrs
|
||||
|
|
@ -108,7 +108,7 @@ impl Handler for SubWorkflowHandler {
|
|||
let max_cycles = node
|
||||
.attrs
|
||||
.get("manager.max_cycles")
|
||||
.and_then(super::super::graph::types::AttrValue::as_i64)
|
||||
.and_then(fabro_graphviz::graph::types::AttrValue::as_i64)
|
||||
.unwrap_or(1000);
|
||||
let max_cycles = u64::try_from(max_cycles).unwrap_or(1000).max(1);
|
||||
|
||||
|
|
@ -254,10 +254,10 @@ impl Handler for SubWorkflowHandler {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::AttrValue;
|
||||
use crate::handler::exit::ExitHandler;
|
||||
use crate::handler::start::StartHandler;
|
||||
use crate::handler::HandlerRegistry;
|
||||
use fabro_graphviz::graph::AttrValue;
|
||||
|
||||
fn make_services() -> EngineServices {
|
||||
let mut services = EngineServices::test_default();
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ use crate::context::Context;
|
|||
use crate::engine::GitState;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::EventEmitter;
|
||||
use crate::graph::{shape_to_handler_type, Graph, Node};
|
||||
use crate::hook::{HookContext, HookDecision, HookRunner};
|
||||
use crate::interviewer::Interviewer;
|
||||
use crate::outcome::Outcome;
|
||||
use fabro_graphviz::graph::{shape_to_handler_type, Graph, Node};
|
||||
|
||||
/// Shared services available to all handlers during execution.
|
||||
pub struct EngineServices {
|
||||
|
|
@ -222,7 +222,7 @@ pub fn default_registry(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::AttrValue;
|
||||
use fabro_graphviz::graph::AttrValue;
|
||||
|
||||
struct TestHandler {
|
||||
_name: String,
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ use crate::context::keys;
|
|||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::WorkflowRunEvent;
|
||||
use crate::graph::{Graph, Node};
|
||||
use crate::hook::{HookContext, HookEvent};
|
||||
use crate::millis_u64;
|
||||
use crate::outcome::{Outcome, StageStatus};
|
||||
use fabro_agent::LocalSandbox;
|
||||
use fabro_graphviz::graph::{Graph, Node};
|
||||
|
||||
use super::{EngineServices, Handler};
|
||||
|
||||
|
|
@ -312,7 +312,7 @@ impl Handler for ParallelHandler {
|
|||
let max_parallel = node
|
||||
.attrs
|
||||
.get("max_parallel")
|
||||
.and_then(super::super::graph::types::AttrValue::as_i64)
|
||||
.and_then(fabro_graphviz::graph::types::AttrValue::as_i64)
|
||||
.unwrap_or(4);
|
||||
let max_parallel = usize::try_from(max_parallel).unwrap_or(4).max(1);
|
||||
|
||||
|
|
@ -830,7 +830,7 @@ fn find_join_node(results: &[BranchResult], graph: &Graph) -> Option<String> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::{AttrValue, Edge};
|
||||
use fabro_graphviz::graph::{AttrValue, Edge};
|
||||
|
||||
fn make_services() -> EngineServices {
|
||||
EngineServices::test_default()
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ use fabro_llm::provider::Provider;
|
|||
use crate::context::keys;
|
||||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::graph::{Graph, Node};
|
||||
use crate::outcome::Outcome;
|
||||
use fabro_graphviz::graph::{Graph, Node};
|
||||
|
||||
use super::agent::{
|
||||
expand_variables, extract_status_fields, truncate, CodergenBackend, CodergenResult,
|
||||
|
|
@ -158,7 +158,7 @@ impl Handler for PromptHandler {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::AttrValue;
|
||||
use fabro_graphviz::graph::AttrValue;
|
||||
use std::sync::Arc;
|
||||
use tempfile::TempDir;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use async_trait::async_trait;
|
|||
|
||||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::graph::{Graph, Node};
|
||||
use crate::outcome::Outcome;
|
||||
use fabro_graphviz::graph::{Graph, Node};
|
||||
|
||||
use super::{EngineServices, Handler};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use async_trait::async_trait;
|
|||
|
||||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::graph::{AttrValue, Graph, Node};
|
||||
use crate::outcome::Outcome;
|
||||
use fabro_graphviz::graph::{AttrValue, Graph, Node};
|
||||
|
||||
use super::{EngineServices, Handler};
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ pub struct HookContext {
|
|||
|
||||
impl HookContext {
|
||||
/// Populate node-related fields from a graph `Node`.
|
||||
pub fn set_node(&mut self, node: &crate::graph::Node) {
|
||||
pub fn set_node(&mut self, node: &fabro_graphviz::graph::Node) {
|
||||
self.node_id = Some(node.id.clone());
|
||||
self.node_label = Some(node.label().to_string());
|
||||
self.handler_type = node.handler_type().map(String::from);
|
||||
|
|
|
|||
|
|
@ -38,13 +38,11 @@ pub mod engine;
|
|||
pub mod error;
|
||||
pub mod event;
|
||||
pub mod git;
|
||||
pub mod graph;
|
||||
pub mod handler;
|
||||
pub mod hook;
|
||||
pub mod interviewer;
|
||||
pub mod manifest;
|
||||
pub mod outcome;
|
||||
pub mod parser;
|
||||
pub mod preamble;
|
||||
pub mod pull_request;
|
||||
pub mod retro;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use std::collections::{HashMap, HashSet};
|
|||
use crate::artifact::{artifact_path, format_artifact_reference};
|
||||
use crate::context::keys;
|
||||
use crate::context::Context;
|
||||
use crate::graph::{is_llm_handler_type, Graph, Node};
|
||||
use crate::outcome::Outcome;
|
||||
use fabro_graphviz::graph::{is_llm_handler_type, Graph, Node};
|
||||
|
||||
const COMPACT_OUTPUT_MAX_LINES: usize = 25;
|
||||
const SUMMARY_HIGH_OUTPUT_MAX_LINES: usize = 50;
|
||||
|
|
@ -612,8 +612,8 @@ fn build_summary_preamble(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::AttrValue;
|
||||
use crate::outcome::StageUsage;
|
||||
use fabro_graphviz::graph::AttrValue;
|
||||
|
||||
// --- truncate mode ---
|
||||
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ fn format_arc_details_section(conclusion: &Conclusion, dot_source: Option<&str>)
|
|||
|
||||
/// Parse a DOT source string to extract graph name, node count, and edge count.
|
||||
fn parse_dot_summary(dot: &str) -> (String, usize, usize) {
|
||||
match crate::parser::parse(dot) {
|
||||
match fabro_graphviz::parser::parse(dot) {
|
||||
Ok(graph) => (
|
||||
format!("{}.fabro", graph.name),
|
||||
graph.nodes.len(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::error::FabroError;
|
||||
use crate::graph::types::{AttrValue, Graph};
|
||||
use fabro_graphviz::graph::types::{AttrValue, Graph};
|
||||
|
||||
/// A parsed stylesheet selector.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
|
@ -235,7 +235,7 @@ pub fn apply_stylesheet(stylesheet: &Stylesheet, graph: &mut Graph) {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::types::Node;
|
||||
use fabro_graphviz::graph::types::Node;
|
||||
|
||||
#[test]
|
||||
fn parse_empty_stylesheet() {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::graph::{AttrValue, Edge, Graph, Node};
|
||||
use crate::stylesheet::{apply_stylesheet, parse_stylesheet};
|
||||
use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node};
|
||||
|
||||
/// A transform that modifies the pipeline graph after parsing and before validation.
|
||||
pub trait Transform {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ pub mod rules;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::error::FabroError;
|
||||
use crate::graph::Graph;
|
||||
use fabro_graphviz::graph::Graph;
|
||||
|
||||
/// Severity level for validation diagnostics.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
|
|
@ -80,7 +80,7 @@ pub fn validate_or_raise(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::{AttrValue, Edge, Graph, Node};
|
||||
use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node};
|
||||
|
||||
fn minimal_valid_graph() -> Graph {
|
||||
let mut g = Graph::new("test");
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::collections::{HashSet, VecDeque};
|
|||
use std::str::FromStr;
|
||||
|
||||
use crate::condition::parse_condition;
|
||||
use crate::graph::{is_llm_handler_type, AttrValue, Graph};
|
||||
use fabro_graphviz::graph::{is_llm_handler_type, AttrValue, Graph};
|
||||
|
||||
use super::{Diagnostic, LintRule, Severity};
|
||||
|
||||
|
|
@ -1165,7 +1165,7 @@ impl LintRule for RandomSelectionNoConditionsRule {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::{AttrValue, Edge, Node};
|
||||
use fabro_graphviz::graph::{AttrValue, Edge, Node};
|
||||
|
||||
fn minimal_graph() -> Graph {
|
||||
let mut g = Graph::new("test");
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use std::path::Path;
|
||||
|
||||
use crate::error::FabroError;
|
||||
use crate::graph::Graph;
|
||||
use crate::transform::{
|
||||
FileInliningTransform, ProviderInferenceTransform, StylesheetApplicationTransform, Transform,
|
||||
VariableExpansionTransform,
|
||||
};
|
||||
use crate::validation::{self, Diagnostic};
|
||||
use fabro_graphviz::graph::Graph;
|
||||
|
||||
/// Builder for configuring and executing a workflow preparation.
|
||||
/// Collects custom transforms that run after the built-in ones.
|
||||
|
|
@ -56,7 +56,7 @@ impl WorkflowBuilder {
|
|||
dot_source: &str,
|
||||
base_dir: Option<&Path>,
|
||||
) -> Result<(Graph, Vec<Diagnostic>), FabroError> {
|
||||
let mut graph = crate::parser::parse(dot_source)?;
|
||||
let mut graph = fabro_graphviz::parser::parse(dot_source)?;
|
||||
|
||||
// Built-in transforms (PreambleTransform moved to engine execution time)
|
||||
VariableExpansionTransform.apply(&mut graph);
|
||||
|
|
@ -113,7 +113,7 @@ pub fn prepare_from_source(dot_source: &str) -> Result<Graph, FabroError> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::graph::AttrValue;
|
||||
use fabro_graphviz::graph::AttrValue;
|
||||
|
||||
const MINIMAL_DOT: &str = r#"digraph Test {
|
||||
graph [goal="Build feature"]
|
||||
|
|
@ -184,7 +184,7 @@ mod tests {
|
|||
fn pipeline_builder_custom_transform() {
|
||||
struct TagTransform;
|
||||
impl Transform for TagTransform {
|
||||
fn apply(&self, graph: &mut crate::graph::Graph) {
|
||||
fn apply(&self, graph: &mut fabro_graphviz::graph::Graph) {
|
||||
for node in graph.nodes.values_mut() {
|
||||
node.attrs
|
||||
.insert("tagged".to_string(), AttrValue::Boolean(true));
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::path::Path;
|
||||
|
||||
use fabro_workflows::parser::parse;
|
||||
use fabro_graphviz::parser::parse;
|
||||
|
||||
fn parse_attractor_dot(filename: &str) -> Result<fabro_workflows::graph::types::Graph, String> {
|
||||
fn parse_attractor_dot(filename: &str) -> Result<fabro_graphviz::graph::types::Graph, String> {
|
||||
let path = Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../../../test/attractor")
|
||||
.join(filename);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use std::path::Path;
|
|||
use std::sync::Arc;
|
||||
|
||||
use fabro_agent::Sandbox;
|
||||
use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node};
|
||||
use fabro_llm::provider::Provider;
|
||||
use fabro_workflows::artifact::sync_artifacts_to_env;
|
||||
use fabro_workflows::checkpoint::Checkpoint;
|
||||
|
|
@ -16,7 +17,6 @@ use fabro_workflows::daytona_sandbox::{DaytonaConfig, DaytonaSandbox, DaytonaSna
|
|||
use fabro_workflows::engine::{RunConfig, WorkflowRunEngine};
|
||||
use fabro_workflows::error::FabroError;
|
||||
use fabro_workflows::event::EventEmitter;
|
||||
use fabro_workflows::graph::{AttrValue, Edge, Graph, Node};
|
||||
use fabro_workflows::handler::exit::ExitHandler;
|
||||
use fabro_workflows::handler::start::StartHandler;
|
||||
use fabro_workflows::handler::{Handler, HandlerRegistry};
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ use std::path::Path;
|
|||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node};
|
||||
use fabro_graphviz::parser::parse;
|
||||
use fabro_llm::provider::Provider;
|
||||
use fabro_workflows::checkpoint::Checkpoint;
|
||||
use fabro_workflows::cli::backend::AgentApiBackend;
|
||||
|
|
@ -10,7 +12,6 @@ use fabro_workflows::context::Context;
|
|||
use fabro_workflows::engine::{RunConfig, WorkflowRunEngine};
|
||||
use fabro_workflows::error::FabroError;
|
||||
use fabro_workflows::event::{EventEmitter, WorkflowRunEvent};
|
||||
use fabro_workflows::graph::{AttrValue, Edge, Graph, Node};
|
||||
use fabro_workflows::handler::agent::{AgentHandler, CodergenBackend, CodergenResult};
|
||||
use fabro_workflows::handler::command::CommandHandler;
|
||||
use fabro_workflows::handler::conditional::ConditionalHandler;
|
||||
|
|
@ -26,7 +27,6 @@ use fabro_workflows::interviewer::queue::QueueInterviewer;
|
|||
use fabro_workflows::interviewer::recording::RecordingInterviewer;
|
||||
use fabro_workflows::interviewer::{Answer, AnswerValue, Interviewer};
|
||||
use fabro_workflows::outcome::{Outcome, StageStatus};
|
||||
use fabro_workflows::parser::parse;
|
||||
use fabro_workflows::stylesheet::{apply_stylesheet, parse_stylesheet};
|
||||
use fabro_workflows::transform::{
|
||||
StylesheetApplicationTransform, Transform, VariableExpansionTransform,
|
||||
|
|
@ -6015,9 +6015,9 @@ mod real_llm {
|
|||
|
||||
use async_trait::async_trait;
|
||||
|
||||
use fabro_graphviz::graph::Node;
|
||||
use fabro_workflows::context::Context;
|
||||
use fabro_workflows::error::FabroError;
|
||||
use fabro_workflows::graph::Node;
|
||||
use fabro_workflows::handler::agent::{AgentHandler, CodergenBackend, CodergenResult};
|
||||
|
||||
use fabro_llm::client::Client;
|
||||
|
|
@ -6105,10 +6105,10 @@ mod real_llm {
|
|||
}
|
||||
|
||||
use super::local_env;
|
||||
use fabro_graphviz::graph::{AttrValue, Edge, Graph};
|
||||
use fabro_workflows::checkpoint::Checkpoint;
|
||||
use fabro_workflows::engine::{RunConfig, WorkflowRunEngine};
|
||||
use fabro_workflows::event::EventEmitter;
|
||||
use fabro_workflows::graph::{AttrValue, Edge, Graph};
|
||||
use fabro_workflows::handler::exit::ExitHandler;
|
||||
use fabro_workflows::handler::human::HumanHandler;
|
||||
use fabro_workflows::handler::start::StartHandler;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue