diff options
| author | sigoden <sigoden@gmail.com> | 2024-06-08 20:46:27 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-08 20:46:27 +0800 |
| commit | 213e949fc8c2362046d197554fda98c87a7906df (patch) | |
| tree | 595a883c6b1fd1154a916569c3d0255634c6e193 /Argcfile.sh | |
| parent | 82d7a7de8a76e56cff306b0da7f4f14fdb57cbf1 (diff) | |
| download | llm-functions-docker-213e949fc8c2362046d197554fda98c87a7906df.tar.gz | |
feat: support bots (#39)
Diffstat (limited to 'Argcfile.sh')
| -rw-r--r-- | Argcfile.sh | 237 |
1 files changed, 231 insertions, 6 deletions
diff --git a/Argcfile.sh b/Argcfile.sh index 1283a55..b0f3c95 100644 --- a/Argcfile.sh +++ b/Argcfile.sh @@ -21,7 +21,7 @@ run-tool() { ext=".cmd" fi if [[ -z "$argc_json" ]]; then - declaration="$(jq --arg name "$argc_cmd" '.[] | select(.name == $name)' functions.json)" + declaration="$(cat functions.json | jq --arg name "$argc_cmd" '.[] | select(.name == $name)')" if [[ -n "$declaration" ]]; then _ask_json_data "$declaration" fi @@ -32,9 +32,33 @@ run-tool() { "$BIN_DIR/$argc_cmd$ext" "$argc_json" } +# @cmd Run the tool +# @arg cmd![`_choice_bot`] The bot command +# @arg action![`_choice_bot_action`] The bot action +# @arg json The json data +run-bot() { + if _is_win; then + ext=".cmd" + fi + if [[ -z "$argc_json" ]]; then + functions_path="bots/$argc_cmd/functions.json" + if [[ -f "$functions_path" ]]; then + declaration="$(jq --arg name "$argc_action" '.[] | select(.name == $name)' "$functions_path")" + if [[ -n "$declaration" ]]; then + _ask_json_data "$declaration" + fi + fi + fi + if [[ -z "$argc_json" ]]; then + _die "error: no JSON data" + fi + "$BIN_DIR/$argc_cmd$ext" "$argc_action" "$argc_json" +} + # @cmd Build the project build() { argc build-tools + argc build-bots } # @cmd Build tools @@ -81,7 +105,7 @@ build-tools-bin() { if [[ -f "$tool_path" ]]; then if _is_win; then bin_file="$BIN_DIR/$basename.cmd" - _build_win_shim_tool $lang > "$bin_file" + _build_win_shim tool $lang > "$bin_file" else bin_file="$BIN_DIR/$basename" ln -s -f "$PWD/scripts/run-tool.$lang" "$bin_file" @@ -143,16 +167,147 @@ build-tool-declaration() { "$cmd" "scripts/build-declarations.$lang" "tools/$1" | jq '.[0]' } -# @cmd List tools that can be put into tools.txt +# @cmd Build bots +# @option --names-file=bots.txt Path to a file containing bot filenames, one per line. +# Example: +# hackernews +# spotify +# @arg bots*[`_choice_bot`] The bot filenames +build-bots() { + if [[ "${#argc_bots[@]}" -gt 0 ]]; then + mkdir -p "$TMP_DIR" + argc_names_file="$TMP_DIR/bots.txt" + printf "%s\n" "${argc_bots[@]}" > "$argc_names_file" + else + argc clean-bots + fi + argc build-bots-json --names-file "${argc_names_file}" + argc build-bots-bin --names-file "${argc_names_file}" +} + +# @cmd Build tools to bin +# @option --names-file=bots.txt Path to a file containing bot filenames, one per line. +# @arg bots*[`_choice_bot`] The bot names +build-bots-bin() { + mkdir -p "$BIN_DIR" + if [[ "${#argc_bots[@]}" -gt 0 ]]; then + names=("${argc_bots[@]}" ) + elif [[ -f "$argc_names_file" ]]; then + names=($(cat "$argc_names_file")) + if [[ "${#names[@]}" -gt 0 ]]; then + (cd "$BIN_DIR" && rm -rf "${names[@]}") + fi + fi + if [[ -z "$names" ]]; then + _die "error: not input bots, not found '$argc_names_file', please create it add some tools." + fi + not_found_bots=() + for name in "${names[@]}"; do + bot_dir="bots/$name" + found=false + for item in "${LANG_CMDS[@]}"; do + lang="${item%:*}" + bot_tools_file="$bot_dir/tools.$lang" + if [[ -f "$bot_tools_file" ]]; then + found=true + if _is_win; then + bin_file="$BIN_DIR/$name.cmd" + _build_win_shim bot $lang > "$bin_file" + else + bin_file="$BIN_DIR/$name" + ln -s -f "$PWD/scripts/run-bot.$lang" "$bin_file" + fi + echo "Build bot $name" + fi + done + if [[ "$found" = "false" ]]; then + not_found_bots+=("$name") + fi + done + if [[ -n "$not_found_bots" ]]; then + _die "error: not found bots: ${not_found_bots[*]}" + fi +} + +# @cmd Build bots functions.json +# @option --names-file=bots.txt Path to a file containing bot filenames, one per line. +# @arg tools*[`_choice_tool`] The tool filenames +build-bots-json() { + if [[ "${#argc_bots[@]}" -gt 0 ]]; then + names=("${argc_bots[@]}" ) + elif [[ -f "$argc_names_file" ]]; then + names=($(cat "$argc_names_file")) + fi + if [[ -z "$names" ]]; then + _die "error: not input bots, not found '$argc_names_file', please create it add some tools." + fi + not_found_bots=() + build_failed_bots=() + for name in "${names[@]}"; do + bot_dir="bots/$name" + build_ok=false + found=false + for item in "${LANG_CMDS[@]}"; do + lang="${item%:*}" + bot_tools_file="$bot_dir/tools.$lang" + if [[ -f "$bot_tools_file" ]]; then + found=true + json_data="$(build-bot-declarations "$name")" || { + build_failed_bots+=("$name") + } + declarations_file="$bot_dir/functions.json" + echo "Build $declarations_file" + echo "$json_data" > "$declarations_file" + fi + done + if [[ "$found" == "false" ]]; then + not_found_bots+=("$name") + fi + done + if [[ -n "$not_found_bots" ]]; then + _die "error: not found bots: ${not_found_bots[*]}" + fi + if [[ -n "$build_failed_bots" ]]; then + _die "error: invalid bots: ${build_failed_bots[*]}" + fi +} + +# @cmd Build function declarations for an bot +# @flag --oneline Summary JSON in one line +# @arg bot![`_choice_bot`] The bot name +build-bot-declarations() { + tools_path="$(_get_bot_tools_path "$1")" + if [[ -z "$tools_path" ]]; then + _die "error: no found entry file at bots/$1/tools.<lang>" + fi + lang="${tools_path##*.}" + cmd="$(_lang_to_cmd "$lang")" + json="$("$cmd" "scripts/build-declarations.$lang" "$tools_path")" + if [[ -n "$argc_oneline" ]]; then + echo "$json" | jq -r '.[] | .name + ": " + (.description | split("\n"))[0]' + else + echo "$json" + fi +} + +# @cmd List tools that can be put into functions.txt # Examples: # argc list-tools > tools.txt list-tools() { _choice_tool } +# @cmd List bots that can be put into bots.txt +# Examples: +# argc list-bots > bots.txt +list-bots() { + _choice_bot +} + # @cmd Test the project test() { test-tools + test-bots } # @cmd Test tools @@ -218,10 +373,55 @@ test-tools-demo() { done } +# @cmd Test bots +test-bots() { + tmp_dir="cache/tmp" + mkdir -p "$tmp_dir" + names_file="$tmp_dir/bots.txt" + argc list-bots > "$names_file" + argc build-bots --names-file "$names_file" + test-bots-todo-lang +} + +# @cmd Test todo-* bots +test-bots-todo-lang() { + if _is_win; then + ext=".cmd" + fi + test_cases=( \ + 'add_todo#{"desc":"Add a todo item"}' \ + 'add_todo#{"desc":"Add another todo item"}' \ + 'del_todo#{"id":1}' \ + 'list_todos#{}' \ + 'clear_todos#{}' \ + ) + for item in "${LANG_CMDS[@]}"; do + cmd="${item#*:}" + if command -v "$cmd" &> /dev/null; then + lang="${item%:*}" + bot_name="todo-$lang" + rm -rf "cache/$bot_name/todos.json" + for test_case in "${test_cases[@]}"; do + IFS='#' read -r action data <<<"${test_case}" + cmd_path="$BIN_DIR/$bot_name$ext" + echo "Test $cmd_path: " + "$cmd_path" "$action" "$data" + done + fi + done + +} # @cmd Clean tools clean-tools() { _choice_tool | sed 's/\.\([a-z]\+\)$//' | xargs -I{} rm -rf "$BIN_DIR/{}" + rm -rf functions.json +} + +# @cmd Clean bots +clean-bots() { + _choice_bot | xargs -I{} rm -rf "$BIN_DIR/{}" + _choice_bot | xargs -I{} rm -rf bots/{}/functions.json } # @cmd Install this repo to aichat functions_dir @@ -269,8 +469,20 @@ _lang_to_cmd() { done } -_build_win_shim_tool() { - lang="$1" +_get_bot_tools_path() { + name="$1" + for item in "${LANG_CMDS[@]}"; do + lang="${item%:*}" + entry_file="bots/$name/tools.$lang" + if [[ -f "bots/$name/tools.$lang" ]]; then + echo "$entry_file" + fi + done +} + +_build_win_shim() { + kind="$1" + lang="$2" cmd="$(_lang_to_cmd "$lang")" if [[ "$lang" == "sh" ]]; then run="\"$(argc --argc-shell-path)\" --noprofile --norc" @@ -285,7 +497,7 @@ set "bin_dir=%~dp0" for %%i in ("%bin_dir:~0,-1%") do set "script_dir=%%~dpi" set "script_name=%~n0" -$run "%script_dir%scripts\run-tool.$lang" "%script_name%.$lang" %* +$run "%script_dir%scripts\run-$kind.$lang" "%script_name%" %* EOF } @@ -338,6 +550,19 @@ _choice_tool() { done } +_choice_bot() { + ls -1 bots +} + +_choice_bot_action() { + if [[ "$ARGC_COMPGEN" -eq 1 ]]; then + expr="s/: /\t/" + else + expr="s/:.*//" + fi + argc build-bot-declarations "$1" --oneline | sed "$expr" +} + _choice_cmd() { ls -1 "$BIN_DIR" | sed -e 's/\.cmd$//' } |
