Compare commits
10 Commits
738d6d7300
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| bca8bc2c06 | |||
| 5b0240b0b4 | |||
|
|
616d8d84c5 | ||
|
|
08e74dec06 | ||
|
|
afe3670038 | ||
|
|
e5f9a9806c | ||
|
|
358a539b55 | ||
|
|
5cd7e71a13 | ||
|
|
4780ecb39d | ||
|
|
7162e2f295 |
+5
-2
@@ -71,6 +71,9 @@ build() {
|
|||||||
else
|
else
|
||||||
echo 'Skipped building agents since agents.txt is missing'
|
echo 'Skipped building agents since agents.txt is missing'
|
||||||
fi
|
fi
|
||||||
|
if [[ -f mcp.json ]]; then
|
||||||
|
argc mcp merge-functions -S
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# @cmd Build tools
|
# @cmd Build tools
|
||||||
@@ -549,8 +552,8 @@ link-code-interpreter() {
|
|||||||
_link_tool $1 code_interpreter
|
_link_tool $1 code_interpreter
|
||||||
}
|
}
|
||||||
|
|
||||||
# @cmd Install this repo to aichat functions_dir
|
# @cmd Link this repo to aichat functions_dir
|
||||||
install() {
|
link-to-aichat() {
|
||||||
functions_dir="$(aichat --info | grep -w functions_dir | awk '{$1=""; print substr($0,2)}')"
|
functions_dir="$(aichat --info | grep -w functions_dir | awk '{$1=""; print substr($0,2)}')"
|
||||||
if [[ -z "$functions_dir" ]]; then
|
if [[ -z "$functions_dir" ]]; then
|
||||||
_die "error: your aichat version don't support function calling"
|
_die "error: your aichat version don't support function calling"
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ Make sure you have the following tools installed:
|
|||||||
|
|
||||||
- [argc](https://github.com/sigoden/argc): A bash command-line framework and command runner
|
- [argc](https://github.com/sigoden/argc): A bash command-line framework and command runner
|
||||||
- [jq](https://github.com/jqlang/jq): A JSON processor
|
- [jq](https://github.com/jqlang/jq): A JSON processor
|
||||||
|
- [yq](https://github.com/mikefarah/yq): A YAML processor
|
||||||
|
|
||||||
## Getting Started with [AIChat](https://github.com/sigoden/aichat)
|
## Getting Started with [AIChat](https://github.com/sigoden/aichat)
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ Make sure you have the following tools installed:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/sigoden/llm-functions
|
git clone https://github.com/sigoden/llm-functions
|
||||||
|
cd llm-functions
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Build tools and agents
|
### 2. Build tools and agents
|
||||||
@@ -82,14 +84,22 @@ argc build
|
|||||||
argc check
|
argc check
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Install to AIChat
|
### 3. Link LLM-functions and AIChat
|
||||||
|
|
||||||
Symlink this repo directory to AIChat's **functions_dir**:
|
AIChat expects LLM-functions to be placed in AIChat's **functions_dir** so that AIChat can use the tools and agents that LLM-functions provides.
|
||||||
|
|
||||||
|
You can symlink this repository directory to AIChat's **functions_dir** with:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ln -s "$(pwd)" "$(aichat --info | sed -n 's/^functions_dir\s\+//p')"
|
ln -s "$(pwd)" "$(aichat --info | sed -n 's/^functions_dir\s\+//p')"
|
||||||
# OR
|
# OR
|
||||||
argc install
|
argc link-to-aichat
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, you can tell AIChat where the LLM-functions directory is by using an environment variable:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export AICHAT_FUNCTIONS_DIR="$(pwd)"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Start using the functions
|
### 4. Start using the functions
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ instructions: |
|
|||||||
3. Providing architectural insights and applying design patterns
|
3. Providing architectural insights and applying design patterns
|
||||||
4. Staying current with the latest technologies and best practices
|
4. Staying current with the latest technologies and best practices
|
||||||
5. Analyzing and manipulating files within the project directory
|
5. Analyzing and manipulating files within the project directory
|
||||||
6. Performing web searches for up-to-date information
|
|
||||||
|
|
||||||
Available tools and their optimal use cases:
|
Available tools and their optimal use cases:
|
||||||
|
|
||||||
@@ -18,18 +17,12 @@ instructions: |
|
|||||||
3. fs_patch: Examine and modify existing files.
|
3. fs_patch: Examine and modify existing files.
|
||||||
4. fs_cat: View the contents of existing files without making changes.
|
4. fs_cat: View the contents of existing files without making changes.
|
||||||
5. fs_ls: Understand the current project structure or locate specific files.
|
5. fs_ls: Understand the current project structure or locate specific files.
|
||||||
6. Analyzing images provided by the user
|
|
||||||
|
|
||||||
Tool Usage Guidelines:
|
Tool Usage Guidelines:
|
||||||
- Always use the most appropriate tool for the task at hand.
|
- Always use the most appropriate tool for the task at hand.
|
||||||
- For file modifications, use fs_edit. Read the file first, then apply changes if needed.
|
- For file modifications, use fs_patch. Read the file first, then apply changes if needed.
|
||||||
- After making changes, always review the diff output to ensure accuracy.
|
- After making changes, always review the diff output to ensure accuracy.
|
||||||
|
|
||||||
Error Handling and Recovery:
|
|
||||||
- If a tool operation fails, analyze the error message and attempt to resolve the issue.
|
|
||||||
- For file-related errors, check file paths and permissions before retrying.
|
|
||||||
- If a search fails, try rephrasing the query or breaking it into smaller, more specific searches.
|
|
||||||
|
|
||||||
Project Creation and Management:
|
Project Creation and Management:
|
||||||
1. Start by creating a root folder for new projects.
|
1. Start by creating a root folder for new projects.
|
||||||
2. Create necessary subdirectories and files within the root folder.
|
2. Create necessary subdirectories and files within the root folder.
|
||||||
|
|||||||
@@ -1,3 +1,28 @@
|
|||||||
# Demo
|
# Demo
|
||||||
|
|
||||||
This agent serves as a demo to guide agent development and showcase various agent capabilities.
|
This agent serves as a demo to guide agent development and showcase various agent capabilities.
|
||||||
|
|
||||||
|
It has been modified from the version defined in the base repo to also include details on
|
||||||
|
how to integrate MCP servers with agents.
|
||||||
|
|
||||||
|
## How MCP Servers Work with Agents
|
||||||
|
A new `mcp_tools` field was added to the [index.yaml](./index.yaml) file in order to define and configure MCP support for
|
||||||
|
agents.
|
||||||
|
|
||||||
|
This field allows you to specify the prefixes of the MCP server functions that are generated according to
|
||||||
|
the MCP servers defined in the [mcp.json](../../mcp.json) file under the `mcpServers` key.
|
||||||
|
|
||||||
|
When `argc mcp start` is executed, it populates the main [`functions.json`](../../functions.json) file with
|
||||||
|
functions that are all prefixed with the name of the corresponding MCP server in the [mcp.json](../../mcp.json).
|
||||||
|
|
||||||
|
What this fork does is it allows you to specify which MCP servers you specifically want access to in your agent.
|
||||||
|
|
||||||
|
Then, when the `argc mcp start` command is executed, will populate each agent it finds with a non-empty `mcp_tools` field
|
||||||
|
with all the generated functions from the main `functions.json`.
|
||||||
|
|
||||||
|
When you stop the MCP server with `argc mcp stop`, it will also remove the MCP functions from the agent's `functions.json` file.
|
||||||
|
|
||||||
|
This allows you to use the agent either with MCP or without, so you don't necessarily have to remember to start the bridge
|
||||||
|
server every time you want to use your agent if you happen to have separate tools or functions defined in the agent's
|
||||||
|
tools.sh file.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
name: Demo
|
name: Demo
|
||||||
description: An AI agent that demonstrates agent capabilities
|
description: An AI agent that demonstrates agent capabilities
|
||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
|
mcp: true
|
||||||
|
mcp_tools:
|
||||||
|
- github
|
||||||
|
- sqlite
|
||||||
|
- git
|
||||||
instructions: |
|
instructions: |
|
||||||
You are a AI agent designed to demonstrate agent capabilities.
|
You are a AI agent designed to demonstrate agent capabilities.
|
||||||
|
|
||||||
@@ -32,4 +37,4 @@ conversation_starters:
|
|||||||
- How to create an agent?
|
- How to create an agent?
|
||||||
documents:
|
documents:
|
||||||
- README.md
|
- README.md
|
||||||
- https://github.com/sigoden/llm-functions/blob/main/README.md
|
- https://github.com/sigoden/llm-functions/blob/main/README.md
|
||||||
|
|||||||
+2
-2
@@ -70,8 +70,8 @@ argc link-web-search web_search_tavily.sh
|
|||||||
argc link-code-interpreter execute_py_code.py
|
argc link-code-interpreter execute_py_code.py
|
||||||
|
|
||||||
# -------- Misc --------
|
# -------- Misc --------
|
||||||
# Install this repo to aichat functions_dir
|
# Link this repo to aichat functions_dir
|
||||||
argc install
|
argc link-to-aichat
|
||||||
# Displays version information for required tools
|
# Displays version information for required tools
|
||||||
argc version
|
argc version
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Let external MCP tools be used by LLM-Functions.
|
|||||||
|
|
||||||
## Get Started
|
## Get Started
|
||||||
|
|
||||||
### 1. Create a `mpc.json` at `<llm-functions-dir>`.
|
### 1. Create a `mcp.json` at `<llm-functions-dir>`.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -52,4 +52,4 @@ argc mcp start
|
|||||||
|
|
||||||
> Run `argc mcp stop` to stop the bridge server, recover functions.json.
|
> Run `argc mcp stop` to stop the bridge server, recover functions.json.
|
||||||
|
|
||||||
> Run `argc mcp logs` to check the server's logs.
|
> Run `argc mcp logs` to check the server's logs.
|
||||||
|
|||||||
+45
-5
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
readarray -t mcp_enabled_agents < <(find . -type f -name index.yaml -exec sh -c 'yq --exit-status ".mcp_tools | length != 0" "$1" > /dev/null 2>&1 && dirname "$1"' _ {} \;)
|
||||||
ROOT_DIR="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd)"
|
ROOT_DIR="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd)"
|
||||||
BIN_DIR="$ROOT_DIR/bin"
|
BIN_DIR="$ROOT_DIR/bin"
|
||||||
MCP_DIR="$ROOT_DIR/cache/__mcp__"
|
MCP_DIR="$ROOT_DIR/cache/__mcp__"
|
||||||
@@ -25,7 +26,7 @@ start() {
|
|||||||
fi
|
fi
|
||||||
echo "Start MCP Bridge server..."
|
echo "Start MCP Bridge server..."
|
||||||
echo "Install node dependencies..." > "$MCP_LOG_FILE"
|
echo "Install node dependencies..." > "$MCP_LOG_FILE"
|
||||||
npm install --prefix "$ROOT_DIR/mcp/bridge" 1>/dev/null 2>> "$MCP_LOG_FILE"
|
(cd "$ROOT_DIR/mcp/bridge" && npm install 1>/dev/null 2>> "$MCP_LOG_FILE")
|
||||||
nohup node "$index_js" "$llm_functions_dir" >> "$MCP_LOG_FILE" 2>&1 &
|
nohup node "$index_js" "$llm_functions_dir" >> "$MCP_LOG_FILE" 2>&1 &
|
||||||
wait-for-server
|
wait-for-server
|
||||||
echo "Merge MCP tools into functions.json"
|
echo "Merge MCP tools into functions.json"
|
||||||
@@ -89,6 +90,7 @@ logs() {
|
|||||||
|
|
||||||
# @cmd Build tools to bin
|
# @cmd Build tools to bin
|
||||||
build-bin() {
|
build-bin() {
|
||||||
|
mkdir -p "$BIN_DIR"
|
||||||
tools=( $(generate-declarations | jq -r '.[].name') )
|
tools=( $(generate-declarations | jq -r '.[].name') )
|
||||||
for tool in "${tools[@]}"; do
|
for tool in "${tools[@]}"; do
|
||||||
if _is_win; then
|
if _is_win; then
|
||||||
@@ -105,12 +107,31 @@ build-bin() {
|
|||||||
# @cmd Merge mcp tools into functions.json
|
# @cmd Merge mcp tools into functions.json
|
||||||
# @flag -S --save Save to functions.json
|
# @flag -S --save Save to functions.json
|
||||||
merge-functions() {
|
merge-functions() {
|
||||||
result="$(jq --argjson json1 "$("$0" recovery-functions)" --argjson json2 "$(generate-declarations)" -n '($json1 + $json2)')"
|
local tmpdir="$(mktemp -d)"
|
||||||
|
"$0" recovery-functions > "$tmpdir/1.json"
|
||||||
|
generate-declarations > "$tmpdir/2.json"
|
||||||
|
result="$(jq -s '.[0] + .[1]' "$tmpdir/1.json" "$tmpdir/2.json")"
|
||||||
if [[ -n "$argc_save" ]]; then
|
if [[ -n "$argc_save" ]]; then
|
||||||
printf "%s" "$result" > "$FUNCTIONS_JSON_PATH"
|
printf "%s" "$result" > "$FUNCTIONS_JSON_PATH"
|
||||||
else
|
else
|
||||||
printf "%s" "$result"
|
printf "%s" "$result"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
for agent in "${mcp_enabled_agents[@]}"; do
|
||||||
|
if [[ -f "${agent}/functions.json" ]]; then
|
||||||
|
tool_json="$(jq '.' "${agent}/functions.json")"
|
||||||
|
rm -f "${agent}/functions.json"
|
||||||
|
else
|
||||||
|
tool_json='[]'
|
||||||
|
fi
|
||||||
|
|
||||||
|
mcp_function_prefixes="$(yq -o json '.mcp_tools' "${agent}/index.yaml")"
|
||||||
|
|
||||||
|
jq -s 'add | unique' \
|
||||||
|
<(jq '.' <<< "$tool_json") \
|
||||||
|
<(jq --argjson prefixes "$mcp_function_prefixes" 'map(select(.mcp as $mcp | $prefixes | index($mcp)))' "$FUNCTIONS_JSON_PATH") \
|
||||||
|
>> "${agent}/functions.json"
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# @cmd Unmerge mcp tools from functions.json
|
# @cmd Unmerge mcp tools from functions.json
|
||||||
@@ -126,17 +147,36 @@ recovery-functions() {
|
|||||||
else
|
else
|
||||||
printf "%s" "$result"
|
printf "%s" "$result"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
for agent in "${mcp_enabled_agents[@]}"; do
|
||||||
|
if [[ -f "${agent}/functions.json" ]]; then
|
||||||
|
tool_json="$(jq '.' "${agent}/functions.json")"
|
||||||
|
rm -f "${agent}/functions.json"
|
||||||
|
else
|
||||||
|
tool_json='[]'
|
||||||
|
fi
|
||||||
|
|
||||||
|
mcp_function_prefixes="$(yq -o json '.mcp_tools' "${agent}/index.yaml")"
|
||||||
|
|
||||||
|
jq --argjson prefixes "$mcp_function_prefixes" 'map(select(.name as $s | $prefixes | any(. as $p | $s | startswith($p))| not))' <<< "$tool_json" \
|
||||||
|
>> "${agent}/functions.json"
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# @cmd Generate function declarations for the mcp tools
|
# @cmd Generate function declarations for the mcp tools
|
||||||
generate-declarations() {
|
generate-declarations() {
|
||||||
curl -sS http://localhost:$MCP_BRIDGE_PORT/tools
|
pid="$(get-server-pid)"
|
||||||
|
if [[ -n "$pid" ]]; then
|
||||||
|
curl -sS http://localhost:$MCP_BRIDGE_PORT/tools
|
||||||
|
else
|
||||||
|
echo "[]"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# @cmd Wait for the mcp bridge server to ready
|
# @cmd Wait for the mcp bridge server to ready
|
||||||
wait-for-server() {
|
wait-for-server() {
|
||||||
while true; do
|
while true; do
|
||||||
if [[ "$(curl -fsS http://localhost:$MCP_BRIDGE_PORT/health 2>&1)" == "OK" ]]; then
|
if [[ "$(curl -fsS --max-time 5 http://localhost:$MCP_BRIDGE_PORT/health 2>&1)" == "OK" ]]; then
|
||||||
break;
|
break;
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
@@ -145,7 +185,7 @@ wait-for-server() {
|
|||||||
|
|
||||||
# @cmd Get the server pid
|
# @cmd Get the server pid
|
||||||
get-server-pid() {
|
get-server-pid() {
|
||||||
curl -fsSL http://localhost:$MCP_BRIDGE_PORT/pid 2>/dev/null || true
|
curl -fsS --max-time 5 http://localhost:$MCP_BRIDGE_PORT/pid 2>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
_ask_json_data() {
|
_ask_json_data() {
|
||||||
|
|||||||
Reference in New Issue
Block a user