diff --git a/apps/cli/package.json b/apps/cli/package.json index 7891d18f..835a3766 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -15,8 +15,10 @@ "test:script": "ts-node ./src/__tests__/runners/script-js.ts" }, "dependencies": { - "@evo-ninja/evo-agent": "0.1.0", + "@evo-ninja/evo-agent": "~0.1.0", + "@evo-ninja/agent-debug": "~0.1.0", "@evo-ninja/agent-utils": "~0.1.0", + "@evo-ninja/agent-utils-fs": "~0.1.0", "forked-agent-protocol": "0.0.5", "chalk": "^4.1.2", "commander": "11.0.0", diff --git a/apps/cli/src/sys/AgentProtocolWorkspace.ts b/apps/cli/src/agent-protocol/AgentProtocolWorkspace.ts similarity index 100% rename from apps/cli/src/sys/AgentProtocolWorkspace.ts rename to apps/cli/src/agent-protocol/AgentProtocolWorkspace.ts diff --git a/apps/cli/src/agent-protocol/index.ts b/apps/cli/src/agent-protocol/index.ts new file mode 100644 index 00000000..f855e236 --- /dev/null +++ b/apps/cli/src/agent-protocol/index.ts @@ -0,0 +1 @@ +export * from "./AgentProtocolWorkspace"; diff --git a/apps/cli/src/api.ts b/apps/cli/src/api.ts index 3b3fc569..7cadbec9 100644 --- a/apps/cli/src/api.ts +++ b/apps/cli/src/api.ts @@ -1,4 +1,4 @@ -import { AgentProtocolWorkspace } from "./sys/AgentProtocolWorkspace"; +import { AgentProtocolWorkspace } from "./agent-protocol"; import { createApp } from "./app"; import Agent, { diff --git a/apps/cli/src/app.ts b/apps/cli/src/app.ts index e9e537fd..4d5659c3 100644 --- a/apps/cli/src/app.ts +++ b/apps/cli/src/app.ts @@ -1,6 +1,3 @@ -import { FileSystemWorkspace, FileLogger } from "./sys"; -import { DebugLog, DebugLlmApi } from "./diagnostic"; - import { Evo } from "@evo-ninja/evo-agent"; import { Env, @@ -14,6 +11,8 @@ import { LlmApi, ContextWindow, } from "@evo-ninja/agent-utils"; +import { DebugLog, DebugLlmApi } from "@evo-ninja/agent-debug"; +import { FileSystemWorkspace, FileLogger } from "@evo-ninja/agent-utils-fs"; import dotenv from "dotenv"; import readline from "readline"; import path from "path"; diff --git a/package.json b/package.json index 3a9af3fc..0c496f97 100644 --- a/package.json +++ b/package.json @@ -17,15 +17,18 @@ "start": "yarn workspace evo-ninja run start", "start:browser": "yarn workspace @evo-ninja/ui run start", "start:api": "yarn workspace evo-ninja run start:api", - "build": "yarn build:agent-utils && yarn build:agents && yarn build:cli && yarn build:browser", - "build:agent-utils": "yarn workspace @evo-ninja/agent-utils run build", - "build:agents": "yarn build:script-writer && yarn build:evo", + "build": "yarn build:agent-utils && yarn build:agent-debug && yarn build:agents && yarn build:cli && yarn build:browser", + "build:agent-utils": "yarn workspace @evo-ninja/agent-utils run build && yarn build:agent-utils-fs", + "build:agent-utils-fs": "yarn workspace @evo-ninja/agent-utils-fs run build", + "build:agent-debug": "yarn workspace @evo-ninja/agent-debug run build", + "build:agents": "yarn build:script-writer && yarn build:dev && yarn build:evo", "build:evo": "yarn workspace @evo-ninja/evo-agent run build", + "build:dev": "yarn workspace @evo-ninja/dev-agent run build", "build:script-writer": "yarn workspace @evo-ninja/js-script-writer-agent run build", "build:cli": "yarn workspace evo-ninja run build", "build:browser": "yarn workspace @evo-ninja/ui run build" }, "devDependencies": { - "rimraf": "5.0.1" + "rimraf": "~5.0.1" } } diff --git a/packages/agent-debug/package.json b/packages/agent-debug/package.json new file mode 100644 index 00000000..c396f60e --- /dev/null +++ b/packages/agent-debug/package.json @@ -0,0 +1,17 @@ +{ + "name": "@evo-ninja/agent-debug", + "version": "0.1.0", + "license": "MIT", + "main": "./build/index.js", + "scripts": { + "build": "rimraf build && tsc" + }, + "dependencies": { + "@evo-ninja/agent-utils": "~0.1.0" + }, + "devDependencies": { + "rimraf": "~5.0.1", + "ts-node": "10.9.1", + "typescript": "4.9.5" + } +} diff --git a/apps/cli/src/diagnostic/DebugLlmApi.ts b/packages/agent-debug/src/DebugLlmApi.ts similarity index 96% rename from apps/cli/src/diagnostic/DebugLlmApi.ts rename to packages/agent-debug/src/DebugLlmApi.ts index 54c8099b..db9f54cf 100644 --- a/apps/cli/src/diagnostic/DebugLlmApi.ts +++ b/packages/agent-debug/src/DebugLlmApi.ts @@ -22,8 +22,6 @@ export class DebugLlmApi implements LlmApi { functionDefinitions: any[], options?: LlmOptions | undefined ): Promise { - console.log(this.getModel()); - const time = new Timer(); time.start(); diff --git a/apps/cli/src/diagnostic/DebugLlmReq.ts b/packages/agent-debug/src/DebugLlmReq.ts similarity index 100% rename from apps/cli/src/diagnostic/DebugLlmReq.ts rename to packages/agent-debug/src/DebugLlmReq.ts diff --git a/apps/cli/src/diagnostic/DebugLog.ts b/packages/agent-debug/src/DebugLog.ts similarity index 100% rename from apps/cli/src/diagnostic/DebugLog.ts rename to packages/agent-debug/src/DebugLog.ts diff --git a/apps/cli/src/diagnostic/Timer.ts b/packages/agent-debug/src/Timer.ts similarity index 100% rename from apps/cli/src/diagnostic/Timer.ts rename to packages/agent-debug/src/Timer.ts diff --git a/apps/cli/src/diagnostic/index.ts b/packages/agent-debug/src/index.ts similarity index 100% rename from apps/cli/src/diagnostic/index.ts rename to packages/agent-debug/src/index.ts diff --git a/packages/agent-debug/tsconfig.json b/packages/agent-debug/tsconfig.json new file mode 100644 index 00000000..b4855d11 --- /dev/null +++ b/packages/agent-debug/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "build" + }, + "include": [ + "./src/**/*.ts" + ], + "exclude": [] +} \ No newline at end of file diff --git a/packages/agent-utils-fs/package.json b/packages/agent-utils-fs/package.json new file mode 100644 index 00000000..6fa26648 --- /dev/null +++ b/packages/agent-utils-fs/package.json @@ -0,0 +1,17 @@ +{ + "name": "@evo-ninja/agent-utils-fs", + "version": "0.1.0", + "license": "MIT", + "main": "./build/index.js", + "scripts": { + "build": "rimraf build && tsc" + }, + "dependencies": { + "@evo-ninja/agent-utils": "~0.1.0" + }, + "devDependencies": { + "rimraf": "~5.0.1", + "ts-node": "10.9.1", + "typescript": "4.9.5" + } +} diff --git a/apps/cli/src/sys/FileLogger.ts b/packages/agent-utils-fs/src/FileLogger.ts similarity index 100% rename from apps/cli/src/sys/FileLogger.ts rename to packages/agent-utils-fs/src/FileLogger.ts diff --git a/apps/cli/src/sys/FileSystemWorkspace.ts b/packages/agent-utils-fs/src/FileSystemWorkspace.ts similarity index 100% rename from apps/cli/src/sys/FileSystemWorkspace.ts rename to packages/agent-utils-fs/src/FileSystemWorkspace.ts diff --git a/apps/cli/src/sys/index.ts b/packages/agent-utils-fs/src/index.ts similarity index 100% rename from apps/cli/src/sys/index.ts rename to packages/agent-utils-fs/src/index.ts diff --git a/packages/agent-utils-fs/tsconfig.json b/packages/agent-utils-fs/tsconfig.json new file mode 100644 index 00000000..b4855d11 --- /dev/null +++ b/packages/agent-utils-fs/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "build" + }, + "include": [ + "./src/**/*.ts" + ], + "exclude": [] +} \ No newline at end of file diff --git a/packages/agent-utils/package.json b/packages/agent-utils/package.json index 1ffc1c81..19afc49e 100644 --- a/packages/agent-utils/package.json +++ b/packages/agent-utils/package.json @@ -10,6 +10,8 @@ "codegen:js-engine": "polywrap codegen -m ./src/scripts/js-engine/polywrap.yaml --codegen-dir ./src/scripts/js-engine/types" }, "dependencies": { + "@polywrap/client-js": "~0.12.0", + "@polywrap/plugin-js": "~0.12.0", "@polywrap/result": "~0.12.0", "axios": "^0.26.0", "figlet": "~1.6.0", diff --git a/packages/agent-utils/src/agent/basicFunctionCallLoop.ts b/packages/agent-utils/src/agent/basicFunctionCallLoop.ts index 4118db8f..4323cd8b 100644 --- a/packages/agent-utils/src/agent/basicFunctionCallLoop.ts +++ b/packages/agent-utils/src/agent/basicFunctionCallLoop.ts @@ -45,12 +45,12 @@ export async function* basicFunctionCallLoop chat.temporary(x)); + const terminate = functionCalled && shouldTerminate(functionCalled, result); + for (let i = 0; i < result.value.outputs.length; i++) { const output = result.value.outputs[i]; - if (i === result.value.outputs.length - 1 && - functionCalled && shouldTerminate(functionCalled, result) - ) { + if (i === result.value.outputs.length - 1 && terminate) { return ResultOk(output); } diff --git a/packages/evo/src/agent-plugin/index.ts b/packages/agent-utils/src/scripts/agent-plugin/index.ts similarity index 83% rename from packages/evo/src/agent-plugin/index.ts rename to packages/agent-utils/src/scripts/agent-plugin/index.ts index 44283141..802c444f 100644 --- a/packages/evo/src/agent-plugin/index.ts +++ b/packages/agent-utils/src/scripts/agent-plugin/index.ts @@ -4,11 +4,13 @@ import { Module, manifest } from "./types"; -import { AGENT_PLUGIN_SPEAK_RESPONSE } from "../prompts"; +import { Logger } from "../../"; -import { Logger } from "@evo-ninja/agent-utils"; import { PluginFactory, PluginPackage } from "@polywrap/plugin-js"; +export const AGENT_PLUGIN_SPEAK_RESPONSE = + "User has been informed! If you think you've achieved the goal, execute onGoalAchieved.\nIf you think you've failed, execute onGoalFailed."; + export interface AgentPluginConfig { logger: Logger; } diff --git a/packages/evo/src/agent-plugin/polywrap.graphql b/packages/agent-utils/src/scripts/agent-plugin/polywrap.graphql similarity index 100% rename from packages/evo/src/agent-plugin/polywrap.graphql rename to packages/agent-utils/src/scripts/agent-plugin/polywrap.graphql diff --git a/packages/evo/src/agent-plugin/polywrap.yaml b/packages/agent-utils/src/scripts/agent-plugin/polywrap.yaml similarity index 100% rename from packages/evo/src/agent-plugin/polywrap.yaml rename to packages/agent-utils/src/scripts/agent-plugin/polywrap.yaml diff --git a/packages/evo/src/agent-plugin/types/index.ts b/packages/agent-utils/src/scripts/agent-plugin/types/index.ts similarity index 100% rename from packages/evo/src/agent-plugin/types/index.ts rename to packages/agent-utils/src/scripts/agent-plugin/types/index.ts diff --git a/packages/evo/src/agent-plugin/types/module.ts b/packages/agent-utils/src/scripts/agent-plugin/types/module.ts similarity index 100% rename from packages/evo/src/agent-plugin/types/module.ts rename to packages/agent-utils/src/scripts/agent-plugin/types/module.ts diff --git a/packages/evo/src/agent-plugin/types/types.ts b/packages/agent-utils/src/scripts/agent-plugin/types/types.ts similarity index 100% rename from packages/evo/src/agent-plugin/types/types.ts rename to packages/agent-utils/src/scripts/agent-plugin/types/types.ts diff --git a/packages/evo/src/agent-plugin/types/wrap.info.ts b/packages/agent-utils/src/scripts/agent-plugin/types/wrap.info.ts similarity index 100% rename from packages/evo/src/agent-plugin/types/wrap.info.ts rename to packages/agent-utils/src/scripts/agent-plugin/types/wrap.info.ts diff --git a/packages/agent-utils/src/scripts/index.ts b/packages/agent-utils/src/scripts/index.ts index 1c25a053..da76ce5d 100644 --- a/packages/agent-utils/src/scripts/index.ts +++ b/packages/agent-utils/src/scripts/index.ts @@ -1,2 +1,4 @@ +export * from "./agent-plugin"; export * from "./js-engine"; +export * from "./wrap-client"; export * from "./Scripts"; diff --git a/packages/evo/src/wrap/WrapClient.ts b/packages/agent-utils/src/scripts/wrap-client/WrapClient.ts similarity index 98% rename from packages/evo/src/wrap/WrapClient.ts rename to packages/agent-utils/src/scripts/wrap-client/WrapClient.ts index 1fa03e8f..3727738e 100644 --- a/packages/evo/src/wrap/WrapClient.ts +++ b/packages/agent-utils/src/scripts/wrap-client/WrapClient.ts @@ -1,3 +1,5 @@ +import { Env, Logger, Workspace } from "../../"; + import { PolywrapClient, PolywrapClientConfigBuilder, @@ -6,13 +8,11 @@ import { IWrapPackage, Result } from "@polywrap/client-js"; -import { PluginPackage } from "@polywrap/plugin-js"; -import axios from "axios"; - import { InvokerOptions } from "@polywrap/client-js/build/types"; +import { PluginPackage } from "@polywrap/plugin-js"; import { ResultErr, ResultOk } from "@polywrap/result"; -import { Env, Logger, Workspace } from "@evo-ninja/agent-utils"; import * as path from "path-browserify" +import axios from "axios"; export class WrapClient extends PolywrapClient { @@ -21,8 +21,8 @@ export class WrapClient extends PolywrapClient { constructor( workspace: Workspace, logger: Logger, - agentPlugin: IWrapPackage | undefined = undefined, - env: Env + agentPlugin?: IWrapPackage, + env?: Env ) { const builder = new PolywrapClientConfigBuilder() .addBundle("web3") @@ -185,7 +185,7 @@ export class WrapClient extends PolywrapClient { "search": async (args: { query: string }) => { const axiosClient = axios.create({ baseURL: 'https://api.search.brave.com/res/v1/web' }); - const apiKey = env.BRAVE_API_KEY + const apiKey = env?.BRAVE_API_KEY if (!apiKey) { throw new Error('BRAVE_API_KEY environment variable is required to use the websearch plugin. See env.template for help') diff --git a/packages/evo/src/wrap/index.ts b/packages/agent-utils/src/scripts/wrap-client/index.ts similarity index 100% rename from packages/evo/src/wrap/index.ts rename to packages/agent-utils/src/scripts/wrap-client/index.ts diff --git a/packages/dev/.gitignore b/packages/dev/.gitignore new file mode 100644 index 00000000..d6104217 --- /dev/null +++ b/packages/dev/.gitignore @@ -0,0 +1 @@ +src/__tests__/test-cases/ \ No newline at end of file diff --git a/packages/dev/package.json b/packages/dev/package.json new file mode 100644 index 00000000..ca651d54 --- /dev/null +++ b/packages/dev/package.json @@ -0,0 +1,25 @@ +{ + "name": "@evo-ninja/dev-agent", + "version": "0.1.0", + "license": "MIT", + "main": "./build/index.js", + "scripts": { + "build": "rimraf build && tsc", + "test": "jest --runInBand --verbose --rootDir . --config ../../jest.config.js" + }, + "dependencies": { + "@polywrap/result": "~0.12.0", + "@evo-ninja/agent-utils": "~0.1.0" + }, + "devDependencies": { + "@types/jest": "29.5.0", + "@evo-ninja/agent-debug": "~0.1.0", + "@evo-ninja/agent-utils-fs": "~0.1.0", + "gpt-tokenizer": "~2.1.1", + "jest": "29.5.0", + "rimraf": "~5.0.1", + "ts-jest": "29.1.1", + "ts-node": "10.9.1", + "typescript": "4.9.5" + } +} diff --git a/packages/dev/src/AgentContext.ts b/packages/dev/src/AgentContext.ts new file mode 100644 index 00000000..314b8e4e --- /dev/null +++ b/packages/dev/src/AgentContext.ts @@ -0,0 +1,15 @@ +import { + Chat, + LlmApi, + Scripts, + WrapClient, + Workspace +} from "@evo-ninja/agent-utils"; + +export interface AgentContext { + llm: LlmApi; + chat: Chat; + workspace: Workspace; + scripts: Scripts; + client: WrapClient; +} diff --git a/packages/dev/src/DevAgent.ts b/packages/dev/src/DevAgent.ts new file mode 100644 index 00000000..aed39dab --- /dev/null +++ b/packages/dev/src/DevAgent.ts @@ -0,0 +1,73 @@ +import { AgentContext } from "./AgentContext"; +import { agentFunctions } from "./agent-functions"; +import { INITIAL_PROMP, GOAL_PROMPT, LOOP_PREVENTION_PROMPT } from "./prompts"; + +import { + Agent, + AgentOutput, + Chat, + RunResult, + LlmApi, + Scripts, + Logger, + Workspace, + WrapClient, + agentPlugin, + basicFunctionCallLoop, + ExecuteAgentFunctionCalled +} from "@evo-ninja/agent-utils"; +import { ResultErr } from "@polywrap/result"; + +export class DevAgent implements Agent { + private readonly context: AgentContext; + + constructor( + llm: LlmApi, + chat: Chat, + workspace: Workspace, + scripts: Scripts, + private readonly logger: Logger + ) { + this.context = { + llm, + chat, + scripts, + workspace, + client: new WrapClient( + workspace, + this.logger, + agentPlugin({ logger: this.logger }) + ), + }; + } + + public get workspace(): Workspace { + return this.context.workspace; + } + + public async* run( + goal: string + ): AsyncGenerator { + const { chat } = this.context; + try { + chat.persistent("system", INITIAL_PROMP()); + chat.persistent("user", GOAL_PROMPT(goal)); + + return yield* basicFunctionCallLoop( + this.context, + agentFunctions, + (functionCalled: ExecuteAgentFunctionCalled) => { + const terminationFunctions = [ + "agent_onGoalAchieved", + "agent_onGoalFailed" + ]; + return terminationFunctions.includes(functionCalled.name); + }, + LOOP_PREVENTION_PROMPT + ); + } catch (err) { + this.logger.error(err); + return ResultErr("Unrecoverable error encountered."); + } + } +} diff --git a/packages/dev/src/__tests__/dev-agent.spec.ts b/packages/dev/src/__tests__/dev-agent.spec.ts new file mode 100644 index 00000000..41bbc533 --- /dev/null +++ b/packages/dev/src/__tests__/dev-agent.spec.ts @@ -0,0 +1,141 @@ +import { DevAgent } from "../DevAgent"; + +import { + Env, + Scripts, + OpenAI, + Chat, + ContextWindow, + LlmApi, + ConsoleLogger, + Logger +} from "@evo-ninja/agent-utils"; +import { FileSystemWorkspace } from "@evo-ninja/agent-utils-fs"; +import { DebugLog, DebugLlmApi } from "@evo-ninja/agent-debug"; +import * as rimraf from "rimraf"; +import dotenv from "dotenv"; +import path from "path"; +import cl100k_base from "gpt-tokenizer/cjs/encoding/cl100k_base"; + +dotenv.config({ + path: path.join(__dirname, "../../../../.env") +}); + +jest.setTimeout(120000); + +describe('Dev Agent Test Suite', () => { + + function createDevAgent(testName: string): { + agent: DevAgent; + debugLog: DebugLog; + } { + const testCaseDir = path.join(__dirname, "test-cases", testName); + + // reset the dir + rimraf.sync(testCaseDir); + + const env = new Env(process.env as Record); + const logger = new Logger([new ConsoleLogger()], { + promptUser: () => { + throw Error("promptUser not supported."); + }, + logUserPrompt: () => { + throw Error("logUserPrompt not supported."); + } + }); + + const llm: LlmApi = new OpenAI( + env.OPENAI_API_KEY, + env.GPT_MODEL, + env.CONTEXT_WINDOW_TOKENS, + env.MAX_RESPONSE_TOKENS, + logger + ); + + const debugLog = new DebugLog( + new FileSystemWorkspace(path.join(testCaseDir, "./debug")) + ); + const debugLlm = new DebugLlmApi(debugLog, llm); + + const contextWindow = new ContextWindow(llm); + const chat = new Chat(cl100k_base, contextWindow, logger); + + const scriptsDir = path.join(__dirname, "../../../../scripts"); + const scriptsWorkspace = new FileSystemWorkspace( + scriptsDir + ); + const scripts = new Scripts(scriptsWorkspace, "./"); + + const workspace = new FileSystemWorkspace(testCaseDir); + + return { + agent: new DevAgent( + debugLlm, + chat, + workspace, + scripts, + logger + ), + debugLog + }; + } + + async function runDevAgent(agent: DevAgent, goal: string, debugLog: DebugLog) { + debugLog.goalStart(goal); + const iterator = agent.run(goal); + + while (true) { + debugLog.stepStart(); + const response = await iterator.next(); + debugLog.stepEnd(); + + if (response.done) { + if (!response.value.ok) { + debugLog.stepError(response.value.error ?? "Unknown error"); + } else { + debugLog.stepLog(JSON.stringify(response.value.value)); + } + return response; + } + } + } + + test("tic-tac-toe", async () => { + const { agent, debugLog } = createDevAgent("tic-tac-toe"); + const response = await runDevAgent( + agent, + "Build a Tic-Tac-Toe game using a python CLI. Here are the specifications.\n\nThe Grid: The game board is a 3x3 grid, consisting of 3 rows and 3 columns, creating a total of 9 squares.\n\nPlayers: There are two players. One player uses the number \"1\", and the other player uses the number \"2\".\n\nTaking Turns: Players take turns to put their respective numbers (\"1\" or \"2\") in an empty square of the grid. Once a player has placed their number in a square, it cannot be changed or removed.\n\nObjective: The goal is to get three of your numbers in a row, either horizontally, vertically, or diagonally.\n\nEnd of the Game: The game concludes in one of two ways: One player gets three of their numbers in a row (horizontally, vertically, or diagonally) and is declared the winner.\nAll squares on the grid are filled, and no player has three in a row. This situation is a \"draw\" or a \"tie\".\n\nTechnical specifications:\nBuild a file called tic_tac_toe.py. This file will be called through command lines. You will have to prompt users for their move. Player 1 will always start.\nPlayers will input their move in the following format: \"x,y\" where x and y represent the location in the grid (0,0 is top left, 2,2 is bottom right).\n\nYour primary requirement is to halt the game when appropriate and to print only one of these three exact sentences:\n\n\"Player 1 won!\"\n\"Player 2 won!\"\n\"Draw\"\n\nEdge cases: A player can send an incorrect location. Either the location is incorrect or the square is already filled. In this case, this counts as doing nothing, and the player gets prompted for new locations again.\n\n\nYou will be expected to create a python file called tic_tac_toe.py that will run through command lines by using ```python tic_tac_toe.py```.\n\nHere is an example of how your tic_tac_toe.py game will be tested.\n```\nprocess = subprocess.Popen(\n ['python', 'tic_tac_toe.py'],\n stdout=subprocess.PIPE,\n text=True\n)\n\noutput, _ = process.communicate('\\n'.join([\"0,0\", \"1,0\", \"0,1\", \"1,1\", \"0,2\"]))\n\nassert \"Player 1 won!\" in output\n```", + debugLog + ); + + expect(response.value.ok).toBe(true); + const sourceCode = agent.workspace.readFileSync("tic_tac_toe.py"); + expect(sourceCode).toBeTruthy(); + }); + + test("three-sum", async () => { + const { agent, debugLog } = createDevAgent("three-sum"); + const response = await runDevAgent( + agent, + "Create a three_sum function in a file called sample_code.py. Given an array of integers, return indices of the three numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the same element twice. Example: Given nums = [2, 7, 11, 15], target = 20, Because nums[0] + nums[1] + nums[2] = 2 + 7 + 11 = 20, return [0, 1, 2].", + debugLog + ); + + expect(response.value.ok).toBe(true); + const sourceCode = agent.workspace.readFileSync("sample_code.py"); + expect(sourceCode).toBeTruthy(); + }); + + test("file-organizer", async () => { + const { agent, debugLog } = createDevAgent("file-organizer"); + const response = await runDevAgent( + agent, + "Create a file organizer CLI tool in Python that sorts files in a directory based on their file types (e.g., images, documents, audio) and moves them into these corresponding folders: 'images', 'documents', 'audio'. The entry point will be a python file that can be run this way: python organize_files.py --directory_path=YOUR_DIRECTORY_PATH", + debugLog + ); + + expect(response.value.ok).toBe(true); + const sourceCode = agent.workspace.readFileSync("organize_files.py"); + expect(sourceCode).toBeTruthy(); + }); +}); diff --git a/packages/dev/src/agent-functions/agent_onGoalAchieved.ts b/packages/dev/src/agent-functions/agent_onGoalAchieved.ts new file mode 100644 index 00000000..baab419d --- /dev/null +++ b/packages/dev/src/agent-functions/agent_onGoalAchieved.ts @@ -0,0 +1,39 @@ +import { createScriptExecutor } from "./util"; +import { AgentContext } from "../AgentContext"; + +import { + AgentFunction, + AgentFunctionResult, + AgentOutputType +} from "@evo-ninja/agent-utils"; + +const FN_NAME = "agent_onGoalAchieved"; + +const SUCCESS = (): AgentFunctionResult => ({ + outputs: [ + { + type: AgentOutputType.Success, + title: "[dev] agent_onGoalAchieved" + } + ], + messages: [] +}); + +export const agent_onGoalAchieved: AgentFunction = { + definition: { + name: FN_NAME, + description: "Informs the user that the goal has been achieved.", + parameters: { + type: "object", + properties: { }, + } + }, + buildExecutor(context: AgentContext) { + return createScriptExecutor( + context.scripts, + context.client, + "agent.onGoalAchieved", + () => SUCCESS() + ); + } +}; diff --git a/packages/dev/src/agent-functions/agent_onGoalFailed.ts b/packages/dev/src/agent-functions/agent_onGoalFailed.ts new file mode 100644 index 00000000..3a951870 --- /dev/null +++ b/packages/dev/src/agent-functions/agent_onGoalFailed.ts @@ -0,0 +1,39 @@ +import { createScriptExecutor } from "./util"; +import { AgentContext } from "../AgentContext"; + +import { + AgentFunction, + AgentFunctionResult, + AgentOutputType +} from "@evo-ninja/agent-utils"; + +const FN_NAME = "agent_onGoalFailed"; + +const SUCCESS = (): AgentFunctionResult => ({ + outputs: [ + { + type: AgentOutputType.Error, + title: "[dev] agent_onGoalFailed" + } + ], + messages: [] +}); + +export const agent_onGoalFailed: AgentFunction = { + definition: { + name: FN_NAME, + description: "Informs the user that the agent could not achieve the goal.", + parameters: { + type: "object", + properties: { }, + } + }, + buildExecutor(context: AgentContext) { + return createScriptExecutor( + context.scripts, + context.client, + "agent.onGoalFailed", + () => SUCCESS() + ); + } +}; diff --git a/packages/dev/src/agent-functions/fs_writeFile.ts b/packages/dev/src/agent-functions/fs_writeFile.ts new file mode 100644 index 00000000..a3053cde --- /dev/null +++ b/packages/dev/src/agent-functions/fs_writeFile.ts @@ -0,0 +1,64 @@ +import { createScriptExecutor } from "./util"; +import { AgentContext } from "../AgentContext"; + +import { + AgentFunction, + AgentFunctionResult, + AgentOutputType, + ChatMessageBuilder, + trimText, +} from "@evo-ninja/agent-utils"; + +const FN_NAME = "fs_writeFile"; + +type FuncParameters = { + path: string; + data: string; + encoding: string; +}; + +const SUCCESS = (params: FuncParameters): AgentFunctionResult => ({ + outputs: [ + { + type: AgentOutputType.Success, + title: "[dev] fs_writeFile", + content: `${params.path}\n` + + `${params.encoding}\n` + + `${trimText(params.data, 200)}` + } + ], + messages: [ + ChatMessageBuilder.functionCall(FN_NAME, params), + ] +}); + +export const fs_writeFile: AgentFunction = { + definition: { + name: FN_NAME, + description: "Writes data to a file, replacing the file if it already exists.", + parameters: { + type: "object", + properties: { + path: { + type: "string", + }, + data: { + type: "string" + }, + encoding: { + type: "string" + }, + }, + required: ["path", "data", "encoding"], + additionalProperties: false + }, + }, + buildExecutor(context: AgentContext) { + return createScriptExecutor( + context.scripts, + context.client, + "fs.writeFile", + (params) => SUCCESS(params) + ); + } +}; diff --git a/packages/dev/src/agent-functions/index.ts b/packages/dev/src/agent-functions/index.ts new file mode 100644 index 00000000..01a22992 --- /dev/null +++ b/packages/dev/src/agent-functions/index.ts @@ -0,0 +1,11 @@ +import { AgentFunction } from "@evo-ninja/agent-utils"; +import { AgentContext } from "../AgentContext"; +import { fs_writeFile } from "./fs_writeFile"; +import { agent_onGoalAchieved } from "./agent_onGoalAchieved"; +import { agent_onGoalFailed } from "./agent_onGoalFailed"; + +export const agentFunctions: AgentFunction[] = [ + fs_writeFile, + agent_onGoalAchieved, + agent_onGoalFailed +]; diff --git a/packages/dev/src/agent-functions/util.ts b/packages/dev/src/agent-functions/util.ts new file mode 100644 index 00000000..23abd2ba --- /dev/null +++ b/packages/dev/src/agent-functions/util.ts @@ -0,0 +1,42 @@ +import { + AgentFunctionResult, + JsEngine, + JsEngine_GlobalVar, + shimCode, + Scripts, + WrapClient +} from "@evo-ninja/agent-utils"; +import { Result, ResultOk, ResultErr } from "@polywrap/result"; + +export function createScriptExecutor( + scripts: Scripts, + client: WrapClient, + scriptName: string, + onSuccess: (params: any) => AgentFunctionResult +) { + return async (params: any): Promise> => { + const script = scripts.getScriptByName(scriptName); + + if (!script) { + return ResultErr(`Unable to find the script ${scriptName}`); + } + + const globals: JsEngine_GlobalVar[] = Object.entries(params).map( + (entry) => ({ + name: entry[0], + value: JSON.stringify(entry[1]) + }) + ); + const jsEngine = new JsEngine(client); + const result = await jsEngine.evalWithGlobals({ + src: shimCode(script.code), + globals + }); + + if (!result.ok) { + return ResultErr(result.error?.toString()); + } + + return ResultOk(onSuccess(params)); + }; +} diff --git a/packages/dev/src/index.ts b/packages/dev/src/index.ts new file mode 100644 index 00000000..8c3ef635 --- /dev/null +++ b/packages/dev/src/index.ts @@ -0,0 +1 @@ +export * from "./DevAgent"; \ No newline at end of file diff --git a/packages/dev/src/prompts.ts b/packages/dev/src/prompts.ts new file mode 100644 index 00000000..590eb1e2 --- /dev/null +++ b/packages/dev/src/prompts.ts @@ -0,0 +1,8 @@ +export const INITIAL_PROMP = () => + `You are an expert software engineer named "dev".`; + +export const GOAL_PROMPT = (goal: string) => + `You have been asked by the user to achieve the following goal: ${goal}`; + +export const LOOP_PREVENTION_PROMPT = + "Assistant, you appear to be in a loop, try executing a different function."; diff --git a/packages/dev/tsconfig.json b/packages/dev/tsconfig.json new file mode 100644 index 00000000..b4855d11 --- /dev/null +++ b/packages/dev/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "build" + }, + "include": [ + "./src/**/*.ts" + ], + "exclude": [] +} \ No newline at end of file diff --git a/packages/evo/src/AgentContext.ts b/packages/evo/src/AgentContext.ts index 1b0dabc9..a20c8a70 100644 --- a/packages/evo/src/AgentContext.ts +++ b/packages/evo/src/AgentContext.ts @@ -1,5 +1,4 @@ -import { Workspace, LlmApi, Scripts, Chat, Logger } from "@evo-ninja/agent-utils"; -import { WrapClient } from "./wrap"; +import { Workspace, WrapClient, LlmApi, Scripts, Chat, Logger } from "@evo-ninja/agent-utils"; export interface AgentContext { globals: Record; diff --git a/packages/evo/src/Evo.ts b/packages/evo/src/Evo.ts index e1409f9b..50f21f0d 100644 --- a/packages/evo/src/Evo.ts +++ b/packages/evo/src/Evo.ts @@ -1,7 +1,5 @@ import { agentFunctions } from "./agent-functions"; -import { agentPlugin } from "./agent-plugin"; import { AgentContext } from "./AgentContext"; -import { WrapClient } from "./wrap"; import { INITIAL_PROMP, LOOP_PREVENTION_PROMPT @@ -20,6 +18,8 @@ import { InMemoryWorkspace, basicFunctionCallLoop, ContextWindow, + WrapClient, + agentPlugin, Env } from "@evo-ninja/agent-utils"; import { ScriptWriter } from "@evo-ninja/js-script-writer-agent"; diff --git a/packages/evo/src/index.ts b/packages/evo/src/index.ts index 2788af69..d45cf669 100644 --- a/packages/evo/src/index.ts +++ b/packages/evo/src/index.ts @@ -1,2 +1 @@ export * from "./Evo"; -export * from "./wrap"; diff --git a/packages/evo/src/prompts.ts b/packages/evo/src/prompts.ts index 92a5942a..4cb1a1b0 100644 --- a/packages/evo/src/prompts.ts +++ b/packages/evo/src/prompts.ts @@ -32,6 +32,3 @@ export const FUNCTION_CALL_FAILED = (params: any, name: string, error: string) = ? trimText(error, 300) : trimText(JSON.stringify(error, null, 2), 300) }\n\`\`\`\n\nArguments:\n\`\`\`\n${JSON.stringify(params, null, 2)}\n\`\`\``; - -export const AGENT_PLUGIN_SPEAK_RESPONSE = - "User has been informed! If you think you've achieved the goal, execute onGoalAchieved.\nIf you think you've failed, execute onGoalFailed."; diff --git a/tsconfig.json b/tsconfig.json index bc04436e..d971478a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,7 +21,7 @@ "noUnusedLocals": true, "module": "commonjs", "sourceMap": true, - "target": "es5", + "target": "es2015", "resolveJsonModule": true, "strictNullChecks": true } diff --git a/yarn.lock b/yarn.lock index 5993d981..b13d262e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1301,9 +1301,9 @@ eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.9.0.tgz#7ccb5f58703fa61ffdcbf39e2c604a109e781162" - integrity sha512-zJmuCWj2VLBt4c25CfBIbMZLGLyhkvs7LznyVX5HfpzeocThgIj5XQK4L+g3U36mMcx8bPMhGyPpwCATamC4jQ== + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.9.1.tgz#449dfa81a57a1d755b09aa58d826c1262e4283b4" + integrity sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA== "@eslint/eslintrc@^2.1.2": version "2.1.2" @@ -2715,9 +2715,9 @@ picomatch "^2.3.1" "@rushstack/eslint-patch@^1.1.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.5.0.tgz#5143b0da9c536bfe8beddfeb68bb8b5d647cc7a3" - integrity sha512-EF3948ckf3f5uPgYbQ6GhyA56Dmv8yg0+ir+BroRjwdxyZJsekhZzawOecC2rOTPCz173t7ZcR1HHZu0dZgOCw== + version "1.5.1" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz#5f1b518ec5fa54437c0b7c4a821546c64fed6922" + integrity sha512-6i/8UoL0P5y4leBIGzvkZdS85RDMG9y1ihZzmTZQ5LdHUYmZ7pKFoj8X0236s3lusPs1Fa5HTQUpwI+UfTcmeA== "@sinclair/typebox@^0.24.1": version "0.24.51" @@ -3132,9 +3132,9 @@ "@types/express" "*" "@types/node@*": - version "20.7.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.7.1.tgz#06d732ead0bd5ad978ef0ea9cbdeb24dc8717514" - integrity sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg== + version "20.8.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.2.tgz#d76fb80d87d0d8abfe334fc6d292e83e5524efc4" + integrity sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w== "@types/parse-json@^4.0.0": version "4.0.0" @@ -3147,9 +3147,9 @@ integrity sha512-XMCcyhSvxcch8b7rZAtFAaierBYdeHXVvg2iYnxOV0MCQHmPuRRmGZPFDRzPayxcGiiSL1Te9UIO+f3cuj0tfw== "@types/prop-types@*", "@types/prop-types@^15.0.0": - version "15.7.7" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.7.tgz#f9361f7b87fd5d8188b2c998db0a1f47e9fb391a" - integrity sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog== + version "15.7.8" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.8.tgz#805eae6e8f41bd19e88917d2ea200dc992f405d3" + integrity sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ== "@types/q@^1.5.1": version "1.5.6" @@ -3181,9 +3181,9 @@ "@types/react" "*" "@types/react@*", "@types/react@^18.2.20": - version "18.2.23" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.23.tgz#60ad6cf4895e93bed858db0e03bcc4ff97d0410e" - integrity sha512-qHLW6n1q2+7KyBEYnrZpcsAmU/iiCh9WGCKgXvMxx89+TYdJWRjZohVIo9XTcoLhfX3+/hP0Pbulu3bCZQ9PSA== + version "18.2.24" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.24.tgz#3c7d68c02e0205a472f04abe4a0c1df35d995c05" + integrity sha512-Ee0Jt4sbJxMu1iDcetZEIKQr99J1Zfb6D4F3qfUWoR1JpInkY1Wdg4WwCyBjL257D0+jGqSl1twBjV8iCaC0Aw== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -3287,9 +3287,9 @@ "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.25" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.25.tgz#3edd102803c97356fb4c805b2bbaf7dfc9ab6abc" - integrity sha512-gy7iPgwnzNvxgAEi2bXOHWCVOG6f7xsprVJH4MjlAWeBmJ7vh/Y1kwMtUrs64ztf24zVIRCpr3n/z6gm9QIkgg== + version "17.0.26" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.26.tgz#388e5002a8b284ad7b4599ba89920a6d74d8d79a" + integrity sha512-Y3vDy2X6zw/ZCumcwLpdhM5L7jmyGpmBCTYMHDLqT2IKVMYRRLdv6ZakA+wxhra6Z/3bwhNbNl9bDGXaFU+6rw== dependencies: "@types/yargs-parser" "*" @@ -4197,7 +4197,7 @@ brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.9: +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.9, browserslist@^4.22.1: version "4.22.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== @@ -4321,9 +4321,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001541: - version "1.0.30001541" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001541.tgz#b1aef0fadd87fb72db4dcb55d220eae17b81cdb1" - integrity sha512-bLOsqxDgTqUBkzxbNlSBt8annkDpQB9NdzdTbO2ooJ+eC/IQcvDspDc058g84ejCelF7vHUx57KIOjEecOHXaw== + version "1.0.30001543" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001543.tgz#478a3e9dddbb353c5ab214b0ecb0dbed529ed1d8" + integrity sha512-qxdO8KPWPQ+Zk6bvNpPeQIOH47qZSYdFZd6dXQzb2KzhnSXju4Kd7H1PkSJx6NICSMgo/IhRZRhhfPTHYpJUCA== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -4676,21 +4676,21 @@ copyfiles@2.4.1: yargs "^16.1.0" core-js-compat@^3.31.0, core-js-compat@^3.32.2: - version "3.32.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.2.tgz#8047d1a8b3ac4e639f0d4f66d4431aa3b16e004c" - integrity sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ== + version "3.33.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.0.tgz#24aa230b228406450b2277b7c8bfebae932df966" + integrity sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw== dependencies: - browserslist "^4.21.10" + browserslist "^4.22.1" core-js-pure@^3.23.3: - version "3.32.2" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.32.2.tgz#b7dbdac528625cf87eb0523b532eb61551b9a6d1" - integrity sha512-Y2rxThOuNywTjnX/PgA5vWM6CZ9QB9sz9oGeCixV8MqXZO70z/5SHzf9EeBrEBK0PN36DnEBBu9O/aGWzKuMZQ== + version "3.33.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.0.tgz#938a28754b4d82017a7a8cbd2727b1abecc63591" + integrity sha512-FKSIDtJnds/YFIEaZ4HszRX7hkxGpNKM7FC9aJ9WLJbSd3lD4vOltFuVIBLR8asSx9frkTSqL0dw90SKQxgKrg== core-js@^3.19.2: - version "3.32.2" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.32.2.tgz#172fb5949ef468f93b4be7841af6ab1f21992db7" - integrity sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ== + version "3.33.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.0.tgz#70366dbf737134761edb017990cf5ce6c6369c40" + integrity sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw== core-util-is@~1.0.0: version "1.0.3" @@ -5214,9 +5214,9 @@ ejs@^3.1.6: jake "^10.8.5" electron-to-chromium@^1.4.535: - version "1.4.535" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.535.tgz#f14765820a0aa31425e1dbbae917cc70872b2a53" - integrity sha512-4548PpR4S5X5dlvX8NUIw0njH7btQtBoJWcgzpq7n2F9NQ5gMXOPP/6p6iVx6+YT3FVioNhEGa14WJj1k+2SfA== + version "1.4.539" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.539.tgz#5ce6b161e252132cc84501bc35d084995a2a9840" + integrity sha512-wRmWJ8F7rgmINuI32S6r2SLrw/h/bJQsDSvBiq9GBfvc2Lh73qTOwn73r3Cf67mjVgFGJYcYtmERzySa5jIWlg== elliptic@6.5.4: version "6.5.4" @@ -6278,7 +6278,7 @@ glob@7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^10.2.5, glob@^10.3.7: +glob@^10.3.7: version "10.3.10" resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== @@ -8386,9 +8386,9 @@ minimist@^1.2.0, minimist@^1.2.6: integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "7.0.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.3.tgz#05ea638da44e475037ed94d1c7efcc76a25e1974" - integrity sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg== + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== mkdirp@^0.5.4, mkdirp@~0.5.1: version "0.5.6" @@ -9558,9 +9558,9 @@ postcss@^7.0.35: source-map "^0.6.1" postcss@^8.3.5, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.4: - version "8.4.30" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.30.tgz#0e0648d551a606ef2192a26da4cabafcc09c1aa7" - integrity sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g== + version "8.4.31" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" + integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== dependencies: nanoid "^3.3.6" picocolors "^1.0.0" @@ -10197,13 +10197,6 @@ rimraf@3.0.2, rimraf@^3.0.2: dependencies: glob "^7.1.3" -rimraf@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.1.tgz#0881323ab94ad45fec7c0221f27ea1a142f3f0d0" - integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== - dependencies: - glob "^10.2.5" - rimraf@~5.0.1: version "5.0.5" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.5.tgz#9be65d2d6e683447d2e9013da2bf451139a61ccf" @@ -10959,9 +10952,9 @@ terser-webpack-plugin@^5.2.5, terser-webpack-plugin@^5.3.7: terser "^5.16.8" terser@^5.0.0, terser@^5.10.0, terser@^5.16.8: - version "5.20.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.20.0.tgz#ea42aea62578703e33def47d5c5b93c49772423e" - integrity sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ== + version "5.21.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.21.0.tgz#d2b27e92b5e56650bc83b6defa00a110f0b124b2" + integrity sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2"