Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create a text editor tool with multiple commands #186

Closed
wants to merge 6 commits into from

Conversation

salman1993
Copy link
Collaborator

@salman1993 salman1993 commented Oct 23, 2024

Changes:

Anthropic is using this text editor tool for Computer Use. It might be useful to try this in goose - docs, code. It seems like they prefer to have fewer tools, but each tool has more optional args which are used for specific actions. For example, in goose we have separate tools for read_file, write_file, patch_file but in this case, its a single EditorTool with command as an Enum that routes to the editor action (view, create, insert).

Test:

tool descriptions are correctly passed
tool-descriptions

@salman1993 salman1993 requested a review from baxen October 23, 2024 17:28
@salman1993 salman1993 changed the title Create a text editor tool with multiple commands feat: create a text editor tool with multiple commands Oct 23, 2024
@@ -1,7 +1,7 @@
import inspect
import uuid
from importlib.metadata import entry_points
from typing import get_args, get_origin
from typing import Literal, get_args, get_origin, Any, List, Tuple, Dict, Union
Copy link
Collaborator

@lamchau lamchau Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:nit: we can use list, tuple, and dict directly now

@michaelneale
Copy link
Collaborator

interesting, will try this out, could be promising. I did notice that tool calling seemed to work well with parameters in the past, and even with richer CLIs - ie able to use the one "tool" different ways seems to suit it more so than choosing between tools (intuitively that makes sense, as a human, to some limited extent, you don't have the cognitive overload of choosing the tool)

@michaelneale
Copy link
Collaborator

@salman1993 any tips on how to try it out to A/B test?

@michaelneale
Copy link
Collaborator

tried it out with editing just one spot in a yaml file... just FYI:

The phrase "Found packages with disallowed licenses" occurs multiple times in the .github/workflows/license-check.yml file, making it necessary to be more      
specific in the string replace operation. I'll view more of the file to identify the different locations and modify them accordingly. Let's check the           
occurrences separately.                                                                                                                                         

─── .github/workflows/license-check.yml ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                                                                                
         uses: actions/setup-python@v5                                                                                                                          
         with:                                                                                                                                                  
           python-version: '3.10'                                                                                                                               
                                                                                                                                                                
       - name: Install dependencies                                                                                                                             
         run: |                                                                                                                                                 
           python -m pip install --upgrade pip                                                                                                                  
           pip install tomli requests urllib3                                                                                                                   
                                                                                                                                                                
       - name: Check licenses                                                                                                                                   
         run: |                                                                                                                                                 
           python .github/workflows/scripts/check_licenses.py \                                                                                                 
             pyproject.toml || exit_code=$?                                                                                                                     
           if [ "${exit_code:-0}" -ne 0 ]; then                                                                                                                 
             echo "::error::Found packages with disallowed licenses"                                                                                            
             exit 1                                                                                                                                             
           fi                                                                                                                                                   
                                                                                                                                                                
       - name: Check Exchange licenses                                                                                                                          
         run: |                                                                                                                                                 
           python .github/workflows/scripts/check_licenses.py \                                                                                                 
             packages/exchange/pyproject.toml || exit_code=$?                                                                                                   
           if [ "${exit_code:-0}" -ne 0 ]; then                                                                                                                 
             echo "::error::Found packages with disallowed licenses in exchange"                                                                                
             exit 1                                                                                                                                             
           fi                                                                                                                                                   
                                                                                                                                                                


─── .github/workflows/license-check.yml ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                                                                                
                                                                                                                                                                
                                                                                                                                                                


─── .github/workflows/license-check.yml ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                                                                                
                                                                                                                                                                
                                                                                                                                                                

Let's specify the contexts where we succeed the operations, starting with the first one.                                                                        

─── .github/workflows/license-check.yml ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                                                                                
 echo "::error::Found packages with disallowed licenses"                                                                                                        
                                                                                                                                                                

->                                                                                                                                                              

                                                                                                                                                                
 echo "::error::Found packages with disallowed licenses, it was in the goose package."                                                                          
                                                                                                                                                                


─── .github/workflows/license-check.yml ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                                                                                
 echo "::error::Found packages with disallowed licenses in exchange"                                                                                            
                                                                                                                                                                

->                                                                                                                                                              

                                                                                                                                                                
 echo "::error::Found packages with disallowed licenses, it was in the goose package."

some odd artifacts like:

image

@michaelneale
Copy link
Collaborator

so far seems to do a good job - but not pushed too hard today

patho = system.to_patho(path)

if patho.exists() and not system.is_active(path):
print(f"We are warning the LLM to view before write in write_file, with path={path} and patho={str(patho)}")
raise ValueError(f"You must view {path} using read_file before you overwrite it")

self._save_file_history(patho) # Save current content to history
Copy link
Collaborator

@lamchau lamchau Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:nit: i see a lot of erroneous comments like these in this pr and most of the time they're already self documenting. maybe remove?

return f"Successfully undid the last edit on {path}"

@tool
def text_editor(
Copy link
Collaborator

@lamchau lamchau Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a lot of conflated concerns/responsibilities in a single method. it's a little tough to read and would even harder to test. how about trying out a dispatch pattern?

command_dispatch: dict[str, callable] = {
    "create": self._create_file,
    "insert": self._insert_string,
    "undo_edit": self._undo_edit,
     ...
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should possibly consider creating a text editor abstraction given the complex interactions we have here. maybe these things would play well with the editor integrations people have made plugins for?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like the suggestion for dispatcher pattern. i opened another PR cause i also batched up the changes for bash and process manager: #191

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lamchau I think this is the approach that claude took and it seems to work well - a smaller number of tools I think is cognitively more pleasant vs LLM needing to decide which tool to use (also lets us put more smarts in the tool vs relying on LLM always to choose the right way) - so I think this general approach feels right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michaelneale not sure i follow? i think the logic itself is sound just tidying it up

@salman1993
Copy link
Collaborator Author

changes from this PR are in this one: #191

@salman1993 salman1993 closed this Oct 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants