From 763841212826142ce248ef3d94524424c6316b0b Mon Sep 17 00:00:00 2001 From: sigoden Date: Fri, 23 Feb 2024 13:15:18 +0800 Subject: feat: support `-e/--execute` to execute shell command (#318) --- src/config/mod.rs | 16 +++++++++++++++- src/config/role.rs | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) (limited to 'src/config') diff --git a/src/config/mod.rs b/src/config/mod.rs index df74716..d38cbf3 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -158,7 +158,7 @@ impl Config { Ok(config) } - pub fn onstart(&mut self) -> Result<()> { + pub fn prelude(&mut self) -> Result<()> { let prelude = self.prelude.clone(); let err_msg = || format!("Invalid prelude '{}", prelude); match prelude.split_once(':') { @@ -275,6 +275,20 @@ impl Config { pub fn set_role(&mut self, name: &str) -> Result<()> { let role = self.retrieve_role(name)?; + self.set_role_obj(role) + } + + pub fn set_execute_role(&mut self) -> Result<()> { + let role = Role::for_execute(); + self.set_role_obj(role) + } + + pub fn set_describe_role(&mut self) -> Result<()> { + let role = Role::for_describe(); + self.set_role_obj(role) + } + + pub fn set_role_obj(&mut self, role: Role) -> Result<()> { if let Some(session) = self.session.as_mut() { session.update_role(Some(role.clone()))?; } diff --git a/src/config/role.rs b/src/config/role.rs index bd7216c..ff60b55 100644 --- a/src/config/role.rs +++ b/src/config/role.rs @@ -1,4 +1,7 @@ -use crate::client::{Message, MessageContent, MessageRole}; +use crate::{ + client::{Message, MessageContent, MessageRole}, + utils::{detect_os, detect_shell}, +}; use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; @@ -18,6 +21,39 @@ pub struct Role { } impl Role { + pub fn for_execute() -> Self { + let os = detect_os(); + let shell = detect_shell(); + let shell = match shell.rsplit_once('/') { + Some((_, v)) => v, + None => &shell, + }; + Self { + name: "__builtin__".into(), + prompt: format!( + r#"Provide only {shell} commands for {os} without any description. +If there is a lack of details, provide most logical solution. +Ensure the output is a valid shell command. +If multiple steps required try to combine them together using &&. +Provide only plain text without Markdown formatting. +Do not provide markdown formatting such as ```"# + ), + temperature: None, + } + } + + pub fn for_describe() -> Self { + Self { + name: "__builtin__".into(), + prompt: r#"Provide a terse, single sentence description of the given shell command. +Describe each argument and option of the command. +Provide short responses in about 80 words. +APPLY MARKDOWN formatting when possible."# + .into(), + temperature: None, + } + } + pub fn info(&self) -> Result { let output = serde_yaml::to_string(&self) .with_context(|| format!("Unable to show info about role {}", &self.name))?; -- cgit v1.2.3