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: add global optional user goosehints file #73

Merged
merged 5 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ To install Goose, use `pipx`. First ensure [pipx][pipx] is installed:
brew install pipx
pipx ensurepath
```
You can also place `.goosehints` in `~/.config/goose/.goosehints` if you like for always loaded hints personal to you.

Then install Goose:

Expand Down
10 changes: 8 additions & 2 deletions src/goose/toolkit/developer.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,15 @@ def system(self) -> str:
"""Retrieve system configuration details for developer"""
hints_path = Path(".goosehints")
system_prompt = Message.load("prompts/developer.jinja").text
home_hints_path = Path.home() / ".config/goose/.goosehints"
Copy link

Choose a reason for hiding this comment

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

It doesn't seem necessary to use a hidden file when it's already in a hidden folder. It might be good to log an error if the dotfile exists though, just to avoid confusion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@vfiano yeah can change it, wouldn't be too confusing as it is called .goosehints elsewhere?

hints = []
if hints_path.is_file():
goosehints = render_template(hints_path)
system_prompt = f"{system_prompt}\n\nHints:\n{goosehints}"
hints.append(render_template(hints_path))
if home_hints_path.is_file():
hints.append(render_template(home_hints_path))
if hints:
hints_text = "\n".join(hints)
system_prompt = f"{system_prompt}\n\nHints:\n{hints_text}"
return system_prompt

@tool
Expand Down
45 changes: 44 additions & 1 deletion tests/toolkit/test_developer.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,50 @@ def test_system_prompt_with_goosehints(temp_dir, developer_toolkit):
assert system_prompt.endswith(expected_end)


def test_update_plan(developer_toolkit):
def test_system_prompt_with_goosehints_only_from_home_dir(temp_dir, developer_toolkit):
readme_file_home = Path.home() / ".config/goose/README.md"
readme_file_home.parent.mkdir(parents=True, exist_ok=True)
readme_file_home.write_text("This is from the README.md file in home.")

home_hints_file = Path.home() / ".config/goose/.goosehints"
home_jinja_template_content = "Hints from home:\n\n{% include 'README.md' %}\nEnd."
home_hints_file.write_text(home_jinja_template_content)

try:
with change_dir(temp_dir):
system_prompt = developer_toolkit.system()
expected_content_home = "Hints from home:\n\nThis is from the README.md file in home.\nEnd."
expected_end = f"Hints:\n{expected_content_home}"
assert system_prompt.endswith(expected_end)
finally:
home_hints_file.unlink()
readme_file_home.unlink()

readme_file = temp_dir / "README.md"
readme_file.write_text("This is from the README.md file.")

hints_file = temp_dir / ".goosehints"
jinja_template_content = "Hints from local:\n\n{% include 'README.md' %}\nEnd."
hints_file.write_text(jinja_template_content)

home_hints_file = Path.home() / ".config/goose/.goosehints"
home_jinja_template_content = "Hints from home:\n\n{% include 'README.md' %}\nEnd."
home_hints_file.write_text(home_jinja_template_content)

home_readme_file = Path.home() / ".config/goose/README.md"
home_readme_file.write_text("This is from the README.md file in home.")

try:
with change_dir(temp_dir):
system_prompt = developer_toolkit.system()
expected_content_local = "Hints from local:\n\nThis is from the README.md file.\nEnd."
expected_content_home = "Hints from home:\n\nThis is from the README.md file in home.\nEnd."
expected_end = f"Hints:\n{expected_content_local}\n{expected_content_home}"
assert system_prompt.endswith(expected_end)
finally:
home_hints_file.unlink()
home_readme_file.unlink()

tasks = [
{"description": "Task 1", "status": "planned"},
{"description": "Task 2", "status": "complete"},
Expand Down