Skip to content

Commit 200e404

Browse files
echobtfactorydroid
andauthored
fix(tui): keep AI-Assisted agent creation flow interactive (#267)
Previously, when selecting 'AI-Assisted' in the agent creation flow, the TUI would exit interactive mode and show a toast asking the user to type in the main input box. This was confusing and broke the interactive flow. Now, selecting 'AI-Assisted' opens an inline form within the TUI panel where users can type their agent description directly, keeping the entire workflow interactive and consistent with other features like MCP server configuration. Changes: - Add build_agent_ai_description_form() function to create inline form - Export the new function from the builders module - Update agent_method handler to open inline form instead of exiting - Add handler for agent-ai-create form submission - Add unit test for the new form builder Co-authored-by: Droid Agent <droid@factory.ai>
1 parent d0bf9fd commit 200e404

3 files changed

Lines changed: 91 additions & 10 deletions

File tree

cortex-tui/src/interactive/builders/agents.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
77
use std::path::Path;
88

9-
use crate::interactive::state::{InteractiveAction, InteractiveItem, InteractiveState};
9+
use crate::interactive::state::{
10+
InlineFormField, InlineFormState, InteractiveAction, InteractiveItem, InteractiveState,
11+
};
1012

1113
/// Agent type for grouping in the list
1214
#[derive(Debug, Clone, Copy, PartialEq)]
@@ -650,6 +652,27 @@ impl NewAgentConfig {
650652
}
651653
}
652654

655+
/// Build an inline form for AI-assisted agent creation description.
656+
///
657+
/// This form stays in the interactive TUI and allows the user to type
658+
/// their agent description directly.
659+
pub fn build_agent_ai_description_form(location: AgentLocation) -> InlineFormState {
660+
let location_str = match location {
661+
AgentLocation::Project => "project",
662+
AgentLocation::Global => "global",
663+
};
664+
665+
InlineFormState::new(
666+
"Describe Your Agent",
667+
format!("agent-ai-create:{}", location_str),
668+
)
669+
.with_field(
670+
InlineFormField::new("description", "Description")
671+
.required()
672+
.with_placeholder("Describe what you want the agent to do..."),
673+
)
674+
}
675+
653676
/// Build an interactive state for confirming a new agent configuration
654677
pub fn build_agent_confirm_selector(config: &NewAgentConfig) -> InteractiveState {
655678
let mut items = Vec::new();
@@ -777,4 +800,19 @@ mod tests {
777800
assert_eq!(project.category, AgentCategory::Project);
778801
assert!(project.source.is_some());
779802
}
803+
804+
#[test]
805+
fn test_build_agent_ai_description_form() {
806+
// Test for project location
807+
let form = build_agent_ai_description_form(AgentLocation::Project);
808+
assert_eq!(form.title, "Describe Your Agent");
809+
assert_eq!(form.action_id, "agent-ai-create:project");
810+
assert_eq!(form.fields.len(), 1);
811+
assert_eq!(form.fields[0].name, "description");
812+
assert!(form.fields[0].required);
813+
814+
// Test for global location
815+
let form_global = build_agent_ai_description_form(AgentLocation::Global);
816+
assert_eq!(form_global.action_id, "agent-ai-create:global");
817+
}
780818
}

cortex-tui/src/interactive/builders/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ pub mod theme;
1919

2020
pub use agents::{
2121
AgentCategory, AgentCreationMethod, AgentDisplayInfo, AgentLocation, NewAgentConfig,
22-
PermissionPreset, build_agent_confirm_selector, build_agent_location_selector,
23-
build_agent_method_selector, build_agents_selector, build_permission_selector,
22+
PermissionPreset, build_agent_ai_description_form, build_agent_confirm_selector,
23+
build_agent_location_selector, build_agent_method_selector, build_agents_selector,
24+
build_permission_selector,
2425
};
2526
pub use approval::{build_approval_selector, build_log_level_selector};
2627
pub use export::build_export_selector;

cortex-tui/src/runner/event_loop.rs

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6169,6 +6169,41 @@ impl EventLoop {
61696169
self.reopen_mcp_panel();
61706170
true
61716171
}
6172+
action if action.starts_with("agent-ai-create:") => {
6173+
// AI-assisted agent creation from inline form
6174+
let location_str = action.strip_prefix("agent-ai-create:").unwrap_or("project");
6175+
let description = values.get("description").cloned().unwrap_or_default();
6176+
6177+
if description.is_empty() {
6178+
self.app_state
6179+
.toasts
6180+
.error("Please describe what you want the agent to do");
6181+
return true; // Stay in form
6182+
}
6183+
6184+
// Determine location
6185+
use crate::interactive::builders::AgentLocation;
6186+
let location = match location_str {
6187+
"global" => AgentLocation::Global,
6188+
_ => AgentLocation::Project,
6189+
};
6190+
6191+
// Store location for later use
6192+
self.app_state.agent_creation_location = Some(location);
6193+
// Set mode to AI and store the description for processing
6194+
self.app_state.agent_creation_mode = Some("ai".to_string());
6195+
6196+
// Insert the description into the input box and trigger AI generation
6197+
let prompt = format!("Create an agent with this description: {}", description);
6198+
self.app_state.input.set_text(&prompt);
6199+
6200+
self.app_state
6201+
.toasts
6202+
.info("Generating agent configuration...");
6203+
6204+
// Exit interactive mode - the description will be processed
6205+
false
6206+
}
61726207
_ => {
61736208
tracing::warn!("Unhandled inline form submission: {}", action_id);
61746209
false
@@ -6614,13 +6649,20 @@ impl EventLoop {
66146649
"agent_method" => {
66156650
// Handle method selection (AI or manual)
66166651
if item_id.starts_with("ai:") {
6617-
// AI-assisted creation - prompt for description
6618-
self.app_state
6619-
.toasts
6620-
.info("Describe the agent you want to create in the input box");
6621-
// Set mode to await AI agent creation
6622-
self.app_state.agent_creation_mode = Some("ai".to_string());
6623-
return false; // Exit interactive mode, user types description
6652+
// AI-assisted creation - show inline form for description
6653+
use crate::interactive::builders::{
6654+
AgentLocation, build_agent_ai_description_form,
6655+
};
6656+
let location = self
6657+
.app_state
6658+
.agent_creation_location
6659+
.unwrap_or(AgentLocation::Project);
6660+
// Open inline form within the interactive panel
6661+
if let Some(state) = self.app_state.input_mode.interactive_mut() {
6662+
let form = build_agent_ai_description_form(location);
6663+
state.open_form(form);
6664+
}
6665+
return true; // Stay in interactive mode
66246666
} else if item_id.starts_with("manual:") {
66256667
// Manual creation - show permission selector
66266668
let interactive =

0 commit comments

Comments
 (0)