diff --git a/llm_agents/tools_agent/.prettierrc b/llm_agents/tools_agent/.prettierrc new file mode 100644 index 00000000..91a35174 --- /dev/null +++ b/llm_agents/tools_agent/.prettierrc @@ -0,0 +1,3 @@ +{ + "printWidth": 160 +} diff --git a/llm_agents/tools_agent/README.md b/llm_agents/tools_agent/README.md new file mode 100644 index 00000000..7a3a9771 --- /dev/null +++ b/llm_agents/tools_agent/README.md @@ -0,0 +1,82 @@ + +# @graphai/tools_agent for GraphAI + +General tools agents + +### Install + +```sh +yarn add @graphai/tools_agent +``` + + +### Usage + +```typescript +import { GraphAI } from "graphai"; +import { toolsAgent } from "@graphai/tools_agent"; + +const agents = { toolsAgent }; + +const graph = new GraphAI(graph_data, agents); +const result = await graph.run(); +``` + +### Agents description +- toolsAgent - + +### Input/Output/Params Schema & samples + - [toolsAgent](https://github.com/receptron/graphai/blob/main/docs/agentDocs/undefined/toolsAgent.md) + +### Input/Params example + - toolsAgent + +```typescript +{ + "inputs": { + "llmAgent": "openAIAgent", + "tools": [ + { + "type": "function", + "function": { + "name": "lightAgent--toggleLight", + "description": "Switch of light", + "parameters": { + "type": "object", + "properties": { + "switch": { + "type": "boolean", + "description": "change light state" + } + } + } + } + } + ], + "messages": [ + { + "role": "system", + "content": "You are a light switch. Please follow the user's instructions." + } + ], + "userInput": { + "text": "turn on the light.", + "message": { + "role": "user", + "content": "turn on the light." + } + } + }, + "params": {} +} +``` + + + + + + + + + + diff --git a/llm_agents/tools_agent/eslint.config.mjs b/llm_agents/tools_agent/eslint.config.mjs new file mode 100644 index 00000000..a5b5503a --- /dev/null +++ b/llm_agents/tools_agent/eslint.config.mjs @@ -0,0 +1,11 @@ +import eslintBase from "../../config/eslint.config.base.mjs"; + +export default [ + { + files: ["{src,test,samles}/**/*.{js,ts,yaml,yml,json}"], + }, + { + ignores: ["lib/**/*", "*.ts", "apiDoc/**/*", "apiDoc/*"], + }, + ...eslintBase, +]; diff --git a/llm_agents/tools_agent/lib/index.d.ts b/llm_agents/tools_agent/lib/index.d.ts new file mode 100644 index 00000000..086cdeab --- /dev/null +++ b/llm_agents/tools_agent/lib/index.d.ts @@ -0,0 +1,2 @@ +import toolsAgent from "./tools_agent"; +export { toolsAgent }; diff --git a/llm_agents/tools_agent/lib/index.js b/llm_agents/tools_agent/lib/index.js new file mode 100644 index 00000000..6beb59ba --- /dev/null +++ b/llm_agents/tools_agent/lib/index.js @@ -0,0 +1,8 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toolsAgent = void 0; +const tools_agent_1 = __importDefault(require("./tools_agent")); +exports.toolsAgent = tools_agent_1.default; diff --git a/llm_agents/tools_agent/lib/tools_agent.d.ts b/llm_agents/tools_agent/lib/tools_agent.d.ts new file mode 100644 index 00000000..bc2e4644 --- /dev/null +++ b/llm_agents/tools_agent/lib/tools_agent.d.ts @@ -0,0 +1,47 @@ +declare const toolsAgentInfo: { + name: string; + agent: (context: import("graphai").AgentFunctionContext) => Promise; + mock: (context: import("graphai").AgentFunctionContext) => Promise; + samples: { + inputs: { + llmAgent: string; + tools: { + type: string; + function: { + name: string; + description: string; + parameters: { + type: string; + properties: { + switch: { + type: string; + description: string; + }; + }; + }; + }; + }[]; + messages: { + role: string; + content: string; + }[]; + userInput: { + text: string; + message: { + role: string; + content: string; + }; + }; + }; + params: {}; + result: string; + }[]; + description: string; + category: never[]; + author: string; + repository: string; + tools: never[]; + license: string; + hasGraphData: boolean; +}; +export default toolsAgentInfo; diff --git a/llm_agents/tools_agent/lib/tools_agent.js b/llm_agents/tools_agent/lib/tools_agent.js new file mode 100644 index 00000000..84ef44ee --- /dev/null +++ b/llm_agents/tools_agent/lib/tools_agent.js @@ -0,0 +1,127 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const nested_agent_1 = require("@graphai/vanilla/lib/graph_agents/nested_agent"); +const toolWorkFlowStep = { + version: 0.5, + nodes: { + llm: { + agent: ":llmAgent", + isResult: true, + params: { + forWeb: true, + stream: true, + tools: ":tools", + }, + inputs: { messages: ":messages", prompt: ":userInput.text" }, + }, + textMessage: { + unless: ":llm.tool.id", + agent: "copyAgent", + inputs: { + messages: [":userInput.message", { role: "assistant", content: ":llm.message.content" }], + }, + }, + tool_calls: { + if: ":llm.tool_calls", + agent: "mapAgent", + inputs: { rows: ":llm.tool_calls" }, + params: { + compositeResult: true, + }, + graph: { + version: 0.5, + nodes: { + tool: { + agent: ":row.name.split(--).$0", + inputs: { + arg: ":row.arguments", + func: ":row.name.split(--).$1", + tool_call: ":row", + }, + }, + message: { + isResult: true, + agent: "copyAgent", + inputs: { + role: "tool", + tool_call_id: ":row.id", + name: ":row.name", + content: ":tool.result", + }, + }, + }, + }, + }, + toolsMessage: { + agent: "pushAgent", + inputs: { + array: [":userInput.message", ":llm.message"], + items: ":tool_calls.message", + }, + }, + buffer: { + agent: "copyAgent", + anyInput: true, + inputs: { array: [":textMessage.messages", ":toolsMessage.array"] }, + }, + reducer: { + isResult: true, + agent: "pushAgent", + inputs: { array: ":messages", items: ":buffer.array.$0" }, + }, + }, +}; +const toolsAgent = (0, nested_agent_1.nestedAgentGenerator)(toolWorkFlowStep); +const toolsAgentInfo = { + name: "toolsAgent", + agent: toolsAgent, + mock: toolsAgent, + samples: [ + { + inputs: { + llmAgent: "openAIAgent", + tools: [ + { + type: "function", + function: { + name: "lightAgent--toggleLight", + description: "Switch of light", + parameters: { + type: "object", + properties: { + switch: { + type: "boolean", + description: "change light state", + }, + }, + }, + }, + }, + ], + messages: [ + { + role: "system", + content: "You are a light switch. Please follow the user's instructions.", + }, + ], + userInput: { + text: "turn on the light.", + message: { + role: "user", + content: "turn on the light.", + }, + }, + }, + params: {}, + result: "", + }, + ], + description: "", + category: [], + author: "", + repository: "", + tools: [], + license: "", + hasGraphData: true, +}; +exports.default = toolsAgentInfo; diff --git a/llm_agents/tools_agent/package.json b/llm_agents/tools_agent/package.json new file mode 100644 index 00000000..9261f849 --- /dev/null +++ b/llm_agents/tools_agent/package.json @@ -0,0 +1,36 @@ +{ + "name": "@graphai/tools_agent", + "version": "0.2.0", + "description": "General tools agents", + "main": "lib/index.js", + "files": [ + "./lib" + ], + "scripts": { + "build": "rm -r lib/* && tsc && tsc-alias", + "eslint": "eslint", + "format": "prettier --write '{src,tests,samples}/**/*.ts'", + "doc": "npx agentdoc", + "examplesDoc": "npx ts-node -r tsconfig-paths/register tests/examples.ts", + "test": "echo nothing", + "test_run": "node --test -r tsconfig-paths/register --require ts-node/register ./tests/run_*.ts # just run locally", + "chat": "node -r tsconfig-paths/register -r ts-node/register ./tests/chat_dispatch.ts", + "b": "yarn run format && yarn run eslint && yarn run build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/receptron/graphai" + }, + "author": "Satoshi Nakajima, Isamu Arimoto", + "license": "MIT", + "bugs": { + "url": "https://github.com/receptron/graphai/issues" + }, + "homepage": "https://github.com/receptron/graphai/blob/main/llm_agents/tools_agent/README.md", + "dependencies": {}, + "devDependencies": {}, + "types": "./lib/index.d.ts", + "directories": { + "lib": "lib" + } +} diff --git a/llm_agents/tools_agent/src/index.ts b/llm_agents/tools_agent/src/index.ts new file mode 100644 index 00000000..a0f829ac --- /dev/null +++ b/llm_agents/tools_agent/src/index.ts @@ -0,0 +1,3 @@ +import toolsAgent from "./tools_agent"; + +export { toolsAgent }; diff --git a/llm_agents/tools_agent/src/tools_agent.ts b/llm_agents/tools_agent/src/tools_agent.ts new file mode 100644 index 00000000..c111b32f --- /dev/null +++ b/llm_agents/tools_agent/src/tools_agent.ts @@ -0,0 +1,129 @@ +import { nestedAgentGenerator } from "@graphai/vanilla/lib/graph_agents/nested_agent"; + +const toolWorkFlowStep = { + version: 0.5, + nodes: { + llm: { + agent: ":llmAgent", + isResult: true, + params: { + forWeb: true, + stream: true, + tools: ":tools", + }, + inputs: { messages: ":messages", prompt: ":userInput.text" }, + }, + textMessage: { + unless: ":llm.tool.id", + agent: "copyAgent", + inputs: { + messages: [":userInput.message", { role: "assistant", content: ":llm.message.content" }], + }, + }, + tool_calls: { + if: ":llm.tool_calls", + agent: "mapAgent", + inputs: { rows: ":llm.tool_calls" }, + params: { + compositeResult: true, + }, + graph: { + version: 0.5, + nodes: { + tool: { + agent: ":row.name.split(--).$0", + inputs: { + arg: ":row.arguments", + func: ":row.name.split(--).$1", + tool_call: ":row", + }, + }, + message: { + isResult: true, + agent: "copyAgent", + inputs: { + role: "tool", + tool_call_id: ":row.id", + name: ":row.name", + content: ":tool.result", + }, + }, + }, + }, + }, + toolsMessage: { + agent: "pushAgent", + inputs: { + array: [":userInput.message", ":llm.message"], + items: ":tool_calls.message", + }, + }, + buffer: { + agent: "copyAgent", + anyInput: true, + inputs: { array: [":textMessage.messages", ":toolsMessage.array"] }, + }, + reducer: { + isResult: true, + agent: "pushAgent", + inputs: { array: ":messages", items: ":buffer.array.$0" }, + }, + }, +}; + +const toolsAgent = nestedAgentGenerator(toolWorkFlowStep); + +const toolsAgentInfo = { + name: "toolsAgent", + agent: toolsAgent, + mock: toolsAgent, + samples: [ + { + inputs: { + llmAgent: "openAIAgent", + tools: [ + { + type: "function", + function: { + name: "lightAgent--toggleLight", + description: "Switch of light", + parameters: { + type: "object", + properties: { + switch: { + type: "boolean", + description: "change light state", + }, + }, + }, + }, + }, + ], + messages: [ + { + role: "system", + content: "You are a light switch. Please follow the user's instructions.", + }, + ], + userInput: { + text: "turn on the light.", + message: { + role: "user", + content: "turn on the light.", + }, + }, + }, + params: {}, + result: "", + }, + ], + description: "", + category: [], + author: "", + repository: "", + tools: [], + license: "", + hasGraphData: true, +}; + +export default toolsAgentInfo; diff --git a/llm_agents/tools_agent/tests/run_tools.ts b/llm_agents/tools_agent/tests/run_tools.ts new file mode 100644 index 00000000..90881471 --- /dev/null +++ b/llm_agents/tools_agent/tests/run_tools.ts @@ -0,0 +1,40 @@ +import "dotenv/config"; +import { toolsAgent } from "@/index"; + +import { AgentFunction, AgentFunctionInfo, AgentFunctionInfoDictionary, defaultTestContext, agentInfoWrapper } from "graphai"; + +import * as vanilla_agents from "@graphai/vanilla"; +import { openAIAgent } from "@graphai/openai_agent"; + +const lightFunc: AgentFunction = async ({ namedInputs }) => { + const { arg, func } = namedInputs; + if (func === "toggleLight") { + if (arg.switch) { + console.log("Light is on!!"); + } else { + console.log("Light is on!!"); + } + } + return { result: "success" }; +}; + +const lightAgent = agentInfoWrapper(lightFunc); + +const main = async (agentInfo: AgentFunctionInfo) => { + const { agent, samples, inputs: inputSchema } = agentInfo; + for await (const sampleKey of samples.keys()) { + const { params, inputs, result, graph } = samples[sampleKey]; + const actual = await agent({ + ...defaultTestContext, + params, + inputSchema, + namedInputs: inputs, + forNestedGraph: { + agents: { ...vanilla_agents, openAIAgent, lightAgent }, + graphOptions: {}, + }, + }); + } +}; + +main(toolsAgent); diff --git a/llm_agents/tools_agent/tsconfig.json b/llm_agents/tools_agent/tsconfig.json new file mode 100644 index 00000000..07df466d --- /dev/null +++ b/llm_agents/tools_agent/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../config/tsconfig.base.json", + "compilerOptions": { + "baseUrl": "./", + "rootDir": "./src/", + "outDir": "./lib", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src"] +}