summaryrefslogtreecommitdiffstats
path: root/src/config
diff options
context:
space:
mode:
authorsigoden <sigoden@gmail.com>2024-02-23 13:15:18 +0800
committerGitHub <noreply@github.com>2024-02-23 13:15:18 +0800
commit763841212826142ce248ef3d94524424c6316b0b (patch)
tree6805fb523b3fa149744d8534928941a023e0d149 /src/config
parent6c0204e6965bf13c3d883ea5fa65d52415acd530 (diff)
downloadaichat-763841212826142ce248ef3d94524424c6316b0b.tar.gz
feat: support `-e/--execute` to execute shell command (#318)
Diffstat (limited to 'src/config')
-rw-r--r--src/config/mod.rs16
-rw-r--r--src/config/role.rs38
2 files changed, 52 insertions, 2 deletions
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<String> {
let output = serde_yaml::to_string(&self)
.with_context(|| format!("Unable to show info about role {}", &self.name))?;