Build reorient launches from typed decisions
This commit is contained in:
parent
5551e35c18
commit
bc57becdba
4 changed files with 87 additions and 66 deletions
|
|
@ -69,6 +69,7 @@ use crate::pressure::derive_epiphany_pressure;
|
|||
use crate::pressure::map_epiphany_pressure;
|
||||
use crate::reorient::EpiphanyFreshnessWatcherSnapshot;
|
||||
use crate::reorient::derive_epiphany_freshness_view;
|
||||
use crate::reorient::derive_epiphany_reorient;
|
||||
use crate::reorient::map_epiphany_reorient;
|
||||
use crate::runtime_results::load_epiphany_reorient_result_snapshot;
|
||||
use crate::runtime_results::load_epiphany_role_result_snapshot;
|
||||
|
|
@ -418,6 +419,13 @@ pub async fn select_epiphany_coordinator_automation(
|
|||
&core_freshness.graph,
|
||||
&core_freshness.watcher,
|
||||
);
|
||||
let (_core_state_status, core_reorient_decision) = derive_epiphany_reorient(
|
||||
Some(input.state),
|
||||
&core_pressure,
|
||||
&core_freshness.retrieval,
|
||||
&core_freshness.graph,
|
||||
&core_freshness.watcher,
|
||||
);
|
||||
if state_status != ThreadEpiphanyReorientStateStatus::Ready {
|
||||
return EpiphanyCoordinatorAutomationVerdict {
|
||||
action: EpiphanyCoordinatorAutomationAction::None,
|
||||
|
|
@ -488,7 +496,7 @@ pub async fn select_epiphany_coordinator_automation(
|
|||
None,
|
||||
input.state,
|
||||
checkpoint,
|
||||
&reorient_decision,
|
||||
&core_reorient_decision,
|
||||
)
|
||||
}),
|
||||
EpiphanyCoordinatorAutomationAction::None
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
use std::path::Path;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use codex_app_server_protocol::ThreadEpiphanyGraphFreshnessStatus;
|
||||
use codex_app_server_protocol::ThreadEpiphanyInvalidationStatus;
|
||||
use codex_app_server_protocol::ThreadEpiphanyPressureLevel;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientAction;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientDecision;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientReason;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientWorkerLaunchDocument;
|
||||
use codex_app_server_protocol::ThreadEpiphanyRetrievalFreshnessStatus;
|
||||
use codex_app_server_protocol::ThreadEpiphanyRoleId;
|
||||
use codex_app_server_protocol::ThreadEpiphanyRoleWorkerLaunchDocument;
|
||||
use codex_app_server_protocol::ThreadEpiphanyWorkerLaunchDocument;
|
||||
use epiphany_core::EpiphanyJobLaunchRequest;
|
||||
use epiphany_core::EpiphanyReorientAction as CoreEpiphanyReorientAction;
|
||||
use epiphany_core::EpiphanyReorientDecision as CoreEpiphanyReorientDecision;
|
||||
use epiphany_core::EpiphanyReorientFreshnessStatus as CoreEpiphanyReorientFreshnessStatus;
|
||||
use epiphany_core::EpiphanyReorientPressureLevel as CoreEpiphanyReorientPressureLevel;
|
||||
use epiphany_core::EpiphanyReorientReason as CoreEpiphanyReorientReason;
|
||||
use epiphany_core::EpiphanyReorientWorkerLaunchDocument;
|
||||
use epiphany_core::EpiphanyRoleWorkerLaunchDocument;
|
||||
use epiphany_core::EpiphanyWorkerLaunchDocument;
|
||||
|
|
@ -480,7 +479,7 @@ pub fn build_epiphany_reorient_launch_request(
|
|||
max_runtime_seconds: Option<u64>,
|
||||
state: &EpiphanyThreadState,
|
||||
checkpoint: &EpiphanyInvestigationCheckpoint,
|
||||
decision: &ThreadEpiphanyReorientDecision,
|
||||
decision: &CoreEpiphanyReorientDecision,
|
||||
) -> EpiphanyJobLaunchRequest {
|
||||
let linked_subgoal_ids = epiphany_active_subgoal_ids(Some(state));
|
||||
let linked_graph_node_ids = unique_strings(
|
||||
|
|
@ -493,12 +492,12 @@ pub fn build_epiphany_reorient_launch_request(
|
|||
.clone()
|
||||
.unwrap_or_else(|| decision.next_action.clone());
|
||||
let authority_scope = match decision.action {
|
||||
ThreadEpiphanyReorientAction::Resume => "epiphany.reorient.resume",
|
||||
ThreadEpiphanyReorientAction::Regather => "epiphany.reorient.regather",
|
||||
CoreEpiphanyReorientAction::Resume => "epiphany.reorient.resume",
|
||||
CoreEpiphanyReorientAction::Regather => "epiphany.reorient.regather",
|
||||
};
|
||||
let scope = match decision.action {
|
||||
ThreadEpiphanyReorientAction::Resume => "reorient-guided checkpoint resume",
|
||||
ThreadEpiphanyReorientAction::Regather => "reorient-guided checkpoint regather",
|
||||
CoreEpiphanyReorientAction::Resume => "reorient-guided checkpoint resume",
|
||||
CoreEpiphanyReorientAction::Regather => "reorient-guided checkpoint regather",
|
||||
};
|
||||
let instruction = build_epiphany_reorient_launch_instruction(decision.action);
|
||||
let launch_document =
|
||||
|
|
@ -521,11 +520,10 @@ pub fn build_epiphany_reorient_launch_request(
|
|||
.map(|reason| reorient_reason_label(*reason).to_string())
|
||||
.collect(),
|
||||
decision_note: decision.note.clone(),
|
||||
pressure_level: pressure_level_label(decision.pressure_level).to_string(),
|
||||
retrieval_status: retrieval_freshness_status_label(decision.retrieval_status)
|
||||
.to_string(),
|
||||
graph_status: graph_freshness_status_label(decision.graph_status).to_string(),
|
||||
watcher_status: invalidation_status_label(decision.watcher_status).to_string(),
|
||||
pressure_level: reorient_pressure_level_label(decision.pressure_level).to_string(),
|
||||
retrieval_status: reorient_freshness_status_label(decision.retrieval_status).to_string(),
|
||||
graph_status: reorient_freshness_status_label(decision.graph_status).to_string(),
|
||||
watcher_status: reorient_freshness_status_label(decision.watcher_status).to_string(),
|
||||
checkpoint_dirty_paths: decision
|
||||
.checkpoint_dirty_paths
|
||||
.iter()
|
||||
|
|
@ -566,11 +564,11 @@ pub fn build_epiphany_reorient_launch_request(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn build_epiphany_reorient_launch_instruction(action: ThreadEpiphanyReorientAction) -> String {
|
||||
pub fn build_epiphany_reorient_launch_instruction(action: CoreEpiphanyReorientAction) -> String {
|
||||
let prompts = &epiphany_specialist_prompt_config().reorientation;
|
||||
let body = match action {
|
||||
ThreadEpiphanyReorientAction::Resume => prompts.resume.as_str(),
|
||||
ThreadEpiphanyReorientAction::Regather => prompts.regather.as_str(),
|
||||
CoreEpiphanyReorientAction::Resume => prompts.resume.as_str(),
|
||||
CoreEpiphanyReorientAction::Regather => prompts.regather.as_str(),
|
||||
};
|
||||
epiphany_agent_prompt_with_memory(body)
|
||||
}
|
||||
|
|
@ -741,10 +739,10 @@ fn path_to_display_string(path: impl AsRef<Path>) -> String {
|
|||
path.as_ref().to_string_lossy().to_string()
|
||||
}
|
||||
|
||||
fn reorient_action_label(action: ThreadEpiphanyReorientAction) -> &'static str {
|
||||
fn reorient_action_label(action: CoreEpiphanyReorientAction) -> &'static str {
|
||||
match action {
|
||||
ThreadEpiphanyReorientAction::Resume => "resume",
|
||||
ThreadEpiphanyReorientAction::Regather => "regather",
|
||||
CoreEpiphanyReorientAction::Resume => "resume",
|
||||
CoreEpiphanyReorientAction::Regather => "regather",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -755,18 +753,38 @@ fn investigation_disposition_label(disposition: EpiphanyInvestigationDisposition
|
|||
}
|
||||
}
|
||||
|
||||
fn reorient_reason_label(reason: ThreadEpiphanyReorientReason) -> &'static str {
|
||||
fn reorient_reason_label(reason: CoreEpiphanyReorientReason) -> &'static str {
|
||||
match reason {
|
||||
ThreadEpiphanyReorientReason::MissingState => "missingState",
|
||||
ThreadEpiphanyReorientReason::MissingCheckpoint => "missingCheckpoint",
|
||||
ThreadEpiphanyReorientReason::CheckpointRequestedRegather => "checkpointRequestedRegather",
|
||||
ThreadEpiphanyReorientReason::CheckpointPathsDirty => "checkpointPathsDirty",
|
||||
ThreadEpiphanyReorientReason::CheckpointPathsChanged => "checkpointPathsChanged",
|
||||
ThreadEpiphanyReorientReason::FrontierChanged => "frontierChanged",
|
||||
ThreadEpiphanyReorientReason::UnanchoredCheckpointWhileStateStale => {
|
||||
CoreEpiphanyReorientReason::MissingState => "missingState",
|
||||
CoreEpiphanyReorientReason::MissingCheckpoint => "missingCheckpoint",
|
||||
CoreEpiphanyReorientReason::CheckpointRequestedRegather => "checkpointRequestedRegather",
|
||||
CoreEpiphanyReorientReason::CheckpointPathsDirty => "checkpointPathsDirty",
|
||||
CoreEpiphanyReorientReason::CheckpointPathsChanged => "checkpointPathsChanged",
|
||||
CoreEpiphanyReorientReason::FrontierChanged => "frontierChanged",
|
||||
CoreEpiphanyReorientReason::UnanchoredCheckpointWhileStateStale => {
|
||||
"unanchoredCheckpointWhileStateStale"
|
||||
}
|
||||
ThreadEpiphanyReorientReason::CheckpointReady => "checkpointReady",
|
||||
CoreEpiphanyReorientReason::CheckpointReady => "checkpointReady",
|
||||
}
|
||||
}
|
||||
|
||||
fn reorient_pressure_level_label(level: CoreEpiphanyReorientPressureLevel) -> &'static str {
|
||||
match level {
|
||||
CoreEpiphanyReorientPressureLevel::Unknown => "unknown",
|
||||
CoreEpiphanyReorientPressureLevel::Low => "low",
|
||||
CoreEpiphanyReorientPressureLevel::Medium => "medium",
|
||||
CoreEpiphanyReorientPressureLevel::High => "high",
|
||||
CoreEpiphanyReorientPressureLevel::Critical => "critical",
|
||||
}
|
||||
}
|
||||
|
||||
fn reorient_freshness_status_label(status: CoreEpiphanyReorientFreshnessStatus) -> &'static str {
|
||||
match status {
|
||||
CoreEpiphanyReorientFreshnessStatus::Unknown => "unknown",
|
||||
CoreEpiphanyReorientFreshnessStatus::Clean => "clean",
|
||||
CoreEpiphanyReorientFreshnessStatus::Dirty => "dirty",
|
||||
CoreEpiphanyReorientFreshnessStatus::Stale => "stale",
|
||||
CoreEpiphanyReorientFreshnessStatus::Changed => "changed",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -779,31 +797,3 @@ pub fn pressure_level_label(level: ThreadEpiphanyPressureLevel) -> &'static str
|
|||
ThreadEpiphanyPressureLevel::Critical => "critical",
|
||||
}
|
||||
}
|
||||
|
||||
fn retrieval_freshness_status_label(
|
||||
status: ThreadEpiphanyRetrievalFreshnessStatus,
|
||||
) -> &'static str {
|
||||
match status {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Missing => "missing",
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Ready => "ready",
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Stale => "stale",
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Indexing => "indexing",
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Unavailable => "unavailable",
|
||||
}
|
||||
}
|
||||
|
||||
fn graph_freshness_status_label(status: ThreadEpiphanyGraphFreshnessStatus) -> &'static str {
|
||||
match status {
|
||||
ThreadEpiphanyGraphFreshnessStatus::Missing => "missing",
|
||||
ThreadEpiphanyGraphFreshnessStatus::Ready => "ready",
|
||||
ThreadEpiphanyGraphFreshnessStatus::Stale => "stale",
|
||||
}
|
||||
}
|
||||
|
||||
fn invalidation_status_label(status: ThreadEpiphanyInvalidationStatus) -> &'static str {
|
||||
match status {
|
||||
ThreadEpiphanyInvalidationStatus::Unavailable => "unavailable",
|
||||
ThreadEpiphanyInvalidationStatus::Clean => "clean",
|
||||
ThreadEpiphanyInvalidationStatus::Changed => "changed",
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ use crate::mutation::thread_epiphany_patch_has_state_replacements;
|
|||
use crate::pressure::derive_epiphany_pressure;
|
||||
use crate::reorient::EpiphanyFreshnessWatcherSnapshot;
|
||||
use crate::reorient::derive_epiphany_freshness_view;
|
||||
use crate::reorient::derive_epiphany_reorient;
|
||||
use crate::reorient::map_epiphany_reorient;
|
||||
use crate::runtime_results::load_completed_epiphany_reorient_finding;
|
||||
use crate::runtime_results::load_completed_epiphany_role_finding;
|
||||
|
|
@ -590,6 +591,13 @@ pub async fn launch_thread_epiphany_reorient(
|
|||
&freshness.graph,
|
||||
&freshness.watcher,
|
||||
);
|
||||
let (_core_state_status, launch_decision) = derive_epiphany_reorient(
|
||||
state,
|
||||
&pressure,
|
||||
&freshness.retrieval,
|
||||
&freshness.graph,
|
||||
&freshness.watcher,
|
||||
);
|
||||
|
||||
let state = state.ok_or_else(|| {
|
||||
EpiphanyBridgeError::InvalidRequest(format!(
|
||||
|
|
@ -610,7 +618,7 @@ pub async fn launch_thread_epiphany_reorient(
|
|||
max_runtime_seconds,
|
||||
state,
|
||||
checkpoint,
|
||||
&decision,
|
||||
&launch_decision,
|
||||
);
|
||||
let changed_fields = epiphany_job_launch_changed_fields();
|
||||
let launched = launch_epiphany_job_on_thread(thread, launch_request).await?;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use epiphany_core::EpiphanyPressure;
|
|||
use epiphany_core::EpiphanyPressureLevel;
|
||||
use epiphany_core::EpiphanyReorientAction as CoreEpiphanyReorientAction;
|
||||
use epiphany_core::EpiphanyReorientCheckpointStatus as CoreEpiphanyReorientCheckpointStatus;
|
||||
use epiphany_core::EpiphanyReorientDecision as CoreEpiphanyReorientDecision;
|
||||
use epiphany_core::EpiphanyReorientFreshnessStatus as CoreEpiphanyReorientFreshnessStatus;
|
||||
use epiphany_core::EpiphanyReorientInput;
|
||||
use epiphany_core::EpiphanyReorientPressureLevel as CoreEpiphanyReorientPressureLevel;
|
||||
|
|
@ -172,7 +173,25 @@ pub fn map_epiphany_reorient(
|
|||
ThreadEpiphanyReorientStateStatus,
|
||||
ThreadEpiphanyReorientDecision,
|
||||
) {
|
||||
let (state_status, decision) = recommend_reorientation(EpiphanyReorientInput {
|
||||
let (state_status, decision) =
|
||||
derive_epiphany_reorient(state, pressure, retrieval, graph, watcher);
|
||||
(
|
||||
map_protocol_reorient_state_status(state_status),
|
||||
map_protocol_reorient_decision(decision),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn derive_epiphany_reorient(
|
||||
state: Option<&EpiphanyThreadState>,
|
||||
pressure: &EpiphanyPressure,
|
||||
retrieval: &CoreEpiphanyRetrievalFreshness,
|
||||
graph: &CoreEpiphanyGraphFreshness,
|
||||
watcher: &CoreEpiphanyInvalidationInput,
|
||||
) -> (
|
||||
CoreEpiphanyReorientStateStatus,
|
||||
CoreEpiphanyReorientDecision,
|
||||
) {
|
||||
recommend_reorientation(EpiphanyReorientInput {
|
||||
checkpoint: state.and_then(|state| state.investigation_checkpoint.as_ref()),
|
||||
state_present: state.is_some(),
|
||||
pressure_level: map_core_reorient_pressure_level(pressure.level),
|
||||
|
|
@ -185,11 +204,7 @@ pub fn map_epiphany_reorient(
|
|||
watcher_graph_node_ids: watcher.graph_node_ids.clone(),
|
||||
active_frontier_node_ids: watcher.active_frontier_node_ids.clone(),
|
||||
watched_root: watcher.watched_root.clone(),
|
||||
});
|
||||
(
|
||||
map_protocol_reorient_state_status(state_status),
|
||||
map_protocol_reorient_decision(decision),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn map_core_reorient_pressure_level(
|
||||
|
|
|
|||
Reference in a new issue