- Added execute_sync_callback call in custom LLM path to match OpenAI behavior
- Fixed issue where Gemini/custom LLM responses were not triggering callbacks
- Prevents duplicate display by relying on LLM class to handle verbose display
- Ensures both paths execute callbacks for consistent behavior
The issue was that custom LLM providers (like Gemini) were not calling
_execute_callback_and_display after guardrail validation, while OpenAI
path was. This caused missing Task/Response display boxes for Gemini.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Fix inconsistency in custom LLM path (line 1116) to match OpenAI path behavior
- Update test script to verify all three fix locations (2 OpenAI + 1 custom LLM)
- Ensure no streaming-like behavior when stream=False regardless of LLM provider
- Maintain backward compatibility and existing functionality
Co-authored-by: Mervin Praison <[email protected]>
When stream=false but verbose=true, the system was incorrectly showing
streaming-like visual behavior (Generating... X.Xs) due to display_generating
being used even when users explicitly set stream=false.
Fixed by changing display_fn from display_generating to None when stream=false
in both locations (lines 1073 and 1172) in agent.py.
This ensures true non-streaming behavior when stream=false is set, regardless
of verbose setting.
Co-authored-by: Mervin Praison <[email protected]>
- Add missing display_fn support to async version (achat_completion_with_tools)
- Add proper error handling with try-catch around Live context manager
- Add safer content access with length checks for choices array
- Add console cleanup (console.print()) consistent with streaming mode
- Maintain backward compatibility with fallback to regular completion
Co-authored-by: Mervin Praison <[email protected]>
- Fix stream parameter not being explicitly passed in start() method
- Ensures display_generating shows when agent.start() is called with default settings
- Agent defaults: verbose=True, stream=False should show ''Generating...'' message
- Resolves issue where chat() method default stream=True overrode agent''s stream=False setting
- Tested logic flow: (not stream and verbose) now correctly evaluates to True
Co-authored-by: Mervin Praison <[email protected]>
- Fixed critical control flow bug where streaming errors set use_streaming=False
but continued executing in streaming block instead of triggering fallback
- When recoverable streaming error occurs, immediately perform actual non-streaming
API call instead of creating mock response with partial/empty data
- Added proper callback handling for both verbose/non-verbose modes
- Enhanced graceful degradation if both streaming and non-streaming fail
- Updated test to use agent.llm_model instead of agent.llm property
Fixes: Issue #1043 streaming JSON parsing errors causing "Response: None"
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Mervin Praison <[email protected]>
Fixed critical bug where (not True and self.verbose) was always False,
preventing display_generating from ever being called in one code path.
Changed to (not stream and self.verbose) to match intended logic.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Change logic from (stream or verbose) to (not stream and verbose)
- Ensure display_generating only appears for non-streaming verbose mode
- Remove streaming display blocks since no display needed when streaming
- Update test files to reflect correct expected behavior
Co-authored-by: Mervin Praison <[email protected]>
- Extend fix to custom LLM providers (Anthropic, Groq, local models)
- Add Live display wrapper for non-streaming custom LLM path
- Ensure consistent behavior: display when (stream OR verbose)
- Maintain backward compatibility for all existing functionality
- Add comprehensive test coverage for both agent paths
Fixes#981 completely for all LLM provider types
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Fix issue where display_generating was only called during streaming
- Now display_generating is called when either stream=True OR verbose=True
- Resolves user issue where verbose=True with default stream=False wasn''t showing ''Generating...'' display
- Add logic tests to verify the fix
Co-authored-by: Mervin Praison <[email protected]>
Remove redundant loops that iterate over all loggers to suppress litellm
submodules. Python''s hierarchical logging automatically propagates the
CRITICAL level from parent ''litellm'' logger to all child loggers
(litellm.utils, litellm.proxy, etc.).
Changes:
- Remove 3 redundant loops in __init__.py and llm/__init__.py
- Remove explicit configuration of child loggers (litellm.utils, etc.)
- Maintain litellm_logging as separate hierarchy (not a child of litellm)
- Add explanatory comments about hierarchical logging inheritance
- Preserve backward compatibility and DEBUG mode behavior
Performance: Eliminates unnecessary iteration over all existing loggers
while maintaining identical logging suppression behavior.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Fix ZeroDivisionError in 02_multi_agent_workflow_monitoring.py by adding zero-check for call counts
- Improve async handling in 04_async_agent_monitoring.py with better simulation and timing
- Fix UnboundLocalError in 05_error_handling_monitoring.py by correcting variable references
- Add zero-check protection in 07_hierarchical_agents_monitoring.py to prevent division errors
- Remove unused json import from 08_custom_tools_monitoring.py
- Remove unused timedelta import from 09_streaming_monitoring.py
- Fix UnboundLocalError in 10_comprehensive_dashboard.py by initializing avg_function_time variable
🤖 Generated with Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Create examples/python/monitoring/ directory with 10 diverse examples
- Cover basic monitoring, multi-agent workflows, tools, async, errors, memory, hierarchical, custom tools, streaming, and comprehensive dashboard
- Each example demonstrates different aspects of the performance monitoring system
- Include detailed README with usage patterns and best practices
- Show practical integration of @monitor_function and track_api_call
- Demonstrate performance analytics, reporting, and optimization insights
Co-authored-by: Mervin Praison <[email protected]>
- Implement missing DEBUG mode functionality as specified in PR description
- Add _should_suppress_warnings() function to respect LOGLEVEL=DEBUG
- Fix overly broad global warning suppression (now module-specific)
- Remove unsafe pydantic.warnings.warn monkey-patching
- Improve test detection with pytest module checks
- Add comprehensive test scripts for validation
Key improvements:
• Warnings are suppressed in normal mode (LOGLEVEL=INFO)
• Warnings are shown when LOGLEVEL=DEBUG (as per PR requirement)
• More targeted warning suppression (module-specific vs global)
• Safer pydantic warning handling with specific filters
• Better backward compatibility and security
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Mervin Praison <[email protected]>
- Remove unused imports (inspect, timedelta, time, deque, etc.)
- Fix division by zero error in performance trend analysis
- Improve call chain building algorithm for better efficiency and accuracy
- Replace bare except clauses with specific Exception handling
- Use collections.deque with maxlen instead of manual truncation
- Remove unused variables and loop variables
- Fix f-strings without placeholders
- Replace magic numbers with named constants
- Improve error handling specificity
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
This implementation addresses all requirements from Issue #1035:
Features Added:
- PerformanceMonitor class for function performance evaluation with detailed statistics
- FunctionFlowAnalyzer for execution flow visualization and bottleneck identification
- API call tracking and performance comparison (fast vs slow calls)
- Real-time performance reporting and comprehensive analytics
- CLI interface for easy command-line access to performance data
- Full backward compatibility with existing telemetry system
Key Capabilities:
1. Function Performance Evaluation: Decorators and context managers for automatic timing
2. Function Flow Analysis: Visual execution flow with bottleneck detection
3. Execution Speed Analysis: Min/max/average timing with trend analysis
4. API Call Performance: Success rates, response times, reliability metrics
5. API Call Visibility: Complete tracking and history of all API interactions
Files Modified:
- Enhanced telemetry/__init__.py to expose new performance tools
- Added performance_monitor.py with core monitoring functionality
- Added performance_utils.py with advanced analysis and visualization
- Added performance_cli.py for command-line interface
- Added comprehensive demo and examples
Integration:
- Seamless integration with existing PraisonAI telemetry infrastructure
- Zero breaking changes to existing functionality
- Optional import structure for graceful degradation
- Thread-safe operations with memory management
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Add environment variables to suppress warnings at source (LITELLM_TELEMETRY, HTTPX_DISABLE_WARNINGS)
- Implement global deprecation warning filters before imports
- Add specific message filters for exact warning text patterns
- Set aggressive logging levels (CRITICAL) for all litellm loggers
- Configure runtime litellm settings to disable debug output
- Apply comprehensive suppression across main and LLM modules
- Addresses remaining warnings from httpx content parameter and pydantic dict method usage
Resolves issue with persistent litellm warnings after initial fix
Co-authored-by: Mervin Praison <[email protected]>
- Fix critical bug where tool_call[''function''][''arguments''] was passed as JSON string instead of parsed dict to execute_tool
- Add proper JSON parsing with fallback to empty dict for missing arguments
- Resolves tool execution failures during streaming when tools are called
- Maintains backward compatibility and error handling
Co-authored-by: Mervin Praison <[email protected]>
Added comprehensive deprecation warning filters to suppress warnings from:
- litellm module and event loop related warnings
- httpx module deprecation warnings
- Pydantic model_dump deprecation warnings
This resolves the noisy deprecation warnings that were cluttering the output
when using PraisonAI agents with newer versions of dependencies.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
Co-authored-by: Mervin Praison <[email protected]>
The remote branch already implements a more comprehensive solution using
threading at the integration level, which addresses the streaming pause issue
more thoroughly than the async_mode parameter approach.
Remote changes include:
- All telemetry tracking made asynchronous using background threads
- Special handling for streaming generators in agent.start()
- Better error handling with try/catch blocks
- Maintains the async_mode parameter in telemetry.py for future use
Resolves streaming pause issue #1031
- Make telemetry tracking asynchronous in all agent methods (chat, start, run)
- For streaming responses, defer telemetry tracking until after generator consumption
- Use separate daemon threads to prevent blocking on PostHog capture calls
- Add comprehensive test script to verify fix works
- Fixes issue where ~20 second pause occurred after ''execution tracked: success=True''
This resolves the streaming performance issue where telemetry calls were
blocking the start of streaming responses, causing users to wait before
seeing any output when using agent.start() with stream=True.
Co-authored-by: Mervin Praison <[email protected]>
This fix modifies Agent._start_stream() to handle OpenAI-style models with direct
streaming that bypasses the display_generation UI, allowing users to get raw
streaming chunks when stream=True.
Key changes:
- Replace self.chat() fallback with direct OpenAI client streaming
- Add proper knowledge search and tool handling for OpenAI path
- Use _build_messages helper for consistent message formatting
- Yield raw chunks without display function interference
- Add robust error handling with chat history rollback
- Preserve fallback to simulated streaming on errors
Fixes streaming behavior where chunks were wrapped in display_generation
instead of being yielded directly to user code.
Co-authored-by: Mervin Praison <[email protected]>
- Add chunk-level error handling in get_response_stream() to catch malformed JSON chunks
- Implement smart error recovery that skips recoverable errors (JSON parsing) vs non-recoverable (connection)
- Add consecutive error limit (3) with automatic fallback to non-streaming mode
- Enhance error logging with specific categorization for better debugging
- Add _is_streaming_error_recoverable() helper method for error classification
- Create test script to validate streaming robustness improvements
Fixes issue where Gemini streaming fails with ''Expecting property name enclosed in double quotes''
when receiving incomplete JSON chunks like ''{'' during streaming responses.
Co-authored-by: Mervin Praison <[email protected]>
- Remove erroneous temperature parameter from _build_messages() call in get_response_stream()
- Fix critical bug that would cause TypeError during streaming
- Tool call handling already implemented with _process_stream_delta helper
- Real-time streaming now works with content and tool execution
- Follow-up responses after tool completion properly handled
- Backward compatibility maintained with stream=False default
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
Fixes critical gap in get_response_stream method where tool calls were
completely ignored during streaming. The method now properly:
- Accumulates tool calls during streaming using _process_stream_delta
- Executes tool calls after streaming completes if execute_tool_fn provided
- Continues conversation with follow-up response after tool execution
- Handles both Ollama and other providers correctly
- Maintains real-time content streaming while adding tool support
This makes streaming fully functional for agents that use tools, which
is essential for PraisonAI''s core functionality.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Mervin Praison <[email protected]>
- Add get_response_stream() generator method to LLM class for true real-time streaming
- Modify Agent._start_stream() to use new streaming generator for custom LLMs
- Replace simulated streaming with actual LiteLLM streaming chunks
- Maintain backward compatibility for OpenAI-style models (temporary fallback)
- Add comprehensive error handling and chat history management
- Include test files for validation
Fixes the issue where streaming was simulated by chunking complete responses
instead of yielding real-time chunks from the underlying LLM.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Replace duplicated logic in _custom_llm_stream() and _openai_stream() with single _start_stream() method
- Reuse existing chat() method logic to maintain all features (tools, knowledge, MCP, etc.)
- Improve error handling and consistency across LLM types
- Maintain backward compatibility and all existing functionality
- Reduce maintenance burden by eliminating 150+ lines of duplicated code
Co-authored-by: Mervin Praison <[email protected]>
- Fix streaming issue where Agent.start() was not yielding real-time chunks
- Add streaming generator support with proper type hints
- Implement _start_stream() method that routes to appropriate handlers
- Add _custom_llm_stream() for custom LLM providers with simulated chunking
- Add _openai_stream() for OpenAI client with true streaming chunks
- Maintain backward compatibility for existing non-streaming usage
- Support both OpenAI and custom LLM streaming with graceful error handling
- Preserve chat history management and proper conversation state
The user''s code pattern now works as expected:
for chunk in agent.start(prompt, stream=True):
print(chunk, end='''', flush=True)
Fixes#981
Co-authored-by: Mervin Praison <[email protected]>
- Fix f-string formatting issues by removing unnecessary f prefix
- Add return type hint to handle_context_command method
- Enhance docstring with return type documentation
- Maintain backward compatibility with existing usage
Co-authored-by: Mervin Praison <[email protected]>
- Add --auto-analyze flag for user control over analysis mode
- Use environment MODEL_NAME/OPENAI_MODEL_NAME instead of hardcoded model
- Update usage messages to include new optional flag
- Follow existing CLI patterns for model configuration
- Maintain backward compatibility with defaults
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Support both ''vector_store'' and ''embedding_db_config'' keys for knowledge context
- Maintains backward compatibility with existing test files
- No functional changes to the verbose header removal functionality
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
This commit transforms all hardcoded analysis methods in ContextAgent to use specialized AI agents for dynamic analysis. The changes enable more flexible, intelligent, and adaptable context processing by leveraging agent-based approaches instead of static analysis patterns.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Remove ''[DB Context]:'' and ''[Vector DB Error]:'' prefixes from agent outputs
- Add debug logging to preserve troubleshooting information
- Return clean content without verbose headers in terminal display
- Hide error details from AI prompts while preserving debug logs
- Consistent with memory.py verbose header removal approach
Co-authored-by: Mervin Praison <[email protected]>
- Add include_in_output parameter to build_context_for_task() method
- Memory content now only included in output when logging level is DEBUG
- Memory is always logged for debugging regardless of output inclusion
- Preserves AI agent functionality while hiding memory from user display
- Addresses user requirement to hide memory items from terminal by default
Co-authored-by: Mervin Praison <[email protected]>
- Move test_embedding_logging.py from root to tests/ directory for better organization
- Improve test structure with comprehensive TRACE logging validation
- Ensure proper test isolation and cleanup
- Maintain backward compatibility while improving code organization
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Mervin Praison <[email protected]>
Co-Authored-By: Claude <[email protected]>
- Fixed core ContextAgent functionality with proper imports and async support
- Added comprehensive error handling and robust implementation
- Cleaned up imports and fixed async method patterns
- Moved test file from root to proper tests/ directory location
- Made implementation fully functional with all required methods
- Enhanced examples with working context engineering workflows
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Remove ''Short-term Memory (X items)'' and ''Long-term Memory (X items)'' headers from AI prompts
- Remove ''Relevant Memory Context:'' and ''Previous task'' prefixes from agent context
- Keep actual memory content and task results for AI functionality
- Move verbose information to debug logging only
- Prevents AI agents from echoing memory context headers in terminal output
This fixes the issue where memory context headers were still appearing in terminal
displays even after the original PR moved verbose information to debug logging.
Co-authored-by: Mervin Praison <[email protected]>
- Add ContextAgent class with comprehensive Context Engineering capabilities
- Implements automated context generation for AI coding assistants
- Features: codebase analysis, pattern extraction, validation loops, PRP generation
- 10x better than prompt engineering, 100x better than vibe coding
- Includes factory function create_context_agent() for easy instantiation
- Add comprehensive examples in agents/ and concepts/ directories
- Full backward compatibility maintained with existing PraisonAI functionality
- Complete test suite with 7/7 tests passing
Co-authored-by: Mervin Praison <[email protected]>
- agents.py: Restore actual task result content and memory context in AI prompts
- task.py: Include actual task context results for proper task chaining
- memory.py: Return actual memory content with clean formatting instead of placeholders
- Fix f-string formatting issue in agents.py
This fixes critical functionality bugs where AI agents were receiving placeholder
messages instead of actual content, breaking memory access and task dependencies.
AI agents now get full context while debug logging is preserved.
Resolves issues identified by automated reviews while maintaining backward compatibility.
Co-authored-by: Mervin Praison <[email protected]>
- Add TRACE_LEVEL (5) below DEBUG (10) for fine-grained logging control
- Implement trace() method on logging.Logger class for backward compatibility
- Convert 4 embedding-related debug statements to use trace level
- Embedding data now only appears when logging level set to TRACE or lower
- Maintains full backward compatibility with existing debug logging
- Addresses issue where sensitive embedding data cluttered terminal output
Test coverage:
- Add test_embedding_logging.py to validate implementation functionality
- Verify TRACE level behavior and message filtering
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Add type checking for memory_result in _process_single_input method
- Handle both dict and list formats for backward compatibility
- Gracefully handle unexpected types with warning instead of crashing
- Resolves issue #1016 where MongoDB memory provider returns dict while Chroma returns list
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
This commit addresses live display context issues by moving detailed content
from user-facing prompts to debug logging while maintaining functionality:
- agents.py line 653: Memory context now logged via logger.debug() with
brief user-facing note in prompt instead of full content
- agents.py line 84: Previous task results logged via logger.debug() with
brief completion status returned instead of full raw content
- task.py line 406: Previous task results logged via logger.debug() with
brief completion message appended instead of full raw content
- memory.py: Memory section headers now use brief titles with item counts
and log detailed content via logger.debug() instead of showing full content
These changes maintain backward compatibility and functionality while
improving user experience by reducing verbose output in live displays.
Detailed information remains available through debug logging for debugging
and troubleshooting purposes.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
Fixed line 717 in knowledge.py where memory_result.get(''results'', [])
was called on a list instead of a dict. Both MongoDBMemory.add() and
CustomMemory._add_to_vector_store() return lists directly, so changed
to all_results.extend(memory_result) for proper list concatenation.
Resolves#1016
Co-authored-by: Mervin Praison <[email protected]>
- Add DEBUG logging level when verbose >= 3
- Maintain INFO level for verbose >= 5
- Keep WARNING level for verbose < 3
- This makes the verbose flag functional for debugging purposes
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
Changed logger.info to logger.debug for context content display
in agents.py to reduce log noise while maintaining the ability
to see context information when debug logging is enabled.
Changes:
- agents.py:315 - Context content logging moved to debug level
- agents.py:638 - Context content logging moved to debug level
Maintains backward compatibility as context count logging remains
at INFO level, only the actual context content is moved to DEBUG.
Fixes#1014
Co-authored-by: Mervin Praison <[email protected]>
- Removed unnecessary force_shutdown_telemetry() call from basic-agents.py to enhance clarity.
- Updated llm parameter in gemini-sequential.py from "gemini-2.5-pro" to "gemini-2.5-flash" for improved performance.
- Simplified the for loop in realtime-streaming.py by removing the return_generator=True argument, maintaining functionality while improving readability.
These changes aim to enhance code efficiency and maintainability without altering existing functionality.
- Add interpreter shutdown detection using sys.is_finalizing() and thread tests
- Skip PostHog operations when interpreter is shutting down to prevent:
- cannot schedule new futures after interpreter shutdown errors
- can''t register atexit after shutdown errors
- Event loop and threading errors during shutdown
- Enhanced error handling with specific shutdown error message filtering
- Apply shutdown prevention to flush, thread cleanup, and shutdown operations
- Maintain full backward compatibility with existing API
- Add comprehensive debug logging for shutdown scenarios
Fixes issue #1011 where PostHog telemetry was causing shutdown errors
when force_shutdown_telemetry() was called during interpreter shutdown.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Add thread safety with shutdown locks to prevent concurrent shutdown calls
- Fix double thread pool shutdown issue that could cause undefined behavior
- Implement memory leak prevention with bounded metrics storage (max 1000 entries)
- Replace unsafe daemon threads with ThreadPoolExecutor for better control
- Increase flush timeout from 2s to 5s for improved reliability
- Add comprehensive error handling with proper logging levels
- Split shutdown logic into maintainable helper methods
- Maintain full backward compatibility with existing API
These changes address critical thread safety issues while preserving all
existing functionality and ensuring reliable telemetry shutdown behavior.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Added timeout-based flush operation in MinimalTelemetry.shutdown()
- Replaced blocking PostHog flush with threaded timeout approach
- Prevents indefinite blocking during program termination
- Maintains backward compatibility and data integrity
- Fixes issue where PostHog queue.join() would hang on exit
Resolves#1009
Co-authored-by: Mervin Praison <[email protected]>
- Simplified logging of parameters in debug mode for better clarity.
- Enhanced error handling during LLM calls and reflections to ensure robust rollback mechanisms.
- Improved structure for handling knowledge search and prompt normalization.
- Reduced code duplication by integrating common functionalities into streamlined processes.
- Replace 13 scattered _cleanup_telemetry() calls with single try...finally block
- Ensure cleanup happens on ALL exit paths regardless of success/failure
- Standardize test tolerances to 2 threads across all test files
- Improve test error messages to show specific thread details
- Maintain backward compatibility and all existing functionality
- Reduce code duplication by 95% in chat method
🤖 Generated with Claude Code
Co-authored-by: Mervin Praison <[email protected]>
- Modified Agent.start() method to automatically consume the generator by default
- Added return_generator=True parameter for backwards compatibility
- Made MCP import optional to prevent import errors
- Updated examples to demonstrate new behavior
- Fixes issue where basic-agents.py would stop without producing output
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
This commit addresses the critical issue where PraisonAI agents would not
terminate properly after completing their tasks, requiring manual interruption.
Root Cause: PostHog telemetry client running in async mode creates
background threads that persist after standard shutdown() calls.
Solution:
- Enhanced telemetry shutdown mechanism with comprehensive thread cleanup
- Added force_shutdown_telemetry() function for robust cleanup
- Implemented timeout-based thread termination with proper error handling
- Updated agent._cleanup_telemetry() to use the new robust cleanup method
Impact:
- Agents now terminate cleanly without hanging
- Maintains full backward compatibility
- Comprehensive thread cleanup prevents resource leaks
- Timeout mechanism prevents infinite waiting
Co-authored-by: Mervin Praison <[email protected]>
- Added _cleanup_telemetry() calls to all return paths in chat() and achat() methods
- Ensures proper program termination without requiring Ctrl+C
- Maintains full backward compatibility with existing APIs
- Addresses syntax error concerns by implementing clean, error-free code
- Added test script to verify the fix works correctly
Co-authored-by: Mervin Praison <[email protected]>
- Fixed syntax error at line 1197 where code was outside try block
- Properly indented all main logic to be inside try block
- Ensures telemetry cleanup finally block executes correctly
- Maintains backward compatibility
- No breaking changes
Co-authored-by: Mervin Praison <[email protected]>
- Added telemetry cleanup to all agent entry points (chat, achat, execute, aexecute)
- Fixed streaming issue by adding cleanup to _start_stream method
- Removed duplicate cleanup from convenience methods
- Ensures proper program termination regardless of which method is used
Co-authored-by: Mervin Praison <[email protected]>
- Fix ID generation consistency between MongoDB and SQLite storage
- Fix inconsistent error handling in memory operations
- Fix security issue with hardcoded API key placeholders in examples
- Fix unused imports in mongodb_tools.py
- Fix pymongo version to >= 4.6.3 to address security vulnerabilities
- Improve datetime import organization
- Ensure consistent storage order for better reliability
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Fix memory record citation duplication (lines 861, 880, 933 in memory.py)
- Make vector dimensions configurable based on embedding model
- Add _get_embedding_dimensions method for proper dimension detection
- Support multiple embedding models (text-embedding-3-small, 3-large, ada-002)
- Improve citation format to use record IDs instead of duplicating text
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
Add comprehensive MongoDB integration for PraisonAI agents including:
**Memory Provider**:
- MongoDB as persistent memory storage option
- Vector search capabilities with Atlas Vector Search
- Support for both key-value and vector operations
- Quality scoring and filtering
- User-specific memory isolation
- Graceful fallback to existing SQLite/ChromaDB
**Knowledge Store**:
- MongoDB as vector store for knowledge base
- Document processing with embeddings
- Vector similarity search for knowledge retrieval
- Chunking and metadata management
- Compatible with existing Mem0/ChromaDB workflow
**Tools Integration**:
- Complete MongoDB tools suite (CRUD operations)
- Vector search and text search capabilities
- Collection management and indexing
- Production-ready connection handling
- Error handling and logging
**Examples**:
- Memory provider example with persistent storage
- Knowledge store example with vector search
- Tools integration example with database operations
- Comprehensive business scenario simulation
- Complete documentation and best practices
**Technical Details**:
- Optional dependency: pip install ''praisonaiagents[mongodb]''
- Backward compatibility maintained
- Supports both local MongoDB and Atlas
- Configurable connection pooling and timeouts
- Comprehensive error handling
Resolves#992🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Mervin Praison <[email protected]>
- Fix chat_history_length initialization bug in both streaming methods
- Add safe array access checks for chunk.choices in OpenAI client
- Add JSON parsing error handling for malformed tool arguments
- Remove unused imports and variables
- Update test files to use mock LLM instead of real APIs
- Ensure robust error handling throughout streaming pipeline
These fixes address all critical issues identified by code review bots
while maintaining backward compatibility and streaming functionality.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Add thread locks to MCPToolRunner._tool_timings and MinimalTelemetry._metrics
- Fix initialization timeout bug where telemetry tracking was bypassed
- Move timing measurement after initialization check for accuracy
- Ensure telemetry is captured for all tool execution outcomes
Co-authored-by: Mervin Praison <[email protected]>
- Enhanced telemetry.track_tool_usage() to accept execution_time parameter
- Added timing instrumentation to MCPToolRunner.call_tool() method
- Tool usage timing is now captured and stored in telemetry metrics
- Maintains backward compatibility with no breaking changes
- Addresses issue #988 where tool usage time was always 0
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Add proper cleanup in Agent.start() and Agent.astart() methods using try-finally blocks
- Implement _cleanup_telemetry() method to ensure telemetry system shutdown
- Prevent hanging after agent execution by properly shutting down background threads
- Add test files to verify the termination fix works correctly
Fixes#987🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
Fixes critical issues identified in PR review:
- Move early stopping logic from inside ''if tool_calls:'' block to ''else:'' block
- Fix logic placement in both sync and async execution paths
- Remove unreachable code in _generate_ollama_tool_summary()
- Ensure early stopping triggers correctly when Ollama returns empty responses after tool execution
This ensures the fix properly handles the Ollama edge case where it returns
empty responses after successful tool execution, preventing infinite loops
while allowing proper sequential tool calls.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
Ensures TelemetryCollector.stop() calls shutdown() instead of just flush()
for consistency with the main atexit handler and proper PostHog session cleanup.
Co-authored-by: Mervin Praison <[email protected]>
- Only trigger early stopping when no new tool calls are present in current response
- Prevents premature termination during sequential tool calls like get_stock_price -> multiply
- Maintains backward compatibility while fixing issue #964
- Applied to both sync and async execution paths
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Add early stopping logic for Ollama after first successful tool execution
- Enhance tool summary generation to create more natural, OpenAI-like responses
- Apply fix to both sync and async execution paths
- Prevent multiple tool calls when execution is complete
- Maintains full backward compatibility
Co-authored-by: Mervin Praison <[email protected]>
- Added _final_display_shown = False reset in achat() method to match chat() method
- Ensures proper display flag management for both sync and async agent interactions
- Maintains consistency across all agent conversation entry points
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Removed unused custom_display_fn function that was defined but never called
- Cleanup after streaming fix to avoid confusion
- No functional changes, streaming fix remains intact
Co-authored-by: Mervin Praison <[email protected]>
- Remove dependency on verbose=True for streaming display function
- Allow stream=True to work with verbose=False for real-time output
- Maintain backward compatibility with existing verbose=True usage
- Fixes issue where Gemini/Google Vertex AI streaming was buffered
Resolves#956
Co-authored-by: Mervin Praison <[email protected]>
Adds missing callback execution to tool-based responses and JSON/Pydantic
output paths in the achat() method to ensure consistent task metadata
propagation across all execution flows.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Modified display condition to show formatted output for both OpenAI and custom LLM providers (like Gemini)
- Added _final_display_shown flag to prevent duplicate displays within same execution
- Reset flag at start of each chat() call for new conversations
- Maintains backward compatibility and existing verbose control behavior
Fixes#958🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Add task_name, task_description, task_id parameters to achat method signature
- Update all achat call sites in agents.py to pass task parameters where available
- Provide fallback None values for API handler contexts without task context
- Fix Agent.aexecute to extract task info when available
- Resolves NameError: name ''task_name'' is not defined in parallel agent execution
Fixes persistent errors in agentic parallelization workflows where callbacks
expect task context parameters but they were not being passed correctly through
the async execution chain.
Co-authored-by: Mervin Praison <[email protected]>
- After successful tool execution, give Ollama LLM explicit prompt for final answer
- Only generate tool summary if LLM fails to respond to explicit prompt
- Prevents premature tool summary generation after sequential execution
- Applied to both sync and async tool execution loops
- Preserves infinite loop prevention while enabling natural responses
Fixes#940
Co-authored-by: Mervin Praison <[email protected]>
- Replace hardcoded iteration threshold (3) with class constant OLLAMA_SUMMARY_ITERATION_THRESHOLD
- Add proper constant definition for better maintainability and readability
- Applied consistently to both sync and async methods
- Addresses reviewer feedback about magic numbers
- Ensures proper tool result accumulation across iterations
Co-authored-by: Mervin Praison <[email protected]>
- Add accumulated_tool_results list to store tool results across all iterations
- Prevents loss of tool execution history when generating summaries
- Applied to both sync (get_response) and async (get_response_async) methods
- Maintains backward compatibility with existing functionality
- Fixes issue where only current iteration''s tool results were available to summary generation
Co-authored-by: Mervin Praison <[email protected]>
- Remove redundant length check in _generate_ollama_tool_summary
- Simplify verbose conditional checks in both sync and async methods
- Add safety checks to prevent infinite loops after 5 iterations
- Maintain backward compatibility with other LLM providers
- Add comprehensive test suite to validate fixes
Co-authored-by: Mervin Praison <[email protected]>
- Replace manual symbol list with dynamic import using
- Use for automatic maintenance
- Remove manual tracking of imported symbols
- Reduce code from 49 to 17 lines
- Future-proof: automatically inherits new exports from praisonaiagents
Co-authored-by: Mervin Praison <[email protected]>
- Modified tool execution logic to allow at least 3 iterations before triggering summary generation
- This prevents Ollama from prematurely terminating when sequential tool calls are needed
- Applied fix to both conversation() and reasoning() methods in LLM class
- Resolves issue where Ollama would generate tool summaries too early, blocking proper tool chaining
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Mervin Praison <[email protected]>
- Fixed critical bug where __all__ list included symbols from praisonaiagents
even when import failed due to missing dependencies
- Implemented dynamic __all__ construction based on successfully imported symbols
- Maintained backward compatibility while fixing the cursor review issue
- Added comprehensive test files to verify fix and backward compatibility
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Changed register_callback to register_display_callback
- Ensures test runs correctly and validates the fix
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
This change allows users to import from the main PraisonAI package instead of
just from praisonaiagents, while maintaining full backward compatibility.
Changes:
- Modified src/praisonai/praisonai/__init__.py to re-export all classes from praisonaiagents
- Added comprehensive __all__ list for proper exports
- Maintained backward compatibility - all existing imports continue to work
New usage patterns now supported:
- from praisonai import Agent, Task, PraisonAIAgents
- from praisonai import Tools, Memory, Knowledge, etc.
Backward compatibility maintained:
- from praisonaiagents import Agent, Task, PraisonAIAgents (still works)
Tests added:
- test_import_conversion.py: Comprehensive test suite
- test_issue_950.py: Specific test for the issue requirements
Resolves#950🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Added iteration count threshold (>=5) before generating Ollama tool summary
- Prevents premature termination after first tool call in sequential execution
- Maintains infinite loop prevention for truly stuck scenarios
- Applied fix to both sync and async methods in llm.py
- Preserves backward compatibility with other LLM providers
Fixes issue where Ollama would terminate after first tool call instead of
continuing with sequential execution (e.g., get_stock_price -> multiply)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Add condition to check if final_response_text is already set before overwriting
- Fix applies to both sync (get_response) and async (get_response_async) methods
- Prevents tool summary from being lost when Ollama returns empty response after tool execution
- Maintains backward compatibility for non-Ollama providers
- Resolves issue where agent.start() returns None despite successful tool execution
Fixes the remaining issue from PR #943 where tool summary was generated but overwritten
Co-authored-by: Mervin Praison <[email protected]>
- Move callback systems to general/
- Move memory examples to memory/
- Move state management to stateful/
- Move hierarchical agents to agents/
- Move guardrails to guardrails/
- Move self-reflection to concepts/
Co-authored-by: Mervin Praison <[email protected]>
- Extract duplicated Ollama tool summary logic into _generate_ollama_tool_summary() helper method
- Replace magic number 10 with OLLAMA_MIN_RESPONSE_LENGTH constant
- Fix test_tool_summary_generation() to call production code instead of reimplementing logic
- Add comprehensive test scenarios for different response types and provider types
- Maintain backward compatibility and fix functionality
Co-authored-by: Mervin Praison <[email protected]>
Simplified all 7 advanced examples to follow flat format requirements:
- Removed 20+ custom classes across all examples
- Reduced total lines from 2,829 to 514 (82% reduction)
- Limited to 1-2 agents max per example
- Focused on core functionality demonstration
- Maintained advanced feature examples while making them accessible
Changes per file:
- advanced-callback-systems.py: 404→59 lines, removed 3 classes
- advanced-graph-memory-integration.py: 226→75 lines, reduced to 1 agent
- advanced-memory-search-optimization.py: 568→76 lines, removed 4 classes
- advanced-state-management-patterns.py: 437→80 lines, removed 3 classes
- autoagents-hierarchical-generation.py: 158→73 lines, removed custom class
- production-guardrails-patterns.py: 480→65 lines, removed 5 classes
- self-reflection-optimization-patterns.py: 556→46 lines, removed 4 classes
All examples now follow the established flat format pattern with simple,
direct agent/task creation and minimal code complexity.
🤖 Generated with Claude Code
Co-Authored-By: Claude <[email protected]>
- Fixed aggressive underscore collapsing that broke dunder names like __init__
- Now only collapses 5+ consecutive underscores instead of any consecutive underscores
- Preserves trailing underscores in double underscore patterns (__name__)
- Handles edge case where purely invalid characters become single underscore
- All 15 test cases now pass including magic method names
- Maintains backward compatibility for AutoGen v0.2, CrewAI, PraisonAI
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Mervin Praison <[email protected]>
- Add special handling for Ollama models in both sync and async tool execution loops
- When Ollama returns empty/minimal response after tool execution, generate summary from tool results
- Prevents infinite loops while maintaining functionality for other LLM providers
- Add comprehensive test suite to validate fix and ensure backward compatibility
- Fixes issue where Ollama models would repeat tool calls indefinitely
Co-authored-by: Mervin Praison <[email protected]>
AutoGen v0.4 requires agent names to be valid Python identifiers,
but role names like ''Narrative Designer'' contain spaces which are invalid.
- Added sanitize_agent_name_for_autogen_v4() function to convert any
string to a valid Python identifier
- Applied sanitization only in AutoGen v0.4 code path for backward compatibility
- AutoGen v0.2 and other frameworks remain unchanged
- Handles spaces, special characters, Python keywords, and edge cases
Resolves issue where ''Narrative Designer'' role causes error:
''The agent name must be a valid Python identifier''
Co-authored-by: Mervin Praison <[email protected]>
- Improved session memory persistence for agent chat history
- Optimised methods for saving and restoring agent chat histories
- Ensured compatibility with existing code while enhancing functionality
- Addressed issues related to chat history loss during session transitions
Co-authored-by: Mervin Praison <[email protected]>
- Fixed session memory persistence issue where state was not being restored correctly
- Disabled embeddings in default memory config to avoid OpenAI API key requirement
- Changed search queries from metadata-based to content-based for SQLite compatibility
- Fixed search query from "type:session_state" to "Session state:" to match stored content
- Fixed agent chat history search from "type:agent_chat_history" to "Agent chat history for"
- Session state persistence now works correctly across session save/restore cycles
- Agent chat history persistence now works correctly across session save/restore cycles
- Maintains backward compatibility with existing code
- Fixes#930🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <[email protected]>
- Fix f-string issues on lines 275, 300 (remove unnecessary f prefixes)
- Fix chat history initialization to always set agent.chat_history even if empty
- Fix critical data loss bug in _save_agent_chat_histories method
- Now prioritizes live agent history but falls back to restored history
- Prevents chat history loss when agents aren''t re-instantiated after restore
Co-authored-by: Mervin Praison <[email protected]>
- Add increment_state method (lines 356-359) for numeric state management
- Fix empty chat history save condition to track agent existence properly
- Improve robustness by checking agent is not None before accessing chat_history
- Enhance memory persistence by saving even empty chat histories to track agent state
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Mervin Praison <[email protected]>
Co-Authored-By: Claude <[email protected]>
const reviewText = '@claude review if the changes made are as per the requirements';
const reviewText = '@claude review if the changes made in the above branch are as per the requirements and make changes to the above branch if issues still exist.';
"# ZeroScript: AI-Powered Browser Test Automation using PraisonAI Agent & OpenAI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "O4PKfpalLsmn"
},
"source": [
"# Description"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CEG1pfumLysm"
},
"source": [
"AI-powered browser testing using PraisonAI Agent and OpenAI. Executes YAML-defined test cases, captures screenshots, logs interactions, and generates JSON reports. Ideal for intelligent, automated UI testing.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lbgxOG4gL1Wf"
},
"source": [
"[](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/ZeroScript_AI_TestExecutor.ipynb)\n"
"AI-powered browser testing using PraisonAI Agent and OpenAI. Executes YAML-defined test cases, captures screenshots, logs interactions, and generates JSON reports. Ideal for intelligent, automated UI testing.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lbgxOG4gL1Wf"
},
"source": [
"[](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/ZeroScript_AI_TestExecutor.ipynb)\n"
# Routing logic - this could be enhanced with more sophisticated rules
instructions="""You are a cost-optimization router. For simple tasks like basic questions,
definitions, or simple calculations, use the cheapest model. For moderate complexity tasks
like writing, analysis, or research, use the balanced model. For complex tasks requiring
deep reasoning, creativity, or specialized knowledge, use the premium model.""",
tools=[duckduckgo],
verbose=True
)
# Example tasks of varying complexity levels
# Simple task - should route to cheap model
print("="*60)
print("TESTING SIMPLE TASK (should use cheap model)")
print("="*60)
simple_result=router.start("What is the capital of France?")
print(f"Simple task result: {simple_result}")
# Moderate complexity task - should route to balanced model
print("\n"+"="*60)
print("TESTING MODERATE TASK (should use balanced model)")
print("="*60)
moderate_result=router.start("Write a brief analysis of renewable energy trends in 2024")
print(f"Moderate task result: {moderate_result}")
# Complex task - should route to premium model
print("\n"+"="*60)
print("TESTING COMPLEX TASK (should use premium model)")
print("="*60)
complex_result=router.start("Conduct a comprehensive strategic analysis of the impact of quantum computing on cybersecurity, including potential vulnerabilities and mitigation strategies")
print(f"Complex task result: {complex_result}")
# Research task with tool usage - should route appropriately
print("\n"+"="*60)
print("TESTING RESEARCH TASK WITH TOOLS")
print("="*60)
research_result=router.start("Research and analyze the latest developments in artificial intelligence regulation globally")
backstory="You are a research analyst who backs all claims with evidence and citations.",
instructions="Support all statements with references to research, studies, or credible data sources."
)
# Create tasks with specific guardrails
# Task with email format guardrail
email_task=Task(
name="email_communication",
description="Write a business proposal for a new software project, including contact information",
expected_output="Professional business proposal with contact email addresses",
agent=email_agent,
guardrail=email_format_guardrail,
max_retries=3
)
# Task with word count guardrail
content_task=Task(
name="detailed_analysis",
description="Write an analysis of cloud computing benefits for small businesses",
expected_output="Comprehensive analysis of cloud computing benefits (minimum 50 words)",
agent=content_agent,
guardrail=word_count_guardrail,
max_retries=3
)
# Task with professional tone guardrail
business_task=Task(
name="professional_advice",
description="Provide advice on handling difficult client relationships",
expected_output="Professional advice maintaining appropriate business tone",
agent=business_agent,
guardrail=professional_tone_guardrail,
max_retries=3
)
# Task with factual accuracy guardrail
research_task=Task(
name="research_report",
description="Analyze the impact of artificial intelligence on job markets",
expected_output="Research-backed analysis with citations and evidence",
agent=research_agent,
guardrail=factual_accuracy_guardrail,
max_retries=3
)
# LLM-based guardrail example
llm_guardrail_agent=Agent(
name="LLMGuardrailAgent",
role="Content Quality Validator",
goal="Validate content quality using LLM-based assessment",
backstory="You are a quality assurance specialist who uses AI to validate content quality.",
instructions="Create marketing content that is engaging, accurate, and compliant with advertising standards."
)
# Task with LLM-based guardrail
llm_guardrail_task=Task(
name="marketing_content",
description="Create a marketing email for a new fitness app targeting busy professionals",
expected_output="Engaging marketing email that is accurate and compliant",
agent=llm_guardrail_agent,
# LLM-based guardrail using natural language validation
guardrail="Validate that this marketing content is: 1) Factually accurate with no false claims, 2) Compliant with advertising standards (no misleading statements), 3) Engaging and professional in tone, 4) Includes a clear call-to-action. If any criteria are not met, explain what needs to be improved.",
instructions="You are a content writing AI agent. "
"Help users create engaging blog posts, articles, marketing copy, "
"and social media content. Provide guidance on SEO optimization, "
"content structure, tone adjustment, and audience targeting.",
llm="meta-llama/Llama-3.1-8B-Instruct"
)
response=agent.start("Hello! I'm your content writing assistant. "
"How can I help you create compelling content today?")
Loaded 100 of 272 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.