diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/config/mod.rs | 36 | ||||
| -rw-r--r-- | src/config/session.rs | 37 | ||||
| -rw-r--r-- | src/main.rs | 2 | ||||
| -rw-r--r-- | src/repl/handler.rs | 28 | ||||
| -rw-r--r-- | src/repl/mod.rs | 29 |
5 files changed, 95 insertions, 37 deletions
diff --git a/src/config/mod.rs b/src/config/mod.rs index e6d9238..9f4a11a 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -148,12 +148,16 @@ impl Config { Ok(config) } - pub fn get_role(&self, name: &str) -> Option<Role> { - self.roles.iter().find(|v| v.match_name(name)).map(|v| { - let mut role = v.clone(); - role.complete_prompt_args(name); - role - }) + pub fn retrieve_role(&self, name: &str) -> Result<Role> { + self.roles + .iter() + .find(|v| v.match_name(name)) + .map(|v| { + let mut role = v.clone(); + role.complete_prompt_args(name); + role + }) + .ok_or_else(|| anyhow!("Unknown role `{name}`")) } pub fn config_dir() -> Result<PathBuf> { @@ -235,20 +239,14 @@ impl Config { Ok(path) } - pub fn set_role(&mut self, name: &str) -> Result<String> { - match self.get_role(name) { - Some(role) => { - if let Some(session) = self.session.as_mut() { - session.update_role(Some(role.clone()))?; - } - let output = serde_yaml::to_string(&role) - .unwrap_or_else(|_| "Unable to echo role details".into()); - self.temperature = role.temperature; - self.role = Some(role); - Ok(output) - } - None => bail!("Unknown role `{name}`"), + pub fn set_role(&mut self, name: &str) -> Result<()> { + let role = self.retrieve_role(name)?; + if let Some(session) = self.session.as_mut() { + session.update_role(Some(role.clone()))?; } + self.temperature = role.temperature; + self.role = Some(role); + Ok(()) } pub fn clear_role(&mut self) -> Result<()> { diff --git a/src/config/session.rs b/src/config/session.rs index 75b863f..4cc172d 100644 --- a/src/config/session.rs +++ b/src/config/session.rs @@ -1,6 +1,8 @@ use super::message::{num_tokens_from_messages, Message, MessageRole}; use super::role::Role; +use crate::render::MarkdownRender; + use anyhow::{bail, Context, Result}; use serde::{Deserialize, Serialize}; use std::fs::{self, read_to_string}; @@ -52,13 +54,46 @@ impl Session { Ok(session) } - pub fn info(&self) -> Result<String> { + pub fn export(&self) -> Result<String> { self.guard_save()?; let output = serde_yaml::to_string(&self) .with_context(|| format!("Unable to show info about session {}", &self.name))?; Ok(output) } + pub fn render(&self, render: &mut MarkdownRender) -> Result<String> { + let temperature = self + .temperature + .map_or_else(|| String::from("-"), |v| v.to_string()); + let items = vec![ + ("path", self.path.clone().unwrap_or_else(|| "-".into())), + ("model", self.model.clone()), + ("tokens", self.tokens.to_string()), + ("temperature", temperature), + ]; + let mut lines = vec![]; + for (name, value) in items { + lines.push(format!("{name:<20}{value}")); + } + lines.push("".into()); + for message in &self.messages { + match message.role { + MessageRole::System => { + continue; + } + MessageRole::Assistant => { + lines.push(render.render(&message.content)); + lines.push("".into()); + } + MessageRole::User => { + lines.push(format!("{}){}", self.name, message.content)); + } + } + } + let output = lines.join("\n"); + Ok(output) + } + pub fn update_role(&mut self, role: Option<Role>) -> Result<()> { self.guard_empty()?; self.temperature = role.as_ref().and_then(|v| v.temperature); diff --git a/src/main.rs b/src/main.rs index a23a81f..8e1835a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -69,7 +69,7 @@ fn main() -> Result<()> { } if cli.info { let info = if let Some(session) = &config.read().session { - session.info()? + session.export()? } else if let Some(role) = &config.read().role { role.info()? } else { diff --git a/src/repl/handler.rs b/src/repl/handler.rs index d70abbe..afe016a 100644 --- a/src/repl/handler.rs +++ b/src/repl/handler.rs @@ -1,7 +1,7 @@ use crate::client::init_client; use crate::config::SharedConfig; use crate::print_now; -use crate::render::render_stream; +use crate::render::{render_stream, MarkdownRender}; use std::fs; use std::io::Read; @@ -15,7 +15,9 @@ use std::cell::RefCell; pub enum ReplCmd { Submit(String), - ViewInfo, + Info, + RoleInfo, + SessionInfo, SetModel(String), SetRole(String), ExitRole, @@ -66,7 +68,7 @@ impl ReplCmdHandler { let _ = self.copy(&buffer); } } - ReplCmd::ViewInfo => { + ReplCmd::Info => { let output = self.config.read().info()?; print_now!("{}\n\n", output.trim_end()); } @@ -75,8 +77,15 @@ impl ReplCmdHandler { print_now!("\n"); } ReplCmd::SetRole(name) => { - let output = self.config.write().set_role(&name)?; - print_now!("{}\n\n", output.trim_end()); + self.config.write().set_role(&name)?; + print_now!("\n"); + } + ReplCmd::RoleInfo => { + if let Some(role) = &self.config.read().role { + print_now!("{}\n\n", role.info()?); + } else { + bail!("No role") + } } ReplCmd::ExitRole => { self.config.write().clear_role()?; @@ -86,6 +95,15 @@ impl ReplCmdHandler { self.config.write().start_session(&name)?; print_now!("\n"); } + ReplCmd::SessionInfo => { + if let Some(session) = &self.config.read().session { + let render_options = self.config.read().get_render_options(); + let mut markdown_render = MarkdownRender::init(render_options)?; + print_now!("{}\n\n", session.render(&mut markdown_render)?); + } else { + bail!("No session") + } + } ReplCmd::ExitSession => { self.config.write().end_session()?; print_now!("\n"); diff --git a/src/repl/mod.rs b/src/repl/mod.rs index e5691dc..4cf59f7 100644 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -18,14 +18,16 @@ use lazy_static::lazy_static; use reedline::Signal; use std::rc::Rc; -pub const REPL_COMMANDS: [(&str, &str); 12] = [ +pub const REPL_COMMANDS: [(&str, &str); 14] = [ (".help", "Print this help message"), - (".info", "Print system-wide information"), + (".info", "Print system info"), (".edit", "Multi-line editing (CTRL+S to finish)"), (".model", "Switch LLM model"), (".role", "Use role"), + (".info role", "Show role info"), (".exit role", "Leave current role"), (".session", "Start a context-aware chat session"), + (".info session", "Show session info"), (".exit session", "End the current session"), (".set", "Modify the configuration parameters"), (".copy", "Copy the last reply to the clipboard"), @@ -66,7 +68,7 @@ impl Repl { } Err(err) => { let err = format!("{err:?}"); - print_now!("{}\n\n", err.trim()); + print_now!("Error: {}\n\n", err.trim()); } } } @@ -95,9 +97,14 @@ impl Repl { ".help" => { dump_repl_help(); } - ".info" => { - handler.handle(ReplCmd::ViewInfo)?; - } + ".info" => match args { + Some("role") => handler.handle(ReplCmd::RoleInfo)?, + Some("session") => handler.handle(ReplCmd::SessionInfo)?, + Some(_) => unknown_command(), + None => { + handler.handle(ReplCmd::Info)?; + } + }, ".edit" => { if let Some(text) = args { handler.handle(ReplCmd::Submit(text.to_string()))?; @@ -128,7 +135,7 @@ impl Repl { ".exit" => match args { Some("role") => handler.handle(ReplCmd::ExitRole)?, Some("session") => handler.handle(ReplCmd::ExitSession)?, - Some(_) => dump_unknown_command(), + Some(_) => unknown_command(), None => { return Ok(true); } @@ -141,9 +148,9 @@ impl Repl { Some("session") => { print_now!("Deprecated. Use '.exit session' instead.\n\n"); } - _ => dump_unknown_command(), + _ => unknown_command(), }, - _ => dump_unknown_command(), + _ => unknown_command(), }, None => { handler.handle(ReplCmd::Submit(line.to_string()))?; @@ -154,8 +161,8 @@ impl Repl { } } -fn dump_unknown_command() { - print_now!("Unknown command. Type \".help\" for more information.\n\n"); +fn unknown_command() { + print_now!("Unknown command. Try `.help`.\n\n"); } fn dump_repl_help() { |
