mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-06 02:48:25 +00:00
refactor(workflows): merge cost.rs into outcome.rs
Colocate compute_stage_cost and format_cost with StageUsage, eliminating a thin module that only imported from outcome. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
505b99c83f
commit
fca50d3336
24 changed files with 133 additions and 143 deletions
|
|
@ -21,12 +21,12 @@ use fabro_agent::LocalSandbox;
|
|||
use crate::error::ApiError;
|
||||
use crate::jwt_auth::{AuthMode, AuthenticatedService, AuthenticatedUser};
|
||||
use fabro_interview::{Answer, Interviewer, QuestionType, WebInterviewer};
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::context::Context;
|
||||
use fabro_workflows::event::{EventEmitter, WorkflowRunEvent};
|
||||
use fabro_workflows::handler::HandlerRegistry;
|
||||
use fabro_workflows::operations::{self, CreateOptions};
|
||||
use fabro_workflows::pipeline::{self, InitOptions};
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::run_settings::LifecycleConfig;
|
||||
use fabro_workflows::run_settings::RunSettings;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,14 +45,12 @@ fn inspect_run_dir(
|
|||
let conclusion = fabro_workflows::records::Conclusion::load(&run_dir.join("conclusion.json"))
|
||||
.ok()
|
||||
.and_then(|v| serde_json::to_value(v).ok());
|
||||
let checkpoint =
|
||||
fabro_workflows::records::Checkpoint::load(&run_dir.join("checkpoint.json"))
|
||||
.ok()
|
||||
.and_then(|v| serde_json::to_value(v).ok());
|
||||
let sandbox =
|
||||
fabro_workflows::records::SandboxRecord::load(&run_dir.join("sandbox.json"))
|
||||
.ok()
|
||||
.and_then(|v| serde_json::to_value(v).ok());
|
||||
let checkpoint = fabro_workflows::records::Checkpoint::load(&run_dir.join("checkpoint.json"))
|
||||
.ok()
|
||||
.and_then(|v| serde_json::to_value(v).ok());
|
||||
let sandbox = fabro_workflows::records::SandboxRecord::load(&run_dir.join("sandbox.json"))
|
||||
.ok()
|
||||
.and_then(|v| serde_json::to_value(v).ok());
|
||||
|
||||
Ok(InspectOutput {
|
||||
run_id: run_id.to_string(),
|
||||
|
|
|
|||
|
|
@ -325,8 +325,8 @@ async fn create_from(
|
|||
) -> Result<()> {
|
||||
let run_dir = fabro_workflows::run_lookup::resolve_run(base, &args.run_id)?.path;
|
||||
|
||||
let record = fabro_workflows::records::RunRecord::load(&run_dir)
|
||||
.context("Failed to load run.json")?;
|
||||
let record =
|
||||
fabro_workflows::records::RunRecord::load(&run_dir).context("Failed to load run.json")?;
|
||||
|
||||
let start = fabro_workflows::records::StartRecord::load(&run_dir)
|
||||
.context("Failed to load start.json")?;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ use fabro_config::config::FabroConfig;
|
|||
use fabro_interview::{AutoApproveInterviewer, ConsoleInterviewer, Interviewer};
|
||||
use fabro_model::{Catalog, Provider};
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::event::{EventEmitter, RunNoticeLevel};
|
||||
use fabro_workflows::handler::llm::{AgentApiBackend, AgentCliBackend, BackendRouter};
|
||||
use fabro_workflows::operations::{
|
||||
|
|
@ -20,6 +19,7 @@ use fabro_workflows::outcome::StageStatus;
|
|||
use fabro_workflows::pipeline::{
|
||||
build_conclusion, classify_engine_result, persist_terminal_outcome,
|
||||
};
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::records::RunRecord;
|
||||
use fabro_workflows::run_settings::{GitCheckpointSettings, LifecycleConfig, RunSettings};
|
||||
use fabro_workflows::sandbox_provider::SandboxProvider;
|
||||
|
|
@ -989,7 +989,7 @@ async fn run_resumed(
|
|||
acc.total_cache_read_tokens += u.cache_read_tokens.unwrap_or(0);
|
||||
acc.total_cache_write_tokens += u.cache_write_tokens.unwrap_or(0);
|
||||
acc.total_reasoning_tokens += u.reasoning_tokens.unwrap_or(0);
|
||||
if let Some(cost) = fabro_workflows::cost::compute_stage_cost(u) {
|
||||
if let Some(cost) = fabro_workflows::outcome::compute_stage_cost(u) {
|
||||
acc.total_cost += cost;
|
||||
acc.has_pricing = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ use fabro_config::{project as project_config, run as run_config, sandbox as sand
|
|||
use fabro_interview::{AutoApproveInterviewer, ConsoleInterviewer, FileInterviewer, Interviewer};
|
||||
use fabro_model::{Catalog, FallbackTarget, Provider};
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::cost::{compute_stage_cost, format_cost};
|
||||
use fabro_workflows::devcontainer_bridge;
|
||||
use fabro_workflows::event::{EventEmitter, RunNoticeLevel, WorkflowRunEvent};
|
||||
use fabro_workflows::git::GitSyncStatus;
|
||||
|
|
@ -26,9 +24,11 @@ use fabro_workflows::operations::{
|
|||
create_from_graph, start, StartFinalizeConfig, StartOptions, StartRetroConfig,
|
||||
};
|
||||
use fabro_workflows::outcome::StageStatus;
|
||||
use fabro_workflows::outcome::{compute_stage_cost, format_cost};
|
||||
use fabro_workflows::pipeline::{
|
||||
build_conclusion, classify_engine_result, persist_terminal_outcome,
|
||||
};
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::run_settings::{GitCheckpointSettings, LifecycleConfig, RunSettings};
|
||||
use fabro_workflows::sandbox_provider::SandboxProvider;
|
||||
use indicatif::HumanDuration;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use fabro_workflows::event::{EventEmitter, RunNoticeLevel, WorkflowRunEvent};
|
|||
use fabro_workflows::outcome::StageStatus;
|
||||
|
||||
use crate::commands::shared::{format_duration_ms, format_tokens_human, tilde_path};
|
||||
use fabro_workflows::cost::{compute_stage_cost, format_cost};
|
||||
use fabro_workflows::outcome::{compute_stage_cost, format_cost};
|
||||
|
||||
// ── Cached styles ───────────────────────────────────────────────────────
|
||||
|
||||
|
|
|
|||
|
|
@ -1,108 +0,0 @@
|
|||
use crate::outcome::StageUsage;
|
||||
|
||||
/// Compute the dollar cost for a stage's token usage, if pricing is available.
|
||||
#[must_use]
|
||||
pub fn compute_stage_cost(usage: &StageUsage) -> Option<f64> {
|
||||
let info = fabro_model::Catalog::builtin().get(&usage.model)?;
|
||||
let input_rate = info.costs.input_cost_per_mtok?;
|
||||
let output_rate = info.costs.output_cost_per_mtok?;
|
||||
let multiplier = if usage.speed.as_deref() == Some("fast") {
|
||||
6.0
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
Some(
|
||||
(usage.input_tokens as f64 * input_rate / 1_000_000.0
|
||||
+ usage.output_tokens as f64 * output_rate / 1_000_000.0)
|
||||
* multiplier,
|
||||
)
|
||||
}
|
||||
|
||||
/// Format a dollar cost for display (e.g. `"$1.23"`).
|
||||
#[must_use]
|
||||
pub fn format_cost(cost: f64) -> String {
|
||||
format!("${cost:.2}")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{compute_stage_cost, format_cost};
|
||||
use crate::outcome::StageUsage;
|
||||
|
||||
#[test]
|
||||
fn format_cost_zero() {
|
||||
assert_eq!(format_cost(0.0), "$0.00");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_cost_normal() {
|
||||
assert_eq!(format_cost(1.5), "$1.50");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_cost_rounds() {
|
||||
assert_eq!(format_cost(123.456), "$123.46");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compute_stage_cost_known_model() {
|
||||
let usage = StageUsage {
|
||||
model: "claude-sonnet-4-5".into(),
|
||||
input_tokens: 1000,
|
||||
output_tokens: 500,
|
||||
cache_read_tokens: None,
|
||||
cache_write_tokens: None,
|
||||
reasoning_tokens: None,
|
||||
speed: None,
|
||||
cost: None,
|
||||
};
|
||||
let cost = compute_stage_cost(&usage);
|
||||
assert!(cost.is_some());
|
||||
assert!(cost.unwrap() > 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compute_stage_cost_unknown_model() {
|
||||
let usage = StageUsage {
|
||||
model: "nonexistent-model-xyz".into(),
|
||||
input_tokens: 1000,
|
||||
output_tokens: 500,
|
||||
cache_read_tokens: None,
|
||||
cache_write_tokens: None,
|
||||
reasoning_tokens: None,
|
||||
speed: None,
|
||||
cost: None,
|
||||
};
|
||||
assert_eq!(compute_stage_cost(&usage), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compute_stage_cost_fast_mode_6x_multiplier() {
|
||||
let standard_usage = StageUsage {
|
||||
model: "claude-sonnet-4-5".into(),
|
||||
input_tokens: 1000,
|
||||
output_tokens: 500,
|
||||
cache_read_tokens: None,
|
||||
cache_write_tokens: None,
|
||||
reasoning_tokens: None,
|
||||
speed: None,
|
||||
cost: None,
|
||||
};
|
||||
let fast_usage = StageUsage {
|
||||
model: "claude-sonnet-4-5".into(),
|
||||
input_tokens: 1000,
|
||||
output_tokens: 500,
|
||||
cache_read_tokens: None,
|
||||
cache_write_tokens: None,
|
||||
reasoning_tokens: None,
|
||||
speed: Some("fast".into()),
|
||||
cost: None,
|
||||
};
|
||||
let standard_cost = compute_stage_cost(&standard_usage).unwrap();
|
||||
let fast_cost = compute_stage_cost(&fast_usage).unwrap();
|
||||
assert!(
|
||||
(fast_cost - standard_cost * 6.0).abs() < 1e-10,
|
||||
"fast mode should be 6x standard cost: standard={standard_cost}, fast={fast_cost}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,8 +5,8 @@ use fabro_git_storage::branchstore::BranchStore;
|
|||
use fabro_git_storage::gitobj::Store;
|
||||
use git2::{Repository, Signature};
|
||||
|
||||
use crate::records::Checkpoint;
|
||||
use crate::error::{FabroError, Result};
|
||||
use crate::records::Checkpoint;
|
||||
|
||||
/// Branch prefix for workflow run branches (e.g. `fabro/run/{run_id}`).
|
||||
pub const RUN_BRANCH_PREFIX: &str = "fabro/run/";
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ use fabro_model::Provider;
|
|||
|
||||
use super::super::agent::{CodergenBackend, CodergenResult};
|
||||
use crate::context::{Context, WorkflowContext};
|
||||
use crate::cost::compute_stage_cost;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::WorkflowRunEvent;
|
||||
use crate::outcome::compute_stage_cost;
|
||||
use crate::outcome::StageUsage;
|
||||
use fabro_graphviz::graph::Node;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ use fabro_model::Provider;
|
|||
|
||||
use super::super::agent::{CodergenBackend, CodergenResult};
|
||||
use crate::context::Context;
|
||||
use crate::cost::compute_stage_cost;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::{EventEmitter, WorkflowRunEvent};
|
||||
use crate::outcome::compute_stage_cost;
|
||||
use crate::outcome::StageUsage;
|
||||
use fabro_graphviz::graph::Node;
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@ pub mod asset_snapshot;
|
|||
pub mod assets;
|
||||
pub mod condition;
|
||||
pub mod context;
|
||||
pub mod cost;
|
||||
pub mod devcontainer_bridge;
|
||||
pub mod error;
|
||||
pub mod event;
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ use fabro_core::outcome::NodeResult;
|
|||
use fabro_core::state::RunState;
|
||||
|
||||
use super::circuit_breaker::CircuitBreakerLifecycle;
|
||||
use crate::records::Checkpoint;
|
||||
use crate::event::{EventEmitter, RunNoticeLevel, WorkflowRunEvent};
|
||||
use crate::graph::WorkflowGraph;
|
||||
use crate::graph::WorkflowNode;
|
||||
use crate::outcome::StageUsage;
|
||||
use crate::records::Checkpoint;
|
||||
use crate::run_dir::{write_node_status, write_start_record};
|
||||
use crate::run_settings::RunSettings;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ use fabro_git_storage::branchstore::{BranchStore, CommitInfo};
|
|||
use fabro_git_storage::gitobj::Store;
|
||||
use git2::{Oid, Repository, Signature};
|
||||
|
||||
use crate::records::Checkpoint;
|
||||
use crate::git::MetadataStore;
|
||||
use crate::records::Checkpoint;
|
||||
use fabro_graphviz::graph::Graph;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
|
|
|||
|
|
@ -116,6 +116,30 @@ impl OutcomeExt for Outcome {
|
|||
}
|
||||
}
|
||||
|
||||
/// Compute the dollar cost for a stage's token usage, if pricing is available.
|
||||
#[must_use]
|
||||
pub fn compute_stage_cost(usage: &StageUsage) -> Option<f64> {
|
||||
let info = fabro_model::Catalog::builtin().get(&usage.model)?;
|
||||
let input_rate = info.costs.input_cost_per_mtok?;
|
||||
let output_rate = info.costs.output_cost_per_mtok?;
|
||||
let multiplier = if usage.speed.as_deref() == Some("fast") {
|
||||
6.0
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
Some(
|
||||
(usage.input_tokens as f64 * input_rate / 1_000_000.0
|
||||
+ usage.output_tokens as f64 * output_rate / 1_000_000.0)
|
||||
* multiplier,
|
||||
)
|
||||
}
|
||||
|
||||
/// Format a dollar cost for display (e.g. `"$1.23"`).
|
||||
#[must_use]
|
||||
pub fn format_cost(cost: f64) -> String {
|
||||
format!("${cost:.2}")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
@ -341,4 +365,81 @@ mod tests {
|
|||
assert!(o.failure.is_none());
|
||||
assert!(o.context_updates.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_cost_zero() {
|
||||
assert_eq!(format_cost(0.0), "$0.00");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_cost_normal() {
|
||||
assert_eq!(format_cost(1.5), "$1.50");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_cost_rounds() {
|
||||
assert_eq!(format_cost(123.456), "$123.46");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compute_stage_cost_known_model() {
|
||||
let usage = StageUsage {
|
||||
model: "claude-sonnet-4-5".into(),
|
||||
input_tokens: 1000,
|
||||
output_tokens: 500,
|
||||
cache_read_tokens: None,
|
||||
cache_write_tokens: None,
|
||||
reasoning_tokens: None,
|
||||
speed: None,
|
||||
cost: None,
|
||||
};
|
||||
let cost = compute_stage_cost(&usage);
|
||||
assert!(cost.is_some());
|
||||
assert!(cost.unwrap() > 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compute_stage_cost_unknown_model() {
|
||||
let usage = StageUsage {
|
||||
model: "nonexistent-model-xyz".into(),
|
||||
input_tokens: 1000,
|
||||
output_tokens: 500,
|
||||
cache_read_tokens: None,
|
||||
cache_write_tokens: None,
|
||||
reasoning_tokens: None,
|
||||
speed: None,
|
||||
cost: None,
|
||||
};
|
||||
assert_eq!(compute_stage_cost(&usage), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compute_stage_cost_fast_mode_6x_multiplier() {
|
||||
let standard_usage = StageUsage {
|
||||
model: "claude-sonnet-4-5".into(),
|
||||
input_tokens: 1000,
|
||||
output_tokens: 500,
|
||||
cache_read_tokens: None,
|
||||
cache_write_tokens: None,
|
||||
reasoning_tokens: None,
|
||||
speed: None,
|
||||
cost: None,
|
||||
};
|
||||
let fast_usage = StageUsage {
|
||||
model: "claude-sonnet-4-5".into(),
|
||||
input_tokens: 1000,
|
||||
output_tokens: 500,
|
||||
cache_read_tokens: None,
|
||||
cache_write_tokens: None,
|
||||
reasoning_tokens: None,
|
||||
speed: Some("fast".into()),
|
||||
cost: None,
|
||||
};
|
||||
let standard_cost = compute_stage_cost(&standard_usage).unwrap();
|
||||
let fast_cost = compute_stage_cost(&fast_usage).unwrap();
|
||||
assert!(
|
||||
(fast_cost - standard_cost * 6.0).abs() < 1e-10,
|
||||
"fast mode should be 6x standard cost: standard={standard_cost}, fast={fast_cost}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ use fabro_hooks::HookConfig;
|
|||
use fabro_interview::AutoApproveInterviewer;
|
||||
|
||||
use super::*;
|
||||
use crate::records::Checkpoint;
|
||||
use crate::context::{self, Context};
|
||||
use crate::error::FabroError;
|
||||
use crate::event::{EventEmitter, WorkflowRunEvent};
|
||||
|
|
@ -23,6 +22,7 @@ use crate::operations::create_from_graph;
|
|||
use crate::outcome::{Outcome, OutcomeExt, StageStatus};
|
||||
use crate::pipeline::initialize;
|
||||
use crate::pipeline::types::{InitOptions, Validated};
|
||||
use crate::records::Checkpoint;
|
||||
use crate::run_settings::{GitCheckpointSettings, LifecycleConfig, RunSettings};
|
||||
use crate::test_support::run_graph;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::records::Checkpoint;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::{EventEmitter, RunNoticeLevel, WorkflowRunEvent};
|
||||
use crate::outcome::{Outcome, OutcomeExt, StageStatus};
|
||||
use crate::records::Checkpoint;
|
||||
use crate::records::Conclusion;
|
||||
use crate::run_settings::RunSettings;
|
||||
use crate::run_status::{RunStatus, StatusReason};
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use std::sync::Arc;
|
|||
use fabro_agent::SessionEvent;
|
||||
use fabro_retro::retro::Retro;
|
||||
|
||||
use crate::records::Checkpoint;
|
||||
use crate::event::WorkflowRunEvent;
|
||||
use crate::records::Checkpoint;
|
||||
|
||||
use super::types::{Executed, RetroOptions, Retroed};
|
||||
|
||||
|
|
@ -151,10 +151,10 @@ mod tests {
|
|||
use fabro_graphviz::graph::Graph;
|
||||
|
||||
use super::*;
|
||||
use crate::records::Checkpoint;
|
||||
use crate::context::Context;
|
||||
use crate::event::{EventEmitter, WorkflowRunEvent};
|
||||
use crate::pipeline::types::Executed;
|
||||
use crate::records::Checkpoint;
|
||||
use crate::run_settings::RunSettings;
|
||||
|
||||
fn write_checkpoint(run_dir: &std::path::Path) {
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ use fabro_graphviz::graph::Graph;
|
|||
use fabro_hooks::HookRunner;
|
||||
use fabro_validate::Diagnostic;
|
||||
|
||||
use crate::records::Checkpoint;
|
||||
use crate::context::Context;
|
||||
use crate::error::FabroError;
|
||||
use crate::event::EventEmitter;
|
||||
use crate::handler::HandlerRegistry;
|
||||
use crate::outcome::Outcome;
|
||||
use crate::records::Checkpoint;
|
||||
use crate::records::Conclusion;
|
||||
use crate::run_settings::{LifecycleConfig, RunSettings};
|
||||
use fabro_validate::Severity;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ fn truncate_pr_body(body: &str) -> String {
|
|||
|
||||
/// Format an optional cost as `$X.XX` or an en-dash when absent.
|
||||
fn format_cost(cost: Option<f64>) -> String {
|
||||
cost.map(crate::cost::format_cost)
|
||||
cost.map(crate::outcome::format_cost)
|
||||
.unwrap_or_else(|| "\u{2013}".to_string())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ use chrono::{DateTime, Utc};
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::records::RunRecord;
|
||||
use crate::run_status::{RunStatus, RunStatusRecord, StatusReason};
|
||||
use crate::records::StartRecord;
|
||||
use crate::run_status::{RunStatus, RunStatusRecord, StatusReason};
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct RunInfo {
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ use std::sync::Arc;
|
|||
|
||||
use fabro_agent::Sandbox;
|
||||
|
||||
use crate::records::Checkpoint;
|
||||
use crate::error::Result;
|
||||
use crate::event::EventEmitter;
|
||||
use crate::handler::HandlerRegistry;
|
||||
use crate::outcome::Outcome;
|
||||
use crate::pipeline;
|
||||
use crate::pipeline::types::Initialized;
|
||||
use crate::records::Checkpoint;
|
||||
use crate::run_settings::RunSettings;
|
||||
|
||||
struct InitializedOptions {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
//! Docker tests require a Docker daemon and are marked `#[ignore]`.
|
||||
//! Run Docker tests with: `cargo test --package arc-workflows --test cp_integration -- --ignored`
|
||||
|
||||
use fabro_workflows::sandbox_reconnect::reconnect;
|
||||
use fabro_workflows::records::SandboxRecord;
|
||||
use fabro_workflows::sandbox_reconnect::reconnect;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Local sandbox
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node};
|
|||
use fabro_llm::provider::Provider;
|
||||
use fabro_sandbox::daytona::{DaytonaConfig, DaytonaSandbox, DaytonaSnapshotConfig};
|
||||
use fabro_workflows::artifact::sync_artifacts_to_env;
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::context::Context;
|
||||
use fabro_workflows::error::FabroError;
|
||||
use fabro_workflows::event::EventEmitter;
|
||||
|
|
@ -21,6 +20,7 @@ use fabro_workflows::handler::exit::ExitHandler;
|
|||
use fabro_workflows::handler::start::StartHandler;
|
||||
use fabro_workflows::handler::{Handler, HandlerRegistry};
|
||||
use fabro_workflows::outcome::{Outcome, OutcomeExt, StageStatus};
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::run_settings::{GitCheckpointSettings, RunSettings};
|
||||
use fabro_workflows::test_support::WorkflowRunner;
|
||||
|
||||
|
|
@ -1740,8 +1740,8 @@ async fn daytona_toolbox_idle_diagnostic() {
|
|||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn daytona_cp_upload_download_round_trip() {
|
||||
use fabro_workflows::sandbox_reconnect::reconnect;
|
||||
use fabro_workflows::records::SandboxRecord;
|
||||
use fabro_workflows::sandbox_reconnect::reconnect;
|
||||
|
||||
// 1. Create and initialize a real Daytona sandbox
|
||||
let env = create_env().await;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ use fabro_interview::{
|
|||
};
|
||||
use fabro_llm::provider::Provider;
|
||||
use fabro_validate::{validate, validate_or_raise, Severity};
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::context::Context;
|
||||
use fabro_workflows::error::FabroError;
|
||||
use fabro_workflows::event::{EventEmitter, WorkflowRunEvent};
|
||||
|
|
@ -29,6 +28,7 @@ use fabro_workflows::handler::start::StartHandler;
|
|||
use fabro_workflows::handler::wait::WaitHandler;
|
||||
use fabro_workflows::handler::{Handler, HandlerRegistry};
|
||||
use fabro_workflows::outcome::{Outcome, OutcomeExt, StageStatus};
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::run_settings::{GitCheckpointSettings, RunSettings};
|
||||
use fabro_workflows::stylesheet::{apply_stylesheet, parse_stylesheet};
|
||||
use fabro_workflows::test_support::{run_graph_with_hooks, WorkflowRunner};
|
||||
|
|
@ -5967,13 +5967,13 @@ mod real_llm {
|
|||
use super::local_env;
|
||||
use fabro_graphviz::graph::{AttrValue, Edge, Graph};
|
||||
use fabro_interview::AutoApproveInterviewer;
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::event::EventEmitter;
|
||||
use fabro_workflows::handler::exit::ExitHandler;
|
||||
use fabro_workflows::handler::human::HumanHandler;
|
||||
use fabro_workflows::handler::start::StartHandler;
|
||||
use fabro_workflows::handler::HandlerRegistry;
|
||||
use fabro_workflows::outcome::StageStatus;
|
||||
use fabro_workflows::records::Checkpoint;
|
||||
use fabro_workflows::run_settings::RunSettings;
|
||||
use fabro_workflows::test_support::WorkflowRunner;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue