mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
row spacer
This commit is contained in:
@@ -1377,9 +1377,9 @@ fn build_initial_planning_seed(goal_text: &str, include_agents: bool) -> Option<
|
||||
}
|
||||
|
||||
let cli_prompt = if include_agents {
|
||||
"Please output a clear plan to best achieve the Primary Goal. If this is not a trival task, launch agents in parallel to find the best approach. Use your tools to research while they are running."
|
||||
"Please provide a clear plan to best achieve the Primary Goal. If this is not a trival task, launch agents and use your tools to research the best approach. If this is a trival task, or the plan is already in the conversation history, just imediately provide the plan. Judge the length of research and planning you perform based on the complexity of the task. For more complex tasks, you could break the plan into workstreams which can be performed at the same time."
|
||||
} else {
|
||||
"Please output a clear plan to best achieve the Primary Goal. If this is not a trival task, use your tools to research the best approach."
|
||||
"Please provide a clear plan to best achieve the Primary Goal. If this is not a trival task, use your tools to research the best approach. If this is a trival task, or the plan is already in the conversation history, just imediately provide the plan. Judge the length of research and planning you perform based on the complexity of the task."
|
||||
};
|
||||
|
||||
Some(InitialPlanningSeed {
|
||||
|
||||
@@ -30661,10 +30661,20 @@ impl WidgetRef for &ChatWidget<'_> {
|
||||
requested_spacer_lines = requested_spacer_lines.max(1);
|
||||
}
|
||||
|
||||
let spacer_lines = self
|
||||
let (spacer_lines, spacer_pending_shrink) = self
|
||||
.history_render
|
||||
.select_bottom_spacer_lines(requested_spacer_lines);
|
||||
|
||||
if spacer_pending_shrink {
|
||||
// Force a follow-up frame so the spacer can settle back to the newly
|
||||
// requested height even if no additional history events arrive. Without
|
||||
// this, we'd keep the stale overscan row on-screen until the user types
|
||||
// or resizes the window again.
|
||||
let _ = self.app_event_tx.send(AppEvent::ScheduleFrameIn(
|
||||
HISTORY_ANIMATION_FRAME_INTERVAL,
|
||||
));
|
||||
}
|
||||
|
||||
if spacer_lines > 0 {
|
||||
total_height = total_height.saturating_add(spacer_lines);
|
||||
self.history_render
|
||||
|
||||
@@ -164,25 +164,35 @@ impl HistoryRenderState {
|
||||
self.bottom_spacer_range.set(range);
|
||||
}
|
||||
|
||||
pub(crate) fn select_bottom_spacer_lines(&self, requested: u16) -> u16 {
|
||||
pub(crate) fn select_bottom_spacer_lines(&self, requested: u16) -> (u16, bool) {
|
||||
let current = self.bottom_spacer_lines.get();
|
||||
if requested >= current {
|
||||
self.bottom_spacer_lines.set(requested);
|
||||
self.pending_bottom_spacer_lines.set(None);
|
||||
return requested;
|
||||
return (requested, false);
|
||||
}
|
||||
|
||||
let pending = self.pending_bottom_spacer_lines.get();
|
||||
if pending == Some(requested) {
|
||||
self.bottom_spacer_lines.set(requested);
|
||||
self.pending_bottom_spacer_lines.set(None);
|
||||
requested
|
||||
(requested, false)
|
||||
} else {
|
||||
self.pending_bottom_spacer_lines.set(Some(requested));
|
||||
current
|
||||
(current, true)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-helpers"))]
|
||||
pub(crate) fn bottom_spacer_lines_for_test(&self) -> u16 {
|
||||
self.bottom_spacer_lines.get()
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-helpers"))]
|
||||
pub(crate) fn pending_bottom_spacer_lines_for_test(&self) -> Option<u16> {
|
||||
self.pending_bottom_spacer_lines.get()
|
||||
}
|
||||
|
||||
pub(crate) fn adjust_scroll_to_content(&self, mut scroll_pos: u16) -> u16 {
|
||||
if scroll_pos == 0 {
|
||||
return scroll_pos;
|
||||
|
||||
@@ -220,6 +220,23 @@ impl ChatWidgetHarness {
|
||||
out
|
||||
}
|
||||
|
||||
pub fn take_scheduled_frame_events(&self) -> usize {
|
||||
self.drain_events()
|
||||
.into_iter()
|
||||
.filter(|event| matches!(event, AppEvent::ScheduleFrameIn(_)))
|
||||
.count()
|
||||
}
|
||||
|
||||
pub fn bottom_spacer_lines(&self) -> u16 {
|
||||
self.chat.history_render.bottom_spacer_lines_for_test()
|
||||
}
|
||||
|
||||
pub fn pending_bottom_spacer_request(&self) -> Option<u16> {
|
||||
self.chat
|
||||
.history_render
|
||||
.pending_bottom_spacer_lines_for_test()
|
||||
}
|
||||
|
||||
pub(crate) fn chat(&mut self) -> &mut ChatWidget<'static> {
|
||||
&mut self.chat
|
||||
}
|
||||
|
||||
@@ -72,6 +72,54 @@ fn bottom_spacer_skips_when_history_fits() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bottom_spacer_hysteresis_requests_followup_frame() {
|
||||
let heights: Vec<u16> = (18..=44).collect();
|
||||
let mut exercised = false;
|
||||
|
||||
'outer: for activate_h in &heights {
|
||||
for release_h in &heights {
|
||||
if activate_h == release_h {
|
||||
continue;
|
||||
}
|
||||
let mut harness = ChatWidgetHarness::new();
|
||||
seed_overflow_wrapped_transcript(&mut harness);
|
||||
|
||||
let _ = render_chat_widget_to_vt100(&mut harness, 100, *activate_h);
|
||||
if harness.bottom_spacer_lines() == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
harness.take_scheduled_frame_events();
|
||||
|
||||
let _ = render_chat_widget_to_vt100(&mut harness, 100, *release_h);
|
||||
let Some(target) = harness.pending_bottom_spacer_request() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let scheduled = harness.take_scheduled_frame_events();
|
||||
assert!(
|
||||
scheduled > 0,
|
||||
"viewport transition {activate_h}->{release_h} should schedule a follow-up frame"
|
||||
);
|
||||
|
||||
let _ = render_chat_widget_to_vt100(&mut harness, 100, *release_h);
|
||||
assert_eq!(
|
||||
harness.bottom_spacer_lines(),
|
||||
target,
|
||||
"follow-up frame should settle spacer height"
|
||||
);
|
||||
exercised = true;
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
|
||||
assert!(
|
||||
exercised,
|
||||
"failed to find a viewport transition that exercises spacer hysteresis"
|
||||
);
|
||||
}
|
||||
|
||||
fn seed_short_wrapped_transcript(harness: &mut ChatWidgetHarness) {
|
||||
harness.push_user_prompt(
|
||||
"Could you provide a detailed overview of how the anti-clipping spacer works?\n\nMake sure the explanation spans multiple lines so we can exercise wrapping in the viewport.",
|
||||
|
||||
Reference in New Issue
Block a user