Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support macro #1087

Merged
merged 1 commit into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion scripts/completions/aichat.bash
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ _aichat() {

case "${cmd}" in
aichat)
opts="-m -r -s -a -e -c -f -S -h -V --model --prompt --role --session --empty-session --save-session --agent --agent-variable --rag --rebuild-rag --serve --execute --code --file --no-stream --dry-run --info --list-models --list-roles --list-sessions --list-agents --list-rags --help --version"
opts="-m -r -s -a -e -c -f -S -h -V --model --prompt --role --session --empty-session --save-session --agent --agent-variable --rag --rebuild-rag --macro --serve --execute --code --file --no-stream --dry-run --info --list-models --list-roles --list-sessions --list-agents --list-rags --list-macros --help --version"
if [[ ${cur} == -* || ${cword} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
Expand Down Expand Up @@ -53,6 +53,11 @@ _aichat() {
__ltrim_colon_completions "$cur"
return 0
;;
--macro)
COMPREPLY=($(compgen -W "$("$1" --list-macros)" -- "${cur}"))
__ltrim_colon_completions "$cur"
return 0
;;
-f|--file)
local oldifs
if [[ -v IFS ]]; then
Expand Down
2 changes: 2 additions & 0 deletions scripts/completions/aichat.fish
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ complete -c aichat -s a -l agent -x -a "(aichat --list-agents)" -d 'Start a age
complete -c aichat -l agent-variable -d 'Set agent variables'
complete -c aichat -l rag -x -a"(aichat --list-rags)" -d 'Start a RAG' -r
complete -c aichat -l rebuild-rag -d 'Rebuild the RAG to sync document changes'
complete -c aichat -l macro -x -a"(aichat --list-macros)" -d 'Execute a macro' -r
complete -c aichat -l serve -d 'Serve the LLM API and WebAPP'
complete -c aichat -s e -l execute -d 'Execute commands in natural language'
complete -c aichat -s c -l code -d 'Output code only'
Expand All @@ -20,5 +21,6 @@ complete -c aichat -l list-roles -d 'List all roles'
complete -c aichat -l list-sessions -d 'List all sessions'
complete -c aichat -l list-agents -d 'List all agents'
complete -c aichat -l list-rags -d 'List all RAGs'
complete -c aichat -l list-macros -d 'List all macros'
complete -c aichat -s h -l help -d 'Print help'
complete -c aichat -s V -l version -d 'Print version'
8 changes: 8 additions & 0 deletions scripts/completions/aichat.nu
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ module completions {
| parse "{value}"
}

def "nu-complete aichat macro" [] {
^aichat --list-macros |
| lines
| parse "{value}"
}

# All-in-one chat and copilot CLI that integrates 10+ AI platforms
export extern aichat [
--model(-m): string@"nu-complete aichat model" # Select a LLM model
Expand All @@ -46,6 +52,7 @@ module completions {
--agent-variable # Set agent variables
--rag: string@"nu-complete aichat rag" # Start a RAG
--rebuild-rag # Rebuild the RAG to sync document changes
--macro: string@"nu-complete aichat macro" # Execute a macro
--serve # Serve the LLM API and WebAPP
--execute(-e) # Execute commands in natural language
--code(-c) # Output code only
Expand All @@ -58,6 +65,7 @@ module completions {
--list-sessions # List all sessions
--list-agents # List all agents
--list-rags # List all RAGs
--list-macros # List all macros
...text: string # Input text
--help(-h) # Print help
--version(-V) # Print version
Expand Down
6 changes: 5 additions & 1 deletion scripts/completions/aichat.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Register-ArgumentCompleter -Native -CommandName 'aichat' -ScriptBlock {
[CompletionResult]::new('--agent-variable', '--agent-variable', [CompletionResultType]::ParameterName, 'Set agent variables')
[CompletionResult]::new('--rag', '--rag', [CompletionResultType]::ParameterName, 'Start a RAG')
[CompletionResult]::new('--rebuild-rag', '--rebuild-rag', [CompletionResultType]::ParameterName, 'Rebuild the RAG to sync document changes')
[CompletionResult]::new('--macro', '--macro', [CompletionResultType]::ParameterName, 'Execute a macro')
[CompletionResult]::new('--serve', '--serve', [CompletionResultType]::ParameterName, 'Serve the LLM API and WebAPP')
[CompletionResult]::new('-e', '-e', [CompletionResultType]::ParameterName, 'Execute commands in natural language')
[CompletionResult]::new('--execute', '--execute', [CompletionResultType]::ParameterName, 'Execute commands in natural language')
Expand All @@ -50,6 +51,7 @@ Register-ArgumentCompleter -Native -CommandName 'aichat' -ScriptBlock {
[CompletionResult]::new('--list-sessions', '--list-sessions', [CompletionResultType]::ParameterName, 'List all sessions')
[CompletionResult]::new('--list-agents', '--list-agents', [CompletionResultType]::ParameterName, 'List all agents')
[CompletionResult]::new('--list-rags', '--list-rags', [CompletionResultType]::ParameterName, 'List all RAGs')
[CompletionResult]::new('--list-macros', '--list-macros', [CompletionResultType]::ParameterName, 'List all macros')
[CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('-V', '-V', [CompletionResultType]::ParameterName, 'Print version')
Expand Down Expand Up @@ -77,8 +79,10 @@ Register-ArgumentCompleter -Native -CommandName 'aichat' -ScriptBlock {
$completions = Get-AichatValues "--list-sessions"
} elseif ($flag -ceq "-a" -or $flag -eq "--agent") {
$completions = Get-AichatValues "--list-agents"
} elseif ($flag -ceq "-R" -or $flag -eq "--rag") {
} elseif ($flag -eq "--rag") {
$completions = Get-AichatValues "--list-rags"
} elseif ($flag -eq "--macro") {
$completions = Get-AichatValues "--list-macros"
} elseif ($flag -ceq "-f" -or $flag -eq "--file") {
$completions = @()
}
Expand Down
4 changes: 3 additions & 1 deletion scripts/completions/aichat.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ _aichat() {
'--agent-variable[Set agent variables]' \
'--rag[Start a RAG]:RAG:->rags' \
'--rebuild-rag[Rebuild the RAG to sync document changes]' \
'--macro[Execute a macro]:MACRO:->macros' \
'--serve[Serve the LLM API and WebAPP]' \
'-e[Execute commands in natural language]' \
'--execute[Execute commands in natural language]' \
Expand All @@ -45,6 +46,7 @@ _aichat() {
'--list-sessions[List all sessions]' \
'--list-agents[List all agents]' \
'--list-rags[List all RAGs]' \
'--list-macros[List all macros]' \
'-h[Print help]' \
'--help[Print help]' \
'-V[Print version]' \
Expand All @@ -56,7 +58,7 @@ _aichat() {
_arguments "${_arguments_options[@]}" $common \
&& ret=0
case $state in
models|roles|sessions|agents|rags)
models|roles|sessions|agents|rags|macros)
local -a values expl
values=( ${(f)"$(_call_program values aichat --list-$state)"} )
_wanted values expl $state compadd -a values && ret=0
Expand Down
51 changes: 46 additions & 5 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use anyhow::{Context, Result};
use clap::Parser;
use is_terminal::IsTerminal;
use std::io::{stdin, Read};

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
Expand Down Expand Up @@ -33,6 +36,9 @@ pub struct Cli {
/// Rebuild the RAG to sync document changes
#[clap(long)]
pub rebuild_rag: bool,
/// Execute a macro
#[clap(long = "macro", value_name = "MACRO")]
pub macro_name: Option<String>,
/// Serve the LLM API and WebAPP
#[clap(long, value_name = "ADDRESS")]
pub serve: Option<Option<String>>,
Expand Down Expand Up @@ -69,17 +75,52 @@ pub struct Cli {
/// List all RAGs
#[clap(long)]
pub list_rags: bool,
/// List all macros
#[clap(long)]
pub list_macros: bool,
/// Input text
#[clap(trailing_var_arg = true)]
text: Vec<String>,
}

impl Cli {
pub fn text(&self) -> Option<String> {
let text = self.text.to_vec().join(" ");
if text.is_empty() {
return None;
pub fn text(&self) -> Result<Option<String>> {
let mut stdin_text = String::new();
if !stdin().is_terminal() {
let _ = stdin()
.read_to_string(&mut stdin_text)
.context("Invalid stdin pipe")?;
};
match self.text.is_empty() {
true => {
if stdin_text.is_empty() {
Ok(None)
} else {
Ok(Some(stdin_text))
}
}
false => {
if self.macro_name.is_some() {
let text = self
.text
.iter()
.map(|v| shell_words::quote(v))
.collect::<Vec<_>>()
.join(" ");
if stdin_text.is_empty() {
Ok(Some(text))
} else {
Ok(Some(format!("{} -- {}", text, stdin_text)))
}
} else {
let text = self.text.join(" ");
if stdin_text.is_empty() {
Ok(Some(text))
} else {
Ok(Some(format!("{}\n{}", text, stdin_text)))
}
}
}
}
Some(text)
}
}
6 changes: 3 additions & 3 deletions src/client/message.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{function::ToolResult, utils::dimmed_text};
use crate::{function::ToolResult, multiline_text, utils::dimmed_text};

use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -83,7 +83,7 @@ impl MessageContent {
agent_info: &Option<(String, Vec<String>)>,
) -> String {
match self {
MessageContent::Text(text) => text.to_string(),
MessageContent::Text(text) => multiline_text(text),
MessageContent::Array(list) => {
let (mut concated_text, mut files) = (String::new(), vec![]);
for item in list {
Expand All @@ -97,7 +97,7 @@ impl MessageContent {
}
}
if !concated_text.is_empty() {
concated_text = format!(" -- {concated_text}")
concated_text = format!(" -- {}", multiline_text(&concated_text))
}
format!(".file {}{}", files.join(" "), concated_text)
}
Expand Down
26 changes: 18 additions & 8 deletions src/client/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::{
};

use crate::config::Config;
use crate::utils::{estimate_token_length, format_option_value};
use crate::utils::estimate_token_length;

use anyhow::{bail, Result};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -133,10 +133,10 @@ impl Model {
supports_function_calling,
..
} = &self.data;
let max_input_tokens = format_option_value(max_input_tokens);
let max_output_tokens = format_option_value(max_output_tokens);
let input_price = format_option_value(input_price);
let output_price = format_option_value(output_price);
let max_input_tokens = stringify_option_value(max_input_tokens);
let max_output_tokens = stringify_option_value(max_output_tokens);
let input_price = stringify_option_value(input_price);
let output_price = stringify_option_value(output_price);
let mut capabilities = vec![];
if *supports_vision {
capabilities.push('👁');
Expand All @@ -161,9 +161,9 @@ impl Model {
max_batch_size,
..
} = &self.data;
let max_tokens = format_option_value(max_tokens_per_chunk);
let max_batch = format_option_value(max_batch_size);
let price = format_option_value(input_price);
let max_tokens = stringify_option_value(max_tokens_per_chunk);
let max_batch = stringify_option_value(max_batch_size);
let price = stringify_option_value(input_price);
format!("max-tokens:{max_tokens};max-batch:{max_batch};price:{price}")
}
ModelType::Reranker => String::new(),
Expand Down Expand Up @@ -366,3 +366,13 @@ impl ModelType {
}
}
}

fn stringify_option_value<T>(value: &Option<T>) -> String
where
T: std::fmt::Display,
{
match value {
Some(value) => value.to_string(),
None => "-".to_string(),
}
}
2 changes: 1 addition & 1 deletion src/config/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl Agent {

let rag = if rag_path.exists() {
Some(Arc::new(Rag::load(config, DEFAULT_AGENT_NAME, &rag_path)?))
} else if !definition.documents.is_empty() && !config.read().cli_info_flag {
} else if !definition.documents.is_empty() && !config.read().info_flag {
let mut ans = false;
if *IS_STDOUT_TERMINAL {
ans = Confirm::new("The agent has the documents, init RAG?")
Expand Down
6 changes: 3 additions & 3 deletions src/config/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ pub struct Input {
medias: Vec<String>,
data_urls: HashMap<String, String>,
tool_calls: Option<MessageContentToolCalls>,
rag_name: Option<String>,
role: Role,
rag_name: Option<String>,
with_session: bool,
with_agent: bool,
}
Expand All @@ -47,8 +47,8 @@ impl Input {
medias: Default::default(),
data_urls: Default::default(),
tool_calls: None,
rag_name: None,
role,
rag_name: None,
with_session,
with_agent,
}
Expand Down Expand Up @@ -128,8 +128,8 @@ impl Input {
medias,
data_urls,
tool_calls: Default::default(),
rag_name: None,
role,
rag_name: None,
with_session,
with_agent,
})
Expand Down
Loading
Loading