From 4a5ee3ecb793362228a88f8c1609bd830eb88cc1 Mon Sep 17 00:00:00 2001 From: sigoden Date: Wed, 10 Apr 2024 20:36:12 +0800 Subject: [PATCH] feat: `-f/--file` take one value and no enter REPL (#399) --- README.md | 12 ++++++------ src/cli.rs | 6 +++--- src/main.rs | 39 +++++++++++++++++++++++++-------------- src/repl/mod.rs | 2 +- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 8bcfbca..e847d8c 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,14 @@ Chat REPL mode: - Support most of the LLM platforms - OpenAI: GPT3.5/GPT4 (paid, vision) - - Gemini (free, vision) - - Claude: (paid) + - Gemini: Gemini-1.0/Gemini-1.5 (free, vision) + - Claude: Claude3 (paid) - Mistral (paid) - Cohere (paid) - - OpenAI-Compatible (local) + - OpenAI-Compatible - Ollama (free, local) - Azure-OpenAI (paid) - - VertexAI: Gemini-1/Gemini-1.5 (paid, vision) + - VertexAI (paid, vision) - Ernie (paid) - Qianwen (paid, vision) - Moonshot (paid) @@ -122,7 +122,7 @@ Options: -s, --session [] Create or reuse a session -e, --execute Execute commands using natural language -c, --code Generate only code - -f, --file ... Attach files to the message to be sent + -f, --file Attach files to the message -H, --no-highlight Disable syntax highlighting -S, --no-stream No stream output -w, --wrap Specify the text-wrapping mode (no, auto, ) @@ -153,7 +153,7 @@ aichat -s session1 --info # Session info cat data.toml | aichat -c to json > data.json # Pipe IO -aichat --file a.png b.png -- diff images # Attach files +aichat --file a.png --file b.png diff images # Attach files ``` ### Shell commands diff --git a/src/cli.rs b/src/cli.rs index 0bab3e0..20192c8 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -21,9 +21,9 @@ pub struct Cli { /// Generate only code #[clap(short = 'c', long)] pub code: bool, - /// Attach files to the message to be sent - #[clap(short = 'f', long, num_args = 1.., value_name = "FILE")] - pub file: Option>, + /// Attach files to the message + #[clap(short = 'f', long, value_name = "FILE")] + pub file: Vec, /// Disable syntax highlighting #[clap(short = 'H', long)] pub no_highlight: bool, diff --git a/src/main.rs b/src/main.rs index 203cc61..d203710 100644 --- a/src/main.rs +++ b/src/main.rs @@ -87,18 +87,19 @@ fn main() -> Result<()> { return Ok(()); } let text = aggregate_text(text)?; + let input = create_input(&config, text, &cli.file)?; if cli.execute { - match text { - Some(text) => { - execute(&config, &text)?; + match input { + Some(input) => { + execute(&config, input)?; return Ok(()); } None => bail!("No input text"), } } config.write().prelude()?; - if let Err(err) = match text { - Some(text) => start_directive(&config, &text, cli.file, cli.no_stream, cli.code), + if let Err(err) = match input { + Some(input) => start_directive(&config, input, cli.no_stream, cli.code), None => start_interactive(&config), } { let highlight = stderr().is_terminal() && config.read().highlight; @@ -109,16 +110,10 @@ fn main() -> Result<()> { fn start_directive( config: &GlobalConfig, - text: &str, - include: Option>, + input: Input, no_stream: bool, code_mode: bool, ) -> Result<()> { - let input = Input::new( - text, - include.unwrap_or_default(), - config.read().input_context(), - )?; let mut client = init_client(config)?; ensure_model_capabilities(client.as_mut(), input.required_capabilities())?; config.read().maybe_print_send_tokens(&input); @@ -153,8 +148,7 @@ fn start_interactive(config: &GlobalConfig) -> Result<()> { repl.run() } -fn execute(config: &GlobalConfig, text: &str) -> Result<()> { - let input = Input::from_str(text, config.read().input_context()); +fn execute(config: &GlobalConfig, input: Input) -> Result<()> { let client = init_client(config)?; config.read().maybe_print_send_tokens(&input); let mut eval_str = client.send_message(input.clone())?; @@ -228,3 +222,20 @@ fn aggregate_text(text: Option) -> Result> { }; Ok(text) } + +fn create_input( + config: &GlobalConfig, + text: Option, + file: &[String], +) -> Result> { + if text.is_none() && file.is_empty() { + return Ok(None); + } + let input_context = config.read().input_context(); + let input = if file.is_empty() { + Input::from_str(&text.unwrap_or_default(), input_context) + } else { + Input::new(&text.unwrap_or_default(), file.to_vec(), input_context)? + }; + Ok(Some(input)) +} diff --git a/src/repl/mod.rs b/src/repl/mod.rs index 339abe4..30be73b 100644 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -234,7 +234,7 @@ impl Repl { let input = Input::new(text, files, self.config.read().input_context())?; self.ask(input)?; } - None => println!("Usage: .file ...[ -- ...]"), + None => println!("Usage: .file ... [-- ...]"), }, ".exit" => match args { Some("role") => {