aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsigoden <sigoden@gmail.com>2025-02-12 07:33:41 +0800
committerGitHub <noreply@github.com>2025-02-12 07:33:41 +0800
commit4ac72b584526765f980baca4454b613e0f56c1fb (patch)
treee816ca0baf9e27be41c05626d978a1cc9ed39f68
parent50ee642b3e109839b52c787a8a999a2e56d36483 (diff)
downloadllm-functions-docker-4ac72b584526765f980baca4454b613e0f56c1fb.tar.gz
feat: support check-related features (#162)
We can run `argc check` to ensure that everything is ready (environment variables, Node/Python dependencies, mcp-bridge server)
-rw-r--r--Argcfile.sh92
-rw-r--r--README.md6
-rw-r--r--docs/argcfile.md16
-rwxr-xr-xscripts/check-deps.sh68
-rwxr-xr-xscripts/mcp.sh12
5 files changed, 189 insertions, 5 deletions
diff --git a/Argcfile.sh b/Argcfile.sh
index 37ec6f5..0a1ad85 100644
--- a/Argcfile.sh
+++ b/Argcfile.sh
@@ -1,6 +1,8 @@
#!/usr/bin/env bash
set -e
+# @meta dotenv
+
BIN_DIR=bin
TMP_DIR="cache/__tmp__"
VENV_DIR=".venv"
@@ -231,8 +233,8 @@ build-bin@agent() {
found=false
for item in "${LANG_CMDS[@]}"; do
lang="${item%:*}"
- agent_tools_file="$agent_dir/tools.$lang"
- if [[ -f "$agent_tools_file" ]]; then
+ agent_tools_path="$agent_dir/tools.$lang"
+ if [[ -f "$agent_tools_path" ]]; then
found=true
if _is_win; then
bin_file="$BIN_DIR/$name.cmd"
@@ -293,8 +295,8 @@ build-declarations@agent() {
tools_json_data=""
for item in "${LANG_CMDS[@]}"; do
lang="${item%:*}"
- agent_tools_file="$agent_dir/tools.$lang"
- if [[ -f "$agent_tools_file" ]]; then
+ agent_tools_path="$agent_dir/tools.$lang"
+ if [[ -f "$agent_tools_path" ]]; then
agent_json_data="$(generate-declarations@agent "$name")" || {
ok=false
build_failed_agents+=("$name")
@@ -359,6 +361,64 @@ generate-declarations@agent() {
fi
}
+# @cmd Check environment variables, Node/Python dependencies, MCP-Bridge-Server status
+check() {
+ argc check@tool
+ argc check@agent
+ argc mcp check
+}
+
+# @cmd Check dependencies and environment variables for a specific tool
+# @alias tool:check
+# @arg tools*[`_choice_tool`] The tool name
+check@tool() {
+ if [[ "${#argc_tools[@]}" -gt 0 ]]; then
+ tool_names=("${argc_tools[@]}")
+ else
+ tool_names=($(cat tools.txt | grep -v '^#'))
+ fi
+ for name in "${tool_names[@]}"; do
+ tool_path="tools/$name"
+ echo "Check $tool_path"
+ if [[ -f "$tool_path" ]]; then
+ _check_bin "${name%.*}"
+ _check_envs "$tool_path"
+ ./scripts/check-deps.sh "$tool_path"
+ else
+ echo "✗ not found tool file"
+ fi
+ done
+}
+
+# @cmd Check dependencies and environment variables for a specific agent
+# @alias agent:check
+# @arg agents*[`_choice_agent`] The agent name
+check@agent() {
+ if [[ "${#argc_agents[@]}" -gt 0 ]]; then
+ agent_names=("${argc_agents[@]}")
+ else
+ agent_names=($(cat agents.txt | grep -v '^#'))
+ fi
+ for name in "${agent_names[@]}"; do
+ agent_dir="agents/$name"
+ echo "Check $agent_dir"
+ if [[ -d "$agent_dir" ]]; then
+ for item in "${LANG_CMDS[@]}"; do
+ lang="${item%:*}"
+ agent_tools_path="$agent_dir/tools.$lang"
+ if [[ -f "$agent_tools_path" ]]; then
+ _check_bin "$name"
+ _check_envs "$agent_tools_path"
+ ./scripts/check-deps.sh "$agent_tools_path"
+ break
+ fi
+ done
+ else
+ echo "✗ not found agent dir"
+ fi
+ done
+}
+
# @cmd List tools which can be put into functions.txt
# @alias tool:list
# Examples:
@@ -602,6 +662,30 @@ python "__ROOT_DIR__/scripts/run-__KIND__.py" "$(basename "$0")" "$@"
EOF
}
+_check_bin() {
+ bin_name="$1"
+ if _is_win; then
+ bin_name+=".cmd"
+ fi
+ if [[ ! -f "$BIN_DIR/$bin_name" ]]; then
+ echo "✗ missing bin/$bin_name"
+ fi
+}
+
+_check_envs() {
+ script_path="$1"
+ envs=( $(sed -E -n 's/.* @env ([A-Z0-9_]+)!.*/\1/p' $script_path) )
+ missing_envs=()
+ for env in $envs; do
+ if [[ -z "${!env}" ]]; then
+ missing_envs+=("$env")
+ fi
+ done
+ if [[ -n "$missing_envs" ]]; then
+ echo "✗ missing envs ${missing_envs[*]}"
+ fi
+}
+
_link_tool() {
from="$1"
to="$2.${1##*.}"
diff --git a/README.md b/README.md
index 88c36a6..d885258 100644
--- a/README.md
+++ b/README.md
@@ -76,6 +76,12 @@ todo
argc build
```
+#### IV. Ensure that everything is ready (environment variables, Node/Python dependencies, mcp-bridge server)
+
+```sh
+argc check
+```
+
### 3. Install to AIChat
Symlink this repo directory to AIChat's **functions_dir**:
diff --git a/docs/argcfile.md b/docs/argcfile.md
index 9366a76..c420977 100644
--- a/docs/argcfile.md
+++ b/docs/argcfile.md
@@ -16,7 +16,7 @@ argc -h # Print help information
argc <command> -h # Print help information for <command>
# -------- Build --------
-# Build
+# Build all
argc build
# Build all tools
@@ -29,6 +29,20 @@ argc build@agent
# Build specific agents
argc build@agent coder todo
+# -------- Check --------
+# Check all
+argc check
+
+# Check all tools
+argc check@tool
+# Check specific tools
+argc check@tool get_current_weather.sh execute_command.sh
+
+# Check all agents
+argc check@agent
+# Check specific agents
+argc check@agent coder todo
+
# -------- Run --------
# Run tool
argc run@tool get_current_weather.sh '{"location":"London"}'
diff --git a/scripts/check-deps.sh b/scripts/check-deps.sh
new file mode 100755
index 0000000..8d44988
--- /dev/null
+++ b/scripts/check-deps.sh
@@ -0,0 +1,68 @@
+#!/usr/bin/env bash
+set -e
+
+# @describe Check dependencies
+#
+# Examples:
+# ./scripts/check-deps.sh tools/execute_sql_code.sh
+# ./scripts/check-deps.sh agents/json-viewer/tools.js
+#
+# @arg script-path! The script file path
+
+main() {
+ script_path="$argc_script_path"
+ if [[ ! -f "$script_path" ]]; then
+ _exit "✗ not found $script_path"
+ fi
+ ext="${script_path##*.}"
+ if [[ "$script_path" == tools/* ]]; then
+ if [[ "$ext" == "sh" ]]; then
+ check_sh_dependencies
+ fi
+ elif [[ "$script_path" == agents/* ]]; then
+ if [[ "$ext" == "sh" ]]; then
+ check_sh_dependencies
+ elif [[ "$ext" == "js" ]]; then
+ check_agent_js_dependencies
+ elif [[ "$ext" == "py" ]]; then
+ check_agent_py_dependencies
+ fi
+ fi
+}
+
+check_sh_dependencies() {
+ deps=( $(sed -E -n 's/.*@meta require-tools //p' "$script_path") )
+ missing_deps=()
+ for dep in "${deps[@]}"; do
+ if ! command -v "$dep" &> /dev/null; then
+ missing_deps+=("$dep")
+ fi
+ done
+ if [[ -n "${missing_deps}" ]]; then
+ _exit "✗ missing tools: ${missing_deps[*]}"
+ fi
+}
+
+check_agent_js_dependencies() {
+ agent_dir="$(dirname "$script_path")"
+ if [[ -f "$agent_dir/package.json" ]]; then
+ npm ls --prefix="$agent_dir" --depth=0 --silent >/dev/null 2>&1 || \
+ _exit "✗ missing node modules, FIX: cd $agent_dir && npm install"
+ fi
+}
+
+check_agent_py_dependencies() {
+ agent_dir="$(dirname "$script_path")"
+ if [[ -f "$agent_dir/requirements.txt" ]]; then
+ python <(cat "$agent_dir/requirements.txt" | sed -E -n 's/^([A-Za-z_]+).*/import \1/p') >/dev/null 2>&1 || \
+ _exit "✗ missing python modules, FIX: cd $agent_dir && pip install -r requirements.txt"
+ fi
+}
+
+_exit() {
+ echo "$*" >&2
+ exit 0
+}
+
+# See more details at https://github.com/sigoden/argc
+eval "$(argc --argc-eval "$0" "$@")"
diff --git a/scripts/mcp.sh b/scripts/mcp.sh
index 87b5183..6e55ca8 100755
--- a/scripts/mcp.sh
+++ b/scripts/mcp.sh
@@ -46,6 +46,18 @@ stop() {
"$0" recovery-functions -S
}
+# @cmd Check the mcp bridge server is running
+check() {
+ if [[ -f "$MCP_JSON_PATH" ]]; then
+ echo "Check mcp/bridge"
+ pid="$(get-server-pid)"
+ if [[ -z "$pid" ]]; then
+ stop
+ echo "✗ server is not running"
+ fi
+ fi
+}
+
# @cmd Run the mcp tool
# @arg tool![`_choice_tool`] The tool name
# @arg json The json data