MetaGPT icon indicating copy to clipboard operation
MetaGPT copied to clipboard

Iterating on a solution

Open rmulligan opened this issue 1 year ago • 9 comments

Is it possible to iterate on a completed solution, or provide feedback on the chosen path? When setting long term memory to True and running again with revised instructions the execution prints the directives, but does not run any further steps.

python startup.py "This should be an emacs lisp package not a python package. The package should be a fork of gptel. Please modify the gptel package to interact with flowise" --n_round=25 --code_review=True --investment=5 2023-09-18 00:32:13.938 | INFO | metagpt.config:init:44 - Config loading done. 2023-09-18 00:32:13.942 | WARNING | metagpt.config:init:77 - LONG_TERM_MEMORY is True 2023-09-18 00:32:24.259 | WARNING | metagpt.memory.longterm_memory:recover_memory:32 - Agent Alice(Product Manager) has existed memory storage with 3 messages and has recovered them. 2023-09-18 00:32:24.297 | WARNING | metagpt.memory.longterm_memory:recover_memory:32 - Agent Bob(Architect) has existed memory storage with 3 messages and has recovered them. 2023-09-18 00:32:24.307 | WARNING | metagpt.memory.longterm_memory:recover_memory:32 - Agent Eve(Project Manager) has existed memory storage with 1 messages and has recovered them. 2023-09-18 00:32:24.330 | WARNING | metagpt.memory.longterm_memory:recover_memory:32 - Agent Alex(Engineer) has existed memory storage with 2 messages and has recovered them. 2023-09-18 00:32:24.334 | INFO | metagpt.software_company:invest:39 - Investment: $5.

rmulligan avatar Sep 18 '23 00:09 rmulligan

I'm wondering the same thing. I happy to contribute a PR with some guidance of course? Is anyone else already working on this? Is it part of the roadmap?

I'd be happy to put together a pull request to address the iteration capabilities and contribute to the project.

Before jumping into coding, I wanted to check if anyone else is already tackling this or if it's part of the current project roadmap. If not, I think it would be a useful enhancement.

My proposed approach would be:

  • Add a new option to enable re-running with additional directives
    • This could be a simple boolean flag
  • Update the execution logic to:
    • Check for new directives each time the script is called
    • Append new directives to existing list
    • Re-run full directive list

samuelmukoti avatar Sep 23 '23 22:09 samuelmukoti

SkyNet v1.0 here we go!

@samuelmukoti let me know if you work it out, i think this would be an ideal next feature.

great project @geekan - any advice for how best to implement ?

javadan avatar Oct 01 '23 21:10 javadan

@rmulligan @samuelmukoti @javadan check latest code and we've incremental dev now.

geekan avatar Dec 21 '23 09:12 geekan

Nice. A few errors I came across (from github head):

  • Only MetaGPT/config/config.yaml was used, not ~/.metagpt/key.yaml resulting in metagpt.config.NotConfiguredException: You should config a LLM configuration first
  • When not specifying a project path, it will generate a project name under the WORKSPACE_PATH and then complain that the path doesn't exist git.exc.NoSuchPathError: /mnt/d/MetaGPT/workspace/code_review so one must mkdir code_review first and then use, for e.g., metagpt "my requirements" --project-path="/mnt/d/MetaGPT/workspace/my_app".
  • Fix error in prepare_documents.py
  File "/mnt/d/MetaGPT/metagpt/actions/prepare_documents.py", line 46, in run
    self._init_repo()
  File "/mnt/d/MetaGPT/metagpt/actions/prepare_documents.py", line 40, in _init_repo
    if path.exists() and not CONFIG.inc:

You can fix it with path = Path(path)

    def _init_repo(self):
    """Initialize the Git environment."""
    path = CONFIG.project_path
    if not path:
        name = CONFIG.project_name or FileRepository.new_filename()
        path = Path(CONFIG.workspace_path) / name

    path = Path(path)  # Convert the path string to a Path object

    if path.exists() and not CONFIG.inc:
        shutil.rmtree(path)
    CONFIG.git_repo = GitRepository(local_path=path, auto_init=True)

After adding that in, it continues. I was thinking specifically of being able to iterate on top of an existing codebase that wasn't generated by Meta-GPT.

I tried dropping a python file in /mnt/d/MetaGPT/code/myfile.py and gave it a requirement to "Code Review /mnt/d/MetaGPT/code/myfile.py", but it just made its own big Code Review project under /mnt/d/MetaGPT/workspace/project_name and then overwrote my file with some generic code review code. I tried rewording it in a couple of ways, but nothing working yet.

How might I integrate my own code into a MetaGPT project?


Another note: I've had mixed success with the incremental design feature:
The one time worked, and the other time it didn't, so far.

The time it didn't work, Alice(Product Manager): to do WritePRD() adds a requirement, and it got integrated into the "Requirement Pool", and the other time, she wrote it but it didn't get added to the pool.

I'm not sure what the issue is... but the prompt that worked for me was more explicit that it was writing an upgrade to the current project.

javadan avatar Dec 25 '23 11:12 javadan

i'm also getting an error at

if path.exists() and not CONFIG.inc:

when using the flags --inc --project-path /path/here

wrapping it in a Path is the answer but @javadan you're rewrapping it i'm happy to submit a PR @geekan

 def _init_repo(self):
        """Initialize the Git environment."""
        path = CONFIG.project_path
        if not path:
            name = CONFIG.project_name or FileRepository.new_filename()
            path = Path(CONFIG.workspace_path) / name
        else:
            path = Path(path)

        if path.exists() and not CONFIG.inc:
            shutil.rmtree(path)
        CONFIG.git_repo = GitRepository(local_path=path, auto_init=True)

kevb10 avatar Dec 28 '23 00:12 kevb10

I've got a process question related to these details. I haven't yet gone through all the code enough to understand the flow:

Therefore, MetaGPT Software Company does not support the input of new requirements of the following nature:

    Requirements related to the architecture, such as how to write setup.py or requirements.txt.
    Specifying that a particular function should perform a specific operation.

I'm interested to know what the flow is, in terms of the files generated under /docs, when incrementing on a solution, with the software company, to understand why architectural changes are not supported. At what point does it break down?

I requested a Java project, and then requested that the project be restructured as a maven project. That is, it needs to make src/main/java and src/main/resources and move the java files, and maybe generate a pom.xml file if I'm lucky:

Here's what happens after the refactor:

/docs/code_summaries/2024.json still contains the original file names /docs/prds/2024.json gets updated with my new requirements /docs/system_design/2024.json gets updated with the new file locations /docs/tasks/2024.json is not updated /docs/bugfix.json has my request to restructure /docs/requirement.json is empty

So it seems like it made some changes, but it didn't result in any changes to the tasks, and the files didn't move, and no pom.xml was generated, despite the PRD's requirement pool being updated explicitly.

So at what point does it break down, or, what is the flow in the code, so that I might look into it myself?

javadan avatar Jan 02 '24 11:01 javadan

@javadan Let me understand, the break down here means that some instructions can be used to interrupt and perform human intervention operations when MetaGPT is running?

Rchenyu avatar Feb 14 '24 07:02 Rchenyu

So geekan added an 'incremental dev' feature.

metagpt --project-path /mnt/d/MetaGPT/workspace/existingproject "Make some change to the project"

That creates a bugfix.txt file and handles the new feature request using the existing docs/ folder, at the PRD level and then waking up the Engineer with a message. However, for me this didn't result in any WriteTasks changes to the tasks, and consequently no meaningful changes were made to my project.

From a quick look at the code, I think it's because it gets to this part (write_prd.py):

    async def _handle_bugfix(self, req: Document) -> Message:
        # ... bugfix logic ...
        await self.repo.docs.save(filename=BUGFIX_FILENAME, content=req.content)
        await self.repo.docs.save(filename=REQUIREMENT_FILENAME, content="")
        bug_fix = BugFixContext(filename=BUGFIX_FILENAME)
        return Message(
            content=bug_fix.model_dump_json(),
            instruct_content=bug_fix,
            role="",
            cause_by=FixBug,
            sent_from=self,
            send_to="Alex",  # the name of Engineer
        )

which clears the requirements file with content="", so that when it gets to this part (engineer.py):

    async def _new_code_plan_and_change_action(self):
        """Create a WriteCodePlanAndChange action for subsequent to-do actions."""
        files = self.project_repo.all_files
        requirement_doc = await self.project_repo.docs.get(REQUIREMENT_FILENAME)
        requirement = requirement_doc.content if requirement_doc else ""
        code_plan_and_change_ctx = CodePlanAndChangeContext.loads(files, requirement=requirement)
        self.rc.todo = WriteCodePlanAndChange(i_context=code_plan_and_change_ctx, context=self.context, llm=self.llm)

it tries to use requirements.txt instead of bugfix.txt and doesn't do anything (?)

javadan avatar Feb 14 '24 09:02 javadan

@kevb10 @javadan @rmulligan @samuelmukoti thanks all for your nice comments and point out the problem.

@iorisa could you plz check this?

geekan avatar Mar 20 '24 14:03 geekan