From baae370bea0c7576c75f5ce420e5579116b97c74 Mon Sep 17 00:00:00 2001 From: marko-kraemer Date: Sat, 2 Nov 2024 04:13:51 +0100 Subject: [PATCH] wip --- README.md | 2 +- core/examples/example-agent/agent.py | 72 +++++++++++++------ .../example-agent/tools/files_tool.py | 56 ++------------- 3 files changed, 58 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index 3f3a1007..ddb190f7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AgentPress: Building Blocks for AI Agents -AgentPress is not a agent framework - it's a collection of _simple, but powerful_ utilities that serve as building blocks for creating AI agents. *Plug, play, and customize.* +AgentPress is a collection of _simple, but powerful_ utilities that serve as building blocks for creating AI agents. *Plug, play, and customize.* - **Threads**: Simple message thread handling utilities - **Tools**: Flexible tool definition and automatic execution diff --git a/core/examples/example-agent/agent.py b/core/examples/example-agent/agent.py index 0a07c49e..29c21ab2 100644 --- a/core/examples/example-agent/agent.py +++ b/core/examples/example-agent/agent.py @@ -12,14 +12,6 @@ async def run_agent(thread_id: str, max_iterations: int = 5): thread_manager.add_tool(FilesTool) thread_manager.add_tool(TerminalTool) - - await thread_manager.add_message( - thread_id, - { - "role": "user", - "content": "Let's create a marketing website for my AI Agent 'Jarvis' using HTML, CSS, Javascript. Use images from pixabay, pexels, and co. Style it cyberpunk style. Make it like Ironmen Jarvis." - } - ) async def init(): pass @@ -32,12 +24,15 @@ async def run_agent(thread_id: str, max_iterations: int = 5): async def after_iteration(): # Ask the user for a custom message or use the default custom_message = input("Enter a message to send (or press Enter to use 'Continue!!!' as message): ") - message_content = custom_message if custom_message else "Continue!!!" + + message_content = custom_message if custom_message else """ + Continue!!! + """ await thread_manager.add_message(thread_id, { "role": "user", "content": message_content }) - + async def finalizer(): pass @@ -49,30 +44,54 @@ async def run_agent(thread_id: str, max_iterations: int = 5): iteration += 1 await pre_iteration() - # Get entire state store - state = await state_manager.export_store() - state_info = f"Current workspace state:\n{json.dumps(state, indent=2)}" - system_message = { "role": "system", - "content": f"""You are a web developer who can create, read, update, and delete files, - and execute terminal commands. You write clean, well-structured code and explain your changes. + "content": """ +You are a world-class web developer who can create, update, delete files, and execute terminal commands. You write clean, well-structured code. Keep iterating on existing files, continue working on this existing codebase - do not omit previous progress; instead, keep iterating. - Current workspace state: - {state_info} - - Explain what you're doing before making changes.""" + +[update_file(file_path, file_contents)] +[create_file(file_path, file_contents)] +[delete_file(file_path)] +[execute_command(command)] + + +ALWAYS RESPOND WITH MULTIPLE SIMULTANEOUS ACTIONS: + +[Provide a concise overview of your planned changes and implementations] + + + +[Include multiple tool calls] + + +Think deeply and step by step. + """ } + + state = await state_manager.export_store() + + state_message = { + "role": "user", + "content": f""" +Current development environment workspace state: + +{json.dumps(state, indent=2)} + + """ + } + model_name = "anthropic/claude-3-5-sonnet-latest" response = await thread_manager.run_thread( thread_id=thread_id, system_message=system_message, model_name=model_name, - temperature=0.7, + temperature=0.1, max_tokens=4096, tool_choice="auto", - execute_tools_async=False, + additional_message=state_message, + execute_tools_async=True, use_tools=True, execute_model_tool_calls=True ) @@ -89,6 +108,15 @@ if __name__ == "__main__": async def main(): thread_manager = ThreadManager() thread_id = await thread_manager.create_thread() + + await thread_manager.add_message( + thread_id, + { + "role": "user", + "content": "Let's create a marketing website for my AI Agent 'Jarvis' using HTML, CSS, Javascript. Use images from pixabay, pexels, and co. Style it cyberpunk style. Make it like Ironmen Jarvis." + } + ) + await run_agent(thread_id) asyncio.run(main()) \ No newline at end of file diff --git a/core/examples/example-agent/tools/files_tool.py b/core/examples/example-agent/tools/files_tool.py index cf6c9e8c..0f2d7f89 100644 --- a/core/examples/example-agent/tools/files_tool.py +++ b/core/examples/example-agent/tools/files_tool.py @@ -12,28 +12,17 @@ class FilesTool(Tool): "package-lock.json", "postcss.config.js", "postcss.config.mjs", - "playwright.config.js", "jsconfig.json", "components.json", "tsconfig.tsbuildinfo", - "next-env.d.ts", "tsconfig.json", - "firebase-service-account.json", - "Dockerfile" } EXCLUDED_DIRS = { - "src/components/ui", - "cypress", "node_modules", - "migrations", ".next", - "playwright-report", - "test-results", "dist", "build", - "coverage", - "terminal_logs", ".git" } @@ -108,11 +97,11 @@ class FilesTool(Tool): @tool_schema({ "name": "create_file", - "description": "Create a new file in the workspace", + "description": "Create a new file with the provided contents at a given path in the workspace", "parameters": { "type": "object", "properties": { - "file_path": {"type": "string", "description": "The relative path of the file to create"}, + "file_path": {"type": "string", "description": "Path to the file to be created."}, "content": {"type": "string", "description": "The content to write to the file"} }, "required": ["file_path", "content"] @@ -133,37 +122,14 @@ class FilesTool(Tool): except Exception as e: return self.fail_response(f"Error creating file: {str(e)}") - @tool_schema({ - "name": "read_file", - "description": "Read the contents of a file in the workspace", - "parameters": { - "type": "object", - "properties": { - "file_path": {"type": "string", "description": "The relative path of the file to read"} - }, - "required": ["file_path"] - } - }) - async def read_file(self, file_path: str) -> ToolResult: - try: - workspace_state = await self.state_manager.get("workspace") - if file_path in workspace_state["files"]: - return self.success_response({ - "file_path": file_path, - "content": workspace_state["files"][file_path]["content"] - }) - return self.fail_response(f"File '{file_path}' not found in workspace state.") - except Exception as e: - return self.fail_response(f"Error reading file: {str(e)}") - @tool_schema({ "name": "update_file", - "description": "Update the contents of a file in the workspace", + "description": "Update an existing file at the given path in the workspace with the provided contents.", "parameters": { "type": "object", "properties": { - "file_path": {"type": "string", "description": "The relative path of the file to update"}, - "content": {"type": "string", "description": "The new content to write to the file"} + "file_path": {"type": "string", "description": "Path to the file to be updated"}, + "content": {"type": "string", "description": "New content to be written to the file. ONLY CODE. The whole file contents, the complete code – The contents of the new file with all instructions implemented perfectly. NEVER write comments. Keep the complete File Contents within this key."} }, "required": ["file_path", "content"] } @@ -181,11 +147,11 @@ class FilesTool(Tool): @tool_schema({ "name": "delete_file", - "description": "Delete a file from the workspace", + "description": "Delete a file at the given path in the workspace.", "parameters": { "type": "object", "properties": { - "file_path": {"type": "string", "description": "The relative path of the file to delete"} + "file_path": {"type": "string", "description": "Path to the file to be deleted."} }, "required": ["file_path"] } @@ -214,18 +180,10 @@ if __name__ == "__main__": create_result = await files_tool.create_file(test_file_path, test_content) print("Create file result:", create_result) - # Test read_file - read_result = await files_tool.read_file(test_file_path) - print("Read file result:", read_result) - # Test update_file update_result = await files_tool.update_file(test_file_path, updated_content) print("Update file result:", update_result) - # Test read_file after update - read_updated_result = await files_tool.read_file(test_file_path) - print("Read updated file result:", read_updated_result) - # Test delete_file delete_result = await files_tool.delete_file(test_file_path) print("Delete file result:", delete_result)