feat: support env var LLM_DUMP_RESULTS (#144)
This commit is contained in:
+3
-3
@@ -28,7 +28,7 @@ run@tool() {
|
|||||||
fi
|
fi
|
||||||
lang="${argc_tool##*.}"
|
lang="${argc_tool##*.}"
|
||||||
cmd="$(_lang_to_cmd "$lang")"
|
cmd="$(_lang_to_cmd "$lang")"
|
||||||
run_tool_script="$PWD/scripts/run-tool.$lang"
|
run_tool_script="scripts/run-tool.$lang"
|
||||||
[[ -n "$argc_cwd" ]] && cd "$argc_cwd"
|
[[ -n "$argc_cwd" ]] && cd "$argc_cwd"
|
||||||
exec "$cmd" "$run_tool_script" "$argc_tool" "$argc_json"
|
exec "$cmd" "$run_tool_script" "$argc_tool" "$argc_json"
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ run@agent() {
|
|||||||
tools_path="$(_get_agent_tools_path "$argc_agent")"
|
tools_path="$(_get_agent_tools_path "$argc_agent")"
|
||||||
lang="${tools_path##*.}"
|
lang="${tools_path##*.}"
|
||||||
cmd="$(_lang_to_cmd "$lang")"
|
cmd="$(_lang_to_cmd "$lang")"
|
||||||
run_agent_script="$PWD/scripts/run-agent.$lang"
|
run_agent_script="scripts/run-agent.$lang"
|
||||||
[[ -n "$argc_cwd" ]] && cd "$argc_cwd"
|
[[ -n "$argc_cwd" ]] && cd "$argc_cwd"
|
||||||
exec "$cmd" "$run_agent_script" "$argc_agent" "$argc_action" "$argc_json"
|
exec "$cmd" "$run_agent_script" "$argc_agent" "$argc_action" "$argc_json"
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,7 @@ build-declarations@tool() {
|
|||||||
build_failed_tools+=("$name")
|
build_failed_tools+=("$name")
|
||||||
}
|
}
|
||||||
if [[ "$json_data" == "null" ]]; then
|
if [[ "$json_data" == "null" ]]; then
|
||||||
_die "error: failed to build declartions for tool $name"
|
_die "error: failed to build declarations for tool $name"
|
||||||
fi
|
fi
|
||||||
json_list+=("$json_data")
|
json_list+=("$json_data")
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
## Injected by `run-tool.*`/`run-agent.*`
|
## Injected by `run-tool.*`/`run-agent.*`
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
| --------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
| --------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `LLM_ROOT_DIR` | Path to `<llm-functions-dir>` |
|
| `LLM_ROOT_DIR` | Path to `<llm-functions-dir>` |
|
||||||
| `LLM_TOOL_NAME` | Tool name, such as `execute_command` |
|
| `LLM_TOOL_NAME` | Tool name, such as `execute_command` |
|
||||||
| `LLM_TOOL_CACHE_DIR` | Path to `<llm-functions-dir>/cache/<tool-name>`,<br>The tool script can use this directory to store some cache data |
|
| `LLM_TOOL_CACHE_DIR` | Path to `<llm-functions-dir>/cache/<tool-name>`,<br>The tool script can use this directory to store some cache data |
|
||||||
| `LLM_AGENT_NAME` | Agent name, such as `todo` |
|
| `LLM_AGENT_NAME` | Agent name, such as `todo` |
|
||||||
| `LLM_AGENT_FUNC` | Agent function, such as `list_todos` |
|
| `LLM_AGENT_FUNC` | Agent function, such as `list_todos` |
|
||||||
| `LLM_AGENT_ROOT_DIR` | Path to `<llm-functions-dir>/agents/<agent-name>` |
|
| `LLM_AGENT_ROOT_DIR` | Path to `<llm-functions-dir>/agents/<agent-name>` |
|
||||||
| `LLM_AGENT_CACHE_DIR` | Path to `<llm-functions-dir>/cache/<agent-name>`,<br>The tool script can use this directory to store some cache data |
|
| `LLM_AGENT_CACHE_DIR` | Path to `<llm-functions-dir>/cache/<agent-name>`,<br>The agent tool script can use this directory to store some cache data |
|
||||||
|
|
||||||
## Injected by runtime (AIChat)
|
## Injected by runtime (AIChat)
|
||||||
|
|
||||||
@@ -23,4 +23,4 @@
|
|||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
| ------------------ | --------------------------------------------------------------------------------------------- |
|
| ------------------ | --------------------------------------------------------------------------------------------- |
|
||||||
| `LLM_DUMP_RESULTS` | Controls whether to print the execution results of the tool, e.g. `get_current_weather\|fs.*` |
|
| `LLM_DUMP_RESULTS` | Controls whether to print the execution results of the tool, e.g. `get_current_weather\|fs.*\|todo:.*`, `.*` |
|
||||||
|
|||||||
+23
-32
@@ -1,8 +1,9 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// Usage: ./run-agent.js <agent-name> <agent-func> <agent-data>
|
||||||
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const { createWriteStream } = require("fs");
|
const { readFile, writeFile } = require("fs/promises");
|
||||||
const { readFile } = require("fs/promises");
|
|
||||||
const os = require("os");
|
const os = require("os");
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
@@ -13,7 +14,7 @@ async function main() {
|
|||||||
await setupEnv(rootDir, agentName, agentFunc);
|
await setupEnv(rootDir, agentName, agentFunc);
|
||||||
|
|
||||||
const agentToolsPath = path.resolve(rootDir, `agents/${agentName}/tools.js`);
|
const agentToolsPath = path.resolve(rootDir, `agents/${agentName}/tools.js`);
|
||||||
await run(agentToolsPath, agentFunc, agentData);
|
await run(agentName, agentToolsPath, agentFunc, agentData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseArgv(thisFileName) {
|
function parseArgv(thisFileName) {
|
||||||
@@ -104,7 +105,7 @@ async function loadEnv(filePath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function run(agentPath, agentFunc, agentData) {
|
async function run(agentName, agentPath, agentFunc, agentData) {
|
||||||
let mod;
|
let mod;
|
||||||
if (os.platform() === "win32") {
|
if (os.platform() === "win32") {
|
||||||
agentPath = `file://${agentPath}`;
|
agentPath = `file://${agentPath}`;
|
||||||
@@ -118,55 +119,45 @@ async function run(agentPath, agentFunc, agentData) {
|
|||||||
throw new Error(`Not module function '${agentFunc}' at '${agentPath}'`);
|
throw new Error(`Not module function '${agentFunc}' at '${agentPath}'`);
|
||||||
}
|
}
|
||||||
const value = await mod[agentFunc](agentData);
|
const value = await mod[agentFunc](agentData);
|
||||||
returnToLLM(value);
|
await returnToLLM(value);
|
||||||
await dumpResult();
|
await dumpResult(`${agentName}:${agentFunc}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function returnToLLM(value) {
|
async function returnToLLM(value) {
|
||||||
if (value === null || value === undefined) {
|
if (value === null || value === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let writer = process.stdout;
|
const write = async (value) => {
|
||||||
if (process.env["LLM_OUTPUT"]) {
|
if (process.env["LLM_OUTPUT"]) {
|
||||||
writer = createWriteStream(process.env["LLM_OUTPUT"]);
|
await writeFile(process.env["LLM_OUTPUT"], value);
|
||||||
|
} else {
|
||||||
|
process.stdout.write(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const type = typeof value;
|
const type = typeof value;
|
||||||
if (type === "string" || type === "number" || type === "boolean") {
|
if (type === "string" || type === "number" || type === "boolean") {
|
||||||
writer.write(value.toString());
|
await write(value.toString());
|
||||||
} else if (type === "object") {
|
} else if (type === "object") {
|
||||||
const proto = Object.prototype.toString.call(value);
|
const proto = Object.prototype.toString.call(value);
|
||||||
if (proto === "[object Object]" || proto === "[object Array]") {
|
if (proto === "[object Object]" || proto === "[object Array]") {
|
||||||
const valueStr = JSON.stringify(value, null, 2);
|
const valueStr = JSON.stringify(value, null, 2);
|
||||||
require("assert").deepStrictEqual(value, JSON.parse(valueStr));
|
require("assert").deepStrictEqual(value, JSON.parse(valueStr));
|
||||||
writer.write(valueStr);
|
await write(valueStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function dumpResult() {
|
async function dumpResult(name) {
|
||||||
if (!process.stdout.isTTY) {
|
if (!process.env["LLM_DUMP_RESULTS"] || !process.env["LLM_OUTPUT"] || !process.stdout.isTTY) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!process.env["LLM_OUTPUT"]) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let showResult = false;
|
let showResult = false;
|
||||||
const agentName = process.env["LLM_AGENT_NAME"].toUpperCase().replace(/-/g, '_');
|
try {
|
||||||
const agentEnvName = `LLM_AGENT_DUMP_RESULT_${agentName}`;
|
if (new RegExp(`\\b(${process.env["LLM_DUMP_RESULTS"]})\\b`).test(name)) {
|
||||||
const agentEnvValue = process.env[agentEnvName] || process.env["LLM_AGENT_DUMP_RESULT"];
|
showResult = true;
|
||||||
|
}
|
||||||
|
} catch { }
|
||||||
|
|
||||||
const funcName = process.env["LLM_AGENT_FUNC"].toUpperCase().replace(/-/g, '_');
|
|
||||||
const funcEnvName = `${agentEnvName}_${funcName}`;
|
|
||||||
const funcEnvValue = process.env[funcEnvName];
|
|
||||||
if (agentEnvValue === '1' || agentEnvValue === 'true') {
|
|
||||||
if (funcEnvValue !== '0' && funcEnvValue !== 'false') {
|
|
||||||
showResult = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (funcEnvValue === '1' || funcEnvValue === 'true') {
|
|
||||||
showResult = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!showResult) {
|
if (!showResult) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-38
@@ -1,6 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Usage: ./run-agent.py <agent-name> <agent-func> <agent-data>
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
import importlib.util
|
import importlib.util
|
||||||
@@ -14,7 +17,7 @@ def main():
|
|||||||
setup_env(root_dir, agent_name, agent_func)
|
setup_env(root_dir, agent_name, agent_func)
|
||||||
|
|
||||||
agent_tools_path = os.path.join(root_dir, f"agents/{agent_name}/tools.py")
|
agent_tools_path = os.path.join(root_dir, f"agents/{agent_name}/tools.py")
|
||||||
run(agent_tools_path, agent_func, agent_data)
|
run(agent_name, agent_tools_path, agent_func, agent_data)
|
||||||
|
|
||||||
|
|
||||||
def parse_raw_data(data):
|
def parse_raw_data(data):
|
||||||
@@ -90,7 +93,7 @@ def load_env(file_path):
|
|||||||
os.environ.update(env_vars)
|
os.environ.update(env_vars)
|
||||||
|
|
||||||
|
|
||||||
def run(agent_path, agent_func, agent_data):
|
def run(agent_name, agent_path, agent_func, agent_data):
|
||||||
try:
|
try:
|
||||||
spec = importlib.util.spec_from_file_location(
|
spec = importlib.util.spec_from_file_location(
|
||||||
os.path.basename(agent_path), agent_path
|
os.path.basename(agent_path), agent_path
|
||||||
@@ -105,42 +108,7 @@ def run(agent_path, agent_func, agent_data):
|
|||||||
|
|
||||||
value = getattr(mod, agent_func)(**agent_data)
|
value = getattr(mod, agent_func)(**agent_data)
|
||||||
return_to_llm(value)
|
return_to_llm(value)
|
||||||
dump_result()
|
dump_result(rf'{agent_name}:{agent_func}')
|
||||||
|
|
||||||
|
|
||||||
def dump_result():
|
|
||||||
if not os.isatty(1):
|
|
||||||
return
|
|
||||||
|
|
||||||
if not os.getenv("LLM_OUTPUT"):
|
|
||||||
return
|
|
||||||
|
|
||||||
show_result = False
|
|
||||||
agent_name = os.environ["LLM_AGENT_NAME"].upper().replace("-", "_")
|
|
||||||
agent_env_name = f"LLM_AGENT_DUMP_RESULT_{agent_name}"
|
|
||||||
agent_env_value = os.getenv(agent_env_name, os.getenv("LLM_AGENT_DUMP_RESULT"))
|
|
||||||
|
|
||||||
func_name = os.environ["LLM_AGENT_FUNC"].upper().replace("-", "_")
|
|
||||||
func_env_name = f"{agent_env_name}_{func_name}"
|
|
||||||
func_env_value = os.getenv(func_env_name)
|
|
||||||
|
|
||||||
if agent_env_value in ("1", "true"):
|
|
||||||
if func_env_value not in ("0", "false"):
|
|
||||||
show_result = True
|
|
||||||
else:
|
|
||||||
if func_env_value in ("1", "true"):
|
|
||||||
show_result = True
|
|
||||||
|
|
||||||
if not show_result:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(os.environ["LLM_OUTPUT"], "r", encoding="utf-8") as f:
|
|
||||||
data = f.read()
|
|
||||||
except:
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"\x1b[2m----------------------\n{data}\n----------------------\x1b[0m")
|
|
||||||
|
|
||||||
|
|
||||||
def return_to_llm(value):
|
def return_to_llm(value):
|
||||||
@@ -161,5 +129,28 @@ def return_to_llm(value):
|
|||||||
writer.write(value_str)
|
writer.write(value_str)
|
||||||
|
|
||||||
|
|
||||||
|
def dump_result(name):
|
||||||
|
if (not os.getenv("LLM_DUMP_RESULTS")) or (not os.getenv("LLM_OUTPUT")) or (not os.isatty(1)):
|
||||||
|
return
|
||||||
|
|
||||||
|
show_result = False
|
||||||
|
try:
|
||||||
|
if re.search(rf'\b({os.environ["LLM_DUMP_RESULTS"]})\b', name):
|
||||||
|
show_result = True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not show_result:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(os.environ["LLM_OUTPUT"], "r", encoding="utf-8") as f:
|
||||||
|
data = f.read()
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"\x1b[2m----------------------\n{data}\n----------------------\x1b[0m")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
+10
-24
@@ -1,4 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Usage: ./run-agent.sh <agent-name> <agent-func> <agent-data>
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
@@ -88,46 +91,29 @@ EOF
|
|||||||
die "error: invalid JSON data"
|
die "error: invalid JSON data"
|
||||||
}
|
}
|
||||||
|
|
||||||
no_llm_output=0
|
|
||||||
if [[ -z "$LLM_OUTPUT" ]]; then
|
if [[ -z "$LLM_OUTPUT" ]]; then
|
||||||
no_llm_output=1
|
is_temp_llm_output=1
|
||||||
export LLM_OUTPUT="$(mktemp)"
|
export LLM_OUTPUT="$(mktemp)"
|
||||||
fi
|
fi
|
||||||
eval "'$tools_path' '$agent_func' $args"
|
eval "'$tools_path' '$agent_func' $args"
|
||||||
if [[ "$no_llm_output" -eq 1 ]]; then
|
if [[ "$is_temp_llm_output" -eq 1 ]]; then
|
||||||
cat "$LLM_OUTPUT"
|
cat "$LLM_OUTPUT"
|
||||||
else
|
else
|
||||||
dump_result
|
dump_result "${LLM_AGENT_NAME}:${LLM_AGENT_FUNC}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_result() {
|
dump_result() {
|
||||||
if [ ! -t 1 ]; then
|
if [[ "$LLM_OUTPUT" == "/dev/stdout" ]] || [[ -z "$LLM_DUMP_RESULTS" ]] || [[ ! -t 1 ]]; then
|
||||||
return;
|
return;
|
||||||
fi
|
fi
|
||||||
|
if grep -q -w -E "$LLM_DUMP_RESULTS" <<<"$1"; then
|
||||||
local agent_env_name agent_env_value func_env_name func_env_value show_result=0
|
cat <<EOF
|
||||||
agent_env_name="LLM_AGENT_DUMP_RESULT_$(echo "$LLM_AGENT_NAME" | tr '[:lower:]' '[:upper:]' | tr '-' '_')"
|
|
||||||
agent_env_value="${!agent_env_name:-"$LLM_AGENT_DUMP_RESULT"}"
|
|
||||||
func_env_name="${agent_env_name}_$(echo "$LLM_AGENT_FUNC" | tr '[:lower:]' '[:upper:]' | tr '-' '_')"
|
|
||||||
func_env_value="${!func_env_name}"
|
|
||||||
if [[ "$agent_env_value" == "1" || "$agent_env_value" == "true" ]]; then
|
|
||||||
if [[ "$func_env_value" != "0" && "$func_env_value" != "false" ]]; then
|
|
||||||
show_result=1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ "$func_env_value" == "1" || "$func_env_value" == "true" ]]; then
|
|
||||||
show_result=1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [[ "$show_result" -ne 1 ]]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat <<EOF
|
|
||||||
$(echo -e "\e[2m")----------------------
|
$(echo -e "\e[2m")----------------------
|
||||||
$(cat "$LLM_OUTPUT")
|
$(cat "$LLM_OUTPUT")
|
||||||
----------------------$(echo -e "\e[0m")
|
----------------------$(echo -e "\e[0m")
|
||||||
EOF
|
EOF
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
die() {
|
die() {
|
||||||
|
|||||||
+10
-24
@@ -1,4 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Usage: ./run-mcp-tool.sh <tool-name> <tool-data>
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
@@ -53,9 +56,8 @@ run() {
|
|||||||
tool_data="$(echo "$tool_data" | sed 's/\\/\\\\/g')"
|
tool_data="$(echo "$tool_data" | sed 's/\\/\\\\/g')"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
no_llm_output=0
|
|
||||||
if [[ -z "$LLM_OUTPUT" ]]; then
|
if [[ -z "$LLM_OUTPUT" ]]; then
|
||||||
no_llm_output=1
|
is_temp_llm_output=1
|
||||||
export LLM_OUTPUT="$(mktemp)"
|
export LLM_OUTPUT="$(mktemp)"
|
||||||
fi
|
fi
|
||||||
curl -sS "http://localhost:${MCP_BRIDGE_PORT:-8808}/tools/$tool_name" \
|
curl -sS "http://localhost:${MCP_BRIDGE_PORT:-8808}/tools/$tool_name" \
|
||||||
@@ -63,40 +65,24 @@ run() {
|
|||||||
-H 'content-type: application/json' \
|
-H 'content-type: application/json' \
|
||||||
-d "$tool_data" > "$LLM_OUTPUT"
|
-d "$tool_data" > "$LLM_OUTPUT"
|
||||||
|
|
||||||
if [[ "$no_llm_output" -eq 1 ]]; then
|
if [[ "$is_temp_llm_output" -eq 1 ]]; then
|
||||||
cat "$LLM_OUTPUT"
|
cat "$LLM_OUTPUT"
|
||||||
else
|
else
|
||||||
dump_result
|
dump_result "$tool_name"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_result() {
|
dump_result() {
|
||||||
if [ ! -t 1 ]; then
|
if [[ "$LLM_OUTPUT" == "/dev/stdout" ]] || [[ -z "$LLM_DUMP_RESULTS" ]] || [[ ! -t 1 ]]; then
|
||||||
return;
|
return;
|
||||||
fi
|
fi
|
||||||
|
if grep -q -w -E "$LLM_DUMP_RESULTS" <<<"$1"; then
|
||||||
local agent_env_name agent_env_value func_env_name func_env_value show_result=0
|
cat <<EOF
|
||||||
agent_env_name="LLM_AGENT_DUMP_RESULT_$(echo "$LLM_AGENT_NAME" | tr '[:lower:]' '[:upper:]' | tr '-' '_')"
|
|
||||||
agent_env_value="${!agent_env_name:-"$LLM_AGENT_DUMP_RESULT"}"
|
|
||||||
func_env_name="${agent_env_name}_$(echo "$LLM_AGENT_FUNC" | tr '[:lower:]' '[:upper:]' | tr '-' '_')"
|
|
||||||
func_env_value="${!func_env_name}"
|
|
||||||
if [[ "$agent_env_value" == "1" || "$agent_env_value" == "true" ]]; then
|
|
||||||
if [[ "$func_env_value" != "0" && "$func_env_value" != "false" ]]; then
|
|
||||||
show_result=1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ "$func_env_value" == "1" || "$func_env_value" == "true" ]]; then
|
|
||||||
show_result=1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [[ "$show_result" -ne 1 ]]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat <<EOF
|
|
||||||
$(echo -e "\e[2m")----------------------
|
$(echo -e "\e[2m")----------------------
|
||||||
$(cat "$LLM_OUTPUT")
|
$(cat "$LLM_OUTPUT")
|
||||||
----------------------$(echo -e "\e[0m")
|
----------------------$(echo -e "\e[0m")
|
||||||
EOF
|
EOF
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
+22
-27
@@ -1,8 +1,9 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// Usage: ./run-tool.js <tool-name> <tool-data>
|
||||||
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const { createWriteStream } = require("fs");
|
const { readFile, writeFile } = require("fs/promises");
|
||||||
const { readFile } = require("fs/promises");
|
|
||||||
const os = require("os");
|
const os = require("os");
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
@@ -13,7 +14,7 @@ async function main() {
|
|||||||
await setupEnv(rootDir, toolName);
|
await setupEnv(rootDir, toolName);
|
||||||
|
|
||||||
const toolPath = path.resolve(rootDir, `tools/${toolName}.js`);
|
const toolPath = path.resolve(rootDir, `tools/${toolName}.js`);
|
||||||
await run(toolPath, "run", toolData);
|
await run(toolName, toolPath, "run", toolData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseArgv(thisFileName) {
|
function parseArgv(thisFileName) {
|
||||||
@@ -91,7 +92,7 @@ async function loadEnv(filePath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function run(toolPath, toolFunc, toolData) {
|
async function run(toolName, toolPath, toolFunc, toolData) {
|
||||||
let mod;
|
let mod;
|
||||||
if (os.platform() === "win32") {
|
if (os.platform() === "win32") {
|
||||||
toolPath = `file://${toolPath}`;
|
toolPath = `file://${toolPath}`;
|
||||||
@@ -105,51 +106,45 @@ async function run(toolPath, toolFunc, toolData) {
|
|||||||
throw new Error(`Not module function '${toolFunc}' at '${toolPath}'`);
|
throw new Error(`Not module function '${toolFunc}' at '${toolPath}'`);
|
||||||
}
|
}
|
||||||
const value = await mod[toolFunc](toolData);
|
const value = await mod[toolFunc](toolData);
|
||||||
returnToLLM(value);
|
await returnToLLM(value);
|
||||||
await dumpResult();
|
await dumpResult(toolName);
|
||||||
}
|
}
|
||||||
|
|
||||||
function returnToLLM(value) {
|
async function returnToLLM(value) {
|
||||||
if (value === null || value === undefined) {
|
if (value === null || value === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let writer = process.stdout;
|
const write = async (value) => {
|
||||||
if (process.env["LLM_OUTPUT"]) {
|
if (process.env["LLM_OUTPUT"]) {
|
||||||
writer = createWriteStream(process.env["LLM_OUTPUT"]);
|
await writeFile(process.env["LLM_OUTPUT"], value);
|
||||||
|
} else {
|
||||||
|
process.stdout.write(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const type = typeof value;
|
const type = typeof value;
|
||||||
if (type === "string" || type === "number" || type === "boolean") {
|
if (type === "string" || type === "number" || type === "boolean") {
|
||||||
writer.write(value.toString());
|
await write(value.toString());
|
||||||
} else if (type === "object") {
|
} else if (type === "object") {
|
||||||
const proto = Object.prototype.toString.call(value);
|
const proto = Object.prototype.toString.call(value);
|
||||||
if (proto === "[object Object]" || proto === "[object Array]") {
|
if (proto === "[object Object]" || proto === "[object Array]") {
|
||||||
const valueStr = JSON.stringify(value, null, 2);
|
const valueStr = JSON.stringify(value, null, 2);
|
||||||
require("assert").deepStrictEqual(value, JSON.parse(valueStr));
|
require("assert").deepStrictEqual(value, JSON.parse(valueStr));
|
||||||
writer.write(valueStr);
|
await write(valueStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function dumpResult() {
|
async function dumpResult(name) {
|
||||||
if (!process.stdout.isTTY) {
|
if (!process.env["LLM_DUMP_RESULTS"] || !process.env["LLM_OUTPUT"] || !process.stdout.isTTY) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!process.env["LLM_OUTPUT"]) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let showResult = false;
|
let showResult = false;
|
||||||
const toolName = process.env["LLM_TOOL_NAME"].toUpperCase().replace(/-/g, '_');
|
try {
|
||||||
const envName = `LLM_TOOL_DUMP_RESULT_${toolName}`;
|
if (new RegExp(`\\b(${process.env["LLM_DUMP_RESULTS"]})\\b`).test(name)) {
|
||||||
const envValue = process.env[envName];
|
|
||||||
if (process.env.LLM_TOOL_DUMP_RESULT === '1' || process.env.LLM_TOOL_DUMP_RESULT === 'true') {
|
|
||||||
if (envValue !== '0' && envValue !== 'false') {
|
|
||||||
showResult = true;
|
showResult = true;
|
||||||
}
|
}
|
||||||
} else {
|
} catch { }
|
||||||
if (envValue === '1' || envValue === 'true') {
|
|
||||||
showResult = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!showResult) {
|
if (!showResult) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-17
@@ -1,6 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Usage: ./run-tool.py <tool-name> <tool-data>
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
import importlib.util
|
import importlib.util
|
||||||
@@ -14,7 +17,7 @@ def main():
|
|||||||
setup_env(root_dir, tool_name)
|
setup_env(root_dir, tool_name)
|
||||||
|
|
||||||
tool_path = os.path.join(root_dir, f"tools/{tool_name}.py")
|
tool_path = os.path.join(root_dir, f"tools/{tool_name}.py")
|
||||||
run(tool_path, "run", tool_data)
|
run(tool_name, tool_path, "run", tool_data)
|
||||||
|
|
||||||
|
|
||||||
def parse_raw_data(data):
|
def parse_raw_data(data):
|
||||||
@@ -85,7 +88,7 @@ def load_env(file_path):
|
|||||||
os.environ.update(env_vars)
|
os.environ.update(env_vars)
|
||||||
|
|
||||||
|
|
||||||
def run(tool_path, tool_func, tool_data):
|
def run(tool_name, tool_path, tool_func, tool_data):
|
||||||
try:
|
try:
|
||||||
spec = importlib.util.spec_from_file_location(
|
spec = importlib.util.spec_from_file_location(
|
||||||
os.path.basename(tool_path), tool_path
|
os.path.basename(tool_path), tool_path
|
||||||
@@ -100,7 +103,7 @@ def run(tool_path, tool_func, tool_data):
|
|||||||
|
|
||||||
value = getattr(mod, tool_func)(**tool_data)
|
value = getattr(mod, tool_func)(**tool_data)
|
||||||
return_to_llm(value)
|
return_to_llm(value)
|
||||||
dump_result()
|
dump_result(tool_name)
|
||||||
|
|
||||||
|
|
||||||
def return_to_llm(value):
|
def return_to_llm(value):
|
||||||
@@ -121,24 +124,16 @@ def return_to_llm(value):
|
|||||||
writer.write(value_str)
|
writer.write(value_str)
|
||||||
|
|
||||||
|
|
||||||
def dump_result():
|
def dump_result(name):
|
||||||
if not os.isatty(1):
|
if (not os.getenv("LLM_DUMP_RESULTS")) or (not os.getenv("LLM_OUTPUT")) or (not os.isatty(1)):
|
||||||
return
|
|
||||||
|
|
||||||
if not os.getenv("LLM_OUTPUT"):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
show_result = False
|
show_result = False
|
||||||
tool_name = os.environ["LLM_TOOL_NAME"].upper().replace("-", "_")
|
try:
|
||||||
env_name = f"LLM_TOOL_DUMP_RESULT_{tool_name}"
|
if re.search(rf'\b({os.environ["LLM_DUMP_RESULTS"]})\b', name):
|
||||||
env_value = os.getenv(env_name)
|
|
||||||
|
|
||||||
if os.getenv("LLM_TOOL_DUMP_RESULT") in ("1", "true"):
|
|
||||||
if env_value not in ("0", "false"):
|
|
||||||
show_result = True
|
|
||||||
else:
|
|
||||||
if env_value in ("1", "true"):
|
|
||||||
show_result = True
|
show_result = True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
if not show_result:
|
if not show_result:
|
||||||
return
|
return
|
||||||
|
|||||||
+10
-22
@@ -1,4 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Usage: ./run-tool.sh <tool-name> <tool-data>
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
@@ -83,44 +86,29 @@ EOF
|
|||||||
args="$(echo "$tool_data" | jq -r "$jq_script" 2>/dev/null)" || {
|
args="$(echo "$tool_data" | jq -r "$jq_script" 2>/dev/null)" || {
|
||||||
die "error: invalid JSON data"
|
die "error: invalid JSON data"
|
||||||
}
|
}
|
||||||
|
|
||||||
no_llm_output=0
|
|
||||||
if [[ -z "$LLM_OUTPUT" ]]; then
|
if [[ -z "$LLM_OUTPUT" ]]; then
|
||||||
no_llm_output=1
|
is_temp_llm_output=1
|
||||||
export LLM_OUTPUT="$(mktemp)"
|
export LLM_OUTPUT="$(mktemp)"
|
||||||
fi
|
fi
|
||||||
eval "'$tool_path' $args"
|
eval "'$tool_path' $args"
|
||||||
if [[ "$no_llm_output" -eq 1 ]]; then
|
if [[ "$is_temp_llm_output" -eq 1 ]]; then
|
||||||
cat "$LLM_OUTPUT"
|
cat "$LLM_OUTPUT"
|
||||||
else
|
else
|
||||||
dump_result
|
dump_result "$tool_name"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_result() {
|
dump_result() {
|
||||||
if [ ! -t 1 ]; then
|
if [[ "$LLM_OUTPUT" == "/dev/stdout" ]] || [[ -z "$LLM_DUMP_RESULTS" ]] || [[ ! -t 1 ]]; then
|
||||||
return;
|
return;
|
||||||
fi
|
fi
|
||||||
local env_name env_value show_result=0
|
if grep -q -w -E "$LLM_DUMP_RESULTS" <<<"$1"; then
|
||||||
env_name="LLM_TOOL_DUMP_RESULT_$(echo "$LLM_TOOL_NAME" | tr '[:lower:]' '[:upper:]' | tr '-' '_')"
|
cat <<EOF
|
||||||
env_value="${!env_name}"
|
|
||||||
if [[ "$LLM_TOOL_DUMP_RESULT" == "1" || "$LLM_TOOL_DUMP_RESULT" == "true" ]]; then
|
|
||||||
if [[ "$env_value" != "0" && "$env_value" != "false" ]]; then
|
|
||||||
show_result=1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ "$env_value" == "1" || "$env_value" == "true" ]]; then
|
|
||||||
show_result=1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [[ "$show_result" -ne 1 ]]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
cat <<EOF
|
|
||||||
$(echo -e "\e[2m")----------------------
|
$(echo -e "\e[2m")----------------------
|
||||||
$(cat "$LLM_OUTPUT")
|
$(cat "$LLM_OUTPUT")
|
||||||
----------------------$(echo -e "\e[0m")
|
----------------------$(echo -e "\e[0m")
|
||||||
EOF
|
EOF
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
die() {
|
die() {
|
||||||
|
|||||||
Reference in New Issue
Block a user