first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -4,6 +4,6 @@ mod view;
|
||||
pub use model::{FinalState, OnboardingQuery};
|
||||
pub use view::{OnboardingCalloutView, OnboardingCalloutViewEvent, OnboardingKeybindings};
|
||||
|
||||
pub fn init(app: &mut galaxyui::AppContext) {
|
||||
pub fn init(app: &mut galaxyui_core::AppContext) {
|
||||
view::init(app);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use galaxy_core::send_telemetry_from_ctx;
|
||||
use galaxyui_core::{Entity, ModelContext};
|
||||
|
||||
use crate::telemetry::OnboardingEvent;
|
||||
use crate::OnboardingIntention;
|
||||
use galaxy_core::send_telemetry_from_ctx;
|
||||
use galaxyui::{Entity, ModelContext};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum FinalState {
|
||||
@@ -64,14 +65,10 @@ pub(super) enum UniversalInputCalloutState {
|
||||
pub(super) enum AgentModalityCalloutState {
|
||||
#[default]
|
||||
Off,
|
||||
/// Step 1: "Meet your terminal input" / "Meet your updated terminal input"
|
||||
MeetTerminalInput,
|
||||
/// Step 2: "Natural language support" with checkbox
|
||||
NaturalLanguageSupport,
|
||||
/// Step 3: "Introducing Warp's new agent experience" (Agent intention only)
|
||||
IntroducingAgentExperience,
|
||||
/// Step 4: "Updated agent input" (Agent intention only)
|
||||
UpdatedAgentInput,
|
||||
/// Step 1: terminal input with natural language support.
|
||||
TerminalMode,
|
||||
/// Step 2: "Agent Mode" (Agent intention only).
|
||||
AgentMode,
|
||||
/// Terminal state
|
||||
Complete(FinalState),
|
||||
}
|
||||
@@ -187,13 +184,9 @@ impl OnboardingCalloutModel {
|
||||
) {
|
||||
let (next_state, emit_enter_agent_modality) = match state {
|
||||
AgentModalityCalloutState::Off => {
|
||||
(Some(AgentModalityCalloutState::MeetTerminalInput), false)
|
||||
(Some(AgentModalityCalloutState::TerminalMode), false)
|
||||
}
|
||||
AgentModalityCalloutState::MeetTerminalInput => (
|
||||
Some(AgentModalityCalloutState::NaturalLanguageSupport),
|
||||
false,
|
||||
),
|
||||
AgentModalityCalloutState::NaturalLanguageSupport => {
|
||||
AgentModalityCalloutState::TerminalMode => {
|
||||
// For Terminal intention, finish here
|
||||
// For Agent intention, continue to IntroducingAgentExperience
|
||||
match self.intention {
|
||||
@@ -203,17 +196,11 @@ impl OnboardingCalloutModel {
|
||||
),
|
||||
OnboardingIntention::AgentDrivenDevelopment => {
|
||||
// Signal to enter agent modality when showing the agent experience slide
|
||||
(
|
||||
Some(AgentModalityCalloutState::IntroducingAgentExperience),
|
||||
true,
|
||||
)
|
||||
(Some(AgentModalityCalloutState::AgentMode), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
AgentModalityCalloutState::IntroducingAgentExperience => {
|
||||
(Some(AgentModalityCalloutState::UpdatedAgentInput), false)
|
||||
}
|
||||
AgentModalityCalloutState::UpdatedAgentInput => {
|
||||
AgentModalityCalloutState::AgentMode => {
|
||||
// For Agent with project: Initialize
|
||||
// For Agent without project: Finish
|
||||
let final_state = if self.has_project {
|
||||
@@ -246,7 +233,9 @@ impl OnboardingCalloutModel {
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::UpdatedAgentInput) => {
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::AgentMode)
|
||||
if self.has_project =>
|
||||
{
|
||||
// Skip initialization
|
||||
self.set_state(
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::Complete(
|
||||
@@ -272,9 +261,7 @@ impl OnboardingCalloutModel {
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
OnboardingCalloutState::AgentModality(
|
||||
AgentModalityCalloutState::NaturalLanguageSupport,
|
||||
) => {
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::TerminalMode) => {
|
||||
// Terminal intention finishes here
|
||||
self.set_state(
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::Complete(
|
||||
@@ -283,7 +270,9 @@ impl OnboardingCalloutModel {
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::UpdatedAgentInput) => {
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::AgentMode)
|
||||
if !self.has_project =>
|
||||
{
|
||||
// Agent without project finishes here
|
||||
self.set_state(
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::Complete(
|
||||
@@ -296,10 +285,10 @@ impl OnboardingCalloutModel {
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle "Back to terminal" action (ESC in UpdatedAgentInput without project)
|
||||
/// Handle "Back to terminal" action (ESC in IntroducingAgentExperience).
|
||||
pub fn back_to_terminal(&mut self, ctx: &mut ModelContext<Self>) {
|
||||
match &self.state {
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::UpdatedAgentInput) => {
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::AgentMode) => {
|
||||
self.set_state(
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::Complete(
|
||||
FinalState::BackToTerminal,
|
||||
@@ -342,17 +331,11 @@ impl OnboardingCalloutModel {
|
||||
OnboardingCalloutState::UniversalInput(UniversalInputCalloutState::TalkToAgent) => {
|
||||
Some("talk_to_agent")
|
||||
}
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::MeetTerminalInput) => {
|
||||
Some("meet_terminal_input")
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::TerminalMode) => {
|
||||
Some("natural_language_support")
|
||||
}
|
||||
OnboardingCalloutState::AgentModality(
|
||||
AgentModalityCalloutState::NaturalLanguageSupport,
|
||||
) => Some("natural_language_support"),
|
||||
OnboardingCalloutState::AgentModality(
|
||||
AgentModalityCalloutState::IntroducingAgentExperience,
|
||||
) => Some("introducing_agent_experience"),
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::UpdatedAgentInput) => {
|
||||
Some("updated_agent_input")
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::AgentMode) => {
|
||||
Some("introducing_agent_experience")
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
@@ -435,16 +418,10 @@ impl OnboardingCalloutModel {
|
||||
fn prompt_for_agent_modality(&self, state: AgentModalityCalloutState) -> OnboardingQuery {
|
||||
match state {
|
||||
AgentModalityCalloutState::Off => OnboardingQuery::None,
|
||||
AgentModalityCalloutState::MeetTerminalInput => {
|
||||
AgentModalityCalloutState::TerminalMode => {
|
||||
OnboardingQuery::TerminalCommand("Run a command...".to_string())
|
||||
}
|
||||
AgentModalityCalloutState::NaturalLanguageSupport => {
|
||||
OnboardingQuery::AgentPrompt("help me terraform my Gcloud setup".to_string())
|
||||
}
|
||||
AgentModalityCalloutState::IntroducingAgentExperience => {
|
||||
OnboardingQuery::AgentPrompt("Tell the agent what to build...".to_string())
|
||||
}
|
||||
AgentModalityCalloutState::UpdatedAgentInput => {
|
||||
AgentModalityCalloutState::AgentMode => {
|
||||
if self.has_project {
|
||||
OnboardingQuery::AgentPrompt("/init".to_string())
|
||||
} else {
|
||||
@@ -470,11 +447,9 @@ impl OnboardingCalloutModel {
|
||||
);
|
||||
}
|
||||
OnboardingCalloutState::AgentModality(_) => {
|
||||
log::info!("Transitioning to AgentModality::MeetTerminalInput");
|
||||
log::info!("Transitioning to AgentModality::NaturalLanguageSupport");
|
||||
self.set_state(
|
||||
OnboardingCalloutState::AgentModality(
|
||||
AgentModalityCalloutState::MeetTerminalInput,
|
||||
),
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::TerminalMode),
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use ui_components::Component;
|
||||
use galaxy_core::ui::appearance::Appearance;
|
||||
use galaxyui::{
|
||||
elements::Empty,
|
||||
keymap::{macros::*, FixedBinding, Keystroke},
|
||||
use galaxyui_core::elements::Empty;
|
||||
use galaxyui_core::keymap::macros::*;
|
||||
use galaxyui_core::keymap::{FixedBinding, Keystroke};
|
||||
use galaxyui_core::{
|
||||
AppContext, Element, Entity, EventContext, ModelHandle, SingletonEntity, TypedActionView, View,
|
||||
ViewContext,
|
||||
};
|
||||
use ui_components::Component;
|
||||
|
||||
/// Display strings for keybindings shown in the onboarding callout.
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -16,16 +17,16 @@ pub struct OnboardingKeybindings {
|
||||
pub submit_to_local_agent: String,
|
||||
/// Display string for submitting to cloud agent (e.g., "⌘⌥⏎")
|
||||
pub submit_to_cloud_agent: String,
|
||||
/// Display string for returning to terminal mode (e.g., "Esc")
|
||||
pub return_to_terminal_mode: String,
|
||||
}
|
||||
|
||||
use crate::{
|
||||
callout::model::{
|
||||
AgentModalityCalloutState, FinalState, OnboardingCalloutModel, OnboardingCalloutModelEvent,
|
||||
OnboardingCalloutState, OnboardingQuery, UniversalInputCalloutState,
|
||||
},
|
||||
components::onboarding_callout::{self, Button, StepStatus},
|
||||
OnboardingIntention,
|
||||
use crate::callout::model::{
|
||||
AgentModalityCalloutState, FinalState, OnboardingCalloutModel, OnboardingCalloutModelEvent,
|
||||
OnboardingCalloutState, OnboardingQuery, UniversalInputCalloutState,
|
||||
};
|
||||
use crate::components::onboarding_callout::{self, Button, StepStatus};
|
||||
use crate::OnboardingIntention;
|
||||
|
||||
/// Options for rendering a callout.
|
||||
struct CalloutOptions {
|
||||
@@ -105,46 +106,23 @@ fn get_agent_modality_callout_options(
|
||||
keybindings: &OnboardingKeybindings,
|
||||
) -> Option<CalloutOptions> {
|
||||
let total_steps = match intention {
|
||||
OnboardingIntention::Terminal => 2,
|
||||
OnboardingIntention::AgentDrivenDevelopment => 4,
|
||||
OnboardingIntention::Terminal => 1,
|
||||
OnboardingIntention::AgentDrivenDevelopment => 2,
|
||||
};
|
||||
|
||||
match state {
|
||||
AgentModalityCalloutState::MeetTerminalInput => {
|
||||
let title: &'static str = if has_project || intention == OnboardingIntention::Terminal {
|
||||
"Meet your terminal input"
|
||||
} else {
|
||||
"Meet your updated terminal input"
|
||||
};
|
||||
Some(CalloutOptions {
|
||||
title,
|
||||
text: format!(
|
||||
"Run commands from the terminal, or use {} or {} to start or send to a local or cloud agent respectively.",
|
||||
keybindings.submit_to_local_agent,
|
||||
keybindings.submit_to_cloud_agent
|
||||
),
|
||||
step: StepStatus::new(0, total_steps),
|
||||
left_button: None,
|
||||
right_button: ButtonOptions {
|
||||
text: "Next",
|
||||
action: OnboardingCalloutViewAction::NextClicked,
|
||||
keystroke: Some(Keystroke::parse("enter").unwrap_or_default()),
|
||||
},
|
||||
checkbox: None,
|
||||
})
|
||||
}
|
||||
AgentModalityCalloutState::NaturalLanguageSupport => {
|
||||
AgentModalityCalloutState::TerminalMode => {
|
||||
let is_final_step = intention == OnboardingIntention::Terminal;
|
||||
// Show different callout content based on initial NL detection state
|
||||
if initial_natural_language_detection_enabled {
|
||||
// NL detection was already enabled - show simpler "overrides" callout without checkbox
|
||||
Some(CalloutOptions {
|
||||
title: "Natural language overrides",
|
||||
title: "Welcome to terminal mode",
|
||||
text: format!(
|
||||
"You can always override any auto-detection using {}.",
|
||||
"Run commands here, just like a regular terminal. If you type a question or task using natural language, Warp can suggest opening it in agent mode. You can always override using {}.",
|
||||
keybindings.toggle_input_mode
|
||||
),
|
||||
step: StepStatus::new(1, total_steps),
|
||||
step: StepStatus::new(0, total_steps),
|
||||
left_button: None,
|
||||
right_button: ButtonOptions {
|
||||
text: if is_final_step { "Finish" } else { "Next" },
|
||||
@@ -156,12 +134,12 @@ fn get_agent_modality_callout_options(
|
||||
} else {
|
||||
// NL detection was disabled - show full explanation with checkbox to enable
|
||||
Some(CalloutOptions {
|
||||
title: "Natural language support",
|
||||
title: "You’re in terminal mode",
|
||||
text: format!(
|
||||
"Natural language input is off by default. If enabled, you can type requests in plain English and Warp will autodetect queries for the agent. You can always override them using {}.",
|
||||
"Run commands here, just like a regular terminal. If you type a question or task using natural language, Warp can suggest opening it in agent mode. You can always override using {}.",
|
||||
keybindings.toggle_input_mode
|
||||
),
|
||||
step: StepStatus::new(1, total_steps),
|
||||
step: StepStatus::new(0, total_steps),
|
||||
left_button: None,
|
||||
right_button: ButtonOptions {
|
||||
text: if is_final_step { "Finish" } else { "Next" },
|
||||
@@ -175,24 +153,12 @@ fn get_agent_modality_callout_options(
|
||||
})
|
||||
}
|
||||
}
|
||||
AgentModalityCalloutState::IntroducingAgentExperience => Some(CalloutOptions {
|
||||
title: "Introducing Warp's new agent experience",
|
||||
text: "Agent conversations are now their own scoped view outside of your terminal. Simply hit ESC to return to the terminal at any point.".to_string(),
|
||||
step: StepStatus::new(2, total_steps),
|
||||
left_button: None,
|
||||
right_button: ButtonOptions {
|
||||
text: "Next",
|
||||
action: OnboardingCalloutViewAction::NextClicked,
|
||||
keystroke: Some(Keystroke::parse("enter").unwrap_or_default()),
|
||||
},
|
||||
checkbox: None,
|
||||
}),
|
||||
AgentModalityCalloutState::UpdatedAgentInput => {
|
||||
AgentModalityCalloutState::AgentMode => {
|
||||
if has_project {
|
||||
Some(CalloutOptions {
|
||||
title: "Updated agent input",
|
||||
text: "Your agent input will detect natural language as well as commands by default. Use ! to lock the input in bash mode to write commands.\n\nSubmit the query below to have the agent initialize this project, or ⊗ to clear the input and start your own!".to_string(),
|
||||
step: StepStatus::new(3, total_steps),
|
||||
title: "You're in agent mode",
|
||||
text: "Agent mode gives your questions and tasks their own conversation, so you can ask follow-ups without leaving your terminal workflow.\n\nSubmit the query below to have the agent initialize this project, or ⊗ to clear the input and start your own!".to_string(),
|
||||
step: StepStatus::new(1, total_steps),
|
||||
left_button: Some(ButtonOptions {
|
||||
text: "Skip initialization",
|
||||
action: OnboardingCalloutViewAction::SkipClicked,
|
||||
@@ -207,9 +173,12 @@ fn get_agent_modality_callout_options(
|
||||
})
|
||||
} else {
|
||||
Some(CalloutOptions {
|
||||
title: "Updated agent input",
|
||||
text: "Your agent input will detect natural language as well as commands by default. Use ! to lock the input in bash mode to write commands.".to_string(),
|
||||
step: StepStatus::new(3, total_steps),
|
||||
title: "You're in agent mode",
|
||||
text: format!(
|
||||
"Agent mode gives your questions and tasks their own conversation, so you can ask follow-ups without leaving your terminal workflow. Press {} to return to terminal mode at any point.",
|
||||
keybindings.return_to_terminal_mode
|
||||
),
|
||||
step: StepStatus::new(1, total_steps),
|
||||
left_button: Some(ButtonOptions {
|
||||
text: "Back to terminal",
|
||||
action: OnboardingCalloutViewAction::BackToTerminalClicked,
|
||||
@@ -378,11 +347,11 @@ impl OnboardingCalloutView {
|
||||
}
|
||||
|
||||
/// Returns true if the callout should be positioned above the zero state.
|
||||
/// For UpdatedAgentInput state, always position relative to the input box instead.
|
||||
/// For the agent experience state, always position relative to the input box instead.
|
||||
pub fn should_position_above_zero_state(&self, app: &AppContext) -> bool {
|
||||
!matches!(
|
||||
self.model.as_ref(app).state(),
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::UpdatedAgentInput)
|
||||
OnboardingCalloutState::AgentModality(AgentModalityCalloutState::AgentMode)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user