fix(grid-agent): keep TUI terminal output isolated
This commit is contained in:
@@ -1892,9 +1892,7 @@ impl AutonomousApprovalReviewer {
|
||||
)
|
||||
.await;
|
||||
cancellation_bridge.abort();
|
||||
let message = result.map_err(|error| {
|
||||
eprintln!("Mentra approval review failed: {error}");
|
||||
})?;
|
||||
let message = result.map_err(|_| ())?;
|
||||
let text = message.text();
|
||||
let verdict = text
|
||||
.trim()
|
||||
@@ -1904,10 +1902,6 @@ impl AutonomousApprovalReviewer {
|
||||
} else if verdict.eq_ignore_ascii_case("DENY") {
|
||||
Ok(false)
|
||||
} else {
|
||||
eprintln!(
|
||||
"Mentra approval review returned an invalid verdict ({} bytes)",
|
||||
text.len()
|
||||
);
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
@@ -1976,18 +1970,8 @@ impl mentra::tool::ToolExecutor for MentraGridTool {
|
||||
.await
|
||||
{
|
||||
crate::tool_loop::ToolExecution::Completed(result) => Ok(result.into_inner()),
|
||||
crate::tool_loop::ToolExecution::Rejected(reason) => {
|
||||
eprintln!(
|
||||
"Mentra grid tool rejected: name={} reason={}",
|
||||
self.definition.name.as_str(),
|
||||
reason.as_str()
|
||||
);
|
||||
Err(reason.into_inner())
|
||||
}
|
||||
crate::tool_loop::ToolExecution::Failed(reason) => {
|
||||
eprintln!("Mentra grid tool failed: {}", reason.as_str());
|
||||
Err(reason.into_inner())
|
||||
}
|
||||
crate::tool_loop::ToolExecution::Rejected(reason)
|
||||
| crate::tool_loop::ToolExecution::Failed(reason) => Err(reason.into_inner()),
|
||||
crate::tool_loop::ToolExecution::AmbiguousMutation => {
|
||||
active.mentra_cancellation.cancel();
|
||||
Err("mutation outcome is ambiguous; stopped without retry".to_owned())
|
||||
@@ -2383,10 +2367,7 @@ impl InteractionResponder for PolicyLlmResponder {
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
||||
.remove(&agent_id);
|
||||
let message = result.map_err(|error| {
|
||||
eprintln!("Mentra inference failed: {error}");
|
||||
mentra_interaction_error(&error)
|
||||
})?;
|
||||
let message = result.map_err(|error| mentra_interaction_error(&error))?;
|
||||
mentra_visible_text(&message)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -22,6 +22,58 @@ impl fmt::Display for CliError {
|
||||
|
||||
impl Error for CliError {}
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
struct SilentLogger;
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
impl libremetaverse::logging::ILogger for SilentLogger {
|
||||
fn is_enabled(&self, _level: libremetaverse::logging::LogLevel) -> bool {
|
||||
false
|
||||
}
|
||||
fn log(
|
||||
&self,
|
||||
_level: libremetaverse::logging::LogLevel,
|
||||
_message: &libremetaverse_types::compat::Object,
|
||||
_exception: Option<&libremetaverse_types::compat::ExternalError>,
|
||||
_client_name: Option<&str>,
|
||||
) {
|
||||
}
|
||||
fn begin_scope(
|
||||
&self,
|
||||
_state: libremetaverse_types::compat::Object,
|
||||
) -> Box<dyn libremetaverse_types::compat::Close> {
|
||||
Box::new(SilentScope)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
struct SilentScope;
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
impl libremetaverse_types::compat::Close for SilentScope {
|
||||
fn close(&mut self) -> Result<(), libremetaverse_types::compat::ExternalError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
struct SilentLoggerFactory;
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
impl libremetaverse::logging::ILoggerFactory for SilentLoggerFactory {
|
||||
fn create_logger(&self, _name: &str) -> Arc<dyn libremetaverse::logging::ILogger> {
|
||||
Arc::new(SilentLogger)
|
||||
}
|
||||
fn shutdown(&self) -> Result<(), libremetaverse_types::compat::ExternalError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
fn install_silent_grid_logger() -> Result<(), libremetaverse::Error> {
|
||||
libremetaverse::Logger::set_logger_factory(Box::new(SilentLoggerFactory), "tui".into())
|
||||
}
|
||||
|
||||
fn color_disabled() -> bool {
|
||||
std::env::var_os("NO_COLOR").is_some()
|
||||
|| std::env::var_os("TERM").is_some_and(|value| value == "dumb")
|
||||
@@ -278,6 +330,10 @@ async fn run_live(
|
||||
SessionSupervisor, TcpControlConfig, TcpControlServer, WorldSnapshotSource,
|
||||
};
|
||||
|
||||
if tui {
|
||||
install_silent_grid_logger()?;
|
||||
}
|
||||
|
||||
let connection = config.grid.clone().ok_or_else(|| {
|
||||
CliError("validated live configuration did not contain a grid connection".into())
|
||||
})?;
|
||||
@@ -335,6 +391,7 @@ async fn run_live(
|
||||
.timeouts
|
||||
.startup
|
||||
.saturating_sub(Duration::from_secs(5)),
|
||||
!tui,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
@@ -472,7 +529,9 @@ async fn run_live(
|
||||
None
|
||||
};
|
||||
|
||||
println!("grid agent session supervisor started; press Ctrl-C to stop");
|
||||
if !tui {
|
||||
println!("grid agent session supervisor started; press Ctrl-C to stop");
|
||||
}
|
||||
let mut signal_error = None;
|
||||
let mut control_failure = None;
|
||||
let mut active_interactions = 0_usize;
|
||||
@@ -496,7 +555,9 @@ async fn run_live(
|
||||
&framework_readiness,
|
||||
status.generation,
|
||||
config.timeouts.startup.saturating_sub(Duration::from_secs(5)),
|
||||
!tui,
|
||||
).await
|
||||
&& !tui
|
||||
{
|
||||
eprintln!("framework initialization failed: {error}");
|
||||
}
|
||||
@@ -524,14 +585,14 @@ async fn run_live(
|
||||
component: "session".into(),
|
||||
state: status.state.as_str().into(),
|
||||
});
|
||||
println!(
|
||||
"grid session state={} generation={} transport_connected={} agent_ready={} reason={reason:?} retry_in={retry_in:?}",
|
||||
status.state.as_str(),
|
||||
status.generation,
|
||||
status.transport_connected,
|
||||
status.agent_ready,
|
||||
);
|
||||
if status.agent_ready {
|
||||
if !tui {
|
||||
println!(
|
||||
"grid session state={} generation={} transport_connected={} agent_ready={} reason={reason:?} retry_in={retry_in:?}",
|
||||
status.state.as_str(), status.generation,
|
||||
status.transport_connected, status.agent_ready,
|
||||
);
|
||||
}
|
||||
if status.agent_ready && !tui {
|
||||
print_ready(&live, status.generation);
|
||||
}
|
||||
}
|
||||
@@ -551,12 +612,12 @@ async fn run_live(
|
||||
pause.conversation = active_interactions != 0;
|
||||
});
|
||||
record_interaction_observation(&live.observability, &event);
|
||||
println!("grid interaction event={event:?}");
|
||||
if !tui { println!("grid interaction event={event:?}"); }
|
||||
}
|
||||
event = live.perception_observations.recv() => {
|
||||
let Some(event) = event else { break; };
|
||||
record_perception_observation(&live.observability, &event);
|
||||
println!("grid perception event={event:?}");
|
||||
if !tui { println!("grid perception event={event:?}"); }
|
||||
}
|
||||
event = live.behavior.next_observation() => {
|
||||
let Some(event) = event else { break; };
|
||||
@@ -568,7 +629,7 @@ async fn run_live(
|
||||
state: format!("{to:?}").to_ascii_lowercase(),
|
||||
});
|
||||
}
|
||||
println!("grid behavior event={event:?}");
|
||||
if !tui { println!("grid behavior event={event:?}"); }
|
||||
}
|
||||
command = control_commands.recv() => {
|
||||
let Some(command) = command else { break; };
|
||||
@@ -639,7 +700,9 @@ async fn run_live(
|
||||
if let Some(error) = control_failure {
|
||||
return Err(CliError(format!("control command failed: {error}")).into());
|
||||
}
|
||||
println!("grid agent stopped cleanly");
|
||||
if !tui {
|
||||
println!("grid agent stopped cleanly");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -649,8 +712,13 @@ async fn prepare_live_framework(
|
||||
readiness: &metacrate_grid_agent::FrameworkReadiness,
|
||||
generation: u64,
|
||||
timeout: Duration,
|
||||
print_status: bool,
|
||||
) -> Result<(), CliError> {
|
||||
println!("INITIALIZING generation={generation} waiting_for=world_state,viewport target_fps=10");
|
||||
if print_status {
|
||||
println!(
|
||||
"INITIALIZING generation={generation} waiting_for=world_state,viewport target_fps=10"
|
||||
);
|
||||
}
|
||||
tokio::time::timeout(timeout, async {
|
||||
loop {
|
||||
let world_ready = live
|
||||
@@ -689,13 +757,15 @@ async fn prepare_live_framework(
|
||||
.map_err(|_| CliError("timed out waiting for stable world state and viewport".into()))?;
|
||||
readiness.mark_ready(generation);
|
||||
let stats = live.vision.viewport_stats().unwrap_or_default();
|
||||
println!(
|
||||
"INITIALIZED generation={} viewport_frames={} last_render_ms={} warmup_missed_deadlines={} world_state=stable viewport_state=stable",
|
||||
generation,
|
||||
stats.completed_frames,
|
||||
stats.last_render.as_millis(),
|
||||
stats.missed_frame_deadlines,
|
||||
);
|
||||
if print_status {
|
||||
println!(
|
||||
"INITIALIZED generation={} viewport_frames={} last_render_ms={} warmup_missed_deadlines={} world_state=stable viewport_state=stable",
|
||||
generation,
|
||||
stats.completed_frames,
|
||||
stats.last_render.as_millis(),
|
||||
stats.missed_frame_deadlines,
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user