Bases: BaseConversationMemoryDriver
A Conversation Memory Driver for Dakera.
Dakera is a self-hosted memory server that persists conversation state across sessions. Each
conversation is stored under its own conversation_id, which is used as the Dakera agent_id
so that a conversation's memories are isolated from every other conversation. On store the
previous snapshot is replaced with the latest one, mirroring the semantics of the other
Conversation Memory Drivers.
Attributes:
| Name |
Type |
Description |
base_url |
str
|
The base URL of the Dakera server. Defaults to the value of the environment
variable DAKERA_BASE_URL or http://localhost:3000.
|
api_key |
str | None
|
The API key used to authenticate with the Dakera server. Defaults to the value of
the environment variable DAKERA_API_KEY. May be None for a server that does not
require authentication.
|
conversation_id |
str
|
The id of the conversation. Used as the Dakera agent_id.
|
Source code in griptape/drivers/memory/conversation/dakera_conversation_memory_driver.py
| @define(kw_only=True)
class DakeraConversationMemoryDriver(BaseConversationMemoryDriver):
"""A Conversation Memory Driver for Dakera.
Dakera is a self-hosted memory server that persists conversation state across sessions. Each
conversation is stored under its own ``conversation_id``, which is used as the Dakera ``agent_id``
so that a conversation's memories are isolated from every other conversation. On ``store`` the
previous snapshot is replaced with the latest one, mirroring the semantics of the other
Conversation Memory Drivers.
Attributes:
base_url: The base URL of the Dakera server. Defaults to the value of the environment
variable ``DAKERA_BASE_URL`` or ``http://localhost:3000``.
api_key: The API key used to authenticate with the Dakera server. Defaults to the value of
the environment variable ``DAKERA_API_KEY``. May be ``None`` for a server that does not
require authentication.
conversation_id: The id of the conversation. Used as the Dakera ``agent_id``.
"""
base_url: str = field(
default=Factory(lambda: os.getenv("DAKERA_BASE_URL", "http://localhost:3000")),
metadata={"serializable": True},
)
api_key: str | None = field(
default=Factory(lambda: os.getenv("DAKERA_API_KEY")),
metadata={"serializable": False},
)
conversation_id: str = field(
default=Factory(lambda: uuid.uuid4().hex),
metadata={"serializable": True},
)
client: DakeraClient = field(
default=Factory(
lambda self: import_optional_dependency("dakera").DakeraClient(
base_url=self.base_url,
api_key=self.api_key,
),
takes_self=True,
),
metadata={"serializable": False},
)
@conversation_id.validator # pyright: ignore[reportAttributeAccessIssue]
def validate_conversation_id(self, _: Attribute, value: str) -> str:
if not value:
raise ValueError(f"{self.__class__.__name__} requires a non-empty conversation_id")
return value
def store(self, runs: list[Run], metadata: dict[str, Any]) -> None:
content = json.dumps(self._to_params_dict(runs, metadata))
# Replace the previous snapshot so that load() only ever returns the latest conversation state.
for memory in self.client.agent_memories(agent_id=self.conversation_id):
memory_id = memory.get("id")
if memory_id is not None:
self.client.forget(agent_id=self.conversation_id, memory_id=memory_id)
self.client.store_memory(
agent_id=self.conversation_id,
content=content,
memory_type="episodic",
importance=1.0,
)
def load(self) -> tuple[list[Run], dict[str, Any]]:
memories = self.client.agent_memories(agent_id=self.conversation_id, limit=1)
if memories:
return self._from_params_dict(json.loads(memories[0]["content"]))
return [], {}
|
api_key = field(default=Factory(lambda: os.getenv('DAKERA_API_KEY')), metadata={'serializable': False})
class-attribute
instance-attribute
base_url = field(default=Factory(lambda: os.getenv('DAKERA_BASE_URL', 'http://localhost:3000')), metadata={'serializable': True})
class-attribute
instance-attribute
client = field(default=Factory(lambda self: import_optional_dependency('dakera').DakeraClient(base_url=self.base_url, api_key=self.api_key), takes_self=True), metadata={'serializable': False})
class-attribute
instance-attribute
conversation_id = field(default=Factory(lambda: uuid.uuid4().hex), metadata={'serializable': True})
class-attribute
instance-attribute
load()
Source code in griptape/drivers/memory/conversation/dakera_conversation_memory_driver.py
| def load(self) -> tuple[list[Run], dict[str, Any]]:
memories = self.client.agent_memories(agent_id=self.conversation_id, limit=1)
if memories:
return self._from_params_dict(json.loads(memories[0]["content"]))
return [], {}
|
store(runs, metadata)
Source code in griptape/drivers/memory/conversation/dakera_conversation_memory_driver.py
| def store(self, runs: list[Run], metadata: dict[str, Any]) -> None:
content = json.dumps(self._to_params_dict(runs, metadata))
# Replace the previous snapshot so that load() only ever returns the latest conversation state.
for memory in self.client.agent_memories(agent_id=self.conversation_id):
memory_id = memory.get("id")
if memory_id is not None:
self.client.forget(agent_id=self.conversation_id, memory_id=memory_id)
self.client.store_memory(
agent_id=self.conversation_id,
content=content,
memory_type="episodic",
importance=1.0,
)
|
validate_conversation_id(_, value)
Source code in griptape/drivers/memory/conversation/dakera_conversation_memory_driver.py
| @conversation_id.validator # pyright: ignore[reportAttributeAccessIssue]
def validate_conversation_id(self, _: Attribute, value: str) -> str:
if not value:
raise ValueError(f"{self.__class__.__name__} requires a non-empty conversation_id")
return value
|