From 7c6841782d36faacc2aa3616dc3ed1b9403fa26e Mon Sep 17 00:00:00 2001 From: sigoden Date: Thu, 2 Nov 2023 10:45:11 +0800 Subject: refactor: improve code quanity (#197) - move model_info.rs/message.rs to clients/ - rename SharedConfig to GlobalConfig --- src/client/azure_openai.rs | 4 +-- src/client/common.rs | 26 ++++++++------- src/client/localai.rs | 4 +-- src/client/message.rs | 52 ++++++++++++++++++++++++++++++ src/client/mod.rs | 4 +++ src/client/model_info.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++++ src/client/openai.rs | 2 +- src/config/message.rs | 52 ------------------------------ src/config/mod.rs | 10 ++---- src/config/model_info.rs | 80 ---------------------------------------------- src/config/role.rs | 2 +- src/config/session.rs | 2 +- src/main.rs | 10 +++--- src/render/cmd.rs | 3 +- src/render/mod.rs | 6 ++-- src/render/repl.rs | 3 +- src/repl/abort.rs | 55 ------------------------------- src/repl/highlighter.rs | 6 ++-- src/repl/mod.rs | 12 +++---- src/repl/prompt.rs | 6 ++-- src/utils/abort_signal.rs | 55 +++++++++++++++++++++++++++++++ src/utils/mod.rs | 2 ++ 22 files changed, 238 insertions(+), 238 deletions(-) create mode 100644 src/client/message.rs create mode 100644 src/client/model_info.rs delete mode 100644 src/config/message.rs delete mode 100644 src/config/model_info.rs delete mode 100644 src/repl/abort.rs create mode 100644 src/utils/abort_signal.rs (limited to 'src') diff --git a/src/client/azure_openai.rs b/src/client/azure_openai.rs index fe3ec0f..f8a9dae 100644 --- a/src/client/azure_openai.rs +++ b/src/client/azure_openai.rs @@ -1,7 +1,7 @@ use super::openai::{openai_build_body, OPENAI_TOKENS_COUNT_FACTORS}; -use super::{AzureOpenAIClient, ExtraConfig, PromptType, SendData}; +use super::{AzureOpenAIClient, ExtraConfig, PromptType, SendData, ModelInfo}; -use crate::{config::ModelInfo, utils::PromptKind}; +use crate::utils::PromptKind; use anyhow::{anyhow, Result}; use async_trait::async_trait; diff --git a/src/client/common.rs b/src/client/common.rs index 0d0c0e2..a7844f3 100644 --- a/src/client/common.rs +++ b/src/client/common.rs @@ -1,8 +1,12 @@ +use super::{openai::OpenAIConfig, ClientConfig, Message}; + use crate::{ - config::{Message, SharedConfig}, + config::GlobalConfig, render::ReplyHandler, - repl::AbortSignal, - utils::{init_tokio_runtime, prompt_input_integer, prompt_input_string, tokenize, PromptKind}, + utils::{ + init_tokio_runtime, prompt_input_integer, prompt_input_string, tokenize, AbortSignal, + PromptKind, + }, }; use anyhow::{Context, Result}; @@ -13,8 +17,6 @@ use serde_json::{json, Value}; use std::{env, time::Duration}; use tokio::time::sleep; -use super::{openai::OpenAIConfig, ClientConfig}; - #[macro_export] macro_rules! register_client { ( @@ -42,15 +44,15 @@ macro_rules! register_client { $( #[derive(Debug)] pub struct $client { - global_config: $crate::config::SharedConfig, + global_config: $crate::config::GlobalConfig, config: $config, - model_info: $crate::config::ModelInfo, + model_info: $crate::client::ModelInfo, } impl $client { pub const NAME: &str = $name; - pub fn init(global_config: $crate::config::SharedConfig) -> Option> { + pub fn init(global_config: $crate::config::GlobalConfig) -> Option> { let model_info = global_config.read().model_info.clone(); let config = { if let ClientConfig::$config_key(c) = &global_config.read().clients[model_info.index] { @@ -73,7 +75,7 @@ macro_rules! register_client { )+ - pub fn init_client(config: $crate::config::SharedConfig) -> anyhow::Result> { + pub fn init_client(config: $crate::config::GlobalConfig) -> anyhow::Result> { None $(.or_else(|| $client::init(config.clone())))+ .ok_or_else(|| { @@ -99,7 +101,7 @@ macro_rules! register_client { anyhow::bail!("Unknown client {}", client) } - pub fn all_models(config: &$crate::config::Config) -> Vec<$crate::config::ModelInfo> { + pub fn all_models(config: &$crate::config::Config) -> Vec<$crate::client::ModelInfo> { config .clients .iter() @@ -122,7 +124,7 @@ macro_rules! openai_compatible_client { fn config( &self, ) -> ( - &$crate::config::SharedConfig, + &$crate::config::GlobalConfig, &Option<$crate::client::ExtraConfig>, ) { (&self.global_config, &self.config.extra) @@ -169,7 +171,7 @@ macro_rules! config_get_fn { #[async_trait] pub trait Client { - fn config(&self) -> (&SharedConfig, &Option); + fn config(&self) -> (&GlobalConfig, &Option); fn build_client(&self) -> Result { let mut builder = ReqwestClient::builder(); diff --git a/src/client/localai.rs b/src/client/localai.rs index 796b574..5cc12cc 100644 --- a/src/client/localai.rs +++ b/src/client/localai.rs @@ -1,7 +1,7 @@ use super::openai::{openai_build_body, OPENAI_TOKENS_COUNT_FACTORS}; -use super::{ExtraConfig, LocalAIClient, PromptType, SendData}; +use super::{ExtraConfig, LocalAIClient, PromptType, SendData, ModelInfo}; -use crate::{config::ModelInfo, utils::PromptKind}; +use crate::utils::PromptKind; use anyhow::Result; use async_trait::async_trait; diff --git a/src/client/message.rs b/src/client/message.rs new file mode 100644 index 0000000..55b2663 --- /dev/null +++ b/src/client/message.rs @@ -0,0 +1,52 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Message { + pub role: MessageRole, + pub content: String, +} + +impl Message { + pub fn new(content: &str) -> Self { + Self { + role: MessageRole::User, + content: content.to_string(), + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum MessageRole { + System, + Assistant, + User, +} + +#[allow(dead_code)] +impl MessageRole { + pub fn is_system(&self) -> bool { + matches!(self, MessageRole::System) + } + + pub fn is_user(&self) -> bool { + matches!(self, MessageRole::User) + } + + pub fn is_assistant(&self) -> bool { + matches!(self, MessageRole::Assistant) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_serde() { + assert_eq!( + serde_json::to_string(&Message::new("Hello World")).unwrap(), + "{\"role\":\"user\",\"content\":\"Hello World\"}" + ); + } +} diff --git a/src/client/mod.rs b/src/client/mod.rs index e55055d..19a0875 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -1,7 +1,11 @@ #[macro_use] mod common; +mod message; +mod model_info; pub use common::*; +pub use message::*; +pub use model_info::*; register_client!( (openai, "openai", OpenAI, OpenAIConfig, OpenAIClient), diff --git a/src/client/model_info.rs b/src/client/model_info.rs new file mode 100644 index 0000000..7a52e63 --- /dev/null +++ b/src/client/model_info.rs @@ -0,0 +1,80 @@ +use super::message::Message; + +use crate::utils::count_tokens; + +use anyhow::{bail, Result}; + +pub type TokensCountFactors = (usize, usize); // (per-messages, bias) + +#[derive(Debug, Clone)] +pub struct ModelInfo { + pub client: String, + pub name: String, + pub index: usize, + pub max_tokens: Option, + pub tokens_count_factors: TokensCountFactors, +} + +impl Default for ModelInfo { + fn default() -> Self { + ModelInfo::new(0, "", "") + } +} + +impl ModelInfo { + pub fn new(index: usize, client: &str, name: &str) -> Self { + Self { + index, + client: client.into(), + name: name.into(), + max_tokens: None, + tokens_count_factors: Default::default(), + } + } + + pub fn set_max_tokens(mut self, max_tokens: Option) -> Self { + match max_tokens { + None | Some(0) => self.max_tokens = None, + _ => self.max_tokens = max_tokens, + } + self + } + + pub fn set_tokens_count_factors(mut self, tokens_count_factors: TokensCountFactors) -> Self { + self.tokens_count_factors = tokens_count_factors; + self + } + + pub fn full_name(&self) -> String { + format!("{}:{}", self.client, self.name) + } + + pub fn messages_tokens(&self, messages: &[Message]) -> usize { + messages.iter().map(|v| count_tokens(&v.content)).sum() + } + + pub fn total_tokens(&self, messages: &[Message]) -> usize { + if messages.is_empty() { + return 0; + } + let num_messages = messages.len(); + let message_tokens = self.messages_tokens(messages); + let (per_messages, _) = self.tokens_count_factors; + if messages[num_messages - 1].role.is_user() { + num_messages * per_messages + message_tokens + } else { + (num_messages - 1) * per_messages + message_tokens + } + } + + pub fn max_tokens_limit(&self, messages: &[Message]) -> Result<()> { + let (_, bias) = self.tokens_count_factors; + let total_tokens = self.total_tokens(messages) + bias; + if let Some(max_tokens) = self.max_tokens { + if total_tokens >= max_tokens { + bail!("Exceed max tokens limit") + } + } + Ok(()) + } +} diff --git a/src/client/openai.rs b/src/client/openai.rs index 98de5a8..5589d2d 100644 --- a/src/client/openai.rs +++ b/src/client/openai.rs @@ -1,9 +1,9 @@ use super::{ ExtraConfig, OpenAIClient, PromptType, SendData, + ModelInfo, TokensCountFactors, }; use crate::{ - config::{ModelInfo, TokensCountFactors}, render::ReplyHandler, utils::PromptKind, }; diff --git a/src/config/message.rs b/src/config/message.rs deleted file mode 100644 index 55b2663..0000000 --- a/src/config/message.rs +++ /dev/null @@ -1,52 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct Message { - pub role: MessageRole, - pub content: String, -} - -impl Message { - pub fn new(content: &str) -> Self { - Self { - role: MessageRole::User, - content: content.to_string(), - } - } -} - -#[derive(Debug, Clone, Copy, Deserialize, Serialize)] -#[serde(rename_all = "snake_case")] -pub enum MessageRole { - System, - Assistant, - User, -} - -#[allow(dead_code)] -impl MessageRole { - pub fn is_system(&self) -> bool { - matches!(self, MessageRole::System) - } - - pub fn is_user(&self) -> bool { - matches!(self, MessageRole::User) - } - - pub fn is_assistant(&self) -> bool { - matches!(self, MessageRole::Assistant) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_serde() { - assert_eq!( - serde_json::to_string(&Message::new("Hello World")).unwrap(), - "{\"role\":\"user\",\"content\":\"Hello World\"}" - ); - } -} diff --git a/src/config/mod.rs b/src/config/mod.rs index 731cc10..da8e9b7 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,16 +1,12 @@ -mod message; -mod model_info; mod role; mod session; -pub use self::message::Message; -pub use self::model_info::{ModelInfo, TokensCountFactors}; use self::role::Role; use self::session::{Session, TEMP_SESSION_NAME}; use crate::client::{ - all_models, create_client_config, list_client_types, ClientConfig, ExtraConfig, OpenAIClient, - SendData, + all_models, create_client_config, list_client_types, ClientConfig, ExtraConfig, Message, + ModelInfo, OpenAIClient, SendData, }; use crate::render::{MarkdownRender, RenderOptions}; use crate::utils::{get_env_name, light_theme_from_colorfgbg, now, prompt_op_err}; @@ -118,7 +114,7 @@ impl Default for Config { } } -pub type SharedConfig = Arc>; +pub type GlobalConfig = Arc>; impl Config { pub fn init(is_interactive: bool) -> Result { diff --git a/src/config/model_info.rs b/src/config/model_info.rs deleted file mode 100644 index 7a52e63..0000000 --- a/src/config/model_info.rs +++ /dev/null @@ -1,80 +0,0 @@ -use super::message::Message; - -use crate::utils::count_tokens; - -use anyhow::{bail, Result}; - -pub type TokensCountFactors = (usize, usize); // (per-messages, bias) - -#[derive(Debug, Clone)] -pub struct ModelInfo { - pub client: String, - pub name: String, - pub index: usize, - pub max_tokens: Option, - pub tokens_count_factors: TokensCountFactors, -} - -impl Default for ModelInfo { - fn default() -> Self { - ModelInfo::new(0, "", "") - } -} - -impl ModelInfo { - pub fn new(index: usize, client: &str, name: &str) -> Self { - Self { - index, - client: client.into(), - name: name.into(), - max_tokens: None, - tokens_count_factors: Default::default(), - } - } - - pub fn set_max_tokens(mut self, max_tokens: Option) -> Self { - match max_tokens { - None | Some(0) => self.max_tokens = None, - _ => self.max_tokens = max_tokens, - } - self - } - - pub fn set_tokens_count_factors(mut self, tokens_count_factors: TokensCountFactors) -> Self { - self.tokens_count_factors = tokens_count_factors; - self - } - - pub fn full_name(&self) -> String { - format!("{}:{}", self.client, self.name) - } - - pub fn messages_tokens(&self, messages: &[Message]) -> usize { - messages.iter().map(|v| count_tokens(&v.content)).sum() - } - - pub fn total_tokens(&self, messages: &[Message]) -> usize { - if messages.is_empty() { - return 0; - } - let num_messages = messages.len(); - let message_tokens = self.messages_tokens(messages); - let (per_messages, _) = self.tokens_count_factors; - if messages[num_messages - 1].role.is_user() { - num_messages * per_messages + message_tokens - } else { - (num_messages - 1) * per_messages + message_tokens - } - } - - pub fn max_tokens_limit(&self, messages: &[Message]) -> Result<()> { - let (_, bias) = self.tokens_count_factors; - let total_tokens = self.total_tokens(messages) + bias; - if let Some(max_tokens) = self.max_tokens { - if total_tokens >= max_tokens { - bail!("Exceed max tokens limit") - } - } - Ok(()) - } -} diff --git a/src/config/role.rs b/src/config/role.rs index 819cc12..eaf805f 100644 --- a/src/config/role.rs +++ b/src/config/role.rs @@ -1,4 +1,4 @@ -use super::message::{Message, MessageRole}; +use crate::client::{Message, MessageRole}; use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; diff --git a/src/config/session.rs b/src/config/session.rs index 7ed5714..446b682 100644 --- a/src/config/session.rs +++ b/src/config/session.rs @@ -1,7 +1,7 @@ -use super::message::{Message, MessageRole}; use super::role::Role; use super::ModelInfo; +use crate::client::{Message, MessageRole}; use crate::render::MarkdownRender; use anyhow::{bail, Context, Result}; diff --git a/src/main.rs b/src/main.rs index b801e47..2bc3d63 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ mod utils; use crate::cli::Cli; use crate::client::Client; -use crate::config::{Config, SharedConfig}; +use crate::config::{Config, GlobalConfig}; use anyhow::Result; use clap::Parser; @@ -17,11 +17,11 @@ use crossbeam::sync::WaitGroup; use is_terminal::IsTerminal; use parking_lot::RwLock; use render::{render_stream, MarkdownRender}; -use repl::{create_abort_signal, Repl}; +use repl::Repl; use std::io::{stdin, Read}; use std::sync::Arc; use std::{io::stdout, process::exit}; -use utils::cl100k_base_singleton; +use utils::{cl100k_base_singleton, create_abort_signal}; fn main() -> Result<()> { let cli = Cli::parse(); @@ -93,7 +93,7 @@ fn main() -> Result<()> { fn start_directive( client: &dyn Client, - config: &SharedConfig, + config: &GlobalConfig, input: &str, no_stream: bool, ) -> Result<()> { @@ -125,7 +125,7 @@ fn start_directive( config.write().save_message(input, &output) } -fn start_interactive(config: SharedConfig) -> Result<()> { +fn start_interactive(config: GlobalConfig) -> Result<()> { cl100k_base_singleton(); let mut repl: Repl = Repl::init(config.clone())?; repl.run() diff --git a/src/render/cmd.rs b/src/render/cmd.rs index e09bd71..a9eccdc 100644 --- a/src/render/cmd.rs +++ b/src/render/cmd.rs @@ -1,7 +1,6 @@ use super::{MarkdownRender, ReplyEvent}; -use crate::repl::AbortSignal; -use crate::utils::{spaces, split_line_sematic, split_line_tail}; +use crate::utils::{spaces, split_line_sematic, split_line_tail, AbortSignal}; use anyhow::Result; use crossbeam::channel::Receiver; diff --git a/src/render/mod.rs b/src/render/mod.rs index 27f9e81..a0f996f 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -7,8 +7,8 @@ pub use self::markdown::{MarkdownRender, RenderOptions}; use self::repl::repl_render_stream; use crate::client::Client; -use crate::config::SharedConfig; -use crate::repl::AbortSignal; +use crate::config::GlobalConfig; +use crate::utils::AbortSignal; use anyhow::{Context, Result}; use crossbeam::channel::{unbounded, Sender}; @@ -19,7 +19,7 @@ use std::thread::spawn; pub fn render_stream( input: &str, client: &dyn Client, - config: &SharedConfig, + config: &GlobalConfig, repl: bool, abort: AbortSignal, wg: WaitGroup, diff --git a/src/render/repl.rs b/src/render/repl.rs index efad0e7..f554359 100644 --- a/src/render/repl.rs +++ b/src/render/repl.rs @@ -1,7 +1,6 @@ use super::{MarkdownRender, ReplyEvent}; -use crate::repl::AbortSignal; -use crate::utils::split_line_tail; +use crate::utils::{split_line_tail, AbortSignal}; use anyhow::Result; use crossbeam::channel::Receiver; diff --git a/src/repl/abort.rs b/src/repl/abort.rs deleted file mode 100644 index af58b35..0000000 --- a/src/repl/abort.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, -}; - -pub type AbortSignal = Arc; - -pub struct AbortSignalInner { - ctrlc: AtomicBool, - ctrld: AtomicBool, -} - -pub fn create_abort_signal() -> AbortSignal { - AbortSignalInner::new() -} - -impl AbortSignalInner { - pub fn new() -> AbortSignal { - Arc::new(Self { - ctrlc: AtomicBool::new(false), - ctrld: AtomicBool::new(false), - }) - } - - pub fn aborted(&self) -> bool { - if self.aborted_ctrlc() { - return true; - } - if self.aborted_ctrld() { - return true; - } - false - } - - pub fn aborted_ctrlc(&self) -> bool { - self.ctrlc.load(Ordering::SeqCst) - } - - pub fn aborted_ctrld(&self) -> bool { - self.ctrld.load(Ordering::SeqCst) - } - - pub fn reset(&self) { - self.ctrlc.store(false, Ordering::SeqCst); - self.ctrld.store(false, Ordering::SeqCst); - } - - pub fn set_ctrlc(&self) { - self.ctrlc.store(true, Ordering::SeqCst); - } - - pub fn set_ctrld(&self) { - self.ctrld.store(true, Ordering::SeqCst); - } -} diff --git a/src/repl/highlighter.rs b/src/repl/highlighter.rs index cca6297..37df659 100644 --- a/src/repl/highlighter.rs +++ b/src/repl/highlighter.rs @@ -1,15 +1,15 @@ -use crate::config::SharedConfig; +use crate::config::GlobalConfig; use nu_ansi_term::{Color, Style}; use reedline::{Highlighter, StyledText}; pub struct ReplHighlighter { external_commands: Vec, - config: SharedConfig, + config: GlobalConfig, } impl ReplHighlighter { - pub fn new(external_commands: Vec, config: SharedConfig) -> Self { + pub fn new(external_commands: Vec, config: GlobalConfig) -> Self { Self { external_commands, config, diff --git a/src/repl/mod.rs b/src/repl/mod.rs index c9c3c73..c19058b 100644 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -1,17 +1,15 @@ -mod abort; mod highlighter; mod prompt; mod validator; -pub use self::abort::{create_abort_signal, AbortSignal}; - use self::highlighter::ReplHighlighter; use self::prompt::ReplPrompt; use self::validator::ReplValidator; use crate::client::init_client; -use crate::config::SharedConfig; +use crate::config::GlobalConfig; use crate::render::{render_error, render_stream}; +use crate::utils::{create_abort_signal, AbortSignal}; use anyhow::{bail, Context, Result}; use arboard::Clipboard; @@ -52,7 +50,7 @@ lazy_static! { } pub struct Repl { - config: SharedConfig, + config: GlobalConfig, editor: Reedline, prompt: ReplPrompt, abort: AbortSignal, @@ -60,7 +58,7 @@ pub struct Repl { } impl Repl { - pub fn init(config: SharedConfig) -> Result { + pub fn init(config: GlobalConfig) -> Result { let commands: Vec = REPL_COMMANDS .into_iter() .map(|(v, _)| v.to_string()) @@ -283,7 +281,7 @@ Type ".help" for more information. ) } - fn create_completer(config: &SharedConfig, commands: &[String]) -> DefaultCompleter { + fn create_completer(config: &GlobalConfig, commands: &[String]) -> DefaultCompleter { let mut completion = commands.to_vec(); completion.extend(config.read().repl_completions()); let mut completer = diff --git a/src/repl/prompt.rs b/src/repl/prompt.rs index 7007b53..b4c9099 100644 --- a/src/repl/prompt.rs +++ b/src/repl/prompt.rs @@ -1,4 +1,4 @@ -use crate::config::SharedConfig; +use crate::config::GlobalConfig; use crossterm::style::Color; use reedline::{Prompt, PromptHistorySearch, PromptHistorySearchStatus}; @@ -11,11 +11,11 @@ const PROMPT_RIGHT_COLOR: Color = Color::AnsiValue(5); #[derive(Clone)] pub struct ReplPrompt { - config: SharedConfig, + config: GlobalConfig, } impl ReplPrompt { - pub fn new(config: SharedConfig) -> Self { + pub fn new(config: GlobalConfig) -> Self { Self { config } } } diff --git a/src/utils/abort_signal.rs b/src/utils/abort_signal.rs new file mode 100644 index 0000000..af58b35 --- /dev/null +++ b/src/utils/abort_signal.rs @@ -0,0 +1,55 @@ +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; + +pub type AbortSignal = Arc; + +pub struct AbortSignalInner { + ctrlc: AtomicBool, + ctrld: AtomicBool, +} + +pub fn create_abort_signal() -> AbortSignal { + AbortSignalInner::new() +} + +impl AbortSignalInner { + pub fn new() -> AbortSignal { + Arc::new(Self { + ctrlc: AtomicBool::new(false), + ctrld: AtomicBool::new(false), + }) + } + + pub fn aborted(&self) -> bool { + if self.aborted_ctrlc() { + return true; + } + if self.aborted_ctrld() { + return true; + } + false + } + + pub fn aborted_ctrlc(&self) -> bool { + self.ctrlc.load(Ordering::SeqCst) + } + + pub fn aborted_ctrld(&self) -> bool { + self.ctrld.load(Ordering::SeqCst) + } + + pub fn reset(&self) { + self.ctrlc.store(false, Ordering::SeqCst); + self.ctrld.store(false, Ordering::SeqCst); + } + + pub fn set_ctrlc(&self) { + self.ctrlc.store(true, Ordering::SeqCst); + } + + pub fn set_ctrld(&self) { + self.ctrld.store(true, Ordering::SeqCst); + } +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 938e07c..1deec3e 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,7 +1,9 @@ +mod abort_signal; mod prompt_input; mod split_line; mod tiktoken; +pub use self::abort_signal::{create_abort_signal, AbortSignal}; pub use self::prompt_input::*; pub use self::split_line::*; pub use self::tiktoken::cl100k_base_singleton; -- cgit v1.2.3