From adfb7c2b49ba4ba691e89683afa700eabbb3388c Mon Sep 17 00:00:00 2001 From: sigoden Date: Sat, 22 Jun 2024 06:52:45 +0800 Subject: refactor: rename bot to agent (#44) --- agents/todo-js/index.yaml | 1 + agents/todo-js/tools.js | 68 +++++++++++++++++++++++++++++++++++++++++++++++ agents/todo-py/index.yaml | 1 + agents/todo-py/tools.py | 62 ++++++++++++++++++++++++++++++++++++++++++ agents/todo-sh/index.yaml | 19 +++++++++++++ agents/todo-sh/tools.sh | 67 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 218 insertions(+) create mode 120000 agents/todo-js/index.yaml create mode 100644 agents/todo-js/tools.js create mode 120000 agents/todo-py/index.yaml create mode 100644 agents/todo-py/tools.py create mode 100644 agents/todo-sh/index.yaml create mode 100755 agents/todo-sh/tools.sh (limited to 'agents') diff --git a/agents/todo-js/index.yaml b/agents/todo-js/index.yaml new file mode 120000 index 0000000..0d19c11 --- /dev/null +++ b/agents/todo-js/index.yaml @@ -0,0 +1 @@ +../todo-sh/index.yaml \ No newline at end of file diff --git a/agents/todo-js/tools.js b/agents/todo-js/tools.js new file mode 100644 index 0000000..cef4c8f --- /dev/null +++ b/agents/todo-js/tools.js @@ -0,0 +1,68 @@ +const fs = require('fs'); +const path = require('path'); + +/** + * Add a new todo item + * @typedef {Object} AddTodoArgs + * @property {string} desc - The task description + * @param {AddTodoArgs} args + */ +exports.add_todo = function addTodo(args) { + const todosFile = _getTodosFile(); + if (fs.existsSync(todosFile)) { + const num = JSON.parse(fs.readFileSync(todosFile)).reduce((max, item) => Math.max(max, item.id), 0) + 1; + const data = fs.readFileSync(todosFile); + fs.writeFileSync(todosFile, JSON.stringify([...JSON.parse(data), { id: num, desc: args.desc }])); + console.log(`Successfully added todo id=${num}`); + } else { + fs.writeFileSync(todosFile, JSON.stringify([{ id: 1, desc: args.desc }])); + console.log('Successfully added todo id=1'); + } +} + +/** + * Delete an existing todo item + * @typedef {Object} DelTodoArgs + * @property {number} id - The task id + * @param {DelTodoArgs} args + */ +exports.del_todo = function delTodo(args) { + const todosFile = _getTodosFile(); + if (fs.existsSync(todosFile)) { + const data = fs.readFileSync(todosFile); + const newData = JSON.parse(data).filter(item => item.id !== args.id); + fs.writeFileSync(todosFile, JSON.stringify(newData)); + console.log(`Successfully deleted todo id=${args.id}`); + } else { + console.log('Empty todo list'); + } +} + +/** + * Display the current todo list in json format. + */ +exports.list_todos = function listTodos() { + const todosFile = _getTodosFile(); + if (fs.existsSync(todosFile)) { + console.log(fs.readFileSync(todosFile, "utf8")); + } else { + console.log("[]"); + } +} + +/** + * Delete the entire todo list. + */ +exports.clear_todos = function clearTodos() { + const todosFile = _getTodosFile(); + fs.unlinkSync(todosFile) + console.log("Successfully deleted entry todo list"); +} + +function _getTodosFile() { + const cacheDir = process.env.LLM_AGENT_CACHE_DIR || '/tmp'; + if (!fs.existsSync(cacheDir)) { + fs.mkdirSync(cacheDir, { recursive: true }); + } + return path.join(cacheDir, 'todos.json'); +} diff --git a/agents/todo-py/index.yaml b/agents/todo-py/index.yaml new file mode 120000 index 0000000..0d19c11 --- /dev/null +++ b/agents/todo-py/index.yaml @@ -0,0 +1 @@ +../todo-sh/index.yaml \ No newline at end of file diff --git a/agents/todo-py/tools.py b/agents/todo-py/tools.py new file mode 100644 index 0000000..0aa5f4b --- /dev/null +++ b/agents/todo-py/tools.py @@ -0,0 +1,62 @@ +import json +import sys +import os +from json import JSONDecodeError + + +def add_todo(desc: str): + """Add a new todo item + Args: + desc: The task description + """ + todos_file = _get_todos_file() + try: + with open(todos_file, "r") as f: + data = json.load(f) + except (FileNotFoundError, JSONDecodeError): + data = [] + num = max([item["id"] for item in data] + [0]) + 1 + data.append({"id": num, "desc": desc}) + with open(todos_file, "w") as f: + json.dump(data, f) + print(f"Successfully added todo id={num}") + + +def del_todo(id: int): + """Delete an existing todo item + Args: + id: The task id + """ + todos_file = _get_todos_file() + try: + with open(todos_file, "r") as f: + data = json.load(f) + except (FileNotFoundError, JSONDecodeError): + print("Empty todo list") + return + data = [item for item in data if item["id"] != id] + with open(todos_file, "w") as f: + json.dump(data, f) + print(f"Successfully deleted todo id={id}") + + +def list_todos(): + """Display the current todo list in json format.""" + todos_file = _get_todos_file() + try: + with open(todos_file, "r") as f: + print(f.read()) + except FileNotFoundError: + print("[]") + + +def clear_todos(): + """Delete the entire todo list.""" + os.remove(_get_todos_file()) + + +def _get_todos_file() -> str: + cache_dir=os.environ.get("LLM_AGENT_CACHE_DIR", "/tmp") + if not os.path.exists(cache_dir): + os.makedirs(cache_dir, exist_ok=True) + return os.path.join(cache_dir, "todos.json") diff --git a/agents/todo-sh/index.yaml b/agents/todo-sh/index.yaml new file mode 100644 index 0000000..490280e --- /dev/null +++ b/agents/todo-sh/index.yaml @@ -0,0 +1,19 @@ +name: Todo +description: A helpful ai agent that manages a todo list. +instructions: | + You will be provided with a list of todos. + Users can interact with you using the following commands: + * add_todo: Add a todo to the list. + * rm_todo: Remove a todo from the list. + * list_todos: Display the current todo list. + * clear_todos: Delete the entire todo list. + Based on the interaction, ensure that you provide appropriate confirmations or errors for the requested operation. For example: + - Confirmations: "Todo item added successfully!", "Todo item removed successfully!", "All todo items deleted!" + - Errors: "Cannot add todo item, missing description.", "Todo item with id {id} not found.", "No todo items to delete." + Make sure you understand the user request properly before performing any action. If unsure, ask clarifying questions like "Do you want to remove all todos or just a specific one?" +conversation_starters: + - "Add a new todo item 'Finish report'." + - "Remove the todo item with id=2." + - "Delete all my todos." + - "What todos do I have pending?" + - "How can I remove a specific todo item?" \ No newline at end of file diff --git a/agents/todo-sh/tools.sh b/agents/todo-sh/tools.sh new file mode 100755 index 0000000..29454aa --- /dev/null +++ b/agents/todo-sh/tools.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +set -e + +# @cmd Add a new todo item +# @option --desc! The task description +add_todo() { + todos_file="$(_get_todos_file)" + if [[ -f "$todos_file" ]]; then + num="$(cat "$todos_file" | jq '[.[].id] | max + 1')" + data="$(cat "$todos_file")" + else + num=1 + data="[]" + fi + echo "$data" | \ + jq --arg new_id $num \ + --arg new_desc "$argc_desc" \ + '. += [{"id": $new_id | tonumber, "desc": $new_desc}]' \ + > "$todos_file" + echo "Successfully added todo id=$num" +} + +# @cmd Delete an existing todo item +# @option --id! The task id +del_todo() { + todos_file="$(_get_todos_file)" + if [[ -f "$todos_file" ]]; then + data="$(cat "$todos_file")" + echo "$data" | \ + jq --arg id $argc_id '[.[] | select(.id != ($id | tonumber))]' \ + > "$todos_file" + echo "Successfully deleted todo id=$argc_id" + else + echo "Empty todo list" + fi +} + +# @cmd Display the current todo list in json format. +list_todos() { + todos_file="$(_get_todos_file)" + if [[ -f "$todos_file" ]]; then + cat "$todos_file" + else + echo '[]' + fi +} + +# @cmd Delete the entire todo list. +clear_todos() { + todos_file="$(_get_todos_file)" + if [[ -f "$todos_file" ]]; then + rm -rf "$todos_file" + fi + echo "Successfully deleted entry todo list" +} + +_argc_before() { + todos_file="$(_get_todos_file)" + mkdir -p "$(dirname "$todos_file")" +} + +_get_todos_file() { + echo "${LLM_AGENT_CACHE_DIR:-/tmp}/todos.json" +} + +# See more details at https://github.com/sigoden/argc +eval "$(argc --argc-eval "$0" "$@")" -- cgit v1.2.3