From 23321d67643ae2a7fa9219a2467ab31e2ed4ff2b Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 2 Oct 2023 16:54:54 +0200 Subject: [PATCH 1/6] chore: init dev-agent --- package.json | 3 +- packages/dev/package.json | 22 +++++++ packages/dev/src/AgentContext.ts | 11 ++++ packages/dev/src/DevAgent.ts | 60 +++++++++++++++++++ packages/dev/src/agent-functions/index.ts | 7 +++ packages/dev/src/agent-functions/writeFile.ts | 55 +++++++++++++++++ packages/dev/src/index.ts | 1 + packages/dev/src/prompts.ts | 10 ++++ packages/dev/tsconfig.json | 10 ++++ 9 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 packages/dev/package.json create mode 100644 packages/dev/src/AgentContext.ts create mode 100644 packages/dev/src/DevAgent.ts create mode 100644 packages/dev/src/agent-functions/index.ts create mode 100644 packages/dev/src/agent-functions/writeFile.ts create mode 100644 packages/dev/src/index.ts create mode 100644 packages/dev/src/prompts.ts create mode 100644 packages/dev/tsconfig.json diff --git a/package.json b/package.json index 3a9af3fc..a0c29e41 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,9 @@ "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: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" diff --git a/packages/dev/package.json b/packages/dev/package.json new file mode 100644 index 00000000..82c3aa83 --- /dev/null +++ b/packages/dev/package.json @@ -0,0 +1,22 @@ +{ + "name": "@evo-ninja/dev-agent", + "version": "0.1.0", + "license": "MIT", + "main": "./build/index.js", + "scripts": { + "build": "rimraf build && tsc" + }, + "dependencies": { + "@polywrap/result": "~0.12.0", + "@evo-ninja/agent-utils": "~0.1.0", + "openai": "~3.3.0" + }, + "devDependencies": { + "@types/jest": "29.5.0", + "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..ccf6a788 --- /dev/null +++ b/packages/dev/src/AgentContext.ts @@ -0,0 +1,11 @@ +import { + Chat, + LlmApi, + Scripts +} from "@evo-ninja/agent-utils"; + +export interface AgentContext { + llm: LlmApi; + chat: Chat; + scripts: Scripts; +} diff --git a/packages/dev/src/DevAgent.ts b/packages/dev/src/DevAgent.ts new file mode 100644 index 00000000..ae138640 --- /dev/null +++ b/packages/dev/src/DevAgent.ts @@ -0,0 +1,60 @@ +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, + basicFunctionCallLoop, + executeAgentFunction +} from "@evo-ninja/agent-utils"; +import { ResultErr } from "@polywrap/result"; + +export class DevAgent implements Agent { + private readonly context: AgentContext; + + constructor( + llm: LlmApi, + chat: Chat, + scripts: Scripts, + private readonly logger: Logger + ) { + this.context = { + llm, + chat, + scripts + }; + } + + 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, + executeAgentFunction, + agentFunctions, + (functionCalled) => { + 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/agent-functions/index.ts b/packages/dev/src/agent-functions/index.ts new file mode 100644 index 00000000..742908c2 --- /dev/null +++ b/packages/dev/src/agent-functions/index.ts @@ -0,0 +1,7 @@ +import { AgentFunction } from "@evo-ninja/agent-utils"; +import { AgentContext } from "../AgentContext"; +import { writeFile } from "./writeFile"; + +export const agentFunctions: AgentFunction[] = [ + writeFile +]; diff --git a/packages/dev/src/agent-functions/writeFile.ts b/packages/dev/src/agent-functions/writeFile.ts new file mode 100644 index 00000000..1af47b78 --- /dev/null +++ b/packages/dev/src/agent-functions/writeFile.ts @@ -0,0 +1,55 @@ +import { Result, ResultOk } from "@polywrap/result"; +import { AgentFunction, AgentFunctionResult, AgentOutputType, ChatMessageBuilder, trimText } from "@evo-ninja/agent-utils"; +import { AgentContext } from "../AgentContext"; + +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 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: ["thoughts"], + additionalProperties: false + }, + }, + buildExecutor(context: AgentContext) { + return async (params: FuncParameters): Promise> => { + // TODO: executeScript(FN_Name, params) + return ResultOk(SUCCESS(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..52d5a858 --- /dev/null +++ b/packages/dev/src/prompts.ts @@ -0,0 +1,10 @@ +export const INITIAL_PROMP = `You are a software developer. You have access to a file-system directory where your code will go.`; + +export const GOAL_PROMPT = (goal: string) => + `Your task is to write software to solve the following goal: ${goal}\n\n` + + `Call fs_writeFile to write source code files to disk.\n` + + `Once you have achieved the goal, call agent_onGoalAchieved.\n` + + `If you can not achieve the goal, call agent_onGoalFailed.`; + +export const LOOP_PREVENTION_PROMPT = + "Assistant, try executing fs_writeFile, agent_onGoalAchieved, or agent_onGoalFailed."; 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 From 015fc6afa9c20691d4c6c4ae5ef00ae29e23ef36 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 2 Oct 2023 17:46:30 +0200 Subject: [PATCH 2/6] chore: move fs agent-utils into their own package --- apps/cli/package.json | 3 +- .../AgentProtocolWorkspace.ts | 0 apps/cli/src/agent-protocol/index.ts | 1 + apps/cli/src/api.ts | 2 +- apps/cli/src/app.ts | 2 +- package.json | 3 +- packages/agent-utils-fs/package.json | 17 ++++ .../agent-utils-fs/src}/FileLogger.ts | 0 .../src}/FileSystemWorkspace.ts | 0 .../agent-utils-fs/src}/index.ts | 0 packages/agent-utils-fs/tsconfig.json | 10 +++ packages/dev/package.json | 5 +- packages/dev/src/DevAgent.ts | 5 +- packages/dev/src/__tests__/dev-agent.spec.ts | 82 +++++++++++++++++++ 14 files changed, 122 insertions(+), 8 deletions(-) rename apps/cli/src/{sys => agent-protocol}/AgentProtocolWorkspace.ts (100%) create mode 100644 apps/cli/src/agent-protocol/index.ts create mode 100644 packages/agent-utils-fs/package.json rename {apps/cli/src/sys => packages/agent-utils-fs/src}/FileLogger.ts (100%) rename {apps/cli/src/sys => packages/agent-utils-fs/src}/FileSystemWorkspace.ts (100%) rename {apps/cli/src/sys => packages/agent-utils-fs/src}/index.ts (100%) create mode 100644 packages/agent-utils-fs/tsconfig.json create mode 100644 packages/dev/src/__tests__/dev-agent.spec.ts diff --git a/apps/cli/package.json b/apps/cli/package.json index 7891d18f..a5205978 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -15,8 +15,9 @@ "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-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 599581cf..01b30473 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 c27036ce..67e36465 100644 --- a/apps/cli/src/app.ts +++ b/apps/cli/src/app.ts @@ -1,4 +1,3 @@ -import { FileSystemWorkspace, FileLogger } from "./sys"; import { DebugLog, DebugLlmApi } from "./diagnostic"; import { Evo } from "@evo-ninja/evo-agent"; @@ -14,6 +13,7 @@ import { LlmApi, ContextWindow, } from "@evo-ninja/agent-utils"; +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 a0c29e41..7fe4c48f 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "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: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: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", 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/dev/package.json b/packages/dev/package.json index 82c3aa83..99f52a94 100644 --- a/packages/dev/package.json +++ b/packages/dev/package.json @@ -4,7 +4,8 @@ "license": "MIT", "main": "./build/index.js", "scripts": { - "build": "rimraf build && tsc" + "build": "rimraf build && tsc", + "test": "jest --runInBand --verbose --rootDir . --config ../../jest.config.js" }, "dependencies": { "@polywrap/result": "~0.12.0", @@ -13,6 +14,8 @@ }, "devDependencies": { "@types/jest": "29.5.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", diff --git a/packages/dev/src/DevAgent.ts b/packages/dev/src/DevAgent.ts index ae138640..412f9537 100644 --- a/packages/dev/src/DevAgent.ts +++ b/packages/dev/src/DevAgent.ts @@ -11,7 +11,7 @@ import { Scripts, Logger, basicFunctionCallLoop, - executeAgentFunction + ExecuteAgentFunctionCalled } from "@evo-ninja/agent-utils"; import { ResultErr } from "@polywrap/result"; @@ -41,9 +41,8 @@ export class DevAgent implements Agent { return yield* basicFunctionCallLoop( this.context, - executeAgentFunction, agentFunctions, - (functionCalled) => { + (functionCalled: ExecuteAgentFunctionCalled) => { const terminationFunctions = [ `agent_onGoalAchieved`, `agent_onGoalFailed` 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..8ea651a4 --- /dev/null +++ b/packages/dev/src/__tests__/dev-agent.spec.ts @@ -0,0 +1,82 @@ +import { + Env, + Scripts, + OpenAI, + Chat, + ContextWindow, + LlmApi, + ConsoleLogger, + Logger +} from "@evo-ninja/agent-utils"; +import { + FileSystemWorkspace +} from "@evo-ninja/agent-utils-fs"; +import dotenv from "dotenv"; +import path from "path"; +import cl100k_base from "gpt-tokenizer/cjs/encoding/cl100k_base"; +import { DevAgent } from "../DevAgent"; + +dotenv.config({ + path: path.join(__dirname, "../../../../.env") +}); + +jest.setTimeout(120000); + +describe('Dev Agent Test Suite', () => { + + function createDevAgent(): DevAgent { + 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 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, "./"); + + return new DevAgent( + llm, + chat, + scripts, + logger + ); + } + + async function runDevAgent(agent: DevAgent, goal: string) { + const iterator = agent.run(goal); + + while (true) { + const response = await iterator.next(); + + if (response.done) { + return response; + } + } + } + + test("tick-tack-toe in python", async () => { + const dev = createDevAgent(); + const response = await runDevAgent(dev, "Build a tick-tack-toe game in python"); + + expect(response.value.ok).toBe(true); + console.log("look for the files") + }); +}); From 7335f613ae0512393aa46f61287362890020d534 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 3 Oct 2023 14:35:29 +0200 Subject: [PATCH 3/6] chore: add agent functions to dev agent --- packages/agent-utils/package.json | 2 + .../src/scripts}/agent-plugin/index.ts | 6 ++- .../scripts}/agent-plugin/polywrap.graphql | 0 .../src/scripts}/agent-plugin/polywrap.yaml | 0 .../src/scripts}/agent-plugin/types/index.ts | 0 .../src/scripts}/agent-plugin/types/module.ts | 0 .../src/scripts}/agent-plugin/types/types.ts | 0 .../scripts}/agent-plugin/types/wrap.info.ts | 0 packages/agent-utils/src/scripts/index.ts | 2 + .../src/scripts/wrap-client}/WrapClient.ts | 8 ++-- .../src/scripts/wrap-client}/index.ts | 0 packages/dev/src/AgentContext.ts | 6 ++- packages/dev/src/DevAgent.ts | 22 ++++++++-- packages/dev/src/__tests__/dev-agent.spec.ts | 9 +++- .../agent-functions/agent_onGoalAchieved.ts | 29 +++++++++++++ .../src/agent-functions/agent_onGoalFailed.ts | 29 +++++++++++++ .../{writeFile.ts => fs_writeFile.ts} | 23 ++++++---- packages/dev/src/agent-functions/index.ts | 8 +++- packages/dev/src/agent-functions/util.ts | 42 +++++++++++++++++++ packages/dev/src/prompts.ts | 13 +++--- packages/evo/src/Evo.ts | 6 +-- packages/evo/src/index.ts | 1 - packages/evo/src/prompts.ts | 3 -- 23 files changed, 174 insertions(+), 35 deletions(-) rename packages/{evo/src => agent-utils/src/scripts}/agent-plugin/index.ts (83%) rename packages/{evo/src => agent-utils/src/scripts}/agent-plugin/polywrap.graphql (100%) rename packages/{evo/src => agent-utils/src/scripts}/agent-plugin/polywrap.yaml (100%) rename packages/{evo/src => agent-utils/src/scripts}/agent-plugin/types/index.ts (100%) rename packages/{evo/src => agent-utils/src/scripts}/agent-plugin/types/module.ts (100%) rename packages/{evo/src => agent-utils/src/scripts}/agent-plugin/types/types.ts (100%) rename packages/{evo/src => agent-utils/src/scripts}/agent-plugin/types/wrap.info.ts (100%) rename packages/{evo/src/wrap => agent-utils/src/scripts/wrap-client}/WrapClient.ts (99%) rename packages/{evo/src/wrap => agent-utils/src/scripts/wrap-client}/index.ts (100%) create mode 100644 packages/dev/src/agent-functions/agent_onGoalAchieved.ts create mode 100644 packages/dev/src/agent-functions/agent_onGoalFailed.ts rename packages/dev/src/agent-functions/{writeFile.ts => fs_writeFile.ts} (70%) create mode 100644 packages/dev/src/agent-functions/util.ts diff --git a/packages/agent-utils/package.json b/packages/agent-utils/package.json index 27006bda..0bf8bf23 100644 --- a/packages/agent-utils/package.json +++ b/packages/agent-utils/package.json @@ -8,6 +8,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/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 99% rename from packages/evo/src/wrap/WrapClient.ts rename to packages/agent-utils/src/scripts/wrap-client/WrapClient.ts index 81e58504..8ba069d2 100644 --- a/packages/evo/src/wrap/WrapClient.ts +++ b/packages/agent-utils/src/scripts/wrap-client/WrapClient.ts @@ -1,3 +1,5 @@ +import { 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 { Logger, Workspace } from "@evo-ninja/agent-utils"; import * as path from "path-browserify" +import axios from "axios"; export class WrapClient extends PolywrapClient { 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/src/AgentContext.ts b/packages/dev/src/AgentContext.ts index ccf6a788..314b8e4e 100644 --- a/packages/dev/src/AgentContext.ts +++ b/packages/dev/src/AgentContext.ts @@ -1,11 +1,15 @@ import { Chat, LlmApi, - Scripts + 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 index 412f9537..1eb81f8e 100644 --- a/packages/dev/src/DevAgent.ts +++ b/packages/dev/src/DevAgent.ts @@ -10,6 +10,9 @@ import { LlmApi, Scripts, Logger, + Workspace, + WrapClient, + agentPlugin, basicFunctionCallLoop, ExecuteAgentFunctionCalled } from "@evo-ninja/agent-utils"; @@ -21,22 +24,33 @@ export class DevAgent implements Agent { constructor( llm: LlmApi, chat: Chat, + workspace: Workspace, scripts: Scripts, private readonly logger: Logger ) { this.context = { llm, chat, - scripts + 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("system", INITIAL_PROMP(agentFunctions.map((func) => func.definition))); chat.persistent("user", GOAL_PROMPT(goal)); return yield* basicFunctionCallLoop( @@ -44,8 +58,8 @@ export class DevAgent implements Agent { agentFunctions, (functionCalled: ExecuteAgentFunctionCalled) => { const terminationFunctions = [ - `agent_onGoalAchieved`, - `agent_onGoalFailed` + "agent_onGoalAchieved", + "agent_onGoalFailed" ]; return terminationFunctions.includes(functionCalled.name); }, diff --git a/packages/dev/src/__tests__/dev-agent.spec.ts b/packages/dev/src/__tests__/dev-agent.spec.ts index 8ea651a4..9074c79d 100644 --- a/packages/dev/src/__tests__/dev-agent.spec.ts +++ b/packages/dev/src/__tests__/dev-agent.spec.ts @@ -6,7 +6,8 @@ import { ContextWindow, LlmApi, ConsoleLogger, - Logger + Logger, + InMemoryWorkspace } from "@evo-ninja/agent-utils"; import { FileSystemWorkspace @@ -52,9 +53,12 @@ describe('Dev Agent Test Suite', () => { ); const scripts = new Scripts(scriptsWorkspace, "./"); + const workspace = new InMemoryWorkspace(); + return new DevAgent( llm, chat, + workspace, scripts, logger ); @@ -76,7 +80,8 @@ describe('Dev Agent Test Suite', () => { const dev = createDevAgent(); const response = await runDevAgent(dev, "Build a tick-tack-toe game in python"); + console.log(response); expect(response.value.ok).toBe(true); - console.log("look for the files") + console.log(dev.workspace.readdirSync("./")) }); }); 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..a3b13464 --- /dev/null +++ b/packages/dev/src/agent-functions/agent_onGoalAchieved.ts @@ -0,0 +1,29 @@ +import { createScriptExecutor } from "./util"; +import { AgentContext } from "../AgentContext"; + +import { + AgentFunction, + AgentFunctionResult, +} from "@evo-ninja/agent-utils"; + +const FN_NAME = "agent_onGoalAchieved"; + +const SUCCESS = (): AgentFunctionResult => ({ + outputs: [], + messages: [] +}); + +export const agent_onGoalAchieved: AgentFunction = { + definition: { + name: FN_NAME, + description: "Informs the user that the goal has been achieved.", + }, + 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..2ea755ee --- /dev/null +++ b/packages/dev/src/agent-functions/agent_onGoalFailed.ts @@ -0,0 +1,29 @@ +import { createScriptExecutor } from "./util"; +import { AgentContext } from "../AgentContext"; + +import { + AgentFunction, + AgentFunctionResult, +} from "@evo-ninja/agent-utils"; + +const FN_NAME = "agent_onGoalFailed"; + +const SUCCESS = (): AgentFunctionResult => ({ + outputs: [], + messages: [] +}); + +export const agent_onGoalFailed: AgentFunction = { + definition: { + name: FN_NAME, + description: "Informs the user that the agent could not achieve the goal.", + }, + buildExecutor(context: AgentContext) { + return createScriptExecutor( + context.scripts, + context.client, + "agent.onGoalFailed", + () => SUCCESS() + ); + } +}; diff --git a/packages/dev/src/agent-functions/writeFile.ts b/packages/dev/src/agent-functions/fs_writeFile.ts similarity index 70% rename from packages/dev/src/agent-functions/writeFile.ts rename to packages/dev/src/agent-functions/fs_writeFile.ts index 1af47b78..d1a1b603 100644 --- a/packages/dev/src/agent-functions/writeFile.ts +++ b/packages/dev/src/agent-functions/fs_writeFile.ts @@ -1,7 +1,14 @@ -import { Result, ResultOk } from "@polywrap/result"; -import { AgentFunction, AgentFunctionResult, AgentOutputType, ChatMessageBuilder, trimText } from "@evo-ninja/agent-utils"; +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 = { @@ -25,7 +32,7 @@ const SUCCESS = (params: FuncParameters): AgentFunctionResult => ({ ] }); -export const writeFile: AgentFunction = { +export const fs_writeFile: AgentFunction = { definition: { name: FN_NAME, description: "Writes data to a file, replacing the file if it already exists.", @@ -47,9 +54,11 @@ export const writeFile: AgentFunction = { }, }, buildExecutor(context: AgentContext) { - return async (params: FuncParameters): Promise> => { - // TODO: executeScript(FN_Name, params) - return ResultOk(SUCCESS(params)); - }; + 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 index 742908c2..01a22992 100644 --- a/packages/dev/src/agent-functions/index.ts +++ b/packages/dev/src/agent-functions/index.ts @@ -1,7 +1,11 @@ import { AgentFunction } from "@evo-ninja/agent-utils"; import { AgentContext } from "../AgentContext"; -import { writeFile } from "./writeFile"; +import { fs_writeFile } from "./fs_writeFile"; +import { agent_onGoalAchieved } from "./agent_onGoalAchieved"; +import { agent_onGoalFailed } from "./agent_onGoalFailed"; export const agentFunctions: AgentFunction[] = [ - writeFile + 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/prompts.ts b/packages/dev/src/prompts.ts index 52d5a858..e98f7109 100644 --- a/packages/dev/src/prompts.ts +++ b/packages/dev/src/prompts.ts @@ -1,10 +1,11 @@ -export const INITIAL_PROMP = `You are a software developer. You have access to a file-system directory where your code will go.`; +import { AgentFunctionDefinition } from "@evo-ninja/agent-utils"; + +export const INITIAL_PROMP = (functions: AgentFunctionDefinition[]) => + `You are an expert software engineer named "dev". You have access to the following functions to accomplish your goal:\n` + + functions.map((def) => (`${def.name}: ${def.description}`)).join("\n"); export const GOAL_PROMPT = (goal: string) => - `Your task is to write software to solve the following goal: ${goal}\n\n` + - `Call fs_writeFile to write source code files to disk.\n` + - `Once you have achieved the goal, call agent_onGoalAchieved.\n` + - `If you can not achieve the goal, call agent_onGoalFailed.`; + `You have been asked by the user to achieve the following goal: ${goal}`; export const LOOP_PREVENTION_PROMPT = - "Assistant, try executing fs_writeFile, agent_onGoalAchieved, or agent_onGoalFailed."; + "Assistant, you appear to be in a loop, try executing a different function."; diff --git a/packages/evo/src/Evo.ts b/packages/evo/src/Evo.ts index e4246196..58be7b9c 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 @@ -19,7 +17,9 @@ import { Timeout, InMemoryWorkspace, basicFunctionCallLoop, - ContextWindow + ContextWindow, + WrapClient, + agentPlugin } from "@evo-ninja/agent-utils"; import { ScriptWriter } from "@evo-ninja/js-script-writer-agent"; import { ResultErr } from "@polywrap/result"; 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 8b577c78..9b326e29 100644 --- a/packages/evo/src/prompts.ts +++ b/packages/evo/src/prompts.ts @@ -30,6 +30,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."; From 6eb711aa44249f6486031469ae10ebf4f9c7373f Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 3 Oct 2023 17:33:22 +0200 Subject: [PATCH 4/6] chore: added 3 dev tests --- apps/cli/package.json | 1 + apps/cli/src/app.ts | 3 +- package.json | 5 +- packages/agent-debug/package.json | 17 ++++ .../agent-debug/src}/DebugLlmApi.ts | 2 - .../agent-debug/src}/DebugLlmReq.ts | 0 .../agent-debug/src}/DebugLog.ts | 0 .../agent-debug/src}/Timer.ts | 0 .../agent-debug/src}/index.ts | 0 packages/agent-debug/tsconfig.json | 10 ++ .../src/agent/basicFunctionCallLoop.ts | 6 +- packages/dev/.gitignore | 1 + packages/dev/package.json | 4 +- packages/dev/src/__tests__/dev-agent.spec.ts | 96 ++++++++++++++---- .../agent-functions/agent_onGoalAchieved.ts | 12 ++- .../src/agent-functions/agent_onGoalFailed.ts | 12 ++- packages/dev/src/prompts.ts | 3 +- yarn.lock | 97 +++++++++---------- 18 files changed, 181 insertions(+), 88 deletions(-) create mode 100644 packages/agent-debug/package.json rename {apps/cli/src/diagnostic => packages/agent-debug/src}/DebugLlmApi.ts (96%) rename {apps/cli/src/diagnostic => packages/agent-debug/src}/DebugLlmReq.ts (100%) rename {apps/cli/src/diagnostic => packages/agent-debug/src}/DebugLog.ts (100%) rename {apps/cli/src/diagnostic => packages/agent-debug/src}/Timer.ts (100%) rename {apps/cli/src/diagnostic => packages/agent-debug/src}/index.ts (100%) create mode 100644 packages/agent-debug/tsconfig.json create mode 100644 packages/dev/.gitignore diff --git a/apps/cli/package.json b/apps/cli/package.json index a5205978..835a3766 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@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", diff --git a/apps/cli/src/app.ts b/apps/cli/src/app.ts index 8c6973fc..4d5659c3 100644 --- a/apps/cli/src/app.ts +++ b/apps/cli/src/app.ts @@ -1,5 +1,3 @@ -import { DebugLog, DebugLlmApi } from "./diagnostic"; - import { Evo } from "@evo-ninja/evo-agent"; import { Env, @@ -13,6 +11,7 @@ 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"; diff --git a/package.json b/package.json index 7fe4c48f..0c496f97 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,10 @@ "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": "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", @@ -28,6 +29,6 @@ "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/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/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 index 99f52a94..ca651d54 100644 --- a/packages/dev/package.json +++ b/packages/dev/package.json @@ -9,11 +9,11 @@ }, "dependencies": { "@polywrap/result": "~0.12.0", - "@evo-ninja/agent-utils": "~0.1.0", - "openai": "~3.3.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", diff --git a/packages/dev/src/__tests__/dev-agent.spec.ts b/packages/dev/src/__tests__/dev-agent.spec.ts index 9074c79d..41bbc533 100644 --- a/packages/dev/src/__tests__/dev-agent.spec.ts +++ b/packages/dev/src/__tests__/dev-agent.spec.ts @@ -1,3 +1,5 @@ +import { DevAgent } from "../DevAgent"; + import { Env, Scripts, @@ -6,16 +8,14 @@ import { ContextWindow, LlmApi, ConsoleLogger, - Logger, - InMemoryWorkspace + Logger } from "@evo-ninja/agent-utils"; -import { - FileSystemWorkspace -} from "@evo-ninja/agent-utils-fs"; +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"; -import { DevAgent } from "../DevAgent"; dotenv.config({ path: path.join(__dirname, "../../../../.env") @@ -25,7 +25,15 @@ jest.setTimeout(120000); describe('Dev Agent Test Suite', () => { - function createDevAgent(): DevAgent { + 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: () => { @@ -44,6 +52,11 @@ describe('Dev Agent Test Suite', () => { 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); @@ -53,35 +66,76 @@ describe('Dev Agent Test Suite', () => { ); const scripts = new Scripts(scriptsWorkspace, "./"); - const workspace = new InMemoryWorkspace(); + const workspace = new FileSystemWorkspace(testCaseDir); - return new DevAgent( - llm, - chat, - workspace, - scripts, - logger - ); + return { + agent: new DevAgent( + debugLlm, + chat, + workspace, + scripts, + logger + ), + debugLog + }; } - async function runDevAgent(agent: DevAgent, goal: string) { + 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("tick-tack-toe in python", async () => { - const dev = createDevAgent(); - const response = await runDevAgent(dev, "Build a tick-tack-toe game in python"); + 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 + ); - console.log(response); expect(response.value.ok).toBe(true); - console.log(dev.workspace.readdirSync("./")) + 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 index a3b13464..baab419d 100644 --- a/packages/dev/src/agent-functions/agent_onGoalAchieved.ts +++ b/packages/dev/src/agent-functions/agent_onGoalAchieved.ts @@ -4,12 +4,18 @@ import { AgentContext } from "../AgentContext"; import { AgentFunction, AgentFunctionResult, + AgentOutputType } from "@evo-ninja/agent-utils"; const FN_NAME = "agent_onGoalAchieved"; const SUCCESS = (): AgentFunctionResult => ({ - outputs: [], + outputs: [ + { + type: AgentOutputType.Success, + title: "[dev] agent_onGoalAchieved" + } + ], messages: [] }); @@ -17,6 +23,10 @@ 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( diff --git a/packages/dev/src/agent-functions/agent_onGoalFailed.ts b/packages/dev/src/agent-functions/agent_onGoalFailed.ts index 2ea755ee..3a951870 100644 --- a/packages/dev/src/agent-functions/agent_onGoalFailed.ts +++ b/packages/dev/src/agent-functions/agent_onGoalFailed.ts @@ -4,12 +4,18 @@ import { AgentContext } from "../AgentContext"; import { AgentFunction, AgentFunctionResult, + AgentOutputType } from "@evo-ninja/agent-utils"; const FN_NAME = "agent_onGoalFailed"; const SUCCESS = (): AgentFunctionResult => ({ - outputs: [], + outputs: [ + { + type: AgentOutputType.Error, + title: "[dev] agent_onGoalFailed" + } + ], messages: [] }); @@ -17,6 +23,10 @@ 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( diff --git a/packages/dev/src/prompts.ts b/packages/dev/src/prompts.ts index e98f7109..3b42fdda 100644 --- a/packages/dev/src/prompts.ts +++ b/packages/dev/src/prompts.ts @@ -1,8 +1,7 @@ import { AgentFunctionDefinition } from "@evo-ninja/agent-utils"; export const INITIAL_PROMP = (functions: AgentFunctionDefinition[]) => - `You are an expert software engineer named "dev". You have access to the following functions to accomplish your goal:\n` + - functions.map((def) => (`${def.name}: ${def.description}`)).join("\n"); + `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}`; diff --git a/yarn.lock b/yarn.lock index 62debb62..0b536bfc 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" @@ -2665,9 +2665,9 @@ picomatch "^2.2.2" "@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" @@ -3082,9 +3082,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" @@ -3097,9 +3097,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" @@ -3131,9 +3131,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" "*" @@ -3232,9 +3232,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" "*" @@ -4142,7 +4142,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== @@ -4266,9 +4266,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" @@ -4621,21 +4621,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" @@ -5159,9 +5159,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" @@ -6218,7 +6218,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== @@ -8294,9 +8294,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" @@ -9466,9 +9466,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" @@ -10105,13 +10105,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" @@ -10860,9 +10853,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" From a69ad98bb32dacc18e5dd34b8ac41b55f32c1b1f Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 3 Oct 2023 17:51:10 +0200 Subject: [PATCH 5/6] chore: update typescript target to es2015 --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 } From f790a28e3d5a2994fd77394cad475b135f037da7 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 3 Oct 2023 21:36:56 +0200 Subject: [PATCH 6/6] chore: changes based on feedback --- packages/dev/src/DevAgent.ts | 2 +- packages/dev/src/agent-functions/fs_writeFile.ts | 2 +- packages/dev/src/prompts.ts | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/dev/src/DevAgent.ts b/packages/dev/src/DevAgent.ts index 1eb81f8e..aed39dab 100644 --- a/packages/dev/src/DevAgent.ts +++ b/packages/dev/src/DevAgent.ts @@ -50,7 +50,7 @@ export class DevAgent implements Agent { ): AsyncGenerator { const { chat } = this.context; try { - chat.persistent("system", INITIAL_PROMP(agentFunctions.map((func) => func.definition))); + chat.persistent("system", INITIAL_PROMP()); chat.persistent("user", GOAL_PROMPT(goal)); return yield* basicFunctionCallLoop( diff --git a/packages/dev/src/agent-functions/fs_writeFile.ts b/packages/dev/src/agent-functions/fs_writeFile.ts index d1a1b603..a3053cde 100644 --- a/packages/dev/src/agent-functions/fs_writeFile.ts +++ b/packages/dev/src/agent-functions/fs_writeFile.ts @@ -49,7 +49,7 @@ export const fs_writeFile: AgentFunction = { type: "string" }, }, - required: ["thoughts"], + required: ["path", "data", "encoding"], additionalProperties: false }, }, diff --git a/packages/dev/src/prompts.ts b/packages/dev/src/prompts.ts index 3b42fdda..590eb1e2 100644 --- a/packages/dev/src/prompts.ts +++ b/packages/dev/src/prompts.ts @@ -1,6 +1,4 @@ -import { AgentFunctionDefinition } from "@evo-ninja/agent-utils"; - -export const INITIAL_PROMP = (functions: AgentFunctionDefinition[]) => +export const INITIAL_PROMP = () => `You are an expert software engineer named "dev".`; export const GOAL_PROMPT = (goal: string) =>