use std::cell::RefCell;
use crate::commands::run::supervision::PushPolicy;
use crate::config;
use crate::contracts::{GitPublishMode, GitRevertMode, ProjectType, Runner};
use crate::{promptflow, runner, runutil};
pub(crate) use crate::commands::run::execution_timings::RunExecutionTimings;
mod phase1;
mod phase2;
pub(crate) mod phase3;
mod shared;
mod single;
#[cfg(test)]
mod tests;
pub use phase1::execute_phase1_planning;
pub use phase2::execute_phase2_implementation;
pub use phase3::execute_phase3_review;
pub use single::execute_single_phase;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PhaseType {
Planning,
Implementation,
Review,
SinglePhase,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PostRunMode {
Normal,
ParallelWorker,
}
pub struct PhaseInvocation<'a> {
pub resolved: &'a config::Resolved,
pub queue_lock: Option<&'a crate::lock::DirLock>,
pub settings: &'a runner::AgentSettings,
pub bins: runner::RunnerBinaries<'a>,
pub task_id: &'a str,
pub task_title: Option<&'a str>,
pub base_prompt: &'a str,
pub policy: &'a promptflow::PromptPolicy,
pub output_handler: Option<runner::OutputHandler>,
pub output_stream: runner::OutputStream,
pub project_type: ProjectType,
pub git_revert_mode: GitRevertMode,
pub git_publish_mode: GitPublishMode,
pub push_policy: PushPolicy,
pub revert_prompt: Option<runutil::RevertPromptHandler>,
pub iteration_context: &'a str,
pub iteration_completion_block: &'a str,
pub phase3_completion_guidance: &'a str,
pub is_final_iteration: bool,
pub is_followup_iteration: bool,
pub allow_dirty_repo: bool,
pub post_run_mode: PostRunMode,
pub parallel_target_branch: Option<&'a str>,
pub notify_on_complete: Option<bool>,
pub notify_sound: Option<bool>,
pub lfs_check: bool,
pub no_progress: bool,
pub execution_timings: Option<&'a RefCell<RunExecutionTimings>>,
pub plugins: Option<&'a crate::plugins::registry::PluginRegistry>,
}
pub(crate) fn generate_phase_session_id(task_id: &str, phase: u8) -> String {
use std::time::{SystemTime, UNIX_EPOCH};
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs();
format!("{}-p{}-{}", task_id, phase, timestamp)
}
pub(crate) fn phase_session_id_for_runner(
runner: Runner,
task_id: &str,
phase: u8,
) -> Option<String> {
match runner {
Runner::Kimi => Some(generate_phase_session_id(task_id, phase)),
_ => None,
}
}