aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--Argcfile.sh10
-rw-r--r--scripts/build-declarations.js49
-rw-r--r--scripts/build-declarations.py9
-rwxr-xr-xscripts/build-declarations.sh37
-rwxr-xr-xscripts/create-tool.sh8
-rwxr-xr-xscripts/run-tool.js58
-rwxr-xr-xscripts/run-tool.py51
-rwxr-xr-xscripts/run-tool.sh40
-rw-r--r--tools/demo_tool.js2
-rwxr-xr-xtools/save_file.sh4
11 files changed, 159 insertions, 115 deletions
diff --git a/.gitignore b/.gitignore
index 801c799..a0ba6bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,8 @@
/tmp
-/functions.txt
-/functions.txt.test
-/functions.json
+functions.txt
+functions.json
/bin
+/cache
/tools/test.*
/.env
*.cmd
diff --git a/Argcfile.sh b/Argcfile.sh
index 382cd88..367eda0 100644
--- a/Argcfile.sh
+++ b/Argcfile.sh
@@ -148,15 +148,15 @@ test-tools() {
)
for test_case in "${test_cases[@]}"; do
- IFS='#' read -r lang func data <<<"${test_case}"
+ IFS='#' read -r lang tool_name data <<<"${test_case}"
cmd="$(_lang_to_cmd "$lang")"
- cmd_path="$BIN_DIR/$func$ext"
+ cmd_path="$BIN_DIR/$tool_name$ext"
if command -v "$cmd" &> /dev/null; then
echo -n "Test $cmd_path: "
"$cmd_path" "$data"
if ! _is_win; then
- echo -n "Test $cmd scripts/run-tool.$lang $func: "
- "$cmd" "scripts/run-tool.$lang" "$func" "$data"
+ echo -n "Test $cmd scripts/run-tool.$lang $tool_name: "
+ "$cmd" "scripts/run-tool.$lang" "$tool_name" "$data"
fi
fi
done
@@ -258,7 +258,7 @@ _choice_cmd() {
}
_die() {
- echo "$*"
+ echo "$*" >&2
exit 1
}
diff --git a/scripts/build-declarations.js b/scripts/build-declarations.js
index 35a75ee..86908fa 100644
--- a/scripts/build-declarations.js
+++ b/scripts/build-declarations.js
@@ -1,11 +1,13 @@
#!/usr/bin/env node
const fs = require("fs");
+const path = require("path");
const TOOL_ENTRY_FUNC = "run";
-function main(isTool = true) {
+function main() {
const scriptfile = process.argv[2];
+ const isTool = path.dirname(scriptfile) == "tools";
const contents = fs.readFileSync(process.argv[2], "utf8");
const functions = extractFunctions(contents, isTool);
let declarations = functions.map(({ funcName, jsdoc }) => {
@@ -56,13 +58,20 @@ function extractFunctions(contents, isTool) {
});
}
} else {
- const match = /function *([_A-Za-z]+)/.exec(line);
+ let match = /^export (async )?function ([A-Za-z0-9_]+)/.exec(line);
+ let funcName = null;
if (match) {
- const funcName = match[1];
- if (!funcName.startsWith("_")) {
- output.push({ funcName, jsdoc });
+ funcName = match[2];
+ }
+ if (!funcName) {
+ match = /^exports\.([A-Za-z0-9_]+) = (async )?function /.exec(line);
+ if (match) {
+ funcName = match[1];
}
}
+ if (funcName) {
+ output.push({ funcName, jsdoc });
+ }
}
jsdoc = "";
}
@@ -166,21 +175,6 @@ function buildProperty(type, description) {
}
/**
- * @param {string} filePath
- */
-function getBasename(filePath) {
- const filenameWithExt = filePath.split(/[/\\]/).pop();
-
- const lastDotIndex = filenameWithExt.lastIndexOf(".");
-
- if (lastDotIndex === -1) {
- return filenameWithExt;
- }
-
- return filenameWithExt.substring(0, lastDotIndex);
-}
-
-/**
* @param {string} name
* @param {string} description
* @param {Param[]} params
@@ -204,4 +198,19 @@ function buildDeclaration(name, description, params) {
return schema;
}
+/**
+ * @param {string} filePath
+ */
+function getBasename(filePath) {
+ const filenameWithExt = filePath.split(/[/\\]/).pop();
+
+ const lastDotIndex = filenameWithExt.lastIndexOf(".");
+
+ if (lastDotIndex === -1) {
+ return filenameWithExt;
+ }
+
+ return filenameWithExt.substring(0, lastDotIndex);
+}
+
main();
diff --git a/scripts/build-declarations.py b/scripts/build-declarations.py
index 2a28e43..2157c88 100644
--- a/scripts/build-declarations.py
+++ b/scripts/build-declarations.py
@@ -9,8 +9,11 @@ from collections import OrderedDict
TOOL_ENTRY_FUNC = "run"
-def main(is_tool = True):
+
+def main(is_tool=True):
scriptfile = sys.argv[1]
+ is_tool = os.path.dirname(scriptfile) == "tools"
+
with open(scriptfile, "r", encoding="utf-8") as f:
contents = f.read()
@@ -92,8 +95,8 @@ def parse_docstring(docstring: str):
break
params = {}
for rawParam in rawParams:
- name, type_, description = parse_param(rawParam)
- params[name] = (type_, description)
+ name, type_, param_description = parse_param(rawParam)
+ params[name] = (type_, param_description)
return (description.strip(), params)
diff --git a/scripts/build-declarations.sh b/scripts/build-declarations.sh
index 1f5786a..6ac2cf4 100755
--- a/scripts/build-declarations.sh
+++ b/scripts/build-declarations.sh
@@ -1,7 +1,23 @@
#!/usr/bin/env bash
-argc --argc-export "$1" | \
-jq -r '
+main() {
+ scriptfile="$1"
+ is_tool=false
+ if [[ "$(dirname "$scriptfile")" == tools ]]; then
+ is_tool=true
+ fi
+ if [[ "$is_tool" == "true" ]]; then
+ expr='[.]'
+ else
+ expr='.subcommands'
+ fi
+ argc --argc-export "$scriptfile" | \
+ jq "$expr" | \
+ build_declarations
+}
+
+build_declarations() {
+ jq -r '
def parse_description(flag_option):
if flag_option.describe == "" then
{}
@@ -36,8 +52,15 @@ jq -r '
required: [flag_options[] | select(.required == true) | .id | sub("-"; "_"; "g")],
};
- [{
- name: (.name | sub("-"; "_"; "g")),
- description: .describe,
- parameters: parse_parameter([.flag_options[] | select(.id != "help" and .id != "version")])
- }]' \ No newline at end of file
+ def parse_declaration:
+ {
+ name: (.name | sub("-"; "_"; "g")),
+ description: .describe,
+ parameters: parse_parameter([.flag_options[] | select(.id != "help" and .id != "version")])
+ };
+ [
+ .[] | parse_declaration
+ ]'
+}
+
+main "$@" \ No newline at end of file
diff --git a/scripts/create-tool.sh b/scripts/create-tool.sh
index ff0ce5e..14e0ac3 100755
--- a/scripts/create-tool.sh
+++ b/scripts/create-tool.sh
@@ -20,15 +20,15 @@ main() {
ext="${argc_name##*.}"
support_exts=('.sh' '.js' '.py')
if [[ "$ext" == "$argc_name" ]]; then
- _die "No extension name, pelease add one of ${support_exts[*]}"
+ _die "error: no extension name, pelease add one of ${support_exts[*]}"
fi
case $ext in
sh) create_sh ;;
js) create_js ;;
py) create_py ;;
- *) _die "Invalid extension name: $ext, must be one of ${support_exts[*]}" ;;
+ *) _die "error: invalid extension name: $ext, must be one of ${support_exts[*]}" ;;
esac
- _die "$output generated"
+ echo "$output generated"
}
create_sh() {
@@ -187,7 +187,7 @@ build_properties() {
}
_die() {
- echo "$*"
+ echo "$*" >&2
exit 1
}
diff --git a/scripts/run-tool.js b/scripts/run-tool.js
index d0cafa4..559b161 100755
--- a/scripts/run-tool.js
+++ b/scripts/run-tool.js
@@ -4,34 +4,34 @@ const path = require("path");
const fs = require("fs");
function parseArgv() {
- let funcName = process.argv[1];
- let funcData = null;
+ let toolName = process.argv[1];
+ let toolData = null;
- if (funcName.endsWith("run-tool.js")) {
- funcName = process.argv[2];
- funcData = process.argv[3];
+ if (toolName.endsWith("run-tool.js")) {
+ toolName = process.argv[2];
+ toolData = process.argv[3];
} else {
- funcName = path.basename(funcName);
- funcData = process.argv[2];
+ toolName = path.basename(toolName);
+ toolData = process.argv[2];
}
- if (funcName.endsWith(".js")) {
- funcName = funcName.slice(0, -3);
+ if (toolName.endsWith(".js")) {
+ toolName = toolName.slice(0, -3);
}
- return [funcName, funcData];
+ return [toolName, toolData];
}
-function loadFunc(funcName) {
- const funcFileName = `${funcName}.js`;
- const funcPath = path.resolve(
- process.env["LLM_FUNCTIONS_DIR"],
- `tools/${funcFileName}`,
+function loadModule(toolName) {
+ const toolFileName = `${toolName}.js`;
+ const toolPath = path.resolve(
+ process.env["LLM_ROOT_DIR"],
+ `tools/${toolFileName}`,
);
try {
- return require(funcPath);
+ return require(toolPath);
} catch {
- console.log(`Invalid function: ${funcFileName}`);
+ console.log(`Invalid tooltion: ${toolFileName}`);
process.exit(1);
}
}
@@ -50,26 +50,32 @@ function loadEnv(filePath) {
} catch {}
}
-process.env["LLM_FUNCTIONS_DIR"] = path.resolve(__dirname, "..");
+const LLM_ROOT_DIR = path.resolve(__dirname, "..");
+process.env["LLM_ROOT_DIR"] = LLM_ROOT_DIR;
-loadEnv(path.resolve(process.env["LLM_FUNCTIONS_DIR"], ".env"));
+loadEnv(path.resolve(LLM_ROOT_DIR, ".env"));
-const [funcName, funcData] = parseArgv();
+const [toolName, toolData] = parseArgv();
-process.env["LLM_FUNCTION_NAME"] = funcName;
+process.env["LLM_TOOL_NAME"] = toolName;
+process.env["LLM_TOOL_CACHE_DIR"] = path.resolve(
+ LLM_ROOT_DIR,
+ "cache",
+ toolName,
+);
-if (!funcData) {
+if (!toolData) {
console.log("No json data");
process.exit(1);
}
-let args;
+let data = null;
try {
- args = JSON.parse(funcData);
+ data = JSON.parse(toolData);
} catch {
console.log("Invalid json data");
process.exit(1);
}
-const { run } = loadFunc(funcName);
-run(args);
+const { run } = loadModule(toolName);
+run(data);
diff --git a/scripts/run-tool.py b/scripts/run-tool.py
index c6bcfc8..220b099 100755
--- a/scripts/run-tool.py
+++ b/scripts/run-tool.py
@@ -7,32 +7,32 @@ import importlib.util
def parse_argv():
- func_name = sys.argv[0]
- func_data = None
+ tool_name = sys.argv[0]
+ tool_data = None
- if func_name.endswith("run-tool.py"):
- func_name = sys.argv[1] if len(sys.argv) > 1 else None
- func_data = sys.argv[2] if len(sys.argv) > 2 else None
+ if tool_name.endswith("run-tool.py"):
+ tool_name = sys.argv[1] if len(sys.argv) > 1 else None
+ tool_data = sys.argv[2] if len(sys.argv) > 2 else None
else:
- func_name = os.path.basename(func_name)
- func_data = sys.argv[1] if len(sys.argv) > 1 else None
+ tool_name = os.path.basename(tool_name)
+ tool_data = sys.argv[1] if len(sys.argv) > 1 else None
- if func_name.endswith(".py"):
- func_name = func_name[:-3]
+ if tool_name.endswith(".py"):
+ tool_name = tool_name[:-3]
- return func_name, func_data
+ return tool_name, tool_data
-def load_func(func_name):
- func_file_name = f"{func_name}.py"
- func_path = os.path.join(os.environ["LLM_FUNCTIONS_DIR"], f"tools/{func_file_name}")
- if os.path.exists(func_path):
- spec = importlib.util.spec_from_file_location(f"{func_file_name}", func_path)
+def load_module(tool_name):
+ tool_file_name = f"{tool_name}.py"
+ tool_path = os.path.join(os.environ["LLM_ROOT_DIR"], f"tools/{tool_file_name}")
+ if os.path.exists(tool_path):
+ spec = importlib.util.spec_from_file_location(f"{tool_file_name}", tool_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
else:
- print(f"Invalid function: {func_file_name}")
+ print(f"Invalid function: {tool_file_name}")
sys.exit(1)
@@ -50,26 +50,27 @@ def load_env(file_path):
pass
-os.environ["LLM_FUNCTIONS_DIR"] = os.path.abspath(
+LLM_ROOT_DIR = os.environ["LLM_ROOT_DIR"] = os.path.abspath(
os.path.join(os.path.dirname(__file__), "..")
)
-load_env(os.path.join(os.environ["LLM_FUNCTIONS_DIR"], ".env"))
+load_env(os.path.join(LLM_ROOT_DIR, ".env"))
-func_name, func_data = parse_argv()
+tool_name, tool_data = parse_argv()
-os.environ["LLM_FUNCTION_NAME"] = func_name
+os.environ["LLM_TOOL_NAME"] = tool_name
+os.environ["LLM_TOOL_CACHE_DIR"] = os.path.join(LLM_ROOT_DIR, "cache", tool_name)
-if not func_data:
+if not tool_data:
print("No json data")
sys.exit(1)
-args = None
+data = None
try:
- args = json.loads(func_data)
+ data = json.loads(tool_data)
except (json.JSONDecodeError, TypeError):
print("Invalid json data")
sys.exit(1)
-module = load_func(func_name)
-module.run(**args)
+module = load_module(tool_name)
+module.run(**data)
diff --git a/scripts/run-tool.sh b/scripts/run-tool.sh
index bd32a49..32e559a 100755
--- a/scripts/run-tool.sh
+++ b/scripts/run-tool.sh
@@ -1,40 +1,42 @@
#!/usr/bin/env bash
set -e
-export LLM_FUNCTIONS_DIR="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd)"
+export LLM_ROOT_DIR="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd)"
-if [[ -f "$LLM_FUNCTIONS_DIR/.env" ]]; then
- source "$LLM_FUNCTIONS_DIR/.env"
+if [[ -f "$LLM_ROOT_DIR/.env" ]]; then
+ source "$LLM_ROOT_DIR/.env"
fi
if [[ "$0" == *run-tool.sh ]]; then
- func_name="$1"
- func_data="$2"
+ tool_name="$1"
+ tool_data="$2"
else
- func_name="$(basename "$0")"
- func_data="$1"
+ tool_name="$(basename "$0")"
+ tool_data="$1"
fi
-if [[ "$func_name" == *.sh ]]; then
- func_name="${func_name:0:$((${#func_name}-3))}"
+if [[ "$tool_name" == *.sh ]]; then
+ tool_name="${tool_name:0:$((${#tool_name}-3))}"
fi
-export LLM_FUNCTION_NAME="$func_name"
-func_file="$LLM_FUNCTIONS_DIR/tools/$func_name.sh"
+export LLM_TOOL_NAME="$tool_name"
+export LLM_TOOL_CACHE_DIR="$LLM_ROOT_DIR/cache/$tool_name"
-export JQ=jq
+tool_file="$LLM_ROOT_DIR/tools/$tool_name.sh"
+
+_jq=jq
if [[ "$OS" == "Windows_NT" ]]; then
- export JQ="jq -b"
- func_file="$(cygpath -w "$func_file")"
+ _jq="jq -b"
+ tool_file="$(cygpath -w "$tool_file")"
fi
-if [[ -z "$func_data" ]]; then
+if [[ -z "$tool_data" ]]; then
echo "No json data"
exit 1
fi
data="$(
- echo "$func_data" | \
- $JQ -r '
+ echo "$tool_data" | \
+ $_jq -r '
to_entries | .[] |
(.key | split("_") | join("-")) as $key |
if .value | type == "array" then
@@ -52,7 +54,7 @@ while IFS= read -r line; do
if [[ "$line" == '--'* ]]; then
args+=("$line")
else
- args+=("$(echo "$line" | $JQ -r '.')")
+ args+=("$(echo "$line" | $_jq -r '.')")
fi
done <<< "$data"
-"$func_file" "${args[@]}" \ No newline at end of file
+"$tool_file" "${args[@]}" \ No newline at end of file
diff --git a/tools/demo_tool.js b/tools/demo_tool.js
index d47fa59..4fd6f04 100644
--- a/tools/demo_tool.js
+++ b/tools/demo_tool.js
@@ -12,5 +12,5 @@
* @param {Args} args
*/
exports.run = function run(args) {
- console.log(args);
+ console.log(JSON.stringify(args, null, 2));
}
diff --git a/tools/save_file.sh b/tools/save_file.sh
index 8d4d43c..c51079f 100755
--- a/tools/save_file.sh
+++ b/tools/save_file.sh
@@ -6,9 +6,9 @@ set -e
# @option --contents! The contents to save.
main() {
- base_dir="$LLM_FUNCTIONS_DIR/tmp/files"
- output_file="$base_dir/$argc_file_name"
+ base_dir="${LLM_TOOL_CACHE_DIR:-/tmp}"
mkdir -p "$base_dir"
+ output_file="$base_dir/$argc_file_name"
echo "$argc_contents" > "$output_file"
echo "$output_file"
}