Compare commits

...
3 Commits
Author SHA1 Message Date
Mervin Praison c1dead194c Release v3.9.4 2026-01-16 06:33:39 +00:00
Mervin Praison 5d67f0fdcf Release v3.9.3 2026-01-16 05:23:44 +00:00
github-actions[bot] fb93b7d6d5 docs: auto-update api.md [skip ci] 2026-01-16 04:38:07 +00:00
123 changed files with 613 additions and 525 deletions

No files matched your search

+4
View File
@@ -148,6 +148,10 @@ Methods:
* <code title="cli">praisonai agents info <a href="./src/praisonai/praisonai/cli/commands/agents.py">--help</a></code>
* <code title="cli">praisonai agents list <a href="./src/praisonai/praisonai/cli/commands/agents.py">--help</a></code>
* <code title="cli">praisonai audit agent-centric <a href="./src/praisonai/praisonai/cli/commands/audit.py">--help</a></code>
* <code title="cli">praisonai batch batch-run <a href="./src/praisonai/praisonai/cli/commands/batch.py">--help</a></code>
* <code title="cli">praisonai batch list <a href="./src/praisonai/praisonai/cli/commands/batch.py">--help</a></code>
* <code title="cli">praisonai batch report <a href="./src/praisonai/praisonai/cli/commands/batch.py">--help</a></code>
* <code title="cli">praisonai batch stats <a href="./src/praisonai/praisonai/cli/commands/batch.py">--help</a></code>
* <code title="cli">praisonai benchmark agent <a href="./src/praisonai/praisonai/cli/commands/benchmark.py">--help</a></code>
* <code title="cli">praisonai benchmark benchmark-callback <a href="./src/praisonai/praisonai/cli/commands/benchmark.py">--help</a></code>
* <code title="cli">praisonai benchmark cli <a href="./src/praisonai/praisonai/cli/commands/benchmark.py">--help</a></code>
+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=3.9.2" \
"praisonai>=3.9.4" \
"praisonai[chat]" \
"embedchain[github,youtube]"
+1 -1
View File
@@ -20,7 +20,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=3.9.2" \
"praisonai>=3.9.4" \
"praisonai[ui]" \
"praisonai[chat]" \
"praisonai[realtime]" \
+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=3.9.2" \
"praisonai>=3.9.4" \
"praisonai[ui]" \
"praisonai[crewai]"
+3 -3
View File
@@ -35,7 +35,7 @@ def run_quick_comparison():
prompt="What is 2+2?",
iterations=2,
paths=["openai_sdk", "praisonai_agent"],
verbose=True
output="verbose"
)
# Print comparison table
@@ -56,7 +56,7 @@ def run_full_benchmark():
report = handler.run_full_benchmark(
prompt="Hi",
iterations=3,
verbose=True
output="verbose"
)
# Print full report
@@ -78,7 +78,7 @@ def run_agent_benchmark():
prompt="Explain Python in one sentence",
iterations=3,
paths=["openai_sdk", "praisonai_agent"],
verbose=True
output="verbose"
)
# Show timeline diagrams
+1 -1
View File
@@ -22,7 +22,7 @@ custom_modes = {
}
# Create handler with verbose output
handler = CompareHandler(verbose=True)
handler = CompareHandler(output="verbose")
# Example: Manually create comparison results for analysis
# (useful for testing without API calls)
+1 -1
View File
@@ -22,7 +22,7 @@ modes = parse_modes("basic,tools,planning")
print(f"\nParsed modes: {modes}")
# Create compare handler
handler = CompareHandler(verbose=True)
handler = CompareHandler(output="verbose")
# Compare modes (this will run actual agent calls)
# Uncomment to run:
@@ -32,7 +32,7 @@ workflow = Workflow(
),
],
# Workflow-level consolidated params
output=WorkflowOutputConfig(verbose=True, stream=True),
output=WorkflowOutputConfig(output="verbose", stream=True),
planning=WorkflowPlanningConfig(enabled=True, reasoning=True),
memory=WorkflowMemoryConfig(backend="file"),
# Agent-like params
+1 -1
View File
@@ -37,7 +37,7 @@ def main():
name="CodeAssistant",
instructions="You are a helpful code assistant.",
context=config,
verbose=False
output="silent"
)
print(f" Agent name: {agent.name}")
@@ -105,7 +105,7 @@ def example_agent_with_default_tools():
name="InteractiveAgent",
instructions="You are a helpful coding assistant with file and code analysis capabilities.",
tools=tools,
verbose=False
output="silent"
)
print(f"Agent created with {len(tools)} tools")
@@ -68,7 +68,7 @@ Answer questions based ONLY on the provided knowledge context.
If the answer is not in the context, say 'I don't have that information.'
Be precise and quote exact values when asked about codes or numbers.""",
knowledge=[temp_dir],
user_id="demo_user",
memory={"user_id": "demo_user"},
output="verbose",
)
@@ -50,7 +50,7 @@ Only authorized personnel with code WRENCH-992 may access this project.
instructions="You ingest and store knowledge.",
knowledge=[temp_dir],
user_id="user_alice", # Scoped to Alice
verbose=False,
output="silent",
)
# Ensure knowledge is processed
@@ -104,7 +104,7 @@ Only authorized personnel with code WRENCH-992 may access this project.
instructions="Answer questions based on the provided knowledge. If you don't have the information, say so.",
knowledge=[temp_dir],
user_id="user_alice", # Same scope as Agent A
verbose=False,
output="silent",
)
response = agent_b.chat("What is the secret access code for Project PHOENIX?")
@@ -74,7 +74,7 @@ def example_agent_locks():
agent = Agent(
name="LockTestAgent",
instructions="Test agent",
verbose=False
output="silent"
)
# Check for locks
@@ -112,7 +112,7 @@ def example_concurrent_real_api():
name="ConcurrentAgent",
instructions="Reply with one word only.",
llm="gpt-4o-mini",
verbose=False
output="silent"
)
results = []
+1 -1
View File
@@ -51,7 +51,7 @@ agent = Agent(
name="KnowledgeAssistant",
instructions="You are a helpful assistant with access to technical documentation.",
knowledge=[doc_path],
knowledge_config={
knowledge={
"vector_store": "qdrant",
"url": "http://localhost:6333"
}
+1 -1
View File
@@ -39,7 +39,7 @@ agent = Agent(
instructions="You are a helpful assistant. Keep responses brief.",
db=db_instance,
session_id="demo-session-001", # Same session_id = resume conversation
verbose=False
output="silent"
)
# Chat with persistence
@@ -8,7 +8,7 @@ Docs: https://docs.praison.ai/cli/git-integration
from praisonai.cli.features import GitIntegrationHandler
# Initialize
handler = GitIntegrationHandler(verbose=True)
handler = GitIntegrationHandler(output="verbose")
git = handler.initialize(repo_path=".")
# Check if it's a git repo
+1 -1
View File
@@ -8,7 +8,7 @@ Docs: https://docs.praison.ai/cli/repo-map
from praisonai.cli.features import RepoMapHandler
# Initialize with current directory
handler = RepoMapHandler(verbose=True)
handler = RepoMapHandler(output="verbose")
repo_map = handler.initialize(root=".")
# Get the repository map
@@ -9,7 +9,7 @@ from praisonai.cli.features import SandboxExecutorHandler
from praisonai.cli.features.sandbox_executor import SandboxMode
# Initialize with basic sandbox
handler = SandboxExecutorHandler(verbose=True)
handler = SandboxExecutorHandler(output="verbose")
sandbox = handler.initialize(mode="basic")
print(f"Sandbox mode: {handler.get_mode()}")
+1 -1
View File
@@ -26,7 +26,7 @@ pdf_agent = Agent(
backstory="You are an expert at reading, analyzing, and answering questions about PDF documents. You provide accurate, detailed answers based on the document content.",
instructions="Read the provided PDF document and answer questions about its content. Be specific and cite relevant sections when possible.",
knowledge=["document.pdf"], # Replace with your PDF file path
knowledge_config=config,
knowledge=config,
reflection=True,
@@ -24,7 +24,7 @@ knowledge_agent = Agent(
goal="Store and retrieve knowledge efficiently",
backstory="Expert in managing and utilizing stored knowledge",
knowledge=["sample.pdf"],
knowledge_config=config)
knowledge=config)
# Define a task for the agent
knowledge_task = Task(
+1 -2
View File
@@ -13,8 +13,7 @@ config = {
agent = Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["small.pdf"],
knowledge_config=config
knowledge=["small.pdf"]
)
agent.start("What is KAG in one line?")
@@ -139,7 +139,7 @@ def main():
name="AI Research Assistant",
instructions="You are an AI research assistant. Use your knowledge base to answer questions about artificial intelligence topics.",
knowledge=sample_documents, # Will use default knowledge config
knowledge_config=rerank_config, # Use reranking config
knowledge=rerank_config, # Use reranking config
llm="gpt-4o-mini"
)
+1 -1
View File
@@ -16,7 +16,7 @@ def example_dict_output_config():
"""Example: Using dict for output configuration."""
from praisonaiagents import Agent
# Dict shorthand - equivalent to OutputConfig(verbose=True, stream=False)
# Dict shorthand - equivalent to OutputConfig(output="verbose", stream=False)
agent = Agent(
name="Assistant",
instructions="You are a helpful assistant.",
+7 -5
View File
@@ -104,11 +104,13 @@ def main():
agents = Agents(
agents=[researcher, retriever],
tasks=[store_task, verify_task, query_task, query_both_task], # Use same verbose level as memory
memory=True,
embedder={
"provider": "openai",
"config": {
"model": "text-embedding-3-small"
memory={
"provider": "rag",
"embedder": {
"provider": "openai",
"config": {
"model": "text-embedding-3-small"
}
}
}
)
@@ -61,7 +61,7 @@ agents_system = Agents(
agents=[knowledge_agent],
tasks=[build_task, query_task],
memory=True,
memory_config=memory_config, output="verbose"
memory=memory_config, output="verbose"
)
print("Starting graph memory demonstration...")
@@ -62,7 +62,7 @@ agents_system = Agents(
agents=[research_agent],
tasks=[build_memory_task, search_task],
memory=True,
memory_config=memory_config, output="verbose"
memory=memory_config, output="verbose"
)
print("Starting memory search optimization demonstration...")
@@ -85,13 +85,13 @@ def main():
agents = Agents(
agents=[researcher, retriever],
tasks=[store_task, retrieve_task],
memory=True,
embedder={
"provider": "gemini",
"config": {
"model": "text-embedding-004",
# Optional: specify task type for better results
# "task_type": "RETRIEVAL_DOCUMENT"
memory={
"provider": "rag",
"embedder": {
"provider": "gemini",
"config": {
"model": "text-embedding-004",
}
}
}
)
+1 -1
View File
@@ -153,7 +153,7 @@ def main():
agents=[researcher],
tasks=[build_knowledge_task, query_knowledge_task, expand_knowledge_task],
memory=True,
memory_config=memory_config
memory=memory_config
)
print("\n🚀 Starting graph memory demonstration...")
@@ -33,7 +33,7 @@ def init_agent():
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["kag-research-paper.pdf"],
knowledge_config=config,
knowledge=config,
user_id="user1",
llm="deepseek-r1"
)
@@ -31,7 +31,7 @@ agent = Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["kag-research-paper.pdf"], # Indexing
knowledge_config=config,
knowledge=config,
user_id="user1",
llm="deepseek-r1"
)
@@ -81,7 +81,7 @@ def main():
backstory="""You are a knowledge management specialist who excels at
organizing, categorizing, and retrieving information from the knowledge base.
You ensure that knowledge is properly stored, indexed, and accessible.""",
knowledge_config=mongodb_knowledge_config,
knowledge=mongodb_knowledge_config,
memory=True,
llm="gpt-4o-mini"
)
@@ -107,7 +107,7 @@ def main():
backstory="""You are a customer service representative who uses the
knowledge base and customer data to provide excellent support. You can
access customer history, product information, and troubleshooting guides.""",
knowledge_config=mongodb_knowledge_config,
knowledge=mongodb_knowledge_config,
tools=[mongodb_tools],
memory=True,
llm="gpt-4o-mini"
@@ -190,7 +190,7 @@ def main():
agents=[data_manager, knowledge_curator, business_analyst, customer_service],
tasks=business_tasks,
memory=True,
memory_config=mongodb_memory_config, output="verbose"
memory=mongodb_memory_config, output="verbose"
)
# Execute the comprehensive business pipeline
@@ -55,7 +55,7 @@ def main():
retrieve information from a comprehensive MongoDB knowledge base. You excel
at finding relevant information, synthesizing knowledge from multiple sources,
and providing accurate, context-aware responses.""",
knowledge_config=mongodb_knowledge_config,
knowledge=mongodb_knowledge_config,
knowledge=[os.path.join(os.path.dirname(__file__), "llms.md")],
memory=True,
llm="gpt-4o-mini"
@@ -94,7 +94,7 @@ def main():
agents=[research_agent],
tasks=research_tasks,
memory=True,
memory_config=mongodb_memory_config, output="verbose"
memory=mongodb_memory_config, output="verbose"
)
# Execute the research pipeline
@@ -1,155 +1,155 @@
{
"timestamp": "2025-12-31T18:45:38.187539Z",
"timestamp": "2026-01-16T05:23:04.919943Z",
"metadata": {
"python_version": "3.12.11",
"platform": "macOS-15.7.4-arm64-arm-64bit",
"praisonai_version": "2.9.2",
"timestamp": "2025-12-31T18:45:38.226558Z"
"platform": "macOS-26.3-arm64-arm-64bit",
"praisonai_version": "3.9.2",
"timestamp": "2026-01-16T05:23:04.932474Z"
},
"startup": {
"cold_ms": 80.9305000002496,
"warm_ms": 55.266541996388696
"cold_ms": 27.866583000104583,
"warm_ms": 27.75670800019725
},
"import_analysis": [
{
"module": "praisonaiagents",
"self_us": 2419,
"cumulative_us": 1645390,
"self_ms": 2.419,
"cumulative_ms": 1645.39
"self_us": 403,
"cumulative_us": 188329,
"self_ms": 0.403,
"cumulative_ms": 188.329
},
{
"module": "praisonaiagents.workflows",
"self_us": 670,
"cumulative_us": 1375919,
"self_ms": 0.67,
"cumulative_ms": 1375.919
"self_us": 106,
"cumulative_us": 112180,
"self_ms": 0.106,
"cumulative_ms": 112.18
},
{
"module": "praisonaiagents.workflows.yaml_parser",
"self_us": 775,
"cumulative_us": 1369435,
"self_ms": 0.775,
"cumulative_ms": 1369.435
"self_us": 217,
"cumulative_us": 107210,
"self_ms": 0.217,
"cumulative_ms": 107.21
},
{
"module": "praisonaiagents.agent.agent",
"self_us": 19,
"cumulative_us": 1349174,
"self_ms": 0.019,
"cumulative_ms": 1349.174
"self_us": 15,
"cumulative_us": 98811,
"self_ms": 0.015,
"cumulative_ms": 98.811
},
{
"module": "praisonaiagents.agent",
"self_us": 537,
"cumulative_us": 1349155,
"self_ms": 0.537,
"cumulative_ms": 1349.155
"self_us": 146,
"cumulative_us": 98796,
"self_ms": 0.146,
"cumulative_ms": 98.796
},
{
"module": "praisonaiagents.agent.agent",
"self_us": 1453,
"cumulative_us": 1285299,
"self_ms": 1.453,
"cumulative_ms": 1285.299
},
{
"module": "praisonaiagents.llm.openai_client",
"self_us": 7887,
"cumulative_us": 1123578,
"self_ms": 7.887,
"cumulative_ms": 1123.578
},
{
"module": "openai",
"self_us": 1083,
"cumulative_us": 1115692,
"self_ms": 1.083,
"cumulative_ms": 1115.692
},
{
"module": "openai.types",
"self_us": 2606,
"cumulative_us": 957990,
"self_ms": 2.606,
"cumulative_ms": 957.99
},
{
"module": "openai.types.batch",
"self_us": 1787,
"cumulative_us": 485667,
"self_ms": 1.787,
"cumulative_ms": 485.667
},
{
"module": "openai._models",
"self_us": 13423,
"cumulative_us": 450798,
"self_ms": 13.423,
"cumulative_ms": 450.798
},
{
"module": "openai.types.eval_create_params",
"self_us": 644,
"cumulative_us": 393275,
"self_ms": 0.644,
"cumulative_ms": 393.275
},
{
"module": "openai.types.graders.grader_inputs_param",
"self_us": 17,
"cumulative_us": 359515,
"self_ms": 0.017,
"cumulative_ms": 359.515
},
{
"module": "openai.types.graders",
"self_us": 392,
"cumulative_us": 359498,
"self_ms": 0.392,
"cumulative_ms": 359.498
},
{
"module": "openai.types.graders.multi_grader",
"self_us": 3847,
"cumulative_us": 351251,
"self_ms": 3.847,
"cumulative_ms": 351.251
},
{
"module": "openai.types.graders.label_model_grader",
"self_us": 5450,
"cumulative_us": 337291,
"self_ms": 5.45,
"cumulative_ms": 337.291
},
{
"module": "openai.types.graders.grader_inputs",
"self_us": 545,
"cumulative_us": 331841,
"self_ms": 0.545,
"cumulative_ms": 331.841
},
{
"module": "openai.types.responses.response_input_text",
"self_us": 21,
"cumulative_us": 331297,
"self_ms": 0.021,
"cumulative_ms": 331.297
},
{
"module": "openai.types.responses",
"self_us": 1301,
"cumulative_us": 331277,
"self_ms": 1.301,
"cumulative_ms": 331.277
"self_us": 1027,
"cumulative_us": 86223,
"self_ms": 1.027,
"cumulative_ms": 86.223
},
{
"module": "rich.logging",
"self_us": 1066,
"cumulative_us": 238256,
"self_ms": 1.066,
"cumulative_ms": 238.256
"self_us": 282,
"cumulative_us": 53009,
"self_ms": 0.282,
"cumulative_ms": 53.009
},
{
"module": "praisonaiagents.main",
"self_us": 18784,
"cumulative_us": 45759,
"self_ms": 18.784,
"cumulative_ms": 45.759
},
{
"module": "praisonaiagents.llm.openai_client",
"self_us": 2470,
"cumulative_us": 28251,
"self_ms": 2.47,
"cumulative_ms": 28.251
},
{
"module": "rich.traceback",
"self_us": 1478,
"cumulative_us": 18788,
"self_ms": 1.478,
"cumulative_ms": 18.788
},
{
"module": "rich.console",
"self_us": 1737,
"cumulative_us": 18587,
"self_ms": 1.737,
"cumulative_ms": 18.587
},
{
"module": "pygments.lexers",
"self_us": 242,
"cumulative_us": 15427,
"self_ms": 0.242,
"cumulative_ms": 15.427
},
{
"module": "rich.markdown",
"self_us": 409,
"cumulative_us": 13987,
"self_ms": 0.409,
"cumulative_ms": 13.987
},
{
"module": "pygments.plugin",
"self_us": 85,
"cumulative_us": 13503,
"self_ms": 0.085,
"cumulative_ms": 13.503
},
{
"module": "importlib.metadata",
"self_us": 637,
"cumulative_us": 13419,
"self_ms": 0.637,
"cumulative_ms": 13.419
},
{
"module": "rich._log_render",
"self_us": 145,
"cumulative_us": 13380,
"self_ms": 0.145,
"cumulative_ms": 13.38
},
{
"module": "markdown_it",
"self_us": 172,
"cumulative_us": 13339,
"self_ms": 0.172,
"cumulative_ms": 13.339
},
{
"module": "rich.text",
"self_us": 582,
"cumulative_us": 13236,
"self_ms": 0.582,
"cumulative_ms": 13.236
},
{
"module": "markdown_it.main",
"self_us": 298,
"cumulative_us": 13168,
"self_ms": 0.298,
"cumulative_ms": 13.168
},
{
"module": "pydantic",
"self_us": 223,
"cumulative_us": 11119,
"self_ms": 0.223,
"cumulative_ms": 11.119
}
],
"scenarios": [
@@ -162,28 +162,22 @@
"iterations": 2
},
"import_time_stats": {
"mean": 0.008833496394800022,
"min": 0.005916997906751931,
"max": 0.011749994882848114,
"stdev": 0.0041245517164382375,
"median": 0.008833496394800022
"mean": 0,
"min": 0,
"max": 0,
"stdev": 0,
"median": 0
},
"total_time_stats": {
"mean": 1727.4090415012324,
"min": 1367.2264170018025,
"max": 2087.5916660006624,
"stdev": 509.3751524982296,
"median": 1727.4090415012324
"mean": 0,
"min": 0,
"max": 0,
"stdev": 0,
"median": 0
},
"first_token_stats": null,
"raw_import_times_ms": [
0.011749994882848114,
0.005916997906751931
],
"raw_total_times_ms": [
1367.2264170018025,
2087.5916660006624
]
"raw_import_times_ms": [],
"raw_total_times_ms": []
},
{
"name": "simple_stream",
@@ -194,34 +188,22 @@
"iterations": 2
},
"import_time_stats": {
"mean": 0.008792001608526334,
"min": 0.006375004886649549,
"max": 0.01120899833040312,
"stdev": 0.0034181495442894613,
"median": 0.008792001608526334
"mean": 0,
"min": 0,
"max": 0,
"stdev": 0,
"median": 0
},
"total_time_stats": {
"mean": 2321.0982290001994,
"min": 1697.1089580038097,
"max": 2945.087499996589,
"stdev": 882.4540898183949,
"median": 2321.0982290001994
"mean": 0,
"min": 0,
"max": 0,
"stdev": 0,
"median": 0
},
"first_token_stats": {
"mean": 2312.8511880022415,
"min": 1681.2440420035273,
"max": 2944.458334000956,
"stdev": 893.2273919631452,
"median": 2312.8511880022415
},
"raw_import_times_ms": [
0.01120899833040312,
0.006375004886649549
],
"raw_total_times_ms": [
2945.087499996589,
1697.1089580038097
]
"first_token_stats": null,
"raw_import_times_ms": [],
"raw_total_times_ms": []
}
]
}
+1 -1
View File
@@ -50,5 +50,5 @@ with st.expander("🔧 Troubleshooting"):
**If you still have issues:**
- Make sure you have Node.js installed for the MCP server
- Set your OpenAI API key: `export OPENAI_API_KEY="your-key"`
- Try the debug mode by setting `verbose=True`
- Try the debug mode by setting `output="verbose"`
""")
@@ -33,7 +33,7 @@ def init_agent():
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["kag-research-paper.pdf"],
knowledge_config=config,
knowledge=config,
user_id="user1",
llm="deepseek-r1"
)
@@ -265,7 +265,7 @@ agents = Agents(
process="hierarchical",
manager_llm="gpt-4o-mini",
memory=True, # Enable shared memory for domain context
memory_config={
memory={
"provider": "rag",
"config": {
"collection_name": f"{domain.replace('.', '_')}_security_analysis"
+3 -3
View File
@@ -58,7 +58,7 @@ def auto_rag_basic():
KNOWLEDGE BASE:
{context}""",
verbose=False
output="silent"
)
# Wrap with AutoRagAgent for intelligent retrieval
@@ -105,7 +105,7 @@ def auto_rag_with_policies():
KNOWLEDGE BASE:
{context}""",
verbose=False
output="silent"
)
print("\n" + "=" * 60)
@@ -153,7 +153,7 @@ def auto_rag_config_options():
KNOWLEDGE BASE:
{context}""",
verbose=False
output="silent"
)
print("\n" + "=" * 60)
+1 -1
View File
@@ -79,7 +79,7 @@ def rag_with_query_context():
agent = Agent(
name="Research Assistant",
instructions="You answer questions based on the context provided in each query.",
verbose=False
output="silent"
)
# Simulate retrieved context (in real RAG, this comes from vector search)
+1 -1
View File
@@ -204,7 +204,7 @@ def rag_with_section_chunks():
PRODUCT DOCUMENTATION:
{context}""",
verbose=False
output="silent"
)
queries = [
+4 -4
View File
@@ -103,7 +103,7 @@ def basic_citations():
POLICY DOCUMENTS:
{context}""",
verbose=False
output="silent"
)
queries = [
@@ -146,7 +146,7 @@ def structured_citations():
POLICY DOCUMENTS:
{context}""",
verbose=False
output="silent"
)
query = "What are the requirements for remote work eligibility?"
@@ -183,7 +183,7 @@ def inline_citations():
POLICY DOCUMENTS:
{context}""",
verbose=False
output="silent"
)
query = "Summarize the key employee benefits."
@@ -267,7 +267,7 @@ def multi_source_synthesis():
POLICY DOCUMENTS:
{context}""",
verbose=False
output="silent"
)
query = "Give me a complete overview of employee benefits and policies."
+3 -3
View File
@@ -125,7 +125,7 @@ def web_augmented_rag():
COMPANY KNOWLEDGE:
{context}""",
verbose=False
output="silent"
)
# Simulate web-augmented queries
@@ -171,7 +171,7 @@ def database_augmented_rag():
COMPANY KNOWLEDGE:
{context}""",
verbose=False
output="silent"
)
queries = [
@@ -249,7 +249,7 @@ def hybrid_source_rag():
COMPANY KNOWLEDGE:
{context}""",
verbose=False
output="silent"
)
query = "Give me a complete business briefing for today"
+2 -2
View File
@@ -156,7 +156,7 @@ def hybrid_rag_example():
TROUBLESHOOTING KNOWLEDGE BASE:
{context}""",
verbose=False
output="silent"
)
# Test with different query types
@@ -204,7 +204,7 @@ def compare_retrieval_modes():
KNOWLEDGE BASE:
{context}""",
verbose=False
output="silent"
)
print(f"\n📝 Query: {query}")
+4 -4
View File
@@ -124,7 +124,7 @@ def graph_aware_rag():
KNOWLEDGE GRAPH:
{context}""",
verbose=False
output="silent"
)
# Relationship-focused queries
@@ -167,7 +167,7 @@ def multi_hop_reasoning():
KNOWLEDGE GRAPH:
{context}""",
verbose=False
output="silent"
)
# Multi-hop query requiring traversal
@@ -200,7 +200,7 @@ def entity_type_filtering():
SCIENTISTS:
{people_context}""",
verbose=False
output="silent"
)
# Filter to only concepts
@@ -213,7 +213,7 @@ def entity_type_filtering():
CONCEPTS:
{concepts_context}""",
verbose=False
output="silent"
)
query = "Tell me about the major developments in early 20th century physics."
+4 -4
View File
@@ -112,7 +112,7 @@ def multi_document_rag():
REPORTS:
{context}""",
verbose=False
output="silent"
)
# Questions that require multi-document synthesis
@@ -157,7 +157,7 @@ def cross_reference_example():
REPORTS:
{context}""",
verbose=False
output="silent"
)
query = """
@@ -185,7 +185,7 @@ def document_filtering():
POLICY REPORT:
{POLICY_REPORT['content']}""",
verbose=False
output="silent"
)
tech_agent = Agent(
@@ -194,7 +194,7 @@ def document_filtering():
TECHNOLOGY REPORT:
{TECH_REPORT['content']}""",
verbose=False
output="silent"
)
query = "What progress has been made in addressing climate change?"
+1 -1
View File
@@ -124,7 +124,7 @@ def main():
KNOWLEDGE:
{SAMPLE_KNOWLEDGE}""",
verbose=False
output="silent"
)
# Get test queries
+4 -4
View File
@@ -61,7 +61,7 @@ def main():
KNOWLEDGE BASE:
{SHARED_KNOWLEDGE}""",
verbose=False
output="silent"
)
summarizer = Agent(
@@ -75,7 +75,7 @@ def main():
KNOWLEDGE BASE:
{SHARED_KNOWLEDGE}""",
verbose=False
output="silent"
)
writer = Agent(
@@ -89,7 +89,7 @@ def main():
KNOWLEDGE BASE:
{SHARED_KNOWLEDGE}""",
verbose=False
output="silent"
)
# Define tasks
@@ -118,7 +118,7 @@ def main():
agents=[researcher, summarizer, writer],
tasks=[research_task, summary_task, report_task],
process="sequential",
verbose=False
output="silent"
)
result = agents.start()
+3 -3
View File
@@ -67,7 +67,7 @@ def main():
DOCUMENT:
{DOCUMENT_CONTENT}""",
verbose=False
output="silent"
)
query = "What are the main topics covered in this document?"
@@ -88,7 +88,7 @@ def main():
DOCUMENT:
{DOCUMENT_CONTENT}""",
verbose=False
output="silent"
)
queries = [
@@ -114,7 +114,7 @@ def main():
DOCUMENT:
{DOCUMENT_CONTENT}""",
verbose=False
output="silent"
)
analysis_query = "Compare the benefits vs challenges of remote work based on this study"
+3 -3
View File
@@ -131,7 +131,7 @@ def rag_with_reranking():
RESEARCH PAPERS:
{context}""",
verbose=False
output="silent"
)
queries = [
@@ -170,7 +170,7 @@ def compare_with_without_reranking():
RESEARCH PAPERS:
{context}""",
verbose=False
output="silent"
)
print(f"\n📝 Query: {query}")
@@ -196,7 +196,7 @@ def reranking_configuration():
agent = Agent(
name="My Agent",
knowledge=documents,
knowledge_config={
knowledge={
# Enable reranking
"rerank": True,
+3 -3
View File
@@ -134,7 +134,7 @@ def policy_based_retrieval():
IT SUPPORT DOCS:
{context}""",
verbose=False
output="silent"
)
query = "How do I set up VPN?"
@@ -217,7 +217,7 @@ def priority_based_retrieval():
HIGH PRIORITY DOCS:
{high_context}""",
verbose=False
output="silent"
)
# Full knowledge agent
@@ -227,7 +227,7 @@ def priority_based_retrieval():
IT SUPPORT DOCS:
{full_context}""",
verbose=False
output="silent"
)
query = "I'm locked out of my account!"
+5 -5
View File
@@ -110,7 +110,7 @@ def json_output_rag():
PRODUCT CATALOG:
{context}""",
verbose=False
output="silent"
)
# Request structured product info
@@ -154,7 +154,7 @@ def pydantic_guided_rag():
PRODUCT CATALOG:
{context}""",
verbose=False
output="silent"
)
query = "Compare the UltraWidget Pro and SmartHome Hub. Which should I buy?"
@@ -184,7 +184,7 @@ def table_format_rag():
PRODUCT CATALOG:
{context}""",
verbose=False
output="silent"
)
query = "Show me all products in a table with name, price, and rating."
@@ -212,7 +212,7 @@ def list_format_rag():
PRODUCT CATALOG:
{context}""",
verbose=False
output="silent"
)
queries = [
@@ -321,7 +321,7 @@ def multi_format_rag():
PRODUCT CATALOG:
{context}""",
verbose=False
output="silent"
)
response = agent.chat(query)
+1 -1
View File
@@ -6,7 +6,7 @@ agent = Agent(
name="Assistant",
instructions="You are a helpful assistant with access to documents.",
knowledge=["./docs/guide.pdf"], # Add your documents here
knowledge_config={
knowledge={
"vector_store": "chroma",
"path": "/tmp/chroma_demo"
}
+1 -1
View File
@@ -6,7 +6,7 @@ agent = Agent(
name="Assistant",
instructions="You are a helpful assistant with access to documents.",
knowledge=["./docs/guide.pdf"], # Add your documents here
knowledge_config={
knowledge={
"vector_store": "lancedb",
"path": "/tmp/lancedb_test"
}
+1 -1
View File
@@ -6,7 +6,7 @@ agent = Agent(
name="Assistant",
instructions="You are a helpful assistant with access to documents.",
knowledge=["./docs/guide.pdf"], # Add your documents here
knowledge_config={
knowledge={
"vector_store": "lancedb",
"path": "/tmp/lancedb_demo"
}
+1 -1
View File
@@ -12,7 +12,7 @@ agent = Agent(
name="Assistant",
instructions="You are a helpful assistant with access to documents.",
knowledge=["./docs/guide.pdf"], # Add your documents here
knowledge_config={
knowledge={
"vector_store": "pgvector",
"url": url
}
+1 -1
View File
@@ -12,7 +12,7 @@ agent = Agent(
name="Assistant",
instructions="You are a helpful assistant with access to documents.",
knowledge=["./docs/guide.pdf"], # Add your documents here
knowledge_config={
knowledge={
"vector_store": "pgvector",
"url": url
}
+1 -1
View File
@@ -16,7 +16,7 @@ agent = Agent(
name="Assistant",
instructions="You are a helpful assistant with access to documents.",
knowledge=["./docs/guide.pdf"], # Add your documents here
knowledge_config={
knowledge={
"vector_store": "pinecone",
"api_key": api_key,
"environment": "us-east-1"
+1 -1
View File
@@ -12,7 +12,7 @@ agent = Agent(
name="Assistant",
instructions="You are a helpful assistant with access to documents.",
knowledge=["./docs/guide.pdf"], # Add your documents here
knowledge_config={
knowledge={
"vector_store": "qdrant",
"url": url
}
+1 -1
View File
@@ -17,7 +17,7 @@ agent = Agent(
name="Assistant",
instructions="You are a helpful assistant with access to documents.",
knowledge=["./docs/guide.pdf"], # Add your documents here
knowledge_config={
knowledge={
"vector_store": "weaviate",
"url": weaviate_url,
"api_key": weaviate_key
+1 -1
View File
@@ -93,7 +93,7 @@ def example_3_execute_yaml_directly():
result = manager.execute_yaml(
yaml_file,
input_data="The future of AI",
verbose=True
output="verbose"
)
print(f"Status: {result['status']}")
@@ -7,15 +7,14 @@ will be automatically displayed when tasks complete!
from praisonaiagents import Agents, Agent, Task
def main():
# Create a simple agent with metrics=True - that's it!
# Create a simple agent with output="debug" - includes metrics!
research_agent = Agent(
name="Research Agent",
role="Research Specialist",
goal="Find information about a topic",
backstory="You are an expert researcher who finds comprehensive information.",
output="verbose",
output="debug", # 🎯 SIMPLIFIED: debug preset includes metrics!
llm="gpt-4o-mini", # Use a cost-effective model for examples
metrics=True # 🎯 SIMPLIFIED: Just add this parameter!
)
# Create a simple task
@@ -143,7 +143,7 @@ def simulate_complex_workflow():
agents=[planner, executor, reviewer],
tasks=[planning_task, execution_task, review_task],
process="sequential",
verbose=False
output="silent"
)
result = workflow.start()
@@ -6,6 +6,8 @@ which will apply to all tasks executed by that agent.
"""
from typing import Tuple, Any
from praisonaiagents import Agent, TaskOutput
def validate_content_length(task_output: TaskOutput) -> Tuple[bool, Any]:
"""
Validate that task output content meets minimum length requirement.
@@ -17,6 +19,8 @@ def validate_content_length(task_output: TaskOutput) -> Tuple[bool, Any]:
if len(task_output.raw) < 50:
return False, "Content too short - must be at least 50 characters"
return True, task_output
def validate_professional_tone(task_output: TaskOutput) -> Tuple[bool, Any]:
"""
Validate that the content has a professional tone.
@@ -31,14 +35,17 @@ def validate_professional_tone(task_output: TaskOutput) -> Tuple[bool, Any]:
if word in content:
return False, f"Content contains unprofessional word: '{word}'"
return True, task_output
def main():
"""Demonstrate Agent-level guardrails with function-based and LLM-based validation."""
print("=== Agent Guardrail Examples ===\n")
# Example 1: Function-based guardrail
print("1. Function-based guardrail (content length validation):")
agent1 = Agent(
name="ContentWriter"
instructions="You are a professional content writer who creates detailed responses"
name="ContentWriter",
instructions="You are a professional content writer who creates detailed responses",
guardrails=validate_content_length
)
try:
@@ -46,11 +53,12 @@ def main():
print(f"Result: {result1}\n")
except Exception as e:
print(f"Error: {e}\n")
# Example 2: LLM-based guardrail (string description)
print("2. LLM-based guardrail (professional tone validation):")
agent2 = Agent(
name="BusinessWriter",
instructions="You are a business communication expert"
instructions="You are a business communication expert",
guardrails="Ensure the content is professional, formal, and suitable for business communication. No casual language or slang."
)
try:
@@ -58,11 +66,12 @@ def main():
print(f"Result: {result2}\n")
except Exception as e:
print(f"Error: {e}\n")
# Example 3: Multiple agents with different guardrails
print("3. Professional tone function-based guardrail:")
agent3 = Agent(
name="ProfessionalWriter"
instructions="Write professional business content"
name="ProfessionalWriter",
instructions="Write professional business content",
guardrails=validate_professional_tone
)
try:
@@ -70,6 +79,9 @@ def main():
print(f"Result: {result3}\n")
except Exception as e:
print(f"Error: {e}\n")
print("=== Agent Guardrails Demonstration Complete ===")
if __name__ == "__main__":
main()
+2 -2
View File
@@ -11,7 +11,7 @@ agents = AutoAgents(
instructions="Search for information about AI Agents",
tools=[tavily],
process="sequential",
verbose=True,
output="verbose",
max_agents=3 # Maximum number of agents to create
)
@@ -53,7 +53,7 @@ agents = AutoAgents(
process="sequential",
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
reflection=False,
verbose=False,
output="silent",
max_agents=3 # Maximum number of agents to create
)
+2 -2
View File
@@ -26,7 +26,7 @@ agent = DeepResearchAgent(
- Clear structure with executive summary
""",
model="deep-research-pro", # Auto-detected as Gemini
verbose=True,
output="verbose",
)
print(f"Agent: {agent}")
@@ -39,7 +39,7 @@ result = agent.research(
# stream=True is the default, set stream=False to disable
)
# The report is already printed during streaming when verbose=True
# The report is already printed during streaming when output="verbose"
# But we can also access it programmatically:
print("\n" + "=" * 60)
print(f"Report length: {len(result.report)} characters")
+2 -2
View File
@@ -25,7 +25,7 @@ agent = DeepResearchAgent(
- Clear, structured responses
""",
model="o4-mini-deep-research", # or "o3-deep-research" for higher quality
verbose=True
output="verbose"
)
print(f"Agent: {agent}")
@@ -38,7 +38,7 @@ result = agent.research(
# stream=True is the default, set stream=False to disable
)
# The report is already printed during streaming when verbose=True
# The report is already printed during streaming when output="verbose"
# But we can also access it programmatically:
print("\n" + "=" * 60)
print(f"Report length: {len(result.report)} characters")
@@ -15,9 +15,7 @@ agent = Agent(
instructions="You are a helpful assistant. Be concise and clear.",
llm=llm_config,
output="verbose",
reflection=True,
max_reflect=2,
min_reflect=1
reflection=True # Use simplest form - enables defaults
)
# Test with a simple prompt
+1 -1
View File
@@ -24,7 +24,7 @@ task = Task(
agents = Agents(
agents=[agent],
tasks=[task],
verbose=True
output="verbose"
)
agents.start()
+2 -5
View File
@@ -32,11 +32,8 @@ agent = Agent(
instructions="You are a helpful Assistant specialized in scientific explanations. "
"Provide clear, accurate, and engaging responses.",
llm=llm_config, # Pass the detailed configuration
output="verbose", # Enable detailed output
markdown=True, # Format responses in markdown
reflection=True, # Enable self-reflection
max_reflect=3, # Maximum reflection iterations
min_reflect=1 # Minimum reflection iterations
output="verbose", # Enable detailed output (includes markdown)
reflection=True # Enable self-reflection with defaults
)
# Test the agent
@@ -70,7 +70,7 @@ def main():
indexing, and ensure data quality and accessibility across the organization.""",
tools=[mongodb_tools],
memory=True,
verbose=True,
output="verbose",
llm="gpt-4o-mini"
)
@@ -82,9 +82,9 @@ def main():
backstory="""You are a knowledge management specialist who excels at
organizing, categorizing, and retrieving information from the knowledge base.
You ensure that knowledge is properly stored, indexed, and accessible.""",
knowledge_config=mongodb_knowledge_config,
knowledge=mongodb_knowledge_config,
memory=True,
verbose=True,
output="verbose",
llm="gpt-4o-mini"
)
@@ -98,7 +98,7 @@ def main():
and provide strategic recommendations based on data analysis.""",
tools=[mongodb_tools],
memory=True,
verbose=True,
output="verbose",
llm="gpt-4o-mini"
)
@@ -110,10 +110,10 @@ def main():
backstory="""You are a customer service representative who uses the
knowledge base and customer data to provide excellent support. You can
access customer history, product information, and troubleshooting guides.""",
knowledge_config=mongodb_knowledge_config,
knowledge=mongodb_knowledge_config,
tools=[mongodb_tools],
memory=True,
verbose=True,
output="verbose",
llm="gpt-4o-mini"
)
@@ -195,7 +195,7 @@ def main():
tasks=business_tasks,
memory=True,
memory_config=mongodb_memory_config,
verbose=True
output="verbose"
)
# Execute the comprehensive business pipeline
@@ -55,10 +55,9 @@ def main():
retrieve information from a comprehensive MongoDB knowledge base. You excel
at finding relevant information, synthesizing knowledge from multiple sources,
and providing accurate, context-aware responses.""",
knowledge_config=mongodb_knowledge_config,
knowledge=[os.path.join(os.path.dirname(__file__), "llms.md")],
memory=True,
verbose=True,
output="verbose",
llm="gpt-4o-mini"
)
@@ -72,7 +71,7 @@ def main():
knowledge base. You ensure information is accurate, well-structured,
and properly categorized.""",
memory=True,
verbose=True,
output="verbose",
llm="gpt-4o-mini"
)
@@ -128,7 +127,7 @@ def main():
agents=[research_agent, knowledge_agent],
tasks=knowledge_tasks,
memory=True,
verbose=True
output="verbose"
)
# Execute the knowledge management pipeline
@@ -49,7 +49,7 @@ def main():
You excel at maintaining context across multiple research sessions and can
retrieve relevant information from your persistent memory store.""",
memory=True,
verbose=True,
output="verbose",
llm="gpt-4o-mini"
)
@@ -94,9 +94,8 @@ def main():
research_system = Agents(
agents=[research_agent],
tasks=research_tasks,
memory=True,
memory_config=mongodb_memory_config,
verbose=True
memory=mongodb_memory_config,
output="verbose"
)
# Execute the research pipeline
@@ -37,7 +37,7 @@ def main():
collections, and analyze data patterns. You excel at using MongoDB tools
for data management and retrieval.""",
tools=[mongodb_tools],
verbose=True,
output="verbose",
llm="gpt-4o-mini"
)
@@ -50,7 +50,7 @@ def main():
from MongoDB databases. You can query data, perform aggregations, and
identify patterns and trends in the stored information.""",
tools=[mongodb_tools],
verbose=True,
output="verbose",
llm="gpt-4o-mini"
)
@@ -116,7 +116,7 @@ def main():
mongodb_system = Agents(
agents=[db_agent, analysis_agent],
tasks=mongodb_tasks,
verbose=True
output="verbose"
)
# Execute the MongoDB operations pipeline
@@ -200,7 +200,7 @@ research_agent = Agent(
goal="Research and analyze performance topics quickly",
backstory="You are an expert at researching performance optimization topics.",
tools=[duckduckgo],
verbose=False # Reduce output for cleaner demo
output="silent" # Reduce output for cleaner demo
)
# Monitor agent operations
@@ -216,7 +216,7 @@ def execute_monitored_task(agent, task_description):
agents_workflow = Agents(
agents=[agent],
tasks=[task],
verbose=False
output="silent"
)
# Simulate API calls during agent execution
+3 -3
View File
@@ -4,11 +4,11 @@ from praisonaiagents import Agent
from praisonaiagents.planning import PlanningAgent, TodoList
# Step 1: Create agents
researcher = Agent(name="Researcher", role="Research Analyst", verbose=True)
writer = Agent(name="Writer", role="Content Writer", verbose=True)
researcher = Agent(name="Researcher", role="Research Analyst", output="verbose")
writer = Agent(name="Writer", role="Content Writer", output="verbose")
# Step 2: Create a plan using PlanningAgent
planner = PlanningAgent(llm="gpt-4o-mini", verbose=1)
planner = PlanningAgent(llm="gpt-4o-mini", output="status")
plan = planner.create_plan_sync(
request="Write a short article about the top 3 benefits of meditation",
agents=[researcher, writer],
@@ -43,6 +43,7 @@ class Task:
rerun: bool = False, # Renamed from can_rerun and logic inverted, default True for backward compatibility
retain_full_context: bool = False, # By default, only use previous task output, not all previous tasks
guardrail: Optional[Union[Callable[[TaskOutput], Tuple[bool, Any]], str]] = None,
guardrails: Optional[Union[Callable[[TaskOutput], Tuple[bool, Any]], str]] = None, # Alias for guardrail
max_retries: int = 3,
retry_count: int = 0,
agent_config: Optional[Dict[str, Any]] = None,
@@ -86,7 +87,7 @@ class Task:
self.quality_check = quality_check
self.rerun = rerun # Assigning the rerun parameter
self.retain_full_context = retain_full_context
self.guardrail = guardrail
self.guardrail = guardrail if guardrail is not None else guardrails # guardrails is alias
self.max_retries = max_retries
self.retry_count = retry_count
self._guardrail_fn = None
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "praisonaiagents"
version = "0.12.2"
version = "0.12.3"
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
readme = "README.md"
requires-python = ">=3.10"
@@ -13,7 +13,7 @@ def main():
# Initialize the agent
agent = QueryRewriterAgent(
model="gpt-4o-mini",
verbose=True
output="verbose"
)
print("=" * 60)
+1 -2
View File
@@ -4,8 +4,7 @@ agent = Agent(
instructions="You are a helpful assistant",
llm="gemini/gemini-2.0-flash",
reflection=False,
verbose=False,
stream=True
output="stream"
)
# Use return_generator=True to get the raw generator for custom streaming handling
@@ -6,12 +6,12 @@ This script directly tests the LLM class to determine where the duplicate callba
ROOT CAUSE IDENTIFIED:
In llm.py, there are two separate callback execution paths:
1. execute_sync_callback() called directly (lines 851-857, 885-891, etc.)
2. display_interaction() called when verbose=True (line 896, etc.)
2. display_interaction() called when output="verbose" (line 896, etc.)
Since display_interaction() ALSO executes sync callbacks internally (main.py lines 164-190),
this results in duplicate callback execution for the same LLM response.
The issue occurs specifically when verbose=True because both callback paths are active.
The issue occurs specifically when output="verbose" because both callback paths are active.
"""
import os
@@ -74,11 +74,11 @@ def test_llm_streaming():
register_display_callback('interaction', track_callback, is_async=False)
try:
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", verbose=False)
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", output="silent")
response = llm.get_response(
prompt="Say exactly: Hello World",
verbose=True, # This should trigger the callback
output="verbose", # This should trigger the callback
stream=True # Test with streaming
)
@@ -103,11 +103,11 @@ def test_llm_non_streaming():
register_display_callback('interaction', track_callback, is_async=False)
try:
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", verbose=False)
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", output="silent")
response = llm.get_response(
prompt="Say exactly: Hello World",
verbose=True, # This should trigger the callback
output="verbose", # This should trigger the callback
stream=False # Test without streaming
)
@@ -132,11 +132,11 @@ def test_llm_with_self_reflection():
register_display_callback('interaction', track_callback, is_async=False)
try:
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", verbose=False, reflection=True)
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", output="silent", reflection=True)
response = llm.get_response(
prompt="Say exactly: Hello World",
verbose=True, # This should trigger the callback
output="verbose", # This should trigger the callback
reflection=True,
min_reflect=1,
max_reflect=1
@@ -152,25 +152,25 @@ def test_llm_with_self_reflection():
return -1
def test_verbose_vs_non_verbose():
"""Test the key difference: verbose=True vs verbose=False to isolate the duplicate issue."""
"""Test the key difference: output="verbose" vs output="silent" to isolate the duplicate issue."""
print("🧪 TEST 4: Verbose vs Non-Verbose (Key Test for Duplicate Issue)")
print("-" * 60)
global callback_invocations
# Test with verbose=False (should trigger callback once via execute_sync_callback)
print(" 🔹 Testing with verbose=False:")
# Test with output="silent" (should trigger callback once via execute_sync_callback)
print(" 🔹 Testing with output="silent":")
callback_invocations = []
register_display_callback('interaction', track_callback, is_async=False)
try:
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", verbose=False)
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", output="silent")
response = llm.get_response(
prompt="Say exactly: Test Non-Verbose",
verbose=False # This should only trigger execute_sync_callback
output="silent" # This should only trigger execute_sync_callback
)
print(f" Response: {response}")
print(f" Callbacks with verbose=False: {len(callback_invocations)}")
print(f" Callbacks with output="silent": {len(callback_invocations)}")
non_verbose_count = len(callback_invocations)
except Exception as e:
print(f" ❌ Error: {e}")
@@ -178,19 +178,19 @@ def test_verbose_vs_non_verbose():
print()
# Test with verbose=True (should trigger callback twice: execute_sync_callback + display_interaction)
print(" 🔹 Testing with verbose=True:")
# Test with output="verbose" (should trigger callback twice: execute_sync_callback + display_interaction)
print(" 🔹 Testing with output="verbose":")
callback_invocations = []
register_display_callback('interaction', track_callback, is_async=False)
try:
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", verbose=False)
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", output="silent")
response = llm.get_response(
prompt="Say exactly: Test Verbose",
verbose=True # This should trigger BOTH execute_sync_callback AND display_interaction
output="verbose" # This should trigger BOTH execute_sync_callback AND display_interaction
)
print(f" Response: {response}")
print(f" Callbacks with verbose=True: {len(callback_invocations)}")
print(f" Callbacks with output="verbose": {len(callback_invocations)}")
verbose_count = len(callback_invocations)
# Show the call stack differences
@@ -204,12 +204,12 @@ def test_verbose_vs_non_verbose():
verbose_count = -1
print(f"\n 📊 RESULT:")
print(f" verbose=False: {non_verbose_count} callback(s)")
print(f" verbose=True: {verbose_count} callback(s)")
print(f" output="silent": {non_verbose_count} callback(s)")
print(f" output="verbose": {verbose_count} callback(s)")
if verbose_count > non_verbose_count and verbose_count > 1:
print(f" 🚨 DUPLICATE ISSUE CONFIRMED!")
print(f" verbose=True triggers {verbose_count - non_verbose_count} extra callback(s)")
print(f" output="verbose" triggers {verbose_count - non_verbose_count} extra callback(s)")
return verbose_count
@@ -225,13 +225,13 @@ def test_multiple_calls():
register_display_callback('interaction', track_callback, is_async=False)
try:
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", verbose=False)
llm = LLM(model="gemini/gemini-2.5-flash-lite-preview-06-17", output="silent")
for i in range(3):
print(f" Call {i+1}:")
response = llm.get_response(
prompt=f"Say exactly: Call {i+1}",
verbose=True
output="verbose"
)
print(f" Response: {response}")
@@ -319,10 +319,10 @@ if __name__ == "__main__":
if count > expected * 1.5: # Allow some tolerance
issues_detected.append(f"{test_name}: {count} > expected {expected}")
elif test_name == 'verbose_vs_nonverbose':
# This is the key test - verbose=True should show the duplicate issue
print(f"{test_name}: {count} invocations (this test shows verbose=True duplicates)")
# This is the key test - output="verbose" should show the duplicate issue
print(f"{test_name}: {count} invocations (this test shows output="verbose" duplicates)")
if count > 1:
issues_detected.append(f"{test_name}: verbose=True triggered {count} callbacks (duplicate issue)")
issues_detected.append(f"{test_name}: output="verbose" triggered {count} callbacks (duplicate issue)")
else:
expected = 1
print(f"{test_name}: {count} invocations (expected {expected})")
+2 -2
View File
@@ -10,7 +10,7 @@ agent = session.Agent(
name="Assistant",
instructions="You are a helpful assistant with memory.",
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
verbose=False,
output="silent",
memory=True
)
@@ -33,7 +33,7 @@ anotherAgent = anotherSession.Agent(
name="Assistant",
instructions="You are a helpful assistant with memory.",
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
verbose=False,
output="silent",
memory=True
)
@@ -16,7 +16,7 @@ from praisonaiagents.config import OutputConfig
agent = Agent(
instructions="You are a helpful assistant",
llm="gpt-4o-mini",
output=OutputConfig(verbose=True) # Show generation progress
output=OutputConfig(output="verbose") # Show generation progress
)
# Run the agent - verbose mode shows streaming progress via Rich Live display
@@ -10,7 +10,7 @@ agent = Agent(
planning=True,
planning_tools=[search_web],
planning_reasoning=True,
verbose=False # Quiet mode
output="silent" # Quiet mode
)
result = agent.start("Research AI trends in 2025 and write a 2 sentence summary")
@@ -176,9 +176,9 @@ def test_llm_console_lazy_loading():
print("\n6. Testing LLM console lazy loading...")
# LLM without verbose (console not needed)
llm1 = LLM(model="gemini/gemini-2.0-flash-exp", verbose=False)
llm1 = LLM(model="gemini/gemini-2.0-flash-exp", output="silent")
console_created_before = hasattr(llm1, '_console') and llm1._console is not None
print(f" Console created before access (verbose=False): {console_created_before}")
print(f" Console created before access (output="silent"): {console_created_before}")
# Access console
_ = llm1.console
@@ -151,7 +151,7 @@ async def test_sequential_async_execution():
agents=[async_agent, sync_agent],
tasks=tasks,
process="sequential",
verbose=True
output="verbose"
)
# Run the workflow
@@ -48,7 +48,7 @@ def test_hierarchical_without_openai():
process="hierarchical",
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
reflection=True,
verbose=True,
output="verbose",
max_agents=3 # Maximum number of agents to create
)
@@ -88,7 +88,7 @@ def test_hierarchical_with_mock_llm():
"api_key": "mock-key",
"base_url": "http://localhost:9999" # Non-existent URL
},
verbose=False,
output="silent",
max_agents=2
)
@@ -43,7 +43,7 @@ def test_callback_enhancement():
goal="Help with testing callbacks",
backstory="I am a helpful assistant for testing purposes",
llm="openai/gpt-5-nano",
verbose=True
output="verbose"
)
# Create a task with detailed information
@@ -59,7 +59,7 @@ def test_callback_enhancement():
agents = Agents(
agents=[agent],
tasks=[task],
verbose=True
output="verbose"
)
result = agents.start()
print(f"Test completed successfully! Result: {result}")
+7 -7
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Test script to verify callbacks work with verbose=False"""
"""Test script to verify callbacks work with output="silent""""
import sys
sys.path.insert(0, 'src/praisonai-agents')
@@ -27,15 +27,15 @@ def simple_callback(message=None, response=None, **kwargs):
# Register callback
register_display_callback('interaction', simple_callback, is_async=False)
# Test with verbose=False
print("Testing with verbose=False...")
# Test with output="silent"
print("Testing with output="silent"...")
agent = Agent(
name="TestAgent",
role="Assistant",
goal="Help with tasks",
backstory="I am a helpful assistant",
llm="gpt-4o-mini", # Using a simple model for testing
verbose=False
output="silent"
)
task = Task(
@@ -47,7 +47,7 @@ task = Task(
# Clear the log file
with open('callback_test_log.txt', 'w') as f:
f.write("Starting test with verbose=False\n")
f.write("Starting test with output="silent"\n")
# Run the agent
try:
@@ -61,9 +61,9 @@ try:
# Check if callback was executed
if callback_executed:
print("✅ SUCCESS: Callback was executed with verbose=False!")
print("✅ SUCCESS: Callback was executed with output="silent"!")
else:
print("❌ FAILED: Callback was NOT executed with verbose=False")
print("❌ FAILED: Callback was NOT executed with output="silent"")
except Exception as e:
print(f"Error during test: {e}")
@@ -43,10 +43,10 @@ def test_single_display_no_tools():
MagicMock(choices=[MagicMock(delta=MagicMock(content="!"))])
]
llm = LLM(model="gpt-4o-mini", verbose=False)
llm = LLM(model="gpt-4o-mini", output="silent")
response = llm.get_response(
prompt="Test prompt",
verbose=True,
output="verbose",
stream=True
)
@@ -82,10 +82,10 @@ def test_single_display_with_reasoning():
}]
}
llm = LLM(model="o1-preview", verbose=False, reasoning_steps=True)
llm = LLM(model="o1-preview", output="silent", reasoning_steps=True)
response = llm.get_response(
prompt="What is the meaning of life?",
verbose=True,
output="verbose",
stream=False,
reasoning_steps=True
)
@@ -139,10 +139,10 @@ def test_single_display_with_self_reflection():
mock_completion.side_effect = mock_streaming
llm = LLM(model="gpt-4o-mini", verbose=False, reflection=True, min_reflect=1, max_reflect=2)
llm = LLM(model="gpt-4o-mini", output="silent", reflection=True, min_reflect=1, max_reflect=2)
response = llm.get_response(
prompt="Test prompt",
verbose=True,
output="verbose",
stream=True,
reflection=True,
min_reflect=1,
@@ -179,10 +179,10 @@ def test_async_single_display():
mock_acompletion.return_value = async_generator()
llm = LLM(model="gpt-4o-mini", verbose=False)
llm = LLM(model="gpt-4o-mini", output="silent")
response = await llm.get_response_async(
prompt="Test async",
verbose=True,
output="verbose",
stream=True
)
+1 -1
View File
@@ -15,7 +15,7 @@ def test_self_reflection_fix():
backstory="You are a helpful math assistant",
reflection=True,
llm="gpt-4o-mini", # Use a more widely available model
verbose=True,
output="verbose",
tools=[evaluate],
min_reflect=1,
max_reflect=2
@@ -25,7 +25,7 @@ test_agent = Agent(
goal="Test the fix",
tools=[simple_tool],
llm="gpt-4o-mini", # Using OpenAI for testing
verbose=False # This is key - verbose=False triggers the bug
output="silent" # This is key - output="silent" triggers the bug
)
# Simple task
@@ -44,7 +44,7 @@ async def main():
agents=[test_agent],
tasks=[test_task],
process="sequential",
verbose=False # This should not cause the error anymore
output="silent" # This should not cause the error anymore
)
try:
@@ -43,7 +43,7 @@ def test_gemini_embedding():
agents_openai = Agents(
agents=[agent],
tasks=[task],
verbose=5,
output="debug",
memory=True
)
@@ -72,7 +72,7 @@ def test_gemini_embedding():
agents_openai_explicit = Agents(
agents=[agent2],
tasks=[task2],
verbose=5,
output="debug",
memory=True,
embedder={
"provider": "openai",
@@ -108,7 +108,7 @@ def test_gemini_embedding():
agents_gemini = Agents(
agents=[agent3],
tasks=[task3],
verbose=5,
output="debug",
memory=True,
embedder={
"provider": "gemini",
+12 -12
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
Test script to reproduce and verify the fix for issue #877
where callbacks only work when verbose=True.
where callbacks only work when output="verbose".
"""
import sys
@@ -36,11 +36,11 @@ with open('callback_log.txt', 'w') as f:
register_display_callback('interaction', simple_callback, is_async=False)
print("=" * 60)
print("Testing Issue #877: Callbacks Only Work When verbose=True")
print("Testing Issue #877: Callbacks Only Work When output="verbose"")
print("=" * 60)
# Test Case 1: verbose=False
print("\nTest Case 1: verbose=False")
# Test Case 1: output="silent"
print("\nTest Case 1: output="silent"")
print("-" * 30)
callback_log.clear()
@@ -50,7 +50,7 @@ agent1 = Agent(
goal="Help with tasks",
backstory="I am a helpful assistant",
llm="gemini/gemini-2.5-flash-lite-preview-06-17", # Using the same model as in the issue
verbose=False
output="silent"
)
task1 = Task(
@@ -68,17 +68,17 @@ try:
result1 = agents1.start()
print(f"Task completed. Callbacks executed: {len(callback_log)}")
if len(callback_log) > 0:
print("✅ SUCCESS: Callbacks were executed with verbose=False!")
print("✅ SUCCESS: Callbacks were executed with output="silent"!")
print(f" First callback: message='{callback_log[0]['message'][:50]}...', response='{callback_log[0]['response'][:50]}...'")
else:
print("❌ FAILED: No callbacks were executed with verbose=False")
print("❌ FAILED: No callbacks were executed with output="silent"")
except Exception as e:
print(f"❌ ERROR during test: {e}")
import traceback
traceback.print_exc()
# Test Case 2: verbose=True (for comparison)
print("\n\nTest Case 2: verbose=True (for comparison)")
# Test Case 2: output="verbose" (for comparison)
print("\n\nTest Case 2: output="verbose" (for comparison)")
print("-" * 30)
callback_log.clear()
@@ -88,7 +88,7 @@ agent2 = Agent(
goal="Help with tasks",
backstory="I am a helpful assistant",
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
verbose=True
output="verbose"
)
task2 = Task(
@@ -106,10 +106,10 @@ try:
result2 = agents2.start()
print(f"\nTask completed. Callbacks executed: {len(callback_log)}")
if len(callback_log) > 0:
print("✅ Callbacks were executed with verbose=True as expected")
print("✅ Callbacks were executed with output="verbose" as expected")
print(f" First callback: message='{callback_log[0]['message'][:50]}...', response='{callback_log[0]['response'][:50]}...'")
else:
print("⚠️ WARNING: No callbacks were executed even with verbose=True")
print("⚠️ WARNING: No callbacks were executed even with output="verbose"")
except Exception as e:
print(f"❌ ERROR during test: {e}")
import traceback
+5 -5
View File
@@ -23,7 +23,7 @@ article_agent = Agent(
goal="Fetch the user's favorite morning article",
tools=[fetch_favorite_article],
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
verbose=True
output="verbose"
)
news_agent = Agent(
@@ -32,7 +32,7 @@ news_agent = Agent(
goal="Search for trending news in Kenya",
tools=[search_trending_kenya],
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
verbose=True
output="verbose"
)
twitter_agent = Agent(
@@ -41,7 +41,7 @@ twitter_agent = Agent(
goal="Fetch the latest Twitter feed",
tools=[fetch_twitter_feed],
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
verbose=True
output="verbose"
)
aggregator = Agent(
@@ -49,7 +49,7 @@ aggregator = Agent(
role="Result Aggregator",
goal="Aggregate and summarize all results",
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
verbose=True
output="verbose"
)
# Tasks for each agent
@@ -94,7 +94,7 @@ async def main():
agents=[article_agent, news_agent, twitter_agent, aggregator],
tasks=[article_task, news_task, twitter_task, aggregate_task],
process="workflow",
verbose=True
output="verbose"
)
results = await workflow.astart()
+3 -3
View File
@@ -60,7 +60,7 @@ def test_router_agent():
goal="Test multi-model functionality",
models=["gpt-4o-mini"], # Using single model for testing
routing_strategy="auto",
verbose=False
output="silent"
)
print(f"Agent created: {agent.name}")
@@ -88,7 +88,7 @@ def test_integration():
goal="Test the integration",
models=["gpt-4o-mini"], # Single model for testing
routing_strategy="manual", # Use manual to avoid complexity
verbose=False
output="silent"
)
# Create a simple task
@@ -104,7 +104,7 @@ def test_integration():
agents=[agent],
tasks=[task],
process="sequential",
verbose=False
output="silent"
)
print("Created Agents with RouterAgent")
@@ -11,7 +11,7 @@ agent1 = Agent(
name="Assistant",
llm="gpt-4o-mini",
planning=True,
verbose=False
output="silent"
)
result1 = agent1.start("Write 2 sentences about AI in healthcare")
print(f"\nResult: {result1[:200]}...")
@@ -25,7 +25,7 @@ agent2 = Agent(
llm="gpt-4o-mini",
planning=True,
planning_tools=[search_web],
verbose=False
output="silent"
)
result2 = agent2.start("Write 2 sentences about AI trends")
print(f"\nResult: {result2[:200]}...")
@@ -40,7 +40,7 @@ agent3 = Agent(
planning=True,
planning_tools=[search_web],
planning_reasoning=True,
verbose=False
output="silent"
)
result3 = agent3.start("Write 2 sentences about AI trends")
print(f"\nResult: {result3[:200]}...")
@@ -52,7 +52,7 @@ print("=" * 60)
agent4 = Agent(
name="Assistant",
llm="gpt-4o-mini",
verbose=False
output="silent"
)
result4 = agent4.start("Write 2 sentences about AI trends")
print(f"\nResult: {result4[:200]}...")
@@ -44,7 +44,7 @@ def main():
role="Research Analyst",
goal="Research topics thoroughly and provide accurate information",
backstory="Expert researcher with access to vast knowledge bases",
verbose=True
output="verbose"
)
writer = Agent(
@@ -52,7 +52,7 @@ def main():
role="Content Writer",
goal="Write clear, engaging, and well-structured content",
backstory="Professional writer skilled in creating compelling narratives",
verbose=True
output="verbose"
)
print("✅ Agents created: Researcher, Writer\n")
+6 -6
View File
@@ -89,7 +89,7 @@ def test_real_streaming():
for name, model in providers:
print(f"\n{'='*60}")
print(f"Testing real streaming with {name}")
print(f"Configuration: stream=True, verbose=True")
print(f"Configuration: stream=True, output="verbose"")
print(f"{'='*60}\n")
try:
@@ -100,7 +100,7 @@ def test_real_streaming():
backstory=f"Testing {name} streaming",
llm=model,
stream=True,
verbose=True
output="verbose"
)
response = agent.chat("Write a haiku about streaming data.")
@@ -123,7 +123,7 @@ if __name__ == "__main__":
print("\n\nAll tests completed!")
print("\nSummary of expected behaviors:")
print("- stream=True, verbose=True: Real-time streaming with content display")
print("- stream=True, verbose=False: Real-time streaming, no display")
print("- stream=False, verbose=True: 'Generating...' animation, no content")
print("- stream=False, verbose=False: No display at all")
print("- stream=True, output="verbose": Real-time streaming with content display")
print("- stream=True, output="silent": Real-time streaming, no display")
print("- stream=False, output="verbose": 'Generating...' animation, no content")
print("- stream=False, output="silent": No display at all")
+2 -2
View File
@@ -31,7 +31,7 @@ def test_llm_self_reflection():
reflection=True,
min_reflect=1,
max_reflect=3,
verbose=True
output="verbose"
)
print(f"LLM Response: {response}")
print()
@@ -45,7 +45,7 @@ def test_llm_no_reflection():
prompt="What is 2+2? Be brief.",
system_prompt="You are a helpful assistant.",
reflection=False,
verbose=True
output="verbose"
)
print(f"LLM Response: {response}")
print()
@@ -37,7 +37,7 @@ def test_self_reflection_with_tools():
backstory="You are an expert analyst with strong critical thinking skills",
reflection=True,
llm="gpt-4o-mini", # Using OpenAI model for testing
verbose=True,
output="verbose",
tools=[mock_tool],
max_reflect=2, # Keep it small for testing
min_reflect=1
@@ -77,7 +77,7 @@ def test_self_reflection_without_tools():
backstory="You are an expert analyst with strong critical thinking skills",
reflection=True,
llm="gpt-4o-mini", # Using OpenAI model for testing
verbose=True,
output="verbose",
max_reflect=2, # Keep it small for testing
min_reflect=1
)
@@ -131,7 +131,7 @@ def test_llm_directly():
reflection=True,
max_reflect=2,
min_reflect=1,
verbose=True,
output="verbose",
execute_tool_fn=mock_tool_executor
)
Loaded 100 of 123 files, more files were not shown because too many files have changed in this diff. Show more