chore: create mkdocs for goose (#70)
37
.gitignore
vendored
@@ -20,12 +20,10 @@ parts/
|
|||||||
sdist/
|
sdist/
|
||||||
var/
|
var/
|
||||||
wheels/
|
wheels/
|
||||||
pip-wheel-metadata/
|
|
||||||
share/python-wheels/
|
share/python-wheels/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
.installed.cfg
|
.installed.cfg
|
||||||
*.egg
|
*.egg
|
||||||
MANIFEST
|
|
||||||
|
|
||||||
# PyInstaller
|
# PyInstaller
|
||||||
# Usually these files are written by a python script from a template
|
# Usually these files are written by a python script from a template
|
||||||
@@ -49,7 +47,6 @@ coverage.xml
|
|||||||
*.cover
|
*.cover
|
||||||
*.py,cover
|
*.py,cover
|
||||||
.hypothesis/
|
.hypothesis/
|
||||||
.pytest_cache/
|
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
*.mo
|
*.mo
|
||||||
@@ -58,8 +55,6 @@ coverage.xml
|
|||||||
# Django stuff:
|
# Django stuff:
|
||||||
*.log
|
*.log
|
||||||
local_settings.py
|
local_settings.py
|
||||||
db.sqlite3
|
|
||||||
db.sqlite3-journal
|
|
||||||
|
|
||||||
# Flask stuff:
|
# Flask stuff:
|
||||||
instance/
|
instance/
|
||||||
@@ -68,7 +63,11 @@ instance/
|
|||||||
# Scrapy stuff:
|
# Scrapy stuff:
|
||||||
.scrapy
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
# PyBuilder
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
target/
|
target/
|
||||||
|
|
||||||
# Jupyter Notebook
|
# Jupyter Notebook
|
||||||
@@ -88,7 +87,8 @@ ipython_config.py
|
|||||||
# install all needed dependencies.
|
# install all needed dependencies.
|
||||||
#Pipfile.lock
|
#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__/
|
__pypackages__/
|
||||||
|
|
||||||
# Celery stuff
|
# Celery stuff
|
||||||
@@ -100,12 +100,8 @@ celerybeat.pid
|
|||||||
|
|
||||||
# Environments
|
# Environments
|
||||||
.env
|
.env
|
||||||
|
.env.*
|
||||||
.venv
|
.venv
|
||||||
env/
|
|
||||||
venv/
|
|
||||||
ENV/
|
|
||||||
env.bak/
|
|
||||||
venv.bak/
|
|
||||||
|
|
||||||
# Spyder project settings
|
# Spyder project settings
|
||||||
.spyderproject
|
.spyderproject
|
||||||
@@ -114,30 +110,15 @@ venv.bak/
|
|||||||
# Rope project settings
|
# Rope project settings
|
||||||
.ropeproject
|
.ropeproject
|
||||||
|
|
||||||
# Ignore mkdocs site files generated locally for testing/validation, but generated
|
# mkdocs documentation
|
||||||
# at buildtime in production
|
/site
|
||||||
site/
|
|
||||||
docs/docs/notebooks*
|
|
||||||
|
|
||||||
# mypy
|
# mypy
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
.dmypy.json
|
.dmypy.json
|
||||||
dmypy.json
|
|
||||||
|
|
||||||
# Pyre type checker
|
|
||||||
.pyre/
|
|
||||||
|
|
||||||
# Hermit
|
|
||||||
.hermit
|
|
||||||
|
|
||||||
# VSCode
|
# VSCode
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
# Autogenerated docs files
|
# Autogenerated docs files
|
||||||
docs/docs/reference
|
docs/docs/reference
|
||||||
|
|
||||||
## goose session files
|
|
||||||
.goose
|
|
||||||
|
|
||||||
# ignore lockfile
|
|
||||||
uv.lock
|
|
||||||
|
|||||||
165
CONTRIBUTING.md
@@ -1,18 +1,45 @@
|
|||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
We welcome Pull Requests for general contributions. If you have a larger new feature or any questions on how
|
<p>
|
||||||
to develop a fix, we recommend you open an issue before starting.
|
<a href="#prerequisites">Prerequisites</a> •
|
||||||
|
<a href="#evaluations">Evaluations</a> •
|
||||||
|
<a href="#developing-and-testing">Developing and testing</a> •
|
||||||
|
<a href="#building-from-source">Building from source</a> •
|
||||||
|
<a href="#developing-goose-plugins">Developing goose-plugins</a> •
|
||||||
|
<a href="#running-ai-exchange-from-source">Running ai-exchange from source</a> •
|
||||||
|
<a href="#evaluations">Evaluations</a> •
|
||||||
|
<a href="#conventional-commits">Conventional Commits</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
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
|
## Prerequisites
|
||||||
|
|
||||||
We provide a shortcut to standard commands using [just][just] in our `justfile`.
|
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
|
## Developing and testing
|
||||||
|
|
||||||
Now that you have a local environment, you can make edits and run our tests.
|
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
|
```sh
|
||||||
uv run pytest tests -m "not integration"
|
uv run pytest tests -m "not integration"
|
||||||
```
|
```
|
||||||
@@ -23,119 +50,69 @@ or, as a shortcut,
|
|||||||
just test
|
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
|
## 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
|
```sh
|
||||||
uv add --editable <path/to/cloned/exchange>
|
uv add --editable <path/to/cloned/exchange>
|
||||||
|
```
|
||||||
|
|
||||||
then when you run goose with `uv run goose` it will be running it all from source.
|
then when you run goose with `uv run goose session start` it will be running it all from source.
|
||||||
|
|
||||||
## Evaluations
|
## Evaluations
|
||||||
|
|
||||||
Given that so much of *goose* involves interactions with LLMs, our unit tests only go so far to
|
Given that so much of Goose involves interactions with LLMs, our unit tests only go so far to confirming things work as intended.
|
||||||
confirming things work as intended.
|
|
||||||
|
|
||||||
We're currently developing a suite of evalutions, to make it easier to make improvements to *goose* more confidently.
|
We're currently developing a suite of evaluations, to make it easier to make improvements to Goose more confidently.
|
||||||
|
|
||||||
In the meantime, we typically incubate any new additions that change the behavior of the *goose*
|
In the meantime, we typically incubate any new additions that change the behavior of the Goose through **opt-in** plugins - `Toolkit`s, `Moderator`s, and `Provider`s. We welcome contributions of plugins that add new capabilities to *goose*. We recommend sending in several examples of the new capabilities in action with your pull request.
|
||||||
through **opt-in** plugins - `Toolkit`s, `Moderator`s, and `Provider`s. We welcome contributions of plugins
|
|
||||||
that add new capabilities to *goose*. We recommend sending in several examples of the new capabilities
|
|
||||||
in action with your pull request.
|
|
||||||
|
|
||||||
Additions to the [developer toolkit][developer] change the core performance, and so will need to be measured carefully.
|
Additions to the [developer toolkit][developer] change the core performance, and so will need to be measured carefully.
|
||||||
|
|
||||||
## Build a Toolkit
|
|
||||||
|
|
||||||
To add a toolkit, start out with a plugin as mentioned above. 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 Toolkit.
|
|
||||||
|
|
||||||
```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')}
|
|
||||||
```
|
|
||||||
"""
|
|
||||||
```
|
|
||||||
|
|
||||||
To make the toolkit available, add it as a plugin. For example in a pyproject.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"
|
|
||||||
```
|
|
||||||
|
|
||||||
And then to setup 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
|
|
||||||
```
|
|
||||||
|
|
||||||
## Conventional Commits
|
## Conventional Commits
|
||||||
|
|
||||||
This project follows the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification for PR titles. Conventional Commits make it easier to understand the history of a project and facilitate automation around versioning and changelog generation.
|
This project follows the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification for PR titles. Conventional Commits make it easier to understand the history of a project and facilitate automation around versioning and changelog generation.
|
||||||
|
|
||||||
|
[issues]: https://github.com/square/goose/issues
|
||||||
|
[goose-plugins]: https://github.com/square/goose-plugins
|
||||||
|
[ai-exchange]: https://github.com/square/exchange
|
||||||
[developer]: src/goose/toolkit/developer.py
|
[developer]: src/goose/toolkit/developer.py
|
||||||
[uv]: https://docs.astral.sh/uv/
|
[uv]: https://docs.astral.sh/uv/
|
||||||
[ruff]: https://docs.astral.sh/ruff/
|
[ruff]: https://docs.astral.sh/ruff/
|
||||||
[just]: https://github.com/casey/just
|
[just]: https://github.com/casey/just
|
||||||
[plugin]: https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-package-metadata
|
[toolkits]: docs/docs/toolkits.md
|
||||||
BIN
docs/docs/assets/bg.png
Normal file
|
After Width: | Height: | Size: 705 KiB |
BIN
docs/docs/assets/bg2.png
Normal file
|
After Width: | Height: | Size: 620 KiB |
BIN
docs/docs/assets/bg3.png
Normal file
|
After Width: | Height: | Size: 684 KiB |
BIN
docs/docs/assets/bg4.png
Normal file
|
After Width: | Height: | Size: 490 KiB |
213
docs/docs/assets/docs.css
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
/*@media only screen and (min-width: 76.25em) {*/
|
||||||
|
/* .md-main__inner {*/
|
||||||
|
/* max-width: none;*/
|
||||||
|
/* }*/
|
||||||
|
/* .md-sidebar--primary {*/
|
||||||
|
/* left: 0;*/
|
||||||
|
/* }*/
|
||||||
|
/* .md-sidebar--secondary {*/
|
||||||
|
/* right: 0;*/
|
||||||
|
/* margin-left: 0;*/
|
||||||
|
/* -webkit-transform: none;*/
|
||||||
|
/* transform: none;*/
|
||||||
|
/* }*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
--md-code-fg-color: white !important;
|
||||||
|
--md-code-bg-color: rgba(0, 0, 0, .5) !important;
|
||||||
|
--shadow-color: #FF9E9E;
|
||||||
|
--shadow-color-light: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#__mermaid_0 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typeset code {
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reduce the space between the term and definition in a definition list
|
||||||
|
Reads better for flags and their documention in CLI options lists */
|
||||||
|
.md-typeset dd {
|
||||||
|
margin-top: 0.125em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We want syntax highlighting in fenced codeblocks describing shell commands
|
||||||
|
because it's nice to see comments dimmed and quoted strings highlighted. */
|
||||||
|
.md-typeset .language-bash {
|
||||||
|
/* We don't need to syntax-highlight numbers in bash blocks */
|
||||||
|
--md-code-hl-number-color: var(--md-code-fg-color);
|
||||||
|
/* We don't need to syntax-highlight shell-native functions (like `cd`) in bash blocks */
|
||||||
|
--md-code-hl-constant-color: var(--md-code-fg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight .kc, .highlight .n {
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
body .md-sidebar--primary .md-sidebar__scrollwrap {
|
||||||
|
border-right: 1px solid #454755;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-container {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 76.25em) {
|
||||||
|
.md-main::before {
|
||||||
|
content: "";
|
||||||
|
|
||||||
|
background-size: cover !important;
|
||||||
|
background-repeat: no-repeat !important;
|
||||||
|
background-attachment: fixed !important;
|
||||||
|
background-position: center !important;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
z-index: -99999;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
opacity: .06;
|
||||||
|
|
||||||
|
animation: changeBg 15s infinite ease-in-out;
|
||||||
|
|
||||||
|
-webkit-transition: background 15s linear;
|
||||||
|
-moz-transition: background 15s linear;
|
||||||
|
-o-transition: background 15s linear;
|
||||||
|
-ms-transition: background 15s linear;
|
||||||
|
transition: background 15s linear;
|
||||||
|
|
||||||
|
animation-duration: 15s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-direction: alternate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes changeBg {
|
||||||
|
0% {
|
||||||
|
background-image: var(--bg1);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
background-image: var(--bg2);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
background-image: var(--bg3);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
background-image: var(--bg4);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-image: var(--bg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-header {
|
||||||
|
background-color: rgba(14, 20, 24, 0.9) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-tabs {
|
||||||
|
background-color: rgba(14, 20, 24, 0.6) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 76.25em) {
|
||||||
|
.md-nav--lifted > .md-nav__list > .md-nav__item--active > .md-nav__link {
|
||||||
|
background: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-nav__toggle.md-toggle--indeterminate~.md-nav, .md-nav__toggle:checked~.md-nav, .md-nav__toggle~.md-nav {
|
||||||
|
-webkit-transition-property: none;
|
||||||
|
-moz-transition-property: none;
|
||||||
|
-o-transition-property: none;
|
||||||
|
transition-property: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 60em) {
|
||||||
|
.md-nav--secondary .md-nav__title {
|
||||||
|
background: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*add a subtle breathing effect to admonitions border*/
|
||||||
|
.admonition {
|
||||||
|
animation: pulsate 10s infinite;
|
||||||
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulsate {
|
||||||
|
0% {
|
||||||
|
-webkit-box-shadow: inset 0 0 .075rem rgb(138, 163, 255);
|
||||||
|
-moz-box-shadow: inset 0 0 .075rem rgb(138, 163, 255);
|
||||||
|
box-shadow: inset 0 0 .075rem rgb(138, 163, 255);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
border-color: rgba(255, 255, 255, .5);
|
||||||
|
-webkit-box-shadow: inset 0 0 .075rem rgba(255, 255, 255, .5);
|
||||||
|
-moz-box-shadow: inset 0 0 .075rem rgba(255, 255, 255, .5);
|
||||||
|
box-shadow: inset 0 0 .075rem rgba(255, 255, 255, .5);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
-webkit-box-shadow: inset 0 0 .075rem rgb(138, 163, 255);
|
||||||
|
-moz-box-shadow: inset 0 0 .075rem rgb(138, 163, 255);
|
||||||
|
box-shadow: inset 0 0 .075rem rgb(138, 163, 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*pop code elements a tad*/
|
||||||
|
code {
|
||||||
|
border: .075rem solid rgba(0, 0, 0, .3);
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon {
|
||||||
|
color: white;
|
||||||
|
animation: neon 3s infinite;
|
||||||
|
margin: calc(50vh - 40px) auto 0 auto;
|
||||||
|
font-size: 25px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-family: "Archivo Black", "Archivo", sans-serif;
|
||||||
|
font-weight: normal;
|
||||||
|
display: block;
|
||||||
|
height: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes neon {
|
||||||
|
0% {
|
||||||
|
text-shadow: -1px -1px 1px var(--shadow-color-light), -1px 1px 1px var(--shadow-color-light), 1px -1px 1px var(--shadow-color-light), 1px 1px 1px var(--shadow-color-light),
|
||||||
|
0 0 3px var(--shadow-color-light), 0 0 10px var(--shadow-color-light), 0 0 20px var(--shadow-color-light),
|
||||||
|
0 0 30px var(--shadow-color), 0 0 20px var(--shadow-color), 0 0 25px var(--shadow-color), 0 0 35px var(--shadow-color), 0 0 25px var(--shadow-color), 0 0 25px var(--shadow-color);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
text-shadow: -1px -1px 1px var(--shadow-color-light), -1px 1px 1px var(--shadow-color-light), 1px -1px 1px var(--shadow-color-light), 1px 1px 1px var(--shadow-color-light),
|
||||||
|
0 0 5px var(--shadow-color-light), 0 0 15px var(--shadow-color-light), 0 0 25px var(--shadow-color-light),
|
||||||
|
0 0 40px var(--shadow-color), 0 0 25px var(--shadow-color), 0 0 30px var(--shadow-color), 0 0 40px var(--shadow-color), 0 0 30px var(--shadow-color), 0 0 30px var(--shadow-color);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
text-shadow: -1px -1px 1px var(--shadow-color-light), -1px 1px 1px var(--shadow-color-light), 1px -1px 1px var(--shadow-color-light), 1px 1px 1px var(--shadow-color-light),
|
||||||
|
0 0 3px var(--shadow-color-light), 0 0 10px var(--shadow-color-light), 0 0 20px var(--shadow-color-light),
|
||||||
|
0 0 30px var(--shadow-color), 0 0 20px var(--shadow-color), 0 0 25px var(--shadow-color), 0 0 35px var(--shadow-color), 0 0 25px var(--shadow-color), 0 0 25px var(--shadow-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-nav__item--section>.md-nav__link[for] {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this is the top nav item side left */
|
||||||
|
.md-nav--lifted>.md-nav__list>.md-nav__item>[for] {
|
||||||
|
color: white;
|
||||||
|
position: absolute; /* otherwise scroll overflow does not look great */
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-nav__link--active {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
261
docs/docs/assets/docs.js
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
const backgrounds = [
|
||||||
|
"/assets/bg.png",
|
||||||
|
"/assets/bg2.png",
|
||||||
|
"/assets/bg3.png",
|
||||||
|
"/assets/bg4.png",
|
||||||
|
];
|
||||||
|
|
||||||
|
// this is to preload the images so the transition is smooth.
|
||||||
|
// otherwise, on transition image will flicker without smooth transition.
|
||||||
|
|
||||||
|
var hiddenContainer = document.createElement('div');
|
||||||
|
hiddenContainer.style.display = 'none';
|
||||||
|
document.body.appendChild(hiddenContainer);
|
||||||
|
|
||||||
|
let index = 1;
|
||||||
|
for (let bg of backgrounds) {
|
||||||
|
let img = [];
|
||||||
|
img[index] = new Image();
|
||||||
|
img[index].src = bg;
|
||||||
|
|
||||||
|
hiddenContainer.appendChild(img[index]);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function shuffleBackgrounds() {
|
||||||
|
let images = []; // preload
|
||||||
|
let index = 1;
|
||||||
|
for (let bg of shuffle(backgrounds)) {
|
||||||
|
document.body.style.setProperty("--bg" + index, "url(" + bg + ")");
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function shuffle(array) {
|
||||||
|
let currentIndex = array.length, randomIndex;
|
||||||
|
|
||||||
|
// While there remain elements to shuffle.
|
||||||
|
while (currentIndex !== 0) {
|
||||||
|
|
||||||
|
// Pick a remaining element.
|
||||||
|
randomIndex = Math.floor(Math.random() * currentIndex);
|
||||||
|
currentIndex--;
|
||||||
|
|
||||||
|
// And swap it with the current element.
|
||||||
|
[array[currentIndex], array[randomIndex]] = [
|
||||||
|
array[randomIndex], array[currentIndex]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
shuffleBackgrounds();
|
||||||
|
|
||||||
|
window.onload = function () {
|
||||||
|
onLoad();
|
||||||
|
};
|
||||||
|
|
||||||
|
let origOpen = XMLHttpRequest.prototype.open;
|
||||||
|
XMLHttpRequest.prototype.open = function () {
|
||||||
|
let url = arguments[1]; // The second argument is the URL
|
||||||
|
|
||||||
|
this.addEventListener('loadend', function (e) {
|
||||||
|
if (url.includes("https://codeserver.sq.dev/api/v1/health")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(url);
|
||||||
|
|
||||||
|
// make sure we have a full render before calling onLoad
|
||||||
|
setTimeout(() => {
|
||||||
|
onLoad();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
origOpen.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
let healthCheckTimer = null;
|
||||||
|
|
||||||
|
function onLoad() {
|
||||||
|
|
||||||
|
console.log("onLoad");
|
||||||
|
let interactiveCodePage = false;
|
||||||
|
document.querySelectorAll("a").forEach((e) => {
|
||||||
|
if (e.innerText === "Run Code") {
|
||||||
|
interactiveCodePage = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (interactiveCodePage) {
|
||||||
|
document.querySelectorAll("code").forEach((e) => {
|
||||||
|
e.style.maxHeight = "40vh";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (healthCheckTimer) {
|
||||||
|
console.log("clearing health check timer");
|
||||||
|
clearInterval(healthCheckTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
healthCheckTimer = setInterval(() => {
|
||||||
|
// if the tab is not visible, don't check
|
||||||
|
if (document.hidden) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if https://codeserver.sq.dev/api/v1/health is up
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", "https://codeserver.sq.dev/api/v1/health", true);
|
||||||
|
xhr.send();
|
||||||
|
xhr.timeout = 1000;
|
||||||
|
xhr.onreadystatechange = function () {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
document.querySelectorAll("a").forEach((e) => {
|
||||||
|
if (e.innerText === "Code Server is down") {
|
||||||
|
e.innerText = "Run Code";
|
||||||
|
e.onclick = function () {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
document.querySelectorAll("a").forEach((e) => {
|
||||||
|
if (e.innerText === "Run Code") {
|
||||||
|
e.innerText = "Code Server is down";
|
||||||
|
e.onclick = function () {
|
||||||
|
alert("Code Server is down.\n\nRun\n\nsq dev up codeserver\n\nto start the code server in your local development environment.");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
let codeServerRequestLoading = false;
|
||||||
|
|
||||||
|
// register button listener
|
||||||
|
// this is for code running examples
|
||||||
|
document.addEventListener("click", function (e) {
|
||||||
|
if (e.target.innerText !== "Run Code") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codeServerRequestLoading) {
|
||||||
|
alert("Please wait for the previous request to finish.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log("e", e.target);
|
||||||
|
// console.log("parent", e.target.parentElement);
|
||||||
|
// console.log("parent pu", getPreviousUntil(e.target.parentElement, '.tabbed-block'));
|
||||||
|
// console.log("parent > 1", e.target.parentElement.previousElementSibling);
|
||||||
|
// console.log("parent > 2", e.target.parentElement.previousElementSibling.previousElementSibling);
|
||||||
|
// console.log("parent > tabbed-block", e.target.parentElement.previousElementSibling.previousElementSibling);
|
||||||
|
// console.log("parent > tabbed-block", e.target.parentElement.previousElementSibling.previousElementSibling.querySelectorAll('.tabbed-block'));
|
||||||
|
|
||||||
|
// const codeClass = e.target.parentElement.previousElementSibling.previousElementSibling.querySelectorAll('.tabbed-block');
|
||||||
|
const codeClass = getPreviousUntil(e.target.parentElement, '.tabbed-content')[0].querySelectorAll('.tabbed-block');
|
||||||
|
|
||||||
|
// console.log("ele", codeClass);
|
||||||
|
|
||||||
|
let language = "";
|
||||||
|
codeClass.forEach((e) => {
|
||||||
|
console.log(window.getComputedStyle(e).display);
|
||||||
|
// this is the visible code block
|
||||||
|
if (window.getComputedStyle(e).display === "block") {
|
||||||
|
console.log(e);
|
||||||
|
const codeBlock = e.querySelector('code');
|
||||||
|
if (codeBlock) {
|
||||||
|
language = codeBlock.closest('div').className.split(" ")[0].split("-")[1];
|
||||||
|
|
||||||
|
console.log("code block", codeBlock);
|
||||||
|
console.log(codeBlock.closest('div'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// console.log("Language", language);
|
||||||
|
|
||||||
|
document.getElementById("loader")?.remove();
|
||||||
|
document.getElementById("output")?.remove();
|
||||||
|
document.getElementById("output-error")?.remove();
|
||||||
|
|
||||||
|
const output = document.createElement("pre");
|
||||||
|
output.id = "loader";
|
||||||
|
output.innerHTML = "<code style='border: .075rem solid white'>Loading...</code>";
|
||||||
|
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 = "<h4>" + toTitleCase(language) + " Execution</h4><pre><code style='border: .075rem solid green'>" + xhr.responseText + "</code></pre>";
|
||||||
|
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 = "<code style='border: solid 1px red'>" + xhr.responseText + "</code>";
|
||||||
|
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;
|
||||||
|
|
||||||
|
};
|
||||||
BIN
docs/docs/assets/logo.gif
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
docs/docs/assets/logo.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
docs/docs/assets/logo.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
60
docs/docs/available-toolkits.md
Normal file
@@ -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.
|
||||||
63
docs/docs/cli.md
Normal file
@@ -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.
|
||||||
148
docs/docs/configuration.md
Normal file
@@ -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/
|
||||||
1
docs/docs/contributing.md
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../CONTRIBUTING.md
|
||||||
94
docs/docs/creating-a-new-toolkit.md
Normal file
@@ -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
|
||||||
5
docs/docs/css/code_select.css
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.highlight .gp,
|
||||||
|
.highlight .go {
|
||||||
|
/* Generic.Prompt, Generic.Output */
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
18
docs/docs/index.md
Normal file
@@ -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
|
||||||
18
docs/docs/installation.md
Normal file
@@ -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`.
|
||||||
15
docs/docs/plugins.md
Normal file
@@ -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.
|
||||||
|
|
||||||
3
docs/docs/providers.md
Normal file
@@ -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.
|
||||||
20
docs/docs/tips.md
Normal file
@@ -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!
|
||||||
202
docs/docs/toolkits.md
Normal file
@@ -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
|
||||||
41
docs/docs/using-toolkits.md
Normal file
@@ -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
|
||||||
|
```
|
||||||
|
|
||||||
110
docs/mkdocs.yml
Normal file
@@ -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 <br> (like GitHub)
|
||||||
|
- pymdownx.arithmatex:
|
||||||
|
generic: true
|
||||||
|
- pymdownx.betterem:
|
||||||
|
smart_enable: all
|
||||||
|
- pymdownx.caret
|
||||||
|
- pymdownx.details
|
||||||
|
- pymdownx.emoji:
|
||||||
|
emoji_generator: !!python/name:material.extensions.emoji.to_svg
|
||||||
|
emoji_index: !!python/name:material.extensions.emoji.twemoji
|
||||||
|
- pymdownx.highlight:
|
||||||
|
anchor_linenums: true
|
||||||
|
line_spans: __span
|
||||||
|
pygments_lang_class: true
|
||||||
|
- pymdownx.inlinehilite
|
||||||
|
- pymdownx.keys
|
||||||
|
- pymdownx.magiclink:
|
||||||
|
repo_url_shorthand: false
|
||||||
|
- pymdownx.mark
|
||||||
|
- pymdownx.smartsymbols
|
||||||
|
- pymdownx.snippets
|
||||||
|
- pymdownx.superfences:
|
||||||
|
custom_fences:
|
||||||
|
- name: mermaid
|
||||||
|
class: mermaid
|
||||||
|
format: !!python/name:pymdownx.superfences.fence_code_format
|
||||||
|
- pymdownx.tabbed:
|
||||||
|
alternate_style: true
|
||||||
|
- pymdownx.tasklist:
|
||||||
|
custom_checkbox: true
|
||||||
|
- pymdownx.tilde
|
||||||
|
- toc:
|
||||||
|
permalink: true
|
||||||
|
nav:
|
||||||
|
- Home: index.md
|
||||||
|
- 'Installation': installation.md
|
||||||
|
- 'Configuration': configuration.md
|
||||||
|
- 'Contributing': contributing.md
|
||||||
|
- Plugins:
|
||||||
|
- 'Overview': plugins.md
|
||||||
|
- Toolkits:
|
||||||
|
- 'Using Toolkits': using-toolkits.md
|
||||||
|
- 'Creating a New Toolkit': creating-a-new-toolkit.md
|
||||||
|
- 'Available Toolkits': available-toolkits.md
|
||||||
|
- CLI Commands:
|
||||||
|
- 'Available CLI Commands': cli.md
|
||||||
|
- Providers:
|
||||||
|
- 'Available Providers': providers.md
|
||||||
|
- 'Tips': tips.md
|
||||||
35
docs/scripts/gen_ref_pages.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
"""Generate the code reference pages and navigation."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import mkdocs_gen_files
|
||||||
|
|
||||||
|
nav = mkdocs_gen_files.Nav()
|
||||||
|
|
||||||
|
root = Path(__file__).parent.parent.parent
|
||||||
|
src = root / "src"
|
||||||
|
|
||||||
|
for path in sorted(src.rglob("*.py")):
|
||||||
|
module_path = path.relative_to(src).with_suffix("")
|
||||||
|
doc_path = path.relative_to(src).with_suffix(".md")
|
||||||
|
full_doc_path = Path("reference", doc_path)
|
||||||
|
|
||||||
|
parts = tuple(module_path.parts)
|
||||||
|
|
||||||
|
if parts[-1] == "__init__":
|
||||||
|
parts = parts[:-1]
|
||||||
|
doc_path = doc_path.with_name("index.md")
|
||||||
|
full_doc_path = full_doc_path.with_name("index.md")
|
||||||
|
elif parts[-1] == "__main__":
|
||||||
|
continue
|
||||||
|
|
||||||
|
nav[parts] = doc_path.as_posix()
|
||||||
|
|
||||||
|
with mkdocs_gen_files.open(full_doc_path, "w") as fd:
|
||||||
|
ident = ".".join(parts)
|
||||||
|
fd.write(f"::: {ident}")
|
||||||
|
|
||||||
|
mkdocs_gen_files.set_edit_path(full_doc_path, path.relative_to(root))
|
||||||
|
|
||||||
|
with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file:
|
||||||
|
nav_file.writelines(nav.build_literate_nav())
|
||||||
3
justfile
@@ -17,3 +17,6 @@ coverage *FLAGS:
|
|||||||
uv run coverage run -m pytest tests -m "not integration" {{FLAGS}}
|
uv run coverage run -m pytest tests -m "not integration" {{FLAGS}}
|
||||||
uv run coverage report
|
uv run coverage report
|
||||||
uv run coverage lcov -o lcov.info
|
uv run coverage lcov -o lcov.info
|
||||||
|
|
||||||
|
docs:
|
||||||
|
cd docs && uv sync && uv run mkdocs serve
|
||||||
|
|||||||
@@ -50,4 +50,17 @@ build-backend = "hatchling.build"
|
|||||||
dev-dependencies = [
|
dev-dependencies = [
|
||||||
"pytest>=8.3.2",
|
"pytest>=8.3.2",
|
||||||
"codecov>=2.1.13",
|
"codecov>=2.1.13",
|
||||||
|
"mkdocstrings>=0.26.1",
|
||||||
|
"mkdocs-literate-nav>=0.6.1",
|
||||||
|
"mkdocs-gen-files>=0.5.0",
|
||||||
|
"mkdocs-section-index>=0.3.9",
|
||||||
|
"mkdocs-material>=9.5.34",
|
||||||
|
"mkdocstrings-python>=1.11.1",
|
||||||
|
"mkdocs-git-revision-date-localized-plugin",
|
||||||
|
"mkdocs-glightbox>=0.4.0",
|
||||||
|
"mkdocs-redirects>=1.2.1",
|
||||||
|
"mkdocs-include-markdown-plugin>=6.2.2",
|
||||||
|
"mkdocs-callouts>=1.14.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||