Fix agent context errors and input visibility
This commit is contained in:
@@ -16161,12 +16161,11 @@ impl View for Input {
|
||||
ambient_agent_model.as_ref(app).should_show_status_footer()
|
||||
});
|
||||
|
||||
if FeatureFlag::CloudMode.is_enabled() && should_show_status_footer {
|
||||
self.render_ambient_agent_status_footer(app)
|
||||
} else if FeatureFlag::AgentView.is_enabled()
|
||||
&& self.agent_view_controller.as_ref(app).is_active()
|
||||
if FeatureFlag::AgentView.is_enabled() && self.agent_view_controller.as_ref(app).is_active()
|
||||
{
|
||||
self.render_agent_input(app)
|
||||
} else if FeatureFlag::CloudMode.is_enabled() && should_show_status_footer {
|
||||
self.render_ambient_agent_status_footer(app)
|
||||
} else if FeatureFlag::AgentView.is_enabled()
|
||||
&& !self.agent_view_controller.as_ref(app).is_active()
|
||||
&& !should_render_ps1_prompt(&self.model.lock(), app)
|
||||
|
||||
+19
-31
@@ -8367,21 +8367,6 @@ impl TerminalView {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In cloud agent conversations, once the shared session is ready but before the first
|
||||
// agent exchange arrives, we hide the interactive input view. A non-interactive footer is
|
||||
// rendered instead (see `TerminalView::render`).
|
||||
if !FeatureFlag::CloudModeSetupV2.is_enabled()
|
||||
&& !FeatureFlag::HandoffCloudCloud.is_enabled()
|
||||
&& ambient_agent::is_cloud_agent_pre_first_exchange(
|
||||
self.ambient_agent_view_model.as_ref(),
|
||||
&self.agent_view_controller,
|
||||
model,
|
||||
app,
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.has_active_init_project(app) && self.is_last_block_init_step(app) {
|
||||
return false;
|
||||
}
|
||||
@@ -8417,23 +8402,28 @@ impl TerminalView {
|
||||
}
|
||||
}
|
||||
|
||||
let active_ai_block = self.active_ai_block(app);
|
||||
if active_ai_block.is_some_and(|ai_block| {
|
||||
let ai_block = ai_block.as_ref(app);
|
||||
ai_block.is_blocked_on_user_confirmation(app)
|
||||
|| ai_block.has_expanded_running_commands(app)
|
||||
}) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let active_command_block = model.block_list().active_block();
|
||||
let is_active_and_long_running = active_command_block.is_active_and_long_running();
|
||||
let is_oz_env_startup_command = active_command_block.is_oz_environment_startup_command();
|
||||
let is_running_in_band_command =
|
||||
model.block_list().is_writing_or_executing_in_band_command();
|
||||
let has_active_long_running_agent_interaction = active_command_block
|
||||
.is_agent_driving_command()
|
||||
|| active_command_block.is_agent_tagged_in();
|
||||
let is_agent_view_active = FeatureFlag::AgentView.is_enabled()
|
||||
&& self.agent_view_controller.as_ref(app).is_active();
|
||||
|
||||
let has_active_long_running_agent_interaction =
|
||||
active_command_block.is_agent_monitoring() || active_command_block.is_agent_tagged_in();
|
||||
let active_ai_block = self.active_ai_block(app);
|
||||
if !is_agent_view_active
|
||||
&& !has_active_long_running_agent_interaction
|
||||
&& active_ai_block.is_some_and(|ai_block| {
|
||||
let ai_block = ai_block.as_ref(app);
|
||||
ai_block.is_blocked_on_user_confirmation(app)
|
||||
|| ai_block.has_expanded_running_commands(app)
|
||||
})
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (active_ai_block.is_none() || has_active_long_running_agent_interaction)
|
||||
&& is_active_and_long_running
|
||||
@@ -8441,11 +8431,9 @@ impl TerminalView {
|
||||
&& !is_running_in_band_command
|
||||
&& model.block_list().is_bootstrapped()
|
||||
{
|
||||
// Show the input if:
|
||||
// * The agent is control of the active, long running block, so long as the agent is not blocked.
|
||||
// * OR the user has 'tagged in' the agent.
|
||||
return (active_command_block.is_agent_in_control()
|
||||
&& !active_command_block.is_agent_blocked())
|
||||
// Keep the agent prompt available while the agent owns, starts, or waits on
|
||||
// a long-running command; hide it for user-owned commands unless tagged in.
|
||||
return active_command_block.is_agent_driving_command()
|
||||
|| active_command_block.is_agent_tagged_in();
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ pub fn create_cloud_mode_view(
|
||||
|
||||
/// Returns `true` when a cloud agent shared session is in any pre-first-exchange phase —
|
||||
/// either still spawning (loading screen) or running setup commands before the first
|
||||
/// agent turn. In this state, we hide the interactive input and render a loading footer.
|
||||
/// agent turn.
|
||||
pub fn is_cloud_agent_pre_first_exchange(
|
||||
ambient_agent_view_model: Option<&ModelHandle<AmbientAgentViewModel>>,
|
||||
agent_view_controller: &ModelHandle<AgentViewController>,
|
||||
|
||||
@@ -1787,6 +1787,60 @@ fn fresh_cloud_mode_setup_enters_agent_view_when_view_pending() {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn legacy_cloud_mode_waiting_for_session_keeps_input_visible() {
|
||||
App::test((), |mut app| async move {
|
||||
initialize_app_for_terminal_view(&mut app);
|
||||
let _agent_view = FeatureFlag::AgentView.override_enabled(true);
|
||||
let _cloud_mode = FeatureFlag::CloudMode.override_enabled(true);
|
||||
let _handoff = FeatureFlag::HandoffCloudCloud.override_enabled(false);
|
||||
let _setup_v2 = FeatureFlag::CloudModeSetupV2.override_enabled(false);
|
||||
|
||||
let terminal = add_window_with_cloud_mode_terminal(&mut app);
|
||||
|
||||
terminal.update(&mut app, |view, ctx| {
|
||||
view.model
|
||||
.lock()
|
||||
.set_shared_session_status(SharedSessionStatus::ViewPending);
|
||||
view.enter_ambient_agent_setup(Some("write the tests".to_string()), ctx);
|
||||
view.ambient_agent_view_model()
|
||||
.expect("cloud mode terminal should have ambient model")
|
||||
.update(ctx, |model, ctx| {
|
||||
model.spawn_agent_with_request(
|
||||
SpawnAgentRequest {
|
||||
prompt: Some("write the tests".to_string()),
|
||||
mode: UserQueryMode::Normal,
|
||||
config: None,
|
||||
title: None,
|
||||
team: None,
|
||||
agent_identity_uid: None,
|
||||
skill: None,
|
||||
attachments: vec![],
|
||||
interactive: None,
|
||||
parent_run_id: None,
|
||||
runtime_skills: vec![],
|
||||
referenced_attachments: vec![],
|
||||
conversation_id: None,
|
||||
initial_snapshot_token: None,
|
||||
snapshot_disabled: None,
|
||||
orchestration_handoff: None,
|
||||
},
|
||||
ctx,
|
||||
);
|
||||
});
|
||||
|
||||
let model = view.model.lock();
|
||||
assert!(ambient_agent::is_cloud_agent_pre_first_exchange(
|
||||
view.ambient_agent_view_model.as_ref(),
|
||||
&view.agent_view_controller,
|
||||
&model,
|
||||
ctx,
|
||||
));
|
||||
assert!(view.is_input_box_visible(&model, ctx));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shared_third_party_viewer_sync_enters_agent_view_and_retags_existing_block() {
|
||||
App::test((), |mut app| async move {
|
||||
@@ -5486,6 +5540,57 @@ fn inline_agent_view_exits_when_tagged_in_long_running_command_is_tagged_out() {
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn agent_view_keeps_input_visible_for_agent_requested_and_blocked_commands() {
|
||||
App::test((), |mut app| async move {
|
||||
initialize_app_for_terminal_view(&mut app);
|
||||
let _agent_view = FeatureFlag::AgentView.override_enabled(true);
|
||||
|
||||
let terminal = add_window_with_terminal(&mut app, None);
|
||||
|
||||
terminal.update(&mut app, |view, ctx| {
|
||||
let conversation_id = view.agent_view_controller().update(ctx, |controller, ctx| {
|
||||
controller
|
||||
.try_enter_agent_view(
|
||||
None,
|
||||
AgentViewEntryOrigin::Input {
|
||||
was_prompt_autodetected: false,
|
||||
},
|
||||
ctx,
|
||||
)
|
||||
.expect("should enter agent view")
|
||||
});
|
||||
bootstrap_with_long_running_block(view);
|
||||
set_active_block_agent_driving(view, conversation_id);
|
||||
|
||||
{
|
||||
let model = view.model.lock();
|
||||
let active_block = model.block_list().active_block();
|
||||
assert!(active_block.is_agent_driving_command());
|
||||
assert!(view.is_input_box_visible(&model, ctx));
|
||||
}
|
||||
|
||||
let task_id = TaskId::new("test-cli-subagent".to_owned());
|
||||
view.model
|
||||
.lock()
|
||||
.block_list_mut()
|
||||
.active_block_mut()
|
||||
.set_agent_interaction_mode_for_agent_monitored_command(&task_id, conversation_id)
|
||||
.expect("agent-requested command should become monitored");
|
||||
view.model
|
||||
.lock()
|
||||
.block_list_mut()
|
||||
.active_block_mut()
|
||||
.update_is_agent_blocked(true);
|
||||
|
||||
let model = view.model.lock();
|
||||
let active_block = model.block_list().active_block();
|
||||
assert!(active_block.is_agent_blocked());
|
||||
assert!(view.is_input_box_visible(&model, ctx));
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_c_after_stop_takeover_cancels_conversation() {
|
||||
App::test((), |mut app| async move {
|
||||
|
||||
Reference in New Issue
Block a user