mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-08 17:31:00 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe4550d2bc | ||
|
|
db09a94425 | ||
|
|
2db36dc932 |
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN pip install flask praisonai==2.0.53 gunicorn markdown
|
||||
RUN pip install flask praisonai==2.0.54 gunicorn markdown
|
||||
EXPOSE 8080
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
|
||||
@@ -1,6 +1,7 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
import logging
|
||||
import os
|
||||
import json
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
@@ -8,11 +9,29 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# Define the configuration for the Knowledge instance
|
||||
config = {
|
||||
"version": "v1.1",
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "knowledge_test",
|
||||
"path": ".praison",
|
||||
"collection_name": "praison",
|
||||
"path": os.path.abspath("./.praison"),
|
||||
"host": None,
|
||||
"port": None
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"embedding_dims": 1536
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0,
|
||||
"max_tokens": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,17 +42,20 @@ knowledge_agent = Agent(
|
||||
role="Information Specialist",
|
||||
goal="Store and retrieve knowledge efficiently",
|
||||
backstory="Expert in managing and utilizing stored knowledge",
|
||||
knowledge=["sample.pdf"],
|
||||
knowledge_config=config,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Define a task for the agent
|
||||
knowledge_task = Task(
|
||||
name="knowledge_task",
|
||||
description="Who is Mervin Praison?",
|
||||
description="KAG",
|
||||
expected_output="Answer to the question",
|
||||
agent=knowledge_agent
|
||||
agent=knowledge_agent,
|
||||
context=[
|
||||
{
|
||||
"embedding_db_config": json.dumps(config["vector_store"])
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
# Create and start the agents
|
||||
|
||||
@@ -4,7 +4,7 @@ config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "custom_knowledge",
|
||||
"collection_name": "praison",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,8 @@ agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["large.pdf"],
|
||||
knowledge_config=config
|
||||
knowledge_config=config,
|
||||
user_id="user1"
|
||||
)
|
||||
|
||||
agent.start("What is KAG in one line?")
|
||||
@@ -0,0 +1,44 @@
|
||||
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 = {
|
||||
"version": "v1.1",
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": os.path.abspath("./.praison"),
|
||||
"host": None,
|
||||
"port": None
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"embedding_dims": 1536
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0,
|
||||
"max_tokens": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
knowledge = Knowledge(config)
|
||||
|
||||
# Search for memories based on a query
|
||||
query = "KAG"
|
||||
logger.info(f"Searching for memories with query: {query}")
|
||||
search_results = knowledge.search(query, user_id="user1")
|
||||
logger.info(f"Search results: {search_results}")
|
||||
print(f"\nSearch results for '{query}':")
|
||||
print(search_results)
|
||||
@@ -0,0 +1,220 @@
|
||||
from mem0 import Memory
|
||||
import logging
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class MemoryManager:
|
||||
def __init__(self):
|
||||
"""Initialize Mem0 Memory manager with configuration"""
|
||||
# Define the complete configuration with only supported fields
|
||||
config = {
|
||||
"version": "v1.1",
|
||||
"custom_prompt": None,
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": os.path.abspath("./.praison/storage"),
|
||||
"host": None,
|
||||
"port": None
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"embedding_dims": 1536
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0,
|
||||
"max_tokens": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Ensure storage directory exists
|
||||
storage_path = os.path.abspath("./.praison/storage")
|
||||
if os.path.exists(storage_path):
|
||||
logger.info(f"Clearing existing storage at {storage_path}")
|
||||
import shutil
|
||||
shutil.rmtree(storage_path)
|
||||
os.makedirs(storage_path, exist_ok=True)
|
||||
logger.info(f"Created storage path: {storage_path}")
|
||||
|
||||
# Initialize memory
|
||||
self.memory = Memory.from_config(config)
|
||||
logger.info("Memory manager initialized")
|
||||
|
||||
def pretty_print(self, data: Any) -> None:
|
||||
"""Helper function to print memory data in a readable format"""
|
||||
if isinstance(data, (dict, list)):
|
||||
print(json.dumps(data, indent=2))
|
||||
else:
|
||||
print(data)
|
||||
|
||||
def extract_memory_id(self, result: Any) -> Optional[str]:
|
||||
"""Extract memory ID from the result, handling different formats"""
|
||||
try:
|
||||
if isinstance(result, dict):
|
||||
# v1.1 format
|
||||
memories = result.get('results', [])
|
||||
return memories[0]['id'] if memories else None
|
||||
elif isinstance(result, list):
|
||||
# v1.0 format
|
||||
return result[0]['id'] if result else None
|
||||
return None
|
||||
except (KeyError, IndexError) as e:
|
||||
logger.warning(f"Could not extract memory ID from result: {e}")
|
||||
return None
|
||||
|
||||
def prepare_metadata(self, metadata: Optional[Dict]) -> Dict:
|
||||
"""Prepare metadata by converting values to acceptable types"""
|
||||
if not metadata:
|
||||
return {}
|
||||
|
||||
clean_metadata = {}
|
||||
for key, value in metadata.items():
|
||||
if isinstance(value, (str, int, float, bool)):
|
||||
clean_metadata[key] = value
|
||||
elif isinstance(value, list):
|
||||
clean_metadata[key] = ','.join(map(str, value))
|
||||
elif isinstance(value, dict):
|
||||
clean_metadata[key] = json.dumps(value)
|
||||
else:
|
||||
clean_metadata[key] = str(value)
|
||||
return clean_metadata
|
||||
|
||||
def verify_memory_addition(self, user_id: str, max_retries: int = 3) -> bool:
|
||||
"""Verify that memory was added successfully"""
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
time.sleep(0.5) # Brief pause to allow indexing
|
||||
memories = self.memory.get_all(user_id=user_id)
|
||||
if len(memories.get('results', [])) > 0:
|
||||
return True
|
||||
logger.warning(f"Memory not found on attempt {attempt + 1}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Verification attempt {attempt + 1} failed: {e}")
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(1)
|
||||
return False
|
||||
|
||||
def add_memory(self, text: str, user_id: Optional[str] = None, metadata: Optional[Dict] = None) -> Dict:
|
||||
"""Add a new memory with error handling and verification"""
|
||||
try:
|
||||
logger.info(f"Adding memory for user {user_id}")
|
||||
clean_metadata = self.prepare_metadata(metadata)
|
||||
logger.debug(f"Prepared metadata: {clean_metadata}")
|
||||
|
||||
messages = [{"role": "user", "content": text}]
|
||||
result = self.memory.add(
|
||||
messages=messages,
|
||||
user_id=user_id,
|
||||
metadata=clean_metadata
|
||||
)
|
||||
|
||||
if self.verify_memory_addition(user_id):
|
||||
logger.info("Memory added and verified successfully")
|
||||
else:
|
||||
logger.warning("Memory addition could not be verified")
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to add memory: {str(e)}")
|
||||
raise
|
||||
|
||||
def get_all_memories(self, user_id: Optional[str] = None) -> Dict:
|
||||
"""Retrieve all memories for a user"""
|
||||
try:
|
||||
logger.info(f"Retrieving all memories for user {user_id}")
|
||||
memories = self.memory.get_all(user_id=user_id)
|
||||
count = len(memories.get('results', []))
|
||||
logger.info(f"Retrieved {count} memories")
|
||||
return memories
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to retrieve memories: {str(e)}")
|
||||
raise
|
||||
|
||||
def search_memories(self, query: str, user_id: Optional[str] = None, limit: int = 5) -> Dict:
|
||||
"""Search memories with a query"""
|
||||
try:
|
||||
logger.info(f"Searching memories with query: {query}")
|
||||
results = self.memory.search(
|
||||
query=query,
|
||||
user_id=user_id,
|
||||
limit=limit
|
||||
)
|
||||
count = len(results.get('results', []))
|
||||
logger.info(f"Found {count} matching memories")
|
||||
return results
|
||||
except Exception as e:
|
||||
logger.error(f"Search failed: {str(e)}")
|
||||
raise
|
||||
|
||||
def main():
|
||||
try:
|
||||
# Initialize memory manager
|
||||
manager = MemoryManager()
|
||||
|
||||
# Add a test memory
|
||||
print("\n1. Adding a new memory:")
|
||||
metadata = {
|
||||
"category": "hobbies",
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"tags": "tennis,learning",
|
||||
"priority": 1,
|
||||
"source": "user_input"
|
||||
}
|
||||
|
||||
result = manager.add_memory(
|
||||
text="I am working on improving my tennis skills. Suggest some online courses.",
|
||||
user_id="alice",
|
||||
metadata=metadata
|
||||
)
|
||||
manager.pretty_print(result)
|
||||
|
||||
# Wait briefly for indexing
|
||||
time.sleep(1)
|
||||
|
||||
print("\n2. Retrieving all memories:")
|
||||
all_memories = manager.get_all_memories(user_id="alice")
|
||||
manager.pretty_print(all_memories)
|
||||
|
||||
print("\n3. Searching memories:")
|
||||
search_results = manager.search_memories(
|
||||
query="What are Alice's hobbies?",
|
||||
user_id="alice",
|
||||
limit=5
|
||||
)
|
||||
manager.pretty_print(search_results)
|
||||
|
||||
# Print summary
|
||||
print("\nMemory Store Summary:")
|
||||
total_memories = len(all_memories.get('results', []))
|
||||
print(f"Total memories stored: {total_memories}")
|
||||
if total_memories > 0:
|
||||
print("Available memories:")
|
||||
for mem in all_memories['results']:
|
||||
print(f"- {mem.get('memory', 'No content')}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Main process failed: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,143 @@
|
||||
from mem0 import Memory
|
||||
import logging
|
||||
import json
|
||||
import os
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class MemorySearcher:
|
||||
def __init__(self):
|
||||
"""Initialize Mem0 Memory searcher with configuration"""
|
||||
# Define the configuration
|
||||
config = {
|
||||
"version": "v1.1",
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": os.path.abspath("./.praison/storage"),
|
||||
"host": None,
|
||||
"port": None
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"embedding_dims": 1536
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0,
|
||||
"max_tokens": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Initialize memory
|
||||
self.memory = Memory.from_config(config)
|
||||
logger.info("Memory searcher initialized")
|
||||
|
||||
def pretty_print(self, data: Any) -> None:
|
||||
"""Helper function to print data in a readable format"""
|
||||
if isinstance(data, (dict, list)):
|
||||
print(json.dumps(data, indent=2))
|
||||
else:
|
||||
print(data)
|
||||
|
||||
def get_all_memories(self, user_id: Optional[str] = None) -> Dict:
|
||||
"""Retrieve all memories for a user"""
|
||||
try:
|
||||
logger.info(f"Retrieving all memories for user {user_id}")
|
||||
memories = self.memory.get_all(user_id=user_id)
|
||||
count = len(memories.get('results', []))
|
||||
logger.info(f"Retrieved {count} memories")
|
||||
return memories
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to retrieve memories: {str(e)}")
|
||||
raise
|
||||
|
||||
def search_memories(self, query: str, user_id: Optional[str] = None, limit: int = 5) -> Dict:
|
||||
"""Search memories with a query"""
|
||||
try:
|
||||
logger.info(f"Searching memories with query: {query}")
|
||||
results = self.memory.search(
|
||||
query=query,
|
||||
user_id=user_id,
|
||||
limit=limit
|
||||
)
|
||||
count = len(results.get('results', []))
|
||||
logger.info(f"Found {count} matching memories")
|
||||
return results
|
||||
except Exception as e:
|
||||
logger.error(f"Search failed: {str(e)}")
|
||||
raise
|
||||
|
||||
def list_unique_users(self) -> list:
|
||||
"""List all unique users in the memory store"""
|
||||
try:
|
||||
all_memories = self.memory.get_all()
|
||||
users = set()
|
||||
for memory in all_memories.get('results', []):
|
||||
if 'user_id' in memory:
|
||||
users.add(memory['user_id'])
|
||||
return sorted(list(users))
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to list users: {str(e)}")
|
||||
raise
|
||||
|
||||
def main():
|
||||
try:
|
||||
# Initialize memory searcher
|
||||
searcher = MemorySearcher()
|
||||
|
||||
# Get list of users
|
||||
print("\n1. Available users in the memory store:")
|
||||
users = searcher.list_unique_users()
|
||||
searcher.pretty_print(users)
|
||||
|
||||
if not users:
|
||||
print("No users found in the memory store. Please add some memories first.")
|
||||
return
|
||||
|
||||
# Example user (using first user found)
|
||||
example_user = users[0]
|
||||
|
||||
print(f"\n2. All memories for user '{example_user}':")
|
||||
all_memories = searcher.get_all_memories(user_id=example_user)
|
||||
searcher.pretty_print(all_memories)
|
||||
|
||||
print(f"\n3. Searching memories for user '{example_user}':")
|
||||
search_results = searcher.search_memories(
|
||||
query="What are their hobbies?",
|
||||
user_id=example_user,
|
||||
limit=5
|
||||
)
|
||||
searcher.pretty_print(search_results)
|
||||
|
||||
# Print summary
|
||||
print("\nMemory Store Summary:")
|
||||
total_memories = len(all_memories.get('results', []))
|
||||
print(f"Total memories for {example_user}: {total_memories}")
|
||||
if total_memories > 0:
|
||||
print("Available memories:")
|
||||
for mem in all_memories['results']:
|
||||
print(f"- {mem.get('memory', 'No content')}")
|
||||
if 'metadata' in mem:
|
||||
print(f" Metadata: {mem['metadata']}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Main process failed: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,26 @@
|
||||
from mem0 import Memory
|
||||
import os
|
||||
import json
|
||||
|
||||
# Basic configuration
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Initialize memory
|
||||
memory = Memory.from_config(config)
|
||||
|
||||
# Search Alice's hobbies
|
||||
search_results = memory.search(
|
||||
query="KAG",
|
||||
user_id="user1",
|
||||
limit=5
|
||||
)
|
||||
|
||||
print(search_results)
|
||||
@@ -0,0 +1,46 @@
|
||||
from mem0 import Memory
|
||||
import os
|
||||
import json
|
||||
|
||||
# Basic configuration
|
||||
config = {
|
||||
"version": "v1.1",
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": os.path.abspath("./.praison/storage")
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small"
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Initialize memory
|
||||
memory = Memory.from_config(config)
|
||||
|
||||
# Search Alice's hobbies
|
||||
search_results = memory.search(
|
||||
query="What are Alice's hobbies?",
|
||||
user_id="alice",
|
||||
limit=5
|
||||
)
|
||||
|
||||
# Print results in a readable format
|
||||
print("\nAlice's Memories:")
|
||||
for memory in search_results['results']:
|
||||
print(f"\nMemory: {memory['memory']}")
|
||||
print(f"Score: {memory['score']}")
|
||||
if 'metadata' in memory:
|
||||
print("Metadata:")
|
||||
print(json.dumps(memory['metadata'], indent=2))
|
||||
@@ -50,7 +50,7 @@ class PraisonAIAgents:
|
||||
raise ValueError("At least one agent must be provided")
|
||||
|
||||
self.run_id = str(uuid.uuid4()) # Auto-generate run_id
|
||||
self.user_id = user_id # Optional user_id
|
||||
self.user_id = user_id or "praison" # Optional user_id
|
||||
self.max_iter = max_iter # Add max_iter parameter
|
||||
|
||||
# Pass user_id to each agent
|
||||
@@ -245,6 +245,24 @@ Expected Output: {task.expected_output}.
|
||||
context_results.append(
|
||||
f"Previous task {context_item.name if context_item.name else context_item.description} has no result yet."
|
||||
)
|
||||
elif isinstance(context_item, dict) and "vector_store" in context_item:
|
||||
from ..knowledge.knowledge import Knowledge
|
||||
try:
|
||||
# Handle both string and dict configs
|
||||
cfg = context_item["vector_store"]
|
||||
if isinstance(cfg, str):
|
||||
cfg = json.loads(cfg)
|
||||
|
||||
knowledge = Knowledge(config={"vector_store": cfg}, verbose=self.verbose)
|
||||
|
||||
# Only use user_id as filter
|
||||
db_results = knowledge.search(
|
||||
task.description,
|
||||
user_id=self.user_id if self.user_id else None
|
||||
)
|
||||
context_results.append(f"[DB Context]: {str(db_results)}")
|
||||
except Exception as e:
|
||||
context_results.append(f"[Vector DB Error]: {e}")
|
||||
|
||||
# Join unique context results
|
||||
unique_contexts = list(dict.fromkeys(context_results)) # Remove duplicates
|
||||
@@ -523,6 +541,24 @@ Expected Output: {task.expected_output}.
|
||||
context_results.append(
|
||||
f"Previous task {context_item.name if context_item.name else context_item.description} has no result yet."
|
||||
)
|
||||
elif isinstance(context_item, dict) and "vector_store" in context_item:
|
||||
from ..knowledge.knowledge import Knowledge
|
||||
try:
|
||||
# Handle both string and dict configs
|
||||
cfg = context_item["vector_store"]
|
||||
if isinstance(cfg, str):
|
||||
cfg = json.loads(cfg)
|
||||
|
||||
knowledge = Knowledge(config={"vector_store": cfg}, verbose=self.verbose)
|
||||
|
||||
# Only use user_id as filter
|
||||
db_results = knowledge.search(
|
||||
task.description,
|
||||
user_id=self.user_id if self.user_id else None
|
||||
)
|
||||
context_results.append(f"[DB Context]: {str(db_results)}")
|
||||
except Exception as e:
|
||||
context_results.append(f"[Vector DB Error]: {e}")
|
||||
|
||||
# Join unique context results
|
||||
unique_contexts = list(dict.fromkeys(context_results)) # Remove duplicates
|
||||
|
||||
@@ -84,8 +84,8 @@ class Knowledge:
|
||||
|
||||
@cached_property
|
||||
def config(self):
|
||||
# Generate unique collection name for each instance
|
||||
collection_name = f"test_{int(time.time())}_{str(uuid.uuid4())[:8]}"
|
||||
# Generate unique collection name for each instance (only if not provided in config)
|
||||
default_collection = f"test_{int(time.time())}_{str(uuid.uuid4())[:8]}"
|
||||
persist_dir = ".praison"
|
||||
|
||||
# Create persistent client config
|
||||
@@ -93,9 +93,11 @@ class Knowledge:
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": collection_name,
|
||||
"collection_name": default_collection,
|
||||
"path": persist_dir,
|
||||
"client": self._deps['chromadb'].PersistentClient(path=persist_dir)
|
||||
"client": self._deps['chromadb'].PersistentClient(path=persist_dir),
|
||||
"host": None,
|
||||
"port": None
|
||||
}
|
||||
},
|
||||
"version": "v1.1",
|
||||
@@ -104,13 +106,29 @@ class Knowledge:
|
||||
|
||||
# If config is provided, merge it with base config
|
||||
if self._config:
|
||||
if "vector_store" in self._config and "config" in self._config["vector_store"]:
|
||||
config_copy = self._config["vector_store"]["config"].copy()
|
||||
for key in ["collection_name", "client"]:
|
||||
if key in config_copy:
|
||||
del config_copy[key]
|
||||
base_config["vector_store"]["config"].update(config_copy)
|
||||
|
||||
# Merge version if provided
|
||||
if "version" in self._config:
|
||||
base_config["version"] = self._config["version"]
|
||||
|
||||
# Merge vector_store config
|
||||
if "vector_store" in self._config:
|
||||
if "provider" in self._config["vector_store"]:
|
||||
base_config["vector_store"]["provider"] = self._config["vector_store"]["provider"]
|
||||
|
||||
if "config" in self._config["vector_store"]:
|
||||
config_copy = self._config["vector_store"]["config"].copy()
|
||||
# Only exclude client as it's managed internally
|
||||
if "client" in config_copy:
|
||||
del config_copy["client"]
|
||||
base_config["vector_store"]["config"].update(config_copy)
|
||||
|
||||
# Merge embedder config if provided
|
||||
if "embedder" in self._config:
|
||||
base_config["embedder"] = self._config["embedder"]
|
||||
|
||||
# Merge llm config if provided
|
||||
if "llm" in self._config:
|
||||
base_config["llm"] = self._config["llm"]
|
||||
return base_config
|
||||
|
||||
@cached_property
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.44"
|
||||
version = "0.0.45"
|
||||
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
|
||||
authors = [
|
||||
{ name="Mervin Praison" }
|
||||
|
||||
Generated
+1
-1
@@ -1558,7 +1558,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.44"
|
||||
version = "0.0.45"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "openai" },
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Define the configuration for the Knowledge instance
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create an agent
|
||||
rag_agent = Agent(
|
||||
name="RAG Agent",
|
||||
role="Information Specialist",
|
||||
goal="Retrieve knowledge efficiently",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Define a task for the agent
|
||||
rag_task = Task(
|
||||
name="RAG Task",
|
||||
description="What is KAG?",
|
||||
expected_output="Answer to the question",
|
||||
agent=rag_agent,
|
||||
context=[config] # Vector Database provided as context
|
||||
)
|
||||
|
||||
# Build Agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[rag_agent],
|
||||
tasks=[rag_task],
|
||||
user_id="user1"
|
||||
)
|
||||
|
||||
# Start Agents
|
||||
agents.start()
|
||||
@@ -110,7 +110,7 @@ Loads environment variables from .env file or system and sets them.</p>
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.53 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.54 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
---
|
||||
title: "RAG Agents"
|
||||
description: "Learn how to create AI agents that can efficiently interact with vector databases for knowledge retrieval and storage."
|
||||
icon: "database"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Input] --> RAGAgent[("RAG Agent")]
|
||||
VDB[(Vector DB)] --> RAGAgent
|
||||
RAGAgent --> Task[Knowledge Task]
|
||||
Task --> |Query| VDB
|
||||
Task --> Out[Output]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style RAGAgent fill:#2E8B57,color:#fff,shape:circle
|
||||
style VDB fill:#4169E1,color:#fff,shape:cylinder
|
||||
style Task fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A knowledge-centric workflow where RAG (Retrieval Augmented Generation) agents interact with vector databases to store and retrieve information efficiently, enabling sophisticated question-answering and information retrieval capabilities.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
Install PraisonAI Agents with knowledge support:
|
||||
```bash
|
||||
pip install "praisonaiagents[knowledge]"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key:
|
||||
```bash
|
||||
export OPENAI_API_KEY=xxxxx
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `app.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["small.pdf"], # Indexing
|
||||
)
|
||||
|
||||
agent.start("What is KAG in one line?") # Retrieval
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Data Indexing and Retrieval Agents
|
||||
|
||||
<Note>
|
||||
Indexing and Ingestion are relatively the same.
|
||||
</Note>
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph In[Input]
|
||||
PDF[PDF]
|
||||
TXT[TXT]
|
||||
MD[MD]
|
||||
end
|
||||
|
||||
subgraph Router[Vector Store]
|
||||
DB[(Vector DB)]
|
||||
end
|
||||
|
||||
subgraph Out[Agents]
|
||||
A1[Agent 1]
|
||||
A2[Agent 2]
|
||||
A3[Agent 3]
|
||||
end
|
||||
|
||||
In --> Router
|
||||
Router --> A1
|
||||
Router --> A2
|
||||
Router --> A3
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Router fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
The simplest way to create a knowledge-based agent is without any configuration:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["small.pdf"] # Indexing
|
||||
)
|
||||
|
||||
agent.start("What is KAG in one line?") # Retrieval
|
||||
```
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
For more control over the knowledge base, you can specify a configuration:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["small.pdf"], # Indexing
|
||||
knowledge_config=config # Configuration
|
||||
)
|
||||
|
||||
agent.start("What is KAG in one line?") # Retrieval
|
||||
```
|
||||
|
||||
### Multi-Agent Knowledge System
|
||||
|
||||
For more complex scenarios, you can create a knowledge-based system with multiple agents:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
import logging
|
||||
import os
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Define the configuration for the Knowledge instance
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create an agent with knowledge capabilities
|
||||
knowledge_agent = Agent(
|
||||
name="KnowledgeAgent",
|
||||
role="Information Specialist",
|
||||
goal="Store and retrieve knowledge efficiently",
|
||||
backstory="Expert in managing and utilizing stored knowledge",
|
||||
knowledge=["sample.pdf"], # Indexing
|
||||
knowledge_config=config, # Configuration
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Define a task for the agent
|
||||
knowledge_task = Task(
|
||||
name="knowledge_task",
|
||||
description="Who is Mervin Praison?",
|
||||
expected_output="Answer to the question",
|
||||
agent=knowledge_agent # Agent
|
||||
)
|
||||
|
||||
# Create and start the agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[knowledge_agent],
|
||||
tasks=[knowledge_task],
|
||||
process="sequential",
|
||||
user_id="user1" # User ID
|
||||
)
|
||||
|
||||
# Start execution
|
||||
result = agents.start() # Retrieval
|
||||
```
|
||||
|
||||
## Retrieval Agents
|
||||
|
||||
<Note>
|
||||
Retrieval is the process of querying the vector database for information.
|
||||
Considering there is data already in the Vector Database.
|
||||
</Note>
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable in your terminal:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `rag_agent.py` with the basic setup:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Define the configuration for the Knowledge instance
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create an agent
|
||||
rag_agent = Agent(
|
||||
name="RAG Agent",
|
||||
role="Information Specialist",
|
||||
goal="Retrieve knowledge efficiently",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Define a task for the agent
|
||||
rag_task = Task(
|
||||
name="RAG Task",
|
||||
description="What is KAG?",
|
||||
expected_output="Answer to the question",
|
||||
agent=rag_agent,
|
||||
context=[config] # Retrieval : Vector Database provided as context
|
||||
)
|
||||
|
||||
# Build Agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[rag_agent],
|
||||
tasks=[rag_task],
|
||||
user_id="user1"
|
||||
)
|
||||
|
||||
# Start Agents
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Start Agents">
|
||||
Type this in your terminal to run your agents:
|
||||
```bash
|
||||
python rag_agent.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
|
||||
- ChromaDB or other supported vector database
|
||||
</Note>
|
||||
|
||||
### Adding Knowledge to RAG Agents
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["small.pdf"], # Indexing
|
||||
knowledge_config=config # Configuration
|
||||
)
|
||||
|
||||
agent.start("What is KAG in one line?") # Retrieval
|
||||
```
|
||||
|
||||
## Understanding RAG Agents
|
||||
|
||||
<Card title="What are RAG Agents?" icon="question">
|
||||
RAG (Retrieval Augmented Generation) agents enable:
|
||||
- Efficient knowledge retrieval
|
||||
- Semantic search capabilities
|
||||
- Persistent knowledge storage
|
||||
- Context-aware responses
|
||||
</Card>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="RAG Architecture" icon="database">
|
||||
Store and manage vector embeddings efficiently.
|
||||
</Card>
|
||||
<Card title="Semantic Search" icon="magnifying-glass">
|
||||
Find relevant information using semantic similarity.
|
||||
</Card>
|
||||
<Card title="Knowledge Integration" icon="brain">
|
||||
Seamlessly integrate with existing knowledge bases.
|
||||
</Card>
|
||||
<Card title="Context Management" icon="layer-group">
|
||||
Handle complex contextual queries and responses.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="RAG Issues" icon="triangle-exclamation">
|
||||
If RAG system isn't working:
|
||||
- Check database configuration
|
||||
- Verify connection settings
|
||||
- Enable verbose mode for debugging
|
||||
</Card>
|
||||
|
||||
<Card title="Query Issues" icon="gauge-high">
|
||||
If queries aren't returning expected results:
|
||||
- Check embedding quality
|
||||
- Verify search parameters
|
||||
- Monitor similarity thresholds
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Next Steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="AutoAgents" icon="robot" href="./autoagents">
|
||||
Learn about automatically created and managed AI agents
|
||||
</Card>
|
||||
<Card title="Mini Agents" icon="microchip" href="./mini">
|
||||
Explore lightweight, focused AI agents
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Note>
|
||||
For optimal results, ensure your vector database is properly configured and indexed for your specific use case.
|
||||
</Note>
|
||||
@@ -117,6 +117,7 @@
|
||||
"pages": [
|
||||
"features/autoagents",
|
||||
"features/selfreflection",
|
||||
"features/rag",
|
||||
"features/reasoning",
|
||||
"features/multimodal",
|
||||
"features/langchain",
|
||||
|
||||
@@ -12,6 +12,46 @@ export REDDIT_CLIENT_SECRET=xxxxxx
|
||||
export REDDIT_CLIENT_ID=xxxxxx
|
||||
```
|
||||
|
||||
[USER] in this format script:APP:v1.0(by/u/USERNAME)
|
||||
|
||||
```bash
|
||||
pip install praisonai langchain_community praw
|
||||
```
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY="Enter your API key"
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
### Single Agent
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from langchain_community.tools.reddit_search.tool import RedditSearchRun
|
||||
|
||||
agent = Agent(name="RedditSearchAgent",instructions="Search Reddit for information", tools=[RedditSearchRun],)
|
||||
|
||||
agent.start("Search Reddit for information about the latest AI advancements in subreddit all")
|
||||
```
|
||||
|
||||
### Multi Agents
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from langchain_community.tools.reddit_search.tool import RedditSearchRun
|
||||
|
||||
agent = Agent(name="RedditSearchAgent",instructions="Search Reddit for information", tools=[RedditSearchRun],)
|
||||
|
||||
task = Task(description="Search Reddit for information about the latest AI news in subreddit all", agent=agent)
|
||||
|
||||
agents = PraisonAIAgents(agents=[agent],tasks=[task])
|
||||
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## No Code
|
||||
|
||||
tools.py
|
||||
|
||||
```python
|
||||
|
||||
@@ -4,7 +4,7 @@ config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "custom_knowledge",
|
||||
"collection_name": "praison",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Define the configuration for the Knowledge instance
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create an agent
|
||||
rag_agent = Agent(
|
||||
name="RAG Agent",
|
||||
role="Information Specialist",
|
||||
goal="Retrieve knowledge efficiently",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Define a task for the agent
|
||||
rag_task = Task(
|
||||
name="RAG Task",
|
||||
description="What is KAG?",
|
||||
expected_output="Answer to the question",
|
||||
agent=rag_agent,
|
||||
context=[config] # Vector Database provided as context
|
||||
)
|
||||
|
||||
# Build Agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[rag_agent],
|
||||
tasks=[rag_task],
|
||||
user_id="user1"
|
||||
)
|
||||
|
||||
# Start Agents
|
||||
agents.start()
|
||||
Binary file not shown.
+1
-1
@@ -3,7 +3,7 @@ class Praisonai < Formula
|
||||
|
||||
desc "AI tools for various AI applications"
|
||||
homepage "https://github.com/MervinPraison/PraisonAI"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/2.0.53.tar.gz"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/2.0.54.tar.gz"
|
||||
sha256 "1828fb9227d10f991522c3f24f061943a254b667196b40b1a3e4a54a8d30ce32" # Replace with actual SHA256 checksum
|
||||
license "MIT"
|
||||
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class CloudDeployer:
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.53 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.54 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "PraisonAI"
|
||||
version = "2.0.53"
|
||||
version = "2.0.54"
|
||||
description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration."
|
||||
readme = "README.md"
|
||||
license = ""
|
||||
@@ -12,7 +12,7 @@ dependencies = [
|
||||
"rich>=13.7",
|
||||
"markdown>=3.5",
|
||||
"pyparsing>=3.0.0",
|
||||
"praisonaiagents>=0.0.44",
|
||||
"praisonaiagents>=0.0.45",
|
||||
"python-dotenv>=0.19.0",
|
||||
"instructor>=1.3.3",
|
||||
"PyYAML>=6.0",
|
||||
@@ -84,7 +84,7 @@ autogen = ["pyautogen>=0.2.19", "praisonai-tools>=0.0.7", "crewai"]
|
||||
|
||||
[tool.poetry]
|
||||
name = "PraisonAI"
|
||||
version = "2.0.53"
|
||||
version = "2.0.54"
|
||||
description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human–agent collaboration."
|
||||
authors = ["Mervin Praison"]
|
||||
license = ""
|
||||
@@ -102,7 +102,7 @@ python = ">=3.10,<3.13"
|
||||
rich = ">=13.7"
|
||||
markdown = ">=3.5"
|
||||
pyparsing = ">=3.0.0"
|
||||
praisonaiagents = ">=0.0.44"
|
||||
praisonaiagents = ">=0.0.45"
|
||||
python-dotenv = ">=0.19.0"
|
||||
instructor = ">=1.3.3"
|
||||
PyYAML = ">=6.0"
|
||||
|
||||
@@ -3060,7 +3060,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonai"
|
||||
version = "2.0.53"
|
||||
version = "2.0.54"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "instructor" },
|
||||
@@ -3197,7 +3197,7 @@ requires-dist = [
|
||||
{ name = "plotly", marker = "extra == 'realtime'", specifier = ">=5.24.0" },
|
||||
{ name = "praisonai-tools", marker = "extra == 'autogen'", specifier = ">=0.0.7" },
|
||||
{ name = "praisonai-tools", marker = "extra == 'crewai'", specifier = ">=0.0.7" },
|
||||
{ name = "praisonaiagents", specifier = ">=0.0.44" },
|
||||
{ name = "praisonaiagents", specifier = ">=0.0.45" },
|
||||
{ name = "pyautogen", marker = "extra == 'autogen'", specifier = ">=0.2.19" },
|
||||
{ name = "pydantic", marker = "extra == 'chat'", specifier = "<=2.10.1" },
|
||||
{ name = "pydantic", marker = "extra == 'code'", specifier = "<=2.10.1" },
|
||||
@@ -3250,16 +3250,16 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.44"
|
||||
version = "0.0.45"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "openai" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "rich" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/96/49/f3d3d637ab49962066bee4a8a812d93e7a50589c5622eb309852985625f3/praisonaiagents-0.0.44.tar.gz", hash = "sha256:d9f23afa79263e0f362c826c65d23e17ee0fac6ee789002217255745fa1f9722", size = 77200 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/47/05/9fa3e9c20677bab481df2275d0ce66062a052953fd50aa6aa032379fc090/praisonaiagents-0.0.45.tar.gz", hash = "sha256:4d21caa34dc6e046128bcf17ab0cf37088d1b9c04ac060b08cf8f2a1b61ab0c1", size = 77600 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/38/19/cc45c410a0c4c9c60ae346da682ec071259b7d3a6f49274537e7807325be/praisonaiagents-0.0.44-py3-none-any.whl", hash = "sha256:82ecfa8b3b06e251d599ddcd4dc7c645bbe6fefebddd6eb998bab2dad92c5021", size = 94813 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/eb/cf5477768b740610015e743b9573fd918653267bc567d5c09b11419b22fe/praisonaiagents-0.0.45-py3-none-any.whl", hash = "sha256:b2feba4ff86a06a7010751e28f0b258a297e4219527bf58e38f2c740694c268d", size = 95181 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in new issue
Block a user