Skip to content

Commit

Permalink
feat: support macro (#1087)
Browse files Browse the repository at this point in the history
  • Loading branch information
sigoden authored Jan 17, 2025
1 parent 50c60e8 commit 30dae5c
Show file tree
Hide file tree
Showing 15 changed files with 709 additions and 459 deletions.
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

0 comments on commit 30dae5c

Please sign in to comment.