aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsigoden <sigoden@gmail.com>2024-07-10 18:53:32 +0800
committerGitHub <noreply@github.com>2024-07-10 18:53:32 +0800
commit732eae532c8e8632db95ab80e0dde5071e744386 (patch)
tree94e9f6d15b64cff5a26d6bbf44f16c53deb8c324
parent01e07c0cc0be0b1600d688616d12ad0afa9edc71 (diff)
downloadllm-functions-docker-732eae532c8e8632db95ab80e0dde5071e744386.tar.gz
feat: adjust the way of returning data to LLM (#69)
-rw-r--r--Argcfile.sh40
-rw-r--r--README.md6
-rw-r--r--agents/demo/tools.js3
-rw-r--r--agents/demo/tools.py1
-rwxr-xr-xagents/demo/tools.sh7
-rwxr-xr-xagents/todo/tools.sh14
-rwxr-xr-xscripts/run-agent.js26
-rwxr-xr-xscripts/run-agent.py15
-rwxr-xr-xscripts/run-agent.sh50
-rwxr-xr-xscripts/run-tool.js14
-rwxr-xr-xscripts/run-tool.py15
-rwxr-xr-xscripts/run-tool.sh44
-rw-r--r--tools/demo_js.js15
-rw-r--r--tools/demo_py.py20
-rwxr-xr-xtools/demo_sh.sh18
-rwxr-xr-xtools/execute_command.sh13
-rw-r--r--tools/execute_js_code.js2
-rw-r--r--tools/execute_py_code.py2
-rwxr-xr-xtools/fs_cat.sh2
-rwxr-xr-xtools/fs_ls.sh2
-rwxr-xr-xtools/fs_mkdir.sh2
-rwxr-xr-xtools/fs_rm.sh2
-rwxr-xr-xtools/fs_write.sh2
-rwxr-xr-xtools/get_current_time.sh3
-rwxr-xr-xtools/get_current_weather.sh3
-rwxr-xr-xtools/get_web_page.sh3
-rwxr-xr-xtools/search_arxiv.sh2
-rwxr-xr-xtools/search_bing.sh4
-rwxr-xr-xtools/search_brave.sh4
-rwxr-xr-xtools/search_duckduckgo.sh2
-rwxr-xr-xtools/search_exa.sh5
-rwxr-xr-xtools/search_google.sh4
-rwxr-xr-xtools/search_searxng.sh4
-rwxr-xr-xtools/search_tavily.sh4
-rwxr-xr-xtools/search_wikipedia.sh2
-rwxr-xr-xtools/search_wolframalpha.sh3
-rwxr-xr-xtools/send_mail.sh2
37 files changed, 218 insertions, 142 deletions
diff --git a/Argcfile.sh b/Argcfile.sh
index 5a9fcce..6c2e221 100644
--- a/Argcfile.sh
+++ b/Argcfile.sh
@@ -362,39 +362,12 @@ test@tool() {
declarations_file="$TMP_DIR/functions.json"
argc list@tool > "$names_file"
argc build@tool --names-file "$names_file" --declarations-file "$declarations_file"
- test-execute-code-tools
-}
-
-# @cmd Test maybe_execute_* tools
-# @alias tool:test-execute-code
-test-execute-code-tools() {
- if _is_win; then
- ext=".cmd"
- fi
- test_cases=( \
- 'sh#execute_command#{"command":"echo \"✓\""}' \
- 'js#execute_js_code#{"code":"console.log(\"✓\")"}' \
- 'py#execute_py_code#{"code":"print(\"✓\")"}' \
- )
-
- for test_case in "${test_cases[@]}"; do
- IFS='#' read -r lang tool_name data <<<"${test_case}"
- cmd="$(_lang_to_cmd "$lang")"
- if command -v "$cmd" &> /dev/null; then
- cmd_path="$BIN_DIR/$tool_name$ext"
- echo -n "Test $cmd_path: "
- "$cmd_path" "$data"
- if ! _is_win; then
- echo -n "Test $cmd scripts/run-tool.$lang $tool_name: "
- "$cmd" "scripts/run-tool.$lang" "$tool_name" "$data"
- fi
- fi
- done
+ test-demo@tool
}
# @cmd Test demo tools
# @alias tool:test-demo
-test-demo-tools() {
+test-demo@tool() {
for item in "${LANG_CMDS[@]}"; do
lang="${item%:*}"
tool="demo_$lang.$lang"
@@ -429,22 +402,23 @@ test@agent() {
names_file="$tmp_dir/agents.txt"
argc list@agent > "$names_file"
argc build@agent --names-file "$names_file"
- test-demo-agents
+ test-demo@agent
}
# @cmd Test demo agents
# @alias agent:test-demo
-test-demo-agents() {
- echo "Test demo agent:"
+test-demo@agent() {
+ echo "---- Test demo agent ---"
argc run@agent demo get_sysinfo '{}'
for item in "${LANG_CMDS[@]}"; do
cmd="${item#*:}"
lang="${item%:*}"
- echo "Test agents/demo/tools.$lang:"
+ echo "---- Test agents/demo/tools.$lang ---"
if [[ "$cmd" == "sh" ]]; then
"$(argc --argc-shell-path)" ./scripts/run-agent.sh demo get_sysinfo '{}'
elif command -v "$cmd" &> /dev/null; then
$cmd ./scripts/run-agent.$lang demo get_sysinfo '{}'
+ echo
fi
done
}
diff --git a/README.md b/README.md
index 32e2c40..5094977 100644
--- a/README.md
+++ b/README.md
@@ -77,7 +77,7 @@ set -e
# @option --command! The command to execute.
main() {
- eval "$argc_command"
+ eval "$argc_command" >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
@@ -95,7 +95,7 @@ Create a new javascript in the [./tools/](./tools/) directory (.e.g. `may_execut
* @param {Args} args
*/
exports.main = function main({ code }) {
- eval(code);
+ return eval(code);
}
```
@@ -110,7 +110,7 @@ def main(code: str):
Args:
code: Python code to execute, such as `print("hello world")`
"""
- exec(code)
+ return exec(code)
```
diff --git a/agents/demo/tools.js b/agents/demo/tools.js
index 37f8937..6a5c071 100644
--- a/agents/demo/tools.js
+++ b/agents/demo/tools.js
@@ -4,6 +4,5 @@ const os = require("node:os");
*/
exports.get_sysinfo = function getSysinfo() {
return `OS: ${os.type()}
-Arch: ${os.arch()}
-User: ${process.env["USER"]}`
+Arch: ${os.arch()}`
}
diff --git a/agents/demo/tools.py b/agents/demo/tools.py
index 5f1a4fc..ec7ca2b 100644
--- a/agents/demo/tools.py
+++ b/agents/demo/tools.py
@@ -8,5 +8,4 @@ def get_sysinfo():
return "\n".join([
f"OS: {platform.system()}",
f"Arch: {platform.machine()}",
- f"User: {os.environ.get('USER')}"
]) \ No newline at end of file
diff --git a/agents/demo/tools.sh b/agents/demo/tools.sh
index 4b5849b..98f3d47 100755
--- a/agents/demo/tools.sh
+++ b/agents/demo/tools.sh
@@ -3,9 +3,10 @@ set -e
# @cmd Get the system info
get_sysinfo() {
- echo "OS: $(uname)"
- echo "Arch: $(arch)"
- echo "User: $USER"
+ cat <<EOF >> "$LLM_OUTPUT"
+OS: $(uname)
+Arch: $(arch)
+EOF
}
# See more details at https://github.com/sigoden/argc
diff --git a/agents/todo/tools.sh b/agents/todo/tools.sh
index 29454aa..6dbe869 100755
--- a/agents/todo/tools.sh
+++ b/agents/todo/tools.sh
@@ -17,7 +17,7 @@ add_todo() {
--arg new_desc "$argc_desc" \
'. += [{"id": $new_id | tonumber, "desc": $new_desc}]' \
> "$todos_file"
- echo "Successfully added todo id=$num"
+ echo "Successfully added todo id=$num" >> "$LLM_OUTPUT"
}
# @cmd Delete an existing todo item
@@ -29,9 +29,9 @@ del_todo() {
echo "$data" | \
jq --arg id $argc_id '[.[] | select(.id != ($id | tonumber))]' \
> "$todos_file"
- echo "Successfully deleted todo id=$argc_id"
+ echo "Successfully deleted todo id=$argc_id" >> "$LLM_OUTPUT"
else
- echo "Empty todo list"
+ echo "Empty todo list" >> "$LLM_OUTPUT"
fi
}
@@ -39,9 +39,9 @@ del_todo() {
list_todos() {
todos_file="$(_get_todos_file)"
if [[ -f "$todos_file" ]]; then
- cat "$todos_file"
+ cat "$todos_file" >> "$LLM_OUTPUT"
else
- echo '[]'
+ echo '[]' >> "$LLM_OUTPUT"
fi
}
@@ -49,9 +49,9 @@ list_todos() {
clear_todos() {
todos_file="$(_get_todos_file)"
if [[ -f "$todos_file" ]]; then
- rm -rf "$todos_file"
+ rm -rf "$todos_file" >> "$LLM_OUTPUT"
fi
- echo "Successfully deleted entry todo list"
+ echo "Successfully deleted entry todo list" >> "$LLM_OUTPUT"
}
_argc_before() {
diff --git a/scripts/run-agent.js b/scripts/run-agent.js
index 69dd119..36fc66b 100755
--- a/scripts/run-agent.js
+++ b/scripts/run-agent.js
@@ -49,11 +49,19 @@ function parseRawData(data) {
}
function setupEnv(rootDir, agentName) {
- process.env["LLM_ROOT_DIR"] = rootDir;
loadEnv(path.resolve(rootDir, ".env"));
+ process.env["LLM_ROOT_DIR"] = rootDir;
process.env["LLM_AGENT_NAME"] = agentName;
- process.env["LLM_AGENT_ROOT_DIR"] = path.resolve(rootDir, "agents", agentName);
- process.env["LLM_AGENT_CACHE_DIR"] = path.resolve(rootDir, "cache", agentName);
+ process.env["LLM_AGENT_ROOT_DIR"] = path.resolve(
+ rootDir,
+ "agents",
+ agentName,
+ );
+ process.env["LLM_AGENT_CACHE_DIR"] = path.resolve(
+ rootDir,
+ "cache",
+ agentName,
+ );
}
function loadEnv(filePath) {
@@ -84,22 +92,26 @@ async function run(agentPath, agentFunc, agentData) {
throw new Error(`Not module function '${agentFunc}' at '${agentPath}'`);
}
const value = await mod[agentFunc](agentData);
- dumpValue(value);
+ returnToLLM(value);
}
-function dumpValue(value) {
+function returnToLLM(value) {
if (value === null || value === undefined) {
return;
}
+ let writer = process.stdout;
+ if (process.env["LLM_OUTPUT"]) {
+ writer = fs.createWriteStream(process.env["LLM_OUTPUT"]);
+ }
const type = typeof value;
if (type === "string" || type === "number" || type === "boolean") {
- console.log(value);
+ writer.write(value);
} else if (type === "object") {
const proto = Object.prototype.toString.call(value);
if (proto === "[object Object]" || proto === "[object Array]") {
const valueStr = JSON.stringify(value, null, 2);
require("assert").deepStrictEqual(value, JSON.parse(valueStr));
- console.log(valueStr);
+ writer.write(value);
}
}
}
diff --git a/scripts/run-agent.py b/scripts/run-agent.py
index 1239753..a3f3ec5 100755
--- a/scripts/run-agent.py
+++ b/scripts/run-agent.py
@@ -50,8 +50,8 @@ def parse_argv(this_file_name):
def setup_env(root_dir, agent_name):
- os.environ["LLM_ROOT_DIR"] = root_dir
load_env(os.path.join(root_dir, ".env"))
+ os.environ["LLM_ROOT_DIR"] = root_dir
os.environ["LLM_AGENT_NAME"] = agent_name
os.environ["LLM_AGENT_ROOT_DIR"] = os.path.join(root_dir, "agents", agent_name)
os.environ["LLM_AGENT_CACHE_DIR"] = os.path.join(root_dir, "cache", agent_name)
@@ -85,20 +85,25 @@ def run(agent_path, agent_func, agent_data):
raise Exception(f"Not module function '{agent_func}' at '{agent_path}'")
value = getattr(mod, agent_func)(**agent_data)
- dump_value(value)
+ return_to_llm(value)
-def dump_value(value):
+def return_to_llm(value):
if value is None:
return
+ if "LLM_OUTPUT" in os.environ:
+ writer = open(os.environ["LLM_OUTPUT"], "w")
+ else:
+ writer = sys.stdout
+
value_type = type(value).__name__
if value_type in ("str", "int", "float", "bool"):
- print(value)
+ writer.write(value)
elif value_type == "dict" or value_type == "list":
value_str = json.dumps(value, indent=2)
assert value == json.loads(value_str)
- print(value_str)
+ writer.write(value_str)
if __name__ == "__main__":
diff --git a/scripts/run-agent.sh b/scripts/run-agent.sh
index 967efa5..c9ccb48 100755
--- a/scripts/run-agent.sh
+++ b/scripts/run-agent.sh
@@ -2,16 +2,16 @@
set -e
main() {
- this_file_name=run-agent.sh
- parse_argv "$@"
root_dir="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd)"
+ self_name=run-agent.sh
+ parse_argv "$@"
setup_env
- agent_tools_path="$root_dir/agents/$agent_name/tools.sh"
- run
+ tools_path="$root_dir/agents/$agent_name/tools.sh"
+ run
}
parse_argv() {
- if [[ "$0" == *"$this_file_name" ]]; then
+ if [[ "$0" == *"$self_name" ]]; then
agent_name="$1"
agent_func="$2"
agent_data="$3"
@@ -26,29 +26,43 @@ parse_argv() {
}
setup_env() {
+ load_env "$root_dir/.env"
export LLM_ROOT_DIR="$root_dir"
- if [[ -f "$LLM_ROOT_DIR/.env" ]]; then
- set -o allexport && source "$LLM_ROOT_DIR/.env" && set +o allexport
- fi
export LLM_AGENT_NAME="$agent_name"
export LLM_AGENT_ROOT_DIR="$LLM_ROOT_DIR/agents/$agent_name"
export LLM_AGENT_CACHE_DIR="$LLM_ROOT_DIR/cache/$agent_name"
}
+load_env() {
+ local env_file="$1" env_vars
+ if [[ -f "$env_file" ]]; then
+ while IFS='=' read -r key value; do
+ if [[ "$key" == $'#'* ]] || [[ -z "$key" ]]; then
+ continue
+ fi
+ if [[ -z "${!key+x}" ]]; then
+ env_vars="$env_vars $key=$value"
+ fi
+ done < "$env_file"
+ if [[ -n "$env_vars" ]]; then
+ eval "export $env_vars"
+ fi
+ fi
+}
+
run() {
if [[ -z "$agent_data" ]]; then
die "No JSON data"
fi
- _jq=jq
if [[ "$OS" == "Windows_NT" ]]; then
- _jq="jq -b"
- agent_tools_path="$(cygpath -w "$agent_tools_path")"
+ set -o igncr
+ tools_path="$(cygpath -w "$tools_path")"
fi
data="$(
echo "$agent_data" | \
- $_jq -r '
+ jq -r '
to_entries | .[] |
(.key | split("_") | join("-")) as $key |
if .value | type == "array" then
@@ -65,10 +79,18 @@ run() {
if [[ "$line" == '--'* ]]; then
args+=("$line")
else
- args+=("$(echo "$line" | $_jq -r '.')")
+ args+=("$(echo "$line" | jq -r '.')")
fi
done <<< "$data"
- "$agent_tools_path" "$agent_func" "${args[@]}"
+ no_llm_output=0
+ if [[ -z "$LLM_OUTPUT" ]]; then
+ no_llm_output=1
+ export LLM_OUTPUT="$(mktemp)"
+ fi
+ "$tools_path" "$agent_func" "${args[@]}"
+ if [[ "$no_llm_output" -eq 1 ]]; then
+ cat "$LLM_OUTPUT"
+ fi
}
die() {
diff --git a/scripts/run-tool.js b/scripts/run-tool.js
index bc09b5e..9728f7d 100755
--- a/scripts/run-tool.js
+++ b/scripts/run-tool.js
@@ -46,8 +46,8 @@ function parseRawData(data) {
}
function setupEnv(rootDir, toolName) {
- process.env["LLM_ROOT_DIR"] = rootDir;
loadEnv(path.resolve(rootDir, ".env"));
+ process.env["LLM_ROOT_DIR"] = rootDir;
process.env["LLM_TOOL_NAME"] = toolName;
process.env["LLM_TOOL_CACHE_DIR"] = path.resolve(rootDir, "cache", toolName);
}
@@ -80,22 +80,26 @@ async function run(toolPath, toolFunc, toolData) {
throw new Error(`Not module function '${toolFunc}' at '${toolPath}'`);
}
const value = await mod[toolFunc](toolData);
- dumpValue(value);
+ returnToLLM(value);
}
-function dumpValue(value) {
+function returnToLLM(value) {
if (value === null || value === undefined) {
return;
}
+ let writer = process.stdout;
+ if (process.env["LLM_OUTPUT"]) {
+ writer = fs.createWriteStream(process.env["LLM_OUTPUT"]);
+ }
const type = typeof value;
if (type === "string" || type === "number" || type === "boolean") {
- console.log(value);
+ writer.write(value);
} else if (type === "object") {
const proto = Object.prototype.toString.call(value);
if (proto === "[object Object]" || proto === "[object Array]") {
const valueStr = JSON.stringify(value, null, 2);
require("assert").deepStrictEqual(value, JSON.parse(valueStr));
- console.log(valueStr);
+ writer.write(value);
}
}
}
diff --git a/scripts/run-tool.py b/scripts/run-tool.py
index f5aef4f..b5cdc79 100755
--- a/scripts/run-tool.py
+++ b/scripts/run-tool.py
@@ -47,8 +47,8 @@ def parse_argv(this_file_name):
def setup_env(root_dir, tool_name):
- os.environ["LLM_ROOT_DIR"] = root_dir
load_env(os.path.join(root_dir, ".env"))
+ os.environ["LLM_ROOT_DIR"] = root_dir
os.environ["LLM_TOOL_NAME"] = tool_name
os.environ["LLM_TOOL_CACHE_DIR"] = os.path.join(root_dir, "cache", tool_name)
@@ -81,20 +81,25 @@ def run(tool_path, tool_func, tool_data):
raise Exception(f"Not module function '{tool_func}' at '{tool_path}'")
value = getattr(mod, tool_func)(**tool_data)
- dump_value(value)
+ return_to_llm(value)
-def dump_value(value):
+def return_to_llm(value):
if value is None:
return
+ if "LLM_OUTPUT" in os.environ:
+ writer = open(os.environ["LLM_OUTPUT"], "w")
+ else:
+ writer = sys.stdout
+
value_type = type(value).__name__
if value_type in ("str", "int", "float", "bool"):
- print(value)
+ writer.write(value)
elif value_type == "dict" or value_type == "list":
value_str = json.dumps(value, indent=2)
assert value == json.loads(value_str)
- print(value_str)
+ writer.write(value_str)
if __name__ == "__main__":
diff --git a/scripts/run-tool.sh b/scripts/run-tool.sh
index 4c89d53..d70b292 100755
--- a/scripts/run-tool.sh
+++ b/scripts/run-tool.sh
@@ -2,16 +2,16 @@
set -e
main() {
- this_file_name=run-tool.sh
- parse_argv "$@"
root_dir="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd)"
+ self_name=run-tool.sh
+ parse_argv "$@"
setup_env
tool_path="$root_dir/tools/$tool_name.sh"
- run
+ run
}
parse_argv() {
- if [[ "$0" == *"$this_file_name" ]]; then
+ if [[ "$0" == *"$self_name" ]]; then
tool_name="$1"
tool_data="$2"
else
@@ -24,28 +24,42 @@ parse_argv() {
}
setup_env() {
+ load_env "$root_dir/.env"
export LLM_ROOT_DIR="$root_dir"
- if [[ -f "$LLM_ROOT_DIR/.env" ]]; then
- set -o allexport && source "$LLM_ROOT_DIR/.env" && set +o allexport
- fi
export LLM_TOOL_NAME="$tool_name"
export LLM_TOOL_CACHE_DIR="$LLM_ROOT_DIR/cache/$tool_name"
}
+load_env() {
+ local env_file="$1" env_vars
+ if [[ -f "$env_file" ]]; then
+ while IFS='=' read -r key value; do
+ if [[ "$key" == $'#'* ]] || [[ -z "$key" ]]; then
+ continue
+ fi
+ if [[ -z "${!key+x}" ]]; then
+ env_vars="$env_vars $key=$value"
+ fi
+ done < "$env_file"
+ if [[ -n "$env_vars" ]]; then
+ eval "export $env_vars"
+ fi
+ fi
+}
+
run() {
if [[ -z "$tool_data" ]]; then
die "No JSON data"
fi
- _jq=jq
if [[ "$OS" == "Windows_NT" ]]; then
- _jq="jq -b"
+ set -o igncr
tool_path="$(cygpath -w "$tool_path")"
fi
data="$(
echo "$tool_data" | \
- $_jq -r '
+ jq -r '
to_entries | .[] |
(.key | split("_") | join("-")) as $key |
if .value | type == "array" then
@@ -62,10 +76,18 @@ run() {
if [[ "$line" == '--'* ]]; then
args+=("$line")
else
- args+=("$(echo "$line" | $_jq -r '.')")
+ args+=("$(echo "$line" | jq -r '.')")
fi
done <<< "$data"
+ no_llm_output=0
+ if [[ -z "$LLM_OUTPUT" ]]; then
+ no_llm_output=1
+ export LLM_OUTPUT="$(mktemp)"
+ fi
"$tool_path" "${args[@]}"
+ if [[ "$no_llm_output" -eq 1 ]]; then
+ cat "$LLM_OUTPUT"
+ fi
}
die() {
diff --git a/tools/demo_js.js b/tools/demo_js.js
index c8b7237..5693d0e 100644
--- a/tools/demo_js.js
+++ b/tools/demo_js.js
@@ -12,13 +12,18 @@
* @param {Args} args
*/
exports.run = function run(args) {
- for (const [key, value] of Object.entries(args)) {
- console.log(`${key}: ${JSON.stringify(value)}`);
- }
-
+ let output = `string: ${args.string}
+string_enum: ${args.string_enum}
+string_optional: ${args.string_optional}
+boolean: ${args.boolean}
+integer: ${args.integer}
+number: ${args.number}
+array: ${args.array}
+array_optional: ${args.array_optional}`;
for (const [key, value] of Object.entries(process.env)) {
if (key.startsWith("LLM_")) {
- console.log(`${key}: ${value}`);
+ output = `${output}\n${key}: ${value}`;
}
}
+ return output;
}
diff --git a/tools/demo_py.py b/tools/demo_py.py
index d53cd0b..dd0bb1d 100644
--- a/tools/demo_py.py
+++ b/tools/demo_py.py
@@ -2,29 +2,37 @@ import os
from typing import List, Literal, Optional
def run(
- boolean: bool,
string: str,
string_enum: Literal["foo", "bar"],
+ boolean: bool,
integer: int,
number: float,
array: List[str],
string_optional: Optional[str] = None,
array_optional: Optional[List[str]] = None,
-) -> None:
+):
"""Demonstrate how to create a tool using Python and how to use comments.
Args:
- boolean: Define a required boolean property
string: Define a required string property
string_enum: Define a required string property with enum
+ boolean: Define a required boolean property
integer: Define a required integer property
number: Define a required number property
array: Define a required string array property
string_optional: Define a optional string property
array_optional: Define a optional string array property
"""
- for key, value in locals().items():
- print(f"{key}: {value}")
+ output = f"""string: {string}
+string_enum: {string_enum}
+string_optional: {string_optional}
+boolean: {boolean}
+integer: {integer}
+number: {number}
+array: {array}
+array_optional: {array_optional}"""
for key, value in os.environ.items():
if key.startswith("LLM_"):
- print(f"{key}: {value}") \ No newline at end of file
+ output = f"{output}\n{key}: {value}"
+
+ return output
diff --git a/tools/demo_sh.sh b/tools/demo_sh.sh
index da35e8f..11dc72b 100755
--- a/tools/demo_sh.sh
+++ b/tools/demo_sh.sh
@@ -1,3 +1,6 @@
+#!/usr/bin/env bash
+set -e
+
# @describe Demonstrate how to create a tool using Bash and how to use comment tags.
# @option --string! Define a required string property
# @option --string-enum![foo|bar] Define a required string property with enum
@@ -9,8 +12,17 @@
# @option --array-optional* Define a optional string array property
main() {
- ( set -o posix ; set ) | grep ^argc_
- printenv | grep '^LLM_'
+ cat <<EOF >> "$LLM_OUTPUT"
+string: ${argc_string}
+string_enum: ${argc_string_enum}
+string_optional: ${argc_string_optional}
+boolean: ${argc_boolean}
+integer: ${argc_integer}
+number: ${argc_number}
+array: ${argc_array[@]}
+array_optional: ${argc_array_optional[@]}
+$(printenv | grep '^LLM_')
+EOF
}
-eval "$(argc --argc-eval "$0" "$@")" \ No newline at end of file
+eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/execute_command.sh b/tools/execute_command.sh
index 6acc021..0e04b85 100755
--- a/tools/execute_command.sh
+++ b/tools/execute_command.sh
@@ -1,11 +1,18 @@
#!/usr/bin/env bash
set -e
-# @describe Runs a shell command.
+# @describe Runs the shell command.
# @option --command! The command to execute.
main() {
- eval "$argc_command"
+ if [ -t 1 ]; then
+ read -r -p "Are you sure you want to continue? [Y/n] " ans
+ if [[ "$ans" == "N" || "$ans" == "n" ]]; then
+ echo "Aborted!"
+ exit 1
+ fi
+ fi
+ eval "$argc_command" >> "$LLM_OUTPUT"
}
-eval "$(argc --argc-eval "$0" "$@")" \ No newline at end of file
+eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/execute_js_code.js b/tools/execute_js_code.js
index 4706e07..bef6454 100644
--- a/tools/execute_js_code.js
+++ b/tools/execute_js_code.js
@@ -5,5 +5,5 @@
* @param {Args} args
*/
exports.run = function run({ code }) {
- eval(code);
+ return eval(code);
}
diff --git a/tools/execute_py_code.py b/tools/execute_py_code.py
index 5f6af2f..b4bf7b1 100644
--- a/tools/execute_py_code.py
+++ b/tools/execute_py_code.py
@@ -3,4 +3,4 @@ def run(code: str):
Args:
code: Python code to execute, such as `print("hello world")`
"""
- exec(code)
+ return exec(code)
diff --git a/tools/fs_cat.sh b/tools/fs_cat.sh
index e8b3722..bec9a12 100755
--- a/tools/fs_cat.sh
+++ b/tools/fs_cat.sh
@@ -9,7 +9,7 @@ set -e
main() {
path="$FS_BASE_DIR/$argc_path"
- cat "$path"
+ cat "$path" >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/fs_ls.sh b/tools/fs_ls.sh
index 876765a..f288f77 100755
--- a/tools/fs_ls.sh
+++ b/tools/fs_ls.sh
@@ -8,7 +8,7 @@ set -e
main() {
path="$FS_BASE_DIR/$argc_path"
- ls -1 "$path"
+ ls -1 "$path" >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/fs_mkdir.sh b/tools/fs_mkdir.sh
index 7a7e71f..79d853a 100755
--- a/tools/fs_mkdir.sh
+++ b/tools/fs_mkdir.sh
@@ -9,7 +9,7 @@ set -e
main() {
path="$FS_BASE_DIR/$argc_path"
mkdir -p "$path"
- echo "Directory created: $path"
+ echo "Directory created: $path" >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/fs_rm.sh b/tools/fs_rm.sh
index 3d84fe8..1d40295 100755
--- a/tools/fs_rm.sh
+++ b/tools/fs_rm.sh
@@ -9,7 +9,7 @@ set -e
main() {
path="$FS_BASE_DIR/$argc_path"
rm -rf "$path"
- echo "Path removed: $path"
+ echo "Path removed: $path" >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/fs_write.sh b/tools/fs_write.sh
index bc97c34..7718b8d 100755
--- a/tools/fs_write.sh
+++ b/tools/fs_write.sh
@@ -14,7 +14,7 @@ main() {
path="$FS_BASE_DIR/$argc_path"
mkdir -p "$(dirname "$path")"
printf "%s" "$argc_contents" > "$path"
- echo "The contents written to: $path"
+ echo "The contents written to: $path" >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/get_current_time.sh b/tools/get_current_time.sh
index 26a25d8..70752eb 100755
--- a/tools/get_current_time.sh
+++ b/tools/get_current_time.sh
@@ -4,8 +4,7 @@ set -e
# @describe Get the current time.
main() {
- date
+ date >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
-
diff --git a/tools/get_current_weather.sh b/tools/get_current_weather.sh
index 47102e0..ab3e613 100755
--- a/tools/get_current_weather.sh
+++ b/tools/get_current_weather.sh
@@ -5,7 +5,8 @@ set -e
# @option --location! The city and optionally the state or country, e.g., "London", "San Francisco, CA".
main() {
- curl -fsSL "https://wttr.in/$(echo "$argc_location" | sed 's/ /+/g')?format=4&M"
+ curl -fsSL "https://wttr.in/$(echo "$argc_location" | sed 's/ /+/g')?format=4&M" \
+ >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/get_web_page.sh b/tools/get_web_page.sh
index 119dff7..7a516bb 100755
--- a/tools/get_web_page.sh
+++ b/tools/get_web_page.sh
@@ -9,7 +9,8 @@ main() {
# span and div tags are dropped from the HTML https://pandoc.org/MANUAL.html#raw-htmltex and sed removes any inline SVG images in image tags from the Markdown content.
curl -fsSL "$argc_url" | \
pandoc -f html-native_divs-native_spans -t gfm-raw_html | \
- sed -E 's/!\[.*?\]\((data:image\/svg\+xml[^)]+)\)//g'
+ sed -E 's/!\[.*?\]\((data:image\/svg\+xml[^)]+)\)//g' \
+ >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/search_arxiv.sh b/tools/search_arxiv.sh
index 7372c4d..6ffa8cf 100755
--- a/tools/search_arxiv.sh
+++ b/tools/search_arxiv.sh
@@ -9,7 +9,7 @@ set -e
main() {
encoded_query="$(jq -nr --arg q "$argc_query" '$q|@uri')"
url="http://export.arxiv.org/api/query?search_query=all:$encoded_query&max_results=$ARXIV_MAX_RESULTS"
- curl -fsSL "$url"
+ curl -fsSL "$url" >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/search_bing.sh b/tools/search_bing.sh
index 28a47dd..4ab1117 100755
--- a/tools/search_bing.sh
+++ b/tools/search_bing.sh
@@ -13,8 +13,8 @@ main() {
url="https://api.bing.microsoft.com/v7.0/search?q=$encoded_query&mkt=en-us&textdecorations=true&textformat=raw&count=$BING_MAX_RESULTS&offset=0"
curl -fsSL "$url" \
-H "Ocp-Apim-Subscription-Key: $BING_API_KEY" | \
- jq '[.webPages.value[] | {name: .name, url: .url, snippet: .snippet}]'
+ jq '[.webPages.value[] | {name: .name, url: .url, snippet: .snippet}]' \
+ >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
-
diff --git a/tools/search_brave.sh b/tools/search_brave.sh
index 553bfc7..9886944 100755
--- a/tools/search_brave.sh
+++ b/tools/search_brave.sh
@@ -14,8 +14,8 @@ main() {
curl -fsSL "$url" \
-H "Accept: application/json" \
-H "X-Subscription-Token: $BRAVE_API_KEY" | \
- jq '[.web.results[] | {title: .title, url: .url, description: .description}]'
+ jq '[.web.results[] | {title: .title, url: .url, description: .description}]' \
+ >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
-
diff --git a/tools/search_duckduckgo.sh b/tools/search_duckduckgo.sh
index a04b1b0..ad57b50 100755
--- a/tools/search_duckduckgo.sh
+++ b/tools/search_duckduckgo.sh
@@ -9,7 +9,7 @@ set -e
# @option --query! The query to search for.
main() {
- ddgr -n $DDG_MAX_RESULTS --json "$argc_query"
+ ddgr -n $DDG_MAX_RESULTS --json "$argc_query" >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/search_exa.sh b/tools/search_exa.sh
index 33d4564..ccb14cf 100755
--- a/tools/search_exa.sh
+++ b/tools/search_exa.sh
@@ -23,9 +23,8 @@ main() {
}
}
}' | \
- jq '[.results[] | {title: .title, url: .url, text: .text}]'
+ jq '[.results[] | {title: .title, url: .url, text: .text}]' \
+ >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
-
-
diff --git a/tools/search_google.sh b/tools/search_google.sh
index 5d3e1f0..94a6789 100755
--- a/tools/search_google.sh
+++ b/tools/search_google.sh
@@ -13,8 +13,8 @@ main() {
encoded_query="$(jq -nr --arg q "$argc_query" '$q|@uri')"
url="https://www.googleapis.com/customsearch/v1?key=$GOOGLE_API_KEY&cx=$GOOGLE_CSE_ID&q=$encoded_query"
curl -fsSL "$url" | \
- jq '[.items[:'"$GOOGLE_MAX_RESULTS"'] | .[] | {title: .title, link: .link, snippet: .snippet}]'
+ jq '[.items[:'"$GOOGLE_MAX_RESULTS"'] | .[] | {title: .title, link: .link, snippet: .snippet}]' \
+ >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
-
diff --git a/tools/search_searxng.sh b/tools/search_searxng.sh
index 34345ca..e171f58 100755
--- a/tools/search_searxng.sh
+++ b/tools/search_searxng.sh
@@ -12,9 +12,9 @@ main() {
encoded_query="$(jq -nr --arg q "$argc_query" '$q|@uri')"
url="$SEARXNG_API_BASE/search?q=$encoded_query&categories=general&language=en-US&format=json"
curl -fsSL "$url" | \
- jq '[.results[:'"$SEARXNG_MAX_RESULTS"'] | .[] | {url: .url, title: .title, content: .content}]'
+ jq '[.results[:'"$SEARXNG_MAX_RESULTS"'] | .[] | {url: .url, title: .title, content: .content}]' \
+ >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
-
diff --git a/tools/search_tavily.sh b/tools/search_tavily.sh
index 5e99aba..13a8520 100755
--- a/tools/search_tavily.sh
+++ b/tools/search_tavily.sh
@@ -18,8 +18,8 @@ main() {
"search_depth": "advanced",
"max_results": "'"$TAVILY_MAX_RESULTS"'"
}' | \
- jq '[.results[] | {title: .title, url: .url, content: .content}]'
+ jq '[.results[] | {title: .title, url: .url, content: .content}]' \
+ >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
-
diff --git a/tools/search_wikipedia.sh b/tools/search_wikipedia.sh
index 8f055a4..6e08614 100755
--- a/tools/search_wikipedia.sh
+++ b/tools/search_wikipedia.sh
@@ -20,7 +20,7 @@ main() {
echo '{
"link": "https://en.wikipedia.org/wiki/'"$title"'",
"summary": "'"$summary"'"
-}'
+}' >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/search_wolframalpha.sh b/tools/search_wolframalpha.sh
index 20488bf..4da189e 100755
--- a/tools/search_wolframalpha.sh
+++ b/tools/search_wolframalpha.sh
@@ -10,7 +10,8 @@ set -e
main() {
encoded_query="$(jq -nr --arg q "$argc_query" '$q|@uri')"
url="https://api.wolframalpha.com/v2/query?appid=$WOLFRAM_API_ID&input=$encoded_query&output=json&format=plaintext"
- curl -fsSL "$url" | jq '[.queryresult | .pods[] | {title:.title, values:[.subpods[].plaintext | select(. != "")]}]'
+ curl -fsSL "$url" | jq '[.queryresult | .pods[] | {title:.title, values:[.subpods[].plaintext | select(. != "")]}]' \
+ >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"
diff --git a/tools/send_mail.sh b/tools/send_mail.sh
index 2645552..a09ee98 100755
--- a/tools/send_mail.sh
+++ b/tools/send_mail.sh
@@ -23,7 +23,7 @@ $argc_body" | \
--mail-from "$EMAIL_SMTP_USER" \
--mail-rcpt "$argc_recipient" \
--upload-file -
- echo "Email sent successfully"
+ echo "Email sent successfully" >> "$LLM_OUTPUT"
}
eval "$(argc --argc-eval "$0" "$@")"