Skip to content

Commit

Permalink
profile cli selection
Browse files Browse the repository at this point in the history
  • Loading branch information
aprxi committed Aug 27, 2024
1 parent 3a91afe commit 452e63d
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 31 deletions.
29 changes: 7 additions & 22 deletions lumni/src/apps/builtin/llm/prompt/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ use super::chat::{
PromptInstruction, ThreadedChatSession,
};
use super::cli::{
handle_db_subcommand, handle_profile_subcommand, parse_cli_arguments,
handle_db_subcommand, handle_profile_selection, handle_profile_subcommand,
parse_cli_arguments,
};
use super::server::{ModelServer, ServerTrait};
use crate::external as lumni;

async fn create_prompt_instruction(
Expand All @@ -42,26 +42,11 @@ async fn create_prompt_instruction(

let mut profile_handler = db_conn.get_profile_handler(None);

// Handle --profile option
// if let Some(profile_name) =
// matches.and_then(|m| m.get_one::<String>("profile"))
// {
// profile_handler.set_profile_name(profile_name.to_string());
// } else {
// // Use default profile if set
// if let Some(default_profile) =
// profile_handler.get_default_profile().await?
// {
// profile_handler.set_profile_name(default_profile);
// }
// }
//
// // Check if a profile is set
// if profile_handler.get_profile_name().is_none() {
// return Err(ApplicationError::InvalidInput(
// "No profile set".to_string(),
// ));
// }
handle_profile_selection(
&mut profile_handler,
matches.and_then(|m| m.get_one::<String>("profile")),
)
.await?;

// Get model_backend
let model_backend =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ impl UserProfileDbHandler {
pub async fn model_backend(
&mut self,
) -> Result<Option<ModelBackend>, ApplicationError> {
// TODO:
return Ok(Some(ModelBackend {
server: ModelServer::from_str("ollama")?,
model: None,
}));
let user_profile = self.profile.clone();

if let Some(profile) = user_profile {
Expand All @@ -76,18 +71,18 @@ impl UserProfileDbHandler {
.await?;

let model_server = settings
.get("__MODEL_SERVER")
.get("__TEMPLATE.__MODEL_SERVER")
.and_then(|v| v.as_str())
.ok_or_else(|| {
ApplicationError::InvalidInput(
"__MODEL_SERVER not found in profile".to_string(),
"MODEL_SERVER not found in profile".to_string(),
)
})?;

let server = ModelServer::from_str(model_server)?;

let model = settings
.get("__MODEL_IDENTIFIER")
.get("__TEMPLATE.MODEL_IDENTIFIER")
.and_then(|v| v.as_str())
.map(|identifier| ModelSpec::new_with_validation(identifier))
.transpose()?;
Expand Down
4 changes: 3 additions & 1 deletion lumni/src/apps/builtin/llm/prompt/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod select_profile;
mod subcommands;

use clap::{Arg, Command};
use lumni::api::spec::ApplicationSpec;
pub use select_profile::handle_profile_selection;
use subcommands::db::create_db_subcommand;
pub use subcommands::db::handle_db_subcommand;
use subcommands::profile::create_profile_subcommand;
Expand All @@ -27,7 +29,7 @@ pub fn parse_cli_arguments(spec: ApplicationSpec) -> Command {
Arg::new("profile")
.long("profile")
.short('p')
.help("Use a specific profile"),
.help("Select a profile (format: name, name::id, or ::id)"),
)
.arg(
Arg::new("system")
Expand Down
139 changes: 139 additions & 0 deletions lumni/src/apps/builtin/llm/prompt/src/cli/select_profile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use std::str::FromStr;

use lumni::api::error::ApplicationError;

use super::UserProfileDbHandler;
use crate::external as lumni;

pub async fn handle_profile_selection(
profile_handler: &mut UserProfileDbHandler,
profile_arg: Option<&String>,
) -> Result<(), ApplicationError> {
if let Some(profile_selector) = profile_arg {
let (name, id) = parse_profile_selector(profile_selector);

match (name, id) {
(Some(name), Some(id)) => {
// Case: name::id
select_profile_by_name_and_id(profile_handler, name, id)
.await?;
}
(Some(name), None) => {
// Case: name
select_profile_by_name(profile_handler, name).await?;
}
(None, Some(id)) => {
// Case: ::id
select_profile_by_id(profile_handler, id).await?;
}
_ => {
return Err(ApplicationError::InvalidInput(
"Invalid profile selector format".to_string(),
));
}
}
} else {
// Use default profile if set
if let Some(default_profile) =
profile_handler.get_default_profile().await?
{
profile_handler.set_profile(default_profile);
} else {
return Err(ApplicationError::InvalidInput(
"No profile set and no default profile available".to_string(),
));
}
}

// Check if a profile is set
if profile_handler.get_profile().is_none() {
return Err(ApplicationError::InvalidInput(
"No profile set".to_string(),
));
}

Ok(())
}

fn parse_profile_selector(selector: &str) -> (Option<&str>, Option<i64>) {
if selector.starts_with("::") {
// Case: ::id
let id_str = selector.trim_start_matches("::");
return (None, i64::from_str(id_str).ok());
}

let parts: Vec<&str> = selector.split("::").collect();
match parts.as_slice() {
[name, id] => (Some(name.trim()), i64::from_str(id.trim()).ok()),
[name] => (Some(name.trim()), None),
_ => (None, None),
}
}

async fn select_profile_by_name_and_id(
profile_handler: &mut UserProfileDbHandler,
name: &str,
id: i64,
) -> Result<(), ApplicationError> {
if let Some(profile) = profile_handler.get_profile_by_id(id).await? {
if profile.name == name {
profile_handler.set_profile(profile);
Ok(())
} else {
Err(ApplicationError::InvalidInput(format!(
"Profile with id {} does not match the name '{}'",
id, name
)))
}
} else {
Err(ApplicationError::InvalidInput(format!(
"No profile found with id {}",
id
)))
}
}

async fn select_profile_by_name(
profile_handler: &mut UserProfileDbHandler,
name: &str,
) -> Result<(), ApplicationError> {
let profiles = profile_handler.get_profiles_by_name(name).await?;
match profiles.len() {
0 => Err(ApplicationError::InvalidInput(format!(
"No profile found with name '{}'",
name
))),
1 => {
profile_handler.set_profile(profiles[0].clone());
Ok(())
}
_ => {
println!(
"Multiple profiles found with the name '{}'. Please specify \
the id:",
name
);
for profile in profiles {
println!(" ID: {}, Name: {}", profile.id, profile.name);
}
Err(ApplicationError::InvalidInput(
"Multiple profiles found. Please specify the id.".to_string(),
))
}
}
}

async fn select_profile_by_id(
profile_handler: &mut UserProfileDbHandler,
id: i64,
) -> Result<(), ApplicationError> {
if let Some(profile) = profile_handler.get_profile_by_id(id).await? {
profile_handler.set_profile(profile);
Ok(())
} else {
Err(ApplicationError::InvalidInput(format!(
"No profile found with id {}",
id
)))
}
}

0 comments on commit 452e63d

Please sign in to comment.