mirror of
https://github.com/sigoden/aichat
synced 2024-11-04 18:00:20 +00:00
feat: -f/--file
take one value and no enter REPL (#399)
This commit is contained in:
parent
a0bd6e1d5d
commit
4a5ee3ecb7
12
README.md
12
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
|
||||
|
@ -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,
|
||||
|
39
src/main.rs
39
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))
|
||||
}
|
||||
|
@ -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") => {
|
||||
|
Loading…
Reference in New Issue
Block a user