diff --git a/.gitignore b/.gitignore index 8733789a..c9142a70 100644 --- a/.gitignore +++ b/.gitignore @@ -20,12 +20,10 @@ parts/ sdist/ var/ wheels/ -pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg -MANIFEST # PyInstaller # Usually these files are written by a python script from a template @@ -49,7 +47,6 @@ coverage.xml *.cover *.py,cover .hypothesis/ -.pytest_cache/ # Translations *.mo @@ -58,8 +55,6 @@ coverage.xml # Django stuff: *.log local_settings.py -db.sqlite3 -db.sqlite3-journal # Flask stuff: instance/ @@ -68,7 +63,11 @@ instance/ # Scrapy stuff: .scrapy +# Sphinx documentation +docs/_build/ + # PyBuilder +.pybuilder/ target/ # Jupyter Notebook @@ -88,7 +87,8 @@ ipython_config.py # install all needed dependencies. #Pipfile.lock -# PEP 582; used by e.g. github.com/David-OConnor/pyflow + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ # Celery stuff @@ -100,12 +100,8 @@ celerybeat.pid # Environments .env +.env.* .venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ # Spyder project settings .spyderproject @@ -114,30 +110,15 @@ venv.bak/ # Rope project settings .ropeproject -# Ignore mkdocs site files generated locally for testing/validation, but generated -# at buildtime in production -site/ -docs/docs/notebooks* +# mkdocs documentation +/site # mypy .mypy_cache/ .dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# Hermit -.hermit # VSCode .vscode # Autogenerated docs files -docs/docs/reference - -## goose session files -.goose - -# ignore lockfile -uv.lock +docs/docs/reference \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c5cb699d..7a4edc4a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,18 +1,45 @@ # Contributing -We welcome Pull Requests for general contributions. If you have a larger new feature or any questions on how -to develop a fix, we recommend you open an issue before starting. +
+Prerequisites • +Evaluations • +Developing and testing • +Building from source • +Developing goose-plugins • +Running ai-exchange from source • +Evaluations • +Conventional Commits +
+ +We welcome Pull Requests for general contributions. If you have a larger new feature or any questions on how to develop a fix, we recommend you open an [issue][issues] before starting. ## Prerequisites We provide a shortcut to standard commands using [just][just] in our `justfile`. -* *goose* uses [uv][uv] for dependency management, and formats with [ruff][ruff] - install UV first: https://pypi.org/project/uv/ +Goose uses [uv][uv] for dependency management, and formats with [ruff][ruff] - install UV first: https://pypi.org/project/uv/ ## Developing and testing Now that you have a local environment, you can make edits and run our tests. +### Creating plugins + +Goose is highly configurable through plugins - it reads in modules that its dependencies install (e.g.`goose-plugins`) and uses those that start with certain prefixes (e.g. `goose.toolkit`) to inject their functionality. For example, you will note that Goose's CLI is actually merged with additional CLI methods that are exported from `goose-plugins`. + +If you are building a net new feature, you should try to fit it inside a plugin. Goose and `goose-plugins` both support plugins, but there's an important difference in how contributions to each are reviewed. Use the guidelines below to decide where to contribute: + +**When to Add to Goose**: + +Plugins added directly to Goose are subject to rigorous review. This is because they are part of the core system and need to meet higher standards for stability, performance, and maintainability, often being validated through benchmarking. + +**When to Add to `goose-plugins`:** + +Plugins in `goose-plugins` undergo less detailed reviews and are more modular or experimental. They can prove their value through usage or iteration over time and may be eventually moved over to Goose. + +To see how to add a toolkit, see the [toolkits documentation][toolkits]. + +### Running tests ```sh uv run pytest tests -m "not integration" ``` @@ -23,119 +50,69 @@ or, as a shortcut, just test ``` -## Running goose from source +## Building from source -`uv run goose session start` +If you want to develop features on `goose`: -will run a fresh goose session (can use the usual goose commands with `uv run` prefixed) +1. Clone Goose: + ```bash + git clone git@github.com:square/goose.git ~/Development/goose + ``` +2. Get `uv` with `brew install uv` +3. Set up your Python virtualenv: +```bash +cd ~/Development/goose +uv sync +uv venv +``` +4. Run the `source` command that follows the `uv venv` command to activate the virtualenv. +5. Run Goose: +```bash +uv run goose session start # or any of goose's commands (e.g. goose --help) +``` + +## Developing goose-plugins + +1. Clone the `goose-plugins` repo: +```bash + git clone git@github.com:square/goose-plugins.git ~/Development/goose-plugins +``` +2. Follow the steps for creating a virtualenv in the `goose` section above +3. Install `goose-plugins` in `goose`. This means any changes to `goose-plugins` in this folder will immediately be reflected in `goose`: +```bash +uv add --editable ~/Development/goose-plugins +``` +4. Make your changes in `goose-plugins`, add the toolkit to the `profiles.yaml` file and run `uv run goose session --start` to see them in action. ## Running ai-exchange from source -goose depends heavily on the https://github.com/square/exchange project, you can clone that repo and then work on both by running: +goose depends heavily on the [`ai-exchange`][ai-exchange] project, you can clone that repo and then work on both by running: ```sh uv add --editableLoading...";
+ e.target.parentElement.appendChild(output);
+
+ const code = e.target.parentElement.previousSibling.previousSibling.querySelector('.language-' + CSS.escape(language));
+ if (code) {
+ const xhr = new XMLHttpRequest();
+ xhr.open("POST", "https://codeserver.sq.dev/api/v1/code/" + language + "/run", true);
+ xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ xhr.send(code.innerText);
+
+ codeServerRequestLoading = true;
+ xhr.onreadystatechange = function () {
+ document.getElementById("loader")?.remove();
+
+ if (xhr.readyState === 4) {
+
+ if (xhr.status === 200) {
+
+ // code result
+ const output = document.createElement("div");
+ output.id = "output";
+ output.innerHTML = "" + xhr.responseText + "";
+ e.target.parentElement.appendChild(output);
+ output.scrollIntoView({behavior: "smooth", block: "center", inline: "nearest"});
+ } else {
+ console.log("Error", xhr.statusText);
+ const output = document.createElement("pre");
+ output.id = "output-error";
+ output.innerHTML = "" + xhr.responseText + "";
+ e.target.parentElement.appendChild(output);
+ output.scrollIntoView({behavior: "smooth", block: "center", inline: "nearest"});
+ }
+ }
+
+ codeServerRequestLoading = false;
+
+ };
+ }
+
+ // do something
+});
+
+function toTitleCase(str) {
+ return str.replace(
+ /\w\S*/g,
+ function (txt) {
+ return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
+ }
+ );
+}
+
+const getPreviousUntil = function (elem, selector) {
+
+ // Setup siblings array and get previous sibling
+ const siblings = [];
+ let prev = elem.previousElementSibling;
+
+ // Loop through all siblings
+ while (prev) {
+
+ // If the matching item is found, quit
+ if (selector && prev.matches(selector)) break;
+
+ // Otherwise, push to array
+ siblings.push(prev);
+
+ // Get the previous sibling
+ prev = prev.previousElementSibling;
+
+ }
+
+ return siblings;
+
+};
diff --git a/docs/docs/assets/logo.gif b/docs/docs/assets/logo.gif
new file mode 100644
index 00000000..90eea64a
Binary files /dev/null and b/docs/docs/assets/logo.gif differ
diff --git a/docs/docs/assets/logo.ico b/docs/docs/assets/logo.ico
new file mode 100644
index 00000000..9e2a5c4a
Binary files /dev/null and b/docs/docs/assets/logo.ico differ
diff --git a/docs/docs/assets/logo.png b/docs/docs/assets/logo.png
new file mode 100644
index 00000000..3ee04189
Binary files /dev/null and b/docs/docs/assets/logo.png differ
diff --git a/docs/docs/available-toolkits.md b/docs/docs/available-toolkits.md
new file mode 100644
index 00000000..a89bb8af
--- /dev/null
+++ b/docs/docs/available-toolkits.md
@@ -0,0 +1,60 @@
+# Available Toolkits in Goose
+
+Goose provides a variety of toolkits designed to help developers with different tasks. Here's an overview of each available toolkit and its functionalities:
+
+## 1. Developer Toolkit
+
+The **Developer** toolkit offers general-purpose development capabilities, including:
+
+- **System Configuration Details:** Retrieves system configuration details.
+- **Task Management:** Update the plan by overwriting all current tasks.
+- **File Operations:**
+ - `patch_file`: Patch a file by replacing specific content.
+ - `read_file`: Read the content of a specified file.
+ - `write_file`: Write content to a specified file.
+- **Shell Command Execution:** Execute shell commands with safety checks.
+
+## 2. GitHub Toolkit
+
+The **GitHub** toolkit provides detailed configuration and procedural guidelines for GitHub operations.
+
+## 3. Lint Toolkit
+
+The **Lint** toolkit ensures that all toolkits have proper documentation. It performs the following checks:
+
+- Toolkit must have a docstring.
+- The first line of the docstring should contain more than 5 words and fewer than 12 words.
+- The first letter of the docstring should be capitalized.
+
+## 4. RepoContext Toolkit
+
+The **RepoContext** toolkit provides context about the current repository. It includes:
+
+- **Repository Size:** Get the size of the repository.
+- **Monorepo Check:** Determine if the repository is a monorepo.
+- **Project Summarization:** Summarize the current project based on the repository or the current project directory.
+
+## 5. Screen Toolkit
+
+The **Screen** toolkit assists users in taking screenshots for debugging or designing purposes. It provides:
+
+- **Take Screenshot:** Capture a screenshot and provide the path to the screenshot file.
+- **System Instructions:** Instructions on how to work with screenshots.
+
+## 6. SummarizeRepo Toolkit
+
+The **SummarizeRepo** toolkit helps in summarizing a repository. It includes:
+
+- **Summarize Repository:** Clone the repository (if not already cloned) and summarize the files based on specified extensions.
+
+## 7. SummarizeProject Toolkit
+
+The **SummarizeProject** toolkit generates or retrieves a summary of a project directory based on specified file extensions. It includes:
+
+- **Get Project Summary:** Generate or retrieve a summary of the project in the specified directory.
+
+## 8. SummarizeFile Toolkit
+
+The **SummarizeFile** toolkit helps in summarizing a specific file. It includes:
+
+- **Summarize File:** Summarize the contents of a specified file with optional instructions.
diff --git a/docs/docs/cli.md b/docs/docs/cli.md
new file mode 100644
index 00000000..5d27563c
--- /dev/null
+++ b/docs/docs/cli.md
@@ -0,0 +1,63 @@
+# Goose CLI Commands
+
+Goose provides a command-line interface (CLI) with various commands to manage sessions, toolkits, and more. Below is a list of the available commands and their descriptions:
+
+## Goose CLI
+
+### `version`
+
+**Usage:**
+```sh
+ goose version
+```
+
+Lists the version of Goose and any associated plugins.
+
+### `session`
+
+#### `start`
+
+**Usage:**
+```sh
+ goose session start [--profile PROFILE] [--plan PLAN]
+```
+
+Starts a new Goose session.
+
+#### `resume`
+
+**Usage:**
+```sh
+ goose session resume [NAME] [--profile PROFILE]
+```
+
+Resumes an existing Goose session.
+
+#### `list`
+
+**Usage:**
+```sh
+ goose session list
+```
+
+Lists all Goose sessions.
+
+#### `clear`
+
+**Usage:**
+```sh
+ goose session clear [--keep KEEP]
+```
+
+Deletes old Goose sessions, keeping the most recent ones as specified by the `--keep` option.
+
+### `toolkit`
+
+#### `list`
+
+**Usage:**
+```sh
+ goose toolkit list
+```
+
+Lists all available toolkits with their descriptions.
diff --git a/docs/docs/configuration.md b/docs/docs/configuration.md
new file mode 100644
index 00000000..c3066864
--- /dev/null
+++ b/docs/docs/configuration.md
@@ -0,0 +1,148 @@
+# Configuring Goose
+
+## Adding a toolkit
+To make a toolkit available to Goose, add it to your project's pyproject.toml. For example in the Goose pyproject.toml file:
+```
+[project.entry-points."goose.toolkit"]
+developer = "goose.toolkit.developer:Developer"
+github = "goose.toolkit.github:Github"
+# Add a line like this - the key becomes the name used in profiles
+my-new-toolkit = "goose.toolkit.my_toolkits:MyNewToolkit" # this is the path to the class that implements the toolkit
+```
+
+Then to set up a profile that uses it, add something to `~/.config/goose/profiles.yaml`:
+```yaml
+my-profile:
+ provider: openai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits: # new toolkit gets added here
+ - developer
+ - my-new-toolkit
+```
+
+And now you can run Goose with this new profile to use the new toolkit!
+
+```sh
+goose session start --profile my-profile
+```
+
+Or, if you're developing a new toolkit and want to test it:
+```sh
+uv run goose session start --profile my-profile
+```
+
+## Tuning it to your repo
+
+Goose ships with the ability to read in the contents of a file named `.goosehints` from your repo. If you find yourself repeating the same information across sessions to Goose, this file is the right place to add this information.
+
+This file will be read into the Goose system prompt if it is present in the current working directory.
+
+> [!NOTE]
+> `.goosehints` follows [jinja templating rules][jinja-guide] in case you want to leverage templating to insert file contents or variables.
+
+## Profiles
+
+If you need to customize goose, one way is via editing: `~/.config/goose/profiles.yaml`.
+
+It will look by default something like (and when you run `goose session start` without the `--profile` flag it will use the `default` profile):
+
+```yaml
+default:
+ provider: open-ai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits:
+ - name: developer
+ requires: {}
+```
+
+### Fields
+
+#### provider
+
+Provider of LLM. LLM providers that currently are supported by Goose:
+
+| Provider | Required environment variable(s) to access provider |
+| ----- | ------------------------------ |
+| openai | `OPENAI_API_KEY` |
+| anthropic | `ANTHROPIC_API_KEY` |
+| databricks | `DATABRICKS_HOST` and `DATABRICKS_TOKEN` |
+
+#### processor
+
+This is the model used for the main Goose loop and main tools -- it should be be capable of complex, multi-step tasks such as writing code and executing commands. Example: `gpt-4o`. You should choose the model based the provider you configured.
+
+#### accelerator
+
+Small model for fast, lightweight tasks. Example: `gpt-4o-mini`. You should choose the model based the provider you configured.
+
+#### moderator
+
+Rules designed to control or manage the output of the model. Moderators that currently are supported by Goose:
+
+- `passive`: does not actively intervene in every response
+- `truncate`: truncates the first contexts when the contexts exceed the max token size
+
+### Example `profiles.yaml` files
+
+#### provider as `anthropic`
+
+```yaml
+
+default:
+ provider: anthropic
+ processor: claude-3-5-sonnet-20240620
+ accelerator: claude-3-5-sonnet-20240620
+```
+
+#### provider as `databricks`
+
+```yaml
+default:
+ provider: databricks
+ processor: databricks-meta-llama-3-1-70b-instruct
+ accelerator: databricks-meta-llama-3-1-70b-instruct
+ moderator: passive
+ toolkits:
+ - name: developer
+ requires: {}
+```
+
+You can tell it to use another provider for example for Anthropic:
+
+```yaml
+default:
+ provider: anthropic
+ processor: claude-3-5-sonnet-20240620
+ accelerator: claude-3-5-sonnet-20240620
+ moderator: passive
+ toolkits:
+ - name: developer
+ requires: {}
+```
+
+this will then use the claude-sonnet model, you will need to set the `ANTHROPIC_API_KEY` to your anthropic API key.
+
+You can also customize Goose's behavior through toolkits. These are set up automatically for you in the same `~/.config/goose/profiles.yaml` file, but you can include or remove toolkits as you see fit.
+
+For example, Goose's `unit-test-gen` command sets up a new profile in this file for you:
+
+```yaml
+unit-test-gen:
+ provider: openai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits:
+ - name: developer
+ requires: {}
+ - name: unit-test-gen
+ requires: {}
+ - name: java
+ requires: {}
+```
+
+[jinja-guide]: https://jinja.palletsprojects.com/en/3.1.x/
diff --git a/docs/docs/contributing.md b/docs/docs/contributing.md
new file mode 120000
index 00000000..f939e75f
--- /dev/null
+++ b/docs/docs/contributing.md
@@ -0,0 +1 @@
+../../CONTRIBUTING.md
\ No newline at end of file
diff --git a/docs/docs/creating-a-new-toolkit.md b/docs/docs/creating-a-new-toolkit.md
new file mode 100644
index 00000000..5b3094fb
--- /dev/null
+++ b/docs/docs/creating-a-new-toolkit.md
@@ -0,0 +1,94 @@
+# Creating a New Toolkit
+
+To add a toolkit, in your code (which doesn't necessarily need to be in the Goose package thanks to [plugin metadata][plugin]!), create a class that derives from the `Toolkit` class.
+
+## Example toolkit class
+Below is an example of a simple toolkit called `Demo` that derives from the `Toolkit` class. This toolkit provides an `authenticate` tool that outputs an authentication code for a user. It also provides system instructions for the model.
+```python
+import os
+import platform
+
+from goose.toolkit.base import Toolkit, tool
+
+
+class Demo(Toolkit):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ # Provide any additional tools as needed!
+ # The docstring of the tool provides instructions to the LLM, so they are important to tune
+ # you do not have to provide any tools, but any function decorated with @tool will be available
+ @tool
+ def authenticate(self, user: str):
+ """Output an authentication code for this user
+
+ Args:
+ user (str): The username to authenticate for
+ """
+ # notifier supports any rich renderable https://rich.readthedocs.io/en/stable/introduction.html#quick-start
+ self.notifier.log(f"[bold red]auth: {str(hash(user))}[/]")
+
+ # Provide any system instructions for the model
+ # This can be generated dynamically, and is run at startup time
+ def system(self) -> str:
+ print("new")
+ return f"""**You must preceed your first message by using the authenticate tool for the current user**
+
+ ```
+ platform: {platform.system()}
+ cwd: {os.getcwd()}
+ user: {os.environ.get('USER')}
+ ```
+ """
+```
+
+## Exposing the New Toolkit to Goose
+
+To make the toolkit available, add it to the `pyproject.toml` file and then update your `profiles.yaml` file.
+
+### Update the `pyproject.toml` file
+If you're adding the new toolkit to Goose or the Goose Plugins repo, simply find the `[project.entry-points."goose.toolkit"]` section in `pyproject.toml` and add a line like this:
+```toml
+[project.entry-points."goose.toolkit"]
+developer = "goose.toolkit.developer:Developer"
+github = "goose.toolkit.github:Github"
+# Add a line like this - the key becomes the name used in profiles
+demo = "goose.toolkit.demo:Demo"
+```
+
+If you are adding the toolkit to a different package, see the docs for `goose-plugins` for more information on how to create a plugins repository that can be used by Goose.
+
+### Update the `profiles.yaml` file
+And then to set up a profile that uses it, add something to ~/.config/goose/profiles.yaml
+```yaml
+default:
+ provider: openai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits:
+ - name: developer
+ requires: {}
+demo-profile:
+ provider: openai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits:
+ - developer
+ - demo
+```
+
+And now you can run goose with this new profile to use the new toolkit!
+
+```sh
+goose session start --profile demo-profile
+```
+
+> [!NOTE]
+> If you're using a plugin from `goose-plugins`, make sure `goose-plugins` is installed in your environment. You can install it via pip:
+>
+> `pipx install goose-ai --preinstall goose-plugins`
+
+[plugin]: https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-package-metadata
+[goose-plugins]: https://github.com/square/goose-plugins
diff --git a/docs/docs/css/code_select.css b/docs/docs/css/code_select.css
new file mode 100644
index 00000000..856995da
--- /dev/null
+++ b/docs/docs/css/code_select.css
@@ -0,0 +1,5 @@
+.highlight .gp,
+.highlight .go {
+ /* Generic.Prompt, Generic.Output */
+ user-select: none;
+}
\ No newline at end of file
diff --git a/docs/docs/index.md b/docs/docs/index.md
new file mode 100644
index 00000000..b2b993a6
--- /dev/null
+++ b/docs/docs/index.md
@@ -0,0 +1,18 @@
+# Goose
+
+Github: [`square/goose`][square/goose]
+
+
+### goose
+* PyPi package name: [`goose-ai`][goose-ai]
+* GitHub: [square/goose]
+
+### exchange
+* PyPi package name: [`ai-exchange`][ai-exchange]
+* GitHub: [square/exchange]
+
+[goose-ai]: https://pypi.org/project/goose-ai/
+[square/goose]: https://github.com/square/goose
+[ai-exchange]: https://pypi.org/project/ai-exchange/
+[square/exchange]: https://github.com/square/exchange
+[install]: installation.md
diff --git a/docs/docs/installation.md b/docs/docs/installation.md
new file mode 100644
index 00000000..641f0e09
--- /dev/null
+++ b/docs/docs/installation.md
@@ -0,0 +1,18 @@
+# Installation
+
+To install Goose, use `pipx`.First ensure [pipx][pipx] is installed:
+
+``` sh
+brew install pipx
+pipx ensurepath
+```
+
+Then install Goose:
+
+```sh
+pipx install goose-ai
+```
+
+[pipx]: https://github.com/pypa/pipx?tab=readme-ov-file#install-pipx
+
+You can then run `goose` from the command line with `goose session start`.
\ No newline at end of file
diff --git a/docs/docs/plugins.md b/docs/docs/plugins.md
new file mode 100644
index 00000000..b95ca5a9
--- /dev/null
+++ b/docs/docs/plugins.md
@@ -0,0 +1,15 @@
+# Plugins in Goose
+
+Goose's functionality is extended via plugins. These plugins fall into three main categories:
+
+1. **Toolkits**:
+ * Provides Goose with tools (functions) it can call and optionally will load additional context into the system prompt (such as 'The Github CLI is called via `gh` and you should use it to run git commands').
+ * Toolkits can do basically anything, from calling external APIs, to taking a screenshot of your screen, to summarizing your current project.
+2. **CLI commands**:
+ * Provides additional commands to the Goose CLI.
+ * These commands can be used to interact with the Goose system, such as listing available toolkits or summarizing a session.
+3. **Providers**:
+ * Provides Goose with access to external LLMs.
+ * For example, the OpenAI provider allows Goose to interact with the OpenAI API.
+ * Most providers for Goose are defined in the Exchange library.
+
diff --git a/docs/docs/providers.md b/docs/docs/providers.md
new file mode 100644
index 00000000..aab25c5e
--- /dev/null
+++ b/docs/docs/providers.md
@@ -0,0 +1,3 @@
+# Providers
+
+Providers in Goose mean "LLM providers" that Goose can interact with. Providers are defined in the Exchange library for the most part, but you can define your own.
\ No newline at end of file
diff --git a/docs/docs/tips.md b/docs/docs/tips.md
new file mode 100644
index 00000000..d07bac48
--- /dev/null
+++ b/docs/docs/tips.md
@@ -0,0 +1,20 @@
+## tips
+
+Here are some collected tips we have for working efficiently with `goose`
+
+- **`goose` can and will edit files**. Use a git strategy to avoid losing anything - such as staging your
+personal edits and leaving `goose` edits unstaged until reviewed. Or consider using individual commits which can be reverted.
+- **`goose` can and will run commands**. You can ask it to check with you first if you are concerned. It will check commands for safety as well.
+- You can interrupt `goose` with `CTRL+C` to correct it or give it more info.
+- `goose` works best when solving concrete problems - experiment with how far you need to break that problem
+down to get `goose` to solve it. Be specific! E.g. it will likely fail to `"create a banking app"`,
+but probably does a good job if prompted with `"create a Fastapi app with an endpoint for deposit and withdrawal and with account balances stored in mysql keyed by id"`
+- If `goose` doesn't have enough context to start with, it might go down the wrong direction. Tell it
+to read files that you are referring to or search for objects in code. Even better, ask it to summarize
+them for you, which will help it set up its own next steps.
+- Refer to any objects in files with something that is easy to search for, such as `"the MyExample class"
+- `goose` *loves* to know how to run tests to get a feedback loop going, just like you do. If you tell it how you test things locally and quickly, it can make use of that when working on your project
+- You can use `goose` for tasks that would require scripting at times, even looking at your screen and correcting designs/helping you fix bugs, try asking it to help you in a way you would ask a person.
+- `goose` will make mistakes, and go in the wrong direction from times, feel free to correct it, or start again.
+- You can tell `goose` to run things for you continuously (and it will iterate, try, retry) but you can also tell it to check with you before doing things (and then later on tell it to go off on its own and do its best to solve).
+- `goose` can run anywhere, doesn't have to be in a repo, just ask it!
\ No newline at end of file
diff --git a/docs/docs/toolkits.md b/docs/docs/toolkits.md
new file mode 100644
index 00000000..a308d607
--- /dev/null
+++ b/docs/docs/toolkits.md
@@ -0,0 +1,202 @@
+# Toolkits
+
+This page contains information about building and using toolkits in Goose. Toolkits are a way to extend Goose's capabilities by adding new tools and functionalities. You can create your own toolkits or use the existing ones provided by Goose.
+
+## Using Toolkits
+
+Use `goose toolkit list` to list the available toolkits.
+
+### Toolkits defined in Goose
+
+Using Goose with toolkits is simple. You can add toolkits to your profile in the `profiles.yaml` file. Here's an example of how to add `my-toolkit` toolkit to your profile:
+
+```yaml
+my-profile:
+ provider: openai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits:
+ - my-toolkit
+```
+
+Then run Goose with the specified profile:
+
+```sh
+goose session start --profile my-profile
+```
+
+### Toolkits defined in Goose Plugins
+
+1. First make sure that `goose-plugins` is intalled with Goose:
+```sh
+pipx install goose-ai --preinstall goose-plugins
+```
+2. Update the `profiles.yaml` file to include the desired toolkit:
+```yaml
+my-profile:
+ provider: openai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits:
+ - my-goose-plugins-toolkit
+```
+
+## Building a Toolkit
+
+To add a toolkit, in your code (which doesn't necessarily need to be in the Goose package thanks to [plugin metadata][plugin]!), create a class that derives from the `Toolkit` class.
+
+### Example toolkit class
+Below is an example of a simple toolkit called `Demo` that derives from the `Toolkit` class. This toolkit provides an `authenticate` tool that outputs an authentication code for a user. It also provides system instructions for the model.
+```python
+import os
+import platform
+
+from goose.toolkit.base import Toolkit, tool
+
+
+class Demo(Toolkit):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ # Provide any additional tools as needed!
+ # The docstring of the tool provides instructions to the LLM, so they are important to tune
+ # you do not have to provide any tools, but any function decorated with @tool will be available
+ @tool
+ def authenticate(self, user: str):
+ """Output an authentication code for this user
+
+ Args:
+ user (str): The username to authenticate for
+ """
+ # notifier supports any rich renderable https://rich.readthedocs.io/en/stable/introduction.html#quick-start
+ self.notifier.log(f"[bold red]auth: {str(hash(user))}[/]")
+
+ # Provide any system instructions for the model
+ # This can be generated dynamically, and is run at startup time
+ def system(self) -> str:
+ print("new")
+ return f"""**You must preceed your first message by using the authenticate tool for the current user**
+
+ ```
+ platform: {platform.system()}
+ cwd: {os.getcwd()}
+ user: {os.environ.get('USER')}
+ ```
+ """
+```
+
+### Exposing the new toolkit to Goose
+
+To make the toolkit available, add it to the `pyproject.toml` file and then update your `profiles.yaml` file.
+
+#### Update the `pyproject.toml` file
+If you're adding the new toolkit to Goose or the Goose Plugins repo, simply find the `[project.entry-points."goose.toolkit"]` section in `pyproject.toml` and add a line like this:
+```toml
+[project.entry-points."goose.toolkit"]
+developer = "goose.toolkit.developer:Developer"
+github = "goose.toolkit.github:Github"
+# Add a line like this - the key becomes the name used in profiles
+demo = "goose.toolkit.demo:Demo"
+```
+
+If you are adding the toolkit to a different package, see the docs for `goose-plugins` for more information on how to create a plugins repository that can be used by Goose.
+
+#### Update the `profiles.yaml` file
+And then to set up a profile that uses it, add something to ~/.config/goose/profiles.yaml
+```yaml
+default:
+ provider: openai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits:
+ - name: developer
+ requires: {}
+demo:
+ provider: openai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits:
+ - developer
+ - demo
+```
+
+And now you can run goose with this new profile to use the new toolkit!
+
+```sh
+goose session start --profile demo
+```
+
+> [!NOTE]
+> If you're using a plugin from `goose-plugins`, make sure `goose-plugins` is installed in your environment. You can install it via pip:
+>
+> `pipx install goose-ai --preinstall goose-plugins`
+
+## Available Toolkits in Goose
+
+To see the available toolkits to you, run `goose toolkit list`, this will show the toolkits defined below as well as any other Goose modules you have installed (for example, `goose-plugins`).
+
+Goose provides a variety of toolkits designed to help developers with different tasks. Here's an overview of each available toolkit and its functionalities:
+
+### 1. Developer Toolkit
+
+The **Developer** toolkit offers general-purpose development capabilities, including:
+
+- **System Configuration Details:** Retrieves system configuration details.
+- **Task Management:** Update the plan by overwriting all current tasks.
+- **File Operations:**
+ - `patch_file`: Patch a file by replacing specific content.
+ - `read_file`: Read the content of a specified file.
+ - `write_file`: Write content to a specified file.
+- **Shell Command Execution:** Execute shell commands with safety checks.
+
+### 2. GitHub Toolkit
+
+The **GitHub** toolkit provides detailed configuration and procedural guidelines for GitHub operations.
+
+### 3. Lint Toolkit
+
+The **Lint** toolkit ensures that all toolkits have proper documentation. It performs the following checks:
+
+- Toolkit must have a docstring.
+- The first line of the docstring should contain more than 5 words and fewer than 12 words.
+- The first letter of the docstring should be capitalized.
+
+### 4. RepoContext Toolkit
+
+The **RepoContext** toolkit provides context about the current repository. It includes:
+
+- **Repository Size:** Get the size of the repository.
+- **Monorepo Check:** Determine if the repository is a monorepo.
+- **Project Summarization:** Summarize the current project based on the repository or the current project directory.
+
+### 5. Screen Toolkit
+
+The **Screen** toolkit assists users in taking screenshots for debugging or designing purposes. It provides:
+
+- **Take Screenshot:** Capture a screenshot and provide the path to the screenshot file.
+- **System Instructions:** Instructions on how to work with screenshots.
+
+### 6. SummarizeRepo Toolkit
+
+The **SummarizeRepo** toolkit helps in summarizing a repository. It includes:
+
+- **Summarize Repository:** Clone the repository (if not already cloned) and summarize the files based on specified extensions.
+
+### 7. SummarizeProject Toolkit
+
+The **SummarizeProject** toolkit generates or retrieves a summary of a project directory based on specified file extensions. It includes:
+
+- **Get Project Summary:** Generate or retrieve a summary of the project in the specified directory.
+
+### 8. SummarizeFile Toolkit
+
+The **SummarizeFile** toolkit helps in summarizing a specific file. It includes:
+
+- **Summarize File:** Summarize the contents of a specified file with optional instructions.
+
+[plugin]: https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-package-metadata
+[goose-plugins]: https://github.com/square/goose-plugins
diff --git a/docs/docs/using-toolkits.md b/docs/docs/using-toolkits.md
new file mode 100644
index 00000000..189e0b7c
--- /dev/null
+++ b/docs/docs/using-toolkits.md
@@ -0,0 +1,41 @@
+# Using Toolkits
+
+Use `goose toolkit list` to list the available toolkits.
+
+## Toolkits defined in Goose
+
+Using Goose with toolkits is simple. You can add toolkits to your profile in the `profiles.yaml` file. Here's an example of how to add `my-toolkit` toolkit to your profile:
+
+```yaml
+my-profile:
+ provider: openai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits:
+ - my-toolkit
+```
+
+Then run Goose with the specified profile:
+
+```sh
+goose session start --profile my-profile
+```
+
+## Toolkits defined in Goose Plugins
+
+1. First make sure that `goose-plugins` is intalled with Goose:
+```sh
+pipx install goose-ai --preinstall goose-plugins
+```
+2. Update the `profiles.yaml` file to include the desired toolkit:
+```yaml
+my-profile:
+ provider: openai
+ processor: gpt-4o
+ accelerator: gpt-4o-mini
+ moderator: passive
+ toolkits:
+ - my-goose-plugins-toolkit
+```
+
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
new file mode 100644
index 00000000..d6e6a020
--- /dev/null
+++ b/docs/mkdocs.yml
@@ -0,0 +1,110 @@
+site_name: Goose Documentation
+site_author: Block
+site_description: Documentation for Goose
+repo_url: https://github.com/square/goose
+repo_name: "square/goose"
+edit_uri: "https://github.com/square/goose/blob/main/docs/docs/"
+# site_url: https://goose-docs.squarecloudservices.com
+theme:
+ name: material
+ features:
+ - announce.dismiss
+ - content.action.edit
+ - content.action.view
+ - content.code.annotate
+ - content.code.copy
+ - content.tooltips
+ - content.tabs.link
+ - navigation.footer
+ - navigation.indexes
+ - navigation.instant
+ - navigation.sections
+ - navigation.top
+ - navigation.tracking
+ - navigation.expand
+ - search.share
+ - search.suggest
+ - toc.follow
+ palette:
+ - scheme: slate
+ primary: black
+ accent: indigo
+ logo: assets/logo.png
+ font:
+ text: Roboto
+ code: Roboto Mono
+ favicon: assets/logo.ico
+ icon:
+ logo: assets/logo.ico
+plugins:
+ - include-markdown
+ - callouts
+ - glightbox
+ - search:
+ separator: '[\s\u200b\-_,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
+ - redirects:
+ redirect_maps:
+extra:
+ annotate:
+ json:
+ - .s2
+ social: [ ]
+ analytics:
+ provider: google
+ property: !ENV GOOGLE_ANALYTICS_KEY
+markdown_extensions:
+ - abbr
+ - admonition
+ - attr_list
+ - def_list
+ - footnotes
+ - md_in_html
+ - nl2br # Newline to