summaryrefslogtreecommitdiffstats
path: root/src/config/role.rs
diff options
context:
space:
mode:
authorsigoden <sigoden@gmail.com>2024-04-14 14:43:42 +0800
committerGitHub <noreply@github.com>2024-04-14 14:43:42 +0800
commit6dc332930bf2e6d31c937d87e7ac7ae14c53b7c6 (patch)
treef944fc7a70e683930799dd77ca259ea6a610f813 /src/config/role.rs
parent1c3e81afe9f63fb47303384a82c7239458166f52 (diff)
downloadaichat-6dc332930bf2e6d31c937d87e7ac7ae14c53b7c6.tar.gz
feat: make built-in roles selectable and rename them (#412)
Diffstat (limited to 'src/config/role.rs')
-rw-r--r--src/config/role.rs44
1 files changed, 23 insertions, 21 deletions
diff --git a/src/config/role.rs b/src/config/role.rs
index 9042da3..5a6ff3a 100644
--- a/src/config/role.rs
+++ b/src/config/role.rs
@@ -1,3 +1,4 @@
+use super::Input;
use crate::{
client::{Message, MessageContent, MessageRole},
utils::{detect_os, detect_shell},
@@ -6,9 +7,11 @@ use crate::{
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
-use super::Input;
+pub const SHELL_ROLE: &str = "%shell%";
+pub const EXPLAIN_ROLE: &str = "%explain%";
+pub const CODE_ROLE: &str = "%code%";
-const INPUT_PLACEHOLDER: &str = "__INPUT__";
+pub const INPUT_PLACEHOLDER: &str = "__INPUT__";
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Role {
@@ -21,19 +24,25 @@ pub struct Role {
}
impl Role {
- pub const EXECUTE: &'static str = "__execute__";
- pub const DESCRIBE_COMMAND: &'static str = "__describe_command__";
- pub const CODE: &'static str = "__code__";
+ pub fn find_system_role(name: &str) -> Option<Self> {
+ match name {
+ SHELL_ROLE => Some(Self::shell()),
+ EXPLAIN_ROLE => Some(Self::explain()),
+ CODE_ROLE => Some(Self::code()),
+ _ => None,
+ }
+ }
- pub fn for_execute() -> Self {
+ pub fn shell() -> Self {
let os = detect_os();
- let (shell, _, _) = detect_shell();
- let (shell, use_semicolon) = match (shell.as_str(), os.as_str()) {
+ let (detected_shell, _, _) = detect_shell();
+ let (shell, use_semicolon) = match (detected_shell.as_str(), os.as_str()) {
+ // GPT doesn’t know much about nushell
("nushell", "windows") => ("cmd", true),
("nushell", _) => ("bash", true),
("powershell", _) => ("powershell", true),
("pwsh", _) => ("powershell", false),
- _ => (shell.as_str(), false),
+ _ => (detected_shell.as_str(), false),
};
let combine = if use_semicolon {
"\nIf multiple steps required try to combine them together using ';'.\nIf it already combined with '&&' try to replace it with ';'.".to_string()
@@ -41,7 +50,7 @@ impl Role {
"\nIf multiple steps required try to combine them together using &&.".to_string()
};
Self {
- name: Self::EXECUTE.into(),
+ name: SHELL_ROLE.into(),
prompt: format!(
r#"Provide only {shell} commands for {os} without any description.
Ensure the output is a valid {shell} command. {combine}
@@ -52,9 +61,9 @@ Output plain text only, without any markdown formatting."#
}
}
- pub fn for_describe_command() -> Self {
+ pub fn explain() -> Self {
Self {
- name: Self::DESCRIBE_COMMAND.into(),
+ name: EXPLAIN_ROLE.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.
@@ -64,9 +73,9 @@ APPLY MARKDOWN formatting when possible."#
}
}
- pub fn for_code() -> Self {
+ pub fn code() -> Self {
Self {
- name: Self::CODE.into(),
+ name: CODE_ROLE.into(),
prompt: r#"Provide only code, without comments or explanations.
If there is a lack of details, provide most logical solution, without requesting further clarification."#
.into(),
@@ -74,13 +83,6 @@ If there is a lack of details, provide most logical solution, without requesting
}
}
- pub fn is_system(&self) -> bool {
- matches!(
- self.name.as_str(),
- Self::EXECUTE | Self::DESCRIBE_COMMAND | Self::CODE
- )
- }
-
pub fn export(&self) -> Result<String> {
let output = serde_yaml::to_string(&self)
.with_context(|| format!("Unable to show info about role {}", &self.name))?;