diff --git a/MIGRATION.md b/MIGRATION.md index fc3c297be2..9eff41633b 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,6 +1,142 @@ # Migration Guide This document provides instructions for migrating your codebase to accommodate breaking changes introduced in new versions of Griptape. +## 0.31.X to 0.32.X + +### Removed `MediaArtifact` + +`MediaArtifact` has been removed. Use `ImageArtifact` or `AudioArtifact` instead. + +#### Before + +```python +image_media = MediaArtifact( + b"image_data", + media_type="image", + format="jpeg" +) + +audio_media = MediaArtifact( + b"audio_data", + media_type="audio", + format="wav" +) +``` + +#### After +```python +image_artifact = ImageArtifact( + b"image_data", + format="jpeg" +) + +audio_artifact = AudioArtifact( + b"audio_data", + format="wav" +) +``` + +### `ImageArtifact.format` is now required + +`ImageArtifact.format` is now a required parameter. Update any code that does not provide a `format` parameter. + +#### Before + +```python +image_artifact = ImageArtifact( + b"image_data" +) +``` + +#### After +```python +image_artifact = ImageArtifact( + b"image_data", + format="jpeg" +) +``` + +### Removed `CsvRowArtifact` + +`CsvRowArtifact` has been removed. Use `TextArtifact` instead. + +#### Before + +```python +artifact = CsvRowArtifact({"name": "John", "age": 30}) +print(artifact.value) # {"name": "John", "age": 30} +print(type(artifact.value)) # +``` + +#### After +```python +artifact = TextArtifact("name: John\nage: 30") +print(artifact.value) # name: John\nage: 30 +print(type(artifact.value)) # +``` + +If you require storing a dictionary as an Artifact, you can use `GenericArtifact` instead. + +### `CsvLoader`, `DataframeLoader`, and `SqlLoader` return types + +`CsvLoader`, `DataframeLoader`, and `SqlLoader` now return a `list[TextArtifact]` instead of `list[CsvRowArtifact]`. + +If you require a dictionary, set a custom `formatter_fn` and then parse the text to a dictionary. + +#### Before + +```python +results = CsvLoader().load(Path("people.csv").read_text()) + +print(results[0].value) # {"name": "John", "age": 30} +print(type(results[0].value)) # +``` + +#### After +```python +results = CsvLoader().load(Path("people.csv").read_text()) + +print(results[0].value) # name: John\nAge: 30 +print(type(results[0].value)) # + +# Customize formatter_fn +results = CsvLoader(formatter_fn=lambda x: json.dumps(x)).load(Path("people.csv").read_text()) +print(results[0].value) # {"name": "John", "age": 30} +print(type(results[0].value)) # + +dict_results = [json.loads(result.value) for result in results] +print(dict_results[0]) # {"name": "John", "age": 30} +print(type(dict_results[0])) # +``` + +### Moved `ImageArtifact.prompt` and `ImageArtifact.model` to `ImageArtifact.meta` + +`ImageArtifact.prompt` and `ImageArtifact.model` have been moved to `ImageArtifact.meta`. + +#### Before + +```python +image_artifact = ImageArtifact( + b"image_data", + format="jpeg", + prompt="Generate an image of a cat", + model="DALL-E" +) + +print(image_artifact.prompt, image_artifact.model) # Generate an image of a cat, DALL-E +``` + +#### After +```python +image_artifact = ImageArtifact( + b"image_data", + format="jpeg", + meta={"prompt": "Generate an image of a cat", "model": "DALL-E"} +) + +print(image_artifact.meta["prompt"], image_artifact.meta["model"]) # Generate an image of a cat, DALL-E +``` + ## 0.31.X to 0.32.X diff --git a/docs/griptape-framework/structures/src/drivers_config_7.py b/docs/griptape-framework/structures/src/drivers_config_7.py index 3b1d396ce2..efec4f3cff 100644 --- a/docs/griptape-framework/structures/src/drivers_config_7.py +++ b/docs/griptape-framework/structures/src/drivers_config_7.py @@ -2,14 +2,15 @@ from griptape.configs import Defaults from griptape.configs.drivers import DriversConfig -from griptape.drivers import AnthropicPromptDriver +from griptape.drivers import AnthropicPromptDriver, OpenAiEmbeddingDriver from griptape.structures import Agent Defaults.drivers_config = DriversConfig( prompt_driver=AnthropicPromptDriver( model="claude-3-sonnet-20240229", api_key=os.environ["ANTHROPIC_API_KEY"], - ) + ), + embedding_driver=OpenAiEmbeddingDriver(), ) diff --git a/griptape/artifacts/__init__.py b/griptape/artifacts/__init__.py index c0e5f767e2..0e58a8a764 100644 --- a/griptape/artifacts/__init__.py +++ b/griptape/artifacts/__init__.py @@ -5,7 +5,6 @@ from .json_artifact import JsonArtifact from .blob_artifact import BlobArtifact from .boolean_artifact import BooleanArtifact -from .csv_row_artifact import CsvRowArtifact from .list_artifact import ListArtifact from .image_artifact import ImageArtifact from .audio_artifact import AudioArtifact @@ -21,7 +20,6 @@ "JsonArtifact", "BlobArtifact", "BooleanArtifact", - "CsvRowArtifact", "ListArtifact", "ImageArtifact", "AudioArtifact", diff --git a/griptape/artifacts/base_artifact.py b/griptape/artifacts/base_artifact.py index 4321ae00bc..61989ab54a 100644 --- a/griptape/artifacts/base_artifact.py +++ b/griptape/artifacts/base_artifact.py @@ -16,7 +16,7 @@ class BaseArtifact(SerializableMixin, ABC): """Serves as the base class for all Artifacts. - Artifacts are used to store data that can be provided as input to, or received as output from, a language model (LLM). + Artifacts are used to encapsulate data and enhance it with metadata. Attributes: id: The unique identifier of the Artifact. Defaults to a random UUID. diff --git a/griptape/artifacts/csv_row_artifact.py b/griptape/artifacts/csv_row_artifact.py deleted file mode 100644 index eea01fc141..0000000000 --- a/griptape/artifacts/csv_row_artifact.py +++ /dev/null @@ -1,28 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from attrs import define, field - -from griptape.artifacts import BaseArtifact, TextArtifact - - -@define -class CsvRowArtifact(TextArtifact): - """Stores a row of a CSV file. - - Attributes: - value: The row of the CSV file. If a dictionary is passed, the keys and values converted to a string. - """ - - value: str = field(converter=lambda value: CsvRowArtifact.value_to_str(value), metadata={"serializable": True}) - - def __add__(self, other: BaseArtifact) -> TextArtifact: - return TextArtifact(self.value + "\n" + other.value) - - @classmethod - def value_to_str(cls, value: Any) -> str: - if isinstance(value, dict): - return "\n".join(f"{key}: {val}" for key, val in value.items()) - else: - return str(value) diff --git a/griptape/artifacts/image_artifact.py b/griptape/artifacts/image_artifact.py index 616dc335a2..36170ee0d8 100644 --- a/griptape/artifacts/image_artifact.py +++ b/griptape/artifacts/image_artifact.py @@ -10,7 +10,7 @@ class ImageArtifact(BlobArtifact): """Stores image data. Attributes: - format: The format of the image data. + format: The format of the image data. Used when building the MIME type. width: The width of the image. height: The height of the image """ diff --git a/griptape/engines/extraction/csv_extraction_engine.py b/griptape/engines/extraction/csv_extraction_engine.py index 973171c5f7..e7be73c73b 100644 --- a/griptape/engines/extraction/csv_extraction_engine.py +++ b/griptape/engines/extraction/csv_extraction_engine.py @@ -6,7 +6,7 @@ from attrs import Factory, define, field -from griptape.artifacts import CsvRowArtifact, ListArtifact, TextArtifact +from griptape.artifacts import ListArtifact, TextArtifact from griptape.common import Message, PromptStack from griptape.engines import BaseExtractionEngine from griptape.utils import J2 @@ -40,7 +40,7 @@ def extract( item_separator="\n", ) - def text_to_csv_rows(self, text: str, column_names: list[str]) -> list[CsvRowArtifact]: + def text_to_csv_rows(self, text: str, column_names: list[str]) -> list[TextArtifact]: rows = [] with io.StringIO(text) as f: @@ -52,10 +52,10 @@ def text_to_csv_rows(self, text: str, column_names: list[str]) -> list[CsvRowArt def _extract_rec( self, artifacts: list[TextArtifact], - rows: list[CsvRowArtifact], + rows: list[TextArtifact], *, rulesets: Optional[list[Ruleset]] = None, - ) -> list[CsvRowArtifact]: + ) -> list[TextArtifact]: artifacts_text = self.chunk_joiner.join([a.value for a in artifacts]) system_prompt = self.system_template_generator.render( column_names=self.column_names,