Repository: griptape-ai/griptape

Issue:
Structured Output + Conversation Memory Fails With Pydantic Models
```python
from griptape.drivers.memory.conversation.local import LocalConversationMemoryDriver
from griptape.memory.structure import ConversationMemory
from griptape.structures import Pipeline
from griptape.tasks import PromptTask
from pydantic import BaseModel


class Output(BaseModel):
    answer: str


pipeline = Pipeline(
    conversation_memory=ConversationMemory(
        conversation_memory_driver=LocalConversationMemoryDriver(
            persist_file="conversation_memory.json"
        )
    ),
    tasks=[
        PromptTask(
            output_schema=Output,
        )
    ],
)

pipeline.run("Hi")
pipeline.run("What's my name?")
```

Run it twice.

Hints from issue comments:

Solution patch:
diff --git a/griptape/schemas/pydantic_model_field.py b/griptape/schemas/pydantic_model_field.py
index 7b7ecfdc..1fc5d262 100644
--- a/griptape/schemas/pydantic_model_field.py
+++ b/griptape/schemas/pydantic_model_field.py
@@ -1,11 +1,9 @@
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, Any, Optional
+from typing import Any, Optional
 
 from marshmallow import fields
-
-if TYPE_CHECKING:
-    from pydantic import BaseModel
+from pydantic import BaseModel, RootModel
 
 
 class PydanticModel(fields.Field):
@@ -14,8 +12,5 @@ class PydanticModel(fields.Field):
             return None
         return value.model_dump()
 
-    def _deserialize(self, value: dict, attr: Any, data: Any, **kwargs) -> dict:
-        # Not implemented as it is non-trivial to deserialize json back into a model
-        # since we need to know the model class to instantiate it.
-        # Would rather not implement right now rather than implement incorrectly.
-        raise NotImplementedError("Model fields cannot be deserialized directly.")
+    def _deserialize(self, value: dict, attr: Any, data: Any, **kwargs) -> BaseModel:
+        return RootModel(value)


Test patch:
diff --git a/tests/unit/artifacts/test_model_artifact.py b/tests/unit/artifacts/test_model_artifact.py
index c9cc52ce..a73cc6a0 100644
--- a/tests/unit/artifacts/test_model_artifact.py
+++ b/tests/unit/artifacts/test_model_artifact.py
@@ -21,5 +21,5 @@ class TestModelArtifact:
 
     def test_deserialization(self, model_artifact):
         artifact_dict = model_artifact.to_dict()
-        with pytest.raises(NotImplementedError):
-            BaseArtifact.from_dict(artifact_dict)
+        model = BaseArtifact.from_dict(artifact_dict)
+        assert isinstance(model, ModelArtifact)