Repository: griptape-ai/griptape (language: python)

Issue:
CSV and JSON extraction engines are not implemented on `TextArtifactStorage`
 - [x] I have read and agree to the [contributing guidelines](https://github.com/griptape-ai/griptape#contributing).

**Describe the bug**
parameters `json_extraction_engine` and `csv_extraction_engine` are available but unused in `TextArtifactStorage`.
[link to code](https://github.com/griptape-ai/griptape/blob/e1977ce2f42665221482a1d365cc92931c5c6179/griptape/memory/task/storage/text_artifact_storage.py#L22-L23)

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Version [e.g. 0.5.1]

**Additional context**
Add any other context about the problem here.



Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6d6e9bffc..138a9c896 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Global event bus, `griptape.events.event_bus`, for publishing and subscribing to events.
 - Global config, `griptape.config.config`, for setting global configuration defaults.
 - Unique name generation for all `RagEngine` modules.
+- `ExtractionTool` for having the LLM extract structured data from text.
+- `PromptSummaryTool` for having the LLM summarize text.
+- `QueryTool` for having the LLM query text.
 - Support for bitshift composition in `BaseTask` for adding parent/child tasks.
 - `JsonArtifact` for handling de/seralization of values.
 
@@ -33,11 +36,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - **BREAKING**: Dropped `Client` from all Tool names for better naming consistency. 
 - **BREAKING**: Dropped `_client` suffix from all Tool packages. 
 - **BREAKING**: Added `Tool` suffix to all Tool names for better naming consistency. 
+- **BREAKING**: Removed `TextArtifactStorage.query` and `TextArtifactStorage.summarize`. 
+- **BREAKING**: Removed `TextArtifactStorage.rag_engine`, and `TextArtifactStorage.retrieval_rag_module_name`.
+- **BREAKING**: Removed `TextArtifactStorage.summary_engine`, `TextArtifactStorage.csv_extraction_engine`, and `TextArtifactStorage.json_extraction_engine`.
+- **BREAKING**: Removed `TaskMemory.summarize_namespace` and `TaskMemory.query_namespace`.
+- **BREAKING**: Removed `Structure.rag_engine`.
+- **BREAKING**: Split `JsonExtractionEngine.template_generator` into `JsonExtractionEngine.system_template_generator` and `JsonExtractionEngine.user_template_generator`.
+- **BREAKING**: Split `CsvExtractionEngine.template_generator` into `CsvExtractionEngine.system_template_generator` and `CsvExtractionEngine.user_template_generator`.
+- **BREAKING**: Changed `JsonExtractionEngine.template_schema` from a `run` argument to a class attribute. 
+- **BREAKING**: Changed `CsvExtractionEngine.column_names` from a `run` argument to a class attribute. 
+- **BREAKING**: Removed `JsonExtractionTask`, and `CsvExtractionTask` use `ExtractionTask` instead.
+- **BREAKING**: Removed `TaskMemoryClient`, use `RagClient`, `ExtractionTool`, or `PromptSummaryTool` instead.
 - **BREAKING**: `BaseTask.add_parent/child` now take a `BaseTask` instead of `str | BaseTask`.
 - Engines that previously required Drivers now pull from `griptape.config.config.drivers` by default.
 - `BaseTask.add_parent/child` will now call `self.structure.add_task` if possible.
 - `BaseTask.add_parent/child` now returns `self`, allowing for chaining.
 
+### Fixed
+- `JsonExtractionEngine` failing to parse json when the LLM outputs more than just the json.
+
 ## [0.29.1] - 2024-08-02
 
 ### Changed
@@ -443,7 +460,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - `JsonExtractionTask` for convenience over using `ExtractionTask` with a `JsonExtractionEngine`.
 - `CsvExtractionTask` for convenience over using `ExtractionTask` with a `CsvExtractionEngine`.
 - `OpenAiVisionImageQueryDriver` to support queries on images using OpenAI's Vision model.
-- `ImageQueryClient` allowing an Agent to make queries on images on disk or in Task Memory.
+- `ImageQueryTool` allowing an Agent to make queries on images on disk or in Task Memory.
 - `ImageQueryTask` and `ImageQueryEngine`.
 
 ### Fixed 
diff --git a/README.md b/README.md
index 1f6d6d883..d9f21c2d8 100644
--- a/README.md
+++ b/README.md
@@ -89,13 +89,13 @@ With Griptape, you can create Structures, such as Agents, Pipelines, and Workflo
 
 ```python
 from griptape.structures import Agent
-from griptape.tools import WebScraperTool, FileManagerTool, TaskMemoryTool
+from griptape.tools import WebScraperTool, FileManagerTool, PromptSummaryTool
 
 agent = Agent(
     input="Load {{ args[0] }}, summarize it, and store it in a file called {{ args[1] }}.",
     tools=[
         WebScraperTool(off_prompt=True),
-        TaskMemoryTool(off_prompt=True),
+        PromptSummaryTool(off_prompt=True),
         FileManagerTool()
     ]
 )
@@ -104,42 +104,63 @@ agent.run("https://griptape.ai", "griptape.txt")
 
 And here is the output:
 ```
-[04/02/24 13:51:09] INFO     ToolkitTask 85700ec1b0594e1a9502c0efe7da6ef4
+[08/12/24 14:48:15] INFO     ToolkitTask c90d263ec69046e8b30323c131ae4ba0
                              Input: Load https://griptape.ai, summarize it, and store it in a file called griptape.txt.
-[04/02/24 13:51:15] INFO     Subtask db6a3e7cb2f549128c358149d340f91c
-                             Thought: First, I need to load the content of the website using the WebScraper action. Then, I will use the TaskMemoryClient action to
-                             summarize the content. Finally, I will save the summarized content to a file using the FileManager action.
+[08/12/24 14:48:16] INFO     Subtask ebe23832cbe2464fb9ecde9fcee7c30f
                              Actions: [
                                {
-                                 "name": "WebScraper",
+                                 "tag": "call_62kBnkswnk9Y6GH6kn1GIKk6",
+                                 "name": "WebScraperTool",
                                  "path": "get_content",
                                  "input": {
                                    "values": {
                                      "url": "https://griptape.ai"
                                    }
-                                 },
-                                 "tag": "load_website_content"
+                                 }
                                }
                              ]
-[04/02/24 13:51:16] INFO     Subtask db6a3e7cb2f549128c358149d340f91c
-                             Response: Output of "WebScraper.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
-                             "752b38bb86da4baabdbd9f444eb4a0d1"
-[04/02/24 13:51:19] INFO     Subtask c3edba87ebf845d4b85e3a791f8fde8d
-                             Thought: Now that the website content is loaded into memory, I need to summarize it using the TaskMemoryClient action.
-                             Actions: [{"tag": "summarize_content", "name": "TaskMemoryClient", "path": "summarize", "input": {"values": {"memory_name": "TaskMemory",
-                             "artifact_namespace": "752b38bb86da4baabdbd9f444eb4a0d1"}}}]
-[04/02/24 13:51:25] INFO     Subtask c3edba87ebf845d4b85e3a791f8fde8d
-                             Response: Output of "TaskMemoryClient.summarize" was stored in memory with memory_name "TaskMemory" and artifact_namespace
-                             "c4f131c201f147dcab07be3925b46294"
-[04/02/24 13:51:33] INFO     Subtask 06fe01ca64a744b38a8c08eb152aaacb
-                             Thought: Now that the content has been summarized and stored in memory, I need to save this summarized content to a file named 'griptape.txt'
-                             using the FileManager action.
-                             Actions: [{"tag": "save_summarized_content", "name": "FileManager", "path": "save_memory_artifacts_to_disk", "input": {"values": {"dir_name":
-                             ".", "file_name": "griptape.txt", "memory_name": "TaskMemory", "artifact_namespace": "c4f131c201f147dcab07be3925b46294"}}}]
-                    INFO     Subtask 06fe01ca64a744b38a8c08eb152aaacb
-                             Response: saved successfully
-[04/02/24 13:51:35] INFO     ToolkitTask 85700ec1b0594e1a9502c0efe7da6ef4
-                             Output: The summarized content of the website https://griptape.ai has been successfully saved to a file named 'griptape.txt'.
+[08/12/24 14:48:17] INFO     Subtask ebe23832cbe2464fb9ecde9fcee7c30f
+                             Response: Output of "WebScraperTool.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "cecca28eb0c74bcd8c7119ed7f790c95"
+[08/12/24 14:48:18] INFO     Subtask dca04901436d49d2ade86cd6b4e1038a
+                             Actions: [
+                               {
+                                 "tag": "call_o9F1taIxHty0mDlWLcAjTAAu",
+                                 "name": "PromptSummaryTool",
+                                 "path": "summarize",
+                                 "input": {
+                                   "values": {
+                                     "summary": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "cecca28eb0c74bcd8c7119ed7f790c95"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 14:48:21] INFO     Subtask dca04901436d49d2ade86cd6b4e1038a
+                             Response: Output of "PromptSummaryTool.summarize" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "73765e32b8404e32927822250dc2ae8b"
+[08/12/24 14:48:22] INFO     Subtask c233853450fb4fd6a3e9c04c52b33bf6
+                             Actions: [
+                               {
+                                 "tag": "call_eKvIUIw45aRYKDBpT1gGKc9b",
+                                 "name": "FileManagerTool",
+                                 "path": "save_memory_artifacts_to_disk",
+                                 "input": {
+                                   "values": {
+                                     "dir_name": ".",
+                                     "file_name": "griptape.txt",
+                                     "memory_name": "TaskMemory",
+                                     "artifact_namespace": "73765e32b8404e32927822250dc2ae8b"
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask c233853450fb4fd6a3e9c04c52b33bf6
+                             Response: Successfully saved memory artifacts to disk
+[08/12/24 14:48:23] INFO     ToolkitTask c90d263ec69046e8b30323c131ae4ba0
+                             Output: The content from https://griptape.ai has been summarized and stored in a file called `griptape.txt`.
 ```
 
 During the run, the Griptape Agent loaded a webpage with a [Tool](https://docs.griptape.ai/stable/griptape-tools/), stored its full content in [Task Memory](https://docs.griptape.ai/stable/griptape-framework/structures/task-memory.md), queried it to answer the original question, and finally saved the answer to a file.
diff --git a/_typos.toml b/_typos.toml
index 1819b51ef..659cc6823 100644
--- a/_typos.toml
+++ b/_typos.toml
@@ -1,3 +1,6 @@
+[default]
+extend-ignore-re = ["call_[[:alnum:]]+"]
+
 [default.extend-words]
 # Don't correct the state ND
 ND = "ND"
diff --git a/docs/examples/multiple-agent-shared-memory.md b/docs/examples/multiple-agent-shared-memory.md
index e73ffe5d6..bd91f977d 100644
--- a/docs/examples/multiple-agent-shared-memory.md
+++ b/docs/examples/multiple-agent-shared-memory.md
@@ -1,6 +1,6 @@
-This example shows how to use one `Agent` to load content into `TaskMemory` and get that content from another `Agent` using `TaskMemoryClient`.
+This example shows how to use one `Agent` to load content into `TaskMemory` and get that content from another `Agent` using `QueryTool`.
 
-The first `Agent` uses a remote vector store (`MongoDbAtlasVectorStoreDriver` in this example) to handle memory operations. The second `Agent` uses the same instance of `TaskMemory` and the `TaskMemoryClient` with the same `MongoDbAtlasVectorStoreDriver` to get the data.
+The first `Agent` uses a remote vector store (`MongoDbAtlasVectorStoreDriver` in this example) to handle memory operations. The second `Agent` uses the same instance of `TaskMemory` and the `QueryTool` with the same `MongoDbAtlasVectorStoreDriver` to get the data.
 
 The `MongoDbAtlasVectorStoreDriver` assumes that you have a vector index configured where the path to the content is called `vector`, and the number of dimensions set on the index is `1536` (this is a commonly used number of dimensions for embedding models).
 
diff --git a/docs/examples/src/multi_agent_workflow_1.py b/docs/examples/src/multi_agent_workflow_1.py
index 137a5075f..e1f00a9bd 100644
--- a/docs/examples/src/multi_agent_workflow_1.py
+++ b/docs/examples/src/multi_agent_workflow_1.py
@@ -5,7 +5,7 @@
 from griptape.structures import Agent, Workflow
 from griptape.tasks import PromptTask, StructureRunTask
 from griptape.tools import (
-    TaskMemoryTool,
+    PromptSummaryTool,
     WebScraperTool,
     WebSearchTool,
 )
@@ -38,7 +38,7 @@ def build_researcher() -> Agent:
             WebScraperTool(
                 off_prompt=True,
             ),
-            TaskMemoryTool(off_prompt=False),
+            PromptSummaryTool(off_prompt=False),
         ],
         rulesets=[
             Ruleset(
diff --git a/docs/examples/src/multiple_agent_shared_memory_1.py b/docs/examples/src/multiple_agent_shared_memory_1.py
index 11590df39..946a21190 100644
--- a/docs/examples/src/multiple_agent_shared_memory_1.py
+++ b/docs/examples/src/multiple_agent_shared_memory_1.py
@@ -4,7 +4,7 @@
 from griptape.config.drivers import AzureOpenAiDriverConfig
 from griptape.drivers import AzureMongoDbVectorStoreDriver, AzureOpenAiEmbeddingDriver
 from griptape.structures import Agent
-from griptape.tools import TaskMemoryTool, WebScraperTool
+from griptape.tools import QueryTool, WebScraperTool
 
 AZURE_OPENAI_ENDPOINT_1 = os.environ["AZURE_OPENAI_ENDPOINT_1"]
 AZURE_OPENAI_API_KEY_1 = os.environ["AZURE_OPENAI_API_KEY_1"]
@@ -47,7 +47,7 @@
 )
 asker = Agent(
     tools=[
-        TaskMemoryTool(off_prompt=False),
+        QueryTool(off_prompt=False),
     ],
     meta_memory=loader.meta_memory,
     task_memory=loader.task_memory,
diff --git a/docs/examples/src/query_webpage_astra_db_1.py b/docs/examples/src/query_webpage_astra_db_1.py
index 6a96a813e..3309e1dcd 100644
--- a/docs/examples/src/query_webpage_astra_db_1.py
+++ b/docs/examples/src/query_webpage_astra_db_1.py
@@ -14,7 +14,7 @@
 from griptape.engines.rag.stages import ResponseRagStage, RetrievalRagStage
 from griptape.loaders import WebLoader
 from griptape.structures import Agent
-from griptape.tools import RagTool, TaskMemoryTool
+from griptape.tools import RagTool
 
 namespace = "datastax_blog"
 input_blogpost = "www.datastax.com/blog/indexing-all-of-wikipedia-on-a-laptop"
@@ -53,5 +53,5 @@
     description="A DataStax blog post",
     rag_engine=engine,
 )
-agent = Agent(tools=[rag_tool, TaskMemoryTool(off_prompt=False)])
+agent = Agent(tools=[rag_tool])
 agent.run("What engine made possible to index such an amount of data, " "and what kind of tuning was required?")
diff --git a/docs/griptape-framework/data/artifacts.md b/docs/griptape-framework/data/artifacts.md
index 1a33a991b..8c4da02b3 100644
--- a/docs/griptape-framework/data/artifacts.md
+++ b/docs/griptape-framework/data/artifacts.md
@@ -40,11 +40,11 @@ Each blob has a [name](../../reference/griptape/artifacts/base_artifact.md#gript
 
 ## Image
 
-An [ImageArtifact](../../reference/griptape/artifacts/image_artifact.md) is used for passing images back to the LLM. In addition to binary image data, an Image Artifact includes image metadata like MIME type, dimensions, and prompt and model information for images returned by [image generation Drivers](../drivers/image-generation-drivers.md). It inherits from [BlobArtifact](#blobartifact).
+An [ImageArtifact](../../reference/griptape/artifacts/image_artifact.md) is used for passing images back to the LLM. In addition to binary image data, an Image Artifact includes image metadata like MIME type, dimensions, and prompt and model information for images returned by [image generation Drivers](../drivers/image-generation-drivers.md). It inherits from [BlobArtifact](#blob).
 
 ## Audio
 
-An [AudioArtifact](../../reference/griptape/artifacts/audio_artifact.md) allows the Framework to interact with audio content. An Audio Artifact includes binary audio content as well as metadata like format, duration, and prompt and model information for audio returned generative models. It inherits from [BlobArtifact](#blobartifact).
+An [AudioArtifact](../../reference/griptape/artifacts/audio_artifact.md) allows the Framework to interact with audio content. An Audio Artifact includes binary audio content as well as metadata like format, duration, and prompt and model information for audio returned generative models. It inherits from [BlobArtifact](#blob).
 
 ## Boolean
 
diff --git a/docs/griptape-framework/data/loaders.md b/docs/griptape-framework/data/loaders.md
index 82d97f494..914fdee2a 100644
--- a/docs/griptape-framework/data/loaders.md
+++ b/docs/griptape-framework/data/loaders.md
@@ -75,7 +75,7 @@ Inherits from the [TextLoader](../../reference/griptape/loaders/text_loader.md)
 !!! info
     This driver requires the `loaders-image` [extra](../index.md#extras).
 
-The Image Loader is used to load an image as an [ImageArtifact](./artifacts.md#imageartifact). The Loader operates on image bytes that can be sourced from files on disk, downloaded images, or images in memory.
+The Image Loader is used to load an image as an [ImageArtifact](./artifacts.md#image). The Loader operates on image bytes that can be sourced from files on disk, downloaded images, or images in memory.
 
 ```python
 --8<-- "docs/griptape-framework/data/src/loaders_7.py"
@@ -104,7 +104,7 @@ Can be used to load email from an imap server:
 !!! info
     This driver requires the `loaders-audio` [extra](../index.md#extras).
 
-The [Audio Loader](../../reference/griptape/loaders/audio_loader.md) is used to load audio content as an [AudioArtifact](./artifacts.md#audioartifact). The Loader operates on audio bytes that can be sourced from files on disk, downloaded audio, or audio in memory.
+The [Audio Loader](../../reference/griptape/loaders/audio_loader.md) is used to load audio content as an [AudioArtifact](./artifacts.md#audio). The Loader operates on audio bytes that can be sourced from files on disk, downloaded audio, or audio in memory.
 
 The Loader will load audio in its native format and populates the resulting Artifact's `format` field by making a best-effort guess of the underlying audio format using the `filetype` package.
 
diff --git a/docs/griptape-framework/drivers/src/embedding_drivers_10.py b/docs/griptape-framework/drivers/src/embedding_drivers_10.py
index a27e60298..dbbc659fb 100644
--- a/docs/griptape-framework/drivers/src/embedding_drivers_10.py
+++ b/docs/griptape-framework/drivers/src/embedding_drivers_10.py
@@ -5,7 +5,12 @@
     VoyageAiEmbeddingDriver,
 )
 from griptape.structures import Agent
-from griptape.tools import TaskMemoryTool, WebScraperTool
+from griptape.tools import PromptSummaryTool, WebScraperTool
+
+config.drivers = DriverConfig(
+    prompt=OpenAiChatPromptDriver(model="gpt-4o"),
+    embedding=VoyageAiEmbeddingDriver(),
+)
 
 config.drivers = DriverConfig(
     prompt=OpenAiChatPromptDriver(model="gpt-4o"),
@@ -13,7 +18,7 @@
 )
 
 agent = Agent(
-    tools=[WebScraperTool(off_prompt=True), TaskMemoryTool(off_prompt=False)],
+    tools=[WebScraperTool(off_prompt=True), PromptSummaryTool(off_prompt=False)],
 )
 
 agent.run("based on https://www.griptape.ai/, tell me what Griptape is")
diff --git a/docs/griptape-framework/drivers/src/web_scraper_drivers_3.py b/docs/griptape-framework/drivers/src/web_scraper_drivers_3.py
index d4c77c2ae..aafa465f8 100644
--- a/docs/griptape-framework/drivers/src/web_scraper_drivers_3.py
+++ b/docs/griptape-framework/drivers/src/web_scraper_drivers_3.py
@@ -1,15 +1,14 @@
 from griptape.drivers import MarkdownifyWebScraperDriver
 from griptape.loaders import WebLoader
 from griptape.structures import Agent
-from griptape.tools import TaskMemoryTool, WebScraperTool
+from griptape.tools import WebScraperTool
 
 agent = Agent(
     tools=[
         WebScraperTool(
             web_loader=WebLoader(web_scraper_driver=MarkdownifyWebScraperDriver(timeout=1000)),
-            off_prompt=True,
+            off_prompt=False,
         ),
-        TaskMemoryTool(off_prompt=False),
     ],
 )
 agent.run("List all email addresses on griptape.ai in a flat numbered markdown list.")
diff --git a/docs/griptape-framework/drivers/src/web_search_drivers_2.py b/docs/griptape-framework/drivers/src/web_search_drivers_2.py
index a33b8c00c..abe80a2e0 100644
--- a/docs/griptape-framework/drivers/src/web_search_drivers_2.py
+++ b/docs/griptape-framework/drivers/src/web_search_drivers_2.py
@@ -2,7 +2,7 @@
 
 from griptape.drivers import GoogleWebSearchDriver
 from griptape.structures import Agent
-from griptape.tools import TaskMemoryTool, WebSearchTool
+from griptape.tools import PromptSummaryTool, WebSearchTool
 
 agent = Agent(
     tools=[
@@ -12,7 +12,7 @@
                 search_id=os.environ["GOOGLE_API_SEARCH_ID"],
             ),
         ),
-        TaskMemoryTool(off_prompt=False),
+        PromptSummaryTool(off_prompt=False),
     ],
 )
 agent.run("Give me some websites with information about AI frameworks.")
diff --git a/docs/griptape-framework/index.md b/docs/griptape-framework/index.md
index ff3670e6e..3dd294f0b 100644
--- a/docs/griptape-framework/index.md
+++ b/docs/griptape-framework/index.md
@@ -128,44 +128,75 @@ Agents are great for getting started, but they are intentionally limited to a si
 ```
 
 ```
-[09/08/23 10:02:34] INFO     ToolkitTask 3c1d2f4a49384873820a9a8cd8acc983
+[08/12/24 14:50:28] INFO     ToolkitTask 19dcf6020968468a91aa8a93c2a3f645
                              Input: Load https://www.griptape.ai, summarize it, and store it in griptape.txt
-[09/08/23 10:02:44] INFO     Subtask 42fd56ba100e45688401c5ce32b79a33
-                             Thought: To complete this task, I need to first load the webpage using the WebScraper tool's get_content
-                             activity. Then, I will summarize the content using the TaskMemory tool's summarize activity. Finally, I will
-                             store the summarized content in a file named griptape.txt using the FileManager tool's save_file_to_disk
-                             activity.
-
-                             Action: {"name": "WebScraper", "path": "get_content", "input": {"values": {"url":
-                             "https://www.griptape.ai"}}}
-[09/08/23 10:02:45] INFO     Subtask 42fd56ba100e45688401c5ce32b79a33
-                             Response: Output of "WebScraper.get_content" was stored in memory with memory_name "TaskMemory" and
-                             artifact_namespace "39ca67bbe26b4e1584193b87ed82170d"
-[09/08/23 10:02:53] INFO     Subtask 8023e3d257274df29065b22e736faca8
-                             Thought: Now that the webpage content is stored in memory, I can use the TaskMemory tool's summarize activity
-                             to summarize the content.
-                             Action: {"name": "TaskMemoryTool", "path": "summarize", "input": {"values": {"memory_name": "TaskMemory", "artifact_namespace": "39ca67bbe26b4e1584193b87ed82170d"}}}
-[09/08/23 10:02:57] INFO     Subtask 8023e3d257274df29065b22e736faca8
-                             Response: Griptape is an open source framework that allows developers to build and deploy AI applications
-                             using large language models (LLMs). It provides the ability to create conversational and event-driven apps that
-                             can securely access and manipulate data. The framework enforces structures for predictability and creativity,
-                             allowing developers to easily transition between the two. Griptape Cloud is a managed platform for deploying and
-                             managing AI apps.
-[09/08/23 10:03:06] INFO     Subtask 7baae700239943c18b5b6b21873f0e13
-                             Thought: Now that I have the summarized content, I can store it in a file named griptape.txt using the
-                             FileManager tool's save_file_to_disk activity.
-                             Action: {"name": "FileManager", "path": "save_file_to_disk", "input": {"values":
-                             {"memory_name": "TaskMemory", "artifact_namespace": "39ca67bbe26b4e1584193b87ed82170d", "path":
-                             "griptape.txt"}}}
-                    INFO     Subtask 7baae700239943c18b5b6b21873f0e13
-                             Response: saved successfully
-[09/08/23 10:03:14] INFO     ToolkitTask 3c1d2f4a49384873820a9a8cd8acc983
-                             Output: The summarized content of the webpage https://www.griptape.ai has been successfully stored in the file
-                             named griptape.txt.
-                    INFO     PromptTask 8635925ff23b46f28a740105bd11ca8f
-                             Input: Say the following in spanish: The summarized content of the webpage https://www.griptape.ai has been
-                             successfully stored in the file named griptape.txt.
-[09/08/23 10:03:18] INFO     PromptTask 8635925ff23b46f28a740105bd11ca8f
-                             Output: El contenido resumido de la página web https://www.griptape.ai se ha almacenado con éxito en el archivo
-                             llamado griptape.txt.
+[08/12/24 14:50:30] INFO     Subtask a685799379c5421b91768353fc219939
+                             Actions: [
+                               {
+                                 "tag": "call_YL5Ozd9WUtag4ykR5Agm12Ce",
+                                 "name": "WebScraperTool",
+                                 "path": "get_content",
+                                 "input": {
+                                   "values": {
+                                     "url": "https://www.griptape.ai"
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 14:50:31] INFO     Subtask a685799379c5421b91768353fc219939
+                             Response: Output of "WebScraperTool.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "6be3a2e0494841fda966b98bec9ffccb"
+[08/12/24 14:50:33] INFO     Subtask 1cf0c19843aa4fada5745c4a82eb4237
+                             Actions: [
+                               {
+                                 "tag": "call_ElTYTPeocOU62I0VjzRqmfoF",
+                                 "name": "PromptSummaryTool",
+                                 "path": "summarize",
+                                 "input": {
+                                   "values": {
+                                     "summary": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "6be3a2e0494841fda966b98bec9ffccb"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 14:50:35] INFO     Subtask 1cf0c19843aa4fada5745c4a82eb4237
+                             Response: Griptape offers a comprehensive solution for building, deploying, and scaling AI applications in the cloud. It provides developers
+                             with a framework and cloud services to create retrieval-driven AI-powered applications. The Griptape Framework allows developers to build
+                             business logic using Python, ensuring better security, performance, and cost-efficiency. It simplifies the creation of Gen AI Agents, Systems of
+                             Agents, Pipelines, Workflows, and RAG implementations without needing extensive knowledge of Gen AI or Prompt Engineering.
+
+                             Griptape Cloud handles infrastructure management, offering services like ETL pipelines for data preparation, Retrieval as a Service (RAG) for
+                             generating answers and summaries, and a Structure Runtime (RUN) for building AI agents and workflows. This enables seamless scaling and
+                             integration with client applications, catering to custom projects, turnkey SaaS offerings, and finished apps.
+[08/12/24 14:50:38] INFO     Subtask aaaeca1a089844d4915d065deb3c00cf
+                             Actions: [
+                               {
+                                 "tag": "call_eKvIUIw45aRYKDBpT1gGKc9b",
+                                 "name": "FileManagerTool",
+                                 "path": "save_content_to_file",
+                                 "input": {
+                                   "values": {
+                                     "path": "griptape.txt",
+                                     "content": "Griptape offers a comprehensive solution for building, deploying, and scaling AI applications in the cloud. It provides
+                             developers with a framework and cloud services to create retrieval-driven AI-powered applications. The Griptape Framework allows developers to
+                             build business logic using Python, ensuring better security, performance, and cost-efficiency. It simplifies the creation of Gen AI Agents,
+                             Systems of Agents, Pipelines, Workflows, and RAG implementations without needing extensive knowledge of Gen AI or Prompt
+                             Engineering.\n\nGriptape Cloud handles infrastructure management, offering services like ETL pipelines for data preparation, Retrieval as a
+                             Service (RAG) for generating answers and summaries, and a Structure Runtime (RUN) for building AI agents and workflows. This enables seamless
+                             scaling and integration with client applications, catering to custom projects, turnkey SaaS offerings, and finished apps."
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask aaaeca1a089844d4915d065deb3c00cf
+                             Response: Successfully saved file
+[08/12/24 14:50:39] INFO     ToolkitTask 19dcf6020968468a91aa8a93c2a3f645
+                             Output: The content from https://www.griptape.ai has been summarized and stored in griptape.txt.
+                    INFO     PromptTask dbbb38f144f445db896dc12854f17ad3
+                             Input: Say the following in spanish: The content from https://www.griptape.ai has been summarized and stored in griptape.txt.
+[08/12/24 14:50:42] INFO     PromptTask dbbb38f144f445db896dc12854f17ad3
+                             Output: El contenido de https://www.griptape.ai ha sido resumido y almacenado en griptape.txt.
 ```
diff --git a/docs/griptape-framework/misc/src/events_3.py b/docs/griptape-framework/misc/src/events_3.py
index 2a567debe..721cf3511 100644
--- a/docs/griptape-framework/misc/src/events_3.py
+++ b/docs/griptape-framework/misc/src/events_3.py
@@ -4,7 +4,7 @@
 from griptape.events import CompletionChunkEvent, EventListener, event_bus
 from griptape.structures import Pipeline
 from griptape.tasks import ToolkitTask
-from griptape.tools import TaskMemoryTool, WebScraperTool
+from griptape.tools import PromptSummaryTool, WebScraperTool
 
 event_bus.add_event_listeners(
     [
@@ -20,7 +20,7 @@
     ToolkitTask(
         "Based on https://griptape.ai, tell me what griptape is.",
         prompt_driver=OpenAiChatPromptDriver(model="gpt-4o", stream=True),
-        tools=[WebScraperTool(off_prompt=True), TaskMemoryTool(off_prompt=False)],
+        tools=[WebScraperTool(off_prompt=True), PromptSummaryTool(off_prompt=False)],
     )
 )
 
diff --git a/docs/griptape-framework/misc/src/events_4.py b/docs/griptape-framework/misc/src/events_4.py
index a66e77b1d..6dc2d3a6c 100644
--- a/docs/griptape-framework/misc/src/events_4.py
+++ b/docs/griptape-framework/misc/src/events_4.py
@@ -1,13 +1,13 @@
 from griptape.structures import Pipeline
 from griptape.tasks import ToolkitTask
-from griptape.tools import TaskMemoryTool, WebScraperTool
+from griptape.tools import PromptSummaryTool, WebScraperTool
 from griptape.utils import Stream
 
 pipeline = Pipeline()
 pipeline.add_tasks(
     ToolkitTask(
         "Based on https://griptape.ai, tell me what griptape is.",
-        tools=[WebScraperTool(off_prompt=True), TaskMemoryTool(off_prompt=False)],
+        tools=[WebScraperTool(off_prompt=True), PromptSummaryTool(off_prompt=False)],
     )
 )
 
diff --git a/docs/griptape-framework/src/index_4.py b/docs/griptape-framework/src/index_4.py
index dd07280ce..50465f99e 100644
--- a/docs/griptape-framework/src/index_4.py
+++ b/docs/griptape-framework/src/index_4.py
@@ -1,7 +1,7 @@
 from griptape.memory.structure import ConversationMemory
 from griptape.structures import Pipeline
 from griptape.tasks import PromptTask, ToolkitTask
-from griptape.tools import FileManagerTool, TaskMemoryTool, WebScraperTool
+from griptape.tools import FileManagerTool, PromptSummaryTool, WebScraperTool
 
 # Pipelines represent sequences of tasks.
 pipeline = Pipeline(conversation_memory=ConversationMemory())
@@ -11,7 +11,7 @@
     ToolkitTask(
         "{{ args[0] }}",
         # Add tools for web scraping, and file management
-        tools=[WebScraperTool(off_prompt=True), FileManagerTool(off_prompt=True), TaskMemoryTool(off_prompt=False)],
+        tools=[WebScraperTool(off_prompt=True), FileManagerTool(off_prompt=True), PromptSummaryTool(off_prompt=False)],
     ),
     # Augment `input` from the previous task.
     PromptTask("Say the following in spanish: {{ parent_output }}"),
diff --git a/docs/griptape-framework/structures/agents.md b/docs/griptape-framework/structures/agents.md
index 376e7288a..1b40fad2b 100644
--- a/docs/griptape-framework/structures/agents.md
+++ b/docs/griptape-framework/structures/agents.md
@@ -12,7 +12,7 @@ directly, which the agent uses to dynamically determine whether to use a [Prompt
 If [tools](../../reference/griptape/structures/agent.md#griptape.structures.agent.Agent.tools) are passed provided to the Agent, a [Toolkit Task](./tasks.md#toolkit-task) will be used. If no [tools](../../reference/griptape/structures/agent.md#griptape.structures.agent.Agent.tools)
 are provided, a [Prompt Task](./tasks.md#prompt-task) will be used.
 
-You can access the final output of the Agent by using the [output](../../reference/griptape/structures/agent.md#griptape.structures.structure.Structure.output) attribute.
+You can access the final output of the Agent by using the [output](../../reference/griptape/structures/structure.md#griptape.structures.structure.Structure.output) attribute.
 
 ## Toolkit Task Agent
 
diff --git a/docs/griptape-framework/structures/pipelines.md b/docs/griptape-framework/structures/pipelines.md
index fc5046196..7bcfc1348 100644
--- a/docs/griptape-framework/structures/pipelines.md
+++ b/docs/griptape-framework/structures/pipelines.md
@@ -6,7 +6,7 @@ search:
 ## Overview 
 A [Pipeline](../../reference/griptape/structures/pipeline.md) is very similar to an [Agent](../../reference/griptape/structures/agent.md), but allows for multiple tasks.
 
-You can access the final output of the Pipeline by using the [output](../../reference/griptape/structures/agent.md#griptape.structures.structure.Structure.output) attribute.
+You can access the final output of the Pipeline by using the [output](../../reference/griptape/structures/structure.md#griptape.structures.structure.Structure.output) attribute.
 
 ## Context
 
diff --git a/docs/griptape-framework/structures/src/task_memory_3.py b/docs/griptape-framework/structures/src/task_memory_3.py
index 926a21cd3..8a0e53d8c 100644
--- a/docs/griptape-framework/structures/src/task_memory_3.py
+++ b/docs/griptape-framework/structures/src/task_memory_3.py
@@ -1,7 +1,7 @@
 from griptape.structures import Agent
-from griptape.tools import CalculatorTool, TaskMemoryTool
+from griptape.tools import CalculatorTool, PromptSummaryTool
 
-# Create an agent with the CalculatorTool tool
-agent = Agent(tools=[CalculatorTool(off_prompt=True), TaskMemoryTool(off_prompt=False)])
+# Create an agent with the Calculator tool
+agent = Agent(tools=[CalculatorTool(off_prompt=True), PromptSummaryTool(off_prompt=False)])
 
 agent.run("What is the square root of 12345?")
diff --git a/docs/griptape-framework/structures/src/task_memory_5.py b/docs/griptape-framework/structures/src/task_memory_5.py
index a53d106b4..a061118e8 100644
--- a/docs/griptape-framework/structures/src/task_memory_5.py
+++ b/docs/griptape-framework/structures/src/task_memory_5.py
@@ -1,10 +1,10 @@
 from griptape.structures import Agent
-from griptape.tools import TaskMemoryTool, WebScraperTool
+from griptape.tools import QueryTool, WebScraperTool
 
 agent = Agent(
     tools=[
         WebScraperTool(off_prompt=True),
-        TaskMemoryTool(off_prompt=False),
+        QueryTool(off_prompt=False),
     ]
 )
 
diff --git a/docs/griptape-framework/structures/src/task_memory_6.py b/docs/griptape-framework/structures/src/task_memory_6.py
index 8d39f0286..3ce87f72d 100644
--- a/docs/griptape-framework/structures/src/task_memory_6.py
+++ b/docs/griptape-framework/structures/src/task_memory_6.py
@@ -6,13 +6,14 @@
     OpenAiChatPromptDriver,
     OpenAiEmbeddingDriver,
 )
-from griptape.engines.rag import RagEngine
-from griptape.engines.rag.modules import PromptResponseRagModule, VectorStoreRetrievalRagModule
-from griptape.engines.rag.stages import ResponseRagStage, RetrievalRagStage
 from griptape.memory import TaskMemory
 from griptape.memory.task.storage import TextArtifactStorage
 from griptape.structures import Agent
-from griptape.tools import FileManagerTool, TaskMemoryTool, WebScraperTool
+from griptape.tools import FileManagerTool, QueryTool, WebScraperTool
+
+config.drivers = OpenAiDriverConfig(
+    prompt=OpenAiChatPromptDriver(model="gpt-4"),
+)
 
 config.drivers = OpenAiDriverConfig(
     prompt=OpenAiChatPromptDriver(model="gpt-4"),
@@ -24,27 +25,13 @@
     task_memory=TaskMemory(
         artifact_storages={
             TextArtifact: TextArtifactStorage(
-                rag_engine=RagEngine(
-                    retrieval_stage=RetrievalRagStage(
-                        retrieval_modules=[
-                            VectorStoreRetrievalRagModule(
-                                vector_store_driver=vector_store_driver,
-                                query_params={"namespace": "griptape", "count": 20},
-                            )
-                        ]
-                    ),
-                    response_stage=ResponseRagStage(
-                        response_modules=[PromptResponseRagModule(prompt_driver=OpenAiChatPromptDriver(model="gpt-4o"))]
-                    ),
-                ),
-                retrieval_rag_module_name="VectorStoreRetrievalRagModule",
                 vector_store_driver=vector_store_driver,
             )
         }
     ),
     tools=[
         WebScraperTool(off_prompt=True),
-        TaskMemoryTool(off_prompt=True, allowlist=["query"]),
+        QueryTool(off_prompt=True),
         FileManagerTool(off_prompt=True),
     ],
 )
diff --git a/docs/griptape-framework/structures/src/task_memory_8.py b/docs/griptape-framework/structures/src/task_memory_8.py
index 846119228..ee106caec 100644
--- a/docs/griptape-framework/structures/src/task_memory_8.py
+++ b/docs/griptape-framework/structures/src/task_memory_8.py
@@ -1,10 +1,12 @@
 from griptape.structures import Agent
-from griptape.tools import TaskMemoryTool, WebScraperTool
+from griptape.tools import PromptSummaryTool, WebScraperTool
 
 agent = Agent(
     tools=[
         WebScraperTool(off_prompt=True),  # This tool will store the data in Task Memory
-        TaskMemoryTool(off_prompt=True),  # This tool will store the data back in Task Memory with no way to get it out
+        PromptSummaryTool(
+            off_prompt=True
+        ),  # This tool will store the data back in Task Memory with no way to get it out
     ]
 )
 agent.run(
diff --git a/docs/griptape-framework/structures/src/tasks_16.py b/docs/griptape-framework/structures/src/tasks_16.py
index 5f2e6b718..a6da835a6 100644
--- a/docs/griptape-framework/structures/src/tasks_16.py
+++ b/docs/griptape-framework/structures/src/tasks_16.py
@@ -5,7 +5,7 @@
 from griptape.structures import Agent, Pipeline
 from griptape.tasks import StructureRunTask
 from griptape.tools import (
-    TaskMemoryTool,
+    PromptSummaryTool,
     WebScraperTool,
     WebSearchTool,
 )
@@ -23,7 +23,7 @@ def build_researcher() -> Agent:
             WebScraperTool(
                 off_prompt=True,
             ),
-            TaskMemoryTool(off_prompt=False),
+            PromptSummaryTool(off_prompt=False),
         ],
         rulesets=[
             Ruleset(
diff --git a/docs/griptape-framework/structures/src/tasks_4.py b/docs/griptape-framework/structures/src/tasks_4.py
index 936b59f99..cd73b3ada 100644
--- a/docs/griptape-framework/structures/src/tasks_4.py
+++ b/docs/griptape-framework/structures/src/tasks_4.py
@@ -1,12 +1,12 @@
 from griptape.structures import Agent
 from griptape.tasks import ToolkitTask
-from griptape.tools import FileManagerTool, TaskMemoryTool, WebScraperTool
+from griptape.tools import FileManagerTool, PromptSummaryTool, WebScraperTool
 
 agent = Agent()
 agent.add_task(
     ToolkitTask(
         "Load https://www.griptape.ai, summarize it, and store it in a file called griptape.txt",
-        tools=[WebScraperTool(off_prompt=True), FileManagerTool(off_prompt=True), TaskMemoryTool(off_prompt=True)],
+        tools=[WebScraperTool(off_prompt=True), FileManagerTool(off_prompt=True), PromptSummaryTool(off_prompt=True)],
     ),
 )
 
diff --git a/docs/griptape-framework/structures/task-memory.md b/docs/griptape-framework/structures/task-memory.md
index ccc4dd1e7..81334b1cb 100644
--- a/docs/griptape-framework/structures/task-memory.md
+++ b/docs/griptape-framework/structures/task-memory.md
@@ -68,19 +68,16 @@ Let's explore what happens when `off_prompt` is set to `True`:
 ...Output truncated for brevity...
 ```
 
-When we set `off_prompt` to `True`, the Agent does not function as expected, even generating an error. This is because the CalculatorTool output is being stored in Task Memory but the Agent has no way to access it. 
-To fix this, we need a [Tool that can read from Task Memory](#tools-that-can-read-from-task-memory) such as the `TaskMemoryTool`.
+When we set `off_prompt` to `True`, the Agent does not function as expected, even generating an error. This is because the Calculator output is being stored in Task Memory but the Agent has no way to access it. 
+To fix this, we need a [Tool that can read from Task Memory](#tools-that-can-read-from-task-memory) such as the `PromptSummaryTool`.
 This is an example of [not providing a Task Memory compatible Tool](#not-providing-a-task-memory-compatible-tool).
 
-## Task Memory Tool
+## Prompt Summary Tool
 
-The [TaskMemoryTool](../../griptape-tools/official-tools/task-memory-tool.md) is a Tool that allows an Agent to interact with Task Memory. It has the following methods:
+The [PromptSummaryTool](../../griptape-tools/official-tools/prompt-summary-tool.md) is a Tool that allows an Agent to summarize the Artifacts in Task Memory. It has the following methods:
 
-- `query`: Retrieve the content of an Artifact stored in Task Memory.
-- `summarize`: Summarize the content of an Artifact stored in Task Memory.
-
-Let's add `TaskMemoryTool` to the Agent and run the same task.
-Note that on the `TaskMemoryTool` we've set `off_prompt` to `False` so that the results of the query can be returned directly to the LLM. 
+Let's add `PromptSummaryTool` to the Agent and run the same task.
+Note that on the `PromptSummaryTool` we've set `off_prompt` to `False` so that the results of the query can be returned directly to the LLM. 
 If we had kept it as `True`, the results would have been stored back Task Memory which would've put us back to square one. See [Task Memory Looping](#task-memory-looping) for more information on this scenario.
 
 ```python
@@ -88,22 +85,43 @@ If we had kept it as `True`, the results would have been stored back Task Memory
 ```
 
 ```
-[04/26/24 13:13:01] INFO     ToolkitTask 5b46f9ef677c4b31906b48aba3f45e2c
+[08/12/24 14:54:04] INFO     ToolkitTask f7ebd8acc3d64e3ca9db82ef9ec4e65f
                              Input: What is the square root of 12345?
-[04/26/24 13:13:07] INFO     Subtask 611d98ea5576430fbc63259420577ab2
-                             Thought: To find the square root of 12345, I can use the CalculatorTool action with the expression "12345 ** 0.5".
-                             Actions: [{"name": "CalculatorTool", "path": "calculate", "input": {"values": {"expression": "12345 ** 0.5"}}, "tag": "sqrt_12345"}]
-[04/26/24 13:13:08] INFO     Subtask 611d98ea5576430fbc63259420577ab2
-                             Response: Output of "CalculatorTool.calculate" was stored in memory with memory_name "TaskMemory" and artifact_namespace
-                             "7554b69e1d414a469b8882e2266dcea1"
-[04/26/24 13:13:15] INFO     Subtask 32b9163a15644212be60b8fba07bd23b
-                             Thought: The square root of 12345 has been calculated and stored in memory. I can retrieve this value using the TaskMemoryTool action with
-                             the query path, providing the memory_name and artifact_namespace as input.
-                             Actions: [{"tag": "retrieve_sqrt", "name": "TaskMemoryTool", "path": "query", "input": {"values": {"memory_name": "TaskMemory",
-                             "artifact_namespace": "7554b69e1d414a469b8882e2266dcea1", "query": "What is the result of the calculation?"}}}]
-[04/26/24 13:13:16] INFO     Subtask 32b9163a15644212be60b8fba07bd23b
-                             Response: The result of the calculation is 111.1080555135405.
-[04/26/24 13:13:17] INFO     ToolkitTask 5b46f9ef677c4b31906b48aba3f45e2c
+[08/12/24 14:54:05] INFO     Subtask 777693d039e74ed288f663742fdde2ea
+                             Actions: [
+                               {
+                                 "tag": "call_DXSs19G27VOV7EmP3PoRwGZI",
+                                 "name": "Calculator",
+                                 "path": "calculate",
+                                 "input": {
+                                   "values": {
+                                     "expression": "12345 ** 0.5"
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask 777693d039e74ed288f663742fdde2ea
+                             Response: Output of "Calculator.calculate" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "370853a8937f4dd7a9e923254459cff2"
+[08/12/24 14:54:06] INFO     Subtask c8394ca51f1f4ae1b715618a2c5c8120
+                             Actions: [
+                               {
+                                 "tag": "call_qqpsWEvAUGIcPLrwAHGuH6o3",
+                                 "name": "PromptSummaryTool",
+                                 "path": "summarize",
+                                 "input": {
+                                   "values": {
+                                     "summary": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "370853a8937f4dd7a9e923254459cff2"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 14:54:07] INFO     Subtask c8394ca51f1f4ae1b715618a2c5c8120
+                             Response: The text contains a single numerical value: 111.1080555135405.
+[08/12/24 14:54:08] INFO     ToolkitTask f7ebd8acc3d64e3ca9db82ef9ec4e65f
                              Output: The square root of 12345 is approximately 111.108.
 ```
 
@@ -125,8 +143,8 @@ When running this example, we get the following error:
                              Please reduce the length of the messages.", 'type': 'invalid_request_error', 'param': 'messages', 'code': 'context_length_exceeded'}}
 ```
 
-This is because the content of the webpage is too large to fit in the LLM's input token limit. We can fix this by storing the content in Task Memory, and then querying it with the `TaskMemoryTool`.
-Note that we're setting `off_prompt` to `False` on the `TaskMemoryTool` so that the _queried_ content can be returned directly to the LLM.
+This is because the content of the webpage is too large to fit in the LLM's input token limit. We can fix this by storing the content in Task Memory, and then querying it with the `QueryTool`.
+Note that we're setting `off_prompt` to `False` on the `QueryTool` so that the _queried_ content can be returned directly to the LLM.
 
 ```python
 --8<-- "docs/griptape-framework/structures/src/task_memory_5.py"
@@ -134,24 +152,46 @@ Note that we're setting `off_prompt` to `False` on the `TaskMemoryTool` so that
 
 And now we get the expected output:
 ```
-[04/26/24 13:51:51] INFO     ToolkitTask 7aca20f202df47a2b9848ed7025f9c21
+[08/12/24 14:56:18] INFO     ToolkitTask d3ce58587dc944b0a30a205631b82944
                              Input: According to this page https://en.wikipedia.org/wiki/Elden_Ring, how many copies of Elden Ring have been sold?
-[04/26/24 13:51:58] INFO     Subtask 5b21d8ead32b4644abcd1e852bb5f512
-                             Thought: I need to scrape the content of the provided URL to find the information about how many copies of Elden Ring have been sold.
-                             Actions: [{"name": "WebScraper", "path": "get_content", "input": {"values": {"url": "https://en.wikipedia.org/wiki/Elden_Ring"}}, "tag":
-                             "scrape_elden_ring"}]
-[04/26/24 13:52:04] INFO     Subtask 5b21d8ead32b4644abcd1e852bb5f512
-                             Response: Output of "WebScraper.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
-                             "2d4ebc7211074bb7be26613eb25d8fc1"
-[04/26/24 13:52:11] INFO     Subtask f12eb3d3b4924e4085808236b460b43d
-                             Thought: Now that the webpage content is stored in memory, I need to query this memory to find the information about how many copies of Elden
-                             Ring have been sold.
-                             Actions: [{"tag": "query_sales", "name": "TaskMemoryTool", "path": "query", "input": {"values": {"memory_name": "TaskMemory",
-                             "artifact_namespace": "2d4ebc7211074bb7be26613eb25d8fc1", "query": "How many copies of Elden Ring have been sold?"}}}]
-[04/26/24 13:52:14] INFO     Subtask f12eb3d3b4924e4085808236b460b43d
-                             Response: Elden Ring sold 23 million copies by February 2024.
-[04/26/24 13:52:15] INFO     ToolkitTask 7aca20f202df47a2b9848ed7025f9c21
-                             Output: Elden Ring sold 23 million copies by February 2024.
+[08/12/24 14:56:20] INFO     Subtask 494850ec40fe474c83d48b5620c5dcbb
+                             Actions: [
+                               {
+                                 "tag": "call_DGsOHC4AVxhV7RPVA7q3rATX",
+                                 "name": "WebScraperTool",
+                                 "path": "get_content",
+                                 "input": {
+                                   "values": {
+                                     "url": "https://en.wikipedia.org/wiki/Elden_Ring"
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 14:56:25] INFO     Subtask 494850ec40fe474c83d48b5620c5dcbb
+                             Response: Output of "WebScraperTool.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "b9f53d6d9b35455aaf4d99719c1bfffa"
+[08/12/24 14:56:26] INFO     Subtask 8669ee523bb64550850566011bcd14e2
+                             Actions: [
+                               {
+                                 "tag": "call_DGsOHC4AVxhV7RPVA7q3rATX",
+                                 "name": "QueryTool",
+                                 "path": "search",
+                                 "input": {
+                                   "values": {
+                                     "query": "number of copies sold",
+                                     "content": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "b9f53d6d9b35455aaf4d99719c1bfffa"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 14:56:29] INFO     Subtask 8669ee523bb64550850566011bcd14e2
+                             Response: "Elden Ring" sold 13.4 million copies worldwide by the end of March 2022 and 25 million by June 2024. The downloadable content (DLC)
+                             "Shadow of the Erdtree" sold five million copies within three days of its release.
+[08/12/24 14:56:30] INFO     ToolkitTask d3ce58587dc944b0a30a205631b82944
+                             Output: Elden Ring sold 13.4 million copies worldwide by the end of March 2022 and 25 million by June 2024.
 ```
 
 ## Sensitive Data
@@ -159,68 +199,72 @@ And now we get the expected output:
 Because Task Memory splits up the storage and retrieval of data, you can use different models for each step.
 
 Here is an example where we use GPT-4 to orchestrate the Tools and store the data in Task Memory, and Amazon Bedrock's Titan model to query the raw content.
-In this example, GPT-4 _never_ sees the contents of the page, only that it was stored in Task Memory. Even the query results generated by the Titan model are stored in Task Memory so that the `FileManager` can save the results to disk without GPT-4 ever seeing them.
+In this example, GPT-4 _never_ sees the contents of the page, only that it was stored in Task Memory. Even the query results generated by the Titan model are stored in Task Memory so that the `FileManagerTool` can save the results to disk without GPT-4 ever seeing them.
 
 ```python 
 --8<-- "docs/griptape-framework/structures/src/task_memory_6.py"
 ```
 
 ```
-[06/21/24 16:00:01] INFO     ToolkitTask 17f30ac14701490c8ef71508f420ea9f       
-                             Input: Use this page                               
-                             https://en.wikipedia.org/wiki/Elden_Ring to find   
-                             how many copies of Elden Ring have been sold, and  
-                             then save the result to a file.                    
-[06/21/24 16:00:05] INFO     Subtask cb06889205334ec9afd7e97f7f231ab5           
-                             Thought: First, I need to scrape the content of the
-                             provided URL to find the information about how many
-                             copies of Elden Ring have been sold. Then, I will  
-                             save this information to a file.                   
-                                                                                
-                             Actions: [{"name": "WebScraper", "path":           
-                             "get_content", "input": {"values": {"url":         
-                             "https://en.wikipedia.org/wiki/Elden_Ring"}},      
-                             "tag": "scrape_elden_ring"}]                       
-[06/21/24 16:00:12] INFO     Subtask cb06889205334ec9afd7e97f7f231ab5           
-                             Response: Output of "WebScraper.get_content" was   
-                             stored in memory with memory_name "TaskMemory" and 
-                             artifact_namespace                                 
-                             "7e48bcff0da94ad3b06aa4e173f8f37b"                 
-[06/21/24 16:00:17] INFO     Subtask 56102d42475d413299ce52a0230506b7           
-                             Thought: Now that the webpage content is stored in 
-                             memory, I need to query this memory to find the    
-                             information about how many copies of Elden Ring    
-                             have been sold.                                    
-                             Actions: [{"tag": "query_sales", "name":           
-                             "TaskMemoryTool", "path": "query", "input":      
-                             {"values": {"memory_name": "TaskMemory",           
-                             "artifact_namespace":                              
-                             "7e48bcff0da94ad3b06aa4e173f8f37b", "query": "How  
-                             many copies of Elden Ring have been sold?"}}}]     
-[06/21/24 16:00:19] INFO     Subtask 56102d42475d413299ce52a0230506b7           
-                             Response: Output of "TaskMemoryTool.query" was   
-                             stored in memory with memory_name "TaskMemory" and 
-                             artifact_namespace                                 
-                             "9ecf4d7b7d0c46149dfc46ba236f178e"                 
-[06/21/24 16:00:25] INFO     Subtask ed2921791dcf46b68c9d8d2f8dbeddbd           
-                             Thought: Now that I have the sales information     
-                             stored in memory, I need to save this information  
-                             to a file.                                         
-                             Actions: [{"tag": "save_sales_info", "name":       
-                             "FileManager", "path":                             
-                             "save_memory_artifacts_to_disk", "input":          
-                             {"values": {"dir_name": "sales_info", "file_name": 
-                             "elden_ring_sales.txt", "memory_name":             
-                             "TaskMemory", "artifact_namespace":                
-                             "9ecf4d7b7d0c46149dfc46ba236f178e"}}}]             
-                    INFO     Subtask ed2921791dcf46b68c9d8d2f8dbeddbd           
-                             Response: Successfully saved memory artifacts to   
-                             disk                                               
-[06/21/24 16:00:27] INFO     ToolkitTask 17f30ac14701490c8ef71508f420ea9f       
-                             Output: The information about how many copies of   
-                             Elden Ring have been sold has been successfully    
-                             saved to the file "elden_ring_sales.txt" in the    
-                             "sales_info" directory.
+[08/12/24 14:55:21] INFO     ToolkitTask 329b1abc760e4d30bbf23e349451d930
+                             Input: Use this page https://en.wikipedia.org/wiki/Elden_Ring to find how many copies of Elden Ring have been sold, and then save the result to
+                             a file.
+[08/12/24 14:55:23] INFO     Subtask 26205b5623174424b618abafd886c4d8
+                             Actions: [
+                               {
+                                 "tag": "call_xMK0IyFZFbjlTapK7AA6kbNq",
+                                 "name": "WebScraperTool",
+                                 "path": "get_content",
+                                 "input": {
+                                   "values": {
+                                     "url": "https://en.wikipedia.org/wiki/Elden_Ring"
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 14:55:28] INFO     Subtask 26205b5623174424b618abafd886c4d8
+                             Response: Output of "WebScraperTool.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "44b8f230645148d0b8d44354c0f2df5b"
+[08/12/24 14:55:31] INFO     Subtask d8b4cf297a0d4d9db04e4f8e63b746c8
+                             Actions: [
+                               {
+                                 "tag": "call_Oiqq6oI20yqmdNrH9Mawb2fS",
+                                 "name": "QueryTool",
+                                 "path": "search",
+                                 "input": {
+                                   "values": {
+                                     "query": "copies sold",
+                                     "content": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "44b8f230645148d0b8d44354c0f2df5b"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 14:55:34] INFO     Subtask d8b4cf297a0d4d9db04e4f8e63b746c8
+                             Response: Output of "QueryTool.search" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "fd828ddd629e4974a7837f9dfde65954"
+[08/12/24 14:55:38] INFO     Subtask 7aafcb3fb0d845858e2fcf9b8dc8a7ec
+                             Actions: [
+                               {
+                                 "tag": "call_nV1DIPAEhUEAVMCjXND0pKoS",
+                                 "name": "FileManagerTool",
+                                 "path": "save_memory_artifacts_to_disk",
+                                 "input": {
+                                   "values": {
+                                     "dir_name": "results",
+                                     "file_name": "elden_ring_sales.txt",
+                                     "memory_name": "TaskMemory",
+                                     "artifact_namespace": "fd828ddd629e4974a7837f9dfde65954"
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask 7aafcb3fb0d845858e2fcf9b8dc8a7ec
+                             Response: Successfully saved memory artifacts to disk
+[08/12/24 14:55:40] INFO     ToolkitTask 329b1abc760e4d30bbf23e349451d930
+                             Output: Successfully saved the number of copies sold of Elden Ring to a file named "elden_ring_sales.txt" in the "results" directory.
 ```
 
 ## Tools That Can Read From Task Memory
@@ -229,11 +273,10 @@ As seen in the previous example, certain Tools are designed to read directly fro
 
 Today, these include:
 
-- [TaskMemoryTool](../../griptape-tools/official-tools/task-memory-tool.md)
-- [FileManager](../../griptape-tools/official-tools/file-manager-tool.md)
-- [AwsS3Tool](../../griptape-tools/official-tools/aws-s3-tool.md)
-- [GoogleDriveTool](../../griptape-tools/official-tools/google-drive-tool.md)
-- [GoogleDocsTool](../../griptape-tools/official-tools/google-docs-tool.md)
+- [PromptSummaryTool](../../griptape-tools/official-tools/prompt-summary-tool.md)
+- [ExtractionTool](../../griptape-tools/official-tools/extraction-tool.md)
+- [RagClient](../../griptape-tools/official-tools/rag-tool.md)
+- [FileManagerTool](../../griptape-tools/official-tools/file-manager-tool.md)
 
 ## Task Memory Considerations
 
diff --git a/docs/griptape-framework/structures/tasks.md b/docs/griptape-framework/structures/tasks.md
index 477ce7b64..f91937ec0 100644
--- a/docs/griptape-framework/structures/tasks.md
+++ b/docs/griptape-framework/structures/tasks.md
@@ -99,39 +99,63 @@ This Task takes in one or more Tools which the LLM will decide to use through Ch
 ```
 
 ```
-[09/08/23 11:14:55] INFO     ToolkitTask 22af656c6ad643e188fe80f9378dfff9
+[08/12/24 15:16:30] INFO     ToolkitTask f5b44fe1dadc4e6688053df71d97e0de
                              Input: Load https://www.griptape.ai, summarize it, and store it in a file called griptape.txt
-[09/08/23 11:15:02] INFO     Subtask 7a6356470e6a4b08b61edc5591b37f0c
-                             Thought: The first step is to load the webpage using the WebScraper tool's get_content activity.
-
-                             Action: {"name": "WebScraper", "path": "get_content", "input": {"values": {"url":
-                             "https://www.griptape.ai"}}}
-[09/08/23 11:15:03] INFO     Subtask 7a6356470e6a4b08b61edc5591b37f0c
-                             Response: Output of "WebScraper.get_content" was stored in memory with memory_name "TaskMemory" and
-                             artifact_namespace "2b50373849d140f698ba8071066437ee"
-[09/08/23 11:15:11] INFO     Subtask a22a7e4ebf594b4b895fcbe8a95c1dd3
-                             Thought: Now that the webpage content is stored in memory, I can use the TaskMemory tool's summarize activity
-                             to summarize it.
-                             Action: {"name": "TaskMemoryTool", "path": "summarize", "input": {"values": {"memory_name": "TaskMemory", "artifact_namespace": "2b50373849d140f698ba8071066437ee"}}}
-[09/08/23 11:15:15] INFO     Subtask a22a7e4ebf594b4b895fcbe8a95c1dd3
-                             Response: Griptape is an open source framework that allows developers to build and deploy AI applications
-                             using large language models (LLMs). It provides the ability to create conversational and event-driven apps that
-                             can access and manipulate data securely. Griptape enforces structures like sequential pipelines and DAG-based
-                             workflows for predictability, while also allowing for creativity by safely prompting LLMs with external APIs and
-                             data stores. The framework can be used to create AI systems that operate across both dimensions. Griptape Cloud
-                             is a managed platform for deploying and managing AI apps, and it offers features like scheduling and connecting
-                             to data stores and APIs.
-[09/08/23 11:15:27] INFO     Subtask 7afb3d44d0114b7f8ef2dac4314a8e90
-                             Thought: Now that I have the summary, I can use the FileManager tool's save_file_to_disk activity to store the
-                             summary in a file named griptape.txt.
-                             Action: {"name": "FileManager", "path": "save_file_to_disk", "input": {"values":
-                             {"memory_name": "TaskMemory", "artifact_namespace": "2b50373849d140f698ba8071066437ee", "path":
-                             "griptape.txt"}}}
-                    INFO     Subtask 7afb3d44d0114b7f8ef2dac4314a8e90
-                             Response: saved successfully
-[09/08/23 11:15:31] INFO     ToolkitTask 22af656c6ad643e188fe80f9378dfff9
-                             Output: The summary of the webpage https://www.griptape.ai has been successfully stored in a file named
-                             griptape.txt.
+[08/12/24 15:16:32] INFO     Subtask a4483eddfbe84129b0f4c04ef0f5d695
+                             Actions: [
+                               {
+                                 "tag": "call_AFeOL9MGhZ4mPFCULcBEm4NQ",
+                                 "name": "WebScraperTool",
+                                 "path": "get_content",
+                                 "input": {
+                                   "values": {
+                                     "url": "https://www.griptape.ai"
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask a4483eddfbe84129b0f4c04ef0f5d695
+                             Response: Output of "WebScraperTool.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "c6a6bcfc16f34481a068108aeaa6838e"
+[08/12/24 15:16:33] INFO     Subtask ee5f11666ded4dc39b94e4c59d18fbc7
+                             Actions: [
+                               {
+                                 "tag": "call_aT7DX0YSQPmOcnumWXrGoMNt",
+                                 "name": "PromptSummaryTool",
+                                 "path": "summarize",
+                                 "input": {
+                                   "values": {
+                                     "summary": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "c6a6bcfc16f34481a068108aeaa6838e"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 15:16:37] INFO     Subtask ee5f11666ded4dc39b94e4c59d18fbc7
+                             Response: Output of "PromptSummaryTool.summarize" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "669d29a704444176be93d09d014298df"
+[08/12/24 15:16:38] INFO     Subtask d9b2dd9f96d841f49f5d460e33905183
+                             Actions: [
+                               {
+                                 "tag": "call_QgMk1M1UuD6DAnxjfQz1MH6X",
+                                 "name": "FileManagerTool",
+                                 "path": "save_memory_artifacts_to_disk",
+                                 "input": {
+                                   "values": {
+                                     "dir_name": ".",
+                                     "file_name": "griptape.txt",
+                                     "memory_name": "TaskMemory",
+                                     "artifact_namespace": "669d29a704444176be93d09d014298df"
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask d9b2dd9f96d841f49f5d460e33905183
+                             Response: Successfully saved memory artifacts to disk
+[08/12/24 15:16:39] INFO     ToolkitTask f5b44fe1dadc4e6688053df71d97e0de
+                             Output: The content from https://www.griptape.ai has been summarized and stored in a file called `griptape.txt`.
 ```
 
 ## Tool Task
@@ -280,7 +304,7 @@ This task takes a python function, and authors can elect to return a custom arti
 
 To generate an image, use one of the following [Image Generation Tasks](../../reference/griptape/tasks/index.md). All Image Generation Tasks accept an [Image Generation Engine](../engines/image-generation-engines.md) configured to use an [Image Generation Driver](../drivers/image-generation-drivers.md).
 
-All successful Image Generation Tasks will always output an [Image Artifact](../data/artifacts.md#imageartifact). Each task can be configured to additionally write the generated image to disk by providing either the `output_file` or `output_dir` field. The `output_file` field supports file names in the current directory (`my_image.png`), relative directory prefixes (`images/my_image.png`), or absolute paths (`/usr/var/my_image.png`). By setting `output_dir`, the task will generate a file name and place the image in the requested directory.
+All successful Image Generation Tasks will always output an [Image Artifact](../data/artifacts.md#image). Each task can be configured to additionally write the generated image to disk by providing either the `output_file` or `output_dir` field. The `output_file` field supports file names in the current directory (`my_image.png`), relative directory prefixes (`images/my_image.png`), or absolute paths (`/usr/var/my_image.png`). By setting `output_dir`, the task will generate a file name and place the image in the requested directory.
 
 ### Prompt Image Generation Task
 
@@ -318,7 +342,7 @@ The [Outpainting Image Generation Task](../../reference/griptape/tasks/outpainti
 
 The [Image Query Task](../../reference/griptape/tasks/image_query_task.md) performs a natural language query on one or more input images. This Task uses an [Image Query Engine](../engines/image-query-engines.md) configured with an [Image Query Driver](../drivers/image-query-drivers.md) to perform the query. The functionality provided by this Task depend on the capabilities of the model provided by the Driver.
 
-This Task accepts two inputs: a query (represented by either a string or a [Text Artifact](../data/artifacts.md#textartifact)) and a list of [Image Artifacts](../data/artifacts.md#imageartifact) or a Callable returning these two values.
+This Task accepts two inputs: a query (represented by either a string or a [Text Artifact](../data/artifacts.md#text)) and a list of [Image Artifacts](../data/artifacts.md#image) or a Callable returning these two values.
 
 ```python
 --8<-- "docs/griptape-framework/structures/src/tasks_15.py"
diff --git a/docs/griptape-framework/structures/workflows.md b/docs/griptape-framework/structures/workflows.md
index 87bb2ae89..9161268ae 100644
--- a/docs/griptape-framework/structures/workflows.md
+++ b/docs/griptape-framework/structures/workflows.md
@@ -7,7 +7,7 @@ search:
 
 A [Workflow](../../reference/griptape/structures/workflow.md) is a non-sequential DAG that can be used for complex concurrent scenarios with tasks having multiple inputs.
 
-You can access the final output of the Workflow by using the [output](../../reference/griptape/structures/agent.md#griptape.structures.structure.Structure.output) attribute.
+You can access the final output of the Workflow by using the [output](../../reference/griptape/structures/structure.md#griptape.structures.structure.Structure.output) attribute.
 
 ## Context
 
diff --git a/docs/griptape-framework/tools/index.md b/docs/griptape-framework/tools/index.md
index 808849dae..d97a9347c 100644
--- a/docs/griptape-framework/tools/index.md
+++ b/docs/griptape-framework/tools/index.md
@@ -19,37 +19,72 @@ Here is an example of a Pipeline using Tools:
 ```
 
 ```
-[09/08/23 10:53:56] INFO     ToolkitTask 979d99f68766423ea05b367e951281bc
-                             Input: Load https://www.griptape.ai, summarize it, and store it in a file called griptape.txt
-[09/08/23 10:54:02] INFO     Subtask 97bd154a71e14a1699f8152e50490a71
-                             Thought: The first step is to load the content of the webpage. I can use the WebScraper tool with the get_content
-                             activity for this.
-
-                             Action: {"name": "WebScraper", "path": "get_content", "input": {"values": {"url":
-                             "https://www.griptape.ai"}}}
-[09/08/23 10:54:03] INFO     Subtask 97bd154a71e14a1699f8152e50490a71
-                             Response: Output of "WebScraper.get_content" was stored in memory with memory_name "TaskMemory" and
-                             artifact_namespace "9eb6f5828cf64356bf323f11d28be27e"
-[09/08/23 10:54:09] INFO     Subtask 7ee08458ce154e3d970711b7d3ed79ba
-                             Thought: Now that the webpage content is stored in memory, I can use the TaskMemory tool with the summarize
-                             activity to summarize the content.
-                             Action: {"name": "TaskMemoryTool", "path": "summarize", "input": {"values": {"memory_name": "TaskMemory", "artifact_namespace": "9eb6f5828cf64356bf323f11d28be27e"}}}
-[09/08/23 10:54:12] INFO     Subtask 7ee08458ce154e3d970711b7d3ed79ba
-                             Response: Griptape is an open source framework that allows developers to build and deploy AI applications
-                             using large language models (LLMs). It provides the ability to create conversational and event-driven apps that
-                             can access and manipulate data securely. Griptape enforces structures like sequential pipelines and workflows for
-                             predictability, while also allowing for creativity by safely prompting LLMs with external APIs and data stores.
-                             The framework can be used to create AI systems that operate across both predictability and creativity dimensions.
-                             Griptape Cloud is a managed platform for deploying and managing AI apps.
-[09/08/23 10:54:24] INFO     Subtask a024949a9a134f058f2e6b7c379c8713
-                             Thought: Now that I have the summary, I can store it in a file called griptape.txt. I can use the FileManager
-                             tool with the save_file_to_disk activity for this.
-                             Action: {"name": "FileManager", "path": "save_file_to_disk", "input": {"values":
-                             {"memory_name": "TaskMemory", "artifact_namespace": "9eb6f5828cf64356bf323f11d28be27e", "path":
-                             "griptape.txt"}}}
-                    INFO     Subtask a024949a9a134f058f2e6b7c379c8713
-                             Response: saved successfully
-[09/08/23 10:54:27] INFO     ToolkitTask 979d99f68766423ea05b367e951281bc
-                             Output: The summary of the webpage https://www.griptape.ai has been successfully stored in a file called
-                             griptape.txt.
+[08/12/24 15:18:19] INFO     ToolkitTask 48ac0486e5374e1ea53e8d2b955e511f
+                             Input: Load https://www.griptape.ai, summarize it, and store it in griptape.txt
+[08/12/24 15:18:20] INFO     Subtask 3b8365c077ae4a7e94087bfeff7a858c
+                             Actions: [
+                               {
+                                 "tag": "call_P6vaURTXfiYBJZolTkUSRHRc",
+                                 "name": "WebScraperTool",
+                                 "path": "get_content",
+                                 "input": {
+                                   "values": {
+                                     "url": "https://www.griptape.ai"
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask 3b8365c077ae4a7e94087bfeff7a858c
+                             Response: Output of "WebScraperTool.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "301e546f4450489ea4680645297092a2"
+[08/12/24 15:18:21] INFO     Subtask 930e9ca52e4140a48cce1e47368d45be
+                             Actions: [
+                               {
+                                 "tag": "call_0VOTEvinRer7rG4oEirBYcow",
+                                 "name": "PromptSummaryTool",
+                                 "path": "summarize",
+                                 "input": {
+                                   "values": {
+                                     "summary": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "301e546f4450489ea4680645297092a2"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 15:18:24] INFO     Subtask 930e9ca52e4140a48cce1e47368d45be
+                             Response: Griptape offers a comprehensive solution for building, deploying, and scaling AI applications in the cloud. It provides developers
+                             with a framework and cloud services to create retrieval-driven AI-powered applications without needing extensive knowledge of AI or prompt
+                             engineering. The Griptape Framework allows developers to build business logic using Python, ensuring better security, performance, and
+                             cost-efficiency. Griptape Cloud handles infrastructure management, enabling seamless deployment and scaling of applications. Key features
+                             include automated data preparation (ETL), retrieval as a service (RAG), and a structure runtime (RUN) for building AI agents, pipelines, and
+                             workflows. Griptape also offers solutions for custom projects, turnkey SaaS offerings, and finished applications.
+[08/12/24 15:18:27] INFO     Subtask d0f22504f576401f8d7e8ea78270a376
+                             Actions: [
+                               {
+                                 "tag": "call_zdUe2vdR0DCfR6LKcxjI6ayb",
+                                 "name": "FileManagerTool",
+                                 "path": "save_content_to_file",
+                                 "input": {
+                                   "values": {
+                                     "path": "griptape.txt",
+                                     "content": "Griptape offers a comprehensive solution for building, deploying, and scaling AI applications in the cloud. It provides
+                             developers with a framework and cloud services to create retrieval-driven AI-powered applications without needing extensive knowledge of AI or
+                             prompt engineering. The Griptape Framework allows developers to build business logic using Python, ensuring better security, performance, and
+                             cost-efficiency. Griptape Cloud handles infrastructure management, enabling seamless deployment and scaling of applications. Key features
+                             include automated data preparation (ETL), retrieval as a service (RAG), and a structure runtime (RUN) for building AI agents, pipelines, and
+                             workflows. Griptape also offers solutions for custom projects, turnkey SaaS offerings, and finished applications."
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask d0f22504f576401f8d7e8ea78270a376
+                             Response: Successfully saved file
+[08/12/24 15:18:28] INFO     ToolkitTask 48ac0486e5374e1ea53e8d2b955e511f
+                             Output: The content from https://www.griptape.ai has been summarized and stored in griptape.txt.
+                    INFO     PromptTask 4a9c59b1c06d4c549373d243a12f1285
+                             Input: Say the following in spanish: The content from https://www.griptape.ai has been summarized and stored in griptape.txt.
+                    INFO     PromptTask 4a9c59b1c06d4c549373d243a12f1285
+                             Output: El contenido de https://www.griptape.ai ha sido resumido y almacenado en griptape.txt.
 ```
diff --git a/docs/griptape-framework/tools/src/index_1.py b/docs/griptape-framework/tools/src/index_1.py
index 488dcfbc8..a894e2037 100644
--- a/docs/griptape-framework/tools/src/index_1.py
+++ b/docs/griptape-framework/tools/src/index_1.py
@@ -1,13 +1,17 @@
 from griptape.structures import Pipeline
 from griptape.tasks import ToolkitTask
-from griptape.tools import FileManagerTool, TaskMemoryTool, WebScraperTool
+from griptape.tools import FileManagerTool, PromptSummaryTool, WebScraperTool
 
 pipeline = Pipeline()
 
 pipeline.add_tasks(
     ToolkitTask(
         "Load https://www.griptape.ai, summarize it, and store it in a file called griptape.txt",
-        tools=[WebScraperTool(off_prompt=True), FileManagerTool(off_prompt=True), TaskMemoryTool(off_prompt=False)],
+        tools=[
+            WebScraperTool(off_prompt=True),
+            FileManagerTool(off_prompt=True),
+            PromptSummaryTool(off_prompt=False),
+        ],
     ),
 )
 
diff --git a/docs/griptape-tools/official-tools/aws-iam-tool.md b/docs/griptape-tools/official-tools/aws-iam-tool.md
index 1f594cff0..8be54afb5 100644
--- a/docs/griptape-tools/official-tools/aws-iam-tool.md
+++ b/docs/griptape-tools/official-tools/aws-iam-tool.md
@@ -6,50 +6,59 @@ This tool enables LLMs to make AWS IAM API requests.
 --8<-- "docs/griptape-tools/official-tools/src/aws_iam_tool_1.py"
 ```
 ```
-[09/11/23 16:45:45] INFO     Task 890fcf77fb074c9490d5c91563e0c995              
-                             Input: List all my IAM users                       
-[09/11/23 16:45:51] INFO     Subtask f2f0809ee10d4538972ed01fdd6a2fb8           
-                             Thought: To list all IAM users, I can use the      
-                             AwsIamTool tool with the list_users activity.    
-                             This activity does not require any input.          
-                                                                                
-                             Action: {"name": "AwsIamTool",   
-                             "path": "list_users"}                          
-[09/11/23 16:45:52] INFO     Subtask f2f0809ee10d4538972ed01fdd6a2fb8           
-                             Response: Output of "AwsIamTool.list_users"   
-                             was stored in memory with memory_name              
-                             "TaskMemory" and artifact_namespace            
-                             "51d22a018a434904a5da3bb8d4f763f7"                 
-[09/11/23 16:45:59] INFO     Subtask 8e0e918571544eeebf46de898466c48c           
-                             Thought: The output of the list_users activity is  
-                             stored in memory. I can retrieve this information  
-                             using the TaskMemory tool with the summarize   
-                             activity.
-                             Action: {"name": "TaskMemoryTool", "path":   
-                             "summarize", "input": {"values": {"memory_name":   
-                             "TaskMemory", "artifact_namespace":                
-                             "51d22a018a434904a5da3bb8d4f763f7"}}}                                                 
-[09/11/23 16:46:03] INFO     Subtask 8e0e918571544eeebf46de898466c48c           
-                             Response: The text provides information about   
-                             two different users in an AWS IAM system. The first
-                             user is named "example-user-1" and has a
-                             user ID of "AIDASHBEHWJLQV2IOYDHM". The second user
-                             is named "example-user-2" and   
-                             has a user ID of "AIDASHBEHWJLWHVS76C6X". Both     
-                             users have a path of "/", and their ARNs (Amazon   
-                             Resource Names) indicate their location in the IAM 
-                             system. The first user was created on July 18,     
-                             2023, at 20:29:27 UTC, while the second user was   
-                             created on August 29, 2023, at 20:56:37 UTC.       
-[09/11/23 16:46:13] INFO     Task 890fcf77fb074c9490d5c91563e0c995              
-                             Output: There are two IAM users in your AWS        
-                             account:                                           
-                                                                                
-                             1. User "example-user-1" with user ID   
-                             "AIDASHBEHWJLQV2IOYDHM", created on July 18, 2023, 
-                             at 20:29:27 UTC.                                   
-                             2. User "example-user-2" with   
-                             user ID "AIDASHBEHWJLWHVS76C6X", created on August 
-                             29, 2023, at 20:56:37 UTC.   
+[08/12/24 14:56:59] INFO     ToolkitTask 12345abcd67890efghijk1112131415
+                             Input: List all my IAM users
+[08/12/24 14:57:00] INFO     Subtask 54321dcba09876fedcba1234567890ab
+                             Actions: [
+                               {
+                                 "tag": "call_OxhQ9ITNIFq0WjkSnOCYAx8h",
+                                 "name": "AwsIamClient",
+                                 "path": "list_users",
+                                 "input": {
+                                   "values": {}
+                                 }
+                               }
+                             ]
+                    INFO     Subtask 54321dcba09876fedcba1234567890ab
+                             Response: {'Path': '/', 'UserName': 'dummy-user-1', 'UserId': 'AIDAAAAAA1111AAAAAA1111', 'Arn':
+                             'arn:aws:iam::123456789012:user/dummy-user-1', 'CreateDate': datetime.datetime(2024, 8, 7, 15, 8, 7, tzinfo=tzutc())}
 
+                             {'Path': '/', 'UserName': 'dummy-user-2', 'UserId': 'AIDBBBBBB2222BBBBBB2222', 'Arn':
+                             'arn:aws:iam::123456789012:user/dummy-user-2', 'CreateDate': datetime.datetime(2023, 7, 18, 20, 29, 27, tzinfo=tzutc())}
+
+                             {'Path': '/', 'UserName': 'dummy-user-3', 'UserId': 'AIDCCCCCC3333CCCCCC3333', 'Arn':
+                             'arn:aws:iam::123456789012:user/dummy-user-3', 'CreateDate': datetime.datetime(2024, 7, 15, 19, 39, 41, tzinfo=tzutc())}
+
+                             {'Path': '/', 'UserName': 'dummy-user-4', 'UserId': 'AIDDDDDDD4444DDDDDD4444', 'Arn':
+                             'arn:aws:iam::123456789012:user/dummy-user-4', 'CreateDate': datetime.datetime(2024, 8, 2, 19, 28, 31, tzinfo=tzutc())}
+
+                             {'Path': '/', 'UserName': 'dummy-user-5', 'UserId': 'AIDEEEEE5555EEEEE5555', 'Arn':
+                             'arn:aws:iam::123456789012:user/dummy-user-5', 'CreateDate': datetime.datetime(2023, 8, 29, 20, 56, 37, tzinfo=tzutc())}
+[08/12/24 14:57:08] INFO     ToolkitTask 12345abcd67890efghijk1112131415
+                             Output: Here are all your IAM users:
+
+                             1. **Username:** dummy-user-1
+                                - **UserId:** AIDAAAAAA1111AAAAAA1111
+                                - **Arn:** arn:aws:iam::123456789012:user/dummy-user-1
+                                - **CreateDate:** 2024-08-07
+
+                             2. **Username:** dummy-user-2
+                                - **UserId:** AIDBBBBBB2222BBBBBB2222
+                                - **Arn:** arn:aws:iam::123456789012:user/dummy-user-2
+                                - **CreateDate:** 2023-07-18
+
+                             3. **Username:** dummy-user-3
+                                - **UserId:** AIDCCCCCC3333CCCCCC3333
+                                - **Arn:** arn:aws:iam::123456789012:user/dummy-user-3
+                                - **CreateDate:** 2024-07-15
+
+                             4. **Username:** dummy-user-4
+                                - **UserId:** AIDDDDDDD4444DDDDDD4444
+                                - **Arn:** arn:aws:iam::123456789012:user/dummy-user-4
+                                - **CreateDate:** 2024-08-02
+
+                             5. **Username:** dummy-user-5
+                                - **UserId:** AIDEEEEE5555EEEEE5555
+                                - **Arn:** arn:aws:iam::123456789012:user/dummy-user-5
+                                - **CreateDate:** 2023-08-29
 ```
diff --git a/docs/griptape-tools/official-tools/aws-s3-tool.md b/docs/griptape-tools/official-tools/aws-s3-tool.md
index 9594861a9..c6a972d76 100644
--- a/docs/griptape-tools/official-tools/aws-s3-tool.md
+++ b/docs/griptape-tools/official-tools/aws-s3-tool.md
@@ -6,45 +6,36 @@ This tool enables LLMs to make AWS S3 API requests.
 --8<-- "docs/griptape-tools/official-tools/src/aws_s3_tool_1.py"
 ```
 ```
-[09/11/23 16:49:35] INFO     Task 8bf7538e217a4b5a8472829f5eee75b9              
-                             Input: List all my S3 buckets.                     
-[09/11/23 16:49:41] INFO     Subtask 9fc44f5c8e73447ba737283cb2ef7f5d           
-                             Thought: To list all S3 buckets, I can use the     
-                             "list_s3_buckets" activity of the "AwsS3Tool"    
-                             tool. This activity doesn't require any input.     
-                                                                                
-                             Action: {"name": "AwsS3Tool",    
-                             "path": "list_s3_buckets"}                     
-[09/11/23 16:49:42] INFO     Subtask 9fc44f5c8e73447ba737283cb2ef7f5d           
-                             Response: Output of                             
-                             "AwsS3Tool.list_s3_buckets" was stored in memory 
-                             with memory_name "TaskMemory" and              
-                             artifact_namespace                                 
-                             "f2592085fd4a430286a46770ea508cc9"                 
-[09/11/23 16:49:50] INFO     Subtask 0e9bb639a432431a92ef40a8c085ca0f           
-                             Thought: The output of the "list_s3_buckets"       
-                             activity is stored in memory. I can retrieve this  
-                             information using the "summarize" activity of the  
-                             "TaskMemory" tool.
-                             Action: {"name": "TaskMemoryTool", "path":   
-                             "summarize", "input": {"values": {"memory_name":   
-                             "TaskMemory", "artifact_namespace":                
-                             "f2592085fd4a430286a46770ea508cc9"}}}                                       
-[09/11/23 16:49:52] INFO     Subtask 0e9bb639a432431a92ef40a8c085ca0f           
-                             Response: The text consists of multiple         
-                             dictionaries, each containing a 'Name' and         
-                             'CreationDate' key-value pair. The 'Name'          
-                             represents the name of a resource or bucket, while 
-                             the 'CreationDate' represents the date and time    
-                             when the resource or bucket was created.           
-[09/11/23 16:50:03] INFO     Task 8bf7538e217a4b5a8472829f5eee75b9              
-                             Output: The names of your S3 buckets are as        
-                             follows:                                           
-                             1. Bucket Name: 'example-bucket-1', Creation Date: 
-                             '2022-01-01T00:00:00Z'                             
-                             2. Bucket Name: 'example-bucket-2', Creation Date: 
-                             '2022-01-02T00:00:00Z'                             
-                             3. Bucket Name: 'example-bucket-3', Creation Date: 
-                             '2022-01-03T00:00:00Z'                             
-                             Please note that the creation dates are in UTC.  
+[08/12/24 14:51:36] INFO     ToolkitTask bfc329ebc7d34497b429ab0d18ff7e7b
+                             Input: List all my S3 buckets.
+[08/12/24 14:51:37] INFO     Subtask dfd07f9e204c4a3d8f55ca3eb9d37ec5
+                             Actions: [
+                               {
+                                 "tag": "call_pZQ05Zmm6lSbEcvPWt4XEDj6",
+                                 "name": "AwsS3Client",
+                                 "path": "list_s3_buckets",
+                                 "input": {
+                                   "values": {}
+                                 }
+                               }
+                             ]
+                    INFO     Subtask dfd07f9e204c4a3d8f55ca3eb9d37ec5
+                             Response: {'Name': 'dummy-bucket-1', 'CreationDate': datetime.datetime(2023, 9, 14, 15, 41, 46,
+                             tzinfo=tzutc())}
+
+                             {'Name': 'dummy-bucket-2', 'CreationDate': datetime.datetime(2023, 9, 14, 15, 40, 33, tzinfo=tzutc())}
+
+                             {'Name': 'dummy-bucket-3', 'CreationDate': datetime.datetime(2023, 6, 23, 20, 19, 53, tzinfo=tzutc())}
+
+                             {'Name': 'dummy-bucket-4', 'CreationDate': datetime.datetime(2023, 8, 19, 17, 17, 13, tzinfo=tzutc())}
+
+                             {'Name': 'dummy-bucket-5', 'CreationDate': datetime.datetime(2024, 2, 15, 23, 17, 21, tzinfo=tzutc())}
+[08/12/24 14:51:43] INFO     ToolkitTask bfc329ebc7d34497b429ab0d18ff7e7b
+                             Output: Here are all your S3 buckets:
+
+                             1. dummy-bucket-1 (Created on 2023-09-14)
+                             2. dummy-bucket-2 (Created on 2023-09-14)
+                             3. dummy-bucket-3 (Created on 2023-06-23)
+                             4. dummy-bucket-4 (Created on 2023-08-19)
+                             5. dummy-bucket-5 (Created on 2024-02-15)
 ```
diff --git a/docs/griptape-tools/official-tools/computer-tool.md b/docs/griptape-tools/official-tools/computer-tool.md
index 758dd8714..f21d4bda9 100644
--- a/docs/griptape-tools/official-tools/computer-tool.md
+++ b/docs/griptape-tools/official-tools/computer-tool.md
@@ -8,80 +8,40 @@ You can specify a local working directory and environment variables during tool
 --8<-- "docs/griptape-tools/official-tools/src/computer_tool_1.py"
 ```
 ```
-[09/11/23 16:24:15] INFO     Task d08009ee983c4286ba10f83bcf3080e6              
-                             Input: Run this shell command for me: touch        
-                             my_new_file.txt                                    
-[09/11/23 16:24:21] INFO     Subtask 1ec0f9ea528e44b89eb9d41da0e00856           
-                             Thought: The user wants to create a new file named 
-                             "my_new_file.txt". I can do this by executing the  
-                             shell command "touch my_new_file.txt" using the    
-                             Computer tool with the execute_command activity.   
-                                                                                
-                             Action: {"name": "Computer",       
-                             "path": "execute_command", "input": {"values": 
-                             {"command": "touch my_new_file.txt"}}}             
-[09/11/23 16:24:22] INFO     Subtask 1ec0f9ea528e44b89eb9d41da0e00856           
-                             Response: Output of "Computer.execute_command"  
-                             was stored in memory with memory_name              
-                             "TaskMemory" and artifact_namespace            
-                             "54ffbc84a37a497480cab6ab4f904e7e"                 
-[09/11/23 16:24:28] INFO     Subtask f3e1b1d09b4c46babda27342680aa770           
-                             Thought: The command has been executed and the     
-                             output is stored in memory. However, the "touch"   
-                             command does not produce any output when it        
-                             successfully creates a file. To confirm that the   
-                             file was created, I can list the files in the      
-                             current directory using the "ls" command.          
-                                                                                
-                             Action: {"name": "Computer",       
-                             "path": "execute_command", "input": {"values": 
-                             {"command": "ls"}}}                                
-[09/11/23 16:24:29] INFO     Subtask f3e1b1d09b4c46babda27342680aa770           
-                             Response: Output of "Computer.execute_command"  
-                             was stored in memory with memory_name              
-                             "TaskMemory" and artifact_namespace            
-                             "82bc4937564e4901b7fc51fced45b643"                 
-[09/11/23 16:24:40] INFO     Subtask 36f0bbfdd7974e6cb52766ba21dc64e0           
-                             Thought: The output of the "ls" command is stored  
-                             in memory. I need to retrieve this output to check 
-                             if "my_new_file.txt" is listed, which would confirm
-                             that the file was created successfully.
-                             Action: {"name": "TaskMemoryTool", "path":   
-                             "query", "input": {"values": {"memory_name":   
-                             "TaskMemory", "artifact_namespace":                
-                             "82bc4937564e4901b7fc51fced45b643", "query": "Is   
-                             my_new_file.txt in the list of files?"}}}                    
-[09/11/23 16:24:41] INFO     Subtask 36f0bbfdd7974e6cb52766ba21dc64e0           
-                             Response: Yes.                                  
-[09/11/23 16:24:42] INFO     Task d08009ee983c4286ba10f83bcf3080e6              
-                             Output: The file "my_new_file.txt" has been        
-                             successfully created.                              
-                    INFO     Task d08009ee983c4286ba10f83bcf3080e6              
-                             Input: Run this shell command for me: echo 'This is
-                             the content of the file.' > my_new_file.txt        
-[09/11/23 16:24:53] INFO     Subtask a0a3fb162d6d4f3398a98c6d3604a491           
-                             Thought: The user wants to write the text 'This is 
-                             the content of the file.' into the file            
-                             'my_new_file.txt'. I can achieve this by using the 
-                             'execute_command' activity of the 'Computer' tool. 
-                                                                                
-                             Action: {"name": "Computer",       
-                             "path": "execute_command", "input": {"values": 
-                             {"command": "echo 'This is the content of the      
-                             file.' > my_new_file.txt"}}}                       
-                    INFO     Subtask a0a3fb162d6d4f3398a98c6d3604a491           
-                             Response: Output of "Computer.execute_command"  
-                             was stored in memory with memory_name              
-                             "TaskMemory" and artifact_namespace            
-                             "ec20f2e7ec674e0286c8d1f05d528957"                 
-[09/11/23 16:25:00] INFO     Task d08009ee983c4286ba10f83bcf3080e6              
-                             Output: The text 'This is the content of the file.'
-                             has been successfully written into                 
-                             'my_new_file.txt'.                                 
-                    INFO     Task d08009ee983c4286ba10f83bcf3080e6              
-                             Input: Run this shell command for me: cat          
-                             my_new_file.txt                                    
-[09/11/23 16:25:10] INFO     Task d08009ee983c4286ba10f83bcf3080e6              
-                             Output: The content of the file 'my_new_file.txt'  
-                             is: 'This is the content of the file.' 
+❮ poetry run python src/docs/task-memory.py
+[08/12/24 15:13:56] INFO     ToolkitTask 203ee958d1934811afe0bb86fb246e86
+                             Input: Make 2 files and then list the files in the current directory
+[08/12/24 15:13:58] INFO     Subtask eb4e843b6f37498f9f0e85ada68114ac
+                             Actions: [
+                               {
+                                 "tag": "call_S17vPQsMCqWY1Lt5x8NtDnTK",
+                                 "name": "Computer",
+                                 "path": "execute_command",
+                                 "input": {
+                                   "values": {
+                                     "command": "touch file1.txt file2.txt"
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask eb4e843b6f37498f9f0e85ada68114ac
+                             Response: Tool returned an empty value
+[08/12/24 15:13:59] INFO     Subtask 032770e7697d44f6a0c8559bfea60420
+                             Actions: [
+                               {
+                                 "tag": "call_n61SVDYUGWTt681BaDSaHgt1",
+                                 "name": "Computer",
+                                 "path": "execute_command",
+                                 "input": {
+                                   "values": {
+                                     "command": "ls"
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask 032770e7697d44f6a0c8559bfea60420
+                             Response: file1.txt
+                             file2.txt
+[08/12/24 15:14:00] INFO     ToolkitTask 203ee958d1934811afe0bb86fb246e86
+                             Output: file1.txt, file2.txt
 ```  
diff --git a/docs/griptape-tools/official-tools/extraction-tool.md b/docs/griptape-tools/official-tools/extraction-tool.md
new file mode 100644
index 000000000..5b0486ffd
--- /dev/null
+++ b/docs/griptape-tools/official-tools/extraction-tool.md
@@ -0,0 +1,53 @@
+The [ExractionTool](../../reference/griptape/tools/extraction/tool.md) enables LLMs to extract structured text from unstructured data.
+
+```python
+--8<-- "docs/griptape-tools/official-tools/src/extraction_tool_1.py"
+```
+```
+[08/12/24 15:58:03] INFO     ToolkitTask 43b3d209a83c470d8371b7ef4af175b4
+                             Input: Load https://griptape.ai and extract key info
+[08/12/24 15:58:05] INFO     Subtask 6a9a63802faf4717bab24bbbea2cb49b
+                             Actions: [
+                               {
+                                 "tag": "call_SgrmWdXaYTQ1Cz9iB0iIZSYD",
+                                 "name": "WebScraperTool",
+                                 "path": "get_content",
+                                 "input": {
+                                   "values": {
+                                     "url": "https://griptape.ai"
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 15:58:06] INFO     Subtask 6a9a63802faf4717bab24bbbea2cb49b
+                             Response: Output of "WebScraperTool.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "bf1c865b82554c9e896cb514bb86844c"
+[08/12/24 15:58:07] INFO     Subtask c06388d6079541d5aaff25c30e322c51
+                             Actions: [
+                               {
+                                 "tag": "call_o3MrpM01OnhCfpxsMe85tpDF",
+                                 "name": "ExtractionTool",
+                                 "path": "extract_json",
+                                 "input": {
+                                   "values": {
+                                     "data": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "bf1c865b82554c9e896cb514bb86844c"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 15:58:11] INFO     Subtask c06388d6079541d5aaff25c30e322c51
+                             Response: {"company_name": "Griptape", "industry": "AI Applications", "product_features": ["Turn any developer into an AI developer.", "Build
+                             your business logic using predictable, programmable python.", "Off-Prompt\u2122 for better security, performance, and lower costs.", "Deploy and
+                             run the ETL, RAG, and structures you developed.", "Simple API abstractions.", "Skip the infrastructure management.", "Scale seamlessly with
+                             workload requirements.", "Clean and clear abstractions for building Gen AI Agents, Systems of Agents, Pipelines, Workflows, and RAG
+                             implementations.", "Build ETL pipelines to prep data for secure LLM access.", "Compose retrieval patterns for fast, accurate, detailed
+                             information.", "Write agents, pipelines, and workflows to integrate business logic.", "Automated Data Prep (ETL): Connect any data source,
+                             extract, prep/transform, and load into a vector database index.", "Retrieval as a Service (RAG): Generate answers, summaries, and details from
+                             your own data with ready-made or custom retrieval patterns.", "Structure Runtime (RUN): Build AI agents, pipelines, and workflows for real-time
+                             interfaces, transactional processes, and batch workloads."]}
+[08/12/24 15:58:14] INFO     ToolkitTask 43b3d209a83c470d8371b7ef4af175b4
+                             Output: Extracted key information from Griptape's website.
+```
diff --git a/docs/griptape-tools/official-tools/file-manager-tool.md b/docs/griptape-tools/official-tools/file-manager-tool.md
index 5f27b8da5..2c27c86ea 100644
--- a/docs/griptape-tools/official-tools/file-manager-tool.md
+++ b/docs/griptape-tools/official-tools/file-manager-tool.md
@@ -10,11 +10,11 @@ This tool enables LLMs to save and load files.
                              Input: Can you get me the sample1.txt file?        
 [09/12/23 12:08:04] INFO     Subtask ddcf48d970ce4edbbc22a46b2f83ec4f           
                              Thought: The user wants the content of the file    
-                             named "sample1.txt". I can use the FileManager tool
+                             named "sample1.txt". I can use the FileManagerTool tool
                              with the activity "load_files_from_disk" to load   
                              the file from the disk.                            
                                                                                 
-                             Action: {"name": "FileManager",    
+                             Action: {"name": "FileManagerTool",    
                              "path": "load_files_from_disk", "input":       
                              {"values": {"paths": ["sample1.txt"]}}}            
                     INFO     Subtask ddcf48d970ce4edbbc22a46b2f83ec4f           
diff --git a/docs/griptape-tools/official-tools/prompt-summary-tool.md b/docs/griptape-tools/official-tools/prompt-summary-tool.md
new file mode 100644
index 000000000..7afecf57b
--- /dev/null
+++ b/docs/griptape-tools/official-tools/prompt-summary-tool.md
@@ -0,0 +1,105 @@
+The [PromptSummaryTool](../../reference/griptape/tools/prompt_summary/tool.md) enables LLMs summarize text data. 
+
+```python
+--8<-- "docs/griptape-tools/official-tools/src/prompt_summary_tool_1.py"
+```
+```
+[08/12/24 15:54:46] INFO     ToolkitTask 8be73eb542c44418ba880399044c017a
+                             Input: How can I build Neovim from source for MacOS according to this https://github.com/neovim/neovim/blob/master/BUILD.md
+[08/12/24 15:54:47] INFO     Subtask cd362a149e1d400997be93c1342d1663
+                             Actions: [
+                               {
+                                 "tag": "call_DGsOHC4AVxhV7RPVA7q3rATX",
+                                 "name": "WebScraperTool",
+                                 "path": "get_content",
+                                 "input": {
+                                   "values": {
+                                     "url": "https://github.com/neovim/neovim/blob/master/BUILD.md"
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 15:54:49] INFO     Subtask cd362a149e1d400997be93c1342d1663
+                             Response: Output of "WebScraperTool.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "990b689c57de4581b8715963c0aecfe3"
+[08/12/24 15:54:50] INFO     Subtask 919a4a9eb900439ab9bfbf6e921feba3
+                             Actions: [
+                               {
+                                 "tag": "call_DK3a4MYoElJbaCrUJekBReIc",
+                                 "name": "PromptSummaryTool",
+                                 "path": "summarize",
+                                 "input": {
+                                   "values": {
+                                     "summary": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "990b689c57de4581b8715963c0aecfe3"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 15:54:56] INFO     Subtask 919a4a9eb900439ab9bfbf6e921feba3
+                             Response: The text provides detailed instructions for building and installing Neovim from source on various operating systems, including Linux,
+                             BSD, Windows, and macOS. Key points include:
+
+                             1. **Pre-requisites**: Ensure all build dependencies are installed.
+                             2. **Cloning and Building**:
+                                - Clone the Neovim repository.
+                                - Use `make` with appropriate `CMAKE_BUILD_TYPE` (Release, Debug, RelWithDebInfo).
+                                - For stable releases, checkout the stable branch.
+                                - Use `gmake` on BSD and follow specific instructions for Windows using MSVC.
+                             3. **Installation**:
+                                - Default install location is `/usr/local`.
+                                - On Debian/Ubuntu, build a DEB package for clean installation.
+                                - Custom install locations can be set using `CMAKE_INSTALL_PREFIX`.
+                             4. **Dependencies**:
+                                - Third-party dependencies are automatically downloaded.
+                                - Use `Ninja` and `ccache` for faster builds.
+                             5. **Platform-Specific Instructions**:
+                                - Detailed steps for building on Windows using Visual Studio.
+                                - Instructions for building on macOS using Homebrew or MacPorts.
+                                - Specific commands for building on NixOS, Cygwin, and MSYS2.
+                             6. **Debugging and Development**:
+                                - Use `RelWithDebInfo` for optimized builds with debug info.
+                                - Instructions for using debuggers and handling build cache.
+                             7. **Localization**:
+                                - Commands for checking and updating translations.
+
+                             The text also includes troubleshooting tips and links to additional resources for further guidance.
+[08/12/24 15:55:01] INFO     ToolkitTask 8be73eb542c44418ba880399044c017a
+                             Output: To build Neovim from source on macOS, follow these steps:
+
+                             1. **Install Dependencies**:
+                                Ensure you have the necessary build dependencies installed. You can use Homebrew to install them:
+                                ```sh
+                                brew install ninja libtool automake cmake pkg-config gettext curl
+                                ```
+
+                             2. **Clone the Neovim Repository**:
+                                Clone the Neovim repository from GitHub:
+                                ```sh
+                                git clone https://github.com/neovim/neovim.git
+                                cd neovim
+                                ```
+
+                             3. **Checkout the Stable Branch (Optional)**:
+                                If you want to build the stable release, checkout the stable branch:
+                                ```sh
+                                git checkout stable
+                                ```
+
+                             4. **Build Neovim**:
+                                Use `make` to build Neovim. You can specify the build type (Release, Debug, RelWithDebInfo):
+                                ```sh
+                                make CMAKE_BUILD_TYPE=Release
+                                ```
+
+                             5. **Install Neovim**:
+                                After building, install Neovim. The default install location is `/usr/local`:
+                                ```sh
+                                sudo make install
+                                ```
+
+                             By following these steps, you should be able to build and install Neovim from source on macOS. For more detailed instructions and
+                             troubleshooting tips, refer to the [BUILD.md](https://github.com/neovim/neovim/blob/master/BUILD.md) file in the Neovim repository.
+```
diff --git a/docs/griptape-tools/official-tools/query-tool.md b/docs/griptape-tools/official-tools/query-tool.md
new file mode 100644
index 000000000..4a4f2bf33
--- /dev/null
+++ b/docs/griptape-tools/official-tools/query-tool.md
@@ -0,0 +1,85 @@
+The [QueryTool](../../reference/griptape/tools/query/tool.md) enables Agents to query unstructured data for specific information.
+
+```python
+--8<-- "docs/griptape-tools/official-tools/src/query_tool_1.py"
+```
+```
+[08/12/24 15:49:23] INFO     ToolkitTask a88abda2e5324bdf81a3e2b99c26b9df
+                             Input: Tell me about the architecture as described here: https://neovim.io/doc/user/vim_diff.html
+[08/12/24 15:49:24] INFO     Subtask 3dc9910bcac44c718b3aedd6222e372a
+                             Actions: [
+                               {
+                                 "tag": "call_VY4r5YRc2QDjtBvn89z5PH8E",
+                                 "name": "WebScraperTool",
+                                 "path": "get_content",
+                                 "input": {
+                                   "values": {
+                                     "url": "https://neovim.io/doc/user/vim_diff.html"
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 15:49:25] INFO     Subtask 3dc9910bcac44c718b3aedd6222e372a
+                             Response: Output of "WebScraperTool.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "bec6deeac5f84e369c41210e67905415"
+[08/12/24 15:49:26] INFO     Subtask f41d2189ecff4458acb8e6dadb5b13aa
+                             Actions: [
+                               {
+                                 "tag": "call_GtBICZi6oIeL85Aj7q5szul9",
+                                 "name": "QueryTool",
+                                 "path": "query",
+                                 "input": {
+                                   "values": {
+                                     "query": "architecture",
+                                     "content": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "bec6deeac5f84e369c41210e67905415"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 15:49:33] INFO     Subtask f41d2189ecff4458acb8e6dadb5b13aa
+                             Response: The architecture of Neovim (Nvim) is designed to improve stability, performance, and extensibility. Here are some key points about
+                             Nvim's architecture:
+
+                             1. **Decoupled UI**: The Nvim UI is decoupled from the core editor. All UIs, including the built-in TUI (terminal user interface), are plugins
+                             that connect to a Nvim server. Multiple Nvim UI clients can connect to the same Nvim editor server.
+
+                             2. **External Plugins**: External plugins run in separate processes, which improves stability and allows those plugins to work without blocking
+                             the editor. Even "legacy" Python and Ruby plugins, which use the old Vim interfaces, run out-of-process, so they cannot crash Nvim.
+
+                             3. **Libuv**: Platform and I/O facilities are built upon libuv. Nvim benefits from libuv features and bug fixes, and other projects benefit from
+                             improvements to libuv by Nvim developers.
+
+                             4. **Robust API**: Nvim has a robust API, which is used instead of exposing internal test functions like Vim's `test_autochdir()`,
+                             `test_settime()`, etc.
+
+                             5. **Feature Inclusion**: Nvim always includes all features, in contrast to Vim, which ships various combinations of 100+ optional features.
+                             This reduces the surface area for bugs and removes a common source of confusion and friction for users.
+
+                             6. **External Plugins and Extensions**: Nvim avoids features that cannot be provided on all platforms, delegating those to external
+                             plugins/extensions.
+
+                             These architectural decisions make Nvim more stable, extensible, and user-friendly compared to traditional Vim.
+[08/12/24 15:49:37] INFO     ToolkitTask a88abda2e5324bdf81a3e2b99c26b9df
+                             Output: The architecture of Neovim (Nvim) is designed to enhance stability, performance, and extensibility. Here are the key points:
+
+                             1. **Decoupled UI**: The user interface (UI) is separated from the core editor. All UIs, including the built-in terminal user interface (TUI),
+                             are plugins that connect to a Nvim server. This allows multiple UI clients to connect to the same Nvim editor server.
+
+                             2. **External Plugins**: Plugins run in separate processes, which improves stability and prevents them from blocking the editor. Even older
+                             Python and Ruby plugins run out-of-process, ensuring they cannot crash Nvim.
+
+                             3. **Libuv**: Nvim's platform and I/O facilities are built on libuv, benefiting from its features and bug fixes. Improvements made by Nvim
+                             developers to libuv also benefit other projects.
+
+                             4. **Robust API**: Nvim provides a robust API, avoiding the need to expose internal test functions like Vim does.
+
+                             5. **Feature Inclusion**: Unlike Vim, which ships with various combinations of optional features, Nvim includes all features by default. This
+                             reduces bugs and user confusion.
+
+                             6. **External Plugins and Extensions**: Nvim delegates features that cannot be provided on all platforms to external plugins/extensions.
+
+                             These architectural choices make Nvim more stable, extensible, and user-friendly compared to traditional Vim.
+```
diff --git a/docs/griptape-tools/official-tools/sql-tool.md b/docs/griptape-tools/official-tools/sql-tool.md
index b20327013..ed8aae2a0 100644
--- a/docs/griptape-tools/official-tools/sql-tool.md
+++ b/docs/griptape-tools/official-tools/sql-tool.md
@@ -6,38 +6,51 @@ This tool enables LLMs to execute SQL statements via [SQLAlchemy](https://www.sq
 --8<-- "docs/griptape-tools/official-tools/src/sql_tool_1.py"
 ```
 ```
-[09/11/23 17:02:55] INFO     Task d8331f8705b64b4b9d9a88137ed73f3f              
-                             Input: SELECT * FROM people;                       
-[09/11/23 17:03:02] INFO     Subtask 46c2f8926ce9469e9ca6b1b3364e3e41           
-                             Thought: The user wants to retrieve all records    
-                             from the 'people' table. I can use the SqlTool   
-                             tool to execute this query.                        
-                                                                                
-                             Action: {"name": "SqlTool",      
-                             "path": "execute_query", "input": {"values":   
-                             {"sql_query": "SELECT * FROM people;"}}}           
-[09/11/23 17:03:03] INFO     Subtask 46c2f8926ce9469e9ca6b1b3364e3e41           
-                             Response: Output of "SqlTool.execute_query"   
-                             was stored in memory with memory_name              
-                             "TaskMemory" and artifact_namespace            
-                             "217715ba3e444e4985bee223df5716a8"                 
-[09/11/23 17:03:11] INFO     Subtask e51f05449647482caa3051378ab5cb8c           
-                             Thought: The output of the SQL query has been      
-                             stored in memory. I can retrieve this data using   
-                             the TaskMemory's 'summarize' activity.
-                             Action: {"name": "TaskMemoryTool", "path":   
-                             "summarize", "input": {"values": {"memory_name":   
-                             "TaskMemory", "artifact_namespace":                
-                             "217715ba3e444e4985bee223df5716a8"}}}                  
-[09/11/23 17:03:12] INFO     Subtask e51f05449647482caa3051378ab5cb8c           
-                             Response: The text includes a list of employees 
-                             with their respective IDs, names, positions. There 
-                             are two employees named Tanya Cooley who are both  
-                             managers, and two employees named John Doe who are 
-                             both coders.                                       
-[09/11/23 17:03:17] INFO     Task d8331f8705b64b4b9d9a88137ed73f3f              
-                             Output: The 'people' table contains records of     
-                             several employees. Notably, there are two employees
-                             named Tanya Cooley who are both managers, and two  
-                             employees named John Doe who are both coders. 
+[08/12/24 14:59:31] INFO     ToolkitTask e302f7315d1a4f939e0125103ff4f09f
+                             Input: SELECT * FROM people;
+[08/12/24 14:59:34] INFO     Subtask 809d1a281b85447f90706d431b77b845
+                             Actions: [
+                               {
+                                 "tag": "call_dCxHWwPwgmDvDKVd3QeOzyuT",
+                                 "name": "SqlClient",
+                                 "path": "execute_query",
+                                 "input": {
+                                   "values": {
+                                     "sql_query": "SELECT * FROM people"
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 14:59:35] INFO     Subtask 809d1a281b85447f90706d431b77b845
+                             Response: 1,Lee,Andrews,"Engineer, electrical"
+
+                             2,Michael,Woods,"Therapist, art"
+
+                             3,Joshua,Allen,"Therapist, sports"
+
+                             4,Eric,Foster,English as a second language teacher
+
+                             5,John,Daniels,Printmaker
+
+                             6,Matthew,Barton,Podiatrist
+
+                             7,Audrey,Wilson,IT technical support officer
+
+                             8,Leah,Knox,"Social research officer, government"
+
+                             9,David,Macdonald,Public relations account executive
+
+                             10,Erica,Ramos,"Accountant, chartered public finance"
+[08/12/24 14:59:43] INFO     ToolkitTask e302f7315d1a4f939e0125103ff4f09f
+                             Output:
+                             1. Lee Andrews - Engineer, electrical
+                             2. Michael Woods - Therapist, art
+                             3. Joshua Allen - Therapist, sports
+                             4. Eric Foster - English as a second language teacher
+                             5. John Daniels - Printmaker
+                             6. Matthew Barton - Podiatrist
+                             7. Audrey Wilson - IT technical support officer
+                             8. Leah Knox - Social research officer, government
+                             9. David Macdonald - Public relations account executive
+                             10. Erica Ramos - Accountant, chartered public finance
 ```
diff --git a/docs/griptape-tools/official-tools/src/aws_s3_tool_1.py b/docs/griptape-tools/official-tools/src/aws_s3_tool_1.py
index 973a0b881..3d9425534 100644
--- a/docs/griptape-tools/official-tools/src/aws_s3_tool_1.py
+++ b/docs/griptape-tools/official-tools/src/aws_s3_tool_1.py
@@ -1,13 +1,13 @@
 import boto3
 
 from griptape.structures import Agent
-from griptape.tools import AwsS3Tool, TaskMemoryTool
+from griptape.tools import AwsS3Tool
 
 # Initialize the AWS S3 client
 aws_s3_client = AwsS3Tool(session=boto3.Session(), off_prompt=True)
 
 # Create an agent with the AWS S3 client tool
-agent = Agent(tools=[aws_s3_client, TaskMemoryTool(off_prompt=False)])
+agent = Agent(tools=[aws_s3_client])
 
 # Task to list all the AWS S3 buckets
 agent.run("List all my S3 buckets.")
diff --git a/docs/griptape-tools/official-tools/src/computer_tool_1.py b/docs/griptape-tools/official-tools/src/computer_tool_1.py
index b0892d425..725210020 100644
--- a/docs/griptape-tools/official-tools/src/computer_tool_1.py
+++ b/docs/griptape-tools/official-tools/src/computer_tool_1.py
@@ -7,13 +7,4 @@
 # Create an agent with the ComputerTool tool
 agent = Agent(tools=[computer])
 
-# Create a file using the shell command
-filename = "my_new_file.txt"
-agent.run(f"Run this shell command for me: touch {filename}")
-
-# Add content to the file using the shell command
-content = "This is the content of the file."
-agent.run(f"Run this shell command for me: echo '{content}' > {filename}")
-
-# Output the contents of the file using the shell command
-agent.run(f"Run this shell command for me: cat {filename}")
+agent.run("Make 2 files and then list the files in the current directory")
diff --git a/docs/griptape-tools/official-tools/src/extraction_tool_1.py b/docs/griptape-tools/official-tools/src/extraction_tool_1.py
new file mode 100644
index 000000000..80e211f03
--- /dev/null
+++ b/docs/griptape-tools/official-tools/src/extraction_tool_1.py
@@ -0,0 +1,28 @@
+import schema
+
+from griptape.engines import JsonExtractionEngine
+from griptape.structures import Agent
+from griptape.tools import ExtractionTool, WebScraperTool
+
+agent = Agent(
+    input="Load {{ args[0] }} and extract key info",
+    tools=[
+        WebScraperTool(off_prompt=True),
+        ExtractionTool(
+            off_prompt=False,
+            extraction_engine=JsonExtractionEngine(
+                template_schema=schema.Schema(
+                    {
+                        "company_name": str,
+                        "industry": str,
+                        schema.Literal(
+                            "product_features",
+                            description="List of key product features.",
+                        ): list[str],
+                    }
+                ).json_schema("Company Info"),
+            ),
+        ),
+    ],
+)
+agent.run("https://griptape.ai")
diff --git a/docs/griptape-tools/official-tools/src/prompt_summary_tool_1.py b/docs/griptape-tools/official-tools/src/prompt_summary_tool_1.py
new file mode 100644
index 000000000..3b4846439
--- /dev/null
+++ b/docs/griptape-tools/official-tools/src/prompt_summary_tool_1.py
@@ -0,0 +1,8 @@
+from griptape.structures import Agent
+from griptape.tools import PromptSummaryTool, WebScraperTool
+
+agent = Agent(tools=[WebScraperTool(off_prompt=True), PromptSummaryTool()])
+
+agent.run(
+    "How can I build Neovim from source for MacOS according to this https://github.com/neovim/neovim/blob/master/BUILD.md"
+)
diff --git a/docs/griptape-tools/official-tools/src/query_tool_1.py b/docs/griptape-tools/official-tools/src/query_tool_1.py
new file mode 100644
index 000000000..0c612eee9
--- /dev/null
+++ b/docs/griptape-tools/official-tools/src/query_tool_1.py
@@ -0,0 +1,6 @@
+from griptape.structures import Agent
+from griptape.tools import QueryTool, WebScraperTool
+
+agent = Agent(tools=[WebScraperTool(off_prompt=True), QueryTool()])
+
+agent.run("Tell me about the architecture as described here: https://neovim.io/doc/user/vim_diff.html")
diff --git a/docs/griptape-tools/official-tools/src/task_memory_tool_1.py b/docs/griptape-tools/official-tools/src/task_memory_tool_1.py
deleted file mode 100644
index f5c2c487f..000000000
--- a/docs/griptape-tools/official-tools/src/task_memory_tool_1.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from griptape.structures import Agent
-from griptape.tools import TaskMemoryTool, WebScraperTool
-
-Agent(tools=[WebScraperTool(off_prompt=True), TaskMemoryTool(off_prompt=False)])
diff --git a/docs/griptape-tools/official-tools/src/vector_store_tool_1.py b/docs/griptape-tools/official-tools/src/vector_store_tool_1.py
index 57ca7b25b..266398d5e 100644
--- a/docs/griptape-tools/official-tools/src/vector_store_tool_1.py
+++ b/docs/griptape-tools/official-tools/src/vector_store_tool_1.py
@@ -2,7 +2,7 @@
 from griptape.drivers import LocalVectorStoreDriver, OpenAiEmbeddingDriver
 from griptape.loaders import WebLoader
 from griptape.structures import Agent
-from griptape.tools import TaskMemoryTool, VectorStoreTool
+from griptape.tools import PromptSummaryTool, VectorStoreTool
 
 vector_store_driver = LocalVectorStoreDriver(
     embedding_driver=OpenAiEmbeddingDriver(),
@@ -20,6 +20,6 @@
     off_prompt=True,
 )
 
-agent = Agent(tools=[vector_db, TaskMemoryTool(off_prompt=False)])
+agent = Agent(tools=[vector_db, PromptSummaryTool()])
 
 agent.run("what is Griptape?")
diff --git a/docs/griptape-tools/official-tools/src/web_scraper_1.py b/docs/griptape-tools/official-tools/src/web_scraper_1.py
new file mode 100644
index 000000000..0e6f55011
--- /dev/null
+++ b/docs/griptape-tools/official-tools/src/web_scraper_1.py
@@ -0,0 +1,6 @@
+from griptape.structures import Agent
+from griptape.tools import PromptSummaryTool, WebScraperTool
+
+agent = Agent(tools=[WebScraperTool(off_prompt=True), PromptSummaryTool(off_prompt=False)])
+
+agent.run("Based on https://www.griptape.ai/, tell me what griptape is")
diff --git a/docs/griptape-tools/official-tools/src/web_scraper_tool_1.py b/docs/griptape-tools/official-tools/src/web_scraper_tool_1.py
index 7716acde4..0e6f55011 100644
--- a/docs/griptape-tools/official-tools/src/web_scraper_tool_1.py
+++ b/docs/griptape-tools/official-tools/src/web_scraper_tool_1.py
@@ -1,6 +1,6 @@
 from griptape.structures import Agent
-from griptape.tools import TaskMemoryTool, WebScraperTool
+from griptape.tools import PromptSummaryTool, WebScraperTool
 
-agent = Agent(tools=[WebScraperTool(off_prompt=True), TaskMemoryTool(off_prompt=False)])
+agent = Agent(tools=[WebScraperTool(off_prompt=True), PromptSummaryTool(off_prompt=False)])
 
 agent.run("Based on https://www.griptape.ai/, tell me what griptape is")
diff --git a/docs/griptape-tools/official-tools/task-memory-tool.md b/docs/griptape-tools/official-tools/task-memory-tool.md
deleted file mode 100644
index a988c3a64..000000000
--- a/docs/griptape-tools/official-tools/task-memory-tool.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Task Memory Tool Tool
-
-This tool enables LLMs to query and summarize task outputs that are stored in short-term tool memory. This tool uniquely requires the user to set the `off_prompt` property explicitly for usability reasons (Griptape doesn't provide the default `True` value).
-
-```python
---8<-- "docs/griptape-tools/official-tools/src/task_memory_tool_1.py"
-```
diff --git a/docs/griptape-tools/official-tools/web-scraper-tool.md b/docs/griptape-tools/official-tools/web-scraper-tool.md
index 1261d955d..26b83f6e3 100644
--- a/docs/griptape-tools/official-tools/web-scraper-tool.md
+++ b/docs/griptape-tools/official-tools/web-scraper-tool.md
@@ -6,62 +6,92 @@ This tool enables LLMs to scrape web pages for full text, summaries, authors, ti
 --8<-- "docs/griptape-tools/official-tools/src/web_scraper_tool_1.py"
 ```
 ```
-[09/11/23 15:27:39] INFO     Task dd9ad12c5c1e4280a6e20d7c116303ed              
-                             Input: Based on https://www.griptape.ai/, tell me  
-                             what griptape is                                   
-[09/11/23 15:27:47] INFO     Subtask 4b34be74b06a47ba9cb3a4b62aa35907           
-                             Thought: I need to find out what griptape is based 
-                             on the information provided on the website         
-                             https://www.griptape.ai/. I can use the WebScraper 
-                             tool with the get_content activity to load the     
-                             content of the website.                            
-                                                                                
-                             Action: {"name": "WebScraper",     
-                             "path": "get_content", "input": {"values":     
-                             {"url": "https://www.griptape.ai/"}}}              
-[09/11/23 15:27:48] INFO     Subtask 4b34be74b06a47ba9cb3a4b62aa35907           
-                             Response: Output of "WebScraper.get_content" was
-                             stored in memory with memory_name "TaskMemory" 
-                             and artifact_namespace                             
-                             "02da5930b8d74f7ca30aecc3760a3318"                 
-[09/11/23 15:27:59] INFO     Subtask 5b255e3e98aa401295f77532bc779390           
-                             Thought: The content of the website has been stored
-                             in memory. I can use the TaskMemory tool with  
-                             the summarize activity to get a summary of the     
-                             content.
-                             Action: {"name": "TaskMemoryTool", "path":   
-                             "summarize", "input": {"values": {"memory_name":   
-                             "TaskMemory", "artifact_namespace":                
-                             "02da5930b8d74f7ca30aecc3760a3318"}}}                                                    
-[09/11/23 15:28:03] INFO     Subtask 5b255e3e98aa401295f77532bc779390           
-                             Response: Griptape is an open source framework  
-                             that allows developers to build and deploy AI      
-                             applications using large language models (LLMs). It
-                             provides the ability to create conversational and  
-                             event-driven apps that can access and manipulate   
-                             data securely. Griptape enforces structures like   
-                             sequential pipelines and DAG-based workflows for   
-                             predictability, while also allowing for creativity 
-                             by safely prompting LLMs with external APIs and    
-                             data stores. The framework can be used to create AI
-                             systems that operate across both dimensions.       
-                             Griptape Cloud is a managed platform for deploying 
-                             and managing AI apps, and it offers features like  
-                             scheduling and connecting to data stores and APIs. 
-[09/11/23 15:28:12] INFO     Task dd9ad12c5c1e4280a6e20d7c116303ed              
-                             Output: Griptape is an open source framework that  
-                             enables developers to build and deploy AI          
-                             applications using large language models (LLMs). It
-                             allows the creation of conversational and          
-                             event-driven apps that can securely access and     
-                             manipulate data. Griptape enforces structures like 
-                             sequential pipelines and DAG-based workflows for   
-                             predictability, while also allowing for creativity 
-                             by safely prompting LLMs with external APIs and    
-                             data stores. The framework can be used to create AI
-                             systems that operate across both dimensions.       
-                             Additionally, Griptape Cloud is a managed platform 
-                             for deploying and managing AI apps, offering       
-                             features like scheduling and connecting to data    
-                             stores and APIs.  
+[08/12/24 15:32:08] INFO     ToolkitTask b14a4305365f4b17a4dcf235f84397e2
+                             Input: Based on https://www.griptape.ai/, tell me what griptape is
+[08/12/24 15:32:10] INFO     Subtask bf396977ea634eb28f55388d3f828f5d
+                             Actions: [
+                               {
+                                 "tag": "call_ExEzJDZuBfnsa9pZMSr6mtsS",
+                                 "name": "WebScraperTool",
+                                 "path": "get_content",
+                                 "input": {
+                                   "values": {
+                                     "url": "https://www.griptape.ai/"
+                                   }
+                                 }
+                               }
+                             ]
+                    INFO     Subtask bf396977ea634eb28f55388d3f828f5d
+                             Response: Output of "WebScraperTool.get_content" was stored in memory with memory_name "TaskMemory" and artifact_namespace
+                             "a55c85bf1aa944d5b69bbe8d61382179"
+[08/12/24 15:32:11] INFO     Subtask 31852039bd274b71bf46feaf22b68112
+                             Actions: [
+                               {
+                                 "tag": "call_6Dovx2GKE2GLjaYIuwXvBxVn",
+                                 "name": "PromptSummaryTool",
+                                 "path": "summarize",
+                                 "input": {
+                                   "values": {
+                                     "summary": {
+                                       "memory_name": "TaskMemory",
+                                       "artifact_namespace": "a55c85bf1aa944d5b69bbe8d61382179"
+                                     }
+                                   }
+                                 }
+                               }
+                             ]
+[08/12/24 15:32:15] INFO     Subtask 31852039bd274b71bf46feaf22b68112
+                             Response: Griptape offers a comprehensive solution for building, deploying, and scaling AI applications in the cloud. It provides developers
+                             with a framework and cloud services to create retrieval-driven AI-powered applications without needing extensive knowledge in AI or prompt
+                             engineering.
+
+                             **Griptape Framework:**
+                             - Enables developers to build AI applications using Python.
+                             - Offers better security, performance, and cost-efficiency with Off-Prompt™ technology.
+                             - Facilitates the creation of Gen AI Agents, Systems of Agents, Pipelines, Workflows, and RAG implementations.
+
+                             **Griptape Cloud:**
+                             - Simplifies deployment and execution of ETL, RAG, and other structures.
+                             - Provides API abstractions and eliminates the need for infrastructure management.
+                             - Supports seamless scaling to accommodate growing workloads.
+
+                             **Solutions & Applications:**
+                             - Custom project development.
+                             - Turnkey SaaS offerings for non-tech businesses.
+                             - Ready-made apps and options to offer apps to customers.
+
+                             **Key Features:**
+                             - Automated Data Prep (ETL): Connect, extract, transform, and load data into a vector database index.
+                             - Retrieval as a Service (RAG): Generate answers, summaries, and details from your data using customizable retrieval patterns.
+                             - Structure Runtime (RUN): Build and integrate AI agents, pipelines, and workflows into client applications.
+[08/12/24 15:32:21] INFO     ToolkitTask b14a4305365f4b17a4dcf235f84397e2
+                             Output: Griptape is a comprehensive solution designed to facilitate the building, deploying, and scaling of AI applications in the cloud. It
+                             provides developers with a framework and cloud services that simplify the creation of retrieval-driven AI-powered applications, even for those
+                             without extensive AI or prompt engineering expertise.
+
+                             ### Key Components of Griptape:
+
+                             1. **Griptape Framework:**
+                                - **Development:** Allows developers to build AI applications using Python.
+                                - **Technology:** Utilizes Off-Prompt™ technology for enhanced security, performance, and cost-efficiency.
+                                - **Capabilities:** Supports the creation of Gen AI Agents, Systems of Agents, Pipelines, Workflows, and Retrieval-Augmented Generation (RAG)
+                             implementations.
+
+                             2. **Griptape Cloud:**
+                                - **Deployment:** Simplifies the deployment and execution of ETL (Extract, Transform, Load), RAG, and other structures.
+                                - **API Abstractions:** Provides API abstractions to eliminate the need for infrastructure management.
+                                - **Scalability:** Supports seamless scaling to accommodate growing workloads.
+
+                             ### Solutions & Applications:
+                             - **Custom Projects:** Development of tailored AI solutions.
+                             - **Turnkey SaaS:** Ready-to-use SaaS offerings for non-technical businesses.
+                             - **Ready-made Apps:** Pre-built applications and options to offer apps to customers.
+
+                             ### Key Features:
+                             - **Automated Data Prep (ETL):** Connects, extracts, transforms, and loads data into a vector database index.
+                             - **Retrieval as a Service (RAG):** Generates answers, summaries, and details from data using customizable retrieval patterns.
+                             - **Structure Runtime (RUN):** Facilitates the building and integration of AI agents, pipelines, and workflows into client applications.
+
+                             In summary, Griptape provides a robust platform for developing and managing AI applications, making it accessible for developers and businesses
+                             to leverage AI technology effectively.
 ```
diff --git a/griptape/engines/extraction/csv_extraction_engine.py b/griptape/engines/extraction/csv_extraction_engine.py
index 3184654b1..c9c040f65 100644
--- a/griptape/engines/extraction/csv_extraction_engine.py
+++ b/griptape/engines/extraction/csv_extraction_engine.py
@@ -7,8 +7,7 @@
 from attrs import Factory, define, field
 
 from griptape.artifacts import CsvRowArtifact, ErrorArtifact, ListArtifact, TextArtifact
-from griptape.common import PromptStack
-from griptape.common.prompt_stack.messages.message import Message
+from griptape.common import Message, PromptStack
 from griptape.engines import BaseExtractionEngine
 from griptape.utils import J2
 
@@ -18,25 +17,22 @@
 
 @define
 class CsvExtractionEngine(BaseExtractionEngine):
-    template_generator: J2 = field(default=Factory(lambda: J2("engines/extraction/csv_extraction.j2")), kw_only=True)
+    column_names: list[str] = field(default=Factory(list), kw_only=True)
+    system_template_generator: J2 = field(default=Factory(lambda: J2("engines/extraction/csv/system.j2")), kw_only=True)
+    user_template_generator: J2 = field(default=Factory(lambda: J2("engines/extraction/csv/user.j2")), kw_only=True)
 
     def extract(
         self,
         text: str | ListArtifact,
         *,
         rulesets: Optional[list[Ruleset]] = None,
-        column_names: Optional[list[str]] = None,
         **kwargs,
     ) -> ListArtifact | ErrorArtifact:
-        if column_names is None:
-            column_names = []
         try:
             return ListArtifact(
                 self._extract_rec(
                     cast(list[TextArtifact], text.value) if isinstance(text, ListArtifact) else [TextArtifact(text)],
-                    column_names,
                     [],
-                    rulesets=rulesets,
                 ),
                 item_separator="\n",
             )
@@ -55,39 +51,56 @@ def text_to_csv_rows(self, text: str, column_names: list[str]) -> list[CsvRowArt
     def _extract_rec(
         self,
         artifacts: list[TextArtifact],
-        column_names: list[str],
         rows: list[CsvRowArtifact],
+        *,
         rulesets: Optional[list[Ruleset]] = None,
     ) -> list[CsvRowArtifact]:
         artifacts_text = self.chunk_joiner.join([a.value for a in artifacts])
-        full_text = self.template_generator.render(
-            column_names=column_names,
-            text=artifacts_text,
+        system_prompt = self.system_template_generator.render(
+            column_names=self.column_names,
             rulesets=J2("rulesets/rulesets.j2").render(rulesets=rulesets),
         )
+        user_prompt = self.user_template_generator.render(
+            text=artifacts_text,
+        )
 
-        if self.prompt_driver.tokenizer.count_input_tokens_left(full_text) >= self.min_response_tokens:
+        if (
+            self.prompt_driver.tokenizer.count_input_tokens_left(system_prompt + user_prompt)
+            >= self.min_response_tokens
+        ):
             rows.extend(
                 self.text_to_csv_rows(
-                    self.prompt_driver.run(PromptStack(messages=[Message(full_text, role=Message.USER_ROLE)])).value,
-                    column_names,
+                    self.prompt_driver.run(
+                        PromptStack(
+                            messages=[
+                                Message(system_prompt, role=Message.SYSTEM_ROLE),
+                                Message(user_prompt, role=Message.USER_ROLE),
+                            ]
+                        )
+                    ).value,
+                    self.column_names,
                 ),
             )
 
             return rows
         else:
             chunks = self.chunker.chunk(artifacts_text)
-            partial_text = self.template_generator.render(
-                column_names=column_names,
+            partial_text = self.user_template_generator.render(
                 text=chunks[0].value,
-                rulesets=J2("rulesets/rulesets.j2").render(rulesets=rulesets),
             )
 
             rows.extend(
                 self.text_to_csv_rows(
-                    self.prompt_driver.run(PromptStack(messages=[Message(partial_text, role=Message.USER_ROLE)])).value,
-                    column_names,
+                    self.prompt_driver.run(
+                        PromptStack(
+                            messages=[
+                                Message(system_prompt, role=Message.SYSTEM_ROLE),
+                                Message(partial_text, role=Message.USER_ROLE),
+                            ]
+                        )
+                    ).value,
+                    self.column_names,
                 ),
             )
 
-            return self._extract_rec(chunks[1:], column_names, rows, rulesets=rulesets)
+            return self._extract_rec(chunks[1:], rows, rulesets=rulesets)
diff --git a/griptape/engines/extraction/json_extraction_engine.py b/griptape/engines/extraction/json_extraction_engine.py
index d9c7cd4aa..8f2f4a3fe 100644
--- a/griptape/engines/extraction/json_extraction_engine.py
+++ b/griptape/engines/extraction/json_extraction_engine.py
@@ -1,6 +1,7 @@
 from __future__ import annotations
 
 import json
+import re
 from typing import TYPE_CHECKING, Optional, cast
 
 from attrs import Factory, define, field
@@ -17,25 +18,25 @@
 
 @define
 class JsonExtractionEngine(BaseExtractionEngine):
-    template_generator: J2 = field(default=Factory(lambda: J2("engines/extraction/json_extraction.j2")), kw_only=True)
+    JSON_PATTERN = r"(?s)[^\[]*(\[.*\])"
+
+    template_schema: dict = field(default=Factory(dict), kw_only=True)
+    system_template_generator: J2 = field(
+        default=Factory(lambda: J2("engines/extraction/json/system.j2")), kw_only=True
+    )
+    user_template_generator: J2 = field(default=Factory(lambda: J2("engines/extraction/json/user.j2")), kw_only=True)
 
     def extract(
         self,
         text: str | ListArtifact,
         *,
         rulesets: Optional[list[Ruleset]] = None,
-        template_schema: Optional[dict | list[dict]] = None,
         **kwargs,
     ) -> ListArtifact | ErrorArtifact:
-        if template_schema is None:
-            template_schema = []
         try:
-            json_schema = json.dumps(template_schema)
-
             return ListArtifact(
                 self._extract_rec(
                     cast(list[TextArtifact], text.value) if isinstance(text, ListArtifact) else [TextArtifact(text)],
-                    json_schema,
                     [],
                     rulesets=rulesets,
                 ),
@@ -45,42 +46,64 @@ def extract(
             return ErrorArtifact(f"error extracting JSON: {e}")
 
     def json_to_text_artifacts(self, json_input: str) -> list[TextArtifact]:
-        return [TextArtifact(json.dumps(e)) for e in json.loads(json_input)]
+        json_matches = re.findall(self.JSON_PATTERN, json_input, re.DOTALL)
+
+        if json_matches:
+            return [TextArtifact(json.dumps(e)) for e in json.loads(json_matches[-1])]
+        else:
+            return []
 
     def _extract_rec(
         self,
         artifacts: list[TextArtifact],
-        json_template_schema: str,
         extractions: list[TextArtifact],
+        *,
         rulesets: Optional[list[Ruleset]] = None,
     ) -> list[TextArtifact]:
         artifacts_text = self.chunk_joiner.join([a.value for a in artifacts])
-        full_text = self.template_generator.render(
-            json_template_schema=json_template_schema,
-            text=artifacts_text,
+        system_prompt = self.system_template_generator.render(
+            json_template_schema=json.dumps(self.template_schema),
             rulesets=J2("rulesets/rulesets.j2").render(rulesets=rulesets),
         )
+        user_prompt = self.user_template_generator.render(
+            text=artifacts_text,
+        )
 
-        if self.prompt_driver.tokenizer.count_input_tokens_left(full_text) >= self.min_response_tokens:
+        if (
+            self.prompt_driver.tokenizer.count_input_tokens_left(user_prompt + system_prompt)
+            >= self.min_response_tokens
+        ):
             extractions.extend(
                 self.json_to_text_artifacts(
-                    self.prompt_driver.run(PromptStack(messages=[Message(full_text, role=Message.USER_ROLE)])).value,
+                    self.prompt_driver.run(
+                        PromptStack(
+                            messages=[
+                                Message(system_prompt, role=Message.SYSTEM_ROLE),
+                                Message(user_prompt, role=Message.USER_ROLE),
+                            ]
+                        )
+                    ).value
                 ),
             )
 
             return extractions
         else:
             chunks = self.chunker.chunk(artifacts_text)
-            partial_text = self.template_generator.render(
-                template_schema=json_template_schema,
+            partial_text = self.user_template_generator.render(
                 text=chunks[0].value,
-                rulesets=J2("rulesets/rulesets.j2").render(rulesets=rulesets),
             )
 
             extractions.extend(
                 self.json_to_text_artifacts(
-                    self.prompt_driver.run(PromptStack(messages=[Message(partial_text, role=Message.USER_ROLE)])).value,
+                    self.prompt_driver.run(
+                        PromptStack(
+                            messages=[
+                                Message(system_prompt, role=Message.SYSTEM_ROLE),
+                                Message(partial_text, role=Message.USER_ROLE),
+                            ]
+                        )
+                    ).value,
                 ),
             )
 
-            return self._extract_rec(chunks[1:], json_template_schema, extractions, rulesets=rulesets)
+            return self._extract_rec(chunks[1:], extractions, rulesets=rulesets)
diff --git a/griptape/memory/task/storage/base_artifact_storage.py b/griptape/memory/task/storage/base_artifact_storage.py
index 866df19da..792f479bc 100644
--- a/griptape/memory/task/storage/base_artifact_storage.py
+++ b/griptape/memory/task/storage/base_artifact_storage.py
@@ -1,12 +1,12 @@
 from __future__ import annotations
 
 from abc import ABC, abstractmethod
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING
 
 from attrs import define
 
 if TYPE_CHECKING:
-    from griptape.artifacts import BaseArtifact, InfoArtifact, ListArtifact, TextArtifact
+    from griptape.artifacts import BaseArtifact, ListArtifact
 
 
 @define
@@ -19,9 +19,3 @@ def load_artifacts(self, namespace: str) -> ListArtifact: ...
 
     @abstractmethod
     def can_store(self, artifact: BaseArtifact) -> bool: ...
-
-    @abstractmethod
-    def summarize(self, namespace: str) -> TextArtifact | InfoArtifact: ...
-
-    @abstractmethod
-    def query(self, namespace: str, query: str, metadata: Any = None) -> BaseArtifact: ...
diff --git a/griptape/memory/task/storage/blob_artifact_storage.py b/griptape/memory/task/storage/blob_artifact_storage.py
index 6199dc3a3..3f4309481 100644
--- a/griptape/memory/task/storage/blob_artifact_storage.py
+++ b/griptape/memory/task/storage/blob_artifact_storage.py
@@ -1,10 +1,8 @@
 from __future__ import annotations
 
-from typing import Any
-
 from attrs import define, field
 
-from griptape.artifacts import BaseArtifact, BlobArtifact, InfoArtifact, ListArtifact
+from griptape.artifacts import BaseArtifact, BlobArtifact, ListArtifact
 from griptape.memory.task.storage import BaseArtifactStorage
 
 
@@ -26,9 +24,3 @@ def store_artifact(self, namespace: str, artifact: BaseArtifact) -> None:
 
     def load_artifacts(self, namespace: str) -> ListArtifact:
         return ListArtifact(next((blobs for key, blobs in self.blobs.items() if key == namespace), []))
-
-    def summarize(self, namespace: str) -> InfoArtifact:
-        return InfoArtifact("can't summarize artifacts")
-
-    def query(self, namespace: str, query: str, metadata: Any = None) -> BaseArtifact:
-        return InfoArtifact("can't query artifacts")
diff --git a/griptape/memory/task/storage/text_artifact_storage.py b/griptape/memory/task/storage/text_artifact_storage.py
index 18f2cff80..623c176ea 100644
--- a/griptape/memory/task/storage/text_artifact_storage.py
+++ b/griptape/memory/task/storage/text_artifact_storage.py
@@ -1,32 +1,20 @@
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Any, Optional
+from typing import TYPE_CHECKING
 
-from attrs import Attribute, Factory, define, field
+from attrs import Factory, define, field
 
-from griptape.artifacts import BaseArtifact, InfoArtifact, ListArtifact, TextArtifact
+from griptape.artifacts import BaseArtifact, ListArtifact, TextArtifact
 from griptape.config import config
-from griptape.engines.rag import RagContext, RagEngine
 from griptape.memory.task.storage import BaseArtifactStorage
 
 if TYPE_CHECKING:
     from griptape.drivers import BaseVectorStoreDriver
-    from griptape.engines import BaseSummaryEngine, CsvExtractionEngine, JsonExtractionEngine
 
 
 @define(kw_only=True)
 class TextArtifactStorage(BaseArtifactStorage):
     vector_store_driver: BaseVectorStoreDriver = field(default=Factory(lambda: config.drivers.vector_store))
-    rag_engine: Optional[RagEngine] = field(default=None)
-    retrieval_rag_module_name: Optional[str] = field(default=None)
-    summary_engine: Optional[BaseSummaryEngine] = field(default=None)
-    csv_extraction_engine: Optional[CsvExtractionEngine] = field(default=None)
-    json_extraction_engine: Optional[JsonExtractionEngine] = field(default=None)
-
-    @rag_engine.validator  # pyright: ignore[reportAttributeAccessIssue]
-    def validate_rag_engine(self, _: Attribute, rag_engine: str) -> None:
-        if rag_engine is not None and self.retrieval_rag_module_name is None:
-            raise ValueError("You have to set retrieval_rag_module_name if rag_engine is provided")
 
     def can_store(self, artifact: BaseArtifact) -> bool:
         return isinstance(artifact, TextArtifact)
@@ -39,35 +27,3 @@ def store_artifact(self, namespace: str, artifact: BaseArtifact) -> None:
 
     def load_artifacts(self, namespace: str) -> ListArtifact:
         return self.vector_store_driver.load_artifacts(namespace=namespace)
-
-    def summarize(self, namespace: str) -> TextArtifact:
-        if self.summary_engine is None:
-            raise ValueError("Summary engine is not set.")
-
-        return self.summary_engine.summarize_artifacts(self.load_artifacts(namespace))
-
-    def query(self, namespace: str, query: str, metadata: Any = None) -> BaseArtifact:
-        if self.rag_engine is None:
-            raise ValueError("rag_engine is not set")
-
-        if self.retrieval_rag_module_name is None:
-            raise ValueError("retrieval_rag_module_name is not set")
-
-        outputs = self.rag_engine.process(
-            RagContext(
-                query=query,
-                module_configs={
-                    self.retrieval_rag_module_name: {
-                        "query_params": {
-                            "namespace": namespace,
-                            "metadata": None if metadata is None else str(metadata),
-                        },
-                    },
-                },
-            ),
-        ).outputs
-
-        if len(outputs) > 0:
-            return outputs[0]
-        else:
-            return InfoArtifact("Empty output")
diff --git a/griptape/memory/task/task_memory.py b/griptape/memory/task/task_memory.py
index e2131d1f0..c7f12b233 100644
--- a/griptape/memory/task/task_memory.py
+++ b/griptape/memory/task/task_memory.py
@@ -4,8 +4,9 @@
 
 from attrs import Attribute, Factory, define, field
 
-from griptape.artifacts import BaseArtifact, ErrorArtifact, InfoArtifact, ListArtifact, TextArtifact
+from griptape.artifacts import BaseArtifact, BlobArtifact, ErrorArtifact, InfoArtifact, ListArtifact, TextArtifact
 from griptape.memory.meta import ActionSubtaskMetaEntry
+from griptape.memory.task.storage import BlobArtifactStorage, TextArtifactStorage
 from griptape.mixins import ActivityMixin
 
 if TYPE_CHECKING:
@@ -16,7 +17,15 @@
 @define
 class TaskMemory(ActivityMixin):
     name: str = field(default=Factory(lambda self: self.__class__.__name__, takes_self=True), kw_only=True)
-    artifact_storages: dict[type, BaseArtifactStorage] = field(factory=dict, kw_only=True)
+    artifact_storages: dict[type, BaseArtifactStorage] = field(
+        default=Factory(
+            lambda: {
+                TextArtifact: TextArtifactStorage(),
+                BlobArtifact: BlobArtifactStorage(),
+            }
+        ),
+        kw_only=True,
+    )
     namespace_storage: dict[str, BaseArtifactStorage] = field(factory=dict, kw_only=True)
     namespace_metadata: dict[str, Any] = field(factory=dict, kw_only=True)
 
@@ -123,19 +132,3 @@ def find_input_memory(self, memory_name: str) -> Optional[TaskMemory]:
             return self
         else:
             return None
-
-    def summarize_namespace(self, namespace: str) -> TextArtifact | InfoArtifact:
-        storage = self.namespace_storage.get(namespace)
-
-        if storage:
-            return storage.summarize(namespace)
-        else:
-            return InfoArtifact("Can't find memory content")
-
-    def query_namespace(self, namespace: str, query: str) -> BaseArtifact:
-        storage = self.namespace_storage.get(namespace)
-
-        if storage:
-            return storage.query(namespace=namespace, query=query, metadata=self.namespace_metadata.get(namespace))
-        else:
-            return InfoArtifact("Can't find memory content")
diff --git a/griptape/structures/structure.py b/griptape/structures/structure.py
index eb56c2cf1..a18e9d578 100644
--- a/griptape/structures/structure.py
+++ b/griptape/structures/structure.py
@@ -6,23 +6,14 @@
 
 from attrs import Attribute, Factory, define, field
 
-from griptape.artifacts import BaseArtifact, BlobArtifact, TextArtifact
 from griptape.common import observable
-from griptape.config import config
-from griptape.engines import CsvExtractionEngine, JsonExtractionEngine, PromptSummaryEngine
-from griptape.engines.rag import RagEngine
-from griptape.engines.rag.modules import (
-    PromptResponseRagModule,
-    VectorStoreRetrievalRagModule,
-)
-from griptape.engines.rag.stages import ResponseRagStage, RetrievalRagStage
 from griptape.events import FinishStructureRunEvent, StartStructureRunEvent, event_bus
 from griptape.memory import TaskMemory
 from griptape.memory.meta import MetaMemory
 from griptape.memory.structure import ConversationMemory
-from griptape.memory.task.storage import BlobArtifactStorage, TextArtifactStorage
 
 if TYPE_CHECKING:
+    from griptape.artifacts import BaseArtifact
     from griptape.memory.structure import BaseConversationMemory
     from griptape.rules import Rule, Ruleset
     from griptape.tasks import BaseTask
@@ -38,9 +29,8 @@ class Structure(ABC):
         default=Factory(lambda: ConversationMemory()),
         kw_only=True,
     )
-    rag_engine: RagEngine = field(default=Factory(lambda self: self.default_rag_engine, takes_self=True), kw_only=True)
     task_memory: TaskMemory = field(
-        default=Factory(lambda self: self.default_task_memory, takes_self=True),
+        default=Factory(lambda self: TaskMemory(), takes_self=True),
         kw_only=True,
     )
     meta_memory: MetaMemory = field(default=Factory(lambda: MetaMemory()), kw_only=True)
@@ -94,33 +84,6 @@ def output(self) -> Optional[BaseArtifact]:
     def finished_tasks(self) -> list[BaseTask]:
         return [s for s in self.tasks if s.is_finished()]
 
-    @property
-    def default_rag_engine(self) -> RagEngine:
-        return RagEngine(
-            retrieval_stage=RetrievalRagStage(
-                retrieval_modules=[VectorStoreRetrievalRagModule()],
-            ),
-            response_stage=ResponseRagStage(
-                response_modules=[PromptResponseRagModule(prompt_driver=config.drivers.prompt, rulesets=self.rulesets)],
-            ),
-        )
-
-    @property
-    def default_task_memory(self) -> TaskMemory:
-        return TaskMemory(
-            artifact_storages={
-                TextArtifact: TextArtifactStorage(
-                    rag_engine=self.rag_engine,
-                    retrieval_rag_module_name="VectorStoreRetrievalRagModule",
-                    vector_store_driver=config.drivers.vector_store,
-                    summary_engine=PromptSummaryEngine(prompt_driver=config.drivers.prompt),
-                    csv_extraction_engine=CsvExtractionEngine(prompt_driver=config.drivers.prompt),
-                    json_extraction_engine=JsonExtractionEngine(prompt_driver=config.drivers.prompt),
-                ),
-                BlobArtifact: BlobArtifactStorage(),
-            },
-        )
-
     def is_finished(self) -> bool:
         return all(s.is_finished() for s in self.tasks)
 
diff --git a/griptape/tasks/__init__.py b/griptape/tasks/__init__.py
index 764d1669a..7d08cf858 100644
--- a/griptape/tasks/__init__.py
+++ b/griptape/tasks/__init__.py
@@ -8,8 +8,6 @@
 from .tool_task import ToolTask
 from .rag_task import RagTask
 from .extraction_task import ExtractionTask
-from .csv_extraction_task import CsvExtractionTask
-from .json_extraction_task import JsonExtractionTask
 from .base_image_generation_task import BaseImageGenerationTask
 from .code_execution_task import CodeExecutionTask
 from .prompt_image_generation_task import PromptImageGenerationTask
@@ -33,8 +31,6 @@
     "ToolTask",
     "RagTask",
     "ExtractionTask",
-    "CsvExtractionTask",
-    "JsonExtractionTask",
     "BaseImageGenerationTask",
     "CodeExecutionTask",
     "PromptImageGenerationTask",
diff --git a/griptape/tasks/csv_extraction_task.py b/griptape/tasks/csv_extraction_task.py
deleted file mode 100644
index c252893de..000000000
--- a/griptape/tasks/csv_extraction_task.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from __future__ import annotations
-
-from attrs import Factory, define, field
-
-from griptape.engines import CsvExtractionEngine
-from griptape.tasks import ExtractionTask
-
-
-@define
-class CsvExtractionTask(ExtractionTask):
-    extraction_engine: CsvExtractionEngine = field(default=Factory(lambda: CsvExtractionEngine()), kw_only=True)
diff --git a/griptape/tasks/extraction_task.py b/griptape/tasks/extraction_task.py
index a1c18eff0..c74c3ac49 100644
--- a/griptape/tasks/extraction_task.py
+++ b/griptape/tasks/extraction_task.py
@@ -14,7 +14,7 @@
 @define
 class ExtractionTask(BaseTextInputTask):
     extraction_engine: BaseExtractionEngine = field(kw_only=True)
-    args: dict = field(kw_only=True)
+    args: dict = field(kw_only=True, factory=dict)
 
     def run(self) -> ListArtifact | ErrorArtifact:
         return self.extraction_engine.extract(self.input.to_text(), rulesets=self.all_rulesets, **self.args)
diff --git a/griptape/tasks/json_extraction_task.py b/griptape/tasks/json_extraction_task.py
deleted file mode 100644
index 94db187da..000000000
--- a/griptape/tasks/json_extraction_task.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from __future__ import annotations
-
-from attrs import Factory, define, field
-
-from griptape.engines import JsonExtractionEngine
-from griptape.tasks import ExtractionTask
-
-
-@define
-class JsonExtractionTask(ExtractionTask):
-    extraction_engine: JsonExtractionEngine = field(default=Factory(lambda: JsonExtractionEngine()), kw_only=True)
diff --git a/griptape/templates/engines/extraction/csv/system.j2 b/griptape/templates/engines/extraction/csv/system.j2
new file mode 100644
index 000000000..7c5776257
--- /dev/null
+++ b/griptape/templates/engines/extraction/csv/system.j2
@@ -0,0 +1,7 @@
+Don't add the header row. Don't use markdown formatting for output. Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes.
+Column Names: """{{ column_names }}"""
+
+{% if rulesets %}
+
+{{ rulesets }}
+{% endif %}
diff --git a/griptape/templates/engines/extraction/csv/user.j2 b/griptape/templates/engines/extraction/csv/user.j2
new file mode 100644
index 000000000..0f33dadc3
--- /dev/null
+++ b/griptape/templates/engines/extraction/csv/user.j2
@@ -0,0 +1,4 @@
+Extract information from the Text based on the Column Names and output it as a CSV file.
+Text: """{{ text }}"""
+
+Answer:
diff --git a/griptape/templates/engines/extraction/csv_extraction.j2 b/griptape/templates/engines/extraction/csv_extraction.j2
deleted file mode 100644
index 6f9da346b..000000000
--- a/griptape/templates/engines/extraction/csv_extraction.j2
+++ /dev/null
@@ -1,11 +0,0 @@
-Text: """{{ text }}"""
-
-Column Names: """{{ column_names }}"""
-
-Extract information from the Text based on the Column Names and output it as a CSV file. Don't add the header row. Don't use markdown formatting for output. Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes.
-{% if rulesets %}
-
-{{ rulesets }}
-{% endif %}
-
-Answer:
diff --git a/griptape/templates/engines/extraction/json/system.j2 b/griptape/templates/engines/extraction/json/system.j2
new file mode 100644
index 000000000..987ff19a9
--- /dev/null
+++ b/griptape/templates/engines/extraction/json/system.j2
@@ -0,0 +1,6 @@
+Extraction Template JSON Schema: """{{ json_template_schema }}"""
+
+{% if rulesets %}
+
+{{ rulesets }}
+{% endif %}
diff --git a/griptape/templates/engines/extraction/json_extraction.j2 b/griptape/templates/engines/extraction/json/user.j2
similarity index 56%
rename from griptape/templates/engines/extraction/json_extraction.j2
rename to griptape/templates/engines/extraction/json/user.j2
index 85d95bef9..984977d9a 100644
--- a/griptape/templates/engines/extraction/json_extraction.j2
+++ b/griptape/templates/engines/extraction/json/user.j2
@@ -1,11 +1,4 @@
-Text: """{{ text }}"""
-
-Extraction Template JSON Schema: """{{ json_template_schema }}"""
-
 Extract information from the Text based on the Extraction Template JSON Schema into an array of JSON objects.
-{% if rulesets %}
-
-{{ rulesets }}
-{% endif %}
+Text: """{{ text }}"""
 
 JSON array:
diff --git a/griptape/tools/__init__.py b/griptape/tools/__init__.py
index c33b9f0b0..ce59088f3 100644
--- a/griptape/tools/__init__.py
+++ b/griptape/tools/__init__.py
@@ -9,7 +9,6 @@
 from .file_manager.tool import FileManagerTool
 from .vector_store.tool import VectorStoreTool
 from .date_time.tool import DateTimeTool
-from .task_memory.tool import TaskMemoryTool
 from .base_aws_tool import BaseAwsTool
 from .aws_iam.tool import AwsIamTool
 from .aws_s3.tool import AwsS3Tool
@@ -30,6 +29,9 @@
 from .rag.tool import RagTool
 from .text_to_speech.tool import TextToSpeechTool
 from .audio_transcription.tool import AudioTranscriptionTool
+from .extraction.tool import ExtractionTool
+from .prompt_summary.tool import PromptSummaryTool
+from .query.tool import QueryTool
 
 __all__ = [
     "BaseTool",
@@ -51,7 +53,6 @@
     "FileManagerTool",
     "VectorStoreTool",
     "DateTimeTool",
-    "TaskMemoryTool",
     "ComputerTool",
     "OpenWeatherTool",
     "PromptImageGenerationTool",
@@ -64,4 +65,7 @@
     "RagTool",
     "TextToSpeechTool",
     "AudioTranscriptionTool",
+    "ExtractionTool",
+    "PromptSummaryTool",
+    "QueryTool",
 ]
diff --git a/griptape/tools/task_memory/__init__.py b/griptape/tools/extraction/__init__.py
similarity index 100%
rename from griptape/tools/task_memory/__init__.py
rename to griptape/tools/extraction/__init__.py
diff --git a/griptape/tools/extraction/manifest.yml b/griptape/tools/extraction/manifest.yml
new file mode 100644
index 000000000..9c489d9f6
--- /dev/null
+++ b/griptape/tools/extraction/manifest.yml
@@ -0,0 +1,5 @@
+version: "v1"
+name: Extraction Client
+description: Tool for performing structured extractions on unstructured data.
+contact_email: hello@griptape.ai
+legal_info_url: https://www.griptape.ai/legal
diff --git a/griptape/tools/extraction/requirements.txt b/griptape/tools/extraction/requirements.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/griptape/tools/extraction/tool.py b/griptape/tools/extraction/tool.py
new file mode 100644
index 000000000..1f6d06b80
--- /dev/null
+++ b/griptape/tools/extraction/tool.py
@@ -0,0 +1,60 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+from attrs import define, field
+from schema import Literal, Or, Schema
+
+from griptape.artifacts import ErrorArtifact, ListArtifact, TextArtifact
+from griptape.mixins import RuleMixin
+from griptape.tools import BaseTool
+from griptape.utils.decorators import activity
+
+if TYPE_CHECKING:
+    from griptape.artifacts import InfoArtifact
+    from griptape.engines import BaseExtractionEngine
+
+
+@define(kw_only=True)
+class ExtractionTool(BaseTool, RuleMixin):
+    """Tool for using an Extraction Engine.
+
+    Attributes:
+        extraction_engine: `ExtractionEngine`.
+    """
+
+    extraction_engine: BaseExtractionEngine = field()
+
+    @activity(
+        config={
+            "description": "Can be used extract structured text from data.",
+            "schema": Schema(
+                {
+                    Literal("data"): Or(
+                        str,
+                        Schema(
+                            {
+                                "memory_name": str,
+                                "artifact_namespace": str,
+                            }
+                        ),
+                    ),
+                }
+            ),
+        },
+    )
+    def extract(self, params: dict) -> ListArtifact | InfoArtifact | ErrorArtifact:
+        data = params["values"]["data"]
+
+        if isinstance(data, str):
+            artifacts = ListArtifact([TextArtifact(data)])
+        else:
+            memory = self.find_input_memory(data["memory_name"])
+            artifact_namespace = data["artifact_namespace"]
+
+            if memory is not None:
+                artifacts = memory.load_artifacts(artifact_namespace)
+            else:
+                return ErrorArtifact("memory not found")
+
+        return self.extraction_engine.extract(artifacts)
diff --git a/griptape/tools/prompt_summary/__init__.py b/griptape/tools/prompt_summary/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/griptape/tools/prompt_summary/manifest.yml b/griptape/tools/prompt_summary/manifest.yml
new file mode 100644
index 000000000..a83ea4021
--- /dev/null
+++ b/griptape/tools/prompt_summary/manifest.yml
@@ -0,0 +1,5 @@
+version: "v1"
+name: Prompt Summary Client
+description: Tool for using a Prompt Summary Engine
+contact_email: hello@griptape.ai
+legal_info_url: https://www.griptape.ai/legal
diff --git a/griptape/tools/prompt_summary/requirements.txt b/griptape/tools/prompt_summary/requirements.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/griptape/tools/prompt_summary/tool.py b/griptape/tools/prompt_summary/tool.py
new file mode 100644
index 000000000..88ec9d855
--- /dev/null
+++ b/griptape/tools/prompt_summary/tool.py
@@ -0,0 +1,55 @@
+from __future__ import annotations
+
+from attrs import define, field
+from schema import Literal, Or, Schema
+
+from griptape.artifacts import BaseArtifact, ErrorArtifact, ListArtifact, TextArtifact
+from griptape.engines import PromptSummaryEngine
+from griptape.mixins.rule_mixin import RuleMixin
+from griptape.tools import BaseTool
+from griptape.utils.decorators import activity
+
+
+@define(kw_only=True)
+class PromptSummaryTool(BaseTool, RuleMixin):
+    """Tool for using a Prompt Summary Engine.
+
+    Attributes:
+        prompt_summary_engine: `PromptSummaryEngine`.
+    """
+
+    prompt_summary_engine: PromptSummaryEngine = field(kw_only=True, default=PromptSummaryEngine())
+
+    @activity(
+        config={
+            "description": "Can be used to summarize text content.",
+            "schema": Schema(
+                {
+                    Literal("summary"): Or(
+                        str,
+                        Schema(
+                            {
+                                "memory_name": str,
+                                "artifact_namespace": str,
+                            }
+                        ),
+                    ),
+                }
+            ),
+        },
+    )
+    def summarize(self, params: dict) -> BaseArtifact:
+        summary = params["values"]["summary"]
+
+        if isinstance(summary, str):
+            artifacts = ListArtifact([TextArtifact(summary)])
+        else:
+            memory = self.find_input_memory(summary["memory_name"])
+            artifact_namespace = summary["artifact_namespace"]
+
+            if memory is not None:
+                artifacts = memory.load_artifacts(artifact_namespace)
+            else:
+                return ErrorArtifact("memory not found")
+
+        return self.prompt_summary_engine.summarize_artifacts(artifacts, rulesets=self.all_rulesets)
diff --git a/griptape/tools/query/__init__.py b/griptape/tools/query/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/griptape/tools/query/manifest.yml b/griptape/tools/query/manifest.yml
new file mode 100644
index 000000000..086a86d5a
--- /dev/null
+++ b/griptape/tools/query/manifest.yml
@@ -0,0 +1,5 @@
+version: "v1"
+name: Query Client
+description: Tool for performing a query against data.
+contact_email: hello@griptape.ai
+legal_info_url: https://www.griptape.ai/legal
diff --git a/griptape/tools/query/requirements.txt b/griptape/tools/query/requirements.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/griptape/tools/query/tool.py b/griptape/tools/query/tool.py
new file mode 100644
index 000000000..3ecc63bca
--- /dev/null
+++ b/griptape/tools/query/tool.py
@@ -0,0 +1,78 @@
+from __future__ import annotations
+
+from attrs import Factory, define, field
+from schema import Literal, Or, Schema
+
+from griptape.artifacts import BaseArtifact, ErrorArtifact, ListArtifact, TextArtifact
+from griptape.config import config
+from griptape.engines.rag import RagEngine
+from griptape.engines.rag.modules import (
+    PromptResponseRagModule,
+)
+from griptape.engines.rag.rag_context import RagContext
+from griptape.engines.rag.stages import ResponseRagStage
+from griptape.mixins.rule_mixin import RuleMixin
+from griptape.tools.base_tool import BaseTool
+from griptape.utils.decorators import activity
+
+
+@define(kw_only=True)
+class QueryTool(BaseTool, RuleMixin):
+    """Tool for performing a query against data."""
+
+    _rag_engine: RagEngine = field(
+        default=Factory(
+            lambda self: RagEngine(
+                response_stage=ResponseRagStage(
+                    response_modules=[
+                        PromptResponseRagModule(prompt_driver=config.drivers.prompt, rulesets=self.rulesets)
+                    ],
+                ),
+            ),
+            takes_self=True,
+        ),
+        alias="_rag_engine",
+    )
+
+    @activity(
+        config={
+            "description": "Can be used to search through textual content.",
+            "schema": Schema(
+                {
+                    Literal("query", description="A natural language search query"): str,
+                    Literal("content"): Or(
+                        str,
+                        Schema(
+                            {
+                                "memory_name": str,
+                                "artifact_namespace": str,
+                            }
+                        ),
+                    ),
+                }
+            ),
+        },
+    )
+    def query(self, params: dict) -> BaseArtifact:
+        query = params["values"]["query"]
+        content = params["values"]["content"]
+
+        if isinstance(content, str):
+            text_artifacts = [TextArtifact(content)]
+        else:
+            memory = self.find_input_memory(content["memory_name"])
+            artifact_namespace = content["artifact_namespace"]
+
+            if memory is not None:
+                artifacts = memory.load_artifacts(artifact_namespace)
+            else:
+                return ErrorArtifact("memory not found")
+
+            text_artifacts = [artifact for artifact in artifacts if isinstance(artifact, TextArtifact)]
+
+        outputs = self._rag_engine.process(RagContext(query=query, text_chunks=text_artifacts)).outputs
+
+        if len(outputs) > 0:
+            return ListArtifact(outputs)
+        else:
+            return ErrorArtifact("query output is empty")
diff --git a/griptape/tools/task_memory/manifest.yml b/griptape/tools/task_memory/manifest.yml
deleted file mode 100644
index 5d40a1e68..000000000
--- a/griptape/tools/task_memory/manifest.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-version: "v1"
-name: Task Memory Tool
-description: Tool for summarizing and querying TaskMemory.
-contact_email: hello@griptape.ai
-legal_info_url: https://www.griptape.ai/legal
\ No newline at end of file
diff --git a/griptape/tools/task_memory/tool.py b/griptape/tools/task_memory/tool.py
deleted file mode 100644
index dfd6c7c4b..000000000
--- a/griptape/tools/task_memory/tool.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from __future__ import annotations
-
-from attrs import define
-from schema import Literal, Schema
-
-from griptape.artifacts import BaseArtifact, ErrorArtifact, InfoArtifact, TextArtifact
-from griptape.tools import BaseTool
-from griptape.utils.decorators import activity
-
-
-@define
-class TaskMemoryTool(BaseTool):
-    @activity(
-        config={
-            "description": "Can be used to summarize memory content",
-            "schema": Schema({"memory_name": str, "artifact_namespace": str}),
-        },
-    )
-    def summarize(self, params: dict) -> TextArtifact | InfoArtifact | ErrorArtifact:
-        memory = self.find_input_memory(params["values"]["memory_name"])
-        artifact_namespace = params["values"]["artifact_namespace"]
-
-        if memory:
-            return memory.summarize_namespace(artifact_namespace)
-        else:
-            return ErrorArtifact("memory not found")
-
-    @activity(
-        config={
-            "description": "Can be used to search and query memory content",
-            "schema": Schema(
-                {
-                    "memory_name": str,
-                    "artifact_namespace": str,
-                    Literal(
-                        "query",
-                        description="A natural language search query in the form of a question with enough "
-                        "contextual information for another person to understand what the query is about",
-                    ): str,
-                },
-            ),
-        },
-    )
-    def query(self, params: dict) -> BaseArtifact:
-        memory = self.find_input_memory(params["values"]["memory_name"])
-        artifact_namespace = params["values"]["artifact_namespace"]
-        query = params["values"]["query"]
-
-        if memory:
-            return memory.query_namespace(namespace=artifact_namespace, query=query)
-        else:
-            return ErrorArtifact("memory not found")
diff --git a/griptape/utils/load_artifact_from_memory.py b/griptape/utils/load_artifact_from_memory.py
index a45a41dbd..2d3f8bc86 100644
--- a/griptape/utils/load_artifact_from_memory.py
+++ b/griptape/utils/load_artifact_from_memory.py
@@ -1,9 +1,14 @@
-from griptape.artifacts import BaseArtifact
-from griptape.memory import TaskMemory
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Optional
+
+if TYPE_CHECKING:
+    from griptape.artifacts import BaseArtifact
+    from griptape.memory import TaskMemory
 
 
 def load_artifact_from_memory(
-    memory: TaskMemory,
+    memory: Optional[TaskMemory],
     artifact_namespace: str,
     artifact_name: str,
     artifact_type: type,
diff --git a/mkdocs.yml b/mkdocs.yml
index ce1772754..7e3806264 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -144,7 +144,6 @@ nav:
           - Open Weather: "griptape-tools/official-tools/openweather-tool.md"
           - Rest Api Client: "griptape-tools/official-tools/rest-api-tool.md"
           - Sql: "griptape-tools/official-tools/sql-tool.md"
-          - Task Memory: "griptape-tools/official-tools/task-memory-tool.md"
           - Vector Store Tool: "griptape-tools/official-tools/vector-store-tool.md"
           - Web Scraper: "griptape-tools/official-tools/web-scraper-tool.md"
           - Web Search: "griptape-tools/official-tools/web-search-tool.md"
@@ -157,6 +156,9 @@ nav:
           - Audio Transcription: "griptape-tools/official-tools/audio-transcription-tool.md"
           - Griptape Cloud Knowledge Base: "griptape-tools/official-tools/griptape-cloud-knowledge-base-tool.md"
           - Rag: "griptape-tools/official-tools/rag-tool.md"
+          - Extraction: "griptape-tools/official-tools/extraction-tool.md"
+          - Query: "griptape-tools/official-tools/query-tool.md"
+          - Prompt Summary: "griptape-tools/official-tools/prompt-summary-tool.md"
       - Custom Tools:
           - Building Custom Tools: "griptape-tools/custom-tools/index.md"
   - Recipes:
diff --git a/poetry.lock b/poetry.lock
index ad2653f13..32c3964ef 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -3125,23 +3125,25 @@ mkdocs = ">=1.2"
 
 [[package]]
 name = "mkdocstrings"
-version = "0.23.0"
+version = "0.25.2"
 description = "Automatic documentation from sources, for MkDocs."
 optional = false
 python-versions = ">=3.8"
 files = [
-    {file = "mkdocstrings-0.23.0-py3-none-any.whl", hash = "sha256:051fa4014dfcd9ed90254ae91de2dbb4f24e166347dae7be9a997fe16316c65e"},
-    {file = "mkdocstrings-0.23.0.tar.gz", hash = "sha256:d9c6a37ffbe7c14a7a54ef1258c70b8d394e6a33a1c80832bce40b9567138d1c"},
+    {file = "mkdocstrings-0.25.2-py3-none-any.whl", hash = "sha256:9e2cda5e2e12db8bb98d21e3410f3f27f8faab685a24b03b06ba7daa5b92abfc"},
+    {file = "mkdocstrings-0.25.2.tar.gz", hash = "sha256:5cf57ad7f61e8be3111a2458b4e49c2029c9cb35525393b179f9c916ca8042dc"},
 ]
 
 [package.dependencies]
+click = ">=7.0"
 importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""}
 Jinja2 = ">=2.11.1"
 Markdown = ">=3.3"
 MarkupSafe = ">=1.1"
-mkdocs = ">=1.2"
+mkdocs = ">=1.4"
 mkdocs-autorefs = ">=0.3.1"
 mkdocstrings-python = {version = ">=0.5.2", optional = true, markers = "extra == \"python\""}
+platformdirs = ">=2.2.0"
 pymdown-extensions = ">=6.3"
 typing-extensions = {version = ">=4.1", markers = "python_version < \"3.10\""}
 
@@ -6986,4 +6988,4 @@ loaders-sql = ["sqlalchemy"]
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.9"
-content-hash = "62e3ac71e745d060bddc2c1f853068e7083cf7fc2b8fb5474baa188477507607"
+content-hash = "ee23a885217a5285e3a33cac221c55f011cd4ce428b33cd8abfbdac38a27a638"
diff --git a/pyproject.toml b/pyproject.toml
index a9992e1b4..54b984261 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -239,7 +239,7 @@ optional = true
 mkdocs = "^1.5.2"
 mkdocs-material = "^9.2.8"
 mkdocs-glightbox = "^0.3.4"
-mkdocstrings = {extras = ["python"], version = "^0.23.0"}
+mkdocstrings = {extras = ["python"], version = "^0.25.2"}
 mkdocs-gen-files = "^0.5.0"
 mkdocs-literate-nav = "^0.6.0"
 mkdocs-section-index = "^0.3.6"


Test patch:
diff --git a/tests/integration/tasks/test_toolkit_task.py b/tests/integration/tasks/test_toolkit_task.py
index 5cb1aa0dc..50b4f2a97 100644
--- a/tests/integration/tasks/test_toolkit_task.py
+++ b/tests/integration/tasks/test_toolkit_task.py
@@ -14,7 +14,7 @@ def structure_tester(self, request):
 
         from griptape.drivers import GoogleWebSearchDriver
         from griptape.structures import Agent
-        from griptape.tools import TaskMemoryTool, WebScraperTool, WebSearchTool
+        from griptape.tools import PromptSummaryTool, WebScraperTool, WebSearchTool
 
         return StructureTester(
             Agent(
@@ -25,7 +25,7 @@ def structure_tester(self, request):
                         )
                     ),
                     WebScraperTool(off_prompt=True),
-                    TaskMemoryTool(off_prompt=False),
+                    PromptSummaryTool(off_prompt=False),
                 ],
                 conversation_memory=None,
                 prompt_driver=request.param,
diff --git a/tests/unit/drivers/event_listener/test_griptape_cloud_event_listener_driver.py b/tests/unit/drivers/event_listener/test_griptape_cloud_event_listener_driver.py
index 1cd198756..0bf298870 100644
--- a/tests/unit/drivers/event_listener/test_griptape_cloud_event_listener_driver.py
+++ b/tests/unit/drivers/event_listener/test_griptape_cloud_event_listener_driver.py
@@ -87,7 +87,3 @@ def try_publish_event_payload_batch(self, mock_post, driver):
                 json=event.to_dict(),
                 headers={"Authorization": "Bearer foo bar"},
             )
-
-    def test_no_structure_run_id(self):
-        with pytest.raises(ValueError):
-            GriptapeCloudEventListenerDriver(api_key="foo bar")
diff --git a/tests/unit/engines/extraction/test_csv_extraction_engine.py b/tests/unit/engines/extraction/test_csv_extraction_engine.py
index d84fc7cdd..893c21d60 100644
--- a/tests/unit/engines/extraction/test_csv_extraction_engine.py
+++ b/tests/unit/engines/extraction/test_csv_extraction_engine.py
@@ -6,10 +6,10 @@
 class TestCsvExtractionEngine:
     @pytest.fixture()
     def engine(self):
-        return CsvExtractionEngine()
+        return CsvExtractionEngine(column_names=["test1"])
 
     def test_extract(self, engine):
-        result = engine.extract("foo", column_names=["test1"])
+        result = engine.extract("foo")
 
         assert len(result.value) == 1
         assert result.value[0].value == {"test1": "mock output"}
diff --git a/tests/unit/engines/extraction/test_json_extraction_engine.py b/tests/unit/engines/extraction/test_json_extraction_engine.py
index d95adbb43..48430f1e5 100644
--- a/tests/unit/engines/extraction/test_json_extraction_engine.py
+++ b/tests/unit/engines/extraction/test_json_extraction_engine.py
@@ -12,22 +12,26 @@ def engine(self):
         return JsonExtractionEngine(
             prompt_driver=MockPromptDriver(
                 mock_output='[{"test_key_1": "test_value_1"}, {"test_key_2": "test_value_2"}]'
-            )
+            ),
+            template_schema=Schema({"foo": "bar"}).json_schema("TemplateSchema"),
         )
 
     def test_extract(self, engine):
-        json_schema = Schema({"foo": "bar"}).json_schema("TemplateSchema")
-        result = engine.extract("foo", template_schema=json_schema)
+        result = engine.extract("foo")
 
         assert len(result.value) == 2
         assert result.value[0].value == '{"test_key_1": "test_value_1"}'
         assert result.value[1].value == '{"test_key_2": "test_value_2"}'
 
     def test_extract_error(self, engine):
-        assert isinstance(engine.extract("foo", template_schema=lambda: "non serializable"), ErrorArtifact)
+        engine.template_schema = lambda: "non serializable"
+        assert isinstance(engine.extract("foo"), ErrorArtifact)
 
     def test_json_to_text_artifacts(self, engine):
         assert [
             a.value
             for a in engine.json_to_text_artifacts('[{"test_key_1": "test_value_1"}, {"test_key_2": "test_value_2"}]')
         ] == ['{"test_key_1": "test_value_1"}', '{"test_key_2": "test_value_2"}']
+
+    def test_json_to_text_artifacts_no_matches(self, engine):
+        assert engine.json_to_text_artifacts("asdfasdfasdf") == []
diff --git a/tests/unit/memory/tool/storage/test_blob_artifact_storage.py b/tests/unit/memory/tool/storage/test_blob_artifact_storage.py
index c7f2cfcbd..78d1c662d 100644
--- a/tests/unit/memory/tool/storage/test_blob_artifact_storage.py
+++ b/tests/unit/memory/tool/storage/test_blob_artifact_storage.py
@@ -25,13 +25,3 @@ def test_load_artifacts(self, storage):
     def test_can_store(self, storage):
         assert not storage.can_store(TextArtifact("foo"))
         assert storage.can_store(BlobArtifact(b"foo"))
-
-    def test_summarize(self, storage):
-        storage.store_artifact("foo", BlobArtifact(b"test"))
-
-        assert storage.summarize("foo").value == "can't summarize artifacts"
-
-    def test_query(self, storage):
-        storage.store_artifact("foo", BlobArtifact(b"test"))
-
-        assert storage.query("foo", "query").value == "can't query artifacts"
diff --git a/tests/unit/memory/tool/storage/test_text_artifact_storage.py b/tests/unit/memory/tool/storage/test_text_artifact_storage.py
index 64f44c581..2f49421d4 100644
--- a/tests/unit/memory/tool/storage/test_text_artifact_storage.py
+++ b/tests/unit/memory/tool/storage/test_text_artifact_storage.py
@@ -25,13 +25,3 @@ def test_load_artifacts(self, storage):
     def test_can_store(self, storage):
         assert storage.can_store(TextArtifact("foo"))
         assert not storage.can_store(BlobArtifact(b"foo"))
-
-    def test_summarize(self, storage):
-        storage.store_artifact("foo", TextArtifact("test"))
-
-        assert storage.summarize("foo").value == "mock output"
-
-    def test_query(self, storage):
-        storage.store_artifact("foo", TextArtifact("test"))
-
-        assert storage.query("foo", "query").value == "mock output"
diff --git a/tests/unit/memory/tool/test_task_memory.py b/tests/unit/memory/tool/test_task_memory.py
index 53e4703a6..2f6ffe1c9 100644
--- a/tests/unit/memory/tool/test_task_memory.py
+++ b/tests/unit/memory/tool/test_task_memory.py
@@ -96,13 +96,3 @@ def test_load_artifacts_for_blob_list_artifact(self, memory):
         )
 
         assert len(memory.load_artifacts("test")) == 2
-
-    def test_summarize_namespace(self, memory):
-        memory.store_artifact("foo", TextArtifact("test"))
-
-        assert memory.summarize_namespace("foo").value == "mock output"
-
-    def test_query_namespace(self, memory):
-        memory.store_artifact("foo", TextArtifact("test"))
-
-        assert memory.query_namespace("foo", "query").value == "mock output"
diff --git a/tests/unit/structures/test_agent.py b/tests/unit/structures/test_agent.py
index 33bfdc5ee..ef5faeff1 100644
--- a/tests/unit/structures/test_agent.py
+++ b/tests/unit/structures/test_agent.py
@@ -1,13 +1,11 @@
 import pytest
 
-from griptape.engines import PromptSummaryEngine
 from griptape.memory import TaskMemory
 from griptape.memory.structure import ConversationMemory
 from griptape.memory.task.storage import TextArtifactStorage
 from griptape.rules import Rule, Ruleset
 from griptape.structures import Agent
 from griptape.tasks import BaseTask, PromptTask, ToolkitTask
-from tests.mocks.mock_embedding_driver import MockEmbeddingDriver
 from tests.mocks.mock_prompt_driver import MockPromptDriver
 from tests.mocks.mock_tool.tool import MockTool
 
@@ -218,23 +216,13 @@ def test_context(self):
 
         assert context["structure"] == agent
 
-    def test_task_memory_defaults(self):
-        prompt_driver = MockPromptDriver()
-        embedding_driver = MockEmbeddingDriver()
-        agent = Agent(prompt_driver=prompt_driver)
+    def test_task_memory_defaults(self, mock_config):
+        agent = Agent()
 
         storage = list(agent.task_memory.artifact_storages.values())[0]
         assert isinstance(storage, TextArtifactStorage)
 
-        assert storage.rag_engine.response_stage.response_modules[0].prompt_driver == prompt_driver
-        assert (
-            storage.rag_engine.retrieval_stage.retrieval_modules[0].vector_store_driver.embedding_driver
-            == embedding_driver
-        )
-        assert isinstance(storage.summary_engine, PromptSummaryEngine)
-        assert storage.summary_engine.prompt_driver == prompt_driver
-        assert storage.csv_extraction_engine.prompt_driver == prompt_driver
-        assert storage.json_extraction_engine.prompt_driver == prompt_driver
+        assert storage.vector_store_driver.embedding_driver == mock_config.drivers.embedding
 
     def finished_tasks(self):
         task = PromptTask("test prompt")
diff --git a/tests/unit/tasks/test_csv_extraction_task.py b/tests/unit/tasks/test_csv_extraction_task.py
deleted file mode 100644
index ec8f70b23..000000000
--- a/tests/unit/tasks/test_csv_extraction_task.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import pytest
-
-from griptape.engines import CsvExtractionEngine
-from griptape.structures import Agent
-from griptape.tasks import CsvExtractionTask
-from tests.mocks.mock_prompt_driver import MockPromptDriver
-
-
-class TestCsvExtractionTask:
-    @pytest.fixture()
-    def task(self):
-        return CsvExtractionTask(args={"column_names": ["test1"]})
-
-    def test_run(self, task):
-        agent = Agent()
-
-        agent.add_task(task)
-
-        result = task.run()
-
-        assert len(result.value) == 1
-        assert result.value[0].value == {"test1": "mock output"}
-
-    def test_config_extraction_engine(self, task):
-        Agent().add_task(task)
-
-        assert isinstance(task.extraction_engine, CsvExtractionEngine)
-        assert isinstance(task.extraction_engine.prompt_driver, MockPromptDriver)
diff --git a/tests/unit/tasks/test_extraction_task.py b/tests/unit/tasks/test_extraction_task.py
index 76a4c3bd2..2d7ab442c 100644
--- a/tests/unit/tasks/test_extraction_task.py
+++ b/tests/unit/tasks/test_extraction_task.py
@@ -8,7 +8,7 @@
 class TestExtractionTask:
     @pytest.fixture()
     def task(self):
-        return ExtractionTask(extraction_engine=CsvExtractionEngine(), args={"column_names": ["test1"]})
+        return ExtractionTask(extraction_engine=CsvExtractionEngine(column_names=["test1"]))
 
     def test_run(self, task):
         agent = Agent()
diff --git a/tests/unit/tasks/test_json_extraction_task.py b/tests/unit/tasks/test_json_extraction_task.py
deleted file mode 100644
index 8f9278c3c..000000000
--- a/tests/unit/tasks/test_json_extraction_task.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import pytest
-from schema import Schema
-
-from griptape.engines import JsonExtractionEngine
-from griptape.structures import Agent
-from griptape.tasks import JsonExtractionTask
-from tests.mocks.mock_prompt_driver import MockPromptDriver
-
-
-class TestJsonExtractionTask:
-    @pytest.fixture()
-    def task(self):
-        return JsonExtractionTask("foo", args={"template_schema": Schema({"foo": "bar"}).json_schema("TemplateSchema")})
-
-    def test_run(self, task, mock_config):
-        mock_config.drivers.prompt.mock_output = '[{"test_key_1": "test_value_1"}, {"test_key_2": "test_value_2"}]'
-        agent = Agent()
-
-        agent.add_task(task)
-
-        result = task.run()
-
-        assert len(result.value) == 2
-        assert result.value[0].value == '{"test_key_1": "test_value_1"}'
-        assert result.value[1].value == '{"test_key_2": "test_value_2"}'
-
-    def test_config_extraction_engine(self, task):
-        Agent().add_task(task)
-
-        assert isinstance(task.extraction_engine, JsonExtractionEngine)
-        assert isinstance(task.extraction_engine.prompt_driver, MockPromptDriver)
diff --git a/tests/unit/tools/test_extraction_tool.py b/tests/unit/tools/test_extraction_tool.py
new file mode 100644
index 000000000..1219da373
--- /dev/null
+++ b/tests/unit/tools/test_extraction_tool.py
@@ -0,0 +1,67 @@
+import json
+
+import pytest
+
+from griptape.artifacts import TextArtifact
+from griptape.engines import CsvExtractionEngine, JsonExtractionEngine
+from griptape.tools import ExtractionTool
+from tests.mocks.mock_prompt_driver import MockPromptDriver
+from tests.utils import defaults
+
+
+class TestExtractionTool:
+    @pytest.fixture()
+    def json_tool(self):
+        return ExtractionTool(
+            input_memory=[defaults.text_task_memory("TestMemory")],
+            extraction_engine=JsonExtractionEngine(
+                prompt_driver=MockPromptDriver(
+                    mock_output='[{"test_key_1": "test_value_1"}, {"test_key_2": "test_value_2"}]'
+                ),
+                template_schema={},
+            ),
+        )
+
+    @pytest.fixture()
+    def csv_tool(self):
+        return ExtractionTool(
+            input_memory=[defaults.text_task_memory("TestMemory")],
+            extraction_engine=CsvExtractionEngine(
+                prompt_driver=MockPromptDriver(),
+                column_names=["test1"],
+            ),
+        )
+
+    def test_json_extract_artifacts(self, json_tool):
+        json_tool.input_memory[0].store_artifact("foo", TextArtifact(json.dumps({})))
+
+        result = json_tool.extract(
+            {"values": {"data": {"memory_name": json_tool.input_memory[0].name, "artifact_namespace": "foo"}}}
+        )
+
+        assert len(result.value) == 2
+        assert result.value[0].value == '{"test_key_1": "test_value_1"}'
+        assert result.value[1].value == '{"test_key_2": "test_value_2"}'
+
+    def test_json_extract_content(self, json_tool):
+        result = json_tool.extract({"values": {"data": "foo"}})
+
+        assert len(result.value) == 2
+        assert result.value[0].value == '{"test_key_1": "test_value_1"}'
+        assert result.value[1].value == '{"test_key_2": "test_value_2"}'
+
+    def test_csv_extract_artifacts(self, csv_tool):
+        csv_tool.input_memory[0].store_artifact("foo", TextArtifact("foo,bar\nbaz,maz"))
+
+        result = csv_tool.extract(
+            {"values": {"data": {"memory_name": csv_tool.input_memory[0].name, "artifact_namespace": "foo"}}}
+        )
+
+        assert len(result.value) == 1
+        assert result.value[0].value == {"test1": "mock output"}
+
+    def test_csv_extract_content(self, csv_tool):
+        result = csv_tool.extract({"values": {"data": "foo"}})
+
+        assert len(result.value) == 1
+        assert result.value[0].value == {"test1": "mock output"}
diff --git a/tests/unit/tools/test_prompt_summary_tool.py b/tests/unit/tools/test_prompt_summary_tool.py
new file mode 100644
index 000000000..81a03acf5
--- /dev/null
+++ b/tests/unit/tools/test_prompt_summary_tool.py
@@ -0,0 +1,29 @@
+import pytest
+
+from griptape.artifacts import TextArtifact
+from griptape.engines import PromptSummaryEngine
+from griptape.tools import PromptSummaryTool
+from tests.mocks.mock_prompt_driver import MockPromptDriver
+from tests.utils import defaults
+
+
+class TestPromptSummaryTool:
+    @pytest.fixture()
+    def tool(self):
+        return PromptSummaryTool(
+            input_memory=[defaults.text_task_memory("TestMemory")],
+            prompt_summary_engine=PromptSummaryEngine(prompt_driver=MockPromptDriver()),
+        )
+
+    def test_summarize_artifacts(self, tool):
+        tool.input_memory[0].store_artifact("foo", TextArtifact("test"))
+
+        assert (
+            tool.summarize(
+                {"values": {"summary": {"memory_name": tool.input_memory[0].name, "artifact_namespace": "foo"}}}
+            ).value
+            == "mock output"
+        )
+
+    def test_summarize_content(self, tool):
+        assert tool.summarize({"values": {"summary": "test"}}).value == "mock output"
diff --git a/tests/unit/tools/test_query_tool.py b/tests/unit/tools/test_query_tool.py
new file mode 100644
index 000000000..dcbee16cf
--- /dev/null
+++ b/tests/unit/tools/test_query_tool.py
@@ -0,0 +1,31 @@
+import pytest
+
+from griptape.tools.query.tool import QueryTool
+from tests.utils import defaults
+
+
+class TestQueryTool:
+    @pytest.fixture()
+    def tool(self):
+        return QueryTool(input_memory=[defaults.text_task_memory("TestMemory")])
+
+    def test_query_str(self, tool):
+        assert tool.query({"values": {"query": "test", "content": "foo"}}).value[0].value == "mock output"
+
+    def test_query_artifacts(self, tool):
+        assert (
+            tool.query(
+                {
+                    "values": {
+                        "query": "test",
+                        "content": {
+                            "memory_name": tool.input_memory[0].name,
+                            "artifact_namespace": "test",
+                        },
+                    }
+                }
+            )
+            .value[0]
+            .value
+            == "mock output"
+        )
diff --git a/tests/unit/tools/test_task_memory_tool.py b/tests/unit/tools/test_task_memory_tool.py
deleted file mode 100644
index 238001d55..000000000
--- a/tests/unit/tools/test_task_memory_tool.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import pytest
-
-from griptape.artifacts import TextArtifact
-from griptape.tools import TaskMemoryTool
-from tests.utils import defaults
-
-
-class TestTaskMemoryTool:
-    @pytest.fixture()
-    def tool(self):
-        return TaskMemoryTool(off_prompt=True, input_memory=[defaults.text_task_memory("TestMemory")])
-
-    def test_summarize(self, tool):
-        tool.input_memory[0].store_artifact("foo", TextArtifact("test"))
-
-        assert (
-            tool.summarize({"values": {"memory_name": tool.input_memory[0].name, "artifact_namespace": "foo"}}).value
-            == "mock output"
-        )
-
-    def test_query(self, tool):
-        tool.input_memory[0].store_artifact("foo", TextArtifact("test"))
-
-        assert (
-            tool.query(
-                {"values": {"query": "foobar", "memory_name": tool.input_memory[0].name, "artifact_namespace": "foo"}}
-            ).value
-            == "mock output"
-        )
diff --git a/tests/utils/defaults.py b/tests/utils/defaults.py
index 8e9d45fb7..0e26225a9 100644
--- a/tests/utils/defaults.py
+++ b/tests/utils/defaults.py
@@ -1,25 +1,18 @@
 from griptape.artifacts import BlobArtifact, TextArtifact
 from griptape.drivers import LocalVectorStoreDriver
-from griptape.engines import CsvExtractionEngine, JsonExtractionEngine, PromptSummaryEngine
 from griptape.engines.rag import RagEngine
 from griptape.engines.rag.modules import PromptResponseRagModule, VectorStoreRetrievalRagModule
 from griptape.engines.rag.stages import ResponseRagStage, RetrievalRagStage
 from griptape.memory import TaskMemory
 from griptape.memory.task.storage import BlobArtifactStorage, TextArtifactStorage
 from tests.mocks.mock_embedding_driver import MockEmbeddingDriver
-from tests.mocks.mock_prompt_driver import MockPromptDriver
 
 
 def text_tool_artifact_storage():
     vector_store_driver = LocalVectorStoreDriver(embedding_driver=MockEmbeddingDriver())
 
     return TextArtifactStorage(
-        rag_engine=rag_engine(MockPromptDriver(), vector_store_driver),
         vector_store_driver=vector_store_driver,
-        retrieval_rag_module_name="VectorStoreRetrievalRagModule",
-        summary_engine=PromptSummaryEngine(),
-        csv_extraction_engine=CsvExtractionEngine(),
-        json_extraction_engine=JsonExtractionEngine(),
     )