Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions crates/terraphim_agent/src/onboarding/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ pub enum OnboardingError {
#[error("Validation failed: {0}")]
Validation(String),

/// Configuration error from terraphim_config
#[error("Configuration error: {0}")]
Config(String),

/// IO error during file operations
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
Expand All @@ -55,22 +51,10 @@ pub enum OnboardingError {
#[error("Not a TTY - interactive mode requires a terminal. Use --template for non-interactive mode.")]
NotATty,

/// Role with this name already exists
#[error("Role already exists: {0}")]
RoleExists(String),

/// JSON serialization/deserialization error
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),

/// Network error during URL validation
#[error("Network error: {0}")]
Network(String),

/// Path does not exist
#[error("Path does not exist: {0}")]
PathNotFound(String),

/// User went back in wizard navigation
#[error("User navigated back")]
NavigateBack,
Expand Down
21 changes: 0 additions & 21 deletions crates/terraphim_agent/src/onboarding/prompts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,27 +572,6 @@ pub fn prompt_knowledge_graph() -> Result<PromptResult<Option<KnowledgeGraph>>,
}
}

/// Prompt for confirmation with custom message
pub fn prompt_confirm(message: &str, default: bool) -> Result<bool, OnboardingError> {
let theme = ColorfulTheme::default();
Ok(Confirm::with_theme(&theme)
.with_prompt(message)
.default(default)
.interact()?)
}

/// Prompt for simple text input
pub fn prompt_input(message: &str, default: Option<&str>) -> Result<String, OnboardingError> {
let theme = ColorfulTheme::default();
let mut input = Input::with_theme(&theme).with_prompt(message);

if let Some(d) = default {
input = input.default(d.to_string());
}

Ok(input.interact_text()?)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 0 additions & 4 deletions crates/terraphim_agent/src/onboarding/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ pub enum ValidationError {
#[error("Service {0} requires: {1}")]
ServiceRequirement(String, String),

/// Path does not exist on filesystem
#[error("Path does not exist: {0}")]
PathNotFound(String),

/// URL is malformed
#[error("Invalid URL: {0}")]
InvalidUrl(String),
Expand Down
95 changes: 32 additions & 63 deletions crates/terraphim_agent/src/onboarding/wizard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
//! Provides the interactive setup wizard flow for first-time users
//! and add-role capability for extending existing configurations.

use std::path::PathBuf;

use dialoguer::{theme::ColorfulTheme, Confirm, Select};
use std::path::PathBuf;
use terraphim_config::Role;
use terraphim_types::RelevanceFunction;

use super::prompts::{
prompt_haystacks, prompt_knowledge_graph, prompt_llm_config, prompt_relevance_function,
prompt_role_basics, prompt_theme, PromptResult,
prompt_role_basics, prompt_theme,
};
use super::templates::{ConfigTemplate, TemplateRegistry};
use super::validation::validate_role;
Expand Down Expand Up @@ -110,6 +109,7 @@ impl QuickStartChoice {
}

/// Check if this is a first run (no existing configuration)
#[cfg(test)]
pub fn is_first_run(config_path: &PathBuf) -> bool {
!config_path.exists()
}
Expand Down Expand Up @@ -312,7 +312,7 @@ fn prompt_path_for_template(
.map_err(|_| OnboardingError::Cancelled)?;

if !proceed {
return Err(OnboardingError::PathNotFound(expanded));
return Err(OnboardingError::Cancelled);
}
}

Expand All @@ -328,84 +328,53 @@ fn custom_wizard(theme: &ColorfulTheme) -> Result<Role, OnboardingError> {
println!();

// Step 1: Role basics (name and shortname)
let (name, shortname) = match prompt_role_basics()? {
PromptResult::Value(v) => v,
PromptResult::Back => return Err(OnboardingError::NavigateBack),
};
let (name, shortname) = prompt_role_basics()?.into_result()?;

let mut role = Role::new(name);
role.shortname = shortname;

// Step 2: Theme selection
role.theme = match prompt_theme()? {
PromptResult::Value(t) => t,
PromptResult::Back => {
// Go back to role basics - restart wizard
return Err(OnboardingError::NavigateBack);
}
};
role.theme = prompt_theme()?.into_result()?;

// Step 3: Relevance function
let relevance = match prompt_relevance_function()? {
PromptResult::Value(r) => r,
PromptResult::Back => {
// Go back - restart wizard
return Err(OnboardingError::NavigateBack);
}
};
let relevance = prompt_relevance_function()?.into_result()?;
role.relevance_function = relevance;
// Set terraphim_it based on relevance function (TerraphimGraph requires it)
role.terraphim_it = matches!(relevance, RelevanceFunction::TerraphimGraph);

// Step 4: Haystacks
role.haystacks = match prompt_haystacks()? {
PromptResult::Value(haystacks) => haystacks,
PromptResult::Back => {
return Err(OnboardingError::NavigateBack);
}
};
role.haystacks = prompt_haystacks()?.into_result()?;

// Step 5: LLM configuration (optional)
match prompt_llm_config()? {
PromptResult::Value(llm_config) => {
if let Some(provider) = llm_config.provider {
role.llm_enabled = true;
role.extra.insert(
"llm_provider".to_string(),
serde_json::Value::String(provider),
);
if let Some(model) = llm_config.model {
role.extra
.insert("ollama_model".to_string(), serde_json::Value::String(model));
}
if let Some(base_url) = llm_config.base_url {
role.extra.insert(
"ollama_base_url".to_string(),
serde_json::Value::String(base_url),
);
}
if let Some(api_key) = llm_config.api_key {
role.extra.insert(
"openrouter_api_key".to_string(),
serde_json::Value::String(api_key),
);
}
} else {
role.llm_enabled = false;
}
let llm_config = prompt_llm_config()?.into_result()?;
if let Some(provider) = llm_config.provider {
role.llm_enabled = true;
role.extra.insert(
"llm_provider".to_string(),
serde_json::Value::String(provider),
);
if let Some(model) = llm_config.model {
role.extra
.insert("ollama_model".to_string(), serde_json::Value::String(model));
}
if let Some(base_url) = llm_config.base_url {
role.extra.insert(
"ollama_base_url".to_string(),
serde_json::Value::String(base_url),
);
}
PromptResult::Back => {
return Err(OnboardingError::NavigateBack);
if let Some(api_key) = llm_config.api_key {
role.extra.insert(
"openrouter_api_key".to_string(),
serde_json::Value::String(api_key),
);
}
} else {
role.llm_enabled = false;
}

// Step 6: Knowledge graph (optional)
role.kg = match prompt_knowledge_graph()? {
PromptResult::Value(kg) => kg,
PromptResult::Back => {
return Err(OnboardingError::NavigateBack);
}
};
role.kg = prompt_knowledge_graph()?.into_result()?;

// Validate the complete role
validate_role(&role).map_err(|errors| {
Expand Down
Loading
Loading