How does `read_chat_history` works if i am using custom storage?

I created a custom redis storage using agno.storage.base.Storage class. My agent uses read_chat_history=True. I want to know how does this work, since currently i am storing AgentSession in my storage which has memory attribute which is a dict with messages and other keys. Below is my code for custom redis storage.

import redis
from typing import List, Literal, Optional
from agno.storage.base import Storage
import json
from agno.storage.session import Session
from agno.storage.session.agent import AgentSession 


class RedisStorage(Storage):
    def __init__(self,host:str="localhost",port:int=6379,db:int=0,mode:Optional[Literal["agent", "team", "workflow"]] = "agent"):
        super().__init__(mode)
        self.client = redis.Redis(host=host,port=port,db=db)

    def create(self) -> None:
        try:
            self.client.ping()
            print("Connected to Redis!")
        except redis.RedisError as e:
            raise Exception("Could not connect to Redis: " + str(e))
    
    def read(self, session_id: str, user_id: Optional[str] = None) -> Optional[Session]:
        key = f"{self.mode}:session:{session_id}"
        data = self.client.get(key)
        if data:
            return AgentSession.from_dict(json.loads(data))
        return None
    
    def get_all_session_ids(self, user_id: Optional[str] = None, agent_id: Optional[str] = None) -> List[str]:
        pattern = f"{self.mode}:session:*"
        keys = self.client.keys(pattern)
        return [key.decode('utf-8').split(":")[-1] for key in keys]
    
    def get_all_sessions(self, user_id: Optional[str] = None, entity_id: Optional[str] = None) -> List[Session]:
        session_ids = self.get_all_session_ids(user_id, entity_id)
        sessions = []
        for sid in session_ids:
            session = self.read(sid)
            if session is not None:
                sessions.append(session)
        return sessions
    
    def upsert(self, session: Session) -> Optional[Session]:
        session_id = session.session_id
        if not session_id:
            raise ValueError("Session must have an 'session_id' field")
        key = f"{self.mode}:session:{session_id}"
        self.client.set(key, json.dumps(session.to_dict()))
        return session
    
    def delete_session(self, session_id: Optional[str] = None):
        if not session_id:
            raise ValueError("session_id must be provided")
        key = f"{self.mode}:session:{session_id}"
        self.client.delete(key)

    def drop(self) -> None:
        pattern = f"{self.mode}:session:*"
        keys = self.client.keys(pattern)
        if keys:
            self.client.delete(*keys)
    
    def upgrade_schema(self) -> None:
        pass

This still needs some update but for my case it does the work of storing session data.

Hi @shivamSingh

thanks for reaching out and supporting Agno. I’ve shared this with the team, we’re working through all requests one by one and will get back to you soon.
If it’s urgent, please let us know. We appreciate your patience!

Hello , i am on a time crunch to get this done so if possible can someone look into this ASAP. Thank You

Hey @shivamSingh
Sorry about that.

We will get back to you today

Thanks for quick response will wait for updates from your team

Hello @shivamSingh

Thank you for reaching out and using Agno.
I am not sure I understand what you mean when you are asking how this works. What aspect are you referring to? You also mention in your message that it does work for storing your session data. So it is not clear what exactly you need here. Please feel free to add any additional context so we can help you as quickly as possible.

If you are busy adding this into Agno, I can encourage you to raise a PR and implement it for Agent, Team and Workflow. This way we can merge it directly into the main repo for easier future use. We can also quickly then help you test your changes and help resolve any issues you encounter.

sorry for badly formatted query. I just wanted to ask if i am using a storage in my case custom redis storage and i did read_chat_history=True , add_history_to_messages=True, num_history_responses=3 will this add the last 3 entries from my redis database. I also wanted to know that i am storing AgentSession directly to the redis by converting to json using AgentSession.to_dict() is this the correct way? or do i need to store each message instead of AgentSession.? this was my main query.
Thank you

Hi @shivamSingh
In our latest release we add our own RedisStorage implementation. Please take a look!

1 Like