Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Refactored tools to not utilize manifest.yaml #1226

Merged
merged 4 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **BREAKING**: `CsvExtractionEngine.column_names` is now required.
- `JsonExtractionEngine.extract_artifacts` now returns a `ListArtifact[JsonArtifact]`.
- `CsvExtractionEngine.extract_artifacts` now returns a `ListArtifact[CsvRowArtifact]`.
- Remove `manifest.yml` requirements for custom tool creation.

### Fixed
- Anthropic native Tool calling
Expand Down
43 changes: 11 additions & 32 deletions docs/griptape-tools/custom-tools/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,25 @@

Building your own tools is easy with Griptape!

To start, create a directory for your tool inside your project. All tool directories should have the following components:
Tools are nothing more than Python classes that inherit from [BaseTool](../../reference/griptape/tools/base_tool.md).
Each method in the class is decorated with an [activity](../../reference/griptape/utils/decorators.md#griptape.utils.decorators.activity) decorator which informs the LLM how and when it should use that Tool Activity.

* `manifest.yml` with a YAML manifest.
* `tool.py` file with a tool Python class.
* `requirements.txt` file with tool Python dependencies.

Let's build a simple random number generator tool! First, create a new directory for your tool `rng_tool`. This is where all tool files will go.

## Tool Manifest

Tool YAML manifests are for humans and downstream systems, like ChatGPT Plugins, to generate manifests of their own. Create a `manifest.yml` file in the `rng_tool` directory:

```yaml
version: "v1"
name: Random Number Generator
description: Tool for generating random numbers.
contact_email: [email protected]
legal_info_url: https://www.griptape.ai/legal
```

## Tool Dependencies
## Random Number Generator Tool

To add Python dependencies for your tool, add a `requirements.txt` file. The tool we are building is pretty simple, so you can leave that file empty.

## Tool Implementation

Next, create a `tool.py` file with the following code:
Here is a simple random number generator Tool:

```python
--8<-- "docs/griptape-tools/custom-tools/src/index_1.py"
```

## Testing Custom Tools
Check out other [Griptape Tools](https://github.com/griptape-ai/griptape/tree/main/griptape/tools) to learn more about tool implementation details.

Finally, let's test our tool:
## Tool Dependencies

```python
--8<-- "docs/griptape-tools/custom-tools/src/index_2.py"
```
Each Tool can also have its own dependencies. You can specify them in a `requirements.txt` file in the tool directory and Griptape will install them during Tool execution.
To start, create a directory for your Tool inside your project. The directory must have the following structure:

That's it! You can start using this tool with any converter or directly via Griptape.
* `tool.py` file with a tool Python class.
* `requirements.txt` file with tool Python dependencies.

Check out other [Griptape Tools](https://github.com/griptape-ai/griptape/tree/main/griptape/tools) to learn more about tool implementation details.
That's it! Import and use your Tool in your project as you would with any other Griptape Tool.
5 changes: 0 additions & 5 deletions griptape/tools/audio_transcription/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/aws_iam/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/aws_s3/manifest.yml

This file was deleted.

19 changes: 0 additions & 19 deletions griptape/tools/base_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from typing import TYPE_CHECKING, Any, Callable, Optional

import schema
import yaml
from attrs import Attribute, Factory, define, field
from schema import Literal, Or, Schema

Expand Down Expand Up @@ -38,7 +37,6 @@ class BaseTool(ActivityMixin, ABC):
off_prompt: Determines whether tool activity output goes to the output memory.
"""

MANIFEST_FILE = "manifest.yml"
REQUIREMENTS_FILE = "requirements.txt"

name: str = field(default=Factory(lambda self: self.__class__.__name__, takes_self=True), kw_only=True)
Expand Down Expand Up @@ -67,19 +65,10 @@ def validate_output_memory(self, _: Attribute, output_memory: dict[str, Optional
if len(output_memory_names) > len(set(output_memory_names)):
raise ValueError(f"memory names have to be unique in activity '{activity_name}' output")

@property
def manifest_path(self) -> str:
return os.path.join(self.abs_dir_path, self.MANIFEST_FILE)

@property
def requirements_path(self) -> str:
return os.path.join(self.abs_dir_path, self.REQUIREMENTS_FILE)

@property
def manifest(self) -> dict:
with open(self.manifest_path) as yaml_file:
return yaml.safe_load(yaml_file)

@property
def abs_file_path(self) -> str:
return os.path.abspath(inspect.getfile(self.__class__))
Expand Down Expand Up @@ -173,16 +162,8 @@ def after_run(
return InfoArtifact("Tool returned an empty value")

def validate(self) -> bool:
from griptape.utils import ManifestValidator

if not os.path.exists(self.manifest_path):
raise Exception(f"{self.MANIFEST_FILE} not found")

if not os.path.exists(self.requirements_path):
raise Exception(f"{self.REQUIREMENTS_FILE} not found")

ManifestValidator().validate(self.manifest)

return True

def tool_dir(self) -> str:
Expand Down
5 changes: 0 additions & 5 deletions griptape/tools/calculator/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/computer/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/date_time/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/email/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/extraction/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/file_manager/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/google_calendar/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/google_docs/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/google_drive/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/google_gmail/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/griptape_cloud_knowledge_base/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/image_query/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/inpainting_image_generation/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/openweather/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/outpainting_image_generation/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/prompt_image_generation/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/prompt_summary/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/query/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/rag/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/rest_api/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/sql/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/structure_run/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/text_to_speech/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/variation_image_generation/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/vector_store/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/web_scraper/manifest.yml

This file was deleted.

5 changes: 0 additions & 5 deletions griptape/tools/web_search/manifest.yml

This file was deleted.

8 changes: 0 additions & 8 deletions tests/unit/tools/test_base_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import os

import pytest
import yaml
from schema import Or, Schema, SchemaMissingKeyError

from griptape.common import ToolAction
Expand Down Expand Up @@ -172,16 +171,9 @@ def test_off_prompt(self, tool):
.output_memory
)

def test_manifest_path(self, tool):
assert tool.manifest_path == os.path.join(tool.abs_dir_path, tool.MANIFEST_FILE)

def test_requirements_path(self, tool):
assert tool.requirements_path == os.path.join(tool.abs_dir_path, tool.REQUIREMENTS_FILE)

def test_manifest(self, tool):
with open(tool.manifest_path) as yaml_file:
assert tool.manifest == yaml.safe_load(yaml_file)

def test_abs_file_path(self, tool):
assert tool.abs_file_path == os.path.abspath(inspect.getfile(tool.__class__))

Expand Down
Loading