-
-
Notifications
You must be signed in to change notification settings - Fork 425
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update dependencies and enhance knowledge management system
- Updated the `chainlit` dependency version from `2.0.1` to `2.0.3` across multiple configurations in `pyproject.toml` and `agents/pyproject.toml` to ensure compatibility with the latest features and fixes. - Introduced a new optional dependency group `knowledge` in `agents/pyproject.toml` for enhanced knowledge management capabilities, including `mem0ai` and `markitdown`. - Refactored the `Knowledge` class in `knowledge.py` to improve initialization and memory management, allowing for better handling of user and agent identifiers. - Enhanced methods for storing, retrieving, and managing memories, including new functionalities for updating and deleting memories. - Updated UI components in `mint.json` and `realtime.py` to reflect changes in model naming conventions, improving user experience and clarity. This commit strengthens the overall functionality and usability of the PraisonAI framework, particularly in knowledge management and UI interactions.
- Loading branch information
1 parent
89c92f7
commit e121d4a
Showing
9 changed files
with
259 additions
and
124 deletions.
There are no files selected for viewing
This file contains 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,3 @@ | ||
I am Mervin Praison, a software engineer and entrepreneur. | ||
|
||
I am the founder of Praison AI, a company that is building AI agents to help people with their daily tasks. |
This file contains 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,104 @@ | ||
import logging | ||
from praisonaiagents.knowledge import Knowledge | ||
import os | ||
# Configure logging | ||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | ||
logger = logging.getLogger(__name__) | ||
|
||
config = { | ||
"vector_store": { | ||
"provider": "chroma", | ||
"config": { | ||
"collection_name": "test", | ||
"path": ".praison", | ||
} | ||
} | ||
} | ||
|
||
knowledge = Knowledge(config) | ||
|
||
# Store memories | ||
logger.info("Storing memories...") | ||
cricket_memory = knowledge.store("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"}) | ||
logger.info(f"Stored cricket memory: {cricket_memory}") | ||
tennis_memory = knowledge.store("Enjoys playing tennis with friends", user_id="alice", metadata={"category": "hobbies"}) | ||
logger.info(f"Stored tennis memory: {tennis_memory}") | ||
work_memory = knowledge.store("Works as a software engineer", user_id="alice", metadata={"category": "work"}) | ||
logger.info(f"Stored work memory: {work_memory}") | ||
|
||
print("Stored memories:") | ||
print(cricket_memory) | ||
print(tennis_memory) | ||
print(work_memory) | ||
|
||
# Retrieve all memories for a user | ||
logger.info("Retrieving all memories for Alice...") | ||
alice_memories = knowledge.get_all(user_id="alice") | ||
logger.info(f"Retrieved memories for Alice: {alice_memories}") | ||
print("\nAll memories for Alice:") | ||
for memory in alice_memories: | ||
print(memory) | ||
|
||
# Retrieve a specific memory by ID | ||
logger.info(f"Retrieving memory with ID: {cricket_memory[0]['id']}") | ||
retrieved_memory = knowledge.get(cricket_memory[0]["id"]) | ||
logger.info(f"Retrieved memory: {retrieved_memory}") | ||
print("\nRetrieved memory:") | ||
print(retrieved_memory) | ||
|
||
# Search for memories based on a query | ||
query = "What are Alice's hobbies?" | ||
logger.info(f"Searching for memories with query: {query}") | ||
search_results = knowledge.search(query, user_id="alice") | ||
logger.info(f"Search results: {search_results}") | ||
print(f"\nSearch results for '{query}':") | ||
for memory in search_results: | ||
print(memory) | ||
|
||
# Update a memory | ||
logger.info(f"Updating memory with ID: {tennis_memory[0]['id']}") | ||
updated_memory = knowledge.update(memory_id=tennis_memory[0]["id"], data="Loves playing tennis on weekends") | ||
logger.info(f"Updated memory: {updated_memory}") | ||
print("\nUpdated memory:") | ||
print(updated_memory) | ||
|
||
# Get memory history | ||
logger.info(f"Retrieving memory history for ID: {tennis_memory[0]['id']}") | ||
memory_history = knowledge.history(memory_id=tennis_memory[0]["id"]) | ||
logger.info(f"Memory history: {memory_history}") | ||
print("\nMemory history:") | ||
for entry in memory_history: | ||
print(entry) | ||
|
||
# Delete a memory | ||
logger.info(f"Deleting memory with ID: {work_memory[0]['id']}") | ||
knowledge.delete(memory_id=work_memory[0]["id"]) | ||
logger.info("Memory deleted") | ||
print("\nDeleted memory") | ||
|
||
# Retrieve memories after deletion | ||
logger.info("Retrieving memories after deletion...") | ||
alice_memories = knowledge.get_all(user_id="alice") | ||
logger.info(f"Retrieved memories after deletion: {alice_memories}") | ||
print("\nMemories after deletion:") | ||
for memory in alice_memories: | ||
print(memory) | ||
|
||
# Delete all memories for a user | ||
logger.info("Deleting all memories for Alice...") | ||
knowledge.delete_all(user_id="alice") | ||
logger.info("All memories for Alice deleted") | ||
print("\nAll memories for Alice deleted") | ||
|
||
# Retrieve memories after deleting all | ||
logger.info("Retrieving memories after deleting all...") | ||
alice_memories = knowledge.get_all(user_id="alice") | ||
logger.info(f"Retrieved memories after deleting all: {alice_memories}") | ||
print("\nMemories after deleting all:") | ||
print(alice_memories) | ||
|
||
# Reset all memories | ||
logger.info("Resetting all memories...") | ||
knowledge.reset() | ||
logger.info("All memories reset") | ||
print("\nAll memories reset") |
This file contains 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 |
---|---|---|
@@ -1,119 +1,128 @@ | ||
# knowledge.py | ||
""" | ||
PraisonAI Knowledge - Advanced knowledge management system with configurable features | ||
""" | ||
|
||
import os | ||
from typing import Any, Dict, List, Optional, Union | ||
from pathlib import Path | ||
|
||
try: | ||
from mem0.memory.main import Memory, MemoryConfig | ||
except ImportError: | ||
print("PraisonAI Knowledge requires additional dependencies.") | ||
print("Please install with: pip install 'praisonai[knowledge]'") | ||
sys.exit(1) | ||
|
||
class Knowledge: | ||
"""Advanced knowledge management system with configurable storage and search capabilities""" | ||
|
||
def __init__( | ||
self, | ||
user_id: str, | ||
agent_id: Optional[str] = None, | ||
run_id: Optional[str] = None, | ||
config: Optional[Dict[str, Any]] = None, | ||
vector_store: str = "chroma", | ||
embedder: str = "openai", | ||
use_graph: bool = False, | ||
): | ||
"""Initialize knowledge system with flexible configuration | ||
def __init__(self, config=None): | ||
try: | ||
from mem0 import Memory | ||
except ImportError: | ||
raise ImportError( | ||
"knowledge is not installed. Please install it using: " | ||
'pip install "praisonaiagents[knowledge]"' | ||
) | ||
|
||
Args: | ||
user_id: Unique identifier for the user/organization | ||
agent_id: Optional agent identifier for multi-agent systems | ||
run_id: Optional run identifier for tracking sessions | ||
config: Custom configuration override | ||
vector_store: Vector store provider ("chroma", "qdrant", "pgvector", etc.) | ||
embedder: Embedding provider ("openai", "huggingface", etc.) | ||
use_graph: Enable graph capabilities | ||
""" | ||
self.user_id = user_id | ||
self.agent_id = agent_id | ||
self.run_id = run_id | ||
|
||
# Build optimized configuration | ||
memory_config = config or { | ||
self.config = config or { | ||
"vector_store": { | ||
"provider": vector_store, | ||
"config": { | ||
"collection_name": "praison_knowledge", | ||
"path": ".praison/knowledge", | ||
} | ||
}, | ||
"embedder": { | ||
"provider": embedder, | ||
"provider": "chroma", | ||
"config": { | ||
"model": "text-embedding-3-small" | ||
"collection_name": "test", | ||
"path": ".praison", | ||
} | ||
}, | ||
"version": "v1.0" | ||
} | ||
} | ||
|
||
# Add graph capabilities if enabled | ||
if use_graph: | ||
memory_config.update({ | ||
"graph_store": { | ||
"provider": "neo4j", | ||
"config": { | ||
"url": os.getenv("PRAISON_GRAPH_URL", "bolt://localhost:7687"), | ||
"username": os.getenv("PRAISON_GRAPH_USER", "neo4j"), | ||
"password": os.getenv("PRAISON_GRAPH_PASSWORD", "password") | ||
} | ||
}, | ||
"version": "v1.1" | ||
}) | ||
|
||
self._store = Memory(MemoryConfig(**memory_config)) | ||
|
||
def add(self, content: Union[str, Path], metadata: Optional[Dict] = None) -> None: | ||
"""Add knowledge content with optional metadata""" | ||
if isinstance(content, Path): | ||
content = content.read_text(encoding="utf-8") | ||
m = Memory.from_config(self.config) | ||
self.memory = m | ||
|
||
def store(self, content, user_id=None, agent_id=None, run_id=None, metadata=None): | ||
""" | ||
Store a memory. | ||
Args: | ||
content (str): The content of the memory. | ||
user_id (str, optional): The user ID associated with the memory. | ||
agent_id (str, optional): The agent ID associated with the memory. | ||
run_id (str, optional): The run ID associated with the memory. | ||
metadata (dict, optional): Additional metadata for the memory. | ||
Returns: | ||
dict: The result of storing the memory. | ||
""" | ||
return self.memory.add(content, user_id=user_id, agent_id=agent_id, run_id=run_id, metadata=metadata) | ||
|
||
def get_all(self, user_id=None, agent_id=None, run_id=None): | ||
""" | ||
Retrieve all memories. | ||
Args: | ||
user_id (str, optional): The user ID to filter memories by. | ||
agent_id (str, optional): The agent ID to filter memories by. | ||
run_id (str, optional): The run ID to filter memories by. | ||
Returns: | ||
list: All memories matching the specified filters. | ||
""" | ||
return self.memory.get_all(user_id=user_id, agent_id=agent_id, run_id=run_id) | ||
|
||
def get(self, memory_id): | ||
""" | ||
Retrieve a specific memory by ID. | ||
Args: | ||
memory_id (str): The ID of the memory to retrieve. | ||
Returns: | ||
dict: The retrieved memory. | ||
""" | ||
return self.memory.get(memory_id) | ||
|
||
def search(self, query, user_id=None, agent_id=None, run_id=None): | ||
""" | ||
Search for memories related to a query. | ||
Args: | ||
query (str): The search query. | ||
user_id (str, optional): The user ID to filter memories by. | ||
agent_id (str, optional): The agent ID to filter memories by. | ||
run_id (str, optional): The run ID to filter memories by. | ||
Returns: | ||
list: Memories related to the search query. | ||
""" | ||
return self.memory.search(query, user_id=user_id, agent_id=agent_id, run_id=run_id) | ||
|
||
def update(self, memory_id, data): | ||
""" | ||
Update a memory. | ||
self._store.add( | ||
messages=[{"role": "user", "content": content}], | ||
user_id=self.user_id, | ||
agent_id=self.agent_id, | ||
run_id=self.run_id, | ||
metadata=metadata or {} | ||
) | ||
|
||
def search(self, query: str, limit: int = 5) -> List[Dict[str, Any]]: | ||
"""Search knowledge using semantic understanding""" | ||
results = self._store.search( | ||
query=query, | ||
user_id=self.user_id, | ||
agent_id=self.agent_id, | ||
run_id=self.run_id, | ||
limit=limit | ||
) | ||
return results.get("results", results) | ||
|
||
def delete(self) -> None: | ||
"""Delete knowledge for current context""" | ||
self._store.delete_all( | ||
user_id=self.user_id, | ||
agent_id=self.agent_id, | ||
run_id=self.run_id | ||
) | ||
|
||
def list(self, limit: int = 100) -> List[Dict[str, Any]]: | ||
"""List all knowledge entries""" | ||
results = self._store.get_all( | ||
user_id=self.user_id, | ||
agent_id=self.agent_id, | ||
run_id=self.run_id, | ||
limit=limit | ||
) | ||
return results.get("results", results) | ||
Args: | ||
memory_id (str): The ID of the memory to update. | ||
data (str): The updated content of the memory. | ||
Returns: | ||
dict: The result of updating the memory. | ||
""" | ||
return self.memory.update(memory_id, data) | ||
|
||
def history(self, memory_id): | ||
""" | ||
Get the history of changes for a memory. | ||
Args: | ||
memory_id (str): The ID of the memory. | ||
Returns: | ||
list: The history of changes for the memory. | ||
""" | ||
return self.memory.history(memory_id) | ||
|
||
def delete(self, memory_id): | ||
""" | ||
Delete a memory. | ||
Args: | ||
memory_id (str): The ID of the memory to delete. | ||
""" | ||
self.memory.delete(memory_id) | ||
|
||
def delete_all(self, user_id=None, agent_id=None, run_id=None): | ||
""" | ||
Delete all memories. | ||
Args: | ||
user_id (str, optional): The user ID to filter memories by. | ||
agent_id (str, optional): The agent ID to filter memories by. | ||
run_id (str, optional): The run ID to filter memories by. | ||
""" | ||
self.memory.delete_all(user_id=user_id, agent_id=agent_id, run_id=run_id) | ||
|
||
def reset(self): | ||
"""Reset all memories.""" | ||
self.memory.reset() |
This file contains 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 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 @@ | ||
# Sample Markdown | ||
## Section 1 | ||
This is a test markdown file. | ||
## Section 2 | ||
It contains some formatted text and sections. |
This file contains 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,3 @@ | ||
This is a sample text file. | ||
It contains multiple lines. | ||
This is for testing purposes. |
This file contains 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 |
---|---|---|
|
@@ -228,8 +228,7 @@ | |
"ui/streamlit", | ||
"ui/ui", | ||
"ui/chat", | ||
"ui/code", | ||
"ui/realtime" | ||
"ui/code" | ||
] | ||
}, | ||
{ | ||
|
Oops, something went wrong.