summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsigoden <sigoden@gmail.com>2024-04-10 20:36:12 +0800
committerGitHub <noreply@github.com>2024-04-10 20:36:12 +0800
commit4a5ee3ecb793362228a88f8c1609bd830eb88cc1 (patch)
tree82ee7de941ed58ad771f1f141019e124c6b51827
parenta0bd6e1d5d68c718a0533037364e3df9ad13da96 (diff)
downloadaichat-4a5ee3ecb793362228a88f8c1609bd830eb88cc1.tar.gz
feat: `-f/--file` take one value and no enter REPL (#399)
-rw-r--r--README.md12
-rw-r--r--src/cli.rs6
-rw-r--r--src/main.rs39
-rw-r--r--src/repl/mod.rs2
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 [<SESSION>] Create or reuse a session
-e, --execute Execute commands using natural language
-c, --code Generate only code
- -f, --file <FILE>... Attach files to the message to be sent
+ -f, --file <FILE> Attach files to the message
-H, --no-highlight Disable syntax highlighting
-S, --no-stream No stream output
-w, --wrap <WRAP> Specify the text-wrapping mode (no, auto, <max-width>)
@@ -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<Vec<String>>,
+ /// Attach files to the message
+ #[clap(short = 'f', long, value_name = "FILE")]
+ pub file: Vec<String>,
/// 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<Vec<String>>,
+ 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<String>) -> Result<Option<String>> {
};
Ok(text)
}
+
+fn create_input(
+ config: &GlobalConfig,
+ text: Option<String>,
+ file: &[String],
+) -> Result<Option<Input>> {
+ 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 <files>...[ -- <text>...]"),
+ None => println!("Usage: .file <files>... [-- <text>...]"),
},
".exit" => match args {
Some("role") => {