-
Notifications
You must be signed in to change notification settings - Fork 62
Introduce the LLM session manager classes #141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 38 commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
26c656b
wip: defining base session manager class methods
justin-cechmanek 872e0fe
removes base session manager parent class
justin-cechmanek 65177b2
adds proposed schema to sesssion manager description
justin-cechmanek ebc07d6
adds session manager init
justin-cechmanek 9dbc928
wip: minimal working session manager
justin-cechmanek bb467c2
wip: adding full conversation history, and cleans up scoping
justin-cechmanek 4ed6208
minor clean up
justin-cechmanek 2c5c52a
wip: initial notebook demo on semantic session manager
justin-cechmanek 4d0b9ce
wip: continues session manager work
justin-cechmanek ba2575a
cleans up first session manager notebook
justin-cechmanek 5fda1ec
makes scope configurable on each call to fetch_context
justin-cechmanek 37ae270
improves scope settings
justin-cechmanek 4e432a4
adds notebook example of controling session access scope
justin-cechmanek 3d404e7
formatting
justin-cechmanek c20d23e
mypy formatting
justin-cechmanek 29b4a05
black formatting
justin-cechmanek e612195
bumps notebook number
justin-cechmanek 45427ad
corrects method name
justin-cechmanek d9aacf9
sets an asymetric retrieval model as default vectorizer
justin-cechmanek 3a117eb
Merge branch 'main' into jc/semantic-session-manager
justin-cechmanek f99967f
moves recency sorting into Redis query
justin-cechmanek 5d4f34b
adds session manager notebook examples to index
justin-cechmanek dff924c
wip:refactor into multiple classes
justin-cechmanek c8b9325
Merge branch 'main' into jc/semantic-session-manager
justin-cechmanek 6e8ca02
refactors session managers into multiple classes
justin-cechmanek 90cfe59
adds tests for session managers
justin-cechmanek b2e80b5
removes redundant notebook
justin-cechmanek d898941
formatting
justin-cechmanek 46fb9b5
formatting
justin-cechmanek 58be5b7
fixes failing test
justin-cechmanek ce09632
changes user_id, session_id to user_tag, session_tag. Adds pydantic v…
justin-cechmanek d32b12e
makes system preamble fully optional, empty if not set
justin-cechmanek a5fb413
renames methods & properties to align with OpenAI and LangChain
justin-cechmanek c683532
changes session managers to match langchain chat history api
justin-cechmanek d666fad
adds messages property to match langchain
justin-cechmanek 158eb52
adds test coverage for messages property
justin-cechmanek 60a1a00
adds optional tool message type
justin-cechmanek 85ba8d0
Merge branch 'main' into jc/semantic-session-manager
justin-cechmanek 241199e
Bugfix in setting vectorizer. Uses index key_separator
justin-cechmanek 5c5a385
updates doc strings
justin-cechmanek a0d0a21
empty arrary is returned when top_k=0
justin-cechmanek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,5 +17,6 @@ llmcache_03 | |
| vectorizers_04 | ||
| hash_vs_json_05 | ||
| rerankers_06 | ||
| session_manager_07 | ||
| ``` | ||
|
|
||
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| from redisvl.extensions.session_manager.base_session import BaseSessionManager | ||
| from redisvl.extensions.session_manager.semantic_session import SemanticSessionManager | ||
| from redisvl.extensions.session_manager.standard_session import StandardSessionManager | ||
|
|
||
| __all__ = ["BaseSessionManager", "StandardSessionManager", "SemanticSessionManager"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| from typing import Any, Dict, List, Optional, Union | ||
|
|
||
| from redis import Redis | ||
|
|
||
|
|
||
| class BaseSessionManager: | ||
| id_field_name: str = "id_field" | ||
| role_field_name: str = "role" | ||
| content_field_name: str = "content" | ||
| tool_field_name: str = "tool_call_id" | ||
| timestamp_field_name: str = "timestamp" | ||
|
|
||
| def __init__( | ||
| self, | ||
| name: str, | ||
| session_tag: str, | ||
| user_tag: str, | ||
| ): | ||
| """Initialize session memory with index | ||
|
|
||
| Session Manager stores the current and previous user text prompts and | ||
| LLM responses to allow for enriching future prompts with session | ||
| context. Session history is stored in prompt:response pairs referred to | ||
| as exchanges. | ||
|
|
||
| Args: | ||
| name (str): The name of the session manager index. | ||
| session_tag (str): Tag to be added to entries to link to a specific | ||
| session. | ||
| user_tag (str): Tag to be added to entries to link to a specific user. | ||
| """ | ||
| self._name = name | ||
| self._user_tag = user_tag | ||
| self._session_tag = session_tag | ||
|
|
||
| def set_scope( | ||
| self, | ||
| session_tag: Optional[str] = None, | ||
| user_tag: Optional[str] = None, | ||
| ) -> None: | ||
| """Set the filter to apply to querries based on the desired scope. | ||
|
|
||
| This new scope persists until another call to set_scope is made, or if | ||
| scope specified in calls to get_recent. | ||
|
|
||
| Args: | ||
| session_tag (str): Id of the specific session to filter to. Default is | ||
| None. | ||
| user_tag (str): Id of the specific user to filter to. Default is None. | ||
| """ | ||
| raise NotImplementedError | ||
|
|
||
| def clear(self) -> None: | ||
| """Clears the chat session history.""" | ||
| raise NotImplementedError | ||
|
|
||
| def delete(self) -> None: | ||
| """Clear all conversation history and remove any search indices.""" | ||
| raise NotImplementedError | ||
|
|
||
| def drop(self, id_field: Optional[str] = None) -> None: | ||
| """Remove a specific exchange from the conversation history. | ||
|
|
||
| Args: | ||
| id_field Optional[str]: The id_field of the entry to delete. | ||
| If None then the last entry is deleted. | ||
| """ | ||
| raise NotImplementedError | ||
|
|
||
| @property | ||
| def messages(self) -> Union[List[str], List[Dict[str, str]]]: | ||
| """Returns the full chat history.""" | ||
| raise NotImplementedError | ||
|
|
||
| def get_recent( | ||
| self, | ||
| top_k: int = 5, | ||
| session_tag: Optional[str] = None, | ||
| user_tag: Optional[str] = None, | ||
| as_text: bool = False, | ||
| raw: bool = False, | ||
| ) -> Union[List[str], List[Dict[str, str]]]: | ||
| """Retreive the recent conversation history in sequential order. | ||
|
|
||
| Args: | ||
| top_k (int): The number of previous exchanges to return. Default is 5. | ||
| Note that one exchange contains both a prompt and response. | ||
| session_tag (str): Tag to be added to entries to link to a specific | ||
| session. | ||
| user_tag (str): Tag to be added to entries to link to a specific user. | ||
| as_text (bool): Whether to return the conversation as a single string, | ||
| or list of alternating prompts and responses. | ||
| raw (bool): Whether to return the full Redis hash entry or just the | ||
| prompt and response | ||
|
|
||
| Returns: | ||
| Union[str, List[str]]: A single string transcription of the session | ||
| or list of strings if as_text is false. | ||
|
|
||
| Raises: | ||
| ValueError: If top_k is not an integer greater than or equal to 0. | ||
| """ | ||
| raise NotImplementedError | ||
|
|
||
| def _format_context( | ||
| self, hits: List[Dict[str, Any]], as_text: bool | ||
| ) -> Union[List[str], List[Dict[str, str]]]: | ||
| """Extracts the prompt and response fields from the Redis hashes and | ||
| formats them as either flat dictionaries oor strings. | ||
justin-cechmanek marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Args: | ||
| hits (List): The hashes containing prompt & response pairs from | ||
| recent conversation history. | ||
| as_text (bool): Whether to return the conversation as a single string, | ||
| or list of alternating prompts and responses. | ||
| Returns: | ||
| Union[str, List[str]]: A single string transcription of the session | ||
| or list of strings if as_text is false. | ||
| """ | ||
| if as_text: | ||
| text_statements = [] | ||
| for hit in hits: | ||
| text_statements.append(hit[self.content_field_name]) | ||
| return text_statements | ||
| else: | ||
| statements = [] | ||
| for hit in hits: | ||
| statements.append( | ||
| { | ||
| self.role_field_name: hit[self.role_field_name], | ||
| self.content_field_name: hit[self.content_field_name], | ||
| } | ||
| ) | ||
| if ( | ||
| hasattr(hit, self.tool_field_name) | ||
| or isinstance(hit, dict) | ||
| and self.tool_field_name in hit | ||
| ): | ||
| statements[-1].update( | ||
| {self.tool_field_name: hit[self.tool_field_name]} | ||
| ) | ||
| return statements | ||
|
|
||
| def store(self, prompt: str, response: str) -> None: | ||
| """Insert a prompt:response pair into the session memory. A timestamp | ||
| is associated with each exchange so that they can be later sorted | ||
| in sequential ordering after retrieval. | ||
|
|
||
| Args: | ||
| prompt (str): The user prompt to the LLM. | ||
| response (str): The corresponding LLM response. | ||
| """ | ||
| raise NotImplementedError | ||
|
|
||
| def add_messages(self, messages: List[Dict[str, str]]) -> None: | ||
| """Insert a list of prompts and responses into the session memory. | ||
| A timestamp is associated with each so that they can be later sorted | ||
| in sequential ordering after retrieval. | ||
|
|
||
| Args: | ||
| messages (List[Dict[str, str]]): The list of user prompts and LLM responses. | ||
| """ | ||
| raise NotImplementedError | ||
|
|
||
| def add_message(self, message: Dict[str, str]) -> None: | ||
| """Insert a single prompt or response into the session memory. | ||
| A timestamp is associated with it so that it can be later sorted | ||
| in sequential ordering after retrieval. | ||
|
|
||
| Args: | ||
| message (Dict[str,str]): The user prompt or LLM response. | ||
| """ | ||
| raise NotImplementedError | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.