Compare commits

...
684 Commits
Author SHA1 Message Date
Mervin Praison a8b1948fc0 feat(ag2): add AG2 framework backend integration (#1143)
feat(ag2): add AG2 framework backend integration
2026-03-26 17:48:37 +00:00
Faridun Mirzoev 56f815c1b1 fix(ag2): address Qodo review issues - YAML config resolution, OPENAI_API_BASE, patch create=True
- Add _resolve() helper to read LLM config from YAML top-level, per-role,
  config_list, and env vars in priority order (fixes Bedrock YAML config ignored)
- Include OPENAI_API_BASE env var in base_url resolution chain
- Add create=True to all patch("autogen.*") calls so tests pass without ag2 installed
2026-03-26 09:48:14 -07:00
Faridun Mirzoev 6b30977d9e feat(ag2): add AG2 framework backend integration
Integrates AG2 (community fork of AutoGen, PyPI package: ag2) as a new
framework option alongside praisonai, crewai, and autogen.

Changes:
- pyproject.toml: add [ag2] optional dependency extra (ag2>=0.11.0)
- agents_generator.py: AG2 detection via importlib.metadata + _run_ag2()
  with LLMConfig dict pattern, GroupChat orchestration, Bedrock support,
  ChatResult.summary extraction, and TERMINATE cleanup
- auto.py: AG2_AVAILABLE flag + validation in AutoGenerator.__init__
- .env.example: add AG2 and AWS Bedrock environment variable templates
- examples/ag2/: basic, multi-agent, and Bedrock YAML examples
- tests: 16 unit tests + 9 mock integration tests (25/25 passing)

Detection uses importlib.metadata.distribution('ag2') + LLMConfig check.
All changes are purely additive — existing code paths unaffected.

E2E tested against OpenAI gpt-4o-mini: single-agent and multi-agent
GroupChat flows both produce correct output.
2026-03-24 16:47:46 -04:00
Mervin Praison 4966ec1ae1 Merge pull request #658 from MervinPraison/develop
Enhance Claude workflow by adding environment variable for GitHub tok…
2025-06-16 08:26:16 +02:00
MervinPraison c31870a991 Enhance Claude workflow by adding environment variable for GitHub token and implementing package visibility check and Docker authentication tests for improved reliability and security. 2025-06-16 07:25:57 +01:00
Mervin Praison 67f4a89062 Merge pull request #657 from MervinPraison/develop
Add debugging steps to Claude workflow for environment verification a…
2025-06-16 08:24:07 +02:00
MervinPraison a898bbb7d1 Add debugging steps to Claude workflow for environment verification and Docker testing 2025-06-16 07:23:50 +01:00
Mervin Praison 107d33deb7 Merge pull request #656 from MervinPraison/develop
Update Claude Code action to restrict package permissions and remove …
2025-06-16 08:21:21 +02:00
MervinPraison 9d963e4eeb Update Claude Code action to restrict package permissions and remove Docker image build step for streamlined workflow. 2025-06-16 07:21:02 +01:00
Mervin Praison 56b296b8d6 Merge pull request #655 from MervinPraison/develop
Update Claude Code action to enable package writing and add Docker im…
2025-06-16 08:18:07 +02:00
MervinPraison fddf999688 Update Claude Code action to enable package writing and add Docker image build and push step for enhanced deployment capabilities. 2025-06-16 07:14:29 +01:00
Mervin Praison 6374aba783 Merge pull request #654 from MervinPraison/develop
Update Claude Code action to use GitHub token for authentication, enh…
2025-06-16 08:13:03 +02:00
MervinPraison 9408d699e8 Update Claude Code action to use GitHub token for authentication, enhancing security and consistency in the workflow. 2025-06-16 07:12:10 +01:00
Mervin Praison 6358671ab9 Merge pull request #652 from MervinPraison/develop
Enhance Claude Code action by adding environment variable verificatio…
2025-06-15 07:43:51 +02:00
MervinPraison f5bd55bb9a Enhance Claude Code action by adding environment variable verification and updating Docker setup for improved reliability 2025-06-15 06:43:34 +01:00
Mervin Praison a93c571f33 Merge pull request #651 from MervinPraison/develop
Update Claude Code action reference to use local action for improved …
2025-06-15 07:42:13 +02:00
MervinPraison 8ea0e4c831 Update Claude Code action reference to use local action for improved maintainability 2025-06-15 06:41:42 +01:00
Mervin Praison 8a1dc24794 Merge pull request #650 from MervinPraison/develop
Update Claude Code action reference to use quotes for consistency
2025-06-15 07:39:30 +02:00
MervinPraison b331229578 Update Claude Code action reference to use quotes for consistency 2025-06-15 06:39:12 +01:00
Mervin Praison 7af52735cf Merge pull request #649 from MervinPraison/develop
Add GitHub Container Registry login step and update Claude Code actio…
2025-06-15 07:37:42 +02:00
MervinPraison 2902fec42e Add GitHub Container Registry login step and update Claude Code action reference 2025-06-15 06:37:28 +01:00
Mervin Praison 64f752a8e0 Merge pull request #648 from MervinPraison/develop
Update Docker image reference in Claude Code action for consistency
2025-06-15 07:35:30 +02:00
MervinPraison d994fb5047 Update Docker image reference in Claude Code action for consistency 2025-06-15 06:34:52 +01:00
Mervin Praison 760fb9530b Merge pull request #647 from MervinPraison/develop
Refactor Claude Code integration to use local action instead of Docke…
2025-06-15 07:33:04 +02:00
MervinPraison de165975b0 Refactor Claude Code integration to use local action instead of Docker image for improved maintainability 2025-06-15 06:32:43 +01:00
Mervin Praison dfd74a2fe7 Merge pull request #646 from MervinPraison/develop
Develop
2025-06-15 07:29:30 +02:00
MervinPraison 9265ca08a2 Update Claude Code integration to use Docker image and add GitHub token for authentication 2025-06-15 06:28:57 +01:00
MervinPraison 665df753fd Remove CLAUDE_CODE_INTEGRATION_PRAISONAI_AGENTS.md as it is no longer needed for the integration of Claude Code with PraisonAI Agents. This deletion simplifies the documentation and reflects the current state of the project. 2025-06-15 05:55:55 +01:00
Mervin Praison 94d991f4ec Merge pull request #643 from MervinPraison/develop
Update PraisonAI and dependencies to version 2.2.33
2025-06-14 08:45:31 +02:00
MervinPraison 632cf68423 Update PraisonAI and dependencies to version 2.2.33
- Updated PraisonAI version from 2.2.32 to 2.2.33 across multiple Dockerfiles and relevant files.
- Adjusted dependency versions in pyproject.toml and other files for consistency.
- Enhanced README documentation to reflect the updated version.

This change integrates the latest features and improvements from PraisonAI while ensuring compatibility with existing code.
2025-06-14 07:45:15 +01:00
Mervin Praison d956c605f7 Merge pull request #635 from MervinPraison/claude/issue-634-20250610_115418
feat: Refactor Claude Code integration to use PraisonAI Agents
2025-06-14 08:43:35 +02:00
Mervin Praison 7e3de10f32 Rename test_claude_code_integration.py to src/praisonai/tests/unit/test_claude_code_integration.py 2025-06-14 07:41:20 +01:00
Mervin Praison 79883f1af2 Merge pull request #642 from MervinPraison/develop
Update PraisonAI and dependencies to version 2.2.32
2025-06-14 08:39:04 +02:00
MervinPraison a098eb0150 Update PraisonAI and dependencies to version 2.2.32
- Updated PraisonAI version from 2.2.31 to 2.2.32 across multiple Dockerfiles and relevant files.
- Adjusted dependency versions in pyproject.toml and other files for consistency.
- Enhanced README documentation to reflect the updated version.

This change integrates the latest features and improvements from PraisonAI while ensuring compatibility with existing code.
2025-06-14 07:38:45 +01:00
Mervin Praison b9ce3b4ccb Merge pull request #641 from MervinPraison/develop
Allow to configure reflection prompt
2025-06-14 08:36:28 +02:00
claude[bot]andMervin Praison 58b44280df feat: add self-reflection support with configurable prompt to achat method
- Implement complete self-reflection logic in achat method to match chat method
- Support configurable reflect_prompt parameter in async operations  
- Add reflection loop with min/max limits and error handling
- Update method docstring to reflect new self-reflection capability
- Ensure consistent behavior between chat and achat methods

Co-authored-by: Mervin Praison <[email protected]>
2025-06-14 06:26:49 +00:00
MervinPraison 4dba09d6b1 Merge remote-tracking branch 'leo-origin/feature/add-reflection-prompt' into test-reflection-prompt 2025-06-14 07:20:09 +01:00
Mervin Praison a538513bec Merge pull request #640 from MervinPraison/develop
Develop
2025-06-14 08:17:26 +02:00
MervinPraison 4fb79207cf Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-06-14 07:16:44 +01:00
MervinPraison 0b444fae34 Merge branch 'develop' of https://github.com/MervinPraison/PraisonAI into develop 2025-06-14 07:16:26 +01:00
MervinPraison bd34e45bbc Update PraisonAI and dependencies to version 2.2.31
- Updated PraisonAI version from 2.2.30 to 2.2.31 across multiple Dockerfiles and the Ruby formula.
- Adjusted dependency versions in pyproject.toml and other relevant files for consistency.
- Enhanced README documentation to reflect the updated version.

This change ensures that the latest features and improvements from PraisonAI are integrated while maintaining compatibility with existing code.
2025-06-14 07:16:25 +01:00
Mervin Praison f4f051e57e Merge pull request #638 from krkead/patch-2
Update chainlit_ui.py to work with newer chainlit versions
2025-06-14 08:13:56 +02:00
Mervin Praison 3c2610cc3c Merge pull request #639 from krkead/patch-1
Update agents.py to work with newer chainlit versions
2025-06-14 08:13:44 +02:00
krkead 9788454134 Update chainlit_ui.py to work with newer chainlit versions
The previous payload modification was incorrect
2025-06-13 18:04:52 -03:00
krkead e618004e60 Update agents.py to work with newer chainlit versions 2025-06-13 18:02:35 -03:00
Mervin Praison 384803ba8e Merge pull request #637 from DhivyaBharathy-web/add-mistral-agent
Add Mistral v0.3 Conversational Agent – Conceptual Workflow
2025-06-12 06:01:21 +02:00
DhivyaBharathy-web d3bb366a51 Add Mistral 7B Instruction Agent notebook 2025-06-11 10:49:16 +00:00
DhivyaBharathy e579e84b52 Add files via upload 2025-06-11 16:13:42 +05:30
leovs09 61440403f5 add agent constructor params description 2025-06-11 00:48:51 +02:00
leovs09 b615782175 Allow to configure reflection prompt 2025-06-11 00:24:59 +02:00
claude[bot]andMervinPraison 35199979f0 feat: Refactor Claude Code integration to use PraisonAI Agents
- Replace litellm direct usage with praisonaiagents framework
- Implement Claude Code as a custom tool that agents can decide to use
- Add --claudecode CLI flag support: `praisonai code --claudecode`
- Create intelligent agent that chooses when to use Claude Code vs regular responses
- Maintain full backward compatibility with litellm fallback
- Add UI toggle switch for enabling/disabling Claude Code
- Implement git operations with automatic branch creation and PR URLs
- Add comprehensive error handling and streaming support
- Include test script and detailed documentation

Key improvements:
- Agent-driven decision making instead of manual detection logic
- Better tool coordination and flexibility
- Minimal code changes with maintained compatibility
- Enhanced user experience with intelligent tool selection

Co-Authored-By: MervinPraison <[email protected]>
2025-06-10 12:02:19 +00:00
DhivyaBharathy eeb77cfd20 Add files via upload 2025-06-10 16:15:43 +05:30
Mervin Praison 00d7994601 Merge pull request #633 from DhivyaBharathy-web/add-nlp-asr-agent
Add NLP + ASR Agent (Official BERT Large + Whisper Large V3)
2025-06-10 08:55:08 +01:00
DhivyaBharathy 10aa49addc Merge branch 'main' into add-nlp-asr-agent 2025-06-10 12:05:50 +05:30
DhivyaBharathy-web 79c9cf8bf9 Add NLP + ASR Agent (Official BERT Large + Whisper Large V3) notebook 2025-06-10 06:32:31 +00:00
Mervin Praison a9416fb7fc Merge pull request #631 from MervinPraison/claude/issue-630-20250609_145612
feat: add remote agent connectivity with Google ADK-like API
2025-06-09 20:43:47 +01:00
Mervin Praison 547b40ee72 Rename test_remote_agent.py to src/praisonai/tests/unit/test_remote_agent.py 2025-06-09 20:43:32 +01:00
claude[bot]andMervinPraison 4fc35d1b10 feat: add remote agent connectivity with Google ADK-like API
- Enhanced Session class to support remote agent URLs
- Added agent_url parameter for direct agent connectivity  
- Implemented HTTP client for remote agent communication
- Added connection testing and validation
- Provided send_message() alias for Google ADK compatibility
- Created comprehensive examples and documentation
- Maintained full backward compatibility
- Added proper error handling for remote operations

Fixes #630

Co-authored-by: MervinPraison <[email protected]>
2025-06-09 15:02:42 +00:00
Mervin Praison c72d74987b Merge pull request #625 from DhivyaBharathy-web/add-mistral7b-agent
Add mistral7b agent
2025-06-08 00:14:37 +01:00
DhivyaBharathy 430ec6571a Update MistralTechAgent.ipynb 2025-06-07 14:22:57 +05:30
DhivyaBharathy e88288773a Add files via upload 2025-06-07 14:15:47 +05:30
DhivyaBharathy-web 9af03e3fef Add Mistral-7B-Instruct-v0.1 Instruction Agent notebook 2025-06-07 08:43:22 +00:00
Mervin Praison 7a7560621b Merge pull request #624 from MervinPraison/develop
Develop
2025-06-07 01:27:46 +01:00
MervinPraison 531c58ac70 Update PraisonAI and dependencies to version 2.2.31 and praisonaiagents to version 0.0.104
- Updated PraisonAI version in Dockerfiles and Ruby formula.
- Adjusted dependency versions in pyproject.toml and uv.lock for consistency.
- Enhanced README to reflect the new versioning.

This change ensures compatibility with the latest features and improvements while maintaining existing functionality.
2025-06-07 01:27:29 +01:00
MervinPraison 274ade8154 Disable litellm telemetry across multiple modules for improved performance and consistency
- Added environment variable to disable litellm telemetry in __init__.py, llm.py, and memory.py.
- Ensured telemetry is disabled after importing litellm to prevent unnecessary data collection.

This change enhances control over telemetry features while maintaining existing functionality.
2025-06-07 00:24:28 +01:00
Mervin Praison 83f4f874e9 Merge pull request #622 from DhivyaBharathy-web/add-groq-Llama3-agent
Add Groq Llama3-8b-8192 Agent notebook
2025-06-06 23:38:03 +01:00
MervinPraison 99cd88dd30 Enhance telemetry support and update dependencies
- Added 'posthog>=4.0.0' to dependencies and optional 'telemetry' section in pyproject.toml.
- Updated blog_agent to use llm_config for improved clarity.
- Disabled memory in PraisonAIAgents instantiation for better control.
- Introduced telemetry support with lazy loading and fallback functions in __init__.py.

This update improves the integration of telemetry features while maintaining existing functionality.
2025-06-06 17:52:43 +01:00
DhivyaBharathy 1d22818662 Add files via upload 2025-06-06 15:28:14 +05:30
DhivyaBharathy-web 4f38e7250a Add Groq Llama3-8b-8192 Agent notebook 2025-06-06 09:52:36 +00:00
Mervin Praison b736567375 Merge pull request #618 from MervinPraison/revert-617-claude/issue-612-20250606_060924
Revert "fix: prevent duplicate Task and Response display when using litellm with memory"
2025-06-06 07:28:27 +01:00
Mervin Praison d014ea8d18 Revert "fix: prevent duplicate Task and Response display when using litellm with memory" 2025-06-06 07:28:13 +01:00
Mervin Praison fd6db3ccfa Merge pull request #617 from MervinPraison/claude/issue-612-20250606_060924
fix: prevent duplicate Task and Response display when using litellm with memory
2025-06-06 07:24:32 +01:00
claude[bot]andMervinPraison 1f2f26c5cf fix: prevent duplicate Task and Response display when using litellm with memory
- Add suppress_display parameter to LLM.get_response() method (default: False)
- Update all display_interaction calls in LLM class to respect suppress_display flag
- Agent class now passes suppress_display=True to prevent LLM duplicate displays
- Agent handles display centrally to ensure single display per interaction
- Maintains full backward compatibility while fixing issue #612

Co-authored-by: MervinPraison <[email protected]>
2025-06-06 06:16:39 +00:00
Mervin Praison 1965f296b0 Merge pull request #614 from MervinPraison/revert-613-claude/issue-612-20250605_213542
Revert "fix: prevent duplicate Task and Response display when using litellm with memory"
2025-06-06 06:43:34 +01:00
Mervin Praison cc7036784b Revert "fix: prevent duplicate Task and Response display when using litellm with memory" 2025-06-06 06:43:21 +01:00
Mervin Praison 826a68c33e Merge pull request #613 from MervinPraison/claude/issue-612-20250605_213542
fix: prevent duplicate Task and Response display when using litellm with memory
2025-06-06 06:41:16 +01:00
claude[bot]andMervinPraison 88ceba804b fix: prevent duplicate Task and Response display when using litellm with memory
- Add display_interaction parameter to LLM.get_response() method (default: True)
- Update all internal display_interaction calls in LLM class to respect new parameter  
- Modify agent calls to pass display_interaction=False when using custom LLM instances
- Maintains backward compatibility while fixing duplicate displays (fixes #612)

Co-authored-by: MervinPraison <[email protected]>
2025-06-05 21:45:59 +00:00
Mervin Praison dc5b10fba8 Merge pull request #611 from MervinPraison/develop
Update PraisonAI version to 2.2.30 across Dockerfiles and related files
2025-06-05 18:18:04 +01:00
MervinPraison f0172e8339 Update PraisonAI version to 2.2.30 across Dockerfiles and related files
- Incremented the version of PraisonAI from 2.2.29 to 2.2.30 in Dockerfiles (Dockerfile, Dockerfile.chat, Dockerfile.dev, Dockerfile.ui).
- Updated the version in the README.md and pyproject.toml files to reflect the new version.
- Adjusted the deploy.py script to install the updated version of PraisonAI.
- Ensured consistency across all relevant files for seamless integration.
2025-06-05 18:17:47 +01:00
Mervin Praison 5c498a12de Merge pull request #610 from MervinPraison/claude/issue-605-20250605_165941
fix: resolve Memory import error with litellm compatibility
2025-06-05 18:16:11 +01:00
Mervin Praison 88410881e1 Rename test_session_import.py to src/praisonai/tests/unit/test_session_import.py 2025-06-05 18:10:43 +01:00
Mervin Praison 791d59f96e Rename test_memory_import.py to src/praisonai/tests/unit/test_memory_import.py 2025-06-05 18:10:25 +01:00
Mervin Praison cdbe1303ad Rename test_comprehensive_import.py to src/praisonai/tests/unit/test_comprehensive_import.py 2025-06-05 18:10:10 +01:00
claude[bot]andMervinPraison b63f931bea feat: add Memory to main package exports and comprehensive tests
- Export Memory class from main praisonaiagents package
- Add Memory to __all__ list for proper package API
- Create comprehensive test suite to verify all import scenarios
- Tests original failing import from GitHub issue
- Tests direct Memory imports and instantiation

Co-authored-by: MervinPraison <[email protected]>
2025-06-05 17:02:47 +00:00
claude[bot]andMervinPraison ff25b96f91 fix: resolve Memory import error by implementing litellm compatibility
- Add LITELLM_AVAILABLE flag for proper dependency detection
- Implement litellm → openai fallback pattern for all embedding operations
- Update search_short_term, store_long_term, search_long_term embedding calls
- Update calculate_quality_metrics to use litellm → openai fallback
- Add graceful degradation when neither litellm nor openai is available
- Fixes ImportError: cannot import name 'Memory' from 'praisonaiagents.memory'

Co-authored-by: MervinPraison <[email protected]>
2025-06-05 17:02:03 +00:00
Mervin Praison 603f0ea008 Merge pull request #609 from MervinPraison/develop
Develop
2025-06-05 17:55:15 +01:00
MervinPraison db38b55174 Update PraisonAI version to 2.2.29 across Dockerfiles and related files
- Incremented the version of PraisonAI from 2.2.28 to 2.2.29 in Dockerfiles (Dockerfile, Dockerfile.chat, Dockerfile.dev, Dockerfile.ui).
- Updated the version in the README.md and pyproject.toml files to reflect the new version.
- Adjusted the deploy.py script to install the updated version of PraisonAI.
- Ensured consistency across all relevant files for seamless integration.
2025-06-05 17:54:57 +01:00
MervinPraison cebd175d61 Update versioning and dependencies in project files
- Incremented version of PraisonAI from 0.0.99 to 0.0.101 in pyproject.toml and uv.lock.
- Added 'litellm' dependency to memory requirements for enhanced functionality.
- Updated .gitignore to include 'CopilotKit*' for better file management.
- Optimised TaskOutput instantiation in agent.py for clarity.
- Refined memory handling in memory.py to utilise LiteLLM for consistency.
- Improved model extraction logic in task.py for better fallback handling.
2025-06-05 17:53:38 +01:00
Mervin Praison 01ff75e573 Merge pull request #606 from DhivyaBharathy-web/add-qwen2-5-agent
Add Qwen2.5 Instruction Agent notebook using Hugging Face Transformers
2025-06-05 17:43:36 +01:00
Mervin Praison 28629f2203 Merge pull request #607 from DhivyaBharathy-web/add-gemma2b-instruction-agent
Add Gemma2B_Instruction_Agent to Cookbooks
2025-06-05 17:43:19 +01:00
Mervin Praison ac5c463362 Merge pull request #602 from DhivyaBharathy-web/add-predictive-maintenance-notebook
Add predictive maintenance notebook
2025-06-05 17:43:05 +01:00
Mervin Praison 84dc57583e Merge pull request #608 from DhivyaBharathy-web/add-tinyllama-model-agent
Add tinyllama model agent
2025-06-05 17:42:50 +01:00
DhivyaBharathy 460e8b45a7 Merge branch 'main' into add-tinyllama-model-agent 2025-06-05 19:30:02 +05:30
DhivyaBharathy f6bbbd7cd6 Update TinyLlama_1_1B_model_SimpleAIAgent.ipynb 2025-06-05 19:29:06 +05:30
DhivyaBharathy 8a435571f4 Add files via upload 2025-06-05 19:10:44 +05:30
DhivyaBharathy 204106daa8 Merge branch 'main' into add-gemma2b-instruction-agent 2025-06-05 16:47:50 +05:30
DhivyaBharathy 6a1e14f97a Merge branch 'main' into add-qwen2-5-agent 2025-06-05 16:47:02 +05:30
DhivyaBharathy 333777b991 Merge branch 'main' into add-predictive-maintenance-notebook 2025-06-05 16:46:13 +05:30
DhivyaBharathy b02cd85290 Update Gemma2B_Instruction_Agent.ipynb 2025-06-05 16:27:38 +05:30
DhivyaBharathy 3bc0c2b533 Update Gemma2B_Instruction_Agent.ipynb 2025-06-05 16:26:56 +05:30
DhivyaBharathy 68d4f34bb7 Update Gemma2B_Instruction_Agent.ipynb 2025-06-05 16:26:37 +05:30
DhivyaBharathy a24d900a8c Add files via upload 2025-06-05 16:22:33 +05:30
DhivyaBharathy-web 552a10df9e Add Qwen2.5 Instruction Agent notebook 2025-06-05 10:49:32 +00:00
DhivyaBharathy 9c57aa3165 Update Qwen2_5_InstructionAgent.ipynb 2025-06-05 15:16:04 +05:30
DhivyaBharathy 40fe92f1d0 Update Qwen2_5_InstructionAgent.ipynb 2025-06-05 15:14:56 +05:30
DhivyaBharathy 179cc9566d Update Qwen2_5_InstructionAgent.ipynb 2025-06-05 15:09:09 +05:30
DhivyaBharathy d9cf9ba534 Add files via upload 2025-06-05 15:07:47 +05:30
DhivyaBharathy-web 4ec0366e79 Add Qwen2.5 Instruction Agent notebook 2025-06-05 09:26:46 +00:00
Mervin Praison d6a3bd1240 Merge pull request #604 from MervinPraison/develop
Update PraisonAI version to 2.2.28 across Dockerfiles and related files
2025-06-04 22:59:48 +01:00
MervinPraison 0a18e27f54 Update PraisonAI version to 2.2.28 across Dockerfiles and related files
- Updated the version of PraisonAI from 2.2.27 to 2.2.28 in Dockerfiles (Dockerfile, Dockerfile.chat, Dockerfile.dev, Dockerfile.ui).
- Modified the version in the README.md and pyproject.toml files to reflect the new version.
- Adjusted the deploy.py script to install the updated version of PraisonAI.
- Ensured consistency across all relevant files for seamless integration.
2025-06-04 22:59:30 +01:00
DhivyaBharathy b824d950b5 Add files via upload 2025-06-04 20:32:10 +05:30
Mervin Praison a5b768c213 Merge pull request #601 from MervinPraison/develop
Develop
2025-06-04 15:50:06 +01:00
MervinPraison 068bdbebc5 Update PraisonAI version to 2.2.27 across Dockerfiles and related files
- Updated the version of PraisonAI from 2.2.26 to 2.2.27 in Dockerfiles (Dockerfile, Dockerfile.chat, Dockerfile.dev, Dockerfile.ui).
- Modified the version in the README.md and pyproject.toml files to reflect the new version.
- Adjusted the deploy.py script to install the updated version of PraisonAI.
- Ensured consistency across all relevant files for seamless integration.
2025-06-04 15:49:47 +01:00
MervinPraison 4d80d795f8 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-06-04 15:48:15 +01:00
MervinPraison 2e3b5cd29b Merge branch 'develop' of https://github.com/MervinPraison/PraisonAI into develop 2025-06-04 15:48:08 +01:00
MervinPraison d948b6de2c Refactor agent guardrails and update versioning
- Removed the outdated agent_guardrails_example.py file.
- Introduced a new guardrail_agents_example.py file with improved structure and user-friendly naming.
- Updated version in pyproject.toml from 0.0.97 to 0.0.98.
- Added revision information in uv.lock for better dependency tracking.
- Imported asyncio in agent.py for enhanced functionality.
2025-06-04 15:47:14 +01:00
Mervin Praison 3adb06950c Merge pull request #599 from MervinPraison/develop
Update test workflow to use custom test runner for 'fast' pattern and…
2025-06-04 14:21:02 +01:00
claude[bot]andClaude e45e85975c feat: implement Agent-level guardrail support
- Add guardrail and max_guardrail_retries parameters to Agent constructor
- Implement _setup_guardrail() method supporting function and LLM-based guardrails  
- Add _process_guardrail() method for validation processing
- Create _apply_guardrail_with_retry() method with automatic retry logic
- Integrate guardrail processing into all major return points in chat() method
- Support both regular responses and reasoning content validation
- Update agent_guardrails_example.py with comprehensive demonstrations
- Enhance CLAUDE.md documentation with Agent-level guardrail usage
- Add test file for Agent guardrail functionality validation

Agent-level guardrails apply to ALL outputs from the agent, providing
consistent validation across all agent interactions with configurable
retry logic and support for both function-based and string-based 
LLM guardrails.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
2025-06-04 11:57:22 +00:00
Mervin Praison 8a7935dc2c Merge pull request #600 from DhivyaBharathy-web/code-analysis-agent
Add code analysis agent notebook
2025-06-04 12:40:08 +01:00
DhivyaBharathy b31edc90d5 Update Code_Analysis_Agent.ipynb 2025-06-04 16:58:52 +05:30
DhivyaBharathy d2841ccb3a Merge branch 'MervinPraison:main' into main 2025-06-04 16:53:54 +05:30
DhivyaBharathy-web e22fda805f Add code analysis agent notebook 2025-06-04 11:20:39 +00:00
MervinPraison 2cde2fd731 Update test workflow to use custom test runner for 'fast' pattern and refine guardrail functionality in Task class
- Changed the test command in the GitHub Actions workflow to run a specific test runner script with a 'fast' pattern.
- Introduced guardrail functionality in the Task class to validate task outputs, including error handling and retry logic for guardrail validation failures.
- Enhanced the initialization of guardrail parameters and ensured proper type checking for guardrail functions.
2025-06-04 12:10:01 +01:00
Mervin Praison f7534681e5 Merge pull request #598 from MervinPraison/develop
Develop
2025-06-04 12:09:21 +01:00
MervinPraison 8c9e3e34cb agent sequential thinking 2025-06-04 11:52:53 +01:00
MervinPraison c470494d76 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-06-04 10:32:57 +01:00
Mervin Praison fdf3cac3e7 Merge pull request #596 from MervinPraison/codex/add-mcp-tool-to-agent-creation
Add MCP SSE tooling example
2025-06-04 10:32:06 +01:00
Mervin Praison ec98cd12c8 Merge pull request #597 from DhivyaBharathy-web/add-hackathon-agent-notebook
Add Hackathon Agent Notebook
2025-06-04 10:29:50 +01:00
DhivyaBharathy-web f318ef02a9 Add Hackathon Agent Notebook 2025-06-04 09:19:01 +00:00
claude[bot]andMervinPraison f086566a2d feat: improve MCP SSE tooling with comprehensive error handling and type safety
- Add comprehensive error handling to MCP initialization and tool execution
- Implement resource cleanup mechanisms with close() method and connection state tracking
- Fix interface typo: MCPPToolInfo -> MCPToolInfo
- Add schemaProperties getter to improve type safety in example code
- Prevent re-initialization of MCP client with guard clause
- Add debug logging throughout MCP lifecycle
- Improve example code with proper error handling for network failures
- Add better parameter mapping with object/positional argument support
- Include validation warnings for missing tools and argument mismatches
- Remove unused MCPTool import from example
- Add proper resource cleanup in finally block

These changes address the ENETUNREACH error mentioned in PR description by providing
graceful error handling when the MCP SSE server is unavailable.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: MervinPraison <[email protected]>
2025-06-04 08:23:07 +00:00
Mervin Praison 6de011b69e Add MCP SSE example and dependency 2025-06-04 09:05:08 +01:00
MervinPraison 89d7821bc9 Update test workflow to use custom test runner for 'all' pattern 2025-06-04 07:38:10 +01:00
MervinPraison 9bff7eddbd Update coverage workflow to include installation of duckduckgo_search and knowledge dependencies from praisonai-agents 2025-06-04 07:18:25 +01:00
MervinPraison 82e5f11acf Enhance test workflows by replacing test runner with pytest for improved coverage reporting and adding Codecov upload steps for comprehensive, core, and quick validation tests. 2025-06-04 07:14:18 +01:00
Mervin Praison 0a4aaeb80d Merge pull request #595 from MervinPraison/develop
Update PraisonAI version to 2.2.26 across Dockerfiles and related con…
2025-06-04 07:08:32 +01:00
MervinPraison 70915e2535 Update PraisonAI version to 2.2.26 across Dockerfiles and related configurations 2025-06-04 07:06:23 +01:00
Mervin Praison f35dd76623 Merge pull request #594 from MervinPraison/codex/find-and-fix-bug-in-codebase
Fix redundant tool invocation
2025-06-04 07:03:42 +01:00
Mervin Praison fccd1197a8 Merge pull request #593 from anupamme/fix-yaml.docker-compose.security.writable-filesystem-service.writable-filesystem-service-docker-docker-compose.dev.yml-349c
Updated docker/docker-compose.dev.yml to fix security vulnerability [yaml.docker-compose.security.writable-filesystem-service.writable-filesystem-service]
2025-06-04 07:00:41 +01:00
Mervin Praisonandcoderabbitai[bot] 9390da7099 Update docker/docker-compose.dev.yml
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-04 06:50:43 +01:00
Mervin Praison 8044fd7927 fix duplicate tool execution 2025-06-04 06:48:38 +01:00
anupamme cd5ba2017e fix: yaml.docker-compose.security.writable-filesystem-service.writable-filesystem-service-docker-docker-compose.dev.yml 2025-06-04 04:56:10 +00:00
Mervin Praison 8c6773b86e Merge pull request #592 from anupamme/fix-yaml.docker-compose.security.no-new-privileges.no-new-privileges-docker-docker-compose.dev.yml-7eaa
Updated docker/docker-compose.dev.yml to fix security vulnerability [yaml.docker-compose.security.no-new-privileges.no-new-privileges]
2025-06-04 05:27:56 +01:00
Mervin Praison 01539581c9 Update docker-compose.dev.yml 2025-06-04 05:27:00 +01:00
Mervin Praison bef8713769 Update docker-compose.dev.yml 2025-06-04 05:26:25 +01:00
Mervin Praisonandcoderabbitai[bot] f84445949e Update docker/docker-compose.dev.yml
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-04 05:24:38 +01:00
anupamme 7c74df7cf9 fix: yaml.docker-compose.security.no-new-privileges.no-new-privileges-docker-docker-compose.dev.yml 2025-06-04 04:17:02 +00:00
Mervin Praison f576afa22c Merge pull request #590 from MervinPraison/claude/issue-588-20250603_160140
feat: enhance stateful agents with Session class and convenience methods
2025-06-04 05:04:54 +01:00
claude[bot]andMervinPraison 79c4ef1de3 fix: enhance stateful agents with SQLite compatibility and improved API
- Fix SQLite query compatibility in session state restoration
- Add type safety to increment_state and improve append_to_state
- Change API from session.create_agent() to session.Agent() (backward compatible)
- Clean up code style: remove unused imports, trailing whitespace, fix f-strings
- Fix missing limit parameter in search_knowledge method
- Update examples to use new API

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: MervinPraison <[email protected]>
2025-06-04 03:52:09 +00:00
Mervin Praison 47e7c5b272 Delete docs/mint.json 2025-06-03 19:14:08 +01:00
Mervin Praison ec9310b1d1 Delete docs/features/stateful-agents.mdx 2025-06-03 19:13:57 +01:00
Mervin Praison 359bfd3759 Merge pull request #589 from MervinPraison/develop
chore: remove deprecated documentation files
2025-06-03 19:10:18 +01:00
MervinPraison c57e4724c1 chore: remove deprecated documentation files
- Deleted various obsolete documentation files to streamline the codebase.
- Ensured minimal code changes while maintaining the integrity of the remaining documentation.
2025-06-03 19:09:57 +01:00
claude[bot]andClaude 0b4739a6f9 feat: enhance stateful agents with Session class and convenience methods
Add minimal enhancements to PraisonAI's existing stateful capabilities:

- Add Session helper class for unified session management
- Add 9 convenience methods to PraisonAIAgents for enhanced state management
- Add comprehensive stateful agents documentation with examples
- Add 3 practical examples demonstrating session, workflow, and memory capabilities
- Maintain backward compatibility - all existing code continues to work

The implementation leverages existing robust infrastructure (Memory, Agent, Process classes)
rather than duplicating functionality, providing better developer experience through
improved APIs and documentation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
2025-06-03 16:11:07 +00:00
Mervin Praison e90c78219d Merge pull request #586 from MervinPraison/develop
refactor: streamline test functions in test_scheduler.py
2025-06-03 16:28:49 +01:00
MervinPraison a640f0710d chore: add knowledge dependencies installation in python-package.yml
- Included installation of knowledge dependencies from praisonai-agents in the python-package workflow.
- Ensured minimal code changes while enhancing the functionality of the workflow.
2025-06-03 16:23:14 +01:00
MervinPraison 7216afbf13 chore: add knowledge dependencies installation in unittest.yml
- Included installation of knowledge dependencies from praisonai-agents in the unittest workflow.
- Ensured minimal code changes while enhancing the functionality of the testing process.
2025-06-03 16:15:34 +01:00
MervinPraison 3f7ea07fa2 chore: add knowledge dependencies installation in workflow files
- Included installation of knowledge dependencies from praisonai-agents in test-comprehensive.yml, test-extended.yml, and test-real.yml.
- Ensured minimal code changes while enhancing the functionality of the workflows.
2025-06-03 16:07:34 +01:00
MervinPraison 5d6792762c refactor: enhance test functions and error handling in approval tests
- Updated test functions to use `execute_command` and `write_file` for improved clarity and consistency.
- Added mock patches for auto-approval callbacks to streamline testing processes.
- Enhanced error handling to assert failures directly, ensuring better test reliability.
- Maintained adherence to minimal code change principles while improving overall test structure.
2025-06-03 16:05:22 +01:00
MervinPraison 092113cedd test update 2025-06-03 15:59:32 +01:00
MervinPraison 314eed51d5 refactor: standardise import paths and enhance error handling in test files
- Updated import paths in multiple test files for consistency and clarity.
- Improved error handling in approval tests to assert failures directly.
- Ensured minimal code changes while maintaining existing functionality and readability.
2025-06-03 14:54:41 +01:00
MervinPraison df26978b3c refactor: improve test structure and error handling in approval tests
- Enhanced readability by formatting command execution in `test_agent_with_auto_approval`.
- Updated import path handling in `test_approval_basic` for consistency.
- Simplified error handling in various test functions to assert failures directly.
- Ensured adherence to minimal code change principles while maintaining functionality.
2025-06-03 14:38:15 +01:00
MervinPraison 0ba0a6415c Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-06-03 13:49:26 +01:00
MervinPraison 0bd8e9f535 fix: ensure newline at end of file in test_graph_memory.py
- Added a newline at the end of the file to comply with standard coding practices.
- Maintained existing functionality while adhering to the principle of minimal code change.
2025-06-03 12:43:55 +01:00
MervinPraison 2dc02ed5a6 refactor: enhance test structure in test_scheduler.py
- Simplified test function structure for improved clarity and maintainability.
- Removed redundant error handling to streamline code execution.
- Ensured adherence to minimal code change principles while maintaining functionality.
2025-06-03 12:26:11 +01:00
MervinPraison ea4a2f3b69 refactor: streamline test functions in test_scheduler.py
- Removed unnecessary try-except blocks in test functions for cleaner code.
- Optimised the structure of test cases for better readability and maintainability.
- Ensured consistent import statements and improved error handling in test execution.
- Maintained functionality while adhering to the principle of minimal code change.
2025-06-03 11:25:35 +01:00
Mervin Praison 4df08daf36 Merge pull request #585 from MervinPraison/claude/issue-142-20250603_084931
fix: add Windows compatibility for shell commands in AICoder
2025-06-03 10:17:48 +01:00
Mervin Praisonandcoderabbitai[bot] a156c2e4a2 Update src/praisonai/praisonai/ui/components/aicoder.py
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-03 09:59:17 +01:00
claude[bot]andMervinPraison d039c2395b fix: add Windows compatibility for shell commands in AICoder
- Add platform import for OS detection
- Implement get_shell_command() method that wraps commands with 'cmd /c' on Windows
- Update execute_command() to use cross-platform command wrapper
- Fixes issue #142 where Unix commands could fail on Windows systems

Co-authored-by: MervinPraison <[email protected]>
2025-06-03 08:51:16 +00:00
Mervin Praison e6bd8d73e4 Merge pull request #584 from MervinPraison/claude/issue-192-20250603_080328
feat: add Azure OpenAI realtime API support via OPENAI_BASE_URL
2025-06-03 09:46:36 +01:00
Mervin Praison e3e4de9f13 Merge pull request #583 from DhivyaBharathy-web/main
Add FunctionAgent Workflow Notebook to Cookbooks
2025-06-03 09:46:04 +01:00
DhivyaBharathy 25b06caa75 Merge branch 'main' into main 2025-06-03 13:48:09 +05:30
claude[bot]andMervinPraison 0a4470dd17 feat: add Azure OpenAI realtime API support via OPENAI_BASE_URL
Replace Azure-specific environment variables with generic OPENAI_* variables:
- OPENAI_BASE_URL: Custom base URL for Azure OpenAI or other providers
- OPENAI_MODEL_NAME: Model name configuration
- OPENAI_API_KEY: API key (already supported)

Features:
- Automatic WebSocket URL conversion for Azure OpenAI endpoints
- Backward compatibility with existing MODEL_NAME variable
- Enhanced OpenAI client configuration in tools
- Updated documentation with Azure configuration examples

Resolves #192

Co-authored-by: MervinPraison <[email protected]>
2025-06-03 08:06:17 +00:00
DhivyaBharathy b65fae4b38 Update FunctionAgent_Workflow.ipynb 2025-06-03 12:43:38 +05:30
DhivyaBharathy-web aa6ef5a94d Added FunctionAgent_Workflow notebook 2025-06-03 07:07:47 +00:00
Mervin Praison cb551debfe Merge pull request #582 from MervinPraison/develop
Develop
2025-06-03 07:55:41 +01:00
MervinPraison fabd852002 chore: update PraisonAI version to 2.2.25 across Dockerfiles and documentation
- Updated the version of PraisonAI from 2.2.24 to 2.2.25 in all relevant Dockerfiles.
- Adjusted version references in README.md and various documentation files.
- Ensured consistency in package versioning for improved stability and performance.
2025-06-03 07:55:27 +01:00
MervinPraison 99de9f4d4f refactor: replace AsyncAsyncWebCrawler with AsyncWebCrawler in chat.py and code.py
- Updated import statements in chat.py and code.py to use AsyncWebCrawler for consistency.
- Modified default model name in realtime.py to include a specific date for clarity.
- Enhanced connection handling in RealtimeAPI to improve websocket connection checks and error handling.
- Added ensure_connected method in RealtimeClient for better connection management.
- Removed outdated realtimedocs.txt file to streamline the codebase.
2025-06-03 07:53:44 +01:00
Mervin Praison daaf92cbeb Merge pull request #581 from MervinPraison/claude/issue-289-20250603_061712
feat: Add domain context solution using existing features
2025-06-03 07:27:29 +01:00
claude[bot]andMervinPraison d8375cb50b feat: Add domain context solution using existing PraisonAI features
Fixes #289 - Multi-agent context issue

This solution demonstrates how to solve the domain context problem where tools 
default to "example.com" instead of user-specified domains. Uses 4 existing 
PraisonAI features:

1. Custom tool wrappers with domain injection
2. Agent instructions with domain context
3. Task context parameter for domain info
4. Shared memory for context persistence

Key benefits:
- No core SDK changes required
- Uses only existing framework features  
- Multi-layer context reliability
- 100% backward compatible
- Works for hierarchical and other processes

Co-authored-by: MervinPraison <[email protected]>
2025-06-03 06:22:53 +00:00
Mervin Praison 36ea8d381e Merge pull request #577 from DhivyaBharathy-web/add-arxiv-agent-notebook
Add arxiv agent notebook example to cookbooks
2025-06-02 11:49:40 +01:00
DhivyaBharathy 8a8f96e5e5 Update arXiv_agent_notebook.ipynb 2025-06-02 15:53:11 +05:30
DhivyaBharathy 7234587829 Update arXiv_agent_notebook.ipynb 2025-06-02 15:28:47 +05:30
DhivyaBharathy d916d0926a Update arXiv_agent_notebook.ipynb 2025-06-02 15:25:56 +05:30
DhivyaBharathy cd09b2de96 Update arXiv_agent_notebook.ipynb 2025-06-02 15:24:29 +05:30
DhivyaBharathy 58b8ad1969 Add files via upload 2025-06-02 15:22:04 +05:30
DhivyaBharathy-web 5e5b6672eb Add arxiv agent notebook example to cookbooks 2025-06-02 09:16:15 +00:00
Mervin Praison f7ce10b92e Merge pull request #566 from MervinPraison/claude/issue-12-20250601_032826
feat: Add human-in-the-loop approval system for dangerous tool operations
2025-06-02 09:42:59 +01:00
Mervin Praison eead19802d Merge pull request #576 from DhivyaBharathy-web/main
Add DuckDuckGo PraisonAI Agent Notebook
2025-06-02 09:40:25 +01:00
MervinPraison 208c8aad3b feat: enhance approval system with context-aware auto-approval
This commit introduces a context-aware auto-approval mechanism for the approval system, allowing non-interactive execution in CI environments. It modifies the test files to include a skip condition for interactive approvals and updates the approval callback logic to support automatic approvals when user input is not required.

Files modified:
- Updated test_approval_agent_integration.py to include auto-approval logic
- Updated test_approval_basic.py to include skip condition for interactive tests
- Updated test_approval_interactive.py to include auto-approval logic
- Enhanced approval.py with context management for approval tracking
- Modified agent.py to prevent double approval in context

This change improves the usability of the approval system in automated workflows while maintaining security.
2025-06-02 09:35:09 +01:00
DhivyaBharathy fb2b086dd5 Update DuckDuckGo_PraisonAI_Agent_Notebook.ipynb 2025-06-02 13:44:41 +05:30
DhivyaBharathy 75972372a6 Update DuckDuckGo_PraisonAI_Agent_Notebook.ipynb 2025-06-02 12:29:34 +05:30
DhivyaBharathy-web 108053bb32 Add DuckDuckGo PraisonAI Agent Notebook 2025-06-02 06:37:45 +00:00
MervinPraison fbddda54ba fix: update import paths in approval agent test files
This commit modifies the import paths in the test files for the approval agent to ensure they correctly reference the local development path. The changes streamline the path structure for better integration with the existing codebase.

Files modified:
- Updated import paths in test_approval_agent_integration.py
- Updated import paths in test_approval_basic.py
- Updated import paths in test_approval_interactive.py
2025-06-01 07:16:28 +01:00
MervinPraison 83427ca929 chore: remove obsolete test_approval_basic.py file
This commit deletes the outdated test_approval_basic.py file, which contained basic tests for the human approval system. The tests are no longer necessary as the functionality has been integrated into other components.

Files modified:
- Deleted test_approval_basic.py
2025-06-01 07:15:18 +01:00
Mervin Praison 36e5047e53 Merge pull request #574 from MervinPraison/claude/issue-444-20250601_050501
fix: resolve Knowledge RAG errors with mem0 API compatibility
2025-06-01 06:23:50 +01:00
claude[bot]andMervinPraison 05d8136433 fix: resolve Knowledge RAG errors with mem0 API compatibility
- Fix CustomMemory._add_to_vector_store method signature to support optional parameters with defaults
- Add backward compatibility for different message formats  
- Update memory.add() call to use correct messages format for mem0 API
- Add fallback mechanism to support both new and legacy API formats
- Resolves "takes 4 positional arguments but 5 were given" error
- Resolves "missing 1 required positional argument: 'infer'" error

Fixes #444

Co-authored-by: MervinPraison <[email protected]>
2025-06-01 05:09:01 +00:00
Mervin Praison af9b251b59 Merge pull request #573 from MervinPraison/claude/issue-107-20250601_045023
feat: integrate Mem0 graph memory support
2025-06-01 06:02:44 +01:00
Mervin Praison c8a6744469 Rename test_graph_memory.py to src/praisonai/tests/unit/test_graph_memory.py 2025-06-01 06:01:31 +01:00
claude[bot]andMervinPraison 678fd462c3 feat: integrate Mem0 graph memory support
- Add graph memory configuration support to Memory class
- Enhanced Knowledge class with graph store support  
- Added optional graph dependency group in pyproject.toml
- Comprehensive examples demonstrating graph memory usage
- Maintained full backward compatibility
- Added test scripts to verify implementation

Supports Neo4j and Memgraph as graph store providers.
Install with: pip install "praisonaiagents[graph]"

Co-authored-by: MervinPraison <[email protected]>
2025-06-01 04:56:24 +00:00
Mervin Praison ba03a0d893 Merge pull request #572 from MervinPraison/claude/issue-421-20250531_210257
feat: support LiteLLM provider-specific parameters
2025-06-01 05:42:39 +01:00
Mervin Praison 3be4c4c70e Merge pull request #571 from MervinPraison/develop
chore: update PraisonAI version to 2.2.24 across Dockerfiles and docu…
2025-06-01 05:38:39 +01:00
MervinPraison 709640240f chore: update PraisonAI version to 2.2.24 across Dockerfiles and documentation
- Updated the version of PraisonAI from 2.2.23 to 2.2.24 in all relevant Dockerfiles.
- Adjusted version references in README.md and various documentation files.
- Ensured consistency in package versioning for improved stability and performance.
2025-06-01 05:36:48 +01:00
Mervin Praison 93d526eb7b Merge pull request #570 from MervinPraison/claude/issue-122-20250601_041558
feat: add --merge CLI parameter for merging agents.yaml files
2025-06-01 05:33:20 +01:00
Mervin Praison 624a2cfa17 Merge pull request #567 from MervinPraison/claude/issue-121-20250531_210355
fix: prevent CLI conflicts when PraisonAI is used as library
2025-06-01 05:30:06 +01:00
Mervin Praison 4d2a6a2e2e Merge pull request #569 from MervinPraison/claude/issue-466-20250601_041120
feat: Add Mem0 built-in reranker support to Knowledge Agent
2025-06-01 05:29:01 +01:00
claude[bot]andMervinPraison a1bdb056a0 refactor: use argparse.Namespace instead of custom DefaultArgs class
Replace the custom DefaultArgs class with argparse.Namespace for better 
maintainability and consistency with argparse conventions. This addresses
the code review suggestion to use idiomatic Python patterns and avoid
duplication of argument handling logic.

Co-authored-by: MervinPraison <[email protected]>
2025-06-01 04:27:44 +00:00
Mervin Praison b4a6401bae Merge pull request #568 from MervinPraison/claude/issue-460-20250601_040421
fix: resolve MCP function signature parameter ordering issue
2025-06-01 05:25:20 +01:00
claude[bot]andMervinPraison 772ce7d2e2 feat: add --merge CLI parameter for merging agents.yaml files
- Add --merge flag to CLI with description for merging behavior
- Default behavior remains overwrite (backwards compatible)
- When --merge is used, preserves existing agents and adds new ones
- Implements intelligent conflict resolution by renaming duplicates
- Combines topics when both existing and new topics are present
- Added comprehensive error handling for invalid YAML files

Usage:
- praisonai --init "topic" (overwrites existing agents.yaml)
- praisonai --init "topic" --merge (merges with existing agents.yaml)

Co-authored-by: MervinPraison <[email protected]>
2025-06-01 04:19:11 +00:00
claude[bot]andMervinPraison 20c2d28f35 feat: Add Mem0 built-in reranker support to Knowledge Agent
- Add rerank parameter to Knowledge.search() method with backward compatibility
- Update memory search methods to pass rerank parameter to Mem0
- Add reranker configuration options with enabled/default_rerank settings
- Support all Mem0 advanced retrieval options (keyword_search, filter_memories)
- Create comprehensive example demonstrating reranker usage and performance
- Maintains full backward compatibility - existing code works unchanged
- Addresses issue #466 for improved RAG relevance with minimal latency impact

Co-authored-by: MervinPraison <[email protected]>
2025-06-01 04:14:24 +00:00
claude[bot]andMervinPraison f8589e4363 fix: resolve MCP function signature parameter ordering issue
Fix ValueError "non-default argument follows default argument" in MCP tool 
wrapper creation by ensuring required parameters come before optional 
parameters in function signatures.

- Separate required and optional parameters during signature creation
- Maintain backward compatibility and preserve all functionality
- Resolves GitHub MCP server initialization failures

Fixes #460

Co-authored-by: MervinPraison <[email protected]>
2025-06-01 04:05:36 +00:00
claude[bot]andMervinPraison 97d368d2e2 feat: Add human-in-the-loop approval system for dangerous tool operations
Implements human approval framework for dangerous operations like shell commands,
code execution, and file operations to enhance security and user control.

Key features:
- @require_approval decorator for marking dangerous tools  
- Risk-based approval (critical, high, medium, low)
- Console approval interface with rich formatting
- Custom approval callbacks for automated policies
- Async/sync support for all workflows
- Runtime configuration of approval requirements

Protected operations:
- Critical: execute_command, kill_process, execute_code
- High: write_file, delete_file, move_file, copy_file
- Medium: evaluate, crawl, scrape_page

Files modified:
- New approval.py module with core framework
- Enhanced main.py with approval callback support
- Modified agent.py to check approvals before tool execution
- Added @require_approval decorators to dangerous tools
- Comprehensive example and test implementations

Resolves: #12

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: MervinPraison <[email protected]>
2025-06-01 03:42:06 +00:00
Mervin Praison 49d9d40199 Merge pull request #565 from MervinPraison/claude/issue-97-20250531_205330
fix: implement litellm handling in code.py same as llm.py
2025-06-01 04:27:46 +01:00
claude[bot]andMervinPraison 445cc037ce fix: prevent CLI conflicts when PraisonAI is used as library
Adds minimal detection in parse_args() to skip CLI parsing when imported
as a library (e.g., by Fabric). Returns default args instead of trying
to parse external application's CLI arguments.

- Only 20 lines added to fix the specific Fabric compatibility issue
- Zero breaking changes - all existing CLI and library usage preserved
- Addresses the root cause from issue #121

Co-authored-by: MervinPraison <[email protected]>
2025-05-31 21:07:12 +00:00
claude[bot]andMervinPraison c4e7b7dc7f feat: support LiteLLM provider-specific parameters
- Add extra_settings to LLM completion parameters
- Enables passing Ollama num_ctx and other provider params
- Maintains backward compatibility
- Addresses issue #421

Co-authored-by: MervinPraison <[email protected]>
2025-05-31 21:05:41 +00:00
claude[bot]andMervinPraison 9e7c172f55 fix: implement litellm handling in code.py same as llm.py
Apply minimal changes to fix LiteLLM provider error:
- Add litellm configuration with drop_params and modify_params
- Add _build_completion_params() helper function
- Update acompletion calls to use proper parameter handling

This prevents "list index out of range" errors when using model names
like "gemini" without provider prefix by leveraging litellm's built-in
parameter validation and modification capabilities.

Fixes #97

Co-authored-by: MervinPraison <[email protected]>
2025-05-31 20:55:14 +00:00
Mervin Praison d89570b085 Merge pull request #564 from MervinPraison/develop
chore: update PraisonAI version to 2.2.23 across Dockerfiles and docu…
2025-05-31 17:09:32 +01:00
MervinPraison ee5dfddccd chore: update PraisonAI version to 2.2.23 across Dockerfiles and documentation
- Updated the PraisonAI version from 2.2.22 to 2.2.23 in all relevant Dockerfiles.
- Adjusted version references in README.md, local-development.mdx, and other documentation files.
- Ensured consistency in versioning for deployment scripts and project files.

This change maintains compatibility with the latest features and fixes in PraisonAI.
2025-05-31 17:08:37 +01:00
Mervin Praison a3bfc6f795 Merge pull request #563 from MervinPraison/claude/issue-459-20250531_155633
fix: resolve MCP tools not working in Streamlit applications (issue #459)
2025-05-31 17:05:57 +01:00
Mervin Praison ebc130854d Merge pull request #562 from MervinPraison/claude/issue-5-20250531_154718
feat: add deployment scheduling functionality
2025-05-31 17:04:49 +01:00
Mervin Praison f40a5c1359 Rename schedule_config.yaml.example to src/praisonai/schedule_config.yaml.example 2025-05-31 17:04:06 +01:00
Mervin Praison 3284f7bbc6 Rename test_scheduler.py to src/praisonai/tests/unit/test_scheduler.py 2025-05-31 17:03:34 +01:00
claude[bot]andMervinPraison 87928611f7 fix: resolve MCP tools not working in Streamlit applications (issue #459)
This commit provides working examples and comprehensive documentation for using MCP tools with Streamlit, without modifying core MCP implementation.

Key fixes:
- Proper session state management to prevent agent re-initialization
- Use standard LLM format instead of provider/model format
- Comprehensive error handling and user feedback
- Working examples with troubleshooting guidance

Files added:
- examples/python/ui/mcp-streamlit-airbnb.py - Complete working Streamlit app
- examples/python/ui/mcp-streamlit-simple.py - Simple fixed version of original code
- docs/ui/streamlit/mcp-streamlit.mdx - Comprehensive documentation and troubleshooting

The root issue was improper usage patterns in Streamlit, not the core MCP implementation.

Co-authored-by: MervinPraison <[email protected]>

🤖 Generated with [Claude Code](https://claude.ai/code)
2025-05-31 15:59:21 +00:00
Mervin Praison 2727bf5992 Merge pull request #561 from MervinPraison/claude/issue-170-20250531_154607
fix: resolve crawling NoneType concatenation error in realtime tools
2025-05-31 16:58:03 +01:00
claude[bot]andMervinPraison 45d04163c3 feat: add deployment scheduling functionality
- Add DeploymentScheduler with provider-agnostic design
- Support interval-based scheduling (daily, hourly, */6h, 3600s)
- CLI integration with --schedule and --schedule-config options
- Backward compatible with existing --deploy behavior
- Thread-safe scheduler with retry mechanism
- Example configuration file for scheduled deployments
- Test suite for validation

Addresses issue #5: --deploy schedule runs

Co-authored-by: MervinPraison <[email protected]>
2025-05-31 15:53:57 +00:00
claude[bot]andMervinPraison 477d0d2e26 fix: resolve crawling NoneType concatenation error in realtime tools
- Fix "can only concatenate str (not "NoneType") to str" error in web crawling
- Update process_tavily_results and fallback_to_duckduckgo to use proper async patterns
- Add null checks for crawl_result.markdown to prevent NoneType errors
- Use async context manager with AsyncWebCrawler and await crawler.arun()
- Match the working async pattern used in chat.py

Fixes #170

Co-authored-by: MervinPraison <[email protected]>
2025-05-31 15:48:02 +00:00
Mervin Praison 77394f5e5f Merge pull request #560 from MervinPraison/develop
Develop
2025-05-31 16:44:03 +01:00
MervinPraison 29e533c18c chore: remove unsloth training dependency from pyproject.toml
- Cleared the train dependencies list by removing unsloth[colab-new]>=2024.11.7.
- Commented out the unsloth dependency to maintain a record without affecting functionality.
2025-05-31 16:43:46 +01:00
MervinPraison 48dbea0566 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-31 12:42:45 +01:00
Mervin Praison 969d6697e1 Merge pull request #559 from MervinPraison/claude/issue-232-20250531_060542
fix: add dependency check for train command to prevent confusing errors
2025-05-31 12:42:22 +01:00
Mervin Praisonandcoderabbitai[bot] 787d2508b1 Update src/praisonai/pyproject.toml
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-05-31 12:41:18 +01:00
claude[bot]andMervinPraison ec42dc92e4 feat: add unsloth training dependencies to pyproject.toml
- Add train optional dependencies with unsloth[colab-new]>=2024.11.7
- Update Poetry extras to include unsloth for train command
- Enables pip install "praisonai[train]" for training dependencies
- Maintains backward compatibility

Co-authored-by: MervinPraison <[email protected]>
2025-05-31 10:45:40 +00:00
claude[bot]andMervinPraison 5b7bae2f43 fix: add dependency check for train command to prevent confusing errors
- Add TRAIN_AVAILABLE flag to track unsloth dependency availability
- Add dependency validation in both parse_args() and main() methods
- Show clear error message with installation instructions when dependencies missing
- Follow same pattern as other commands (chat, code, call, realtime) for consistency
- Fixes issue where train command would show "train not available" without helpful context

Resolves #232

Co-authored-by: MervinPraison <[email protected]>
2025-05-31 06:07:31 +00:00
MervinPraison 69a1efac47 fix(tests): update expected name in tool call parsing test for malformed JSON
- Changed the expected function name in the test for malformed JSON from 'hello_world' to 'unknown_function' to reflect correct error handling behaviour.
- Adjusted the Python path in the test file to point to the correct source directory for the praisonai-agents module.
2025-05-31 06:51:09 +01:00
Mervin Praison e6381139ec Merge pull request #558 from MervinPraison/develop
Develop
2025-05-30 18:10:59 +01:00
MervinPraison aca2a58971 chore: update PraisonAI version to 2.2.22 across Dockerfiles and documentation
- Updated the version of PraisonAI from 2.2.21 to 2.2.22 in all relevant Dockerfiles.
- Adjusted README and local development documentation to reflect the new version.
- Ensured consistency in versioning across all instances where PraisonAI is referenced.
2025-05-30 18:10:42 +01:00
MervinPraison 7a07ebd05e Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 18:06:46 +01:00
Mervin Praison 418d6c810b Merge pull request #557 from MervinPraison/claude/issue-471-20250530_151237
fix(ollama): resolve tool-call issues with local Ollama models
2025-05-30 18:04:17 +01:00
Mervin Praison 8bcfdfe713 Update and rename test_ollama_fix.py to src/praisonai/tests/unit/test_ollama_fix.py 2025-05-30 18:01:53 +01:00
claude[bot]andMervinPraison 57f2fa0471 fix(ollama): resolve tool-call issues with local Ollama models
- Fix tool parameter logic in agent.py to handle empty tools list properly
- Add comprehensive Ollama provider detection via model name and env vars
- Implement centralized tool call argument parsing with error handling
- Add consistent JSON error handling for all providers (sync and async)
- Users no longer need to pass tools to both agents AND tasks

Fixes #471

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 15:17:06 +00:00
MervinPraison 2fdffd2d8d playwright mcp 2025-05-30 15:56:30 +01:00
Mervin Praison 471a6a106c Update article_generation_agents.ipynb 2025-05-30 15:41:18 +01:00
Mervin Praison 7c51c3aad1 Update article_generation_agents.ipynb 2025-05-30 15:40:48 +01:00
Mervin Praison dfa261f5ef Merge pull request #556 from MervinPraison/develop
chore: update PraisonAI version to 2.2.21 across Dockerfiles and docu…
2025-05-30 15:36:44 +01:00
MervinPraison 9a97f0b80f chore: update PraisonAI version to 2.2.21 across Dockerfiles and documentation
- Updated the version of PraisonAI from 2.2.20 to 2.2.21 in all relevant Dockerfiles.
- Adjusted README and local development documentation to reflect the new version.
- Ensured consistency in versioning across all instances where PraisonAI is referenced.
2025-05-30 15:36:03 +01:00
Mervin Praison eef9a5f7ae Merge pull request #555 from MervinPraison/claude/issue-18-20250530_125354
feat: Add comprehensive secondary market research agent system
2025-05-30 14:24:29 +01:00
Mervin Praison 510e9b1797 Merge pull request #554 from MervinPraison/claude/issue-23-20250530_125338
Add CSV processing examples for issue #23
2025-05-30 14:22:23 +01:00
Mervin Praison 89f48cf7a2 Merge pull request #553 from MervinPraison/develop
chore: update PraisonAI version to 2.2.20 across Dockerfiles and docu…
2025-05-30 14:16:47 +01:00
MervinPraison 97fb7fdd52 chore: update PraisonAI version to 2.2.20 across Dockerfiles and documentation
- Updated the version of PraisonAI from 2.2.19 to 2.2.20 in all relevant Dockerfiles.
- Adjusted README and local development documentation to reflect the new version.
- Ensured consistency in versioning across all instances where PraisonAI is referenced.
2025-05-30 14:16:19 +01:00
Mervin Praison ea4cb42324 Merge pull request #552 from MervinPraison/claude/issue-115-20250530_125352
fix: resolve ForwardRef TypeError for praisonai code command
2025-05-30 14:14:11 +01:00
claude[bot]andMervinPraison 43da66d129 feat: Add comprehensive secondary market research agent system
- Multi-agent system with 6 specialized research agents
- Customizable parameters for company, geography, industry, and sections
- YAML configuration for easy setup and customization
- FastAPI integration with async job processing and REST API
- Professional report generation suitable for business decision-making
- Jupyter notebook with multiple implementation examples
- Complete documentation and usage guidelines

Addresses issue #18 - Secondary market research agent with customization

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 13:00:21 +00:00
claude[bot]andMervinPraison e1a61959ea feat: Add comprehensive CSV processing examples for issue #23
- Add simple CSV URL processor for basic use cases
- Add comprehensive CSV processing with 4 different methods
- Add complete documentation with setup and troubleshooting
- Address GitHub issue #23: "How to pass in a CSV file"
- Support sequential processing of URLs and other CSV data
- Include validation, error handling, and multiple processing patterns

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 12:58:39 +00:00
Mervin Praison 71c5b929b7 Merge pull request #551 from MervinPraison/develop
Develop
2025-05-30 13:57:04 +01:00
claude[bot]andMervinPraison c9edf19907 fix: resolve ForwardRef TypeError for praisonai code command
Fixes #115

Resolves TypeError: ForwardRef._evaluate() missing recursive_guard argument when running `praisonai code`.

## Changes
- Moved crewai import from module level to conditional import in handle_direct_prompt
- The `code` command doesn't need crewai, only chainlit and other UI dependencies
- Follows existing pattern for optional dependencies

## Testing
- `praisonai code` now works without requiring crewai installation
- Direct prompt functionality still works when crewai is available

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 12:56:57 +00:00
MervinPraison 6cdc79f4a2 fix: update import path for database_config module in unit tests
- Adjusted the import statement in test_database_config.py to reference the correct module path.
- Ensures that the tests can locate the database_config functionalities properly.
2025-05-30 13:56:49 +01:00
MervinPraison fdda350b72 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 13:33:56 +01:00
Mervin Praison 85f748d5d1 Merge pull request #549 from DhivyaBharathy-web/add-langchain-praisonai-agents-notebook
Add LangChain + PraisonAI agents Colab notebook
2025-05-30 13:33:50 +01:00
MervinPraison bf24548598 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 13:33:24 +01:00
Mervin Praison a1622a2a79 Merge pull request #550 from MervinPraison/claude/issue-17-20250530_113738
feat: add piped input support to CLI
2025-05-30 13:32:57 +01:00
DhivyaBharathy-web 209faff03c Add LangChain + PraisonAI agents Colab notebook 2025-05-30 11:49:03 +00:00
Mervin Praison ad67089813 Merge pull request #548 from MervinPraison/claude/issue-201-20250530_113510
fix: move OpenAI API key validation from import-time to runtime
2025-05-30 12:41:49 +01:00
claude[bot]andMervinPraison 3e44eadd37 feat: add piped input support to CLI
Implement piped command functionality similar to fabric project, allowing:
- echo "content" | praisonai "command"
- cat file.txt | praisonai --auto "task"
- echo "question" | praisonai

Added read_stdin_if_available() method to detect and read piped input,
and modified main() to handle piped content in three scenarios:
1. Command + piped input
2. Direct prompt + piped input  
3. Only piped input

Fixes #17

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 11:39:42 +00:00
claude[bot]andMervinPraison 764e9aa838 fix: move OpenAI API key validation from import-time to runtime in call.py
- Removes import-time API key requirement that prevented GUI startup
- Moves validation to run_server() function where it's actually needed
- Allows PraisonAI to start without OpenAI API key for non-voice features
- Users can now configure API key through existing GUI interfaces
- Follows existing codebase patterns for conditional feature validation

Fixes #201

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 11:39:28 +00:00
Mervin Praison ccfc92564e Merge pull request #547 from MervinPraison/claude/issue-140-20250529_041935
fix: add fallback mechanism for conda run failure in training
2025-05-30 12:33:06 +01:00
MervinPraison 1f61000922 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 12:30:26 +01:00
Mervin Praison 2164f3e658 Merge pull request #546 from MervinPraison/claude/issue-190-20250530_111525
fix: add console scripts to project.scripts section for pip compatibility
2025-05-30 12:30:18 +01:00
MervinPraison 739a9ff8b5 docker 2025-05-30 12:28:49 +01:00
MervinPraison dbe63cbbc9 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 12:27:33 +01:00
Mervin Praison f4bff11e83 Merge pull request #545 from MervinPraison/claude/issue-130-20250530_105428
feat: implement comprehensive Docker support and package publishing for issue #130
2025-05-30 12:27:23 +01:00
Mervin Praison 6552f61322 Update __init__.py 2025-05-30 12:26:57 +01:00
Mervin Praison d5d898ff1b Update __init__.py 2025-05-30 12:26:15 +01:00
Mervin Praison 4df8d122fc Update __init__.py 2025-05-30 12:25:51 +01:00
Mervin Praison 766e5789e3 Update __init__.py 2025-05-30 12:25:14 +01:00
Mervin Praison f9585e83cb Delete src/praisonai/praisonai/inc/directory_manager.py 2025-05-30 12:24:57 +01:00
claude[bot]andMervinPraison e019bab987 fix: address critical security and implementation issues
- Remove automatic directory initialization on package import to prevent unexpected file operations
- Add DOCKER_CONTAINER=true environment variable to all Dockerfiles
- Fix hardcoded password security issue in docker-compose.dev.yml
- Prevent api.py overwrite in main Dockerfile by checking if file exists
- Use non-editable pip install in production Dockerfile for praisonaiagents
- Move package installations from runtime commands to Dockerfile build stage for better efficiency

These fixes address the critical issues identified in the code review while maintaining the core functionality.

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 11:20:27 +00:00
claude[bot]andMervinPraison 54072a1d55 fix: add console scripts to project.scripts section for pip compatibility
- Add [project.scripts] section with praisonai, setup-conda-env, and praisonai-call entry points
- Fixes issue where praisonai command was not found when installing with pip instead of Poetry
- Entry points were only defined in [tool.poetry.scripts] which pip ignores
- Maintains compatibility with both pip and Poetry installation methods

Fixes #190

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 11:17:09 +00:00
Mervin Praison 16ddcb8644 Merge pull request #544 from MervinPraison/claude/issue-246-20250530_105609
fix: add targeted o1 model support for system messages
2025-05-30 12:06:16 +01:00
MervinPraison e0b9739b66 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 12:04:03 +01:00
claude[bot]andMervinPraison 1bb6c8ca61 fix: add targeted o1 model support for system messages
- Add `_needs_system_message_skip()` method to detect legacy o1 models
- Skip system messages only for specific models: o1-preview, o1-mini, o1-mini-2024-09-12
- Update all 4 system message handling locations in LLM class
- Maintains backward compatibility for all other models
- Fixes 400 error for legacy o1 models that don't support system messages

Fixes #246

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 11:03:18 +00:00
claude[bot]andMervinPraison a242a26353 feat: implement directory management solution for issue #130
- Add DirectoryManager class to organize files in ~/.praison/
- Automatic migration of existing configuration files from root
- Environment variable management for proper config paths
- Solves directory clutter issue (chainlit.md, .chainlit, public)

Co-Authored-By: MervinPraison <[email protected]>
2025-05-30 11:01:42 +00:00
claude[bot]andMervinPraison ff4f63fc54 feat: add Docker documentation and development setup
- Comprehensive Docker setup guide and documentation
- Environment template for easy configuration
- Development Docker Compose with hot reload
- Interactive quick-start script for user convenience

Co-Authored-By: MervinPraison <[email protected]>
2025-05-30 11:01:35 +00:00
claude[bot]andMervinPraison 48707686f0 feat: update Docker configurations for improved multi-service setup
- Add new praisonaiagents Dockerfile
- Update docker-compose.yml with multi-service orchestration
- Align versions across all Dockerfiles
- Add directory management environment variables
- Support for ~/.praison/ configuration directory

Co-Authored-By: MervinPraison <[email protected]>
2025-05-30 11:01:23 +00:00
MervinPraison 1a414989bf Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 11:59:17 +01:00
Mervin Praison 141535c160 Merge pull request #543 from MervinPraison/claude/issue-238-20250528_161801
feat: add camera integration examples and documentation
2025-05-30 11:58:29 +01:00
MervinPraison 6911d6ad64 fix: Update import path for database_config module in unit tests
- Adjusted the sys.path in test_database_config.py to correctly locate the database_config module.
- Ensured compatibility with the module's new location for improved test functionality.
2025-05-30 11:51:29 +01:00
Mervin Praison 6b4be5ca2f Merge pull request #542 from MervinPraison/develop
chore: Update praisonai version to 2.2.19 across Dockerfiles and rela…
2025-05-30 11:46:35 +01:00
MervinPraison a5d08f8f33 chore: Update praisonai version to 2.2.19 across Dockerfiles and related configurations
- Increment praisonai version from 2.2.18 to 2.2.19 in Dockerfiles and deployment scripts
- Update version in pyproject.toml for praisonaiagents from 0.0.91 to 0.0.92
- Ensure consistency across all relevant files for the new version

This update addresses compatibility and feature improvements associated with the latest praisonai release.
2025-05-30 11:46:15 +01:00
Mervin Praison 8e0fa939a4 Merge pull request #540 from MervinPraison/claude/issue-240-20250528_161140
fix: Add DeepSeek compatibility fallback for hierarchical process mode
2025-05-30 11:42:07 +01:00
Mervin Praison 359d02bd56 Merge pull request #537 from MervinPraison/claude/issue-335-20250529_033521
fix: Add FORCE_SQLITE environment variable to bypass production database detection
2025-05-30 11:12:41 +01:00
Mervin Praison 7630e35622 Rename test_database_config.py to src/praisonai/tests/unit/test_database_config.py 2025-05-30 11:12:21 +01:00
claude[bot]andMervinPraison 1fc3a22335 refactor: centralize FORCE_SQLITE logic to eliminate code duplication
- Create shared database_config module with utility functions
- Eliminate duplicated FORCE_SQLITE parsing logic between db.py and sql_alchemy.py  
- Improve maintainability by centralizing database configuration logic
- Add comprehensive test coverage for all scenarios

Addresses reviewer feedback from CodeRabbit and Gemini Code Assist

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 10:09:52 +00:00
claude[bot]andMervinPraison 3d56de7d64 fix: Resolve async client usage and improve error handling in DeepSeek fallback
- Fix critical async client usage by importing and using AsyncOpenAI for async methods
- Add proper exception chaining with 'from' clauses and detailed logging
- Implement JSON parsing error handling with specific exception types
- Replace hardcoded JSON structure prompts with dynamic schema generation
- Enhance fallback mechanism robustness for DeepSeek compatibility

Fixes identified issues:
- Lines 168 & 181: Async methods now use proper AsyncOpenAI clients
- Lines 124 & 164: Exception handling now chains errors properly
- Lines 158-160 & 192-194: JSON parsing wrapped in try-catch blocks
- Lines 119 & 145: Dynamic prompt generation from Pydantic schemas

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 09:48:12 +00:00
Mervin Praison 6008f5c9b6 Merge pull request #541 from MervinPraison/claude/issue-337-20250528_160403
feat: Add SearxNG search tool for privacy-focused web searches
2025-05-30 10:38:22 +01:00
Mervin Praison 6b9a186751 Merge pull request #539 from DhivyaBharathy-web/add-advanced-react-agent-notebook
Add Advanced ReAct Agent notebook to cookbooks
2025-05-30 09:16:32 +01:00
Mervin Praison ce0e46b7f4 Merge pull request #538 from DhivyaBharathy-web/add-joke-agent-notebook
Add Joke Agent notebook to cookbooks
2025-05-30 09:15:46 +01:00
DhivyaBharathy-web 74563a2fbb Add Advanced ReAct Agent notebook to cookbooks 2025-05-29 13:46:48 +00:00
DhivyaBharathy-web 92324d55d2 Add Joke Agent notebook to cookbooks 2025-05-29 07:32:17 +00:00
Mervin Praison 280c66ad94 Merge pull request #535 from MervinPraison/claude/issue-332-20250528_161954
fix: improve API key validation for LM Studio and local servers
2025-05-29 05:45:14 +01:00
claude[bot]andMervinPraison dc9faba1c9 refactor: improve API key validation with constants and enhanced local server detection
- Add LOCAL_SERVER_API_KEY_PLACEHOLDER constant for consistency
- Improve error messages to clearly distinguish default OpenAI vs local servers
- Enhance local server detection with urlparse for localhost/127.0.0.1 handling
- Remove hardcoded "nokey" fallback that masked missing API key issues
- Maintain full backward compatibility

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: MervinPraison <[email protected]>
2025-05-29 04:41:10 +00:00
Mervin Praison 10d9f00fd5 Update models.py 2025-05-29 05:30:08 +01:00
Mervin Praison 5c9ac6f222 Merge branch 'main' into claude/issue-332-20250528_161954 2025-05-29 05:27:36 +01:00
Mervin Praisonandgemini-code-assist[bot] 8ea7c3289f Update src/praisonai/praisonai/inc/models.py
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-05-29 05:22:03 +01:00
Mervin Praison 2ac83534d8 Merge pull request #536 from MervinPraison/claude/issue-307-20250528_161908
fix: resolve asyncio event loop error in memory callbacks
2025-05-29 05:21:20 +01:00
claude[bot]andMervinPraison ba5af94dcb fix: add fallback mechanism for conda run failure in training
- Add robust conda environment detection and setup validation
- Implement fallback to direct Python execution when conda fails
- Maintain backward compatibility while improving reliability
- Handle cases where conda is not available or environment setup fails

Fixes #140

Co-authored-by: MervinPraison <[email protected]>
2025-05-29 04:20:59 +00:00
Mervin Praison b1d9ef567b Merge pull request #534 from MervinPraison/develop
2.2.18
2025-05-29 04:52:31 +01:00
MervinPraison e633ad959d chore: update PraisonAI version and enhance environment variable handling
- Upgraded PraisonAI version from 2.2.17 to 2.2.18 across multiple Dockerfiles and configuration files for improved functionality.
- Enhanced GitHub Actions workflow by exporting additional environment variables related to the OpenAI API, improving integration and debugging capabilities.

These changes aim to ensure better performance and reliability in the workflow and API interactions.
2025-05-29 04:51:53 +01:00
MervinPraison 27065af652 chore: enhance API key handling and testing in workflows
- Introduced a dummy class for SecretStr to handle cases where Pydantic is not available, ensuring compatibility in minimal contexts.
- Added a utility function to display API key values more securely, improving the visibility of sensitive information during testing.
- Updated test cases to ensure the OPENAI_API_KEY is available for subprocess commands, enhancing the reliability of tests that require real API interactions.

These changes aim to improve the robustness of API key handling and enhance the testing framework's functionality.
2025-05-29 04:38:51 +01:00
claude[bot]andMervinPraison 46585a88e6 fix: Add FORCE_SQLITE environment variable to bypass production database detection
- Add FORCE_SQLITE flag in both db.py and sql_alchemy.py
- When FORCE_SQLITE=true, ignores DATABASE_URL and SUPABASE_DATABASE_URL
- Forces SQLite usage to prevent accidental production database connections
- Maintains backward compatibility with default behavior (FORCE_SQLITE=false)
- Resolves database conflict issues in production environments

Fixes #335

Co-authored-by: MervinPraison <[email protected]>
2025-05-29 03:36:38 +00:00
Mervin Praison 312d1a8734 Merge pull request #532 from MervinPraison/develop
Develop
2025-05-28 18:41:01 +01:00
MervinPraison 311034e78b chore: update PraisonAI dependencies and enhance model testing in workflows
- Upgraded PraisonAI version from 2.2.16 to 2.2.17 across multiple Dockerfiles and configuration files for improved functionality.
- Enhanced the testing of the PraisonAIModel by explicitly passing the API key and base URL, improving integration with CrewAI.
- Added error handling during model instantiation to provide clearer feedback on failures, enhancing debugging capabilities.

These changes aim to ensure better performance and reliability in the workflow and model interactions.
2025-05-28 18:40:48 +01:00
MervinPraison 509d8492ec chore: add debugging steps for PraisonAI API key validation in GitHub Actions workflow
- Introduced additional checks to verify the presence and validity of the OpenAI API key within the workflow.
- Added a new step to directly test the PraisonAI API key usage, enhancing visibility into the API key configuration and its integration with the PraisonAI model.
- These changes aim to improve debugging capabilities and ensure proper API key handling during the workflow execution.
2025-05-28 18:33:25 +01:00
MervinPraison cb4ee28e7e chore: enhance GitHub Actions workflows with environment variable debugging
- Added steps to set and debug environment variables related to the OpenAI API in the GitHub Actions workflows.
- Included checks for the availability of the API key and its fallback mechanism, improving visibility during execution.
- Enhanced dependency installation commands for better integration with the existing setup.

These changes aim to streamline the workflow and provide clearer insights into the environment configuration.
2025-05-28 18:27:08 +01:00
MervinPraison 7f23daf670 chore: enhance testing workflow and API test execution
- Added new steps to the GitHub Actions workflow to run real API tests and end-to-end tests with the actual OpenAI API key.
- Removed API key validation checks from test cases, allowing all tests to run regardless of API key status.
- Streamlined test cases for better readability and maintainability.

These changes improve the testing process and ensure comprehensive test coverage.
2025-05-28 18:17:55 +01:00
MervinPraison 223650dad5 chore: update .gitignore to include additional test directories for CrewAI
- Added entries to the .gitignore file to ensure that integration and end-to-end test directories for CrewAI are not ignored.
- This change enhances the visibility of relevant test files during the development process.
2025-05-28 18:08:16 +01:00
MervinPraison 1e23d76742 chore: add debugging steps to GitHub Actions workflow for CrewAI tests
- Introduced a new debugging section to display the directory structure and contents relevant to CrewAI tests.
- Enhanced the test execution process by attempting multiple methods to run CrewAI tests, providing clearer feedback on failures.

These changes aim to improve visibility and troubleshooting during the testing process.
2025-05-28 18:03:38 +01:00
MervinPraison 83adac3709 chore: enhance GitHub Actions workflow and test cases
- Added debugging steps to check API key availability and log environment variables in the GitHub Actions workflow.
- Updated test cases to remove API key validation checks, ensuring all tests run regardless of API key status.
- Renamed test steps for clarity and improved readability.

These changes improve the testing process and provide better insights during execution.
2025-05-28 17:58:44 +01:00
MervinPraison e3a5f87a1f chore: enhance test workflow and API key handling
- Added PYTHONPATH to the GitHub Actions environment for improved module accessibility.
- Updated legacy test command to skip execution if the API key is invalid, providing clearer output.
- Optimised command execution in test cases for better readability and maintainability.

These changes improve the testing process and ensure better handling of API key scenarios.
2025-05-28 17:53:00 +01:00
MervinPraison 63f94c6a4d refactor: streamline API test skipping and result validation in test cases
- Updated test cases to provide clearer messages for skipping tests due to invalid/test API keys.
- Simplified result validation by asserting non-null results instead of checking for specific output strings.
- Removed redundant exception handling for API errors, focusing on essential functionality.

This change enhances readability and maintainability of the test code.
2025-05-28 17:32:34 +01:00
claude[bot]andMervinPraison ecb4974333 fix: improve API key validation for LM Studio and local servers
- Replace hardcoded "xxxx" fallback in main.py with proper validation
- Replace hardcoded "nokey" fallback in models.py with proper validation  
- Add automatic detection and support for local servers (LM Studio, etc.)
- Provide clear error messages when API keys are missing
- Support multiple base URL environment variable patterns

Fixes #332

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 16:23:06 +00:00
claude[bot]andMervinPraison 955a05be59 feat: add camera integration examples and documentation
- Add comprehensive camera integration examples in examples/python/camera/
  - camera-basic.py: Single frame capture and analysis
  - camera-continuous.py: Continuous monitoring system
  - camera-multi-agent.py: Multi-agent parallel analysis
  - camera-video-analysis.py: Video recording and temporal analysis
  - README.md: Complete documentation for all examples

- Add camera integration documentation in docs/features/camera-integration.mdx
  - Complete integration patterns and use cases
  - Configuration options and best practices
  - Troubleshooting guide and security considerations
  - Links to example code

- Update docs/mint.json to include camera integration in navigation

Addresses issue #238 regarding multimodel agent camera input

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 16:22:02 +00:00
MervinPraison b95b88d0cb Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-28 17:20:57 +01:00
claude[bot]andMervinPraison f6526ab127 fix: resolve asyncio event loop error in memory callbacks
- Replace deprecated asyncio.get_event_loop() with asyncio.get_running_loop()
- Add proper RuntimeError handling for non-main threads (Streamlit)
- Fix memory dependency checking to use warnings instead of exceptions
- Improves compatibility with Python 3.10+ and threaded environments

Fixes #307

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 16:20:44 +00:00
Mervin Praison 9b155e54e2 Merge pull request #531 from MervinPraison/claude/issue-247-20250528_143914
fix: resolve PydanticSchemaGenerationError for List[Any] and BaseModel fields
2025-05-28 17:20:30 +01:00
claude[bot]andMervinPraison 66dc2e3c48 fix: Add DeepSeek compatibility fallback for hierarchical process mode
- Add JSON fallback when structured output fails
- Implements minimal code change solution for issue #240  
- Maintains compatibility with both OpenAI and DeepSeek APIs
- Uses try-catch to gracefully fallback from structured output to JSON mode
- Enhanced prompts for better JSON parsing reliability

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 16:14:48 +00:00
claude[bot]andMervinPraison 90c3a90752 feat: Add SearxNG search tool for privacy-focused web searches
- Implement SearxNG search tool following PraisonAI patterns
- Add comprehensive documentation with setup instructions
- Include working examples for both tools and agents
- Support configurable SearxNG URL and search parameters
- Integrate with existing tools registry and documentation
- Provide privacy-focused alternative to traditional search engines

Addresses issue #337

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 16:07:30 +00:00
Mervin Praison a2d7629492 Merge pull request #530 from MervinPraison/claude/issue-311-20250528_143819
fix: Memory error with wrong LLM model #311
2025-05-28 17:05:58 +01:00
Mervin Praison a904673325 Merge pull request #529 from MervinPraison/claude/issue-388-20250528_154600
fix: resolve Python 3.8 compatibility issue with tuple type annotation
2025-05-28 16:56:42 +01:00
Mervin Praison a6d1ef93e0 Merge pull request #528 from MervinPraison/claude/issue-393-20250528_143351
fix: update chainlit Action constructor to use payload parameter
2025-05-28 16:54:12 +01:00
Mervin Praison d1989159bc Merge pull request #526 from MervinPraison/claude/issue-394-20250528_143330
fix: Support OPENAI_BASE_URL and MODEL_NAME for Ollama integration
2025-05-28 16:53:04 +01:00
Mervin Praison b2a0f5b341 Merge pull request #527 from MervinPraison/claude/issue-457-20250528_143145
fix: correct knowledge_sources parameter in AutoAgents
2025-05-28 16:52:54 +01:00
claude[bot]andMervinPraison caabe553ce fix: resolve Python 3.8 compatibility issue with tuple type annotation
- Change `tuple[List[Agent], List[Task]]` to `Tuple[List[Agent], List[Task]]` in autoagents.py:258
- Add `Tuple` import to typing imports
- Add `requires-python = ">=3.8"` to pyproject.toml

Fixes #388

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 15:47:23 +00:00
MervinPraison f62601ed47 Add API key validation check to skip tests when invalid key is provided 2025-05-28 16:05:33 +01:00
claude[bot]andMervinPraison 402796020c fix: resolve PydanticSchemaGenerationError for List[Any] and BaseModel fields
- Add arbitrary_types_allowed=True to LoopItems model in process.py
- Add arbitrary_types_allowed=True to TaskOutput model in main.py  
- Add arbitrary_types_allowed=True to AgentConfig and AutoAgentsConfig models in autoagents.py
- Import ConfigDict from pydantic in all affected files

Fixes #247

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 14:45:13 +00:00
claude[bot]andMervinPraison 3a30c3813d fix: Pass agent's LLM model to memory quality metrics calculation
Fixes issue where memory system was using hardcoded gpt-4o model instead of user's configured LLM (e.g., llama3 with Ollama). The calculate_quality_metrics method now receives the agent's LLM configuration to use the correct model for quality evaluation.

Resolves #311

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 14:42:56 +00:00
Mervin Praison 8e16621f46 Merge pull request #525 from MervinPraison/claude/issue-404-20250524_061713
Fix TypeError in AutoAgents: change knowledge_sources to knowledge parameter
2025-05-28 15:39:24 +01:00
claude[bot] f86e9ef470 docs: Update Ollama integration documentation with new environment variables
- Added standard OpenAI SDK environment variables (OPENAI_BASE_URL, MODEL_NAME)
- Documented alternative patterns (OLLAMA_API_BASE) from community feedback
- Added complete usage example with praisonai --init
- Maintained backward compatibility documentation for legacy patterns

Related to #394 - Now users have clear documentation on how to properly
configure Ollama with the fixed environment variable support.
2025-05-28 14:38:43 +00:00
claude[bot] c4058143aa chore: Remove temporary test file after verifying Ollama fix
The test file was created to verify the Ollama integration fix works correctly
and is no longer needed in the repository.
2025-05-28 14:38:21 +00:00
claude[bot]andMervinPraison 6b4ed568a8 fix: Support OPENAI_BASE_URL and MODEL_NAME environment variables for Ollama integration
- Fixed auto.py to check OPENAI_BASE_URL before OPENAI_API_BASE
- Added support for MODEL_NAME environment variable (community requested)
- Added support for OLLAMA_API_BASE environment variable  
- Applied same fixes to cli.py for consistency
- Added comprehensive test script to verify the fix

Fixes #394 - Users can now use standard OpenAI SDK environment variables:
- OPENAI_BASE_URL=http://localhost:11434/v1 
- MODEL_NAME=deepseek-r1:14b
- OPENAI_API_KEY=NA

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 14:38:15 +00:00
claude[bot]andMervinPraison 1ba540f0ab fix: update chainlit Action constructor to use payload parameter
- Replace deprecated 'value' parameter with 'payload' in cl.Action constructor
- Fixes ValidationError when executing 'python -m praisonai ui'
- Updates both agents.py and chainlit_ui.py files
- Resolves compatibility issue with chainlit 2.5.5

Resolves #393

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 14:35:20 +00:00
claude[bot]andMervinPraison ce4103d311 fix: correct knowledge_sources parameter in AutoAgents
- Fixed parameter name mismatch in AutoAgents._create_agents_and_tasks()
- Changed 'knowledge_sources' to 'knowledge' when passing to Agent constructor
- Resolves TypeError when using AutoAgents with DuckDuckGo tool

Fixes #457

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 14:33:40 +00:00
Mervin Praison a21c9ea15a Merge pull request #524 from MervinPraison/develop
Remove unused agent files and clean up test directory by deleting obs…
2025-05-28 14:49:08 +01:00
MervinPraison 422d638cd4 Refactor mock completion function in mini agents tests for improved clarity and functionality 2025-05-28 14:13:02 +01:00
MervinPraison baa5caf3c3 Update test mocks in mini agents to use the correct model class path 2025-05-27 10:21:15 +01:00
MervinPraison 4a51cae4f8 Update test mocks for mini agents to reference the correct class path 2025-05-27 10:19:07 +01:00
MervinPraison caa4473871 Update GitHub Actions workflow to use absolute paths for agent scripts 2025-05-27 10:08:57 +01:00
MervinPraison acdfc54302 Fix file paths and add test mocking for mini agents sequential tests 2025-05-27 09:57:37 +01:00
MervinPraison 3856be09df Remove unused agent files and clean up test directory by deleting obsolete test scripts and configuration files. 2025-05-27 09:49:57 +01:00
Mervin Praison 81f0f49d15 Merge pull request #523 from MervinPraison/develop
Reorganize examples directory structure and update file paths
2025-05-27 07:56:34 +01:00
MervinPraison 13e425e0ac Reorganize examples directory structure and update file paths 2025-05-27 07:56:14 +01:00
Mervin Praison 9c9a8b249e Merge pull request #522 from MervinPraison/develop
Develop
2025-05-27 07:32:17 +01:00
MervinPraison ff4ab536af Moved cookbook examples to examples/cookbooks directory and reorganized YAML files 2025-05-27 07:31:59 +01:00
MervinPraison 7a7b9bd0d4 Reorganize docs structure and update package dependencies for v2.2.16 2025-05-27 07:15:50 +01:00
Mervin Praison 8900fdcc95 Merge pull request #521 from MervinPraison/develop
Restructure
2025-05-27 07:08:47 +01:00
MervinPraison e7f7b1239c Add initial README with package description and directory structure 2025-05-27 07:06:17 +01:00
MervinPraison 9596b49f3c Update GitHub Actions workflow directory paths and add package README.md 2025-05-27 07:04:51 +01:00
MervinPraison 6fa66157ae Add cd src/praisonai before package installation in CI workflows 2025-05-27 06:57:53 +01:00
MervinPraison c50e3d94b5 Remove PYTHONPATH from workflows and update test coverage path to praisonai 2025-05-27 06:42:49 +01:00
MervinPraison 0ef82bdf7e Restructure 2025-05-27 06:34:35 +01:00
Mervin Praison a7ce92f9ce Merge pull request #520 from MervinPraison/claude/issue-481-20250527_044929
feat: Add AWS Bedrock integration support
2025-05-27 06:13:04 +01:00
Mervin Praison f36415d4ea Merge pull request #519 from MervinPraison/develop
Update version to 2.2.16 across project files
2025-05-27 06:10:32 +01:00
MervinPraison 13c3e31458 Update version to 2.2.16 across project files
- Incremented PraisonAI version from 2.2.15 to 2.2.16 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Updated dependency version for `praisonaiagents` from 0.0.88 to 0.0.89.
- Ensured minimal changes to existing code while maintaining versioning accuracy across the project.
2025-05-27 06:10:01 +01:00
Mervin Praison 41d550c4a5 Merge pull request #518 from MervinPraison/claude/issue-484-20250527_043953
feat: Add context management for workflow loops
2025-05-27 05:54:45 +01:00
Mervin Praison ac570e5b93 Rename test_context_management.py to tests/unit/test_context_management.py 2025-05-27 05:54:18 +01:00
claude[bot]andMervinPraison 65e389af03 feat: Add AWS Bedrock integration support
- Add comprehensive AWS Bedrock documentation with setup guide
- Support for Anthropic Claude, Amazon Titan, Cohere, and Meta models via Bedrock
- Include IAM permissions, regional availability, and cost optimization guidance
- Add Python example demonstrating multi-model usage
- Add YAML cookbook example for multi-agent workflows
- Update navigation to include AWS Bedrock in models section
- Maintain backward compatibility through existing LiteLLM integration

Resolves #481

Co-authored-by: MervinPraison <[email protected]>
2025-05-27 04:53:40 +00:00
claude[bot]andMervinPraison a5465882ee feat: Add context management for workflow loops to prevent context length issues
- Add retain_full_context parameter to Task class (default False)
- By default, only include most recent previous task in context
- Maintain backwards compatibility with retain_full_context=True
- Add _build_task_context helper method to Process class  
- Update both async and sync workflow methods to use new context building
- Add test script to verify functionality

Fixes context accumulation issue in workflow loops where all previous
task results were being appended, causing exponential context growth.

Co-authored-by: MervinPraison <[email protected]>
2025-05-27 04:47:37 +00:00
Mervin Praison f86b03e5d8 Merge pull request #517 from MervinPraison/develop
Update version to 2.2.15 across project files
2025-05-27 05:47:27 +01:00
MervinPraison 397a466f55 Update version to 2.2.15 across project files
- Incremented PraisonAI version from 2.2.14 to 2.2.15 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Updated dependency version for `praisonaiagents` from 0.0.87 to 0.0.88.
- Ensured minimal changes to existing code while maintaining versioning accuracy across the project.
2025-05-27 05:36:34 +01:00
Mervin Praison 36c3066ba4 Merge pull request #515 from MervinPraison/claude/issue-514-20250526_155559
fix: Add asyncio import to local scope in launch() method
2025-05-26 20:00:06 +01:00
claude[bot]andMervinPraison df06e794b3 fix: Add asyncio import to local scope in launch() method
This fixes the NameError: cannot access free variable 'asyncio' where it is not associated with a value in enclosing scope error that occurs at line 1563.

The issue was that the handle_agent_query function (containing line 1563) is defined inside a try/except block that imports FastAPI dependencies but didn't include asyncio. Added import asyncio to the try block and removed redundant import from line 1659.

Fixes #514

Co-authored-by: MervinPraison <[email protected]>
2025-05-26 15:59:29 +00:00
Mervin Praison 71fe678d66 Merge pull request #513 from MervinPraison/develop
Update version to 2.2.14 across project files
2025-05-25 06:47:58 +01:00
MervinPraison c8875eec81 Update version to 2.2.14 across project files
- Incremented PraisonAI version from 2.2.13 to 2.2.14 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Ensured minimal changes to existing code while maintaining versioning accuracy across the project.
2025-05-25 06:47:32 +01:00
Mervin Praison f88204d2e8 Merge pull request #512 from MervinPraison/develop
Update version to 2.2.13 across project files
2025-05-24 23:18:37 +01:00
MervinPraison fc01a80956 Update version to 2.2.13 across project files
- Incremented PraisonAI version from 2.2.12 to 2.2.13 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Ensured minimal changes to existing code while maintaining versioning accuracy across the project.
2025-05-24 23:18:09 +01:00
Mervin Praison cd91565b12 Merge pull request #511 from MervinPraison/develop
Update version to 2.2.12 across project files
2025-05-24 22:59:55 +01:00
MervinPraison d233d4597c Update version to 2.2.12 across project files
- Incremented PraisonAI version from 2.2.11 to 2.2.12 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Ensured minimal changes to existing code while maintaining versioning accuracy across the project.
2025-05-24 22:59:36 +01:00
Mervin Praison a9fabce0ea Merge pull request #510 from MervinPraison/develop
Develop
2025-05-24 22:46:10 +01:00
MervinPraison 6bcd3ba9bd Update version to 2.2.11 across project files
- Incremented PraisonAI version from 2.2.10 to 2.2.11 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Ensured minimal changes to existing code while maintaining versioning accuracy across the project.
2025-05-24 22:45:46 +01:00
MervinPraison 37028b0dd2 Enhance backup process for root configuration files in GitHub Actions workflow
- Updated echo statements to provide clearer context regarding the backup of `agents.yaml` and `tools.py`, preventing default file resolution interference during tests.
- Ensured minimal changes to existing code while improving clarity and user understanding of the backup process.
2025-05-24 22:38:10 +01:00
MervinPraison 6807d0e017 Add backup and restore steps for root configuration files in GitHub Actions workflow
- Introduced steps to back up and restore `agents.yaml` and `tools.py` during the workflow execution, preventing interference and ensuring a clean environment for tests.
- Added comprehensive execution debug step to provide detailed insights into the execution path and configuration status.
- Ensured minimal changes to existing code while enhancing the debugging and testing process for configuration management.
2025-05-24 22:35:23 +01:00
MervinPraison bca845d771 Add debug steps for logging level and researcher role detection in GitHub Actions workflow
- Introduced a new environment variable for log level and additional steps to search for the 'Researcher' role in YAML files, enhancing visibility during the workflow execution.
- Added a step to trace the AutoGen execution path, providing insights into framework decisions and available roles.
- Ensured minimal changes to existing code while improving the debugging and testing process for configuration and role management.
2025-05-24 22:07:21 +01:00
Mervin Praison 0596d2da2e Merge pull request #509 from MervinPraison/develop
Develop
2025-05-24 22:02:07 +01:00
MervinPraison 368498452c Add debug steps for YAML loading and framework detection in GitHub Actions workflow
- Introduced new steps in `unittest.yml` to debug YAML file loading and framework detection, providing detailed output on available YAML files and their content.
- Enhanced error handling to ensure visibility of issues during framework detection.
- Ensured minimal changes to existing code while improving the debugging process for configuration and role management.
2025-05-24 22:01:42 +01:00
MervinPraison 47e5ad2a65 Update version to 2.2.10 across project files
- Incremented PraisonAI version from 2.2.9 to 2.2.10 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Updated `litellm` dependency version from `1.41.8` to `1.68.0` across multiple files to ensure compatibility and improvements.
- Ensured minimal changes to existing code while maintaining versioning accuracy and optimising dependency management.
2025-05-24 21:58:27 +01:00
MervinPraison eb346be5f8 Add debug step for PraisonAIModel API key handling in GitHub Actions workflow
- Introduced a new step in `unittest.yml` to debug the handling of the PraisonAIModel API key, providing detailed output on its status and configuration.
- Ensured minimal changes to existing code while enhancing the testing process for API key integration and error visibility.
2025-05-24 21:53:47 +01:00
MervinPraison 62ab76f3e9 Add API key validation step in GitHub Actions workflow
- Introduced a new step in `unittest.yml` to validate the OpenAI API key by making a minimal API call, providing feedback on its status.
- Ensured minimal changes to existing code while enhancing the testing process for API configurations.
2025-05-24 21:50:48 +01:00
MervinPraison ac26c5fbe8 Add debug and test steps in GitHub Actions workflow
- Introduced a new step in `unittest.yml` to debug Python environment variables, checking the status of OpenAI API keys and other related variables for better visibility.
- Added a test step for direct PraisonAI execution to validate local functionality.
- Ensured minimal changes to existing code while enhancing the testing and debugging process in the workflow.
2025-05-24 21:45:36 +01:00
MervinPraison 22c10ff6ac Enhance error handling in test cases for API authentication
- Added try-except blocks in `test_agents_playbook.py` to handle API authentication errors gracefully, allowing tests to skip when encountering specific exceptions.
- Ensured minimal changes to existing code while improving robustness in test execution.
2025-05-24 21:40:25 +01:00
Mervin Praison 494f835e73 Merge pull request #508 from MervinPraison/develop
Develop
2025-05-24 21:36:27 +01:00
MervinPraison 3686eb2eaa Update version to 2.2.9 across project files
- Incremented PraisonAI version from 2.2.8 to 2.2.9 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Enhanced model retrieval logic in `agents_generator.py` for improved fallback handling.
- Ensured minimal changes to existing code while maintaining versioning accuracy and optimising model configuration.
2025-05-24 21:35:30 +01:00
MervinPraison 58c63f0dd4 Update LLM models in agents-advanced.yaml for consistency
- Replaced existing LLM model references with "openai/gpt-4o-mini" across various roles to standardise the configuration.
- Ensured minimal changes to existing code while enhancing model uniformity.
2025-05-24 21:20:43 +01:00
MervinPraison 7bf5c0a4d8 Add debug step for API key status in GitHub Actions workflow
- Introduced a new step in `unittest.yml` to check the availability of the OpenAI API key, providing feedback on its status and fallback usage.
- Ensured minimal changes to existing code while enhancing the debugging process for API configurations.
2025-05-24 21:16:47 +01:00
Mervin Praison 082d802fd9 Merge pull request #507 from MervinPraison/develop
Develop
2025-05-24 21:13:54 +01:00
MervinPraison 8cd926a244 Update version to 2.2.8 across project files
- Incremented PraisonAI version from 2.2.7 to 2.2.8 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Ensured minimal changes to existing code while maintaining versioning accuracy.
2025-05-24 21:13:31 +01:00
MervinPraison 987f63f032 Update environment variable setup in GitHub Actions workflows
- Modified `test-comprehensive.yml`, `test-core.yml`, `test-extended.yml`, and `test-frameworks.yml` to include default values for OpenAI API configuration, enhancing robustness during testing.
- Ensured minimal changes to existing code while improving the handling of environment variables.
2025-05-24 20:53:59 +01:00
Mervin Praison bec938883d Merge pull request #506 from MervinPraison/develop
Update version to 2.2.7 across project files
2025-05-24 18:15:04 +01:00
MervinPraison 76079a92fe Update version to 2.2.7 across project files
- Incremented PraisonAI version from 2.2.6 to 2.2.7 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Updated Python version specification in `test-comprehensive.yml` to focus solely on Python 3.11.
- Ensured minimal changes to existing code while maintaining versioning accuracy.
2025-05-24 18:13:59 +01:00
Mervin Praison c14fb2ee5d Merge pull request #505 from MervinPraison/develop
Update version to 2.2.6 across project files
2025-05-24 17:39:59 +01:00
MervinPraison 31c9a6a994 Update version to 2.2.6 across project files
- Incremented PraisonAI version from 2.2.5 to 2.2.6 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Updated test command patterns in GitHub Actions workflows for improved clarity and functionality.
- Ensured minimal changes to existing code while maintaining versioning accuracy.
2025-05-24 17:39:41 +01:00
Mervin Praison b5b4370cc8 Merge pull request #504 from MervinPraison/develop
Update Python version format in GitHub Actions workflow
2025-05-24 17:28:59 +01:00
MervinPraison 745f82b9c4 Update version to 2.2.5 across project files
- Incremented PraisonAI version from 2.2.4 to 2.2.5 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Ensured minimal changes to existing code while maintaining versioning accuracy.
2025-05-24 17:28:26 +01:00
MervinPraison 6845c7b0f6 Update Python version format in GitHub Actions workflow
- Changed the Python version specification in `test-comprehensive.yml` from unquoted to quoted strings for consistency and improved readability.
- Ensured minimal changes to existing code while enhancing clarity in the workflow configuration.
2025-05-24 17:20:27 +01:00
Mervin Praison e7be52722e Merge pull request #503 from MervinPraison/develop
Develop
2025-05-24 17:10:20 +01:00
MervinPraison e673189454 Update version to 2.2.4 across project files
- Incremented PraisonAI version from 2.2.3 to 2.2.4 in `pyproject.toml`, `uv.lock`, and all relevant Dockerfiles for consistency.
- Ensured minimal changes to existing code while maintaining versioning accuracy.
2025-05-24 17:09:45 +01:00
MervinPraison ab9192c57e Enhance GitHub Actions workflows and update test assertions
- Added environment variable setup in `test-extended.yml` for OpenAI API configuration.
- Updated test command in `unittest.yml` to use a pattern for faster execution.
- Refined assertions in `test_base_url_api_base_fix.py` to reflect changes in parameter naming from `base_url` to `api_base`.
- Improved mock tool listing in `test_mcp_integration.py` for clarity.
- Adjusted knowledge update logic in `test_rag_integration.py` to handle existing knowledge more effectively.
- Ensured minimal changes to existing code while enhancing test clarity and functionality.
2025-05-24 17:03:52 +01:00
Mervin Praison 819874275f Merge pull request #502 from MervinPraison/develop
Update GitHub Actions workflows to remove Python 3.9 support
2025-05-24 16:31:46 +01:00
MervinPraison 0a36fdb966 Update GitHub Actions workflows to remove Python 3.9 support
- Modified workflow files to exclude Python 3.9 from the test matrix, focusing on Python 3.10 and 3.11 for improved compatibility.
- Ensured minimal changes to existing code while streamlining the testing process.
2025-05-24 16:29:14 +01:00
Mervin Praison 768549bb52 Merge pull request #501 from MervinPraison/develop
Develop
2025-05-24 16:00:41 +01:00
MervinPraison 5d1bc19e15 Update version to 2.2.3 and enhance test configurations
- Incremented PraisonAI version from 2.2.2 to 2.2.3 in `pyproject.toml`, `uv.lock`, and Dockerfiles for consistency.
- Updated `.gitignore` to include exceptions for CrewAI test directories.
- Added new test markers in `pytest.ini` for better categorisation of tests.
- Enhanced GitHub Actions workflows to include new test patterns for AutoGen and CrewAI frameworks.
- Refactored test runner to improve clarity and user experience, including warnings for real tests and full execution tests.
- Ensured minimal changes to existing code while improving overall test structure and documentation.
2025-05-24 15:59:57 +01:00
MervinPraison 05a114f939 Update GitHub Actions workflows to use actions/setup-python@v5
- Modified multiple workflow files to upgrade actions/setup-python from version 4 to version 5 for improved functionality and consistency.
- Ensured minimal changes to existing code while enhancing the setup process for Python environments.
2025-05-24 14:00:02 +01:00
MervinPraison 4b9d291d16 Update GitHub Actions workflows to use latest action versions
- Upgraded actions/checkout to version 4 and actions/setup-python to version 5 across multiple workflow files for improved functionality.
- Updated actions/upload-artifact to version 4 in relevant workflows to enhance artifact management.
2025-05-24 13:54:03 +01:00
MervinPraison 5eb8862a7e Update dependencies and refactor test functions for clarity
- Added `pytest-asyncio` as a dependency in `pyproject.toml` for improved async testing capabilities.
- Updated GitHub Actions workflow to include `pytest-cov` for coverage reporting.
- Renamed test functions in `advanced_example.py` and `basic_example.py` for better clarity and user-friendliness.
- Removed unused event loop fixture from `conftest.py` to streamline test setup.
- Enhanced assertions in various tests to ensure better error reporting and maintainability.
2025-05-24 13:48:22 +01:00
MervinPraison 0bacff3997 Add simple test runner and basic diagnostic tests
- Introduced a new simple test runner (`simple_test_runner.py`) that operates without pytest dependency at import time.
- Added a basic diagnostic test script (`test_basic.py`) to validate Python and module imports.
- Updated `README.md` to include new test runner instructions and troubleshooting tips for pytest import issues.
- Enhanced `test_runner.py` to conditionally import pytest and fallback to subprocess if not available, maintaining existing functionality.
- Ensured backward compatibility with existing tests and workflows.
2025-05-24 13:14:24 +01:00
MervinPraison ac8e6daadf Refactor GitHub Actions workflow for quick validation tests
- Renamed workflow from 'Run specific unittest' to 'Quick Validation Tests'.
- Introduced a new job 'quick-test' for streamlined testing.
- Added installation of pytest and pytest-asyncio for enhanced testing capabilities.
- Updated test command to run legacy example tests using pytest with improved output options.
- Included environment variable for PYTHONPATH to facilitate module resolution.
2025-05-24 13:08:14 +01:00
MervinPraison f4cf97abdb Update GitHub Actions workflow to use latest action versions and improve installation commands
- Upgraded actions/checkout and actions/setup-python to version 4.
- Changed UV installation method to use a script for better integration.
- Modified dependency installation commands to include the --system flag for UV.
- Enhanced unittest command to run with verbose output for clearer test results.
2025-05-24 08:25:23 +01:00
Mervin Praison 2f0e3c0507 Merge pull request #498 from MervinPraison/develop
Update version numbers and dependencies to 2.2.2 and 0.0.87 across pr…
2025-05-24 08:23:33 +01:00
MervinPraison 5e11f7566d Update version numbers and dependencies to 2.2.2 and 0.0.87 across project files
- Incremented PraisonAI version from 2.2.1 to 2.2.2 in pyproject.toml, uv.lock, Dockerfiles, and documentation.
- Updated praisonaiagents version from 0.0.85 to 0.0.87 in relevant files.
- Adjusted installation commands in GitHub Actions workflow to use 'uv' for dependency management.
- Enhanced test scripts to return meaningful results for better assertion checks.
2025-05-24 08:22:57 +01:00
Mervin Praison 66a8c9e074 Merge pull request #497 from MervinPraison/claude/issue-467-20250524_055552
Claude/issue 467 20250524 055552
2025-05-24 07:33:18 +01:00
Mervin Praison 2ef8250d49 Delete tests/test_base_url_api_base_fix.py 2025-05-24 07:33:11 +01:00
Mervin Praison 090f1d1339 Merge pull request #493 from MervinPraison/claude/issue-411-20250524_055043
Fix Mini Agents sequential task data passing issue
2025-05-24 07:31:19 +01:00
Mervin Praison e299a5aaf3 Merge pull request #495 from MervinPraison/claude/issue-410-20250524_055025
Fix agent tool calls expecting strings for integer parameters
2025-05-24 07:30:42 +01:00
Mervin Praison 15bda4df81 Rename test_mini_agents_sequential.py to tests/unit/agent/test_mini_agents_sequential.py 2025-05-24 07:25:32 +01:00
Mervin Praison 57fdc5e4ed Rename test_mini_agents_fix.py to tests/unit/agent/test_mini_agents_fix.py 2025-05-24 07:25:12 +01:00
claude[bot]andMervinPraison 54cb01426f Fix undefined variable in _cast_arguments logging statement
- Replace undefined `function_name` with `getattr(func, '__name__', 'unknown function')`
- This prevents NameError when type casting fails and provides robust function name extraction
- Addresses CodeRabbit review feedback

Co-authored-by: MervinPraison <[email protected]>
2025-05-24 06:22:54 +00:00
Mervin Praison f3d61459fe Delete test_type_casting.py 2025-05-24 07:19:06 +01:00
claude[bot]andMervinPraison ff309010b9 Fix TypeError in AutoAgents: change knowledge_sources to knowledge parameter
- The Agent constructor expects 'knowledge' parameter, not 'knowledge_sources'
- This fixes the TypeError: Agent.__init__() got an unexpected keyword argument 'knowledge_sources'
- Resolves issue #404

Co-authored-by: MervinPraison <[email protected]>
2025-05-24 06:18:58 +00:00
claude[bot]andMervinPraison 53d7d7e7f7 Improve Mini Agents code quality based on review feedback
- Add TaskStatus enum for consistent status string handling
- Create centralized process_task_context() helper function to eliminate code duplication
- Fix poetry.lock sync issue by regenerating lock file
- Maintain existing functionality while improving maintainability

Addresses review feedback from CodeRabbit and Gemini reviewers about:
1. Hardcoded status strings (now use TaskStatus enum)
2. Code duplication between async/sync methods (now use shared helper)
3. CI failure due to poetry lock mismatch (regenerated lock file)

Co-authored-by: MervinPraison <[email protected]>
2025-05-24 06:18:32 +00:00
Mervin Praison c133e24816 Merge pull request #496 from MervinPraison/claude/issue-467-20250524_060326
Add comprehensive integration test for base_url to api_base mapping
2025-05-24 07:14:53 +01:00
Mervin Praison 318131bb92 Merge pull request #494 from MervinPraison/claude/issue-410-20250524_060223
Create unit test structure and add test_type_casting.py
2025-05-24 07:08:11 +01:00
claude[bot]andMervinPraison 6cfa8f30d7 Add comprehensive integration test for base_url to api_base mapping
Addresses Issue #467: Organize test suite with proper directory structure

- Created tests/integration/ directory following TypeScript test patterns
- Added comprehensive test_base_url_api_base_fix.py as integration test
- Tests specific KoboldCPP and OpenAI-compatible endpoint scenarios
- Includes backward compatibility and environment variable tests
- Mock-based testing for reliable CI/CD

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: MervinPraison <[email protected]>
2025-05-24 06:05:32 +00:00
claude[bot]andMervinPraison f6b1517aa0 Create unit test structure and add test_type_casting.py
- Created tests/unit/ directory structure following TypeScript pattern
- Added comprehensive test_type_casting.py in tests/unit/agent/
- Tests cover integer, float, boolean, mixed types, and edge cases
- Tests include graceful fallback for conversion failures
- Ready for when _cast_arguments method is implemented

Co-authored-by: MervinPraison <[email protected]>
2025-05-24 06:04:56 +00:00
claude[bot]andMervinPraison 624837356e Add comprehensive test suite for base_url to api_base mapping fix
- Addresses Issue #467: litellm compatibility with OpenAI-compatible endpoints
- Tests specific KoboldCPP and OpenAI-compatible endpoint scenarios
- Includes backward compatibility and environment variable tests
- Mock-based testing to avoid external dependencies
- Verifies both base_url and api_base parameters are properly passed to litellm

Co-authored-by: MervinPraison <[email protected]>
2025-05-24 05:58:19 +00:00
claude[bot]andMervinPraison df12ae032f Fix Mini Agents sequential task data passing issue
- Improved context processing to validate task completion status
- Fixed context formatting from space-separated to newline-separated 
- Added better error handling for incomplete tasks
- Enhanced debugging with verbose logging
- Added test scripts to verify the fix

This resolves the issue where output from previous tasks was not 
properly passed to subsequent tasks in Mini Agents sequential workflows.

Co-authored-by: MervinPraison <[email protected]>
2025-05-24 05:57:15 +00:00
claude[bot]andMervinPraison c405aaf121 Fix agent tool calls expecting strings for integer parameters
Added type casting utility to Agent class that converts arguments to their expected types based on function signatures:
- Converts string arguments to int, float, bool when annotations are present
- Graceful fallback if conversion fails
- Preserves existing behavior for non-annotated parameters

Fixes #410

Co-authored-by: MervinPraison <[email protected]>
2025-05-24 05:54:12 +00:00
Mervin Praison 03e2bb94f2 Merge pull request #492 from MervinPraison/claude/issue-469-20250523_220748
Fix UnicodeDecodeError in Docker for MCP Google Maps
2025-05-23 23:21:23 +01:00
claude[bot]andMervinPraison 5e3e503dd9 Fix UnicodeDecodeError in Docker for MCP Google Maps initialization
- Add explicit UTF-8 encoding to all subprocess.run() calls in npx_mcp_wrapper_main.py
- Set UTF-8 environment variables (PYTHONIOENCODING, LC_ALL, LANG) in both MCP classes  
- Add UTF-8 encoding to temporary script file creation
- Ensure environment variables are passed to subprocess calls

This resolves the 'ascii' codec can't decode byte 0xc2 error that occurs during
MCP server initialization in Docker containers with minimal locale settings.

Fixes #469

Co-authored-by: MervinPraison <[email protected]>
2025-05-23 22:12:35 +00:00
Mervin Praison 633d724eb2 Merge pull request #485 from MervinPraison/develop
Increment version to 0.0.84 in `pyproject.toml` and `uv.lock`, update…
2025-05-23 23:00:34 +01:00
MervinPraison 5cfda3fa54 Increment version to 2.2.1 in pyproject.toml, uv.lock, and Dockerfiles, and update praisonaiagents version to 0.0.85 across relevant files for improved functionality and compatibility. 2025-05-23 23:00:10 +01:00
MervinPraison 370cb108f2 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-23 22:54:18 +01:00
Mervin Praison 83cb80e907 Merge pull request #487 from MervinPraison/claude/issue-482-20250523_112045
fix: Pass base_url, api_key, and other essential parameters to all litellm calls
2025-05-23 13:37:08 +01:00
claude[bot]andMervinPraison f385de04e0 fix: Pass base_url, api_key, and other essential parameters to all litellm calls
- Add _build_completion_params() method to centralize parameter handling
- Update all 24+ litellm.completion() and litellm.acompletion() calls to use the new method
- Fix async/sync inconsistencies in get_response_async() method
- Ensure base_url, api_key, api_version, timeout, and other configured parameters are consistently passed to litellm
- Resolves connection issues for Ollama and other providers using custom base URLs

Fixes #482

Co-authored-by: MervinPraison <[email protected]>
2025-05-23 11:28:45 +00:00
Mervin Praison 18695543e5 Merge pull request #486 from MervinPraison/add-claude-github-actions-1747999126084
Add Claude Code GitHub Workflow
2025-05-23 12:20:13 +01:00
Mervin Praison 267f223a3e Add Claude PR Assistant workflow 2025-05-23 12:18:47 +01:00
MervinPraison 02bd52a06d Increment version to 0.0.84 in pyproject.toml and uv.lock, update agent functionality in mcp-sse.py and openai-mcp.py for improved task handling, and enhance timeout management in MCP tools for better performance. 2025-05-22 15:35:45 +01:00
Mervin Praison 076576af85 Merge pull request #480 from MervinPraison/develop
v2.2 with MCP SSE and STDIO
2025-05-17 05:03:27 +01:00
MervinPraison 17547073ec v2.2 with MCP SSE and STDIO 2025-05-15 16:01:28 +01:00
Mervin Praison 124a95d7d0 Merge pull request #479 from MervinPraison/develop
Remove agent names and version constraints in MCP server documentation
2025-05-15 12:04:45 +01:00
MervinPraison 8ca4e3285d Remove agent names and version constraints in MCP server documentation 2025-05-15 12:04:07 +01:00
Mervin Praison 5eac60dab3 Merge pull request #478 from MervinPraison/develop
2.1.6
2025-05-15 07:54:46 +01:00
MervinPraison 59ee7cbbe5 Add MCP server examples and deployment docs with version bump to 2.1.6 2025-05-15 07:54:17 +01:00
MervinPraison 81517b58e5 Increment version to 0.0.82 in pyproject.toml and uv.lock, and enhance agent launch functionality in agents.py to support both HTTP and MCP protocols, including improved endpoint management, healthcheck capabilities, and error handling for agent execution. 2025-05-15 07:42:53 +01:00
Mervin Praison c1a8338a24 Merge pull request #477 from MervinPraison/develop
multi agents deploy
2025-05-14 13:08:57 +01:00
MervinPraison dba5a49569 multi agents deploy 2025-05-14 13:08:18 +01:00
Mervin Praison 6dab69e9d7 Merge pull request #476 from MervinPraison/develop
Add multi-agent API functionality in `multi-agents-api.py` and `multi…
2025-05-14 12:50:13 +01:00
MervinPraison 90563207f7 Add multi-agent API functionality in multi-agents-api.py and multi-agents-group-api.py, increment version to 0.0.80 in pyproject.toml and uv.lock, and enhance agent launch logic in agents.py with improved endpoint management and healthcheck capabilities. 2025-05-14 12:49:58 +01:00
Mervin Praison 46330b0487 Merge pull request #475 from MervinPraison/develop
v2.1.4
2025-05-14 10:49:01 +01:00
MervinPraison a133f0d5e2 Update package versions and add deployment documentation 2025-05-14 10:48:27 +01:00
MervinPraison fb22e6e1c7 Refactor agent launch functionality in multi-agent-api.py to remove blocking parameters, update version to 0.0.79 in pyproject.toml and uv.lock, and enhance server startup logic in agent.py with healthcheck endpoint and improved thread management. 2025-05-14 09:13:40 +01:00
Mervin Praison e938fe63ea Merge pull request #473 from emmanuel-ferdman/main
Resolve Python Logger warnings
2025-05-14 06:33:25 +01:00
Mervin Praison ef96e53843 Merge pull request #474 from MervinPraison/develop
Increment version to 0.0.78 in `pyproject.toml`, add API dependencies…
2025-05-14 06:32:05 +01:00
MervinPraison 036c463a43 Increment version to 0.0.78 in pyproject.toml, add API dependencies for FastAPI and Uvicorn, and implement HTTP API launch functionality in agent.py for enhanced agent interaction. 2025-05-14 06:30:42 +01:00
Emmanuel Ferdman 0e6b4aefc3 Resolve Python Logger warnings
Signed-off-by: Emmanuel Ferdman <[email protected]>
2025-05-13 14:08:22 -07:00
Mervin Praison bbb9f677ae Merge pull request #472 from MervinPraison/develop
Add STDIO MCP documentation and update navigation menu
2025-05-13 16:40:35 +01:00
MervinPraison 0da201b3b6 Add STDIO MCP documentation and update navigation menu 2025-05-13 16:40:20 +01:00
Mervin Praison a7b85043e1 Merge pull request #470 from elandau1260/add_repot_path_to_env
Added PRAISONAI_CODE_REPO_PATH env variable to point code to differen…
2025-05-13 14:55:28 +01:00
Mervin Praison dc393e1211 Merge pull request #456 from MervinPraison/develop
Increment version to 0.0.77 in `pyproject.toml` and update `markitdow…
2025-05-13 14:47:44 +01:00
MervinPraison fdff17faf9 MCP SSE Docs 2025-05-13 14:46:11 +01:00
MervinPraison b3d893fae1 Implement SSEMCPClient and SSEMCPTool for MCP server interaction, enhance logging configuration, and increment version to 0.0.77 in pyproject.toml and uv.lock for improved functionality. 2025-05-13 14:29:41 +01:00
MervinPraison d92dede515 Re-add mcp-sse-direct-agent.py without API key 2025-05-13 14:01:35 +01:00
MervinPraison a1882233dc mcp sse 2025-05-13 13:55:32 +01:00
Ed Landau aa6b6ac62e Added PRAISONAI_CODE_REPO_PATH env variable to point code to different repot 2025-05-02 13:01:21 -07:00
MervinPraison c540ba34fb Increment version to 0.0.76 in pyproject.toml and update markitdown dependency to include all extras in uv.lock for enhanced functionality. 2025-04-08 12:05:03 +01:00
Mervin Praison 0abb1b659a Merge pull request #455 from MervinPraison/develop
Increment version to 0.0.75 in `pyproject.toml` and update Python com…
2025-04-08 11:49:15 +01:00
MervinPraison 81adb28688 Increment version to 0.0.75 in pyproject.toml and update Python compatibility requirements in uv.lock to support Python 3.11 and above. 2025-04-08 11:48:53 +01:00
Mervin Praison 5fbe6e948c Merge pull request #450 from ihsankursadunal/add-to-vector-store-fifth-positional-argument
RAG knowledge positional argument error fix
2025-04-08 11:48:11 +01:00
Mervin Praison 6128e4c885 Merge pull request #454 from MervinPraison/develop
Add new Databutton and Research agents in `databutton-mcp.py` and `mc…
2025-04-08 11:35:34 +01:00
MervinPraison 0e563989ed Add new Databutton and Research agents in databutton-mcp.py and mcp-llama4.py, respectively. Increment version to 0.0.74 in pyproject.toml and update Python requirements in uv.lock for compatibility with Python 3.13. 2025-04-08 11:34:37 +01:00
Mervin Praison 510a853e05 Merge pull request #453 from chonknick/update-chonkie-v102
Fix: breaking change with Chonkie `v1.0.2` — `WordChunker` not found
2025-04-08 11:32:13 +01:00
Bhavnick @ chonkie.ai d6084cb7ce Update chonkie dependency version to 1.0.2 in pyproject.toml and requirements.txt for improved compatibility. 2025-04-07 23:45:26 +05:30
Bhavnick @ chonkie.ai 8d4b1c411b Enhance chunking method: Disable unsupported context parameters and add warning for future support. Track in https://github.com/chonkie-inc/chonkie/issues/21 2025-04-07 23:38:37 +05:30
bhavnicksm 3be05c855b Fix: Remove WordChunker + Disable OverlapRefinery (temporarily) 2025-04-07 23:18:43 +05:30
bhavnicksm 3e5a2f76f4 Update chonkie version to the latest v1.0.2 2025-04-07 23:18:14 +05:30
ihsankursadunal 8eee881d2e RAG knowledge positional argument error fix 2025-04-06 13:09:35 +03:00
Mervin Praison d75f4be41a Merge pull request #448 from MervinPraison/develop
Develop
2025-04-03 06:47:51 +01:00
MervinPraison 9ea89448ef Increment version number to 0.0.73 in pyproject.toml and uv.lock to reflect recent updates. 2025-04-03 06:47:35 +01:00
MervinPraison 0a5e2df278 Merge PR #409: Support chat without stream while maintaining stream=True as default 2025-04-03 06:30:23 +01:00
MervinPraison cc3b64f89b fix: keep default stream=True while supporting stream=False option 2025-04-03 06:30:04 +01:00
Mervin Praison 546dc5a441 Merge pull request #391 from yiranwu0/main
Update AG2 reference
2025-04-02 21:44:22 +01:00
Mervin Praison bd7422c7ca Merge pull request #443 from MervinPraison/develop
Add WhatsApp and Perplexity MCP Integrations
2025-04-02 09:54:17 +01:00
MervinPraison 0c2c6da8dd Add WhatsApp and Perplexity MCP Integrations
- Included new MCP tools for WhatsApp and Perplexity in `mint.json` for enhanced functionality.
- Updated installation instructions in `openrouter.mdx` and `xai.mdx` to specify the correct package format.
- Added detailed documentation for WhatsApp and Perplexity integrations, including setup steps and example scripts.
- Incremented version number to 0.0.72 in `pyproject.toml` and `uv.lock` to reflect recent changes.
2025-04-02 09:54:02 +01:00
Mervin Praison b43688086f Merge pull request #442 from MervinPraison/develop
Update to version 2.1.1
2025-04-01 22:22:06 +01:00
MervinPraison 820619e8d9 Update to version 2.1.1
- Incremented version number to 2.1.1 in `pyproject.toml`, `praisonai.rb`, and `uv.lock` to reflect recent changes.
- Updated dependency version for `praisonaiagents` to 0.0.71 in `pyproject.toml` and `uv.lock`.
- Modified Dockerfile and deployment scripts to install the updated version of `praisonai`.
- Added new documentation files for various MCP integrations, including Anthropic, Gemini, Groq, Mistral, Ollama, OpenAI, and XAI.
- Introduced example scripts for each MCP integration to facilitate user understanding and implementation.
- Enhanced the LLM class to process tool results based on the original user query for improved response accuracy.
2025-04-01 22:21:50 +01:00
Mervin Praison 94202adddd Merge pull request #441 from MervinPraison/develop
Version 2.1
2025-04-01 21:14:15 +01:00
MervinPraison c7911629b1 Version 2.1 2025-04-01 21:13:30 +01:00
Mervin Praison 5a4e3ba707 Merge pull request #440 from MervinPraison/develop
Update LLM and MCP Integration
2025-04-01 17:54:05 +01:00
MervinPraison 641057b622 Update LLM and MCP Integration
- Changed the LLM model from "groq/llama-3.3-70b-versatile" to "groq/llama-3.2-90b-vision-preview" in `groq-mcp.py` for improved performance.
- Added a new example script `ollama-python.py` for stock price retrieval using the Ollama model.
- Incremented version number to 0.0.70 in `pyproject.toml` to reflect recent changes.
- Updated Python version requirement in `uv.lock` to support Python 3.11 and above for better compatibility.
- Enhanced the LLM class to handle tool calls specifically for Ollama models, ensuring proper processing of tool results.
2025-04-01 17:53:45 +01:00
Mervin Praison db1dbf142e Merge pull request #438 from MervinPraison/develop
groq support included
2025-04-01 13:51:43 +01:00
MervinPraison d9a19ae277 groq support included 2025-04-01 13:51:24 +01:00
Mervin Praison 3c9d889b4f Merge pull request #437 from MervinPraison/develop
Add MCP Integration and Update Documentation
2025-03-31 13:24:04 +01:00
MervinPraison 2f324e74db Add MCP Integration and Update Documentation
- Added `mcp` dependency to `pyproject.toml` for enhanced functionality.
- Introduced new example scripts for various MCP tools, including `fetch-mcp.py`, `git-mcp.py`, `ollama.py`, `sentry-mcp.py`, and `time-mcp.py`, to demonstrate their usage.
- Updated `airbnb.mdx` to reflect the addition of the Airbnb tool to the AI agent.
- Enhanced the `Agent` class to support MCP tools and ensure proper integration with custom LLMs.
- Improved logging for better debugging and tool management.
- Incremented version number to 0.0.68 in `pyproject.toml` for release clarity.
2025-03-31 13:23:49 +01:00
Mervin Praison c22fef3e6d Merge pull request #436 from MervinPraison/develop
Enhance MCP Documentation and Integration
2025-03-31 09:47:52 +01:00
MervinPraison 53bee19948 Enhance MCP Documentation and Integration
- Updated `mint.json` to include additional MCP pages for improved navigation.
- Added new documentation files for various MCP integrations, including AWS KB Retrieval, Everart, Filesystem, Google Drive, GitHub, GitLab, Google Maps, Memory, PostgreSQL, Puppeteer, Redis, Sequential Thinking, Slack, and Stock Price.
- Introduced example scripts for each MCP integration to facilitate user understanding and implementation.
- Ensured consistency in documentation format and clarity in instructions for setting up and using MCP tools.
2025-03-31 09:47:38 +01:00
kevin666aa 798fe68908 update reference 2025-03-30 16:40:06 -04:00
kevin666aa 95796cd4c7 Merge remote-tracking branch 'upstream/main' 2025-03-30 16:22:40 -04:00
Mervin Praison b447b7e6eb Merge pull request #434 from MervinPraison/develop
Add Gradio UI for Airbnb Booking Assistant
2025-03-29 20:55:04 +00:00
MervinPraison 29dfe4b192 Add Gradio UI for Airbnb Booking Assistant
- Introduced a new Gradio interface in `airbnb.mdx` and `ui.py` for searching and booking apartments on Airbnb.
- Implemented the `search_airbnb` function to handle user queries and display results.
- Enhanced user experience with a clear input prompt and structured output format.
2025-03-29 20:54:38 +00:00
Mervin Praison aca95b1713 Merge pull request #433 from MervinPraison/develop
Update navigation and MCP integration
2025-03-29 19:18:34 +00:00
MervinPraison b4cc3d7a8e Update navigation and MCP integration
- Added "MCP" section to `mint.json` for improved documentation navigation.
- Integrated environment variable for `BRAVE_API_KEY` in `mcp-npx-brave.py` to enhance security and flexibility.
- Updated search agent prompt for better clarity.
2025-03-29 19:17:27 +00:00
Mervin Praison c6c27e58a6 Merge pull request #432 from MervinPraison/develop
adding other changes
2025-03-29 17:59:16 +00:00
MervinPraison ae21881522 adding other changes 2025-03-29 17:58:51 +00:00
Mervin Praison 68efb982af Merge pull request #429 from MervinPraison/develop
Add MCP integration for stock price retrieval
2025-03-29 17:58:05 +00:00
MervinPraison c539306b96 Increment version number in pyproject.toml to 2.0.81 2025-03-29 17:57:31 +00:00
MervinPraison c2f2d43d0d adding mcp 2025-03-29 17:57:10 +00:00
MervinPraison 7847515b4b adding mcp npx 2025-03-29 17:55:09 +00:00
Mervin Praison 1f2c412521 Merge pull request #428 from asiffarhankhan/main
Add .py files for all existing .mdx tools, Add .mdx, .py for the new AgentQL tool
2025-03-26 06:06:06 +00:00
asiffarhankhan 355fe1e59c Add local test file 2025-03-23 12:26:56 +05:30
asiffarhankhan 2ed64adc48 Remove API key from code 2025-03-23 12:19:55 +05:30
asiffarhankhan b8bc8583b1 Add agentql tool 2025-03-23 12:13:04 +05:30
asiffarhankhan 51a3a065c4 Add Python Files for existing MDX tools 2025-03-23 04:52:18 +05:30
Mervin Praison 4ba8745544 Merge pull request #427 from bhavnicksm/update-chonkie-config
Fix: `tokenizer` is not recognized error with `chonkie.RecursiveChunker`
2025-03-20 06:03:10 +00:00
bhavnicksm efc347f507 Update chonkie dependency version to ensure compatibility 2025-03-20 05:45:05 +05:30
bhavnicksm 72a162c722 Refactor tokenizer parameter in Chunking class for consistency and clarity 2025-03-20 05:41:02 +05:30
bhavnicksm 734a632dd4 Update chonkie dependency version in requirements.txt 2025-03-20 05:35:11 +05:30
MervinPraison dfaa3ed671 Add MCP integration for stock price retrieval
- Introduced multiple new files for MCP agent functionality, including `mcp-agents-detailed.py`, `mcp-agents.py`, `mcp-basic.py`, `mcp-multiagents.py`, and `mcp-test.py`.
- Implemented a dedicated `MCP` class for managing connections and tool execution.
- Created an asynchronous function to retrieve stock prices using MCP tools.
- Added example agents for stock price checking and web searching.
- Updated `pyproject.toml` and `uv.lock` to reflect version increment to 0.0.66.
- Ensured backward compatibility and improved tool function generation for better usability.
2025-03-18 18:23:39 +00:00
Mervin Praison 175b55704d Merge pull request #425 from asiffarhankhan/main
Add Bearly, Azure and Jina Code Interpreter
2025-03-18 16:56:19 +00:00
asiffarhankhan 084d1a2820 Add Azure and Jina, Bearly Code Interpreter 2025-03-17 23:46:41 +05:30
asiffarhankhan 8518c3ae9d Add Azure and Jina Code Inerpreter 2025-03-17 23:33:33 +05:30
Mervin Praison ac95c0000b Merge pull request #419 from asiffarhankhan/main
Add SearchAPI, YouSearch, TavillySearch tools
2025-03-17 13:38:39 +00:00
asiffarhankhan 8447e02f5d Merge branch 'main' of github.com:asiffarhankhan/PraisonAI 2025-03-15 15:07:38 +05:30
asiffarhankhan 3e612f61dc Add SearchAPI, YouSearch, TavillySearch tools 2025-03-15 15:06:07 +05:30
Mervin Praison b39c04dfb5 Merge pull request #417 from asiffarhankhan/main
Add MDX for Google and Jina Search
2025-03-14 04:46:44 +00:00
asiffarhankhan 8fc367ee6d Add "YOUR_API_KEY" placeholder to empty API variable 2025-03-12 14:26:43 +05:30
asiffarhankhan f7f157d3e7 Update Jina Search to MDX format 2025-03-12 14:19:49 +05:30
asiffarhankhan 05ede2a366 Add Google, Jina Search tools 2025-03-12 14:14:06 +05:30
Mervin Praison f8a2a93400 Merge pull request #416 from MervinPraison/develop
Add playground documentation to navigation
2025-03-11 10:34:12 +00:00
MervinPraison 1a77826a21 Add playground documentation to navigation
- Updated `mint.json` to include the "playground" page in the documentation navigation
- Positioned under the "Other Features" group for easy access
2025-03-11 10:33:54 +00:00
Mervin Praison adfd982547 Merge pull request #415 from MervinPraison/develop
updates
2025-03-11 09:43:36 +00:00
MervinPraison facd52103e updates 2025-03-11 09:42:04 +00:00
Mervin Praison 06d3d3decb Merge pull request #414 from MervinPraison/develop
Add course documentation for AI Agents
2025-03-11 04:59:27 +00:00
MervinPraison 7f35ac6113 Add course documentation for AI Agents
- Created a comprehensive course on AI Agents covering 20 lessons
- Included documentation for course topics like agent architecture, tools, memory, multi-agent systems, and deployment
- Added structured MDX files for each lesson with code examples, explanations, and best practices
- Updated `mint.json` to include new course navigation and pages
- Provided a step-by-step learning path for understanding and building AI agents
2025-03-11 04:58:56 +00:00
Mervin Praison e68fbb46f6 Merge pull request #413 from MervinPraison/develop
Add documentation for additional search tools
2025-03-11 04:10:25 +00:00
MervinPraison 50a7bf6c91 Add documentation for additional search tools
- Updated `mint.json` to include new search tools
- Added documentation pages for DuckDuckGo, Exa, Google Serper, Serp, and Wikipedia search tools
- Included installation instructions, overview, and example code for each search tool
2025-03-11 04:10:02 +00:00
Yuga Sun eaf337b301 fix: remove default stream value for agent 2025-03-11 04:07:40 +00:00
Mervin Praison bce6e424d8 Merge pull request #412 from asiffarhankhan/main
Add search based tools using wikipedia, serper, serp, brave, exa, duckduckgo
2025-03-11 04:01:30 +00:00
asiffarhankhan 5cad05dc0d Align .py files with existing .mdx files 2025-03-11 00:37:40 +05:30
asiffarhankhan 3ecc722866 Add search based tools using wikipedia, serper, serp, brave, exa, duckduckgo 2025-03-11 00:32:02 +05:30
Yuga Sun 2f73cf1882 fix: support chat without stream 2025-03-10 08:00:05 +00:00
Mervin Praison c881fb3280 Merge pull request #408 from MervinPraison/develop
Refactor tools documentation with comprehensive examples and improved…
2025-03-10 06:20:01 +00:00
MervinPraison 15f9cbbe47 Refactor tools documentation with comprehensive examples and improved structure
- Updated tools documentation with new tabbed interface
- Added detailed code and no-code examples for tool creation
- Simplified tool registration and agent configuration examples
- Improved readability and provided step-by-step guidance for tool implementation
2025-03-10 06:19:41 +00:00
Mervin Praison f431347793 Merge pull request #407 from MervinPraison/develop
Add Langchain external search tool examples for PraisonAI agents
2025-03-10 06:03:11 +00:00
MervinPraison e0725c1296 Add Langchain external search tool examples for PraisonAI agents
- Introduced example scripts for Brave Search, Google Trends, and SerpAPI
- Demonstrated multi-agent workflows using external search tools
- Added API key configuration instructions for each search tool
- Included examples of research and content generation agents using search capabilities
2025-03-10 06:02:45 +00:00
Mervin Praison b40295efb9 Merge pull request #406 from MervinPraison/develop
Add external search tool documentation for PraisonAI agents
2025-03-10 05:54:34 +00:00
MervinPraison 2f7769d334 Add external search tool documentation for PraisonAI agents
- Updated `mint.json` to include new external tools section
- Expanded `langchain_tools.mdx` with more comprehensive examples and explanations
- Added documentation pages for BraveSearch, Google Trends, and SerpAPI tools
- Included installation, setup, and usage examples for external search tools
- Organized new documentation under the "External Tools" group
2025-03-10 05:54:13 +00:00
Mervin Praison c326aaf015 Merge pull request #405 from MervinPraison/develop
Add TypeScript documentation and examples for AI agent tools
2025-03-04 20:52:08 +00:00
MervinPraison 03874553eb Add TypeScript documentation and examples for AI agent tools
- Expanded documentation for TypeScript AI agents with tool registration examples
- Added new documentation pages for custom tools in TypeScript
- Updated installation and quickstart guides to include TypeScript sections
- Created example scripts demonstrating single and multi-agent tool usage
- Introduced new documentation for external tools like Google Trends
2025-03-04 20:51:53 +00:00
Mervin Praison 97ae6647c9 Merge pull request #403 from MervinPraison/develop
Expand tool registration documentation and examples
2025-03-03 08:25:09 +00:00
MervinPraison 046fb7cbe7 Expand tool registration documentation and examples
- Added comprehensive TypeScript documentation for tool registration methods in `docs/js/typescript.mdx`
- Created new README example file `examples/README-tool-examples.md` with detailed tool registration approaches
- Updated example scripts to demonstrate direct function tool registration
- Refined agent tool registration logic to support multiple function registration styles
- Bumped package version to 1.0.19
2025-03-03 08:24:46 +00:00
Mervin Praison afdd6ab6f8 Merge pull request #402 from MervinPraison/develop
Enhance agent tool function registration with direct function support
2025-03-03 08:13:52 +00:00
MervinPraison 4581486a81 Enhance agent tool function registration with direct function support
- Added support for directly registering tool functions without global declaration
- Implemented auto-generation of tool definitions for registered functions
- Created new example scripts demonstrating direct function tool registration
- Updated package version to 1.0.18
- Expanded Agent configuration to support `toolFunctions` property
- Added type exports for improved type safety
2025-03-03 08:13:31 +00:00
Mervin Praison e10b991fab Merge pull request #401 from MervinPraison/develop
npm 1.0.17 praisonai
2025-03-03 07:52:40 +00:00
MervinPraison 2d790f79a9 Add tool call support for agents with multi-tool and single-tool test cases
- Enhanced OpenAI service to support tool calls in chat and text generation methods
- Updated Agent classes to register and process tool functions dynamically
- Added new test cases for single and multi-tool agent interactions
- Improved type safety and conversion for OpenAI tool and message formats
- Bumped package version to 1.0.17
2025-03-03 07:52:07 +00:00
MervinPraison ec04dd7a91 test 7 2025-02-28 17:12:25 +00:00
MervinPraison bd49416f2b test 6 2025-02-28 17:05:09 +00:00
MervinPraison da2e11921c test 5 2025-02-28 17:03:42 +00:00
MervinPraison 8287c3a3d4 test 4 2025-02-28 16:57:02 +00:00
MervinPraison 6904f86557 test 3 2025-02-28 16:54:54 +00:00
MervinPraison cbebb3a900 test 2 2025-02-28 16:53:48 +00:00
MervinPraison 413484ea9f test 2025-02-28 16:36:58 +00:00
MervinPraison 785317c4fa test 2025-02-28 11:56:13 +00:00
MervinPraison c70f9ebf1f Add package.json and update documentation requirements
- Created package.json for documentation with Mintlify dev and build scripts
- Updated requirements.in with additional documentation and tool dependencies
- Removed redundant requirements.txt file
- Added support for enhanced documentation generation and API documentation
2025-02-28 11:51:31 +00:00
Mervin Praison d278f2d2b2 Merge pull request #399 from MervinPraison/develop
Bump version to 2.0.80 and update praisonaiagents dependency
2025-02-28 10:25:47 +00:00
MervinPraison df4596a699 Bump version to 2.0.80 and update praisonaiagents dependency
- Updated version to 2.0.80 across multiple files including praisonai.rb, pyproject.toml, uv.lock, Dockerfile, and docs
- Upgraded praisonaiagents dependency from 0.0.64 to 0.0.65
- Enhanced agent start methods with optional return_dict parameter
- Improved result handling in start and astart methods to return final response by default
- Synchronized version updates across project configuration files
2025-02-28 10:25:32 +00:00
Mervin Praison dd0f47ec81 Merge pull request #398 from MervinPraison/develop
Bump version to 2.0.79 and update praisonaiagents dependency
2025-02-28 07:26:52 +00:00
MervinPraison e53017a2fe Bump version to 2.0.79 and update praisonaiagents dependency
- Updated version to 2.0.79 across multiple files including praisonai.rb, pyproject.toml, uv.lock, Dockerfile, and docs
- Upgraded praisonaiagents dependency from 0.0.63 to 0.0.64
- Updated example agent scripts for Anthropic and Gemini LLMs
- Added parameter modification support in LLM initialization
- Synchronized version updates across project configuration files
2025-02-28 07:26:22 +00:00
Mervin Praison fe034ba8f4 Merge pull request #397 from MervinPraison/develop
Enhance Agent Tool Execution Logging and Debugging
2025-02-28 07:05:13 +00:00
MervinPraison 063e5780d6 Enhance Agent Tool Execution Logging and Debugging
- Added comprehensive debug logging for tool execution in LLM and Agent components
- Improved display of tool call messages with more detailed information
- Added logging for empty content and tool execution scenarios
- Enhanced error handling and logging in display functions
- Added new Anthropic LLM example script in src/praisonai-agents
- Bumped version to 2.0.78 and updated praisonaiagents dependency to 0.0.63
2025-02-28 07:04:50 +00:00
Mervin Praison 904e21ca87 Merge pull request #396 from MervinPraison/develop
v2.0.77
2025-02-27 09:12:33 +00:00
MervinPraison 526665ea11 Bump version to 2.0.77 and update praisonaiagents dependency
- Updated version to 2.0.77 across multiple files including praisonai.rb, pyproject.toml, uv.lock, Dockerfile, and docs
- Upgraded praisonaiagents dependency from 0.0.61 to 0.0.62
- Synchronized version updates across project configuration files
2025-02-27 09:11:18 +00:00
MervinPraison c2e97d2432 adding litellm tools fix 2025-02-27 09:08:22 +00:00
MervinPraison 60be6a1f99 Add Comprehensive Debug Logging to LLM and Agent Components
- Enhanced LLM and Agent classes with detailed debug logging capabilities
- Added parameter and configuration logging for get_response and chat methods
- Implemented time tracking for method execution in debug mode
- Masked sensitive information like API keys in logs
- Created new Wikipedia agent example script demonstrating agent initialization
2025-02-27 06:54:32 +00:00
kevin666aa 680949742e Merge remote-tracking branch 'upstream/main' 2025-02-13 15:44:32 -05:00
kevin666aa 560219dcd7 update 2025-02-13 13:39:48 -05:00
Mervin Praison 0ba7d2e834 Merge pull request #385 from MervinPraison/develop
Add Vision Model Upload Functionality and Enhance Training Workflow
2025-02-09 21:23:38 +00:00
MervinPraison 184b241395 Add Vision Model Upload Functionality and Enhance Training Workflow
- Introduced new upload_vision.py script for comprehensive model upload capabilities
- Extended train_vision.py with additional upload methods for Hugging Face and Ollama
- Added support for saving merged models, pushing GGUF models, and creating Ollama models
- Implemented flexible upload targeting with configurable options
- Enhanced model preparation and deployment workflow for vision models
2025-02-09 21:23:24 +00:00
Mervin Praison 4354e76fe5 Merge pull request #383 from MervinPraison/develop
Enhance Vision Model Training with Robust Dataset Conversion and Memo…
2025-02-09 02:46:01 +00:00
MervinPraison 4dd77efb75 Enhance Vision Model Training with Robust Dataset Conversion and Memory Optimization
- Significantly improved train_vision.py with more robust dataset conversion process
- Added detailed debugging and logging for dataset loading and conversion
- Implemented advanced memory management techniques for vision model training
- Enhanced tokenizer handling with fallback mechanisms
- Updated version to 2.0.76 across all relevant files
2025-02-09 02:45:47 +00:00
Mervin Praison 11db6e18ba Merge pull request #382 from MervinPraison/develop
Add Vision Model Training Support and Update Unsloth Dependency
2025-02-09 00:31:40 +00:00
MervinPraison 0d6f698e6c Add Vision Model Training Support and Update Unsloth Dependency
- Enhanced CLI to dynamically select training script based on model type (vision vs. standard)
- Added support for detecting vision models through flexible name matching
- Updated Unsloth dependency to latest commit
- Bumped version to 2.0.75 across all relevant files
2025-02-09 00:31:20 +00:00
Mervin Praison b8574f78e2 Merge pull request #381 from MervinPraison/develop
Bump version to 2.0.74 and refactor train.py template generation
2025-02-07 13:14:32 +00:00
MervinPraison e631774a0f Bump version to 2.0.74 and refactor train.py template generation
- Updated version to 2.0.74 across multiple files (praisonai.rb, pyproject.toml, uv.lock, Dockerfile, docs)
- Simplified training template generation in train.py
- Removed complex stop tokens and simplified template structure
- Dynamically built training arguments with improved configuration flexibility
2025-02-07 13:14:16 +00:00
Mervin Praison df735aa748 Merge pull request #378 from MervinPraison/develop
Enhance train.py with Configurable Training Parameters
2025-02-06 07:48:00 +00:00
MervinPraison 3bdf5b6c65 Enhance train.py with Configurable Training Parameters
- Updated version to 2.0.73 across multiple files
- Refactored TrainModel to use configurable training parameters with default fallbacks
- Improved flexibility of training configuration by allowing custom settings via config
- Dynamically set training arguments based on provided configuration
2025-02-06 07:47:40 +00:00
Mervin Praison 361fa67108 Merge pull request #377 from MervinPraison/develop
Bump version to 2.0.72 and enhance CLI configuration in train and cli…
2025-02-06 07:26:59 +00:00
MervinPraison c5abcf362a Bump version to 2.0.72 and enhance CLI configuration in train and cli modules
- Updated version to 2.0.72 across multiple files (praisonai.rb, pyproject.toml, uv.lock, Dockerfile, docs)
- Refined CLI configuration handling in cli.py for config.yaml generation
- Simplified train.py main function to always use provided config path
- Improved configuration flexibility for training and model setup
2025-02-06 07:26:41 +00:00
Mervin Praison 7ed2d99a11 Merge pull request #376 from MervinPraison/develop
Enhance train.py CLI configuration handling and bump version to 2.0.71
2025-02-06 07:19:11 +00:00
MervinPraison 81307da7c8 Enhance train.py CLI configuration handling and bump version to 2.0.71
- Updated version to 2.0.71 across multiple files (praisonai.rb, pyproject.toml, uv.lock, Dockerfile, docs)
- Modified train.py to use existing config.yaml when no CLI arguments are provided
- Improved CLI configuration flexibility for training command
2025-02-06 07:18:56 +00:00
Mervin Praison fb75153b5c Merge pull request #373 from MervinPraison/develop
Bump version to 2.0.70 and update configuration handling
2025-02-05 06:28:07 +00:00
MervinPraison cddcfcf170 Bump version to 2.0.70 and update configuration handling
- Updated version to 2.0.70 across multiple files (praisonai.rb, pyproject.toml, uv.lock, Dockerfile, docs)
- Enhanced CLI configuration handling in cli.py to load existing config when not creating a new one
- Minor improvements to configuration management and deployment scripts
2025-02-05 06:27:50 +00:00
Mervin Praison 398b0473e0 Merge pull request #372 from MervinPraison/develop
Update train.mdx with Wandb configuration and requirements
2025-02-05 05:07:23 +00:00
MervinPraison c5d260782a Update train.mdx with Wandb configuration and requirements
- Added detailed requirements for training, including Huggingface token and model details
- Included Wandb login and configuration instructions
- Updated documentation with environment variables for Wandb logging
2025-02-05 05:07:08 +00:00
Mervin Praison 116ac5a64d Merge pull request #370 from MervinPraison/develop
Add Wandb Support for Training and Bump Version to 2.0.69
2025-02-04 11:18:42 +00:00
MervinPraison abf6e2e8d1 Add Wandb Support for Training and Bump Version to 2.0.69
- Updated version to 2.0.69 across multiple files (praisonai.rb, pyproject.toml, uv.lock, Dockerfile, docs)
- Enhanced train.py with optional Wandb logging support
- Added environment variable-based Wandb configuration
- Implemented dynamic Wandb reporting and run naming
2025-02-04 11:18:20 +00:00
Mervin Praison cb2b3617fa Merge pull request #369 from MervinPraison/develop
Bump version to 2.0.68 and enhance Ollama model template generation
2025-02-04 11:10:50 +00:00
MervinPraison 6de67c7d0d Bump version to 2.0.68 and enhance Ollama model template generation
- Updated version across multiple files (praisonai.rb, pyproject.toml, uv.lock, Dockerfile, docs)
- Significantly improved train.py's prepare_modelfile_content() method
- Added comprehensive template and stop token mapping for multiple model architectures
- Implemented dynamic template selection based on model name
- Enhanced Ollama model file generation with more flexible configuration
2025-02-04 11:10:26 +00:00
Mervin Praison 5699d90894 Merge pull request #368 from MervinPraison/develop
Enhance train.py with Dynamic Stop Token Generation for Ollama Models
2025-02-04 10:33:19 +00:00
MervinPraison 2982e8ea9c Enhance train.py with Dynamic Stop Token Generation for Ollama Models
- Added intelligent stop token inference for various model architectures in train.py
- Implemented dynamic stop token selection based on model name
- Supported models include Phi, LLaVA, Mistral, Qwen, DeepSeek, and default models
- Updated Modelfile generation to include model-specific stop tokens
- Improved Ollama model preparation flexibility
2025-02-04 10:33:05 +00:00
Mervin Praison 9dd2146342 Merge pull request #367 from MervinPraison/develop
Bump version to 2.0.66 and remove TRAIN_AVAILABLE flag
2025-02-04 09:31:20 +00:00
MervinPraison f79184a6ee Bump version to 2.0.66 and remove TRAIN_AVAILABLE flag
- Updated version across multiple files (praisonai.rb, pyproject.toml, uv.lock, Dockerfile, deploy.py, docs)
- Removed TRAIN_AVAILABLE flag from cli.py
- Simplified CLI configuration by removing optional training feature check
2025-02-04 09:31:07 +00:00
Mervin Praison 0985e12ad4 Merge pull request #366 from MervinPraison/develop
Bump version to 2.0.65 and update deployment configurations
2025-02-04 08:05:06 +00:00
MervinPraison 0fbb7972e1 Bump version to 2.0.65 and update deployment configurations
- Updated version across multiple files (praisonai.rb, pyproject.toml, uv.lock, Dockerfile, deploy.py, docs)
- Enhanced Conda environment setup script with Ollama installation check
- Minor improvements to deployment and setup scripts
2025-02-04 08:04:44 +00:00
Mervin Praison 5744ae853e Merge pull request #365 from MervinPraison/develop
Develop
2025-02-04 07:36:59 +00:00
MervinPraison bd6e3da4ff Bump version to 2.0.64 and update dependencies
- Updated version across multiple files (praisonai.rb, pyproject.toml, uv.lock, Dockerfile, deploy.py, docs)
- Added TRAIN_AVAILABLE flag in cli.py for optional training feature
- Updated Conda environment setup script with latest dependencies
- Minor improvements to training and deployment configurations
2025-02-04 07:36:43 +00:00
MervinPraison f2f51d9e8b Refactor train.py with Enhanced Dataset Processing and Tokenization
- Completely rewrote training script with robust dataset handling
- Added support for ShareGPT and Alpaca-style datasets
- Implemented advanced formatting and tokenization functions
- Enhanced debug logging and error handling
- Simplified model preparation and training workflow
- Updated chat template and tokenization strategies
- Improved inference and model saving methods
2025-02-03 19:38:57 +00:00
Mervin Praison 4a1098603d Merge pull request #364 from MervinPraison/develop
cli docs
2025-02-03 07:41:14 +00:00
MervinPraison 5468e35bc1 cli docs 2025-02-03 07:40:46 +00:00
Mervin Praison b468267a87 Merge pull request #362 from MervinPraison/develop
Develop
2025-02-02 06:45:30 +00:00
MervinPraison 48141bbd9e update readme 2025-02-02 06:45:12 +00:00
MervinPraison b3cdf53d07 adding demo 2025-02-02 06:43:16 +00:00
Mervin Praison aa594ddc32 Merge pull request #361 from MervinPraison/develop
update read me 2
2025-02-02 06:30:57 +00:00
MervinPraison 5f330e8fb2 update read me 2 2025-02-02 06:30:37 +00:00
Mervin Praison ff94e128de Merge pull request #360 from MervinPraison/develop
update read me
2025-02-02 06:28:35 +00:00
MervinPraison 854a016fc5 update read me 2025-02-02 06:28:08 +00:00
Mervin Praison 12e8ed7b77 Merge pull request #359 from MervinPraison/develop
Update CLI Documentation with Latest LLM Model Option
2025-02-01 21:51:34 +00:00
MervinPraison 13c5f5537e Update CLI Documentation with Latest LLM Model Option
- Updated CLI documentation to reflect the latest LLM model option
- Changed example command to use `gpt-4o-mini` instead of `gpt-4-mini`
- Minor documentation refinement for CLI feature
2025-02-01 21:51:20 +00:00
Mervin Praison e7c1614ac8 Merge pull request #358 from MervinPraison/develop
Add CLI Documentation and Enhance CLI Functionality
2025-02-01 00:20:09 +00:00
MervinPraison 7cc6db2a34 Add CLI Documentation and Enhance CLI Functionality
- Added comprehensive CLI documentation in docs/features/cli.mdx
- Enhanced CLI functionality with new command-line options
- Implemented `--llm` flag to specify LLM models for direct prompts
- Updated CLI parsing to support flexible LLM model selection
- Improved direct prompt handling across different AI frameworks
- Bumped package version to 2.0.63
2025-02-01 00:19:44 +00:00
Mervin Praison b869bbc346 Merge pull request #357 from MervinPraison/develop
Enhance CLI with Direct Prompt Handling and Framework Flexibility
2025-02-01 00:01:27 +00:00
MervinPraison 5492be4412 Enhance CLI with Direct Prompt Handling and Framework Flexibility
- Added direct prompt handling in CLI for immediate task execution
- Implemented fallback mechanism to support multiple AI agent frameworks (PraisonAI, CrewAI, AutoGen)
- Updated CLI parsing to handle various input scenarios
- Simplified agent initialization for direct prompts
- Improved error messaging for framework installation
- Bumped package version to 2.0.62
2025-02-01 00:01:12 +00:00
Mervin Praison c2e33ef6a6 Merge pull request #355 from MervinPraison/develop
Add Image Generation AI Agents with Async Support
2025-01-31 17:26:37 +00:00
MervinPraison 5b2e0a9417 Add Image Generation AI Agents with Async Support
- Introduced new ImageAgent class for generating images using AI models
- Added image generation examples in examples/image/ directory
- Created documentation for image generation feature in docs/features/image-generation.mdx
- Updated package versions to 2.0.61
- Implemented synchronous and asynchronous image generation methods
- Added support for different image models and generation configurations
- Enhanced agent framework with specialized image generation capabilities
2025-01-31 17:26:20 +00:00
Mervin Praison 2f6d9ebcc9 Merge pull request #354 from MervinPraison/develop
Update TypeScript Documentation and Examples with Simplified Agent Wo…
2025-01-31 12:04:54 +00:00
MervinPraison 0610a5b3a4 Update TypeScript Documentation and Examples with Simplified Agent Workflows
- Refactored TypeScript documentation in docs/js/typescript.mdx with simplified code examples
- Updated example scripts in src/praisonai-ts/examples/ with concise, emoji-enhanced workflows
- Simplified multi-agent and single-agent example scripts
- Adjusted task-based agent examples to focus on brevity and creativity
- Updated package version to 1.0.15
- Improved logging and initialization of agents
2025-01-31 12:04:39 +00:00
Mervin Praison 7463744e62 Merge pull request #353 from MervinPraison/develop
Add JavaScript and TypeScript Documentation for PraisonAI SDK
2025-01-31 08:30:18 +00:00
MervinPraison c7428b8282 Add JavaScript and TypeScript Documentation for PraisonAI SDK
- Updated README.md with JavaScript code examples and installation instructions
- Added JavaScript documentation to docs/index.mdx, docs/installation.mdx, docs/introduction.mdx, and docs/quickstart.mdx
- Created new documentation pages for JavaScript, Node.js, and TypeScript in docs/js/
- Added example scripts for single and multi-agent workflows in src/praisonai-ts/examples/
- Updated package version to 1.0.14
- Enhanced PraisonAIAgents class to support auto-generated tasks and improved logging
- Simplified agent initialization and task generation
2025-01-31 08:30:01 +00:00
Mervin Praison ff1deb6b97 Merge pull request #352 from MervinPraison/develop
Update PraisonAI TypeScript SDK with Enhanced Logging, Examples, and …
2025-01-31 07:06:13 +00:00
MervinPraison bdbed2667d Update PraisonAI TypeScript SDK with Enhanced Logging, Examples, and Dependencies
- Upgraded package dependencies and versions
- Added new optional dependencies for enhanced logging and CLI experience
- Implemented PrettyLogger for improved console output
- Updated OpenAI service with more robust error handling and streaming
- Added new example scripts for single, multi-agent, and task-based workflows
- Enhanced logging and debugging capabilities
- Improved agent configuration and initialization
- Added CommonJS example scripts for easier integration
2025-01-31 07:05:56 +00:00
Mervin Praison 2810ec879c Merge pull request #351 from MervinPraison/develop
Add Development and Async TypeScript Documentation for PraisonAI Agen…
2025-01-31 05:31:00 +00:00
MervinPraison 04a8c621bb Add Development and Async TypeScript Documentation for PraisonAI Agents Framework
- Added new documentation pages for development setup and async TypeScript agents
- Updated docs/mint.json to include new navigation entries for JavaScript section
- Added development setup instructions and package structure overview
- Created new documentation for TypeScript async agent workflows
- Simplified and standardized example code across documentation pages
- Updated package version to 1.0.11
2025-01-31 05:30:41 +00:00
Mervin Praison 17cbadaf64 Merge pull request #350 from MervinPraison/develop
Update JavaScript and TypeScript Documentation for PraisonAI Agents F…
2025-01-31 04:55:36 +00:00
MervinPraison fbcdf84350 Update JavaScript and TypeScript Documentation for PraisonAI Agents Framework
- Added new documentation pages for JavaScript, Node.js, and TypeScript in docs/js/
- Updated docs/mint.json to include new navigation entries
- Simplified and standardized example code across documentation pages
- Updated package version to 1.0.8
- Refactored example scripts to use imported PraisonAI package
- Improved documentation structure and code examples for single, multi-agent, and task-based workflows
2025-01-31 04:55:23 +00:00
Mervin Praison ab3295caa1 Merge pull request #349 from MervinPraison/develop
Add TypeScript Examples for PraisonAI Agents SDK
2025-01-30 21:25:54 +00:00
MervinPraison 95517f5007 Add TypeScript Examples for PraisonAI Agents SDK
Expand the PraisonAI TypeScript SDK with comprehensive example scripts demonstrating various agent interaction patterns:

- Added single-agent and multi-agent example scripts
- Implemented chat and task-based agent workflows
- Created examples for parallel and sequential agent processing
- Updated package version to 1.0.7
- Enhanced Agent and PraisonAIAgents classes with improved method signatures
- Added examples covering scenarios like script writing, recipe generation, and research tasks
2025-01-30 21:25:31 +00:00
Mervin Praison 3800825b38 Merge pull request #348 from MervinPraison/develop
Add Node.js AI Agents Framework Documentation
2025-01-30 20:41:21 +00:00
MervinPraison f85e16ab87 Add Node.js AI Agents Framework Documentation
Update documentation to include a comprehensive guide for the PraisonAI Node.js framework:
- Added new JS documentation page in docs/js/js.mdx
- Updated docs/mint.json to include JS navigation and sidebar entry
- Removed praisonai-examples directory, consolidating examples into documentation
- Provided installation, usage, and development setup instructions for the framework
2025-01-30 20:41:00 +00:00
Mervin Praison dbdd3d3d9a Merge pull request #347 from MervinPraison/develop
Add PraisonAI TypeScript AI Agents Framework node.js AI Agents Framework
2025-01-30 20:30:25 +00:00
MervinPraison 1cc5dad01f Add PraisonAI TypeScript Examples and SDK Infrastructure
This commit establishes the TypeScript implementation of the PraisonAI Agents SDK, including:

- Created comprehensive example scripts in `praisonai-examples/`
- Implemented core SDK modules in `praisonai-ts/src/`
- Added multi-agent workflow examples (single, multi-agent, task-based)
- Developed base implementations for agents, tasks, tools, and LLM integration
- Configured TypeScript project with comprehensive package setup
- Implemented ArXiv search and download tools as initial tool example
- Added logging and utility modules for enhanced development experience

The commit provides a foundational TypeScript SDK with modular architecture and example scripts demonstrating agent interactions.
2025-01-30 20:27:33 +00:00
Mervin Praison 3797e4fe25 Merge pull request #346 from MervinPraison/develop
Remove Jupyter notebook agent examples from cookbooks/notebooks/yaml/
2025-01-30 07:04:34 +00:00
MervinPraison d840e7d0ef Remove Jupyter notebook agent examples from cookbooks/notebooks/yaml/
This commit removes a collection of Jupyter notebook files containing agent example implementations across various domains, including:

- Research and analysis
- Writing and creative tasks
- Job and recruitment workflows
- Trip planning
- Social media and content generation
- Search and information retrieval

The removal appears to be part of a broader reorganization of the project's example and cookbook materials, streamlining the repository structure.
2025-01-30 07:04:19 +00:00
Mervin Praison 6f9ca636aa Merge pull request #345 from MervinPraison/develop
Remove multiple Jupyter notebook agent examples from cookbooks
2025-01-30 07:03:19 +00:00
MervinPraison f254d9e290 Remove multiple Jupyter notebook agent examples from cookbooks
This commit removes a large collection of Jupyter notebook files in the `cookbooks/notebooks/` directory that contained various agent example implementations. These notebooks covered a wide range of use cases including:

- Research and analysis agents
- Writing and creative agents
- Job and recruitment agents
- Trip planning agents
- Social media and content generation agents
- Search and information retrieval agents

The removal appears to be part of a broader reorganization of the project's example and cookbook materials.
2025-01-30 07:03:06 +00:00
Mervin Praison 2e95279cd5 Merge pull request #344 from MervinPraison/develop
adding cookbooks
2025-01-30 07:02:19 +00:00
MervinPraison c218ad62ce adding cookbooks 2025-01-30 07:01:39 +00:00
Mervin Praison d10849085d Merge pull request #343 from MervinPraison/develop
adding js sdk
2025-01-30 06:55:13 +00:00
MervinPraison 9594426fc2 Add PraisonAI Agents SDK and Example Scripts
- Initialized PraisonAI Agents SDK project structure in `src/praisonai-agents/`
- Added comprehensive set of example scripts demonstrating agent capabilities
- Included core SDK modules for agents, tasks, tools, knowledge, and LLM integration
- Implemented various agent workflows including:
  - Chain of Thought reasoning
  - Web search
  - Code analysis
  - Memory management
  - Multi-agent coordination
- Created configuration files for development environment setup
- Added sample data and test files for agent interactions

The commit establishes a foundational SDK with diverse agent interaction examples and modular architecture.
2025-01-30 06:54:57 +00:00
MervinPraison 1c6fc71a06 adding js sdk 2025-01-30 06:52:54 +00:00
Mervin Praison d7289acc1d Merge pull request #340 from MervinPraison/develop
Add Hugging Face token export instruction to generate-reasoning docum…
2025-01-29 06:28:13 +00:00
MervinPraison 54a748b4c7 Add Hugging Face token export instruction to generate-reasoning documentation
- Updated docs/features/generate-reasoning.mdx to include HuggingFace token export step
- Expanded environment variable setup instructions for Hugging Face integration
2025-01-29 06:27:49 +00:00
Mervin Praison 9f62e9201a Merge pull request #339 from MervinPraison/develop
2.0.60
2025-01-29 05:59:25 +00:00
MervinPraison 1b69360d9f Bump PraisonAI version to 2.0.60 and update dependencies
- Updated version to 2.0.60 in Homebrew formula, pyproject.toml, and Docker files
- Upgraded praisonaiagents dependency from 0.0.56 to 0.0.60
- Added new documentation for generating reasoning data
- Included example script for chain-of-thought data generation
- Enhanced workflow task management and logging in process modules

The changes improve the framework's version management, documentation, and provide new tools for synthetic reasoning data generation.
2025-01-29 05:58:58 +00:00
MervinPraison 9bdc6545ad Enhance Workflow Task Management with Workflow Finished Flag and Improved Routing
- Added `workflow_finished` flag to `Process` class to enable early workflow termination
- Implemented more robust task routing logic in `process.py` for decision and loop tasks
- Updated task reset mechanism to respect `rerun` parameter
- Improved context clearing and task status management
- Enhanced logging for workflow progression and task transitions

The changes provide more flexible and controlled workflow execution, with better handling of task conditions and early termination scenarios.
2025-01-28 16:40:22 +00:00
MervinPraison 06cd909367 Add max_iter parameter and enhanced workflow task management with fallback mechanism
- Updated `orchestrator-workers.py` to include `max_iter=10` parameter in workflow initialization
- Enhanced `process.py` with a new `_find_next_not_started_task()` method to provide fallback task selection
- Implemented comprehensive logging for workflow cycles, task status, and iteration tracking
- Added retry counter and fallback mechanism to handle scenarios with incomplete or stalled tasks
- Improved workflow termination logic with detailed final summary logging

The changes improve workflow reliability, prevent potential infinite loops, and provide more robust task management in complex multi-agent scenarios.
2025-01-28 11:26:32 +00:00
MervinPraison 67aeece7fc Bump praisonaiagents package version to 0.0.58
- Updated version in `pyproject.toml` and `uv.lock`
- Incremented package version for continued development and improvements
2025-01-27 19:19:40 +00:00
MervinPraison ef67d0753c Enhance Workflow Task Management with Detailed Logging and Loop Task Handling
- Updated `.cursorrules` with comprehensive technical overview of workflow execution challenges
- Refactored `cot-agents.py` to:
  - Add Pydantic model for structured output
  - Improve task description and condition handling
  - Add output validation for chain of thought generation
- Enhanced `process.py` with:
  - Extensive debug logging for task execution
  - Improved loop task and subtask management
  - More detailed logging of task status and progression

The changes improve workflow reliability, provide deeper insights into task execution, and prevent infinite loops in complex task workflows.
2025-01-27 19:18:49 +00:00
MervinPraison f374f9f791 Enhance COT Agent Workflow with Improved Task Management and Logging
- Refactored `cot-agents.py` to include:
  - New `write_csv` and `count_questions` functions
  - Added `TotalQuestionsEvaluator` agent for tracking question count
  - Improved task workflow with decision and loop task types
- Updated `process.py` to support:
  - Enhanced logging for task execution
  - Better handling of loop and decision tasks
  - Improved subtask creation and management
- Modified `csv_tools.py` to support more flexible CSV writing with string input
- Implemented more robust task progression and status tracking

The changes improve the flexibility, logging, and task management of the Chain of Thought agent workflow.
2025-01-27 13:59:59 +00:00
MervinPraison 492fb29af9 Enhance Chain of Thought (COT) agent workflow with batch processing and Hugging Face integration
- Added `cot-agents-batch.py` to support batch processing of Q&A pairs
- Updated `cot-agents.py` with a more comprehensive workflow including:
  - Question generation
  - Chain of Thought solution generation
  - Hugging Face dataset upload
- Refined `generatecot.py` with improvements to solution generation:
  - Reduced max attempts
  - Adjusted scoring thresholds
  - Added direct QA pair tracking

The changes improve the flexibility and automation of Chain of Thought solution generation and dataset management.
2025-01-27 02:52:14 +00:00
MervinPraison cd56ebd5cf Add Chain of Thought (COT) generation tools and update project structure
- Introduced comprehensive `generatecot.py` in `praisonaiagents/tools/train/data/` with advanced Chain of Thought solution generation capabilities
- Added multiple COT-related tools and methods:
  - Solution generation and improvement
  - Answer verification
  - Error detection and correction
  - Export to various formats (JSON, CSV, Alpaca)
  - HuggingFace dataset upload support
- Updated tool mappings in `__init__.py` to include COT-related tools
- Moved existing `generatecot.py` from `train/data/` to `tools/train/data/`
- Bumped project version to 0.0.57 in relevant files

The changes enhance the framework's capabilities for generating and managing step-by-step problem-solving solutions with AI-powered reasoning.
2025-01-26 07:22:32 +00:00
MervinPraison 08e99f6ef7 Enhance GenerateCOT with dictionary-based solution generation and Alpaca format export
- Added new methods to generate solutions in dictionary format:
  - `get_solution_dict()` for step-by-step problem solving
  - `improve_solution_dict()` to refine existing solutions
  - `start_dict()` to generate and validate solutions
- Implemented `export_alpaca_format()` to convert solutions to Alpaca training format
- Updated type hints and added example usage for new methods
- Extended the script with additional QA data processing and export demonstration

The changes improve the flexibility and usability of the GenerateCOT class for solution generation and data preparation.
2025-01-25 08:22:08 +00:00
MervinPraison 670d653ae9 Add GenerateCOT class for step-by-step solution generation and verification
- Created a new Python script `generatecot.py` in the train/data directory
- Implemented a comprehensive solution generation class with features like:
  - Step-by-step problem solving
  - Answer verification
  - Solution improvement
  - Error detection and correction
- Added support for loading and saving solutions with JSON
- Included an example usage demonstrating the class functionality

The GenerateCOT (Chain of Thought) class provides a robust mechanism for generating and refining solutions to various problems using AI-powered reasoning.
2025-01-25 07:47:20 +00:00
Mervin Praison faa014b8b0 Merge pull request #333 from MervinPraison/develop
2.0.59
2025-01-24 17:17:53 +00:00
MervinPraison 6d454d0c6e Update PraisonAI to version 2.0.59 and enhance dependencies
- Bumped PraisonAI version from 2.0.58 to 2.0.59 in `Dockerfile`, `pyproject.toml`, and `uv.lock` to reflect the latest updates.
- Updated the `praisonaiagents` dependency version from `0.0.53` to `0.0.56` across relevant files for improved functionality.
- Modified agent task descriptions in `repetitive-agents.py` to clarify expected outputs.
- Enhanced the `process.py` file to improve task handling and expected output management.

These changes aim to refine the PraisonAI framework's capabilities and ensure compatibility with the latest dependencies.
2025-01-24 17:17:32 +00:00
MervinPraison 0ec3fe3510 Add new agent scripts and update version to 0.0.55
- Introduced three new Python scripts: `deepseek-reasoning-output-tokens.py`, `llm-deepseek-reasoning-steps.py`, and `llm-langchain-toolcall.py` to enhance reasoning capabilities and multi-source information retrieval.
- Updated `pyproject.toml` and `uv.lock` to reflect the new version 0.0.55.
- Enhanced `wikipedia-agent.py` to utilize the new `gpt-4o-mini` model for improved performance.
- Improved `agent.py` to support tool calls in chat completions, refining the overall functionality of the agent framework.

These changes aim to expand the capabilities of the PraisonAI framework by integrating new reasoning features and improving user experience with updated versioning.
2025-01-24 13:04:34 +00:00
MervinPraison 707888cdf9 Remove deprecated agent scripts and update version to 0.0.54
- Deleted `any-llm-agents.py` and `any-llm-agents-advanced.py` scripts to streamline the agent framework.
- Updated `pyproject.toml` and `uv.lock` to reflect the new version 0.0.54.
- Enhanced `agent.py` and `llm.py` to improve handling of reasoning steps by ensuring `reasoning_steps` is properly managed in API calls.

These changes aim to simplify the agent framework and improve the overall functionality of the PraisonAI system.
2025-01-24 10:35:42 +00:00
Mervin Praison 42051630bc Merge pull request #331 from MervinPraison/develop
Develop
2025-01-23 17:19:08 +00:00
MervinPraison bfcccb6355 Update PraisonAI to version 2.0.58 and enhance reasoning capabilities
- Bumped PraisonAI version from 2.0.57 to 2.0.58 in `Dockerfile`, `pyproject.toml`, and `uv.lock` to reflect the latest updates.
- Updated the `praisonaiagents` dependency version from `0.0.50` to `0.0.53` across relevant files for improved functionality.
- Enhanced reasoning features by modifying agent initialization parameters to use `reasoning_steps` instead of `show_reasoning`, improving clarity in agent behavior.
- Introduced a new script `deepseek-reasoning-multi-agents.py` for multi-agent reasoning tasks, showcasing the integration of reasoning agents.
- Added documentation for new reasoning features, including a detailed guide on creating reasoning extract agents.

These changes aim to refine the reasoning capabilities and improve the overall user experience within the PraisonAI framework.
2025-01-23 17:18:54 +00:00
MervinPraison e329afc394 Refactor reasoning capabilities and update version to 0.0.52
- Removed the `any-llm-think.py` script to streamline the agent framework.
- Enhanced `deepseek-reasoning-agents.py` to include reasoning display options and updated the method for starting agents.
- Updated `pyproject.toml` and `uv.lock` to reflect the new version 0.0.52.
- Improved `agent.py` and `llm.py` to support reasoning content in both synchronous and asynchronous calls, enhancing the overall functionality of the agent framework.

These changes aim to refine the reasoning features and improve the user experience within the PraisonAI framework.
2025-01-23 13:52:58 +00:00
MervinPraison 9417cc6457 Add new reasoning agents and update version to 0.0.51
- Introduced three new Python scripts: `any-llm-think.py`, `deepseek-reasoning-agents.py`, and `deepseek-think.py` for enhanced reasoning capabilities using the `deepseek-reasoner` model.
- Updated `pyproject.toml` and `uv.lock` to reflect the new version 0.0.51.
- Enhanced the `agent.py` file with new data classes and methods to support reasoning content in chat completions, improving the overall functionality of the agent framework.

These changes aim to expand the capabilities of the PraisonAI framework by integrating reasoning features and improving the user experience with updated versioning.
2025-01-23 10:52:15 +00:00
Mervin Praison 10a3d279ae Merge pull request #329 from MervinPraison/develop
Update index.mdx description to enhance clarity and detail
2025-01-23 06:40:49 +00:00
MervinPraison 2a916208e1 Update index.mdx description to enhance clarity and detail
- Revised the description of PraisonAI to emphasize its capabilities as a production-ready Multi-AI Agents framework with self-reflection.
- Highlighted the integration of PraisonAI Agents, AutoGen, and CrewAI as a low-code solution for automating tasks and solving complex challenges.
- Focused on the framework's strengths in simplicity, customization, and effective human-agent collaboration.

These changes aim to provide users with a clearer understanding of PraisonAI's functionalities and benefits.
2025-01-23 06:40:23 +00:00
Mervin Praison bcd0bbbd24 Merge pull request #328 from MervinPraison/develop
Refactor documentation for agent setup and usage
2025-01-23 06:38:06 +00:00
MervinPraison 5701a40f11 Refactor documentation for agent setup and usage
- Updated the introduction.mdx file to streamline the steps for installing the PraisonAI package and configuring the environment.
- Revised agent creation examples to simplify the process for both single and multiple agents, enhancing clarity and usability.
- Added a new section for creating an `agents.yaml` configuration file for no-code users, including automatic generation instructions.
- Improved the overall structure and readability of the documentation to facilitate a better user experience.

These changes aim to provide clearer guidance for users in setting up and utilizing the PraisonAI framework effectively.
2025-01-23 06:37:49 +00:00
Mervin Praison 3ffac395bb Merge pull request #327 from MervinPraison/develop
Update README and documentation with new video tutorials
2025-01-23 06:34:56 +00:00
MervinPraison 37119aa3ac Update README and documentation with new video tutorials
- Removed the License section from README.md to streamline content.
- Added a comprehensive list of video tutorials to docs/index.mdx, covering various AI agent functionalities such as self-reflection, reasoning, and multimodal capabilities.
- Enhanced the documentation's educational resources, providing users with visual aids to better understand the Praison AI framework.

These changes aim to improve user engagement and learning through accessible video content.
2025-01-23 06:34:36 +00:00
Mervin Praison 8b2d324d3b Merge pull request #326 from MervinPraison/develop
Enhance README with new AI agent video resources
2025-01-23 06:30:01 +00:00
MervinPraison 6d0b29e60d Enhance README with new AI agent video resources
- Added multiple new video links to the README.md, showcasing various AI agent functionalities including self-reflection, reasoning, multimodal capabilities, and more.
- Improved the documentation's educational value by providing visual resources for users to better understand the Praison AI framework.

These changes aim to enrich the user experience by offering accessible learning materials related to AI agents.
2025-01-23 06:29:44 +00:00
Mervin Praison 583cbc5efa Merge pull request #325 from MervinPraison/develop
Update documentation and examples for agent initialization and usage
2025-01-23 06:21:43 +00:00
MervinPraison 90dd84a152 Update documentation and examples for agent initialization and usage
- Revised the README.md to reflect the updated method for starting agents, changing `agent.chat` to `agent.start` for clarity and accuracy.
- Added a new section in the README.md for creating an `agents.yaml` file, enhancing the setup instructions for users.
- Updated the installation instructions in `docs/index.mdx` to clarify package names and improve the overall structure of the documentation.
- Streamlined code examples in `docs/concepts/agents.mdx` to focus on single and multiple agent initialization, ensuring users have clear and concise guidance.

These changes improve the clarity and usability of the documentation, making it easier for users to understand and implement the PraisonAI framework.
2025-01-23 06:21:25 +00:00
1052 changed files with 87171 additions and 52887 deletions

No files matched your search

-1885
View File
File diff suppressed because it is too large. Load diff
-6
View File
@@ -1,6 +0,0 @@
OPENAI_MODEL_NAME="gpt-4o"
OPENAI_API_KEY="Enter your API key"
OPENAI_API_BASE="https://api.openai.com/v1"
CHAINLIT_USERNAME=admin
CHAINLIT_USERNAME=admin
CHAINLIT_AUTH_SECRET="chainlit create-secret to create"
-10
View File
@@ -1,10 +0,0 @@
{
"extends": ["plugin:mdx/recommended"],
// optional, if you want to lint code blocks at the same time
"settings": {
"mdx/code-blocks": true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
"mdx/language-mapper": {}
}
}
@@ -0,0 +1,9 @@
FROM node:20-alpine
RUN npm install -g @anthropic-ai/claude-code
WORKDIR /app
COPY entrypoint.sh .
RUN chmod +x entrypoint.sh
ENTRYPOINT ["/app/entrypoint.sh"]
@@ -0,0 +1,20 @@
name: "Claude Code Action"
description: "Custom Claude Code runner for PraisonAI"
inputs:
anthropic_api_key:
required: true
description: "Anthropic API key"
github_token:
required: true
description: "GitHub token for repo access"
runs:
using: "docker"
image: "ghcr.io/mervinpraison/praisonai-claudecode:latest"
env:
ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }}
GITHUB_TOKEN: ${{ inputs.github_token }}
args:
- "--anthropic-api-key=${{ inputs.anthropic_api_key }}"
- "--github-token=${{ inputs.github_token }}"
@@ -0,0 +1,21 @@
#!/bin/sh
set -e
echo "Running Claude Code in CI mode..."
# Extract GitHub context and create a smart prompt
PROMPT="Analyse the GitHub issue or PR context and generate a smart response based on the repository context."
# Set environment variables from arguments
export ANTHROPIC_API_KEY="${1#--anthropic-api-key=}"
export GITHUB_TOKEN="${2#--github-token=}"
# Verify environment variables
if [ -z "$ANTHROPIC_API_KEY" ] || [ -z "$GITHUB_TOKEN" ]; then
echo "Error: Required environment variables are not set"
exit 1
fi
# Run Claude with the prompt
claude -p "$PROMPT"
+117
View File
@@ -0,0 +1,117 @@
name: "Claude Code Action"
description: "Run Claude Code in GitHub Actions workflows"
inputs:
github_token:
description: "GitHub token with repo and issues permissions"
required: true
anthropic_api_key:
description: "Anthropic API key"
required: true
prompt:
description: "The prompt to send to Claude Code"
required: false
default: ""
prompt_file:
description: "Path to a file containing the prompt to send to Claude Code"
required: false
default: ""
allowed_tools:
description: "Comma-separated list of allowed tools for Claude Code to use"
required: false
default: ""
output_file:
description: "File to save Claude Code output to (optional)"
required: false
default: ""
timeout_minutes:
description: "Timeout in minutes for Claude Code execution"
required: false
default: "10"
install_github_mcp:
description: "Whether to install the GitHub MCP server"
required: false
default: "false"
runs:
using: "composite"
steps:
- name: Install Claude Code
shell: bash
run: npm install -g @anthropic-ai/claude-code
- name: Install GitHub MCP Server
if: inputs.install_github_mcp == 'true'
shell: bash
run: |
claude mcp add-json github '{
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:sha-ff3036d"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${{ inputs.GITHUB_TOKEN }}"
}
}'
- name: Prepare Prompt File
shell: bash
id: prepare_prompt
run: |
if [ -z "${{ inputs.prompt }}" ] && [ -z "${{ inputs.prompt_file }}" ]; then
echo "::error::Neither 'prompt' nor 'prompt_file' was provided. At least one is required."
exit 1
fi
if [ ! -z "${{ inputs.prompt_file }}" ]; then
if [ ! -f "${{ inputs.prompt_file }}" ]; then
echo "::error::Prompt file '${{ inputs.prompt_file }}' does not exist."
exit 1
fi
PROMPT_PATH="${{ inputs.prompt_file }}"
else
mkdir -p /tmp/claude-action
PROMPT_PATH="/tmp/claude-action/prompt.txt"
echo "${{ inputs.prompt }}" > "$PROMPT_PATH"
fi
if [ ! -s "$PROMPT_PATH" ]; then
echo "::error::Prompt is empty. Please provide a non-empty prompt."
exit 1
fi
echo "PROMPT_PATH=$PROMPT_PATH" >> $GITHUB_ENV
- name: Run Claude Code
shell: bash
id: run_claude
run: |
timeout_seconds=$((${{ inputs.timeout_minutes }} * 60))
if [ -z "${{ inputs.output_file }}" ]; then
timeout $timeout_seconds claude \
-p \
--verbose \
--output-format stream-json \
"$(cat ${{ env.PROMPT_PATH }})" \
${{ inputs.allowed_tools != '' && format('--allowedTools "{0}"', inputs.allowed_tools) || '' }}
else
timeout $timeout_seconds claude \
-p \
--verbose \
--output-format stream-json \
"$(cat ${{ env.PROMPT_PATH }})" \
${{ inputs.allowed_tools != '' && format('--allowedTools "{0}"', inputs.allowed_tools) || '' }} | tee output.txt
jq -s '.' output.txt > output.json
jq -r '.[-1].result' output.json > "${{ inputs.output_file }}"
echo "Complete output saved to output.json, final response saved to ${{ inputs.output_file }}"
fi
env:
ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }}
GITHUB_TOKEN: ${{ inputs.github_token }}
+39
View File
@@ -0,0 +1,39 @@
name: Build Claude Code Image
on:
workflow_dispatch:
inputs:
version:
description: 'Image version tag'
required: true
default: 'latest'
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./.github/actions/claude-code-action
push: true
tags: ghcr.io/mervinpraison/praisonai-claudecode:${{ inputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: false
+82
View File
@@ -0,0 +1,82 @@
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
packages: read
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Debug Environment
run: |
echo "=== Environment Debug ==="
echo "GITHUB_ACTOR: $GITHUB_ACTOR"
echo "GITHUB_REPOSITORY: $GITHUB_REPOSITORY"
echo "GITHUB_REPOSITORY_OWNER: $GITHUB_REPOSITORY_OWNER"
echo "GITHUB_TOKEN exists: $([ -n "$GITHUB_TOKEN" ] && echo "yes" || echo "no")"
echo "GITHUB_TOKEN length: ${#GITHUB_TOKEN}"
- name: Check Package Visibility
run: |
echo "=== Checking Package Visibility ==="
curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/users/MervinPraison/packages/container/praisonai-claudecode" \
|| echo "Package API call failed"
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Test Docker Authentication
run: |
echo "=== Testing Docker Authentication ==="
echo "Checking ~/.docker/config.json"
cat ~/.docker/config.json | jq '.' || echo "No docker config found"
echo "=== Testing Registry Access ==="
curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
"https://ghcr.io/v2/" || echo "Registry access failed"
- name: Test Docker Pull
run: |
echo "=== Testing Docker Pull ==="
echo "Attempting to pull image: ghcr.io/mervinpraison/praisonai-claudecode:latest"
docker pull ghcr.io/mervinpraison/praisonai-claudecode:latest || echo "Pull failed with exit code: $?"
echo "=== Checking Docker Images ==="
docker images | grep praisonai-claudecode || echo "No images found"
- name: Run Claude Code
id: claude
uses: ./.github/actions/claude-code-action
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
+60
View File
@@ -0,0 +1,60 @@
name: Run tests and upload coverage
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
test:
name: Run tests and collect coverage
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-cov pytest-asyncio
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
echo "LOGLEVEL=DEBUG" >> $GITHUB_ENV
echo "PYTHONPATH=${{ github.workspace }}/src/praisonai-agents:$PYTHONPATH" >> $GITHUB_ENV
- name: Run tests
run: |
cd src/praisonai
pytest --cov=praisonai --cov-branch --cov-report=xml tests/unit/
- name: Upload results to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: src/praisonai/coverage.xml
flags: unit-tests
name: unit-tests-coverage
fail_ci_if_error: false
verbose: true
+33 -5
View File
@@ -19,22 +19,50 @@ jobs:
python-version: ["3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
echo "LOGLEVEL=DEBUG" >> $GITHUB_ENV
- name: Install dependencies
run: |
cd src/praisonai
python -m pip install --upgrade pip
python -m pip install flake8 pytest
python -m pip install ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
python -m pip install duckduckgo_search
python -m pip install pytest-asyncio pytest-cov
# Install knowledge dependencies from praisonai-agents
python -m pip install "praisonaiagents[knowledge]"
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Debug API Key Status
run: |
echo "🔍 Checking API key availability..."
if [ -n "${{ secrets.OPENAI_API_KEY }}" ]; then
echo "✅ GitHub secret OPENAI_API_KEY is available"
echo "🔑 API key starts with: $(echo "$OPENAI_API_KEY" | cut -c1-7)..."
else
echo "⚠️ GitHub secret OPENAI_API_KEY is NOT set - using fallback"
echo "🔑 Using fallback key: sk-test-key..."
fi
echo "🌐 API Base: $OPENAI_API_BASE"
echo "🤖 Model: $OPENAI_MODEL_NAME"
# - name: Lint with flake8
# run: |
# # stop the build if there are Python syntax errors or undefined names
# flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
# flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
# - name: Test with pytest
# run: |
# pytest
- name: Test with pytest
run: |
cd src/praisonai && python tests/test_runner.py --pattern fast
+4 -3
View File
@@ -21,9 +21,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
@@ -31,9 +31,10 @@ jobs:
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
run: python -m build src/praisonai
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
packages_dir: src/praisonai/dist/
+2 -2
View File
@@ -64,7 +64,7 @@ jobs:
git reset --hard ${{ steps.get_commit.outputs.commit_hash }}
- name: Setup Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
@@ -422,7 +422,7 @@ jobs:
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: praisonai-output-${{ matrix.os }}-${{ matrix.framework }}
path: test_output/
+190
View File
@@ -0,0 +1,190 @@
name: Comprehensive Test Suite
on:
workflow_dispatch: # Allow manual triggering
inputs:
test_type:
description: 'Type of tests to run'
required: true
default: 'all'
type: choice
options:
- all
- unit
- integration
- fast
- performance
- frameworks
- autogen
- crewai
release:
types: [published, prereleased]
schedule:
# Run comprehensive tests weekly on Sundays at 3 AM UTC
- cron: '0 3 * * 0'
jobs:
comprehensive-test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov pytest-benchmark
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
- name: Run Comprehensive Test Suite
run: |
# Determine test type from input or default to 'all'
TEST_TYPE="${{ github.event.inputs.test_type || 'all' }}"
echo "🧪 Running comprehensive test suite (type: $TEST_TYPE)"
case $TEST_TYPE in
"unit")
cd src/praisonai && python -m pytest tests/unit/ -v --tb=short --disable-warnings --cov=praisonai --cov-report=xml --cov-branch
;;
"integration")
cd src/praisonai && python -m pytest tests/integration/ -v --tb=short --disable-warnings --cov=praisonai --cov-report=xml --cov-branch
;;
"fast")
cd src/praisonai && python tests/test_runner.py --pattern fast
;;
"performance")
cd src/praisonai && python tests/test_runner.py --pattern "performance"
;;
"frameworks")
cd src/praisonai && python tests/test_runner.py --pattern frameworks
;;
"autogen")
cd src/praisonai && python tests/test_runner.py --pattern autogen
;;
"crewai")
cd src/praisonai && python tests/test_runner.py --pattern crewai
;;
"all"|*)
cd src/praisonai && python tests/test_runner.py --pattern all
;;
esac
- name: Generate Comprehensive Test Report
if: always()
run: |
echo "# 📋 Comprehensive Test Report" > comprehensive_report.md
echo "" >> comprehensive_report.md
echo "**Python Version:** ${{ matrix.python-version }}" >> comprehensive_report.md
echo "**Test Type:** ${{ github.event.inputs.test_type || 'all' }}" >> comprehensive_report.md
echo "**Trigger:** ${{ github.event_name }}" >> comprehensive_report.md
echo "**Date:** $(date -u)" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "## 🧪 Test Categories Covered:" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "### Unit Tests:" >> comprehensive_report.md
echo "- ✅ Core agent functionality" >> comprehensive_report.md
echo "- ✅ Async operations" >> comprehensive_report.md
echo "- ✅ Tool integrations" >> comprehensive_report.md
echo "- ✅ UI components" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "### Integration Tests:" >> comprehensive_report.md
echo "- ✅ MCP (Model Context Protocol)" >> comprehensive_report.md
echo "- ✅ RAG (Retrieval Augmented Generation)" >> comprehensive_report.md
echo "- ✅ Base URL API mapping" >> comprehensive_report.md
echo "- ✅ Multi-agent workflows" >> comprehensive_report.md
echo "- ✅ AutoGen framework integration" >> comprehensive_report.md
echo "- ✅ CrewAI framework integration" >> comprehensive_report.md
echo "- 💬 LLM integrations (OpenAI, Anthropic, etc.)" >> comprehensive_report.md
echo "- 🖥️ UI frameworks (Gradio, Streamlit)" >> comprehensive_report.md
echo "- 📊 Memory and persistence" >> comprehensive_report.md
echo "- 🌐 Multi-modal capabilities" >> comprehensive_report.md
echo "- ✅ AutoGen framework integration" >> comprehensive_report.md
echo "- ✅ CrewAI framework integration" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "### Key Features Tested:" >> comprehensive_report.md
echo "- 🤖 Agent creation and configuration" >> comprehensive_report.md
echo "- 📋 Task management and execution" >> comprehensive_report.md
echo "- 🔄 Sync/async workflows" >> comprehensive_report.md
echo "- 🛠️ Custom tools and error handling" >> comprehensive_report.md
echo "- 🧠 Knowledge bases and RAG" >> comprehensive_report.md
echo "- 🔌 MCP server connections" >> comprehensive_report.md
echo "- 💬 LLM integrations (OpenAI, Anthropic, etc.)" >> comprehensive_report.md
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: src/praisonai/coverage.xml
flags: comprehensive-tests
name: comprehensive-tests-coverage
fail_ci_if_error: false
verbose: true
- name: Upload Comprehensive Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: comprehensive-test-results-python-${{ matrix.python-version }}
path: |
comprehensive_report.md
src/praisonai/htmlcov/
src/praisonai/coverage.xml
src/praisonai/.coverage
retention-days: 30
test-matrix-summary:
runs-on: ubuntu-latest
needs: comprehensive-test
if: always()
steps:
- name: Generate Matrix Summary
run: |
echo "# 🎯 Test Matrix Summary" > matrix_summary.md
echo "" >> matrix_summary.md
echo "## Python Version Results:" >> matrix_summary.md
echo "- Python 3.10: ${{ needs.comprehensive-test.result }}" >> matrix_summary.md
echo "- Python 3.11: ${{ needs.comprehensive-test.result }}" >> matrix_summary.md
echo "" >> matrix_summary.md
echo "## Overall Status:" >> matrix_summary.md
if [ "${{ needs.comprehensive-test.result }}" == "success" ]; then
echo "✅ **All tests passed across all Python versions!**" >> matrix_summary.md
else
echo "❌ **Some tests failed. Check individual job logs for details.**" >> matrix_summary.md
fi
- name: Upload Matrix Summary
uses: actions/upload-artifact@v4
with:
name: test-matrix-summary
path: matrix_summary.md
retention-days: 30
+286
View File
@@ -0,0 +1,286 @@
name: Core Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
test-core:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.11]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
echo "LOGLEVEL=DEBUG" >> $GITHUB_ENV
echo "PYTHONPATH=${{ github.workspace }}/src/praisonai-agents:$PYTHONPATH" >> $GITHUB_ENV
# Also export to current shell session for immediate availability
export OPENAI_API_KEY="${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}"
export OPENAI_API_BASE="${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}"
export OPENAI_MODEL_NAME="${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}"
export LOGLEVEL=DEBUG
# Verify immediate availability
echo "🔧 Immediate verification in same step:"
echo " OPENAI_API_KEY length in current session: ${#OPENAI_API_KEY}"
echo " OPENAI_API_KEY starts with sk-: $(echo "$OPENAI_API_KEY" | grep -q '^sk-' && echo 'YES' || echo 'NO')"
- name: Debug API Key Status
run: |
echo "🔍 Checking API key availability..."
if [ -n "${{ secrets.OPENAI_API_KEY }}" ]; then
echo "✅ GitHub secret OPENAI_API_KEY is available"
echo "🔑 API key starts with: $(echo "$OPENAI_API_KEY" | cut -c1-7)..."
else
echo "⚠️ GitHub secret OPENAI_API_KEY is NOT set - using fallback"
echo "🔑 Using fallback key: sk-test-key..."
fi
echo "🌐 API Base: $OPENAI_API_BASE"
echo "🤖 Model: $OPENAI_MODEL_NAME"
echo "🐛 Log Level: $LOGLEVEL"
echo "📊 Environment Check:"
echo " - OPENAI_API_KEY length: ${#OPENAI_API_KEY}"
echo " - OPENAI_API_BASE: $OPENAI_API_BASE"
echo " - OPENAI_MODEL_NAME: $OPENAI_MODEL_NAME"
echo " - LOGLEVEL: $LOGLEVEL"
echo "🔍 Is API key actually set?"
echo " - API key starts with sk-: $(echo "$OPENAI_API_KEY" | grep -q '^sk-' && echo 'YES' || echo 'NO')"
echo " - API key is not test key: $([ "$OPENAI_API_KEY" != 'sk-test-key-for-github-actions-testing-only-not-real' ] && echo 'YES' || echo 'NO')"
- name: Debug Environment Variables Raw
run: |
echo "🔧 Raw environment variable check:"
echo "OPENAI_API_KEY set: $(if [ -n "$OPENAI_API_KEY" ]; then echo 'YES'; else echo 'NO'; fi)"
echo "OPENAI_API_KEY length: ${#OPENAI_API_KEY}"
echo "OPENAI_API_KEY first 10 chars: ${OPENAI_API_KEY:0:10}"
echo "OPENAI_API_KEY last 5 chars: ${OPENAI_API_KEY: -5}"
printenv | grep OPENAI || echo "No OPENAI env vars found"
- name: Debug Python Environment Variables
run: |
python -c "
import os
print('🐍 Python Environment Variable Check:')
api_key = os.environ.get('OPENAI_API_KEY', 'NOT_SET')
if api_key != 'NOT_SET':
print(f' ✅ OPENAI_API_KEY: {api_key[:7]}... (length: {len(api_key)})')
else:
print(' ❌ OPENAI_API_KEY: NOT_SET')
print(f' 🌐 OPENAI_API_BASE: {os.environ.get(\"OPENAI_API_BASE\", \"NOT_SET\")}')
print(f' 🤖 OPENAI_MODEL_NAME: {os.environ.get(\"OPENAI_MODEL_NAME\", \"NOT_SET\")}')
print(f' 📋 All OPENAI env vars:')
for key, value in os.environ.items():
if key.startswith('OPENAI'):
print(f' {key}: {value[:10] if len(value) > 10 else value}...')
"
- name: Validate API Key
run: |
echo "🔑 Testing API key validity with minimal OpenAI call..."
python -c "
import os
try:
from openai import OpenAI
client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
response = client.models.list()
print('✅ API Key is VALID - OpenAI responded successfully')
print(f'📊 Available models: {len(list(response.data))} models found')
except Exception as e:
print(f'❌ API Key is INVALID - Error: {e}')
print('🔍 This explains why all API-dependent tests are failing')
print('💡 The GitHub secret OPENAI_API_KEY needs to be updated with a valid key')
"
continue-on-error: true
- name: Debug PraisonAI API Key Usage
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}
OPENAI_API_BASE: ${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}
OPENAI_MODEL_NAME: ${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}
LOGLEVEL: DEBUG
run: |
echo "🔍 Testing PraisonAI API key usage directly..."
cd src/praisonai
python -c "
import os
import sys
sys.path.insert(0, '.')
# Attempt to import SecretStr, otherwise use a dummy class
try:
from pydantic.types import SecretStr
except ImportError:
class SecretStr: # Dummy class if pydantic is not available in this minimal context
def __init__(self, value): self._value = value
def get_secret_value(self): return self._value
def get_key_display_value(key_value):
if isinstance(key_value, SecretStr):
return key_value.get_secret_value()[:10] if key_value.get_secret_value() else 'EMPTY_SECRET'
elif isinstance(key_value, str):
return key_value[:10] if key_value != 'nokey' and key_value != 'NOT_SET' else key_value
return 'INVALID_TYPE'
print('🔧 Direct PraisonAI API Key Check:')
env_api_key = os.environ.get(\\"OPENAI_API_KEY\\", \\"NOT_SET\\")
print(f'Environment OPENAI_API_KEY: {get_key_display_value(env_api_key)}...')
from praisonai import PraisonAI
praisonai = PraisonAI()
print(f'PraisonAI config_list: {praisonai.config_list}')
api_key_from_config = praisonai.config_list[0].get('api_key', 'NOT_SET')
print(f'API key from PraisonAI config: {get_key_display_value(api_key_from_config)}...')
from praisonai.inc.models import PraisonAIModel
print('\\\\n🧪 Testing PraisonAIModel with explicit API key (CrewAI method):')
model_with_explicit_key = PraisonAIModel(
model='openai/gpt-4o-mini',
base_url=praisonai.config_list[0].get('base_url'),
api_key=api_key_from_config # This will be a string from praisonai.config_list
)
print(f' Model: {model_with_explicit_key.model}')
print(f' Model name: {model_with_explicit_key.model_name}')
print(f' API key var: {model_with_explicit_key.api_key_var}')
# model_with_explicit_key.api_key is now a string, or 'nokey'
print(f' API key (explicitly passed to PraisonAIModel): {get_key_display_value(model_with_explicit_key.api_key)}...')
print(f' Base URL: {model_with_explicit_key.base_url}')
try:
llm_instance = model_with_explicit_key.get_model()
print(f' ✅ LLM instance created successfully: {type(llm_instance).__name__}')
# langchain_openai.ChatOpenAI stores the key in openai_api_key as SecretStr
llm_api_key_attr = getattr(llm_instance, 'openai_api_key', 'NOT_FOUND')
if llm_api_key_attr != 'NOT_FOUND':
print(f' LLM instance API key: {get_key_display_value(llm_api_key_attr)}...')
else:
print(f' LLM instance API key attribute not found.')
except Exception as e:
print(f' ❌ Failed to create LLM instance: {e}')
import traceback
traceback.print_exc()
"
continue-on-error: true
- name: Run Unit Tests
run: |
cd src/praisonai && python -m pytest tests/unit/ -v --tb=short --disable-warnings --cov=praisonai --cov-report=term-missing --cov-report=xml --cov-branch
- name: Run Integration Tests
run: |
cd src/praisonai && python -m pytest tests/integration/ -v --tb=short --disable-warnings
- name: Debug Directory Structure
run: |
echo "🔍 Debugging directory structure for CrewAI tests..."
cd src/praisonai
echo "Current working directory: $(pwd)"
echo "📁 Contents of current directory:"
ls -la
echo ""
echo "📁 Contents of tests directory:"
ls -la tests/ || echo "❌ tests/ directory not found"
echo ""
echo "📁 Contents of tests/integration:"
ls -la tests/integration/ || echo "❌ tests/integration/ directory not found"
echo ""
echo "📁 Looking for crewai directory:"
find . -name "crewai" -type d 2>/dev/null || echo "❌ No crewai directories found"
echo ""
echo "📁 Full directory tree of tests:"
tree tests/ || find tests/ -type d 2>/dev/null || echo "❌ Cannot explore tests directory"
- name: Test AutoGen Framework
run: |
echo "🤖 Testing AutoGen Framework Integration..."
cd src/praisonai && python tests/test_runner.py --pattern autogen --verbose
- name: Test CrewAI Framework
run: |
echo "⛵ Testing CrewAI Framework Integration..."
cd src/praisonai
echo "🔍 Trying test runner first..."
python tests/test_runner.py --pattern crewai --verbose || {
echo "❌ Test runner failed, trying direct pytest..."
echo "📁 Current directory: $(pwd)"
echo "📁 Looking for CrewAI tests..."
find . -name "*crewai*" -type f 2>/dev/null
echo "🧪 Trying direct pytest on integration/crewai..."
python -m pytest tests/integration/crewai/ -v --tb=short --disable-warnings || {
echo "❌ Direct path failed, trying relative path..."
python -m pytest integration/crewai/ -v --tb=short --disable-warnings || {
echo "❌ All CrewAI test attempts failed"
exit 1
}
}
}
- name: Run Legacy Tests with API Key
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}
OPENAI_API_BASE: ${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}
OPENAI_MODEL_NAME: ${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}
LOGLEVEL: DEBUG
run: |
echo "🧪 Running legacy tests with real API key..."
echo "🔧 Final environment check before pytest:"
echo " OPENAI_API_KEY set: $([ -n "$OPENAI_API_KEY" ] && echo 'YES' || echo 'NO')"
echo " OPENAI_API_KEY length: ${#OPENAI_API_KEY}"
echo " OPENAI_API_KEY starts with sk-: $(echo "$OPENAI_API_KEY" | grep -q '^sk-' && echo 'YES' || echo 'NO')"
export OPENAI_API_KEY="$OPENAI_API_KEY"
export OPENAI_API_BASE="$OPENAI_API_BASE"
export OPENAI_MODEL_NAME="$OPENAI_MODEL_NAME"
cd src/praisonai && python -m pytest tests/test.py -v --tb=short --disable-warnings
- name: Upload coverage reports to Codecov
if: matrix.python-version == '3.11'
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: src/praisonai/coverage.xml
flags: core-tests
name: core-tests-coverage
fail_ci_if_error: false
verbose: true
- name: Upload Coverage Reports (Artifacts)
if: matrix.python-version == '3.11'
uses: actions/upload-artifact@v4
with:
name: coverage-reports
path: |
src/praisonai/.coverage
src/praisonai/htmlcov/
src/praisonai/coverage.xml
retention-days: 7
+164
View File
@@ -0,0 +1,164 @@
name: Extended Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
# Run nightly at 2 AM UTC
- cron: '0 2 * * *'
workflow_dispatch: # Allow manual triggering
jobs:
test-examples:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
echo "PYTHONPATH=${{ github.workspace }}/src/praisonai-agents:$PYTHONPATH" >> $GITHUB_ENV
- name: Test Key Example Scripts
run: |
echo "🧪 Testing key example scripts from praisonai-agents..."
# Create a timeout function for consistent handling
timeout_run() {
timeout 30s "$@" || echo "⏱️ $1 test completed/timed out"
}
# Test basic agent functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/basic-agents.py
# Test async functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/async_example.py
# Test knowledge/RAG functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/knowledge-agents.py
# Test MCP functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/mcp-basic.py
# Test UI functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/ui.py
echo "✅ Example script testing completed"
continue-on-error: true
performance-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system pytest pytest-benchmark
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Run Performance Benchmarks
run: |
echo "🏃 Running performance benchmarks..."
python -c "
import time
import sys
import statistics
sys.path.insert(0, 'src/praisonai')
print('🏃 Testing agent creation performance...')
times = []
try:
from praisonaiagents import Agent
for i in range(5):
start_time = time.time()
agent = Agent(name=f'PerfAgent{i}')
times.append(time.time() - start_time)
avg_time = statistics.mean(times)
print(f'✅ Average agent creation time: {avg_time:.3f}s')
print(f'📊 Min: {min(times):.3f}s, Max: {max(times):.3f}s')
except Exception as e:
print(f'❌ Agent creation benchmark failed: {e}')
print('🏃 Testing import performance...')
start_time = time.time()
try:
import praisonaiagents
import_time = time.time() - start_time
print(f'✅ Import completed in {import_time:.3f}s')
except Exception as e:
print(f'❌ Import benchmark failed: {e}')
print('🏃 Testing memory usage...')
try:
import psutil
import os
process = psutil.Process(os.getpid())
memory_mb = process.memory_info().rss / 1024 / 1024
print(f'📊 Memory usage: {memory_mb:.1f} MB')
except ImportError:
print('⚠️ psutil not available for memory testing')
except Exception as e:
print(f'❌ Memory benchmark failed: {e}')
"
continue-on-error: true
- name: Generate Performance Report
run: |
echo "## 📊 Performance Test Results" > performance_report.md
echo "" >> performance_report.md
echo "### Benchmarks Run:" >> performance_report.md
echo "- ⚡ Agent creation speed" >> performance_report.md
echo "- 📦 Import performance" >> performance_report.md
echo "- 💾 Memory usage" >> performance_report.md
echo "- 🧪 Example script execution" >> performance_report.md
echo "" >> performance_report.md
echo "_Performance results are logged in the CI output above._" >> performance_report.md
- name: Upload Performance Report
uses: actions/upload-artifact@v4
with:
name: performance-report
path: performance_report.md
retention-days: 30
+153
View File
@@ -0,0 +1,153 @@
name: Framework Integration Tests
on:
workflow_dispatch: # Allow manual triggering
inputs:
framework:
description: 'Framework to test'
required: true
default: 'all'
type: choice
options:
- all
- autogen
- crewai
schedule:
# Run framework tests daily at 6 AM UTC
- cron: '0 6 * * *'
push:
paths:
- 'tests/integration/autogen/**'
- 'tests/integration/crewai/**'
- '.github/workflows/test-frameworks.yml'
jobs:
framework-tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.11]
framework: [autogen, crewai]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
- name: Test ${{ matrix.framework }} Framework
run: |
echo "🧪 Testing ${{ matrix.framework }} framework integration with Python ${{ matrix.python-version }}"
cd src/praisonai && python tests/test_runner.py --pattern ${{ matrix.framework }} --verbose --coverage
continue-on-error: false
- name: Generate Framework Test Report
if: always()
run: |
echo "# 🤖 ${{ matrix.framework }} Framework Test Report" > ${{ matrix.framework }}_report.md
echo "" >> ${{ matrix.framework }}_report.md
echo "**Framework:** ${{ matrix.framework }}" >> ${{ matrix.framework }}_report.md
echo "**Python Version:** ${{ matrix.python-version }}" >> ${{ matrix.framework }}_report.md
echo "**Date:** $(date -u)" >> ${{ matrix.framework }}_report.md
echo "**Trigger:** ${{ github.event_name }}" >> ${{ matrix.framework }}_report.md
echo "" >> ${{ matrix.framework }}_report.md
if [ "${{ matrix.framework }}" == "autogen" ]; then
echo "## AutoGen Integration Tests" >> ${{ matrix.framework }}_report.md
echo "- ✅ AutoGen import verification" >> ${{ matrix.framework }}_report.md
echo "- ✅ Basic agent creation through PraisonAI" >> ${{ matrix.framework }}_report.md
echo "- ✅ Conversation flow testing" >> ${{ matrix.framework }}_report.md
echo "- ✅ Configuration validation" >> ${{ matrix.framework }}_report.md
elif [ "${{ matrix.framework }}" == "crewai" ]; then
echo "## CrewAI Integration Tests" >> ${{ matrix.framework }}_report.md
echo "- ✅ CrewAI import verification" >> ${{ matrix.framework }}_report.md
echo "- ✅ Basic crew creation through PraisonAI" >> ${{ matrix.framework }}_report.md
echo "- ✅ Multi-agent workflow testing" >> ${{ matrix.framework }}_report.md
echo "- ✅ Agent collaboration verification" >> ${{ matrix.framework }}_report.md
echo "- ✅ Configuration validation" >> ${{ matrix.framework }}_report.md
fi
echo "" >> ${{ matrix.framework }}_report.md
echo "## Test Commands" >> ${{ matrix.framework }}_report.md
echo '```bash' >> ${{ matrix.framework }}_report.md
echo "# Run ${{ matrix.framework }} tests locally:" >> ${{ matrix.framework }}_report.md
echo "python tests/test_runner.py --pattern ${{ matrix.framework }} --verbose" >> ${{ matrix.framework }}_report.md
echo '```' >> ${{ matrix.framework }}_report.md
- name: Upload Framework Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: ${{ matrix.framework }}-test-results-python-${{ matrix.python-version }}
path: |
${{ matrix.framework }}_report.md
htmlcov/
coverage.xml
.coverage
retention-days: 14
framework-summary:
runs-on: ubuntu-latest
needs: framework-tests
if: always()
steps:
- name: Generate Framework Summary
run: |
echo "# 🚀 Framework Integration Test Summary" > framework_summary.md
echo "" >> framework_summary.md
echo "## Test Results by Framework and Python Version:" >> framework_summary.md
echo "" >> framework_summary.md
echo "### AutoGen Framework:" >> framework_summary.md
echo "- Python 3.11: ${{ needs.framework-tests.result }}" >> framework_summary.md
echo "" >> framework_summary.md
echo "### CrewAI Framework:" >> framework_summary.md
echo "- Python 3.11: ${{ needs.framework-tests.result }}" >> framework_summary.md
echo "" >> framework_summary.md
echo "## Overall Status:" >> framework_summary.md
if [ "${{ needs.framework-tests.result }}" == "success" ]; then
echo "✅ **All framework integration tests passed!**" >> framework_summary.md
else
echo "❌ **Some framework tests failed. Check individual job logs for details.**" >> framework_summary.md
fi
echo "" >> framework_summary.md
echo "## Frameworks Tested:" >> framework_summary.md
echo "- **AutoGen**: Microsoft's conversational AI framework" >> framework_summary.md
echo "- **CrewAI**: Multi-agent collaboration framework" >> framework_summary.md
echo "" >> framework_summary.md
echo "## Test Coverage:" >> framework_summary.md
echo "- Import verification" >> framework_summary.md
echo "- Agent/crew creation" >> framework_summary.md
echo "- Workflow execution" >> framework_summary.md
echo "- Configuration validation" >> framework_summary.md
echo "- Integration with PraisonAI" >> framework_summary.md
- name: Upload Framework Summary
uses: actions/upload-artifact@v4
with:
name: framework-test-summary
path: framework_summary.md
retention-days: 30
+167
View File
@@ -0,0 +1,167 @@
name: Real End-to-End Tests
# ⚠️ WARNING: This workflow makes real API calls and incurs costs!
# Only runs when manually triggered to prevent accidental charges
on:
workflow_dispatch: # Manual trigger only
inputs:
framework:
description: 'Framework to test (⚠️ Will incur API costs!)'
required: true
default: 'none'
type: choice
options:
- none
- autogen
- crewai
- all
confirm_costs:
description: 'I understand this will make real API calls and may incur costs'
required: true
type: boolean
default: false
jobs:
real-tests:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.confirm_costs == 'true' && github.event.inputs.framework != 'none' }}
strategy:
matrix:
python-version: [3.11] # Single version to minimize costs
steps:
- name: 🚨 Cost Warning
run: |
echo "⚠️ WARNING: This workflow will make real API calls!"
echo "💰 This may incur charges on your API accounts"
echo "🎯 Framework: ${{ github.event.inputs.framework }}"
echo "✅ Cost confirmation: ${{ github.event.inputs.confirm_costs }}"
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system pytest pytest-asyncio pytest-cov
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}" >> $GITHUB_ENV
echo "ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }}" >> $GITHUB_ENV
echo "GOOGLE_API_KEY=${{ secrets.GOOGLE_API_KEY }}" >> $GITHUB_ENV
- name: Verify API Keys
run: |
if [ -z "${{ secrets.OPENAI_API_KEY }}" ]; then
echo "❌ OPENAI_API_KEY not set in secrets"
echo "🔧 Add your API key to repository secrets"
exit 1
fi
echo "✅ API keys configured"
- name: Run Real AutoGen Tests
if: ${{ github.event.inputs.framework == 'autogen' || github.event.inputs.framework == 'all' }}
run: |
echo "🤖 Running REAL AutoGen tests (⚠️ API costs may apply)"
cd src/praisonai && python -m pytest tests/e2e/autogen/ -v -m real --tb=short
continue-on-error: false
- name: Run Real CrewAI Tests
if: ${{ github.event.inputs.framework == 'crewai' || github.event.inputs.framework == 'all' }}
run: |
echo "⛵ Running REAL CrewAI tests (⚠️ API costs may apply)"
cd src/praisonai && python -m pytest tests/e2e/crewai/ -v -m real --tb=short
continue-on-error: false
- name: Generate Real Test Report
if: always()
run: |
echo "# 🔥 Real End-to-End Test Report" > real_test_report.md
echo "" >> real_test_report.md
echo "⚠️ **WARNING: This report represents tests that made real API calls**" >> real_test_report.md
echo "" >> real_test_report.md
echo "**Framework Tested:** ${{ github.event.inputs.framework }}" >> real_test_report.md
echo "**Python Version:** ${{ matrix.python-version }}" >> real_test_report.md
echo "**Date:** $(date -u)" >> real_test_report.md
echo "**Triggered by:** ${{ github.actor }}" >> real_test_report.md
echo "" >> real_test_report.md
echo "## 🧪 Test Results" >> real_test_report.md
echo "" >> real_test_report.md
if [ "${{ github.event.inputs.framework }}" == "autogen" ] || [ "${{ github.event.inputs.framework }}" == "all" ]; then
echo "### AutoGen Real Tests:" >> real_test_report.md
echo "- Environment verification" >> real_test_report.md
echo "- Agent creation with real API calls" >> real_test_report.md
echo "- Configuration validation" >> real_test_report.md
echo "" >> real_test_report.md
fi
if [ "${{ github.event.inputs.framework }}" == "crewai" ] || [ "${{ github.event.inputs.framework }}" == "all" ]; then
echo "### CrewAI Real Tests:" >> real_test_report.md
echo "- Environment verification" >> real_test_report.md
echo "- Crew creation with real API calls" >> real_test_report.md
echo "- Multi-agent setup validation" >> real_test_report.md
echo "" >> real_test_report.md
fi
echo "## 💰 Cost Considerations" >> real_test_report.md
echo "- These tests made actual API calls to LLM providers" >> real_test_report.md
echo "- Costs depend on your API pricing tier" >> real_test_report.md
echo "- Tests are designed to be minimal to reduce costs" >> real_test_report.md
echo "- Check your API provider dashboard for actual usage" >> real_test_report.md
echo "## 📋 Next Steps" >> real_test_report.md
echo "- Review test results for any failures" >> real_test_report.md
echo "- Check API usage in your provider dashboard" >> real_test_report.md
echo "- Use mock tests (tests/integration/) for routine testing" >> real_test_report.md
- name: Upload Real Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: real-test-results-${{ github.event.inputs.framework }}-python-${{ matrix.python-version }}
path: |
real_test_report.md
retention-days: 30
# Safety job that runs when costs not confirmed
safety-check:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.confirm_costs != 'true' || github.event.inputs.framework == 'none' }}
steps:
- name: 🛡️ Safety Check Failed
run: |
echo "🚨 Real tests not executed due to safety checks:"
echo ""
echo "✅ Costs confirmed: ${{ github.event.inputs.confirm_costs }}"
echo "✅ Framework selected: ${{ github.event.inputs.framework }}"
echo ""
echo "To run real tests:"
echo "1. Select a framework (autogen, crewai, or all)"
echo "2. Check 'I understand this will make real API calls and may incur costs'"
echo "3. Ensure API keys are set in repository secrets"
echo ""
echo "💡 For cost-free testing, use mock tests instead:"
echo " - Run 'python -m pytest tests/integration/' locally"
echo " - Or trigger other workflows that use mock tests"
exit 1
+493 -14
View File
@@ -1,36 +1,515 @@
name: Run specific unittest
name: Quick Validation Tests
on: [push, pull_request]
jobs:
test:
quick-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install Poetry
- name: Install UV
run: |
curl -sSL https://install.python-poetry.org | python3 -
export PATH="$HOME/.local/bin:$PATH"
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
poetry install
poetry run python -m pip install duckduckgo_search
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME }}" >> $GITHUB_ENV
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
echo "LOGLEVEL=DEBUG" >> $GITHUB_ENV
echo "PYTHONPATH=${{ github.workspace }}/src/praisonai-agents:$PYTHONPATH" >> $GITHUB_ENV
- name: Run specific unittest
- name: Backup Root Config Files
run: |
poetry run python -m unittest tests.test.TestExamples
echo "🔄 Backing up root configuration files to prevent default file resolution interference..."
echo "ℹ️ PraisonAI automatically uses 'agents.yaml' in working directory when no file specified"
echo "ℹ️ This can interfere with test files that specify their own YAML files"
if [ -f "agents.yaml" ]; then
mv agents.yaml agents.yaml.backup
echo "✅ Moved root agents.yaml to agents.yaml.backup"
echo " - This prevents default file fallback during tests"
fi
if [ -f "tools.py" ]; then
mv tools.py tools.py.backup
echo "✅ Moved tools.py to tools.py.backup"
fi
- name: Debug API Key Status
run: |
echo "🔍 Checking API key availability..."
if [ -n "${{ secrets.OPENAI_API_KEY }}" ]; then
echo "✅ GitHub secret OPENAI_API_KEY is available"
echo "🔑 API key starts with: $(echo "$OPENAI_API_KEY" | cut -c1-7)..."
else
echo "⚠️ GitHub secret OPENAI_API_KEY is NOT set - using fallback"
echo "🔑 Using fallback key: sk-test-key..."
fi
echo "🌐 API Base: $OPENAI_API_BASE"
echo "🤖 Model: $OPENAI_MODEL_NAME"
echo "🐛 Log Level: $LOGLEVEL"
echo "📊 Environment Check:"
echo " - OPENAI_API_KEY length: ${#OPENAI_API_KEY}"
echo " - OPENAI_API_BASE: $OPENAI_API_BASE"
echo " - OPENAI_MODEL_NAME: $OPENAI_MODEL_NAME"
echo " - LOGLEVEL: $LOGLEVEL"
- name: Debug Python Environment Variables
run: |
python -c "
import os
print('🐍 Python Environment Variable Check:')
api_key = os.environ.get('OPENAI_API_KEY', 'NOT_SET')
if api_key != 'NOT_SET':
print(f' ✅ OPENAI_API_KEY: {api_key[:7]}... (length: {len(api_key)})')
else:
print(' ❌ OPENAI_API_KEY: NOT_SET')
print(f' 🌐 OPENAI_API_BASE: {os.environ.get(\"OPENAI_API_BASE\", \"NOT_SET\")}')
print(f' 🤖 OPENAI_MODEL_NAME: {os.environ.get(\"OPENAI_MODEL_NAME\", \"NOT_SET\")}')
print(f' 📋 All OPENAI env vars:')
for key, value in os.environ.items():
if key.startswith('OPENAI'):
print(f' {key}: {value[:10] if len(value) > 10 else value}...')
"
- name: Find Researcher Role Source
run: |
echo "🔍 Hunting for the mysterious 'Researcher' role..."
cd src/praisonai
python -c "
import os
import yaml
import glob
print('📋 Searching for Researcher role in all YAML files:')
yaml_files = glob.glob('src/praisonai/tests/*.yaml')
for yaml_file in yaml_files:
try:
with open(yaml_file, 'r') as f:
config = yaml.safe_load(f)
# Check if any role contains 'researcher'
roles = config.get('roles', {})
for role_key, role_data in roles.items():
role_name = role_data.get('role', '')
if 'researcher' in role_key.lower() or 'researcher' in role_name.lower():
print(f' 🎯 FOUND in {yaml_file}:')
print(f' Framework: {config.get(\"framework\", \"NOT_SET\")}')
print(f' Role key: {role_key}')
print(f' Role name: {role_name}')
print(f' All roles: {list(roles.keys())}')
print()
except Exception as e:
print(f' ❌ Error reading {yaml_file}: {e}')
print('🔍 Checking for default configurations...')
# Check if there are any default configs or hardcoded roles
try:
import praisonai
print(f' PraisonAI package location: {praisonai.__file__}')
# Check if there are any example YAML files in the package
package_dir = os.path.dirname(praisonai.__file__)
for root, dirs, files in os.walk(package_dir):
for file in files:
if file.endswith(('.yaml', '.yml')):
file_path = os.path.join(root, file)
print(f' 📁 Found YAML in package: {file_path}')
except Exception as e:
print(f' ❌ Error checking package: {e}')
"
continue-on-error: true
- name: Trace AutoGen Execution Path
run: |
echo "🔍 Tracing AutoGen execution to find where it diverges..."
cd src/praisonai
python -c "
import os
import sys
sys.path.insert(0, '.')
try:
from praisonai import PraisonAI
from praisonai.agents_generator import AgentsGenerator
# Test the exact execution path
print('🎯 Testing AutoGen execution path:')
praisonai = PraisonAI(agent_file='tests/autogen-agents.yaml')
print(f' 1. PraisonAI framework: \"{praisonai.framework}\"')
agents_gen = AgentsGenerator(
agent_file='tests/autogen-agents.yaml',
framework=praisonai.framework,
config_list=praisonai.config_list
)
print(f' 2. AgentsGenerator framework: \"{agents_gen.framework}\"')
# Load the YAML to check what it contains
import yaml
with open('src/praisonai/tests/autogen-agents.yaml', 'r') as f:
config = yaml.safe_load(f)
framework = agents_gen.framework or config.get('framework')
print(f' 3. Final framework decision: \"{framework}\"')
print(f' 4. Available frameworks:')
# Check framework availability
try:
import autogen
print(f' ✅ AutoGen available')
except ImportError:
print(f' ❌ AutoGen NOT available')
try:
from praisonaiagents import Agent
print(f' ✅ PraisonAI agents available')
except ImportError:
print(f' ❌ PraisonAI agents NOT available')
try:
from crewai import Agent
print(f' ✅ CrewAI available')
except ImportError:
print(f' ❌ CrewAI NOT available')
print(f' 5. Roles in YAML: {list(config.get(\"roles\", {}).keys())}')
# Now test the actual framework execution
if framework == 'autogen':
print(f' 6. ✅ Should execute _run_autogen')
elif framework == 'praisonai':
print(f' 6. ❌ Would execute _run_praisonai (WRONG!)')
else:
print(f' 6. ❌ Would execute _run_crewai (DEFAULT FALLBACK)')
except Exception as e:
print(f'❌ Error tracing execution: {e}')
import traceback
traceback.print_exc()
"
continue-on-error: true
- name: Debug YAML Loading and Roles
run: |
echo "🔍 Tracing YAML file loading and role creation..."
cd src/praisonai
python -c "
import os
import sys
import yaml
sys.path.insert(0, '.')
print('📁 Available YAML files in src/praisonai/tests/:')
import glob
yaml_files = glob.glob('tests/*.yaml')
for f in yaml_files:
print(f' {f}')
print()
print('📋 Content of autogen-agents.yaml:')
with open('tests/autogen-agents.yaml', 'r') as f:
config = yaml.safe_load(f)
print(f' Framework: {config.get(\"framework\")}')
print(f' Topic: {config.get(\"topic\")}')
print(f' Roles: {list(config.get(\"roles\", {}).keys())}')
for role_key, role_data in config.get('roles', {}).items():
print(f' {role_key} -> {role_data.get(\"role\", \"NO_ROLE\")}')
print()
print('🔍 Checking if execution uses a different YAML:')
# Check other YAML files for 'Researcher' role
for yaml_file in yaml_files:
try:
with open(yaml_file, 'r') as f:
test_config = yaml.safe_load(f)
roles = test_config.get('roles', {})
for role_key, role_data in roles.items():
if 'researcher' in role_key.lower() or 'researcher' in role_data.get('role', '').lower():
print(f' 🎯 FOUND Researcher in {yaml_file}!')
print(f' Framework: {test_config.get(\"framework\")}')
print(f' Role key: {role_key} -> {role_data.get(\"role\")}')
except:
pass
"
continue-on-error: true
- name: Debug Framework Detection
run: |
echo "🔍 Testing framework detection and config flow..."
python -c "
import os
import sys
import yaml
sys.path.insert(0, '.')
print('🔧 Testing framework detection:')
# Load the YAML file
with open('tests/autogen-agents.yaml', 'r') as f:
config = yaml.safe_load(f)
print(f' 📋 YAML framework: {config.get(\"framework\", \"NOT_SET\")}')
print(f' 📋 YAML topic: {config.get(\"topic\", \"NOT_SET\")}')
try:
from praisonai import PraisonAI
from praisonai.agents_generator import AgentsGenerator
# Test PraisonAI initialization
praisonai = PraisonAI(agent_file='tests/autogen-agents.yaml')
print(f' 🎯 PraisonAI framework: {praisonai.framework}')
# Test AgentsGenerator initialization
agents_gen = AgentsGenerator(
agent_file='tests/autogen-agents.yaml',
framework=praisonai.framework,
config_list=praisonai.config_list
)
print(f' ⚙️ AgentsGenerator framework: {agents_gen.framework}')
print(f' ⚙️ Final framework decision: {agents_gen.framework or config.get(\"framework\")}')
# Check config_list
print(f' 🔑 Config list model: {praisonai.config_list[0].get(\"model\")}')
print(f' 🔑 Config list API key: {praisonai.config_list[0].get(\"api_key\", \"NOT_SET\")[:10]}...')
except Exception as e:
print(f'❌ Error in framework detection: {e}')
"
continue-on-error: true
- name: Debug PraisonAIModel API Key Flow
run: |
echo "🔍 Testing PraisonAIModel API key handling..."
cd src/praisonai
python -c "
import os
import sys
sys.path.insert(0, '.')
print('🔑 Environment API Key Check:')
env_key = os.environ.get('OPENAI_API_KEY', 'NOT_FOUND')
print(f' OPENAI_API_KEY: {env_key[:10] if env_key != \"NOT_FOUND\" else \"NOT_FOUND\"}...')
try:
from praisonai.inc.models import PraisonAIModel
# Test PraisonAIModel with openai/gpt-4o-mini (from YAML)
model = PraisonAIModel(model='openai/gpt-4o-mini')
print('🤖 PraisonAIModel Configuration:')
print(f' model: {model.model}')
print(f' model_name: {model.model_name}')
print(f' api_key_var: {model.api_key_var}')
print(f' api_key: {model.api_key[:10] if model.api_key != \"nokey\" else \"DEFAULT_NOKEY\"}...')
print(f' base_url: {model.base_url}')
if model.api_key == 'nokey':
print('❌ FOUND THE ISSUE: PraisonAIModel is using default \"nokey\" instead of environment variable!')
else:
print('✅ PraisonAIModel has valid API key from environment')
except Exception as e:
print(f'❌ Error testing PraisonAIModel: {e}')
"
continue-on-error: true
- name: Validate API Key
run: |
echo "🔑 Testing API key validity with minimal OpenAI call..."
python -c "
import os
try:
from openai import OpenAI
client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
# Make a minimal API call to test key validity
response = client.models.list()
print('✅ API Key is VALID - OpenAI responded successfully')
print(f'📊 Available models: {len(list(response.data))} models found')
except Exception as e:
print(f'❌ API Key is INVALID - Error: {e}')
print('🔍 This explains why all API-dependent tests are failing')
print('💡 The GitHub secret OPENAI_API_KEY needs to be updated with a valid key')
"
continue-on-error: true
- name: Test Direct PraisonAI Execution
run: |
echo "🧪 Testing direct PraisonAI execution (what works locally)..."
python -m praisonai src/praisonai/tests/autogen-agents.yaml
continue-on-error: true
- name: Comprehensive Execution Debug
run: |
echo "🔍 Comprehensive debugging of PraisonAI execution path..."
cd src/praisonai
python -c "
import os
import sys
import yaml
sys.path.insert(0, '.')
print('=' * 60)
print('🔍 COMPREHENSIVE EXECUTION DEBUG')
print('=' * 60)
# Check current working directory
print(f'📁 Current working directory: {os.getcwd()}')
# List files in current directory
print('📋 Files in current directory:')
for f in os.listdir('.'):
print(f' {f}')
print()
print('📋 Files in src/praisonai/tests/ directory:')
for f in os.listdir('tests'):
if f.endswith('.yaml'):
print(f' src/praisonai/tests/{f}')
# Check if root agents.yaml exists
print()
if os.path.exists('agents.yaml'):
print('❌ ROOT agents.yaml EXISTS (this is the problem!)')
with open('agents.yaml', 'r') as f:
root_config = yaml.safe_load(f)
print(f' Root framework: {root_config.get(\"framework\")}')
print(f' Root roles: {list(root_config.get(\"roles\", {}).keys())}')
else:
print('✅ ROOT agents.yaml does NOT exist (good!)')
# Test the actual execution path
print()
print('🎯 Testing EXACT execution path:')
try:
from praisonai import PraisonAI
from praisonai.agents_generator import AgentsGenerator
# Test with full path
test_file = 'src/praisonai/tests/autogen-agents.yaml'
print(f' Using test file: {test_file}')
print(f' File exists: {os.path.exists(test_file)}')
# Load the test file directly
with open(test_file, 'r') as f:
test_config = yaml.safe_load(f)
print(f' Test file framework: {test_config.get(\"framework\")}')
print(f' Test file roles: {list(test_config.get(\"roles\", {}).keys())}')
# Create PraisonAI instance
praisonai = PraisonAI(agent_file=test_file)
print(f' PraisonAI.agent_file: {praisonai.agent_file}')
print(f' PraisonAI.framework: {praisonai.framework}')
# Create AgentsGenerator
agents_gen = AgentsGenerator(
agent_file=test_file,
framework=praisonai.framework,
config_list=praisonai.config_list
)
print(f' AgentsGenerator.agent_file: {agents_gen.agent_file}')
print(f' AgentsGenerator.framework: {agents_gen.framework}')
# Test what would happen in generate_crew_and_kickoff
print()
print('🔧 Testing generate_crew_and_kickoff logic:')
# Simulate the loading logic
if agents_gen.agent_yaml:
loaded_config = yaml.safe_load(agents_gen.agent_yaml)
print(' Would load from agent_yaml')
else:
if agents_gen.agent_file == '/app/api:app' or agents_gen.agent_file == 'api:app':
agents_gen.agent_file = 'agents.yaml'
print(f' Would change agent_file to: {agents_gen.agent_file}')
try:
with open(agents_gen.agent_file, 'r') as f:
loaded_config = yaml.safe_load(f)
print(f' Successfully loaded: {agents_gen.agent_file}')
except FileNotFoundError:
print(f' FileNotFoundError: {agents_gen.agent_file}')
loaded_config = None
if loaded_config:
final_framework = agents_gen.framework or loaded_config.get('framework')
print(f' Final framework decision: {final_framework}')
print(f' Loaded roles: {list(loaded_config.get(\"roles\", {}).keys())}')
if 'researcher' in loaded_config.get('roles', {}):
print(' ❌ FOUND Researcher role in loaded config!')
else:
print(' ✅ No Researcher role in loaded config')
except Exception as e:
print(f'❌ Error during execution debug: {e}')
import traceback
traceback.print_exc()
"
continue-on-error: true
- name: Run Fast Tests
run: |
# Run the fastest, most essential tests with coverage
cd src/praisonai && python -m pytest tests/unit/test_core_agents.py -v --tb=short --disable-warnings --cov=praisonai --cov-report=xml --cov-branch
- name: Run Real API Tests
run: |
echo "🔑 Running real API tests with actual OpenAI API key..."
cd src/praisonai && python -m pytest tests/test_agents_playbook.py -v --tb=short --disable-warnings -m real
continue-on-error: true
- name: Run E2E Real Tests
run: |
echo "🧪 Running E2E real tests..."
cd src/praisonai && python -m pytest tests/e2e/ -v --tb=short --disable-warnings -m real
continue-on-error: true
- name: Run Legacy Example Tests
run: |
cd src/praisonai && python -m pytest tests/test.py -v --tb=short --disable-warnings
continue-on-error: true
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: src/praisonai/coverage.xml
flags: quick-validation
name: quick-validation-coverage
fail_ci_if_error: false
verbose: true
- name: Restore Root Config Files
run: |
echo "🔄 Restoring root configuration files..."
if [ -f "agents.yaml.backup" ]; then
mv agents.yaml.backup agents.yaml
echo "✅ Restored agents.yaml"
fi
if [ -f "tools.py.backup" ]; then
mv tools.py.backup tools.py
echo "✅ Restored tools.py"
fi
if: always() # Always run this step, even if previous steps failed
+10 -1
View File
@@ -1,3 +1,4 @@
workspace.code-workspace
.vscode
crewai
.cache
@@ -51,6 +52,10 @@ agentops.log
# crewAI
crewAI
!tests/integration/crewai
!tests/e2e/crewai
!src/praisonai/tests/integration/crewai
!src/praisonai/tests/e2e/crewai
# virtualenv
.venv
@@ -66,4 +71,8 @@ agents/praisonaiagents/build
agents/praisonaiagents/dist
agents/praisonaiagents/praisonaiagents.egg-info
.codegpt
.praison
.praison
# Local Netlify folder
.netlify
.qodo
CopilotKit*
-23
View File
@@ -1,23 +0,0 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.12"
jobs:
post_install:
- bash docs/generate_docs.sh
mkdocs:
configuration: mkdocs.yml
fail_on_warning: true
python:
install:
- requirements: docs/requirements.txt
+31 -8
View File
@@ -20,7 +20,7 @@
</div>
PraisonAI is a production-ready Multi-AI Agents framework with self-reflection, designed to create AI Agents to automate and solve problems ranging from simple tasks to complex challenges. By integrating PraisonAI Agents, AutoGen, and CrewAI into a low-code solution, it streamlines the building and management of multi-agent LLM systems, emphasising simplicity, customisation, and effective human-agent collaboration.
PraisonAI is a production-ready Multi-AI Agents framework with self-reflection, designed to create AI Agents to automate and solve problems ranging from simple tasks to complex challenges. By integrating PraisonAI Agents, AG2 (Formerly AutoGen), and CrewAI into a low-code solution, it streamlines the building and management of multi-agent LLM systems, emphasising simplicity, customisation, and effective human-agent collaboration.
<div align="center">
<a href="https://docs.praison.ai">
@@ -54,7 +54,7 @@ PraisonAI is a production-ready Multi-AI Agents framework with self-reflection,
- 📄 YAML Configuration
- 💯 100+ LLM Support
## Using Code
## Using Python Code
Light weight package dedicated for coding:
```bash
@@ -71,7 +71,7 @@ Create app.py file and add the code below:
```python
from praisonaiagents import Agent
agent = Agent(instructions="Your are a helpful AI assistant")
agent.chat("Write a movie script about a robot in Mars")
agent.start("Write a movie script about a robot in Mars")
```
Run:
@@ -105,6 +105,21 @@ export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
praisonai --auto create a movie script about Robots in Mars
```
## Using JavaScript Code
```bash
npm install praisonai
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
```
```javascript
const { Agent } = require('praisonai');
const agent = new Agent({ instructions: 'You are a helpful AI assistant' });
agent.start('Write a movie script about a robot in Mars');
```
![PraisonAI CLI Demo](docs/demo/praisonai-cli-demo.gif)
## AI Agents Flow
```mermaid
@@ -472,6 +487,8 @@ export OPENAI_BASE_URL=https://api.groq.com/openai/v1
### Simple Playbook Example
Create `agents.yaml` file and add the code below:
```yaml
framework: praisonai
topic: Artificial Intelligence
@@ -531,7 +548,7 @@ uv pip install -r pyproject.toml --extra "crewai,autogen"
## Other Features
- 🔄 Use CrewAI or AutoGen Framework
- 🔄 Use CrewAI or AG2 (Formerly AutoGen) Framework
- 💻 Chat with ENTIRE Codebase
- 🎨 Interactive UIs
- 📄 YAML-based Configuration
@@ -544,14 +561,19 @@ uv pip install -r pyproject.toml --extra "crewai,autogen"
[![Star History Chart](https://api.star-history.com/svg?repos=MervinPraison/PraisonAI&type=Date)](https://docs.praison.ai)
## License
Praison AI is an open-sourced software licensed under the **[MIT license](https://opensource.org/licenses/MIT)**.
## Video Tutorials
| Topic | Video |
|-------|--------|
| AI Agents with Self Reflection | [![Self Reflection](https://img.youtube.com/vi/vLXobEN2Vc8/0.jpg)](https://www.youtube.com/watch?v=vLXobEN2Vc8) |
| Reasoning Data Generating Agent | [![Reasoning Data](https://img.youtube.com/vi/fUT332Y2zA8/0.jpg)](https://www.youtube.com/watch?v=fUT332Y2zA8) |
| AI Agents with Reasoning | [![Reasoning](https://img.youtube.com/vi/KNDVWGN3TpM/0.jpg)](https://www.youtube.com/watch?v=KNDVWGN3TpM) |
| Multimodal AI Agents | [![Multimodal](https://img.youtube.com/vi/hjAWmUT1qqY/0.jpg)](https://www.youtube.com/watch?v=hjAWmUT1qqY) |
| AI Agents Workflow | [![Workflow](https://img.youtube.com/vi/yWTH44QPl2A/0.jpg)](https://www.youtube.com/watch?v=yWTH44QPl2A) |
| Async AI Agents | [![Async](https://img.youtube.com/vi/VhVQfgo00LE/0.jpg)](https://www.youtube.com/watch?v=VhVQfgo00LE) |
| Mini AI Agents | [![Mini](https://img.youtube.com/vi/OkvYp5aAGSg/0.jpg)](https://www.youtube.com/watch?v=OkvYp5aAGSg) |
| AI Agents with Memory | [![Memory](https://img.youtube.com/vi/1hVfVxvPnnQ/0.jpg)](https://www.youtube.com/watch?v=1hVfVxvPnnQ) |
| Repetitive Agents | [![Repetitive](https://img.youtube.com/vi/dAYGxsjDOPg/0.jpg)](https://www.youtube.com/watch?v=dAYGxsjDOPg) |
| Introduction | [![Introduction](https://img.youtube.com/vi/Fn1lQjC0GO0/0.jpg)](https://www.youtube.com/watch?v=Fn1lQjC0GO0) |
| Tools Overview | [![Tools Overview](https://img.youtube.com/vi/XaQRgRpV7jo/0.jpg)](https://www.youtube.com/watch?v=XaQRgRpV7jo) |
| Custom Tools | [![Custom Tools](https://img.youtube.com/vi/JSU2Rndh06c/0.jpg)](https://www.youtube.com/watch?v=JSU2Rndh06c) |
@@ -564,4 +586,5 @@ Praison AI is an open-sourced software licensed under the **[MIT license](https:
| Training | [![Training](https://img.youtube.com/vi/aLawE8kwCrI/0.jpg)](https://www.youtube.com/watch?v=aLawE8kwCrI) |
| Realtime Voice Interface | [![Realtime](https://img.youtube.com/vi/frRHfevTCSw/0.jpg)](https://www.youtube.com/watch?v=frRHfevTCSw) |
| Call Interface | [![Call](https://img.youtube.com/vi/m1cwrUG2iAk/0.jpg)](https://www.youtube.com/watch?v=m1cwrUG2iAk) |
| Reasoning Extract Agents | [![Reasoning Extract](https://img.youtube.com/vi/2PPamsADjJA/0.jpg)](https://www.youtube.com/watch?v=2PPamsADjJA) |
Binary file not shown.
-53
View File
@@ -1,53 +0,0 @@
"""
Praison AI Agents - A package for hierarchical AI agent task execution
"""
from .agent.agent import Agent
from .agents.agents import PraisonAIAgents
from .task.task import Task
from .tools.tools import Tools
from .agents.autoagents import AutoAgents
from .knowledge.knowledge import Knowledge
from .knowledge.chunking import Chunking
from .main import (
TaskOutput,
ReflectionOutput,
display_interaction,
display_self_reflection,
display_instruction,
display_tool_call,
display_error,
display_generating,
clean_triple_backticks,
error_logs,
register_display_callback,
sync_display_callbacks,
async_display_callbacks,
)
# Add Agents as an alias for PraisonAIAgents
Agents = PraisonAIAgents
__all__ = [
'Agent',
'PraisonAIAgents',
'Agents',
'Tools',
'Task',
'TaskOutput',
'ReflectionOutput',
'AutoAgents',
'display_interaction',
'display_self_reflection',
'display_instruction',
'display_tool_call',
'display_error',
'display_generating',
'clean_triple_backticks',
'error_logs',
'register_display_callback',
'sync_display_callbacks',
'async_display_callbacks',
'Knowledge',
'Chunking'
]
-4
View File
@@ -1,4 +0,0 @@
"""Agent module for AI agents"""
from .agent import Agent
__all__ = ['Agent']
File diff suppressed because it is too large. Load diff
-851
View File
@@ -1,851 +0,0 @@
import os
import time
import json
import logging
from typing import Any, Dict, Optional, List
from pydantic import BaseModel
from rich.text import Text
from rich.panel import Panel
from rich.console import Console
from ..main import display_error, TaskOutput, error_logs, client
from ..agent.agent import Agent
from ..task.task import Task
from ..process.process import Process, LoopItems
import asyncio
import uuid
# Set up logger
logger = logging.getLogger(__name__)
def encode_file_to_base64(file_path: str) -> str:
"""Base64-encode a file."""
import base64
with open(file_path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
def process_video(video_path: str, seconds_per_frame=2):
"""Split video into frames (base64-encoded)."""
import cv2
import base64
base64_frames = []
video = cv2.VideoCapture(video_path)
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
fps = video.get(cv2.CAP_PROP_FPS)
frames_to_skip = int(fps * seconds_per_frame)
curr_frame = 0
while curr_frame < total_frames:
video.set(cv2.CAP_PROP_POS_FRAMES, curr_frame)
success, frame = video.read()
if not success:
break
_, buffer = cv2.imencode(".jpg", frame)
base64_frames.append(base64.b64encode(buffer).decode("utf-8"))
curr_frame += frames_to_skip
video.release()
return base64_frames
class PraisonAIAgents:
def __init__(self, agents, tasks=None, verbose=0, completion_checker=None, max_retries=5, process="sequential", manager_llm=None, memory=False, memory_config=None, embedder=None, user_id=None, max_iter=10):
# Add check at the start if memory is requested
if memory:
try:
from ..memory.memory import Memory
MEMORY_AVAILABLE = True
except ImportError:
raise ImportError(
"Memory features requested but memory dependencies not installed. "
"Please install with: pip install \"praisonaiagents[memory]\""
)
if not agents:
raise ValueError("At least one agent must be provided")
self.run_id = str(uuid.uuid4()) # Auto-generate run_id
self.user_id = user_id or "praison" # Optional user_id
self.max_iter = max_iter # Add max_iter parameter
# Pass user_id to each agent
for agent in agents:
agent.user_id = self.user_id
self.agents = agents
self.tasks = {}
if max_retries < 3:
max_retries = 3
self.completion_checker = completion_checker if completion_checker else self.default_completion_checker
self.task_id_counter = 0
self.verbose = verbose
self.max_retries = max_retries
self.process = process
# Check for manager_llm in environment variable if not provided
self.manager_llm = manager_llm or os.getenv('OPENAI_MODEL_NAME', 'gpt-4o')
# Set logger level based on verbose
if verbose >= 5:
logger.setLevel(logging.INFO)
else:
logger.setLevel(logging.WARNING)
# Also set third-party loggers to WARNING
logging.getLogger('chromadb').setLevel(logging.WARNING)
logging.getLogger('openai').setLevel(logging.WARNING)
logging.getLogger('httpx').setLevel(logging.WARNING)
logging.getLogger('httpcore').setLevel(logging.WARNING)
if self.verbose:
logger.info(f"Using model {self.manager_llm} for manager")
# If no tasks provided, generate them from agents
if tasks is None:
tasks = []
for agent in self.agents:
task = agent.generate_task()
tasks.append(task)
logger.info(f"Auto-generated {len(tasks)} tasks from agents")
else:
# Validate tasks for backward compatibility
if not tasks:
raise ValueError("If tasks are provided, at least one task must be present")
logger.info(f"Using {len(tasks)} provided tasks")
# Add tasks and set their status
for task in tasks:
self.add_task(task)
task.status = "not started"
# If tasks were auto-generated from agents or process is sequential, set up sequential flow
if len(tasks) > 1 and (process == "sequential" or all(task.next_tasks == [] for task in tasks)):
for i in range(len(tasks) - 1):
# Set up next task relationship
tasks[i].next_tasks = [tasks[i + 1].name]
# Set up context for the next task to include the current task
if tasks[i + 1].context is None:
tasks[i + 1].context = []
tasks[i + 1].context.append(tasks[i])
logger.info("Set up sequential flow with automatic context passing")
self._state = {} # Add state storage at PraisonAIAgents level
# Initialize memory system
self.shared_memory = None
if memory:
try:
from ..memory.memory import Memory
# Get memory config from parameter or first task
mem_cfg = memory_config
if not mem_cfg:
mem_cfg = next((t.config.get('memory_config') for t in tasks if hasattr(t, 'config') and t.config), None)
# Set default memory config if none provided
if not mem_cfg:
mem_cfg = {
"provider": "rag",
"use_embedding": True,
"storage": {
"type": "sqlite",
"path": "./.praison/memory.db"
},
"rag_db_path": "./.praison/chroma_db"
}
# Add embedder config if provided
if embedder:
if isinstance(embedder, dict):
mem_cfg = mem_cfg or {}
mem_cfg["embedder"] = embedder
else:
# Handle direct embedder function
mem_cfg = mem_cfg or {}
mem_cfg["embedder_function"] = embedder
if mem_cfg:
# Pass verbose level to Memory
self.shared_memory = Memory(config=mem_cfg, verbose=verbose)
if verbose >= 5:
logger.info("Initialized shared memory for PraisonAIAgents")
# Distribute memory to tasks
for task in tasks:
if not task.memory:
task.memory = self.shared_memory
if verbose >= 5:
logger.info(f"Assigned shared memory to task {task.id}")
except Exception as e:
logger.error(f"Failed to initialize shared memory: {e}")
# Update tasks with shared memory
if self.shared_memory:
for task in tasks:
if not task.memory:
task.memory = self.shared_memory
logger.info(f"Assigned shared memory to task {task.id}")
def add_task(self, task):
task_id = self.task_id_counter
task.id = task_id
self.tasks[task_id] = task
self.task_id_counter += 1
return task_id
def clean_json_output(self, output: str) -> str:
cleaned = output.strip()
if cleaned.startswith("```json"):
cleaned = cleaned[len("```json"):].strip()
if cleaned.startswith("```"):
cleaned = cleaned[len("```"):].strip()
if cleaned.endswith("```"):
cleaned = cleaned[:-3].strip()
return cleaned
def default_completion_checker(self, task, agent_output):
if task.output_json and task.result and task.result.json_dict:
return True
if task.output_pydantic and task.result and task.result.pydantic:
return True
return len(agent_output.strip()) > 0
async def aexecute_task(self, task_id):
"""Async version of execute_task method"""
if task_id not in self.tasks:
display_error(f"Error: Task with ID {task_id} does not exist")
return
task = self.tasks[task_id]
# Only import multimodal dependencies if task has images
if task.images and task.status == "not started":
try:
import cv2
import base64
from moviepy import VideoFileClip
except ImportError as e:
display_error(f"Error: Missing required dependencies for image/video processing: {e}")
display_error("Please install with: pip install opencv-python moviepy")
task.status = "failed"
return None
if task.status == "not started":
task.status = "in progress"
executor_agent = task.agent
# Ensure tools are available from both task and agent
tools = task.tools or []
if executor_agent and executor_agent.tools:
tools.extend(executor_agent.tools)
task_prompt = f"""
You need to do the following task: {task.description}.
Expected Output: {task.expected_output}.
"""
if task.context:
context_results = [] # Use list to avoid duplicates
for context_item in task.context:
if isinstance(context_item, str):
context_results.append(f"Input Content:\n{context_item}")
elif isinstance(context_item, list):
context_results.append(f"Input Content: {' '.join(str(x) for x in context_item)}")
elif hasattr(context_item, 'result'): # Task object
if context_item.result:
context_results.append(
f"Result of previous task {context_item.name if context_item.name else context_item.description}:\n{context_item.result.raw}"
)
else:
context_results.append(
f"Previous task {context_item.name if context_item.name else context_item.description} has no result yet."
)
elif isinstance(context_item, dict) and "vector_store" in context_item:
from ..knowledge.knowledge import Knowledge
try:
# Handle both string and dict configs
cfg = context_item["vector_store"]
if isinstance(cfg, str):
cfg = json.loads(cfg)
knowledge = Knowledge(config={"vector_store": cfg}, verbose=self.verbose)
# Only use user_id as filter
db_results = knowledge.search(
task.description,
user_id=self.user_id if self.user_id else None
)
context_results.append(f"[DB Context]: {str(db_results)}")
except Exception as e:
context_results.append(f"[Vector DB Error]: {e}")
# Join unique context results
unique_contexts = list(dict.fromkeys(context_results)) # Remove duplicates
task_prompt += f"""
Context:
{' '.join(unique_contexts)}
"""
task_prompt += "Please provide only the final result of your work. Do not add any conversation or extra explanation."
if self.verbose >= 2:
logger.info(f"Executing task {task_id}: {task.description} using {executor_agent.name}")
logger.debug(f"Starting execution of task {task_id} with prompt:\n{task_prompt}")
if task.images:
def _get_multimodal_message(text_prompt, images):
content = [{"type": "text", "text": text_prompt}]
for img in images:
# If local file path for a valid image
if os.path.exists(img):
ext = os.path.splitext(img)[1].lower()
# If it's a .mp4, convert to frames
if ext == ".mp4":
frames = process_video(img, seconds_per_frame=1)
content.append({"type": "text", "text": "These are frames from the video."})
for f in frames:
content.append({
"type": "image_url",
"image_url": {"url": f"data:image/jpg;base64,{f}"}
})
else:
encoded = encode_file_to_base64(img)
content.append({
"type": "image_url",
"image_url": {
"url": f"data:image/{ext.lstrip('.')};base64,{encoded}"
}
})
else:
# Treat as a remote URL
content.append({
"type": "image_url",
"image_url": {"url": img}
})
return content
agent_output = await executor_agent.achat(
_get_multimodal_message(task_prompt, task.images),
tools=tools,
output_json=task.output_json,
output_pydantic=task.output_pydantic
)
else:
agent_output = await executor_agent.achat(
task_prompt,
tools=tools,
output_json=task.output_json,
output_pydantic=task.output_pydantic
)
if agent_output:
task_output = TaskOutput(
description=task.description,
summary=task.description[:10],
raw=agent_output,
agent=executor_agent.name,
output_format="RAW"
)
if task.output_json:
cleaned = self.clean_json_output(agent_output)
try:
parsed = json.loads(cleaned)
task_output.json_dict = parsed
task_output.output_format = "JSON"
except:
logger.warning(f"Warning: Could not parse output of task {task_id} as JSON")
logger.debug(f"Output that failed JSON parsing: {agent_output}")
if task.output_pydantic:
cleaned = self.clean_json_output(agent_output)
try:
parsed = json.loads(cleaned)
pyd_obj = task.output_pydantic(**parsed)
task_output.pydantic = pyd_obj
task_output.output_format = "Pydantic"
except:
logger.warning(f"Warning: Could not parse output of task {task_id} as Pydantic Model")
logger.debug(f"Output that failed Pydantic parsing: {agent_output}")
task.result = task_output
return task_output
else:
task.status = "failed"
return None
async def arun_task(self, task_id):
"""Async version of run_task method"""
if task_id not in self.tasks:
display_error(f"Error: Task with ID {task_id} does not exist")
return
task = self.tasks[task_id]
if task.status == "completed":
logger.info(f"Task with ID {task_id} is already completed")
return
retries = 0
while task.status != "completed" and retries < self.max_retries:
logger.debug(f"Attempt {retries+1} for task {task_id}")
if task.status in ["not started", "in progress"]:
task_output = await self.aexecute_task(task_id)
if task_output and self.completion_checker(task, task_output.raw):
task.status = "completed"
# Run execute_callback for memory operations
try:
try:
# If a loop is already running, just create the task
loop = asyncio.get_running_loop()
loop.create_task(task.execute_callback(task_output))
except RuntimeError:
# Otherwise, create and set a new loop, and run the callback
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.create_task(task.execute_callback(task_output))
except Exception as e:
logger.error(f"Error executing memory callback for task {task_id}: {e}")
logger.exception(e)
# Run task callback if exists
if task.callback:
try:
if asyncio.iscoroutinefunction(task.callback):
if asyncio.get_event_loop().is_running():
asyncio.create_task(task.callback(task_output))
else:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(task.callback(task_output))
else:
task.callback(task_output)
except Exception as e:
logger.error(f"Error executing task callback for task {task_id}: {e}")
logger.exception(e)
self.save_output_to_file(task, task_output)
if self.verbose >= 1:
logger.info(f"Task {task_id} completed successfully.")
else:
task.status = "in progress"
if self.verbose >= 1:
logger.info(f"Task {task_id} not completed, retrying")
await asyncio.sleep(1)
retries += 1
else:
if task.status == "failed":
logger.info("Task is failed, resetting to in-progress for another try...")
task.status = "in progress"
else:
logger.info("Invalid Task status")
break
if retries == self.max_retries and task.status != "completed":
logger.info(f"Task {task_id} failed after {self.max_retries} retries.")
async def arun_all_tasks(self):
"""Async version of run_all_tasks method"""
process = Process(
tasks=self.tasks,
agents=self.agents,
manager_llm=self.manager_llm,
verbose=self.verbose,
max_iter=self.max_iter
)
if self.process == "workflow":
# Collect all tasks that should run in parallel
parallel_tasks = []
async for task_id in process.aworkflow():
if self.tasks[task_id].async_execution and self.tasks[task_id].is_start:
parallel_tasks.append(task_id)
elif parallel_tasks:
# Execute collected parallel tasks
await asyncio.gather(*[self.arun_task(t) for t in parallel_tasks])
parallel_tasks = []
# Run the current non-parallel task
if self.tasks[task_id].async_execution:
await self.arun_task(task_id)
else:
self.run_task(task_id)
# Execute any remaining parallel tasks
if parallel_tasks:
await asyncio.gather(*[self.arun_task(t) for t in parallel_tasks])
elif self.process == "sequential":
async for task_id in process.asequential():
if self.tasks[task_id].async_execution:
await self.arun_task(task_id)
else:
self.run_task(task_id)
elif self.process == "hierarchical":
async for task_id in process.ahierarchical():
if isinstance(task_id, Task):
task_id = self.add_task(task_id)
if self.tasks[task_id].async_execution:
await self.arun_task(task_id)
else:
self.run_task(task_id)
async def astart(self, content=None, **kwargs):
"""Async version of start method"""
if content:
# Add content to context of all tasks
for task in self.tasks.values():
if isinstance(content, (str, list)):
if not task.context:
task.context = []
task.context.append(content)
await self.arun_all_tasks()
return {
"task_status": self.get_all_tasks_status(),
"task_results": {task_id: self.get_task_result(task_id) for task_id in self.tasks}
}
def save_output_to_file(self, task, task_output):
if task.output_file:
try:
if task.create_directory:
os.makedirs(os.path.dirname(task.output_file), exist_ok=True)
with open(task.output_file, "w") as f:
f.write(str(task_output))
if self.verbose >= 1:
logger.info(f"Task output saved to {task.output_file}")
except Exception as e:
display_error(f"Error saving task output to file: {e}")
def execute_task(self, task_id):
"""Synchronous version of execute_task method"""
if task_id not in self.tasks:
display_error(f"Error: Task with ID {task_id} does not exist")
return
task = self.tasks[task_id]
logger.info(f"Starting execution of task {task_id}")
logger.info(f"Task config: {task.config}")
# Initialize memory before task execution
if not task.memory:
task.memory = task.initialize_memory()
logger.info(f"Task memory status: {'Initialized' if task.memory else 'Not initialized'}")
# Only import multimodal dependencies if task has images
if task.images and task.status == "not started":
try:
import cv2
import base64
from moviepy import VideoFileClip
except ImportError as e:
display_error(f"Error: Missing required dependencies for image/video processing: {e}")
display_error("Please install with: pip install opencv-python moviepy")
task.status = "failed"
return None
if task.status == "not started":
task.status = "in progress"
executor_agent = task.agent
task_prompt = f"""
You need to do the following task: {task.description}.
Expected Output: {task.expected_output}.
"""
if task.context:
context_results = [] # Use list to avoid duplicates
for context_item in task.context:
if isinstance(context_item, str):
context_results.append(f"Input Content:\n{context_item}")
elif isinstance(context_item, list):
context_results.append(f"Input Content: {' '.join(str(x) for x in context_item)}")
elif hasattr(context_item, 'result'): # Task object
if context_item.result:
context_results.append(
f"Result of previous task {context_item.name if context_item.name else context_item.description}:\n{context_item.result.raw}"
)
else:
context_results.append(
f"Previous task {context_item.name if context_item.name else context_item.description} has no result yet."
)
elif isinstance(context_item, dict) and "vector_store" in context_item:
from ..knowledge.knowledge import Knowledge
try:
# Handle both string and dict configs
cfg = context_item["vector_store"]
if isinstance(cfg, str):
cfg = json.loads(cfg)
knowledge = Knowledge(config={"vector_store": cfg}, verbose=self.verbose)
# Only use user_id as filter
db_results = knowledge.search(
task.description,
user_id=self.user_id if self.user_id else None
)
context_results.append(f"[DB Context]: {str(db_results)}")
except Exception as e:
context_results.append(f"[Vector DB Error]: {e}")
# Join unique context results
unique_contexts = list(dict.fromkeys(context_results)) # Remove duplicates
task_prompt += f"""
Context:
{' '.join(unique_contexts)}
"""
# Add memory context if available
if task.memory:
try:
memory_context = task.memory.build_context_for_task(task.description)
if memory_context:
task_prompt += f"\n\nRelevant memory context:\n{memory_context}"
except Exception as e:
logger.error(f"Error getting memory context: {e}")
task_prompt += "Please provide only the final result of your work. Do not add any conversation or extra explanation."
if self.verbose >= 2:
logger.info(f"Executing task {task_id}: {task.description} using {executor_agent.name}")
logger.debug(f"Starting execution of task {task_id} with prompt:\n{task_prompt}")
if task.images:
def _get_multimodal_message(text_prompt, images):
content = [{"type": "text", "text": text_prompt}]
for img in images:
# If local file path for a valid image
if os.path.exists(img):
ext = os.path.splitext(img)[1].lower()
# If it's a .mp4, convert to frames
if ext == ".mp4":
frames = process_video(img, seconds_per_frame=1)
content.append({"type": "text", "text": "These are frames from the video."})
for f in frames:
content.append({
"type": "image_url",
"image_url": {"url": f"data:image/jpg;base64,{f}"}
})
else:
encoded = encode_file_to_base64(img)
content.append({
"type": "image_url",
"image_url": {
"url": f"data:image/{ext.lstrip('.')};base64,{encoded}"
}
})
else:
# Treat as a remote URL
content.append({
"type": "image_url",
"image_url": {"url": img}
})
return content
agent_output = executor_agent.chat(
_get_multimodal_message(task_prompt, task.images),
tools=task.tools,
output_json=task.output_json,
output_pydantic=task.output_pydantic
)
else:
agent_output = executor_agent.chat(
task_prompt,
tools=task.tools,
output_json=task.output_json,
output_pydantic=task.output_pydantic
)
if agent_output:
# Store the response in memory
if task.memory:
try:
task.store_in_memory(
content=agent_output,
agent_name=executor_agent.name,
task_id=task_id
)
except Exception as e:
logger.error(f"Failed to store agent output in memory: {e}")
task_output = TaskOutput(
description=task.description,
summary=task.description[:10],
raw=agent_output,
agent=executor_agent.name,
output_format="RAW"
)
if task.output_json:
cleaned = self.clean_json_output(agent_output)
try:
parsed = json.loads(cleaned)
task_output.json_dict = parsed
task_output.output_format = "JSON"
except:
logger.warning(f"Warning: Could not parse output of task {task_id} as JSON")
logger.debug(f"Output that failed JSON parsing: {agent_output}")
if task.output_pydantic:
cleaned = self.clean_json_output(agent_output)
try:
parsed = json.loads(cleaned)
pyd_obj = task.output_pydantic(**parsed)
task_output.pydantic = pyd_obj
task_output.output_format = "Pydantic"
except:
logger.warning(f"Warning: Could not parse output of task {task_id} as Pydantic Model")
logger.debug(f"Output that failed Pydantic parsing: {agent_output}")
task.result = task_output
return task_output
else:
task.status = "failed"
return None
def run_task(self, task_id):
"""Synchronous version of run_task method"""
if task_id not in self.tasks:
display_error(f"Error: Task with ID {task_id} does not exist")
return
task = self.tasks[task_id]
if task.status == "completed":
logger.info(f"Task with ID {task_id} is already completed")
return
retries = 0
while task.status != "completed" and retries < self.max_retries:
logger.debug(f"Attempt {retries+1} for task {task_id}")
if task.status in ["not started", "in progress"]:
task_output = self.execute_task(task_id)
if task_output and self.completion_checker(task, task_output.raw):
task.status = "completed"
# Run execute_callback for memory operations
try:
try:
# If a loop is already running, just create the task
loop = asyncio.get_running_loop()
loop.create_task(task.execute_callback(task_output))
except RuntimeError:
# Otherwise, create and set a new loop, and run the callback
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.create_task(task.execute_callback(task_output))
except Exception as e:
logger.error(f"Error executing memory callback for task {task_id}: {e}")
logger.exception(e)
# Run task callback if exists
if task.callback:
try:
if asyncio.iscoroutinefunction(task.callback):
if asyncio.get_event_loop().is_running():
asyncio.create_task(task.callback(task_output))
else:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(task.callback(task_output))
else:
task.callback(task_output)
except Exception as e:
logger.error(f"Error executing task callback for task {task_id}: {e}")
logger.exception(e)
self.save_output_to_file(task, task_output)
if self.verbose >= 1:
logger.info(f"Task {task_id} completed successfully.")
else:
task.status = "in progress"
if self.verbose >= 1:
logger.info(f"Task {task_id} not completed, retrying")
time.sleep(1)
retries += 1
else:
if task.status == "failed":
logger.info("Task is failed, resetting to in-progress for another try...")
task.status = "in progress"
else:
logger.info("Invalid Task status")
break
if retries == self.max_retries and task.status != "completed":
logger.info(f"Task {task_id} failed after {self.max_retries} retries.")
def run_all_tasks(self):
"""Synchronous version of run_all_tasks method"""
process = Process(
tasks=self.tasks,
agents=self.agents,
manager_llm=self.manager_llm,
verbose=self.verbose,
max_iter=self.max_iter
)
if self.process == "workflow":
for task_id in process.workflow():
self.run_task(task_id)
elif self.process == "sequential":
for task_id in process.sequential():
self.run_task(task_id)
elif self.process == "hierarchical":
for task_id in process.hierarchical():
if isinstance(task_id, Task):
task_id = self.add_task(task_id)
self.run_task(task_id)
def get_task_status(self, task_id):
if task_id in self.tasks:
return self.tasks[task_id].status
return None
def get_all_tasks_status(self):
return {task_id: self.tasks[task_id].status for task_id in self.tasks}
def get_task_result(self, task_id):
if task_id in self.tasks:
return self.tasks[task_id].result
return None
def get_task_details(self, task_id):
if task_id in self.tasks:
return str(self.tasks[task_id])
return None
def get_agent_details(self, agent_name):
agent = [task.agent for task in self.tasks.values() if task.agent and task.agent.name == agent_name]
if agent:
return str(agent[0])
return None
def start(self, content=None, **kwargs):
"""Start agent execution with optional content and config"""
if content:
# Add content to context of all tasks
for task in self.tasks.values():
if isinstance(content, (str, list)):
# If context is empty, initialize it
if not task.context:
task.context = []
# Add content to context
task.context.append(content)
# Run tasks as before
self.run_all_tasks()
return {
"task_status": self.get_all_tasks_status(),
"task_results": {task_id: self.get_task_result(task_id) for task_id in self.tasks}
}
def set_state(self, key: str, value: Any) -> None:
"""Set a state value"""
self._state[key] = value
def get_state(self, key: str, default: Any = None) -> Any:
"""Get a state value"""
return self._state.get(key, default)
def update_state(self, updates: Dict) -> None:
"""Update multiple state values"""
self._state.update(updates)
def clear_state(self) -> None:
"""Clear all state values"""
self._state.clear()
-823
View File
@@ -1,823 +0,0 @@
import logging
import os
import warnings
from typing import Any, Dict, List, Optional, Union, Literal, Callable
from pydantic import BaseModel
import time
import json
from ..main import (
display_error,
display_tool_call,
display_instruction,
display_interaction,
display_generating,
display_self_reflection,
ReflectionOutput,
)
from rich.console import Console
from rich.live import Live
class LLMContextLengthExceededException(Exception):
"""Raised when LLM context length is exceeded"""
def __init__(self, message: str):
self.message = message
super().__init__(self.message)
def _is_context_limit_error(self, error_message: str) -> bool:
"""Check if error is related to context length"""
context_limit_phrases = [
"maximum context length",
"context window is too long",
"context length exceeded",
"context_length_exceeded"
]
return any(phrase in error_message.lower() for phrase in context_limit_phrases)
class LLM:
"""
Easy to use wrapper for language models. Supports multiple providers like OpenAI,
Anthropic, and others through LiteLLM.
"""
# Default window sizes for different models (75% of actual to be safe)
MODEL_WINDOWS = {
# OpenAI
"gpt-4": 6144, # 8,192 actual
"gpt-4o": 96000, # 128,000 actual
"gpt-4o-mini": 96000, # 128,000 actual
"gpt-4-turbo": 96000, # 128,000 actual
"o1-preview": 96000, # 128,000 actual
"o1-mini": 96000, # 128,000 actual
# Anthropic
"claude-3-5-sonnet": 12288, # 16,384 actual
"claude-3-sonnet": 12288, # 16,384 actual
"claude-3-opus": 96000, # 128,000 actual
"claude-3-haiku": 96000, # 128,000 actual
# Gemini
"gemini-2.0-flash": 786432, # 1,048,576 actual
"gemini-1.5-pro": 1572864, # 2,097,152 actual
"gemini-1.5-flash": 786432, # 1,048,576 actual
"gemini-1.5-flash-8b": 786432, # 1,048,576 actual
# Deepseek
"deepseek-chat": 96000, # 128,000 actual
# Groq
"gemma2-9b-it": 6144, # 8,192 actual
"gemma-7b-it": 6144, # 8,192 actual
"llama3-70b-8192": 6144, # 8,192 actual
"llama3-8b-8192": 6144, # 8,192 actual
"mixtral-8x7b-32768": 24576, # 32,768 actual
"llama-3.3-70b-versatile": 96000, # 128,000 actual
"llama-3.3-70b-instruct": 96000, # 128,000 actual
# Other llama models
"llama-3.1-70b-versatile": 98304, # 131,072 actual
"llama-3.1-8b-instant": 98304, # 131,072 actual
"llama-3.2-1b-preview": 6144, # 8,192 actual
"llama-3.2-3b-preview": 6144, # 8,192 actual
"llama-3.2-11b-text-preview": 6144, # 8,192 actual
"llama-3.2-90b-text-preview": 6144 # 8,192 actual
}
def __init__(
self,
model: str,
timeout: Optional[int] = None,
temperature: Optional[float] = None,
top_p: Optional[float] = None,
n: Optional[int] = None,
max_tokens: Optional[int] = None,
presence_penalty: Optional[float] = None,
frequency_penalty: Optional[float] = None,
logit_bias: Optional[Dict[int, float]] = None,
response_format: Optional[Dict[str, Any]] = None,
seed: Optional[int] = None,
logprobs: Optional[bool] = None,
top_logprobs: Optional[int] = None,
api_version: Optional[str] = None,
stop_phrases: Optional[Union[str, List[str]]] = None,
api_key: Optional[str] = None,
base_url: Optional[str] = None,
events: List[Any] = [],
**extra_settings
):
try:
import litellm
# Set litellm options globally
litellm.set_verbose = False
litellm.success_callback = []
litellm._async_success_callback = []
litellm.callbacks = []
# Additional logging suppression
litellm.suppress_debug_messages = True
logging.getLogger("litellm.utils").setLevel(logging.WARNING)
logging.getLogger("litellm.main").setLevel(logging.WARNING)
except ImportError:
raise ImportError(
"LiteLLM is required but not installed. "
"Please install with: pip install 'praisonaiagents[llm]'"
)
self.model = model
self.timeout = timeout
self.temperature = temperature
self.top_p = top_p
self.n = n
self.max_tokens = max_tokens
self.presence_penalty = presence_penalty
self.frequency_penalty = frequency_penalty
self.logit_bias = logit_bias
self.response_format = response_format
self.seed = seed
self.logprobs = logprobs
self.top_logprobs = top_logprobs
self.api_version = api_version
self.stop_phrases = stop_phrases
self.api_key = api_key
self.base_url = base_url
self.events = events
self.extra_settings = extra_settings
self.console = Console()
self.chat_history = []
self.verbose = extra_settings.get('verbose', True)
self.markdown = extra_settings.get('markdown', True)
self.self_reflect = extra_settings.get('self_reflect', False)
self.max_reflect = extra_settings.get('max_reflect', 3)
self.min_reflect = extra_settings.get('min_reflect', 1)
# Enable error dropping for cleaner output
litellm.drop_params = True
self._setup_event_tracking(events)
def get_response(
self,
prompt: Union[str, List[Dict]],
system_prompt: Optional[str] = None,
chat_history: Optional[List[Dict]] = None,
temperature: float = 0.2,
tools: Optional[List[Any]] = None,
output_json: Optional[BaseModel] = None,
output_pydantic: Optional[BaseModel] = None,
verbose: bool = True,
markdown: bool = True,
self_reflect: bool = False,
max_reflect: int = 3,
min_reflect: int = 1,
console: Optional[Console] = None,
agent_name: Optional[str] = None,
agent_role: Optional[str] = None,
agent_tools: Optional[List[str]] = None,
execute_tool_fn: Optional[Callable] = None,
**kwargs
) -> str:
"""Enhanced get_response with all OpenAI-like features"""
try:
import litellm
# Disable litellm debug messages
litellm.set_verbose = False
# Build messages list
messages = []
if system_prompt:
if output_json:
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_json.model_json_schema())}"
elif output_pydantic:
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_pydantic.model_json_schema())}"
messages.append({"role": "system", "content": system_prompt})
if chat_history:
messages.extend(chat_history)
# Handle prompt modifications for JSON output
original_prompt = prompt
if output_json or output_pydantic:
if isinstance(prompt, str):
prompt += "\nReturn ONLY a valid JSON object. No other text or explanation."
elif isinstance(prompt, list):
for item in prompt:
if item["type"] == "text":
item["text"] += "\nReturn ONLY a valid JSON object. No other text or explanation."
break
# Add prompt to messages
if isinstance(prompt, list):
messages.append({"role": "user", "content": prompt})
else:
messages.append({"role": "user", "content": prompt})
start_time = time.time()
reflection_count = 0
while True:
try:
if verbose:
display_text = prompt
if isinstance(prompt, list):
display_text = next((item["text"] for item in prompt if item["type"] == "text"), "")
if display_text and str(display_text).strip():
display_instruction(
f"Agent {agent_name} is processing prompt: {display_text}",
console=console,
agent_name=agent_name,
agent_role=agent_role,
agent_tools=agent_tools
)
# Get response from LiteLLM
start_time = time.time()
if verbose:
with Live(display_generating("", start_time), console=console, refresh_per_second=4) as live:
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
response_text += content
live.update(display_generating(response_text, start_time))
else:
# Non-verbose mode, just collect the response
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
response_text = response_text.strip()
# Get final completion to check for tool calls
final_response = litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=False, # No streaming for tool call check
**kwargs
)
tool_calls = final_response["choices"][0]["message"].get("tool_calls")
# Handle tool calls
if tool_calls and execute_tool_fn:
messages.append({
"role": "assistant",
"content": response_text,
"tool_calls": tool_calls
})
for tool_call in tool_calls:
function_name = tool_call["function"]["name"]
arguments = json.loads(tool_call["function"]["arguments"])
if verbose:
display_tool_call(f"Agent {agent_name} is calling function '{function_name}' with arguments: {arguments}", console=console)
tool_result = execute_tool_fn(function_name, arguments)
if tool_result:
if verbose:
display_tool_call(f"Function '{function_name}' returned: {tool_result}", console=console)
messages.append({
"role": "tool",
"tool_call_id": tool_call["id"],
"content": json.dumps(tool_result)
})
else:
messages.append({
"role": "tool",
"tool_call_id": tool_call["id"],
"content": "Function returned an empty output"
})
# Get response after tool calls with streaming
if verbose:
with Live(display_generating("", start_time), console=console, refresh_per_second=4) as live:
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
response_text += content
live.update(display_generating(response_text, start_time))
else:
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
response_text = response_text.strip()
# Handle output formatting
if output_json or output_pydantic:
self.chat_history.append({"role": "user", "content": original_prompt})
self.chat_history.append({"role": "assistant", "content": response_text})
if verbose:
display_interaction(original_prompt, response_text, markdown=markdown,
generation_time=time.time() - start_time, console=console)
return response_text
if not self_reflect:
if verbose:
display_interaction(original_prompt, response_text, markdown=markdown,
generation_time=time.time() - start_time, console=console)
return response_text
# Handle self-reflection
reflection_prompt = f"""
Reflect on your previous response: '{response_text}'.
Identify any flaws, improvements, or actions.
Provide a "satisfactory" status ('yes' or 'no').
Output MUST be JSON with 'reflection' and 'satisfactory'.
"""
reflection_messages = messages + [
{"role": "assistant", "content": response_text},
{"role": "user", "content": reflection_prompt}
]
# Get reflection response with streaming
if verbose:
with Live(display_generating("", start_time), console=console, refresh_per_second=4) as live:
reflection_text = ""
for chunk in litellm.completion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
response_format={"type": "json_object"}
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
reflection_text += content
live.update(display_generating(reflection_text, start_time))
else:
reflection_text = ""
for chunk in litellm.completion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
response_format={"type": "json_object"}
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
reflection_text += chunk.choices[0].delta.content
try:
reflection_data = json.loads(reflection_text)
satisfactory = reflection_data.get("satisfactory", "no").lower() == "yes"
if verbose:
display_self_reflection(
f"Agent {agent_name} self reflection: reflection='{reflection_data['reflection']}' satisfactory='{reflection_data['satisfactory']}'",
console=console
)
if satisfactory and reflection_count >= min_reflect - 1:
if verbose:
display_interaction(prompt, response_text, markdown=markdown,
generation_time=time.time() - start_time, console=console)
return response_text
if reflection_count >= max_reflect - 1:
if verbose:
display_interaction(prompt, response_text, markdown=markdown,
generation_time=time.time() - start_time, console=console)
return response_text
reflection_count += 1
messages.extend([
{"role": "assistant", "content": response_text},
{"role": "user", "content": reflection_prompt},
{"role": "assistant", "content": reflection_text},
{"role": "user", "content": "Now regenerate your response using the reflection you made"}
])
continue
except json.JSONDecodeError:
reflection_count += 1
if reflection_count >= max_reflect:
return response_text
continue
except Exception as e:
display_error(f"Error in LLM response: {str(e)}")
return None
except Exception as error:
display_error(f"Error in get_response: {str(error)}")
raise
async def get_response_async(
self,
prompt: Union[str, List[Dict]],
system_prompt: Optional[str] = None,
chat_history: Optional[List[Dict]] = None,
temperature: float = 0.2,
tools: Optional[List[Any]] = None,
output_json: Optional[BaseModel] = None,
output_pydantic: Optional[BaseModel] = None,
verbose: bool = True,
markdown: bool = True,
self_reflect: bool = False,
max_reflect: int = 3,
min_reflect: int = 1,
console: Optional[Console] = None,
agent_name: Optional[str] = None,
agent_role: Optional[str] = None,
agent_tools: Optional[List[str]] = None,
execute_tool_fn: Optional[Callable] = None,
**kwargs
) -> str:
"""Async version of get_response with identical functionality."""
try:
import litellm
litellm.set_verbose = False
# Build messages list
messages = []
if system_prompt:
if output_json:
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_json.model_json_schema())}"
elif output_pydantic:
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_pydantic.model_json_schema())}"
messages.append({"role": "system", "content": system_prompt})
if chat_history:
messages.extend(chat_history)
# Handle prompt modifications for JSON output
original_prompt = prompt
if output_json or output_pydantic:
if isinstance(prompt, str):
prompt += "\nReturn ONLY a valid JSON object. No other text or explanation."
elif isinstance(prompt, list):
for item in prompt:
if item["type"] == "text":
item["text"] += "\nReturn ONLY a valid JSON object. No other text or explanation."
break
# Add prompt to messages
if isinstance(prompt, list):
messages.append({"role": "user", "content": prompt})
else:
messages.append({"role": "user", "content": prompt})
start_time = time.time()
reflection_count = 0
# Format tools for LiteLLM
formatted_tools = None
if tools:
logging.info(f"Starting tool formatting for {len(tools)} tools")
formatted_tools = []
for tool in tools:
logging.info(f"Processing tool: {tool.__name__ if hasattr(tool, '__name__') else str(tool)}")
if hasattr(tool, '__name__'):
tool_name = tool.__name__
tool_doc = tool.__doc__ or "No description available"
# Get function signature
import inspect
sig = inspect.signature(tool)
logging.debug(f"Tool signature: {sig}")
params = {}
required = []
for name, param in sig.parameters.items():
logging.debug(f"Processing parameter: {name} with annotation: {param.annotation}")
param_type = "string"
if param.annotation != inspect.Parameter.empty:
if param.annotation == int:
param_type = "integer"
elif param.annotation == float:
param_type = "number"
elif param.annotation == bool:
param_type = "boolean"
elif param.annotation == Dict:
param_type = "object"
elif param.annotation == List:
param_type = "array"
elif hasattr(param.annotation, "__name__"):
param_type = param.annotation.__name__.lower()
params[name] = {"type": param_type}
if param.default == inspect.Parameter.empty:
required.append(name)
logging.debug(f"Generated parameters: {params}")
logging.debug(f"Required parameters: {required}")
tool_def = {
"type": "function",
"function": {
"name": tool_name,
"description": tool_doc,
"parameters": {
"type": "object",
"properties": params,
"required": required
}
}
}
# Ensure tool definition is JSON serializable
print(f"Generated tool definition: {tool_def}")
try:
json.dumps(tool_def) # Test serialization
logging.info(f"Generated tool definition: {tool_def}")
formatted_tools.append(tool_def)
except TypeError as e:
logging.error(f"Tool definition not JSON serializable: {e}")
continue
# Validate final tools list
if formatted_tools:
try:
json.dumps(formatted_tools) # Final serialization check
logging.info(f"Final formatted tools: {json.dumps(formatted_tools, indent=2)}")
except TypeError as e:
logging.error(f"Final tools list not JSON serializable: {e}")
formatted_tools = None
response_text = ""
if verbose:
# ----------------------------------------------------
# 1) Make the streaming call WITHOUT tools
# ----------------------------------------------------
async for chunk in await litellm.acompletion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
print("\033[K", end="\r")
print(f"Generating... {time.time() - start_time:.1f}s", end="\r")
else:
# Non-verbose streaming call, still no tools
async for chunk in await litellm.acompletion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
response_text = response_text.strip()
# ----------------------------------------------------
# 2) If tool calls are needed, do a non-streaming call
# ----------------------------------------------------
if tools and execute_tool_fn:
# Next call with tools if needed
tool_response = await litellm.acompletion(
model=self.model,
messages=messages,
temperature=temperature,
stream=False,
tools=formatted_tools, # We safely pass tools here
**kwargs
)
# handle tool_calls from tool_response as usual...
tool_calls = tool_response.choices[0].message.get("tool_calls")
if tool_calls:
messages.append({
"role": "assistant",
"content": response_text,
"tool_calls": tool_calls
})
for tool_call in tool_calls:
function_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
if verbose:
display_tool_call(f"Agent {agent_name} is calling function '{function_name}' with arguments: {arguments}", console=console)
tool_result = await execute_tool_fn(function_name, arguments)
if tool_result:
if verbose:
display_tool_call(f"Function '{function_name}' returned: {tool_result}", console=console)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(tool_result)
})
else:
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": "Function returned an empty output"
})
# Get response after tool calls with streaming
response_text = ""
if verbose:
async for chunk in await litellm.acompletion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
tools=formatted_tools,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
response_text += content
print("\033[K", end="\r")
print(f"Reflecting... {time.time() - start_time:.1f}s", end="\r")
else:
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
response_text = response_text.strip()
# Handle output formatting
if output_json or output_pydantic:
self.chat_history.append({"role": "user", "content": original_prompt})
self.chat_history.append({"role": "assistant", "content": response_text})
if verbose:
display_interaction(original_prompt, response_text, markdown=markdown,
generation_time=time.time() - start_time, console=console)
return response_text
if not self_reflect:
if verbose:
display_interaction(original_prompt, response_text, markdown=markdown,
generation_time=time.time() - start_time, console=console)
return response_text
# Handle self-reflection
reflection_prompt = f"""
Reflect on your previous response: '{response_text}'.
Identify any flaws, improvements, or actions.
Provide a "satisfactory" status ('yes' or 'no').
Output MUST be JSON with 'reflection' and 'satisfactory'.
"""
reflection_messages = messages + [
{"role": "assistant", "content": response_text},
{"role": "user", "content": reflection_prompt}
]
# Get reflection response
reflection_text = ""
if verbose:
async for chunk in await litellm.acompletion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
response_format={"type": "json_object"},
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
reflection_text += content
print("\033[K", end="\r")
print(f"Reflecting... {time.time() - start_time:.1f}s", end="\r")
else:
async for chunk in await litellm.acompletion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
response_format={"type": "json_object"},
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
reflection_text += chunk.choices[0].delta.content
while True: # Add loop for reflection handling
try:
reflection_data = json.loads(reflection_text)
satisfactory = reflection_data.get("satisfactory", "no").lower() == "yes"
if verbose:
display_self_reflection(
f"Agent {agent_name} self reflection: reflection='{reflection_data['reflection']}' satisfactory='{reflection_data['satisfactory']}'",
console=console
)
if satisfactory and reflection_count >= min_reflect - 1:
if verbose:
display_interaction(prompt, response_text, markdown=markdown,
generation_time=time.time() - start_time, console=console)
return response_text
if reflection_count >= max_reflect - 1:
if verbose:
display_interaction(prompt, response_text, markdown=markdown,
generation_time=time.time() - start_time, console=console)
return response_text
reflection_count += 1
messages.extend([
{"role": "assistant", "content": response_text},
{"role": "user", "content": reflection_prompt},
{"role": "assistant", "content": reflection_text},
{"role": "user", "content": "Now regenerate your response using the reflection you made"}
])
continue # Now properly in a loop
except json.JSONDecodeError:
reflection_count += 1
if reflection_count >= max_reflect:
return response_text
continue # Now properly in a loop
except Exception as error:
if LLMContextLengthExceededException(str(error))._is_context_limit_error(str(error)):
raise LLMContextLengthExceededException(str(error))
display_error(f"Error in get_response_async: {str(error)}")
raise
def can_use_tools(self) -> bool:
"""Check if this model can use tool functions"""
try:
import litellm
allowed_params = litellm.get_supported_openai_params(model=self.model)
return "response_format" in allowed_params
except ImportError:
raise ImportError(
"LiteLLM is required but not installed. "
"Please install it with: pip install 'praisonaiagents[llm]'"
)
except:
return False
def can_use_stop_words(self) -> bool:
"""Check if this model supports stop words"""
try:
import litellm
allowed_params = litellm.get_supported_openai_params(model=self.model)
return "stop" in allowed_params
except ImportError:
raise ImportError(
"LiteLLM is required but not installed. "
"Please install it with: pip install 'praisonaiagents[llm]'"
)
except:
return False
def get_context_size(self) -> int:
"""Get safe input size limit for this model"""
for model_prefix, size in self.MODEL_WINDOWS.items():
if self.model.startswith(model_prefix):
return size
return 4000 # Safe default
def _setup_event_tracking(self, events: List[Any]) -> None:
"""Setup callback functions for tracking model usage"""
try:
import litellm
except ImportError:
raise ImportError(
"LiteLLM is required but not installed. "
"Please install it with: pip install 'praisonaiagents[llm]'"
)
event_types = [type(event) for event in events]
# Remove old events of same type
for event in litellm.success_callback[:]:
if type(event) in event_types:
litellm.success_callback.remove(event)
for event in litellm._async_success_callback[:]:
if type(event) in event_types:
litellm._async_success_callback.remove(event)
litellm.callbacks = events
-650
View File
@@ -1,650 +0,0 @@
import logging
import asyncio
from typing import Dict, Optional, List, Any, AsyncGenerator
from pydantic import BaseModel
from ..agent.agent import Agent
from ..task.task import Task
from ..main import display_error, client
import csv
import os
class LoopItems(BaseModel):
items: List[Any]
class Process:
def __init__(self, tasks: Dict[str, Task], agents: List[Agent], manager_llm: Optional[str] = None, verbose: bool = False, max_iter: int = 10):
self.tasks = tasks
self.agents = agents
self.manager_llm = manager_llm
self.verbose = verbose
self.max_iter = max_iter
async def aworkflow(self) -> AsyncGenerator[str, None]:
"""Async version of workflow method"""
current_iter = 0 # Track how many times we've looped
# Build workflow relationships first
for task in self.tasks.values():
if task.next_tasks:
for next_task_name in task.next_tasks:
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
if next_task:
next_task.previous_tasks.append(task.name)
# Find start task
start_task = None
for task_id, task in self.tasks.items():
if task.is_start:
start_task = task
break
if not start_task:
start_task = list(self.tasks.values())[0]
logging.info("No start task marked, using first task")
current_task = start_task
visited_tasks = set()
loop_data = {} # Store loop-specific data
while current_task:
current_iter += 1
if current_iter > self.max_iter:
logging.info(f"Max iteration limit {self.max_iter} reached, ending workflow.")
break
task_id = current_task.id
logging.info(f"Executing workflow task: {current_task.name if current_task.name else task_id}")
# Add context from previous tasks to description
if current_task.previous_tasks or current_task.context:
context = "\nInput data from previous tasks:"
# Add data from previous tasks in workflow
for prev_name in current_task.previous_tasks:
prev_task = next((t for t in self.tasks.values() if t.name == prev_name), None)
if prev_task and prev_task.result:
# Handle loop data
if current_task.task_type == "loop":
# # create a loop manager Agent
# loop_manager = Agent(
# name="Loop Manager",
# role="Loop data processor",
# goal="Process loop data and convert it to list format",
# backstory="Expert at handling loop data and converting it to proper format",
# llm=self.manager_llm,
# verbose=self.verbose,
# markdown=True
# )
# # get the loop data convert it to list using calling Agent class chat
# loop_prompt = f"""
# Process this data into a list format:
# {prev_task.result.raw}
# Return a JSON object with an 'items' array containing the items to process.
# """
# if current_task.async_execution:
# loop_data_str = await loop_manager.achat(
# prompt=loop_prompt,
# output_json=LoopItems
# )
# else:
# loop_data_str = loop_manager.chat(
# prompt=loop_prompt,
# output_json=LoopItems
# )
# try:
# # The response will already be parsed into LoopItems model
# loop_data[f"loop_{current_task.name}"] = {
# "items": loop_data_str.items,
# "index": 0,
# "remaining": len(loop_data_str.items)
# }
# context += f"\nCurrent loop item: {loop_data_str.items[0]}"
# except Exception as e:
# display_error(f"Failed to process loop data: {e}")
# context += f"\n{prev_name}: {prev_task.result.raw}"
context += f"\n{prev_name}: {prev_task.result.raw}"
else:
context += f"\n{prev_name}: {prev_task.result.raw}"
# Add data from context tasks
if current_task.context:
for ctx_task in current_task.context:
if ctx_task.result and ctx_task.name != current_task.name:
context += f"\n{ctx_task.name}: {ctx_task.result.raw}"
# Update task description with context
current_task.description = current_task.description + context
# Execute task using existing run_task method
yield task_id
visited_tasks.add(task_id)
# Reset completed task to "not started" so it can run again
if self.tasks[task_id].status == "completed":
logging.debug(f"Task {task_id} was completed, resetting to 'not started' for next iteration.")
self.tasks[task_id].status = "not started"
# Handle loop progression
if current_task.task_type == "loop":
loop_key = f"loop_{current_task.name}"
if loop_key in loop_data:
loop_info = loop_data[loop_key]
loop_info["index"] += 1
has_more = loop_info["remaining"] > 0
# Update result to trigger correct condition
if current_task.result:
result = current_task.result.raw
if has_more:
result += "\nmore"
else:
result += "\ndone"
current_task.result.raw = result
# Determine next task based on result
next_task = None
if current_task and current_task.result:
if current_task.task_type in ["decision", "loop"]:
# MINIMAL CHANGE: use pydantic decision if present
decision_str = current_task.result.raw.lower()
if current_task.result.pydantic and hasattr(current_task.result.pydantic, "decision"):
decision_str = current_task.result.pydantic.decision.lower()
# Check conditions
for condition, tasks in current_task.condition.items():
if condition.lower() == decision_str:
# Handle both list and direct string values
task_value = tasks[0] if isinstance(tasks, list) else tasks
if not task_value or task_value == "exit":
logging.info("Workflow exit condition met, ending workflow")
current_task = None
break
next_task_name = task_value
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
# For loops, allow revisiting the same task
if next_task and next_task.id == current_task.id:
visited_tasks.discard(current_task.id)
break
if not next_task and current_task and current_task.next_tasks:
next_task_name = current_task.next_tasks[0]
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
current_task = next_task
if not current_task:
logging.info("Workflow execution completed")
break
async def asequential(self) -> AsyncGenerator[str, None]:
"""Async version of sequential method"""
for task_id in self.tasks:
if self.tasks[task_id].status != "completed":
yield task_id
async def ahierarchical(self) -> AsyncGenerator[str, None]:
"""Async version of hierarchical method"""
logging.debug(f"Starting hierarchical task execution with {len(self.tasks)} tasks")
manager_agent = Agent(
name="Manager",
role="Project manager",
goal="Manage the entire flow of tasks and delegate them to the right agent",
backstory="Expert project manager to coordinate tasks among agents",
llm=self.manager_llm,
verbose=self.verbose,
markdown=True,
self_reflect=False
)
class ManagerInstructions(BaseModel):
task_id: int
agent_name: str
action: str
manager_task = Task(
name="manager_task",
description="Decide the order of tasks and which agent executes them",
expected_output="All tasks completed successfully",
agent=manager_agent
)
manager_task_id = yield manager_task
logging.info(f"Created manager task with ID {manager_task_id}")
completed_count = 0
total_tasks = len(self.tasks) - 1
logging.info(f"Need to complete {total_tasks} tasks (excluding manager task)")
while completed_count < total_tasks:
tasks_summary = []
for tid, tk in self.tasks.items():
if tk.name == "manager_task":
continue
task_info = {
"task_id": tid,
"name": tk.name,
"description": tk.description,
"status": tk.status if tk.status else "not started",
"agent": tk.agent.name if tk.agent else "No agent"
}
tasks_summary.append(task_info)
logging.info(f"Task {tid} status: {task_info}")
manager_prompt = f"""
Here is the current status of all tasks except yours (manager_task):
{tasks_summary}
Provide a JSON with the structure:
{{
"task_id": <int>,
"agent_name": "<string>",
"action": "<execute or stop>"
}}
"""
try:
logging.info("Requesting manager instructions...")
if manager_task.async_execution:
manager_response = await client.beta.chat.completions.parse(
model=self.manager_llm,
messages=[
{"role": "system", "content": manager_task.description},
{"role": "user", "content": manager_prompt}
],
temperature=0.7,
response_format=ManagerInstructions
)
else:
manager_response = client.beta.chat.completions.parse(
model=self.manager_llm,
messages=[
{"role": "system", "content": manager_task.description},
{"role": "user", "content": manager_prompt}
],
temperature=0.7,
response_format=ManagerInstructions
)
parsed_instructions = manager_response.choices[0].message.parsed
logging.info(f"Manager instructions: {parsed_instructions}")
except Exception as e:
display_error(f"Manager parse error: {e}")
logging.error(f"Manager parse error: {str(e)}", exc_info=True)
break
selected_task_id = parsed_instructions.task_id
selected_agent_name = parsed_instructions.agent_name
action = parsed_instructions.action
logging.info(f"Manager selected task_id={selected_task_id}, agent={selected_agent_name}, action={action}")
if action.lower() == "stop":
logging.info("Manager decided to stop task execution")
break
if selected_task_id not in self.tasks:
error_msg = f"Manager selected invalid task id {selected_task_id}"
display_error(error_msg)
logging.error(error_msg)
break
original_agent = self.tasks[selected_task_id].agent.name if self.tasks[selected_task_id].agent else "None"
for a in self.agents:
if a.name == selected_agent_name:
self.tasks[selected_task_id].agent = a
logging.info(f"Changed agent for task {selected_task_id} from {original_agent} to {selected_agent_name}")
break
if self.tasks[selected_task_id].status != "completed":
logging.info(f"Starting execution of task {selected_task_id}")
yield selected_task_id
logging.info(f"Finished execution of task {selected_task_id}, status: {self.tasks[selected_task_id].status}")
if self.tasks[selected_task_id].status == "completed":
completed_count += 1
logging.info(f"Task {selected_task_id} completed. Total completed: {completed_count}/{total_tasks}")
self.tasks[manager_task.id].status = "completed"
if self.verbose >= 1:
logging.info("All tasks completed under manager supervision.")
logging.info("Hierarchical task execution finished")
def workflow(self):
"""Synchronous version of workflow method"""
current_iter = 0 # Track how many times we've looped
# Build workflow relationships first
for task in self.tasks.values():
if task.next_tasks:
for next_task_name in task.next_tasks:
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
if next_task:
next_task.previous_tasks.append(task.name)
# Find start task
start_task = None
for task_id, task in self.tasks.items():
if task.is_start:
start_task = task
break
if not start_task:
start_task = list(self.tasks.values())[0]
logging.info("No start task marked, using first task")
# If loop type and no input_file, default to tasks.csv
if start_task and start_task.task_type == "loop" and not start_task.input_file:
start_task.input_file = "tasks.csv"
# --- If loop + input_file, read file & create tasks
if start_task and start_task.task_type == "loop" and getattr(start_task, "input_file", None):
try:
file_ext = os.path.splitext(start_task.input_file)[1].lower()
new_tasks = []
if file_ext == ".csv":
# existing CSV reading logic
with open(start_task.input_file, "r", encoding="utf-8") as f:
# Try as simple CSV first
reader = csv.reader(f)
previous_task = None
for i, row in enumerate(reader):
if row: # Skip empty rows
task_desc = row[0] # Take first column
row_task = Task(
description=task_desc, # Keep full row as description
agent=start_task.agent,
name=task_desc, # Use first column as name
is_start=(i == 0),
task_type="task",
condition={
"complete": ["next"],
"retry": ["current"]
}
)
self.tasks[row_task.id] = row_task
new_tasks.append(row_task)
if previous_task:
previous_task.next_tasks = [row_task.name]
previous_task.condition["complete"] = [row_task.name]
previous_task = row_task
else:
# If not CSV, read lines
with open(start_task.input_file, "r", encoding="utf-8") as f:
lines = f.read().splitlines()
previous_task = None
for i, line in enumerate(lines):
row_task = Task(
description=line.strip(),
agent=start_task.agent,
name=line.strip(),
is_start=(i == 0),
task_type="task",
condition={
"complete": ["next"],
"retry": ["current"]
}
)
self.tasks[row_task.id] = row_task
new_tasks.append(row_task)
if previous_task:
previous_task.next_tasks = [row_task.name]
previous_task.condition["complete"] = [row_task.name]
previous_task = row_task
if new_tasks:
start_task = new_tasks[0]
logging.info(f"Created {len(new_tasks)} tasks from: {start_task.input_file}")
except Exception as e:
logging.error(f"Failed to read file tasks: {e}")
# end of the new block
current_task = start_task
visited_tasks = set()
loop_data = {} # Store loop-specific data
while current_task:
current_iter += 1
if current_iter > self.max_iter:
logging.info(f"Max iteration limit {self.max_iter} reached, ending workflow.")
break
task_id = current_task.id
logging.info(f"Executing workflow task: {current_task.name if current_task.name else task_id}")
# Add context from previous tasks to description
if current_task.previous_tasks or current_task.context:
context = "\nInput data from previous tasks:"
# Add data from previous tasks in workflow
for prev_name in current_task.previous_tasks:
prev_task = next((t for t in self.tasks.values() if t.name == prev_name), None)
if prev_task and prev_task.result:
# Handle loop data
if current_task.task_type == "loop":
# # create a loop manager Agent
# loop_manager = Agent(
# name="Loop Manager",
# role="Loop data processor",
# goal="Process loop data and convert it to list format",
# backstory="Expert at handling loop data and converting it to proper format",
# llm=self.manager_llm,
# verbose=self.verbose,
# markdown=True
# )
# # get the loop data convert it to list using calling Agent class chat
# loop_prompt = f"""
# Process this data into a list format:
# {prev_task.result.raw}
# Return a JSON object with an 'items' array containing the items to process.
# """
# loop_data_str = loop_manager.chat(
# prompt=loop_prompt,
# output_json=LoopItems
# )
# try:
# # The response will already be parsed into LoopItems model
# loop_data[f"loop_{current_task.name}"] = {
# "items": loop_data_str.items,
# "index": 0,
# "remaining": len(loop_data_str.items)
# }
# context += f"\nCurrent loop item: {loop_data_str.items[0]}"
# except Exception as e:
# display_error(f"Failed to process loop data: {e}")
# context += f"\n{prev_name}: {prev_task.result.raw}"
context += f"\n{prev_name}: {prev_task.result.raw}"
else:
context += f"\n{prev_name}: {prev_task.result.raw}"
# Add data from context tasks
if current_task.context:
for ctx_task in current_task.context:
if ctx_task.result and ctx_task.name != current_task.name:
context += f"\n{ctx_task.name}: {ctx_task.result.raw}"
# Update task description with context
current_task.description = current_task.description + context
# Execute task using existing run_task method
yield task_id
visited_tasks.add(task_id)
# Reset completed task to "not started" so it can run again: Only for workflow because some tasks may be revisited
if self.tasks[task_id].status == "completed":
logging.debug(f"Task {task_id} was completed, resetting to 'not started' for next iteration.")
self.tasks[task_id].status = "not started"
# Handle loop progression
if current_task.task_type == "loop":
loop_key = f"loop_{current_task.name}"
if loop_key in loop_data:
loop_info = loop_data[loop_key]
loop_info["index"] += 1
has_more = loop_info["remaining"] > 0
# Update result to trigger correct condition
if current_task.result:
result = current_task.result.raw
if has_more:
result += "\nmore"
else:
result += "\ndone"
current_task.result.raw = result
# Determine next task based on result
next_task = None
if current_task and current_task.result:
if current_task.task_type in ["decision", "loop"]:
# MINIMAL CHANGE: use pydantic decision if present
decision_str = current_task.result.raw.lower()
if current_task.result.pydantic and hasattr(current_task.result.pydantic, "decision"):
decision_str = current_task.result.pydantic.decision.lower()
# Check conditions
for condition, tasks in current_task.condition.items():
if condition.lower() == decision_str:
# Handle both list and direct string values
task_value = tasks[0] if isinstance(tasks, list) else tasks
if not task_value or task_value == "exit":
logging.info("Workflow exit condition met, ending workflow")
current_task = None
break
next_task_name = task_value
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
# For loops, allow revisiting the same task
if next_task and next_task.id == current_task.id:
visited_tasks.discard(current_task.id)
break
if not next_task and current_task and current_task.next_tasks:
next_task_name = current_task.next_tasks[0]
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
current_task = next_task
if not current_task:
logging.info("Workflow execution completed")
break
def sequential(self):
"""Synchronous version of sequential method"""
for task_id in self.tasks:
if self.tasks[task_id].status != "completed":
yield task_id
def hierarchical(self):
"""Synchronous version of hierarchical method"""
logging.debug(f"Starting hierarchical task execution with {len(self.tasks)} tasks")
manager_agent = Agent(
name="Manager",
role="Project manager",
goal="Manage the entire flow of tasks and delegate them to the right agent",
backstory="Expert project manager to coordinate tasks among agents",
llm=self.manager_llm,
verbose=self.verbose,
markdown=True,
self_reflect=False
)
class ManagerInstructions(BaseModel):
task_id: int
agent_name: str
action: str
manager_task = Task(
name="manager_task",
description="Decide the order of tasks and which agent executes them",
expected_output="All tasks completed successfully",
agent=manager_agent
)
manager_task_id = yield manager_task
logging.info(f"Created manager task with ID {manager_task_id}")
completed_count = 0
total_tasks = len(self.tasks) - 1
logging.info(f"Need to complete {total_tasks} tasks (excluding manager task)")
while completed_count < total_tasks:
tasks_summary = []
for tid, tk in self.tasks.items():
if tk.name == "manager_task":
continue
task_info = {
"task_id": tid,
"name": tk.name,
"description": tk.description,
"status": tk.status if tk.status else "not started",
"agent": tk.agent.name if tk.agent else "No agent"
}
tasks_summary.append(task_info)
logging.info(f"Task {tid} status: {task_info}")
manager_prompt = f"""
Here is the current status of all tasks except yours (manager_task):
{tasks_summary}
Provide a JSON with the structure:
{{
"task_id": <int>,
"agent_name": "<string>",
"action": "<execute or stop>"
}}
"""
try:
logging.info("Requesting manager instructions...")
manager_response = client.beta.chat.completions.parse(
model=self.manager_llm,
messages=[
{"role": "system", "content": manager_task.description},
{"role": "user", "content": manager_prompt}
],
temperature=0.7,
response_format=ManagerInstructions
)
parsed_instructions = manager_response.choices[0].message.parsed
logging.info(f"Manager instructions: {parsed_instructions}")
except Exception as e:
display_error(f"Manager parse error: {e}")
logging.error(f"Manager parse error: {str(e)}", exc_info=True)
break
selected_task_id = parsed_instructions.task_id
selected_agent_name = parsed_instructions.agent_name
action = parsed_instructions.action
logging.info(f"Manager selected task_id={selected_task_id}, agent={selected_agent_name}, action={action}")
if action.lower() == "stop":
logging.info("Manager decided to stop task execution")
break
if selected_task_id not in self.tasks:
error_msg = f"Manager selected invalid task id {selected_task_id}"
display_error(error_msg)
logging.error(error_msg)
break
original_agent = self.tasks[selected_task_id].agent.name if self.tasks[selected_task_id].agent else "None"
for a in self.agents:
if a.name == selected_agent_name:
self.tasks[selected_task_id].agent = a
logging.info(f"Changed agent for task {selected_task_id} from {original_agent} to {selected_agent_name}")
break
if self.tasks[selected_task_id].status != "completed":
logging.info(f"Starting execution of task {selected_task_id}")
yield selected_task_id
logging.info(f"Finished execution of task {selected_task_id}, status: {self.tasks[selected_task_id].status}")
if self.tasks[selected_task_id].status == "completed":
completed_count += 1
logging.info(f"Task {selected_task_id} completed. Total completed: {completed_count}/{total_tasks}")
self.tasks[manager_task.id].status = "completed"
if self.verbose >= 1:
logging.info("All tasks completed under manager supervision.")
logging.info("Hierarchical task execution finished")
-41
View File
@@ -1,41 +0,0 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "praisonaiagents"
version = "0.0.50"
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
authors = [
{ name="Mervin Praison" }
]
dependencies = [
"pydantic",
"rich",
"openai"
]
[project.optional-dependencies]
memory = [
"chromadb>=0.5.23"
]
knowledge = [
"mem0ai>=0.1.0",
"chromadb==0.5.23",
"markitdown",
"chonkie"
]
# Add LLM dependencies
llm = [
"litellm>=1.50.0",
"pydantic>=2.4.2"
]
# Combined features
all = [
"praisonaiagents[memory]",
"praisonaiagents[knowledge]",
"praisonaiagents[llm]"
]
+53
View File
@@ -0,0 +1,53 @@
# PraisonAI Docker Environment Configuration
# Copy this file to .env and update with your values
# Required: OpenAI API Key
OPENAI_API_KEY=your_openai_api_key_here
# Required: Chainlit Authentication Secret (generate a random string)
CHAINLIT_AUTH_SECRET=your_chainlit_secret_here
# Optional: Additional API Keys
ANTHROPIC_API_KEY=your_anthropic_api_key_here
GOOGLE_API_KEY=your_google_api_key_here
GROQ_API_KEY=your_groq_api_key_here
COHERE_API_KEY=your_cohere_api_key_here
# Optional: Service Configuration
FLASK_ENV=development
CHAINLIT_HOST=0.0.0.0
# Optional: Port Configuration (modify if you have conflicts)
UI_PORT=8082
CHAT_PORT=8083
API_PORT=8080
# Optional: Database Configuration
DATABASE_URL=sqlite:///root/.praison/database.sqlite
# Optional: Logging Configuration
LOG_LEVEL=INFO
PYTHONPATH=/app
# Optional: Development Settings
DEV_MODE=false
DEBUG=false
# Optional: Model Configuration
DEFAULT_MODEL=gpt-4
DEFAULT_TEMPERATURE=0.7
MAX_TOKENS=4000
# Optional: Security Settings
CORS_ORIGINS=http://localhost:3000,http://localhost:8082,http://localhost:8083
RATE_LIMIT=100
# Optional: Feature Flags
ENABLE_CHAT=true
ENABLE_UI=true
ENABLE_API=true
ENABLE_REALTIME=true
# Optional: Volume Paths (for custom mounting)
PRAISON_DATA_PATH=~/.praison
EXAMPLES_PATH=./examples
+40 -1
View File
@@ -1,6 +1,45 @@
FROM python:3.11-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
python3-dev \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
# Create praison config directory
RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
flask \
"praisonai>=2.2.33" \
"praisonai[api]" \
gunicorn \
markdown
# Copy application code
COPY . .
RUN pip install flask praisonai==2.0.57 gunicorn markdown
# Set environment variables for directory management
ENV PRAISON_CONFIG_DIR=/root/.praison
ENV DOCKER_CONTAINER=true
# Create health check API if api.py doesn't exist
RUN if [ ! -f api.py ]; then \
echo "from flask import Flask\n\
app = Flask(__name__)\n\
\n\
@app.route('/health')\n\
def health():\n\
return {'status': 'healthy'}, 200\n\
\n\
if __name__ == '__main__':\n\
app.run()" > api.py; \
fi
EXPOSE 8080
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
+12 -3
View File
@@ -7,18 +7,27 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
python3-dev \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
# Install Python packages
# Create praison config directory
RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonaiagents>=0.0.4 \
praisonai_tools \
"praisonai==2.0.18" \
"praisonai>=2.2.33" \
"praisonai[chat]" \
"embedchain[github,youtube]"
# Copy application code
COPY . .
# Set environment variables for directory management
ENV PRAISON_CONFIG_DIR=/root/.praison
ENV CHAINLIT_CONFIG_DIR=/root/.praison
ENV CHAINLIT_DB_DIR=/root/.praison
ENV DOCKER_CONTAINER=true
# Default command (will be overridden by docker-compose)
CMD ["praisonai", "chat"]
+23 -4
View File
@@ -9,20 +9,39 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
portaudio19-dev \
python3-pyaudio \
curl \
git \
vim \
nano \
&& rm -rf /var/lib/apt/lists/*
# Install Python packages
# Create praison config directory
RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonaiagents>=0.0.4 \
praisonai_tools \
"praisonai==2.0.18" \
"praisonai>=2.2.33" \
"praisonai[ui]" \
"praisonai[chat]" \
"praisonai[realtime]" \
"embedchain[github,youtube]"
"praisonai[code]" \
"embedchain[github,youtube]" \
jupyter \
jupyterlab \
notebook \
pytest \
pytest-asyncio \
mkdocs \
mkdocs-material
# Copy application code
COPY . .
# Set environment variables for directory management
ENV PRAISON_CONFIG_DIR=/root/.praison
ENV CHAINLIT_CONFIG_DIR=/root/.praison
ENV CHAINLIT_DB_DIR=/root/.praison
ENV DOCKER_CONTAINER=true
# Default command (will be overridden by docker-compose)
CMD ["praisonai", "ui"]
+32
View File
@@ -0,0 +1,32 @@
FROM python:3.11-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
python3-dev \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
# Create praison config directory
RUN mkdir -p /root/.praison
# Copy praisonaiagents source
COPY src/praisonai-agents/ /app/praisonaiagents/
WORKDIR /app/praisonaiagents
# Install praisonaiagents with all features (non-editable for production)
RUN pip install --no-cache-dir ".[all]"
# Set environment variables for directory management
ENV PRAISON_CONFIG_DIR=/root/.praison
ENV CHAINLIT_CONFIG_DIR=/root/.praison
ENV CHAINLIT_DB_DIR=/root/.praison
ENV DOCKER_CONTAINER=true
WORKDIR /app
# Default command
CMD ["python", "-c", "import praisonaiagents; print('PraisonAI Agents installed successfully')"]
+12 -3
View File
@@ -7,18 +7,27 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
python3-dev \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
# Install Python packages
# Create praison config directory
RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonaiagents>=0.0.4 \
praisonai_tools \
"praisonai==2.0.18" \
"praisonai>=2.2.33" \
"praisonai[ui]" \
"praisonai[crewai]"
# Copy application code
COPY . .
# Set environment variables for directory management
ENV PRAISON_CONFIG_DIR=/root/.praison
ENV CHAINLIT_CONFIG_DIR=/root/.praison
ENV CHAINLIT_DB_DIR=/root/.praison
ENV DOCKER_CONTAINER=true
# Default command (will be overridden by docker-compose)
CMD ["praisonai", "ui"]
+265
View File
@@ -0,0 +1,265 @@
# PraisonAI Docker Setup
This directory contains Docker configurations for running PraisonAI services in containerized environments. The setup addresses directory management issues and provides comprehensive multi-service deployment options.
## 🐳 Available Services
### Core Services
- **UI Service** (`port 8082`) - Chainlit-based web interface
- **Chat Service** (`port 8083`) - Dedicated chat interface
- **API Service** (`port 8080`) - REST API endpoint
- **Agents Service** - Standalone PraisonAI Agents runtime
### Docker Files
- `Dockerfile` - Basic API service
- `Dockerfile.ui` - UI service with web interface
- `Dockerfile.chat` - Chat-focused service
- `Dockerfile.dev` - Development environment with tools
- `Dockerfile.praisonaiagents` - Standalone agents framework
- `docker-compose.yml` - Multi-service orchestration
## 🚀 Quick Start
### Single Service
```bash
# Run UI service
docker run -p 8082:8082 -e OPENAI_API_KEY=your_key ghcr.io/mervinpraison/praisonai:ui
# Run Chat service
docker run -p 8083:8083 -e OPENAI_API_KEY=your_key ghcr.io/mervinpraison/praisonai:chat
# Run API service
docker run -p 8080:8080 -e OPENAI_API_KEY=your_key ghcr.io/mervinpraison/praisonai:api
```
### Multi-Service with Docker Compose
```bash
# Create environment file
cat > .env << EOF
OPENAI_API_KEY=your_openai_api_key_here
CHAINLIT_AUTH_SECRET=your_secret_here
EOF
# Start all services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down
```
## 📁 Directory Management
### Problem Solved
The original issue was that files like `chainlit.md`, `.chainlit` directory, and `public` folder were cluttering the root directory.
### Solution Implemented
All PraisonAI configuration and runtime files are now stored in `~/.praison/`:
```bash
~/.praison/
├── database.sqlite # Chainlit database
├── chainlit.md # Chainlit configuration
├── .chainlit/ # Chainlit runtime files
└── config/ # PraisonAI configuration
```
### Environment Variables
```bash
PRAISON_CONFIG_DIR=/root/.praison # Main config directory
CHAINLIT_CONFIG_DIR=/root/.praison # Chainlit config location
CHAINLIT_DB_DIR=/root/.praison # Database location
```
## 🔧 Service Configuration
### UI Service (Port 8082)
```yaml
environment:
- CHAINLIT_PORT=8082
- CHAINLIT_HOST=0.0.0.0
- OPENAI_API_KEY=${OPENAI_API_KEY}
- CHAINLIT_AUTH_SECRET=${CHAINLIT_AUTH_SECRET}
```
### Chat Service (Port 8083)
```yaml
environment:
- CHAINLIT_PORT=8083
- CHAINLIT_HOST=0.0.0.0
- OPENAI_API_KEY=${OPENAI_API_KEY}
```
### API Service (Port 8080)
```yaml
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
```
## 🎯 Service Endpoints
| Service | Port | Endpoint | Description |
|---------|------|----------|-------------|
| UI | 8082 | http://localhost:8082 | Web interface |
| Chat | 8083 | http://localhost:8083 | Chat interface |
| API | 8080 | http://localhost:8080 | REST API |
| API Health | 8080 | http://localhost:8080/health | Health check |
## 🔍 Health Checks
All services include health checks:
```yaml
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:PORT"]
interval: 10s
timeout: 5s
retries: 3
```
## 📦 Package Versions
All Docker images use consistent, up-to-date versions:
- PraisonAI: `>=2.2.33`
- PraisonAI Agents: `>=0.0.92`
- Python: `3.11-slim`
## 🔒 Security Features
- Non-root user execution where possible
- Minimal base image (python:3.11-slim)
- No unnecessary packages installed
- Environment variable-based configuration
- Volume mounting for persistent data
## 🛠 Development
### Development Environment
```bash
# Use development Dockerfile with additional tools
docker build -f Dockerfile.dev -t praisonai:dev .
docker run -it -v $(pwd):/app praisonai:dev bash
```
### Custom Configuration
```bash
# Mount custom config directory
docker run -v ~/.praison:/root/.praison praisonai:ui
```
## 📊 Monitoring
### Docker Compose Monitoring
```bash
# View service status
docker-compose ps
# View resource usage
docker-compose top
# View logs for specific service
docker-compose logs ui
docker-compose logs chat
docker-compose logs api
```
## 🚨 Troubleshooting
### Common Issues
1. **Port conflicts**
```bash
# Check port usage
netstat -tlnp | grep :8082
# Use different ports
docker run -p 9082:8082 praisonai:ui
```
2. **Environment variables not loading**
```bash
# Verify .env file
cat .env
# Set variables directly
docker run -e OPENAI_API_KEY=your_key praisonai:ui
```
3. **Permission issues**
```bash
# Check volume permissions
ls -la ~/.praison/
# Fix permissions
sudo chown -R $(id -u):$(id -g) ~/.praison/
```
4. **Service won't start**
```bash
# Check logs
docker-compose logs service_name
# Restart service
docker-compose restart service_name
```
## 🔄 Updates
### Pulling Latest Images
```bash
# Pull latest images
docker-compose pull
# Restart with new images
docker-compose up -d
```
### Version Pinning
To use specific versions, update the Dockerfile:
```dockerfile
RUN pip install "praisonai==2.2.33" "praisonaiagents==0.0.92"
```
## 🌐 Production Deployment
### Recommended Production Setup
```yaml
# docker-compose.prod.yml
version: '3.8'
services:
ui:
image: ghcr.io/mervinpraison/praisonai:ui
restart: unless-stopped
environment:
- CHAINLIT_HOST=0.0.0.0
- CHAINLIT_PORT=8082
volumes:
- praison_data:/root/.praison
networks:
- praison_network
deploy:
resources:
limits:
memory: 1G
reservations:
memory: 512M
```
### Load Balancer Configuration
For production environments, consider using nginx or similar:
```nginx
upstream praisonai {
server localhost:8082;
server localhost:8083;
}
server {
listen 80;
location / {
proxy_pass http://praisonai;
}
}
```
This Docker setup provides a clean, organized, and scalable way to deploy PraisonAI services while solving the directory management issues mentioned in the original request.
+201
View File
@@ -0,0 +1,201 @@
version: '3.8'
# Development Docker Compose Configuration
# Extends the main docker-compose.yml with development-specific settings
services:
# Development UI Service with hot reload
ui-dev:
build:
context: ..
dockerfile: docker/Dockerfile.dev
volumes:
- praison_data:/root/.praison
- ../src:/app/src:rw
- ../examples:/app/examples:rw
- ../docs:/app/docs:ro
ports:
- "${UI_PORT:-8082}:8082"
environment:
FLASK_ENV: development
CHAINLIT_PORT: "8082"
CHAINLIT_HOST: "0.0.0.0"
OPENAI_API_KEY: ${OPENAI_API_KEY}
CHAINLIT_AUTH_SECRET: ${CHAINLIT_AUTH_SECRET}
PRAISON_CONFIG_DIR: /root/.praison
CHAINLIT_CONFIG_DIR: /root/.praison
CHAINLIT_DB_DIR: /root/.praison
DEBUG: "true"
DEV_MODE: "true"
PYTHONPATH: /app/src
command: praisonai ui --host 0.0.0.0 --reload
networks:
- praison_network
depends_on:
- database
# Development Chat Service
chat-dev:
build:
context: ..
dockerfile: docker/Dockerfile.dev
volumes:
- praison_data:/root/.praison
- ../src:/app/src:rw
- ../examples:/app/examples:rw
ports:
- "${CHAT_PORT:-8083}:8083"
environment:
CHAINLIT_PORT: "8083"
CHAINLIT_HOST: "0.0.0.0"
OPENAI_API_KEY: ${OPENAI_API_KEY}
CHAINLIT_AUTH_SECRET: ${CHAINLIT_AUTH_SECRET}
PRAISON_CONFIG_DIR: /root/.praison
CHAINLIT_CONFIG_DIR: /root/.praison
CHAINLIT_DB_DIR: /root/.praison
DEBUG: "true"
DEV_MODE: "true"
PYTHONPATH: /app/src
command: praisonai chat --host 0.0.0.0 --port 8083 --reload
networks:
- praison_network
depends_on:
- database
# Development API Service with hot reload
api-dev:
build:
context: ..
dockerfile: docker/Dockerfile.dev
volumes:
- praison_data:/root/.praison
- ../src:/app/src:rw
- ../examples:/app/examples:rw
ports:
- "${API_PORT:-8080}:8080"
environment:
OPENAI_API_KEY: ${OPENAI_API_KEY}
PRAISON_CONFIG_DIR: /root/.praison
FLASK_ENV: development
DEBUG: "true"
DEV_MODE: "true"
PYTHONPATH: /app/src
command: python -m flask --app api run --host 0.0.0.0 --port 8080 --debug
networks:
- praison_network
depends_on:
- database
# Development Jupyter Notebook Service
jupyter:
build:
context: ..
dockerfile: docker/Dockerfile.dev
volumes:
- praison_data:/root/.praison
- ../src:/app/src:rw
- ../examples:/app/examples:rw
- ../docs:/app/docs:rw
ports:
- "8888:8888"
environment:
OPENAI_API_KEY: ${OPENAI_API_KEY}
PRAISON_CONFIG_DIR: /root/.praison
JUPYTER_ENABLE_LAB: "yes"
PYTHONPATH: /app/src
command: jupyter lab --ip=0.0.0.0 --port=8888 --no-browser --allow-root --LabApp.token='' --LabApp.password=''
networks:
- praison_network
# Development Testing Service
test:
build:
context: ..
dockerfile: docker/Dockerfile.dev
volumes:
- ../src:/app/src:rw
- ../tests:/app/tests:rw
- praison_data:/root/.praison
environment:
OPENAI_API_KEY: ${OPENAI_API_KEY}
PRAISON_CONFIG_DIR: /root/.praison
PYTHONPATH: /app/src
PYTEST_CURRENT_TEST: "true"
command: python -m pytest tests/ -v
networks:
- praison_network
profiles:
- test
# Standalone database for development
database:
security_opt:
- "no-new-privileges:true"
image: postgres:15-alpine
environment:
POSTGRES_DB: praisonai_dev
POSTGRES_USER: praisonai
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-praisonai_dev_pass}
volumes:
database:
image: postgres:15-alpine
environment:
POSTGRES_DB: praisonai_dev
POSTGRES_USER: praisonai
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-praisonai_dev_pass}
volumes:
- postgres_data:/var/lib/postgresql/data
read_only: true
tmpfs:
- /tmp
- /var/tmp
ports:
- "5432:5432"
networks:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
networks:
- praison_network
profiles:
- database
# Redis for caching and session management
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- praison_network
profiles:
- cache
# Development documentation server
docs:
build:
context: ..
dockerfile: docker/Dockerfile.dev
volumes:
- ../docs:/app/docs:rw
- ../README.md:/app/README.md:ro
ports:
- "8000:8000"
command: sh -c "cd docs && mkdocs serve --dev-addr 0.0.0.0:8000"
networks:
- praison_network
profiles:
- docs
volumes:
praison_data:
driver: local
postgres_data:
driver: local
redis_data:
driver: local
networks:
praison_network:
driver: bridge
+81 -3
View File
@@ -1,9 +1,13 @@
version: '3.8'
services:
# PraisonAI UI Service
ui:
build:
context: .
dockerfile: Dockerfile.ui
context: ..
dockerfile: docker/Dockerfile.ui
volumes:
- praison_data:/root/.praison
- .:/app
ports:
- "8082:8082"
@@ -13,9 +17,83 @@ services:
CHAINLIT_HOST: "0.0.0.0"
OPENAI_API_KEY: ${OPENAI_API_KEY}
CHAINLIT_AUTH_SECRET: ${CHAINLIT_AUTH_SECRET}
PRAISON_CONFIG_DIR: /root/.praison
CHAINLIT_CONFIG_DIR: /root/.praison
CHAINLIT_DB_DIR: /root/.praison
command: praisonai ui --host 0.0.0.0
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8082"]
interval: 10s
timeout: 5s
retries: 3
retries: 3
networks:
- praison_network
# PraisonAI Chat Service
chat:
build:
context: ..
dockerfile: docker/Dockerfile.chat
volumes:
- praison_data:/root/.praison
- .:/app
ports:
- "8083:8083"
environment:
CHAINLIT_PORT: "8083"
CHAINLIT_HOST: "0.0.0.0"
OPENAI_API_KEY: ${OPENAI_API_KEY}
CHAINLIT_AUTH_SECRET: ${CHAINLIT_AUTH_SECRET}
PRAISON_CONFIG_DIR: /root/.praison
CHAINLIT_CONFIG_DIR: /root/.praison
CHAINLIT_DB_DIR: /root/.praison
command: praisonai chat --host 0.0.0.0 --port 8083
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8083"]
interval: 10s
timeout: 5s
retries: 3
networks:
- praison_network
# PraisonAI API Service
api:
build:
context: ..
dockerfile: docker/Dockerfile
volumes:
- praison_data:/root/.praison
ports:
- "8080:8080"
environment:
OPENAI_API_KEY: ${OPENAI_API_KEY}
PRAISON_CONFIG_DIR: /root/.praison
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 5s
retries: 3
networks:
- praison_network
# PraisonAI Agents Service (standalone)
agents:
build:
context: ..
dockerfile: docker/Dockerfile.praisonaiagents
volumes:
- praison_data:/root/.praison
- ./examples:/app/examples
environment:
OPENAI_API_KEY: ${OPENAI_API_KEY}
PRAISON_CONFIG_DIR: /root/.praison
networks:
- praison_network
volumes:
praison_data:
driver: local
networks:
praison_network:
driver: bridge
+289
View File
@@ -0,0 +1,289 @@
#!/bin/bash
# PraisonAI Docker Quick Start Script
# This script helps users quickly get started with PraisonAI using Docker
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if Docker is installed
check_docker() {
if ! command -v docker &> /dev/null; then
print_error "Docker is not installed. Please install Docker first:"
echo " - Visit: https://docs.docker.com/get-docker/"
exit 1
fi
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
print_error "Docker Compose is not available. Please install Docker Compose:"
echo " - Visit: https://docs.docker.com/compose/install/"
exit 1
fi
print_success "Docker and Docker Compose are available"
}
# Check if .env file exists, create from template if not
setup_environment() {
if [ ! -f ".env" ]; then
print_status "Creating .env file from template..."
if [ -f ".env.template" ]; then
cp .env.template .env
else
cat > .env << EOF
# PraisonAI Docker Environment Configuration
OPENAI_API_KEY=your_openai_api_key_here
CHAINLIT_AUTH_SECRET=$(openssl rand -hex 32 2>/dev/null || echo "your_chainlit_secret_here")
FLASK_ENV=development
CHAINLIT_HOST=0.0.0.0
UI_PORT=8082
CHAT_PORT=8083
API_PORT=8080
EOF
fi
print_warning "Please edit .env file and add your API keys before continuing"
print_status "Required: OPENAI_API_KEY"
read -p "Press Enter to continue after updating .env file..."
else
print_success ".env file already exists"
fi
}
# Function to show menu
show_menu() {
echo ""
echo "=== PraisonAI Docker Quick Start ==="
echo ""
echo "1) Start UI Service (Web Interface) - Port 8082"
echo "2) Start Chat Service - Port 8083"
echo "3) Start API Service - Port 8080"
echo "4) Start All Services (Recommended)"
echo "5) Start Development Environment"
echo "6) View Service Status"
echo "7) View Logs"
echo "8) Stop All Services"
echo "9) Pull Latest Images"
echo "10) Clean Up (Remove containers and volumes)"
echo "11) Show Service URLs"
echo "0) Exit"
echo ""
}
# Start specific service
start_service() {
local service=$1
print_status "Starting $service service..."
docker-compose up -d $service
print_success "$service service started"
}
# Start all services
start_all_services() {
print_status "Starting all PraisonAI services..."
docker-compose up -d
print_success "All services started"
show_service_urls
}
# Start development environment
start_dev_environment() {
print_status "Starting development environment..."
if [ -f "docker-compose.dev.yml" ]; then
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d ui-dev chat-dev api-dev
print_success "Development environment started"
echo ""
echo "Development services available:"
echo " - UI (with hot reload): http://localhost:${UI_PORT:-8082}"
echo " - Chat (with hot reload): http://localhost:${CHAT_PORT:-8083}"
echo " - API (with hot reload): http://localhost:${API_PORT:-8080}"
echo " - Jupyter Lab: http://localhost:8888"
echo ""
else
print_warning "Development configuration not found, starting regular services"
start_all_services
fi
}
# Show service status
show_status() {
print_status "Service Status:"
docker-compose ps
}
# Show logs
show_logs() {
echo ""
echo "Which service logs would you like to view?"
echo "1) All services"
echo "2) UI service"
echo "3) Chat service"
echo "4) API service"
echo "5) Agents service"
read -p "Enter choice (1-5): " log_choice
case $log_choice in
1) docker-compose logs -f ;;
2) docker-compose logs -f ui ;;
3) docker-compose logs -f chat ;;
4) docker-compose logs -f api ;;
5) docker-compose logs -f agents ;;
*) print_error "Invalid choice" ;;
esac
}
# Stop all services
stop_services() {
print_status "Stopping all services..."
docker-compose down
print_success "All services stopped"
}
# Pull latest images
pull_images() {
print_status "Pulling latest images..."
docker-compose pull
print_success "Images updated"
}
# Clean up
cleanup() {
print_warning "This will remove all containers, networks, and volumes"
read -p "Are you sure? (y/N): " confirm
if [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then
print_status "Cleaning up..."
docker-compose down -v --remove-orphans
docker system prune -f
print_success "Cleanup completed"
fi
}
# Show service URLs
show_service_urls() {
local ui_port=${UI_PORT:-8082}
local chat_port=${CHAT_PORT:-8083}
local api_port=${API_PORT:-8080}
echo ""
echo "=== Service URLs ==="
echo "UI Service: http://localhost:$ui_port"
echo "Chat Service: http://localhost:$chat_port"
echo "API Service: http://localhost:$api_port"
echo "API Health: http://localhost:$api_port/health"
echo ""
}
# Check system requirements
check_requirements() {
print_status "Checking system requirements..."
# Check available memory
if command -v free &> /dev/null; then
available_ram=$(free -m | awk 'NR==2{printf "%.1f", $7/1024}')
print_status "Available RAM: ${available_ram}GB"
if (( $(echo "$available_ram < 2.0" | bc -l 2>/dev/null || echo "1") )); then
print_warning "Low available memory. Recommended: 2GB+ available RAM"
fi
fi
# Check disk space
if command -v df &> /dev/null; then
available_space=$(df -BG . | awk 'NR==2{print $4}' | sed 's/G//')
print_status "Available disk space: ${available_space}GB"
if [ "$available_space" -lt 5 ]; then
print_warning "Low disk space. Recommended: 5GB+ available space"
fi
fi
}
# Main function
main() {
clear
echo "🤖 Welcome to PraisonAI Docker Setup!"
echo ""
# Check prerequisites
check_docker
check_requirements
setup_environment
# Main loop
while true; do
show_menu
read -p "Enter your choice (0-11): " choice
case $choice in
1)
start_service "ui"
echo "UI Service: http://localhost:${UI_PORT:-8082}"
;;
2)
start_service "chat"
echo "Chat Service: http://localhost:${CHAT_PORT:-8083}"
;;
3)
start_service "api"
echo "API Service: http://localhost:${API_PORT:-8080}"
;;
4)
start_all_services
;;
5)
start_dev_environment
;;
6)
show_status
;;
7)
show_logs
;;
8)
stop_services
;;
9)
pull_images
;;
10)
cleanup
;;
11)
show_service_urls
;;
0)
print_success "Thank you for using PraisonAI!"
exit 0
;;
*)
print_error "Invalid choice. Please try again."
;;
esac
echo ""
read -p "Press Enter to continue..."
done
}
# Run main function
main
-1
View File
@@ -1 +0,0 @@
docs.praison.ai
-20
View File
@@ -1,20 +0,0 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-124
View File
@@ -1,124 +0,0 @@
---
title: "AI Agents"
description: "Overview of all available PraisonAI agents and their capabilities"
icon: "robot"
---
PraisonAI provides a diverse set of specialized agents for various tasks. Each agent is designed with specific capabilities and tools to handle different types of tasks effectively.
```mermaid
graph LR
%% Define the main flow
Start([▶ Start]) --> Agent1
Agent1 --> Process[⚙ Process]
Process --> Agent2
Agent2 --> Output([✓ Output])
Process -.-> Agent1
%% Define subgraphs for agents and their tasks
subgraph Agent1[ ]
Task1[📋 Task]
AgentIcon1[🤖 AI Agent]
Tools1[🔧 Tools]
Task1 --- AgentIcon1
AgentIcon1 --- Tools1
end
subgraph Agent2[ ]
Task2[📋 Task]
AgentIcon2[🤖 AI Agent]
Tools2[🔧 Tools]
Task2 --- AgentIcon2
AgentIcon2 --- Tools2
end
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Start,Output,Task1,Task2 input
class Process,AgentIcon1,AgentIcon2 process
class Tools1,Tools2 tools
class Agent1,Agent2 transparent
```
## Data & Analysis
<CardGroup cols={2}>
<Card title="Data Analyst" icon="chart-line" href="/agents/data-analyst">
Analyze data from various sources, create visualizations, and generate insights.
</Card>
<Card title="Finance" icon="money-bill-trend-up" href="/agents/finance">
Track stocks, analyze financial data, and provide investment recommendations.
</Card>
<Card title="Research" icon="magnifying-glass-chart" href="/agents/research">
Conduct comprehensive research and analysis across various topics.
</Card>
<Card title="Wikipedia" icon="book" href="/agents/wikipedia">
Search and extract information from Wikipedia articles.
</Card>
</CardGroup>
## Media & Content
<CardGroup cols={2}>
<Card title="Image Analysis" icon="image" href="/agents/image">
Analyze and understand visual content from images.
</Card>
<Card title="Image to Text" icon="text" href="/agents/image-to-text">
Convert images to textual descriptions and extract text content.
</Card>
<Card title="Video" icon="video" href="/agents/video">
Analyze video content and extract meaningful information.
</Card>
<Card title="Markdown" icon="markdown" href="/agents/markdown">
Generate and format content in Markdown syntax.
</Card>
</CardGroup>
## Search & Recommendations
<CardGroup cols={2}>
<Card title="Web Search" icon="globe" href="/agents/websearch">
Perform intelligent web searches and gather information.
</Card>
<Card title="Recommendation" icon="thumbs-up" href="/agents/recommendation">
Generate personalized recommendations based on preferences.
</Card>
<Card title="Shopping" icon="shop" href="/agents/shopping">
Compare prices and find the best deals across stores.
</Card>
<Card title="Planning" icon="calendar" href="/agents/planning">
Create travel plans and detailed itineraries.
</Card>
</CardGroup>
## Development
<CardGroup cols={2}>
<Card title="Programming" icon="code" href="/agents/programming">
Write, analyze, and debug code across multiple languages.
</Card>
<Card title="Single Agent" icon="circle-1" href="/agents/single">
Simple, focused agent for basic tasks without external tools.
</Card>
</CardGroup>
## Getting Started
Each agent can be easily initialized and customized for your specific needs. Here's a basic example:
```python
from praisonaiagents import Agent
# Create an agent with specific instructions
agent = Agent(instructions="Your task-specific instructions")
# Start the agent with a task
response = agent.start("Your task description")
```
For more detailed information about each agent, click on the respective cards above.
-120
View File
@@ -1,120 +0,0 @@
---
title: "Data Analyst Agent"
sidebarTitle: "Data Analyst"
description: "Learn how to create AI agents for data analysis and insights generation."
icon: "chart-line"
---
```mermaid
flowchart LR
In[Data Source] --> Reader[Data Reader]
Reader --> Analyzer[Data Analyzer]
Analyzer --> Generator[Insights Generator]
Generator --> Out[Output]
style In fill:#8B0000,color:#fff
style Reader fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Data Analyst Agent can read data from various sources, analyze it, and generate insights.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `data_analysis.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import (
read_csv, read_excel, write_csv, write_excel,
filter_data, get_summary, group_by, pivot_table
)
agent = Agent(
instructions="You are a Data Analyst Agent",
tools=[
read_csv, read_excel, write_csv, write_excel,
filter_data, get_summary, group_by, pivot_table
]
)
# Start analysis with a specific task
agent.start(f"""
Read the data from the csv file {os.path.join(os.path.dirname(__file__), "tesla-stock-price.csv")}
Analyse the data and give me the insights
read_csv to read the file
""")
```
</Step>
</Steps>
## Understanding Data Analysis Workflow
The Data Analyst Agent is designed to perform comprehensive data analysis tasks using a suite of specialized tools. Here's how it works:
1. **Data Reading**: The agent can read data from various sources:
- CSV files using `read_csv`
- Excel files using `read_excel`
2. **Data Analysis**: Multiple analysis tools are available:
- `filter_data`: Filter datasets based on conditions
- `get_summary`: Generate statistical summaries
- `group_by`: Group data by specific columns
- `pivot_table`: Create pivot tables for analysis
3. **Data Export**: Results can be exported to:
- CSV format using `write_csv`
- Excel format using `write_excel`
## Features
<CardGroup cols={2}>
<Card title="Multiple Data Sources" icon="table">
Support for both CSV and Excel file formats.
</Card>
<Card title="Analysis Tools" icon="calculator">
Comprehensive suite of analysis tools including filtering, summarization, and pivoting.
</Card>
<Card title="Data Export" icon="file-export">
Export capabilities to various formats.
</Card>
<Card title="Automated Insights" icon="lightbulb">
Automatic generation of data insights and patterns.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Analyzing stock data
agent.start("""
1. Read 'stock_data.csv'
2. Filter data for the last 30 days
3. Calculate daily returns
4. Generate summary statistics
5. Export results to 'analysis_results.xlsx'
""")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex analysis workflows
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving analysis accuracy
- Check out other specialized agents like the [Finance Agent](/agents/finance) for specific use cases
-97
View File
@@ -1,97 +0,0 @@
---
title: "Finance Agent"
sidebarTitle: "Finance"
description: "Learn how to create AI agents for financial analysis and investment recommendations."
icon: "money-bill-trend-up"
---
```mermaid
flowchart LR
In[Request] --> Price[Stock Price]
Price --> Info[Stock Info]
Info --> History[Historical Data]
History --> Out[Investment Advice]
style In fill:#8B0000,color:#fff
style Price fill:#2E8B57,color:#fff
style Info fill:#2E8B57,color:#fff
style History fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Finance Agent can analyze stock market data and provide investment recommendations.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `finance_analysis.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import get_stock_price, get_stock_info, get_historical_data
agent = Agent(
instructions="You are a Research Agent",
tools=[get_stock_price, get_stock_info, get_historical_data]
)
agent.start("Understand current stock price and historical data of Apple and Google. Tell me if I can invest in them")
```
</Step>
</Steps>
## Understanding Financial Analysis
The Finance Agent specializes in stock market analysis and investment recommendations using three key components:
1. **Real-time Price Data**: Uses `get_stock_price` to fetch current market prices
2. **Company Information**: Retrieves company details using `get_stock_info`
3. **Historical Analysis**: Analyzes trends with `get_historical_data`
## Features
<CardGroup cols={2}>
<Card title="Real-time Data" icon="clock">
Access to current stock market prices and information.
</Card>
<Card title="Company Analysis" icon="building">
Detailed company information and fundamentals.
</Card>
<Card title="Historical Trends" icon="chart-line">
Analysis of historical price movements and patterns.
</Card>
<Card title="Investment Advice" icon="money-bill">
AI-powered investment recommendations.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Analyzing specific stocks
agent.start("""
1. Get current prices for AAPL and GOOGL
2. Retrieve company information
3. Analyze 6-month historical data
4. Provide investment recommendations
""")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex financial analysis
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving recommendation accuracy
- Check out the [Data Analyst Agent](/agents/data-analyst) for detailed data analysis capabilities
-140
View File
@@ -1,140 +0,0 @@
---
title: "Image to Text Agent"
sidebarTitle: "Image to Text"
description: "Learn how to create AI agents for converting images to textual descriptions and extracting text from images."
icon: "text"
---
```mermaid
flowchart LR
In[Image Input] --> OCR[Text Extractor]
OCR --> Analyzer[Content Analyzer]
Analyzer --> Generator[Description Generator]
Generator --> Out[Text Output]
style In fill:#8B0000,color:#fff
style OCR fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Image-to-Text Agent can extract text from images and generate comprehensive descriptions.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `image_to_text.py`:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create Image-to-Text Agent
image_text_agent = Agent(
name="ImageTextConverter",
role="Image Text Extraction Specialist",
goal="Convert image content to textual descriptions and extract text",
backstory="""You are an expert in OCR and image understanding.
You excel at extracting text from images and generating detailed descriptions.""",
llm="gpt-4o-mini",
self_reflect=False
)
# Create text extraction task
extraction_task = Task(
name="extract_text",
description="Extract all text from this image and describe its layout.",
expected_output="Extracted text and layout description",
agent=image_text_agent,
images=["document.jpg"]
)
# Create description task
description_task = Task(
name="generate_description",
description="Generate a detailed description of the image content.",
expected_output="Comprehensive description of visual elements",
agent=image_text_agent,
images=["scene.jpg"]
)
# Create PraisonAIAgents instance
agents = PraisonAIAgents(
agents=[image_text_agent],
tasks=[extraction_task, description_task],
process="sequential",
verbose=1
)
# Run analysis
agents.start()
```
</Step>
</Steps>
## Understanding Image-to-Text Conversion
The Image-to-Text Agent combines multiple capabilities to convert visual content into textual form:
1. **OCR Processing**: Extracts text from images using optical character recognition
2. **Layout Analysis**: Understands the spatial arrangement of text and visual elements
3. **Content Description**: Generates natural language descriptions of image content
4. **Text Formatting**: Preserves text formatting and structure where possible
## Features
<CardGroup cols={2}>
<Card title="Text Extraction" icon="text">
Advanced OCR capabilities for text extraction.
</Card>
<Card title="Layout Understanding" icon="table-layout">
Analysis of text and content layout.
</Card>
<Card title="Content Description" icon="pen-to-square">
Detailed descriptions of visual content.
</Card>
<Card title="Format Preservation" icon="paragraph">
Maintains text formatting and structure.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Processing a document image
document_task = Task(
name="process_document",
description="Extract text and analyze document layout",
expected_output="Extracted text with layout information",
agent=image_text_agent,
images=["business_document.jpg"]
)
# Run single task
agents = PraisonAIAgents(
agents=[image_text_agent],
tasks=[document_task],
process="sequential"
)
agents.start()
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex document processing
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving text extraction accuracy
- Check out the [Image Agent](/agents/image) for pure image analysis capabilities
-139
View File
@@ -1,139 +0,0 @@
---
title: "Image Analysis Agent"
sidebarTitle: "Image Analysis"
description: "Learn how to create AI agents for image analysis and visual content understanding."
icon: "image"
---
```mermaid
flowchart LR
In[Image Input] --> Analyzer[Image Analyzer]
Analyzer --> Detector[Object Detector]
Detector --> Generator[Description Generator]
Generator --> Out[Analysis Output]
style In fill:#8B0000,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Detector fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Image Analysis Agent can process and analyze visual content, detect objects, and generate detailed descriptions.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `image_analysis.py`:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create Image Analysis Agent
image_agent = Agent(
name="ImageAnalyst",
role="Image Analysis Specialist",
goal="Analyze images and videos to extract meaningful information",
backstory="""You are an expert in computer vision and image analysis.
You excel at describing images, detecting objects, and understanding visual content.""",
llm="gpt-4o-mini",
self_reflect=False
)
# Create tasks for different types of analysis
task1 = Task(
name="analyze_landmark",
description="Describe this famous landmark and its architectural features.",
expected_output="Detailed description of the landmark's architecture and significance",
agent=image_agent,
images=["https://example.com/landmark.jpg"]
)
task2 = Task(
name="analyze_local_image",
description="What objects can you see in this image? Describe their arrangement.",
expected_output="Detailed description of objects and their spatial relationships",
agent=image_agent,
images=["local_image.jpg"]
)
# Create PraisonAIAgents instance
agents = PraisonAIAgents(
agents=[image_agent],
tasks=[task1, task2],
process="sequential",
verbose=1
)
# Run analysis
agents.start()
```
</Step>
</Steps>
## Understanding Image Analysis
The Image Analysis Agent is designed to process and understand visual content through several key capabilities:
1. **Image Input**: Supports both URL and local file inputs
2. **Object Detection**: Identifies and locates objects within images
3. **Architectural Analysis**: Specialized in analyzing architectural features
4. **Spatial Understanding**: Describes spatial relationships between objects
## Features
<CardGroup cols={2}>
<Card title="Multiple Input Sources" icon="images">
Support for both URL and local image files.
</Card>
<Card title="Object Detection" icon="magnifying-glass">
Advanced object detection and recognition.
</Card>
<Card title="Architectural Analysis" icon="building">
Specialized analysis of architectural features.
</Card>
<Card title="Detailed Descriptions" icon="pen">
Generation of comprehensive visual descriptions.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Analyzing a landmark image
landmark_task = Task(
name="analyze_famous_landmark",
description="Analyze this historical landmark",
expected_output="Architectural details and historical significance",
agent=image_agent,
images=["https://example.com/landmark.jpg"]
)
# Run single task
agents = PraisonAIAgents(
agents=[image_agent],
tasks=[landmark_task],
process="sequential"
)
agents.start()
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex image analysis workflows
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving analysis accuracy
- Check out the [Video Agent](/agents/video) for video content analysis
-120
View File
@@ -1,120 +0,0 @@
---
title: "Markdown Agent"
sidebarTitle: "Markdown"
description: "Learn how to create AI agents for generating and formatting content in Markdown."
icon: "markdown"
---
```mermaid
flowchart LR
In[Content Request] --> Generator[Content Generator]
Generator --> Formatter[Markdown Formatter]
Formatter --> Validator[Format Validator]
Validator --> Out[Markdown Output]
style In fill:#8B0000,color:#fff
style Generator fill:#2E8B57,color:#fff
style Formatter fill:#2E8B57,color:#fff
style Validator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Markdown Agent can generate and format content in Markdown syntax.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `markdown_generator.py`:
```python
from praisonaiagents import Agent
# Create Markdown Agent
markdown_agent = Agent(
name="MarkdownWriter",
role="Markdown Content Specialist",
goal="Generate well-formatted content in Markdown syntax",
instructions="You are a Markdown Agent, output in markdown format",
llm="gpt-4o-mini",
self_reflect=False
)
# Generate content
response = markdown_agent.start(
"Write a blog post about artificial intelligence"
)
# Save to file
with open('blog_post.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Markdown Generation
The Markdown Agent specializes in creating properly formatted Markdown content:
1. **Content Generation**: Creates original content based on prompts
2. **Markdown Formatting**: Applies proper Markdown syntax
3. **Structure Validation**: Ensures correct formatting
4. **Document Organization**: Creates well-structured documents
## Features
<CardGroup cols={2}>
<Card title="Content Creation" icon="pen-to-square">
Generates original, well-structured content.
</Card>
<Card title="Markdown Syntax" icon="code">
Proper implementation of Markdown formatting.
</Card>
<Card title="Document Structure" icon="sitemap">
Organized document hierarchy and sections.
</Card>
<Card title="Format Validation" icon="check">
Ensures correct Markdown syntax usage.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Generate a technical documentation
agent = Agent(
instructions="You are a Markdown Agent, output in markdown format"
)
# Generate API documentation
response = agent.start("""
Create technical documentation for a REST API with:
- Introduction
- Authentication
- Endpoints
- Examples
""")
# Save documentation
with open('api_docs.md', 'w') as f:
f.write(response)
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex document generation
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving content quality
- Check out the [Documentation Agent](/agents/documentation) for specialized documentation generation
-109
View File
@@ -1,109 +0,0 @@
---
title: "Planning Agent"
sidebarTitle: "Planning"
description: "Learn how to create AI agents for trip planning and itinerary generation."
icon: "calendar"
---
```mermaid
flowchart LR
In[Request] --> Search[Web Search]
Search --> Analyzer[Options Analyzer]
Analyzer --> Generator[Plan Generator]
Generator --> Out[Itinerary]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Planning Agent can search for travel options and create detailed itineraries.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `travel_planner.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Planning Agent
planning_agent = Agent(
name="TravelPlanner",
role="Travel Planning Specialist",
goal="Create comprehensive travel plans and itineraries",
instructions="You are a Planning Agent",
tools=[duckduckgo]
)
# Generate travel plan
response = planning_agent.start(
"I want to go to London next week, find me a good hotel and flight"
)
# Save plan
with open('travel_plan.txt', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Travel Planning
The Planning Agent combines multiple capabilities to create comprehensive travel plans:
1. **Web Search**: Uses DuckDuckGo to find current travel options
2. **Options Analysis**: Evaluates and compares different choices
3. **Plan Generation**: Creates detailed itineraries
4. **Recommendations**: Provides personalized suggestions
## Features
<CardGroup cols={2}>
<Card title="Flight Search" icon="plane">
Finds and compares flight options.
</Card>
<Card title="Hotel Booking" icon="hotel">
Recommends suitable accommodations.
</Card>
<Card title="Itinerary Creation" icon="calendar-days">
Generates detailed travel schedules.
</Card>
<Card title="Real-time Data" icon="clock">
Uses current pricing and availability.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Create a weekend trip plan
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(instructions="You are a Planning Agent", tools=[duckduckgo])
agent.start("I want to go London next week, find me a good hotel and flight")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex travel planning
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving recommendations
- Check out the [Research Agent](/agents/research) for detailed destination research
-125
View File
@@ -1,125 +0,0 @@
---
title: "Programming Agent"
sidebarTitle: "Programming"
description: "Learn how to create AI agents for code development, analysis, and execution."
icon: "code"
---
```mermaid
flowchart LR
In[Code Request] --> Analyzer[Code Analyzer]
Analyzer --> Generator[Code Generator]
Generator --> Executor[Code Executor]
Executor --> Debugger[Code Debugger]
Debugger --> Out[Output]
style In fill:#8B0000,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Executor fill:#2E8B57,color:#fff
style Debugger fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Programming Agent can analyze, generate, execute, and debug code.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `code_assistant.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import execute_code, analyze_code, format_code, lint_code, disassemble_code # Code Tools
from praisonaiagents.tools import execute_command, list_processes, kill_process, get_system_info # Shell Tools
from praisonaiagents.tools import duckduckgo # Web Search Tool
agent = Agent(
instructions="You are a Programming Agent", self_reflect=True, min_reflect=5, max_reflect=10,
tools=[execute_code, analyze_code, format_code, lint_code, disassemble_code, execute_command, list_processes, kill_process, get_system_info, duckduckgo]
)
agent.start(
"Write a python script using yfinance to find the stock price of Tesla"
"First check if required packages are installed"
"Run it using execute_code"
"execute_command if you want to run any terminal command"
"search internet using duckduckgo if you want to know update python package information"
"Analyse the output using analyze_code and fix error if required"
"if no package is installed, install it"
"then run the code"
)
```
</Step>
</Steps>
## Understanding Code Development
The Programming Agent combines multiple tools for comprehensive code development:
1. **Code Tools**:
- `execute_code`: Run Python code
- `analyze_code`: Analyze code structure
- `format_code`: Format code to standards
- `lint_code`: Check code quality
- `disassemble_code`: View bytecode
2. **Shell Tools**:
- `execute_command`: Run terminal commands
- `list_processes`: View running processes
- `kill_process`: Terminate processes
- `get_system_info`: System information
3. **Web Tools**:
- `duckduckgo`: Search for programming resources
## Features
<CardGroup cols={2}>
<Card title="Code Execution" icon="play">
Run and test code directly.
</Card>
<Card title="Code Analysis" icon="magnifying-glass-code">
Analyze and improve code quality.
</Card>
<Card title="System Integration" icon="terminal">
Execute system commands and manage processes.
</Card>
<Card title="Package Management" icon="box">
Handle dependencies and installations.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Create and run a data analysis script
response = agent.start("""
1. Create a script that:
- Uses pandas for data analysis
- Reads a CSV file
- Performs basic statistics
- Creates a visualization
2. Check and install required packages
3. Execute and analyze the results
""")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex development workflows
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving code quality
- Check out the [Data Analyst Agent](/agents/data-analyst) for specialized data analysis
-109
View File
@@ -1,109 +0,0 @@
---
title: "Recommendation Agent"
sidebarTitle: "Recommendation"
description: "Learn how to create AI agents for personalized recommendations across various domains."
icon: "thumbs-up"
---
```mermaid
flowchart LR
In[User Preferences] --> Search[Content Search]
Search --> Analyzer[Preference Analyzer]
Analyzer --> Generator[Recommendation Generator]
Generator --> Out[Recommendations]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Recommendation Agent can analyze preferences and generate personalized recommendations.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `recommendation_system.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Recommendation Agent
recommendation_agent = Agent(
name="RecommendationEngine",
role="Recommendation Specialist",
goal="Generate personalized recommendations based on preferences",
instructions="You are a Recommendation Agent",
tools=[duckduckgo]
)
# Get recommendations
response = recommendation_agent.start(
"Recommend me a good movie to watch in 2025"
)
# Save recommendations
with open('recommendations.txt', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Recommendation System
The Recommendation Agent uses multiple approaches to generate personalized suggestions:
1. **Content Search**: Uses DuckDuckGo to find current options
2. **Preference Analysis**: Understands user preferences
3. **Recommendation Generation**: Creates personalized suggestions
4. **Content Filtering**: Filters based on relevance and quality
## Features
<CardGroup cols={2}>
<Card title="Personalization" icon="user">
Tailored recommendations based on preferences.
</Card>
<Card title="Real-time Data" icon="clock">
Up-to-date content and information.
</Card>
<Card title="Multi-domain" icon="layer-group">
Recommendations across various categories.
</Card>
<Card title="Content Filtering" icon="filter">
Quality-based content selection.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Get personalized recommendations
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(instructions="You are a Recommendation Agent", tools=[duckduckgo])
agent.start("Recommend me a good movie to watch in 2025")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex recommendation systems
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving recommendation accuracy
- Check out the [Research Agent](/agents/research) for detailed content research
-108
View File
@@ -1,108 +0,0 @@
---
title: "Research Agent"
sidebarTitle: "Research"
description: "Learn how to create AI agents for conducting comprehensive research and analysis."
icon: "magnifying-glass-chart"
---
```mermaid
flowchart LR
In[Research Query] --> Search[Web Search]
Search --> Analyzer[Content Analyzer]
Analyzer --> Synthesizer[Information Synthesizer]
Synthesizer --> Out[Research Report]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Synthesizer fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Research Agent can gather, analyze, and synthesize information from various sources.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `research_assistant.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Research Agent
research_agent = Agent(
name="ResearchAssistant",
role="Research Specialist",
goal="Conduct comprehensive research and analysis",
instructions="You are a Research Agent",
tools=[duckduckgo]
)
# Conduct research
response = research_agent.start(
"Research about AI developments in 2024"
)
# Save research findings
with open('research_report.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Research Process
The Research Agent employs a systematic approach to information gathering and analysis:
1. **Web Search**: Uses DuckDuckGo to find relevant sources
2. **Content Analysis**: Evaluates source credibility and relevance
3. **Information Synthesis**: Combines findings into coherent insights
4. **Report Generation**: Creates structured research reports
## Features
<CardGroup cols={2}>
<Card title="Web Research" icon="globe">
Comprehensive online information gathering.
</Card>
<Card title="Content Analysis" icon="microscope">
In-depth evaluation of sources.
</Card>
<Card title="Information Synthesis" icon="layer-group">
Integration of multiple sources.
</Card>
<Card title="Report Generation" icon="file-lines">
Structured research documentation.
</Card>
</CardGroup>
## Example Usage
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(instructions="You are a Research Agent", tools=[duckduckgo])
agent.start("Research about AI 2024")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex research projects
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving research quality
- Check out the [Data Analyst Agent](/agents/data-analyst) for data-driven research
-109
View File
@@ -1,109 +0,0 @@
---
title: "Shopping Agent"
sidebarTitle: "Shopping"
description: "Learn how to create AI agents for price comparison and shopping assistance."
icon: "shop"
---
```mermaid
flowchart LR
In[Product Query] --> Search[Store Search]
Search --> Analyzer[Price Analyzer]
Analyzer --> Comparator[Price Comparator]
Comparator --> Out[Price Report]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Comparator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Shopping Agent can search for products, compare prices, and provide shopping recommendations.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `shopping_assistant.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Shopping Agent
shopping_agent = Agent(
name="ShoppingAssistant",
role="Shopping Specialist",
goal="Find the best prices and deals across stores",
instructions="You are a Shopping Agent",
tools=[duckduckgo]
)
# Search for product prices
response = shopping_agent.start(
"I want to buy iPhone 16 Pro Max, check 5 stores and give me price in table"
)
# Save price comparison
with open('price_comparison.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Shopping Assistant
The Shopping Agent combines multiple capabilities for effective price comparison:
1. **Store Search**: Uses DuckDuckGo to find retailers
2. **Price Analysis**: Gathers pricing information
3. **Price Comparison**: Compares prices across stores
4. **Deal Finding**: Identifies special offers and discounts
## Features
<CardGroup cols={2}>
<Card title="Price Comparison" icon="scale-balanced">
Compare prices across multiple stores.
</Card>
<Card title="Deal Detection" icon="tag">
Find special offers and discounts.
</Card>
<Card title="Store Analysis" icon="store">
Evaluate retailer reliability.
</Card>
<Card title="Price Tracking" icon="chart-line">
Monitor price changes over time.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Compare product prices
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(instructions="You are a Shopping Agent", tools=[duckduckgo])
agent.start("I want to buy iPhone 16 Pro Max, check 5 stores and give me price in table")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex shopping research
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving price accuracy
- Check out the [Research Agent](/agents/research) for detailed product research
-102
View File
@@ -1,102 +0,0 @@
---
title: "Single Agent"
sidebarTitle: "Single"
description: "Learn how to create a basic single-purpose AI agent for simple tasks."
icon: "circle-1"
---
```mermaid
flowchart LR
In[Input] --> Agent[Single Agent]
Agent --> Out[Output]
style In fill:#8B0000,color:#fff
style Agent fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how to create and use a simple single-purpose agent.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `simple_agent.py`:
```python
from praisonaiagents import Agent
agent = Agent(instructions="You are a Markdown Agent, output in markdown format")
agent.start("Write a blog post about AI")
```
</Step>
</Steps>
## Understanding Single Agent
The Single Agent is the simplest form of PraisonAI agent:
1. **Simple Setup**: Minimal configuration required
2. **Single Purpose**: Focused on one specific task
3. **Direct Execution**: Straightforward input-output flow
4. **No Dependencies**: No external tools required
## Features
<CardGroup cols={2}>
<Card title="Simple Setup" icon="square-1">
Minimal configuration needed.
</Card>
<Card title="Focused Task" icon="bullseye">
Single-purpose execution.
</Card>
<Card title="Quick Start" icon="bolt">
Rapid implementation.
</Card>
<Card title="No Tools" icon="toolbox">
No external dependencies.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Create a content generation agent
from praisonaiagents import Agent
# Create content agent
agent = Agent(
instructions="You are a Content Generation Agent, create engaging content"
)
# Generate content
response = agent.start("""
Write a short story about:
- A future world
- With advanced AI
- And human collaboration
""")
# Save the story
with open('ai_story.txt', 'w') as f:
f.write(response)
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for more complex workflows
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving output quality
- Check out other specialized agents like the [Markdown Agent](/agents/markdown) for specific use cases
-149
View File
@@ -1,149 +0,0 @@
---
title: "Video Agent"
sidebarTitle: "Video"
description: "Learn how to create AI agents for video analysis and content understanding."
icon: "video"
---
```mermaid
flowchart LR
In[Video Input] --> Analyzer[Content Analyzer]
Analyzer --> Detector[Object Detector]
Detector --> Transcriber[Text Transcriber]
Transcriber --> Out[Analysis Report]
style In fill:#8B0000,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Detector fill:#2E8B57,color:#fff
style Transcriber fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Video Agent can analyze video content, detect objects, and extract meaningful information.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `video_analyzer.py`:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create Video Analysis Agent
video_agent = Agent(
name="VideoAnalyst",
role="Video Analysis Specialist",
goal="Analyze videos to extract meaningful information",
backstory="""You are an expert in computer vision and video analysis.
You excel at describing content, detecting objects, and understanding context.""",
llm="gpt-4o-mini",
self_reflect=False
)
# Create video analysis task
analysis_task = Task(
name="analyze_video",
description="""Analyze this video and provide:
1. Summary of main events
2. Key objects and people
3. Text and important information
4. Context and setting""",
expected_output="Comprehensive video analysis",
agent=video_agent,
images=["video.mp4"]
)
# Create PraisonAIAgents instance
agents = PraisonAIAgents(
agents=[video_agent],
tasks=[analysis_task],
process="sequential",
verbose=1
)
# Run analysis
agents.start()
```
</Step>
</Steps>
## Understanding Video Analysis
The Video Agent combines multiple capabilities for comprehensive video understanding:
1. **Content Analysis**: Analyzes video scenes and events
2. **Object Detection**: Identifies objects and people
3. **Text Extraction**: Captures text shown in videos
4. **Context Understanding**: Interprets settings and situations
## Features
<CardGroup cols={2}>
<Card title="Scene Analysis" icon="film">
Detailed analysis of video scenes.
</Card>
<Card title="Object Detection" icon="cube">
Identification of objects and people.
</Card>
<Card title="Text Extraction" icon="closed-captioning">
Capture of text and captions.
</Card>
<Card title="Context Analysis" icon="sitemap">
Understanding of video context.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Analyze a presentation video
from praisonaiagents import Agent, Task, PraisonAIAgents
video_agent = Agent(
name="VideoAnalyst",
role="Video Analysis Specialist",
goal="Extract information from presentation videos",
llm="gpt-4o-mini"
)
# Create presentation analysis task
presentation_task = Task(
name="analyze_presentation",
description="""Analyze this presentation video:
1. Extract key points
2. Capture slide content
3. Note speaker's main arguments
4. Summarize Q&A session""",
expected_output="Detailed presentation summary",
agent=video_agent,
images=["presentation.mp4"]
)
# Run analysis
agents = PraisonAIAgents(
agents=[video_agent],
tasks=[presentation_task],
process="sequential"
)
agents.start()
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex video analysis
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving analysis accuracy
- Check out the [Image Agent](/agents/image) for still image analysis
-124
View File
@@ -1,124 +0,0 @@
---
title: "Web Search Agent"
sidebarTitle: "Web Search"
description: "Learn how to create AI agents for intelligent web searching and information gathering."
icon: "globe"
---
```mermaid
flowchart LR
In[Search Query] --> Search[Web Search]
Search --> Filter[Content Filter]
Filter --> Summarizer[Content Summarizer]
Summarizer --> Out[Search Results]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Filter fill:#2E8B57,color:#fff
style Summarizer fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Web Search Agent can perform intelligent searches and process web content.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `web_search.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Web Search Agent
search_agent = Agent(
name="WebSearcher",
role="Web Search Specialist",
goal="Perform intelligent web searches and gather information",
instructions="You are a Web Search Agent",
tools=[duckduckgo]
)
# Perform search
response = search_agent.start(
"Search about AI developments in 2024"
)
# Save search results
with open('search_results.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Web Search
The Web Search Agent employs sophisticated search strategies:
1. **Query Processing**: Optimizes search queries
2. **Content Filtering**: Filters relevant results
3. **Information Extraction**: Extracts key information
4. **Result Summarization**: Summarizes findings
## Features
<CardGroup cols={2}>
<Card title="Smart Search" icon="magnifying-glass">
Intelligent query processing.
</Card>
<Card title="Content Filtering" icon="filter">
Relevance-based filtering.
</Card>
<Card title="Information Extraction" icon="scissors">
Key information extraction.
</Card>
<Card title="Result Summary" icon="list">
Concise result summaries.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Perform topic research
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(
instructions="You are a Web Search Agent",
tools=[duckduckgo]
)
# Research specific topic
response = agent.start("""
Search for information about quantum computing:
- Recent breakthroughs
- Leading companies
- Current applications
- Future predictions
""")
# Save research results
with open('quantum_computing_research.md', 'w') as f:
f.write(response)
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex search workflows
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving search relevance
- Check out the [Research Agent](/agents/research) for comprehensive research capabilities
-139
View File
@@ -1,139 +0,0 @@
---
title: "Wikipedia Agent"
sidebarTitle: "Wikipedia"
description: "Learn how to create AI agents for searching and extracting information from Wikipedia."
icon: "book"
---
```mermaid
flowchart LR
In[Query] --> Search[Wiki Search]
Search --> Page[Page Retrieval]
Page --> Summary[Content Summary]
Summary --> Out[Knowledge Output]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Page fill:#2E8B57,color:#fff
style Summary fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Wikipedia Agent can search, retrieve, and summarize Wikipedia content.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `wikipedia_assistant.py`:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import (
wiki_search,
wiki_summary,
wiki_page,
wiki_random,
wiki_language
)
# Create Wikipedia Agent
wiki_agent = Agent(
name="WikipediaAssistant",
role="Wikipedia Research Specialist",
goal="Extract and summarize Wikipedia content",
instructions="You are a Wikipedia Agent",
tools=[
wiki_search,
wiki_summary,
wiki_page,
wiki_random,
wiki_language
],
self_reflect=True,
min_reflect=3,
max_reflect=5
)
# Research a topic
response = wiki_agent.start("""
What is the history of AI?
First search the history of AI
Read the page of the history of AI
Get the summary of the page
""")
# Save research results
with open('ai_history.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Wikipedia Research
The Wikipedia Agent provides comprehensive Wikipedia access through multiple tools:
1. **Wiki Search**: `wiki_search` for finding relevant articles
2. **Page Access**: `wiki_page` for retrieving full articles
3. **Summarization**: `wiki_summary` for concise overviews
4. **Random Articles**: `wiki_random` for discovering content
5. **Language Support**: `wiki_language` for multilingual access
## Features
<CardGroup cols={2}>
<Card title="Article Search" icon="magnifying-glass">
Find relevant Wikipedia articles.
</Card>
<Card title="Content Retrieval" icon="book-open">
Access complete article content.
</Card>
<Card title="Summarization" icon="compress">
Generate concise article summaries.
</Card>
<Card title="Multilingual" icon="language">
Access content in multiple languages.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Research a scientific topic
from praisonaiagents import Agent
from praisonaiagents.tools import wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language
agent = Agent(
instructions="You are a Wikipedia Agent",
tools=[wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language],
self_reflect=True,
min_reflect=3,
max_reflect=5,
)
agent.start(
"What is the history of AI?"
"First search the history of AI"
"Read the page of the history of AI"
"Get the summary of the page"
)
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex Wikipedia research
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving research quality
- Check out the [Research Agent](/agents/research) for broader research capabilities
-45
View File
@@ -1,45 +0,0 @@
---
title: 'API Reference'
description: 'PraisonAI API documentation with framework-specific details'
icon: "book-open"
---
# API Reference
This section provides detailed information about the PraisonAI API and its framework-specific implementations.
## Core Modules
- [praisonai](../api/praisonai/index) - Core package functionality
- [praisonai.auto](../api/praisonai/auto) - Automated agent generation
- [praisonai.agents_generator](../api/praisonai/agents_generator) - Framework-specific agent generation
- [praisonai.cli](../api/praisonai/cli) - Command-line interface
- [praisonai.deploy](../api/praisonai/deploy) - Deployment utilities
## Framework Support
### CrewAI Integration
Requires installation with:
```bash
pip install "praisonai[crewai]"
```
Features:
- Task delegation
- Sequential/parallel execution
- Built-in tools
- Structured workflows
### AutoGen Integration
Requires installation with:
```bash
pip install "praisonai[autogen]"
```
Features:
- Multi-agent conversations
- Code execution
- Built-in tools
- Flexible interactions
For detailed API documentation of each module, please refer to the generated files in the `api` folder.
-79
View File
@@ -1,79 +0,0 @@
---
title: "API Reference"
description: "Complete API reference for PraisonAI, including core modules, installation options, and framework-specific features"
icon: "code"
---
## Core Modules
### praisonai
The main package containing core functionality.
```python
from praisonai import PraisonAI
```
### praisonai.auto
Automated agent generation functionality.
```python
from praisonai.auto import AutoGenerator
```
### praisonai.agents_generator
Framework-specific agent generation and orchestration:
- CrewAI support (requires `praisonai[crewai]`)
- AutoGen support (requires `praisonai[autogen]`)
```python
from praisonai.agents_generator import AgentsGenerator
```
### praisonai.cli
Command-line interface with framework-specific handling.
```python
from praisonai.cli import PraisonAI
```
### praisonai.deploy
Deployment utilities.
```python
from praisonai.deploy import CloudDeployer
```
## Installation Options
```bash
# Basic installation
pip install praisonai
# Framework-specific installations
pip install "praisonai[crewai]" # Install with CrewAI support
pip install "praisonai[autogen]" # Install with AutoGen support
pip install "praisonai[crewai,autogen]" # Install both frameworks
# Additional features
pip install "praisonai[ui]" # Install UI support
pip install "praisonai[chat]" # Install Chat interface
pip install "praisonai[code]" # Install Code interface
pip install "praisonai[realtime]" # Install Realtime voice interaction
pip install "praisonai[call]" # Install Call feature
```
## Framework-specific Features
### CrewAI
When installing with `pip install "praisonai[crewai]"`, you get:
- CrewAI framework support
- PraisonAI tools integration
- Task delegation capabilities
- Sequential and parallel task execution
### AutoGen
When installing with `pip install "praisonai[autogen]"`, you get:
- AutoGen framework support
- PraisonAI tools integration
- Multi-agent conversation capabilities
- Code execution environment
-566
View File
@@ -1,566 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.agents_generator API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.agents_generator</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.agents_generator.disable_crewai_telemetry"><code class="name flex">
<span>def <span class="ident">disable_crewai_telemetry</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.agents_generator.noop"><code class="name flex">
<span>def <span class="ident">noop</span></span>(<span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.agents_generator.AgentsGenerator"><code class="flex name class">
<span>class <span class="ident">AgentsGenerator</span></span>
<span>(</span><span>agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None, tools=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initialize the AgentsGenerator object.</p>
<h2 id="parameters">Parameters</h2>
<p>agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
log_level (int, optional): The logging level to use. Defaults to logging.INFO.
agent_callback (callable, optional): A callback function to be executed after each agent step.
task_callback (callable, optional): A callback function to be executed after each tool run.
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
tools (dict, optional): A dictionary containing the tools to be used for the agents. Defaults to None.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code></dt>
<dd>The path to the agent file.</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code></dt>
<dd>The framework to be used for the agents.</dd>
<dt><strong><code>config_list</code></strong> :&ensp;<code>list</code></dt>
<dd>A list of configurations for the agents.</dd>
<dt><strong><code>log_level</code></strong> :&ensp;<code>int</code></dt>
<dd>The logging level to use.</dd>
<dt><strong><code>agent_callback</code></strong> :&ensp;<code>callable</code>, optional</dt>
<dd>A callback function to be executed after each agent step.</dd>
<dt><strong><code>task_callback</code></strong> :&ensp;<code>callable</code>, optional</dt>
<dd>A callback function to be executed after each tool run.</dd>
<dt><strong><code>tools</code></strong> :&ensp;<code>dict</code></dt>
<dd>A dictionary containing the tools to be used for the agents.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class AgentsGenerator:
def __init__(self, agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None, tools=None):
&#34;&#34;&#34;
Initialize the AgentsGenerator object.
Parameters:
agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
log_level (int, optional): The logging level to use. Defaults to logging.INFO.
agent_callback (callable, optional): A callback function to be executed after each agent step.
task_callback (callable, optional): A callback function to be executed after each tool run.
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
tools (dict, optional): A dictionary containing the tools to be used for the agents. Defaults to None.
Attributes:
agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
log_level (int): The logging level to use.
agent_callback (callable, optional): A callback function to be executed after each agent step.
task_callback (callable, optional): A callback function to be executed after each tool run.
tools (dict): A dictionary containing the tools to be used for the agents.
&#34;&#34;&#34;
self.agent_file = agent_file
self.framework = framework
self.config_list = config_list
self.log_level = log_level
self.agent_callback = agent_callback
self.task_callback = task_callback
self.agent_yaml = agent_yaml
self.tools = tools or [] # Store tool class names as a list
self.log_level = log_level or logging.getLogger().getEffectiveLevel()
if self.log_level == logging.NOTSET:
self.log_level = os.environ.get(&#39;LOGLEVEL&#39;, &#39;INFO&#39;).upper()
logging.basicConfig(level=self.log_level, format=&#39;%(asctime)s - %(levelname)s - %(message)s&#39;)
self.logger = logging.getLogger(__name__)
self.logger.setLevel(self.log_level)
def is_function_or_decorated(self, obj):
&#34;&#34;&#34;
Checks if the given object is a function or has a __call__ method.
Parameters:
obj (object): The object to be checked.
Returns:
bool: True if the object is a function or has a __call__ method, False otherwise.
&#34;&#34;&#34;
return inspect.isfunction(obj) or hasattr(obj, &#39;__call__&#39;)
def load_tools_from_module(self, module_path):
&#34;&#34;&#34;
Loads tools from a specified module path.
Parameters:
module_path (str): The path to the module containing the tools.
Returns:
dict: A dictionary containing the names of the tools as keys and the corresponding functions or objects as values.
Raises:
FileNotFoundError: If the specified module path does not exist.
&#34;&#34;&#34;
spec = importlib.util.spec_from_file_location(&#34;tools_module&#34;, module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return {name: obj for name, obj in inspect.getmembers(module, self.is_function_or_decorated)}
def load_tools_from_module_class(self, module_path):
&#34;&#34;&#34;
Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.
Parameters:
module_path (str): The path to the module containing the tools.
Returns:
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
Raises:
FileNotFoundError: If the specified module path does not exist.
&#34;&#34;&#34;
spec = importlib.util.spec_from_file_location(&#34;tools_module&#34;, module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return {name: obj() for name, obj in inspect.getmembers(module, lambda x: inspect.isclass(x) and (x.__module__.startswith(&#39;langchain_community.tools&#39;) or issubclass(x, BaseTool)) and x is not BaseTool)}
def load_tools_from_package(self, package_path):
&#34;&#34;&#34;
Loads tools from a specified package path containing modules with functions or classes.
Parameters:
package_path (str): The path to the package containing the tools.
Returns:
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
Raises:
FileNotFoundError: If the specified package path does not exist.
This function iterates through all the .py files in the specified package path, excluding those that start with &#34;__&#34;. For each file, it imports the corresponding module and checks if it contains any functions or classes that can be loaded as tools. The function then returns a dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
&#34;&#34;&#34;
tools_dict = {}
for module_file in os.listdir(package_path):
if module_file.endswith(&#39;.py&#39;) and not module_file.startswith(&#39;__&#39;):
module_name = f&#34;{package_path.name}.{module_file[:-3]}&#34; # Remove .py for import
module = importlib.import_module(module_name)
for name, obj in inspect.getmembers(module, self.is_function_or_decorated):
tools_dict[name] = obj
return tools_dict
def generate_crew_and_kickoff(self):
&#34;&#34;&#34;
Generates a crew of agents and initiates tasks based on the provided configuration.
Parameters:
agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
Returns:
str: The output of the tasks performed by the crew of agents.
Raises:
FileNotFoundError: If the specified agent file does not exist.
This function first loads the agent configuration from the specified file. It then initializes the tools required for the agents based on the specified framework. If the specified framework is &#34;autogen&#34;, it loads the LLM configuration dynamically and creates an AssistantAgent for each role in the configuration. It then adds tools to the agents if specified in the configuration. Finally, it prepares tasks for the agents based on the configuration and initiates the tasks using the crew of agents. If the specified framework is not &#34;autogen&#34;, it creates a crew of agents and initiates tasks based on the configuration.
&#34;&#34;&#34;
if self.agent_yaml:
config = yaml.safe_load(self.agent_yaml)
else:
if self.agent_file == &#39;/app/api:app&#39; or self.agent_file == &#39;api:app&#39;:
self.agent_file = &#39;agents.yaml&#39;
try:
with open(self.agent_file, &#39;r&#39;) as f:
config = yaml.safe_load(f)
except FileNotFoundError:
print(f&#34;File not found: {self.agent_file}&#34;)
return
topic = config[&#39;topic&#39;]
tools_dict = {
&#39;CodeDocsSearchTool&#39;: CodeDocsSearchTool(),
&#39;CSVSearchTool&#39;: CSVSearchTool(),
&#39;DirectorySearchTool&#39;: DirectorySearchTool(),
&#39;DOCXSearchTool&#39;: DOCXSearchTool(),
&#39;DirectoryReadTool&#39;: DirectoryReadTool(),
&#39;FileReadTool&#39;: FileReadTool(),
# &#39;GithubSearchTool&#39;: GithubSearchTool(),
# &#39;SeperDevTool&#39;: SeperDevTool(),
&#39;TXTSearchTool&#39;: TXTSearchTool(),
&#39;JSONSearchTool&#39;: JSONSearchTool(),
&#39;MDXSearchTool&#39;: MDXSearchTool(),
&#39;PDFSearchTool&#39;: PDFSearchTool(),
# &#39;PGSearchTool&#39;: PGSearchTool(),
&#39;RagTool&#39;: RagTool(),
&#39;ScrapeElementFromWebsiteTool&#39;: ScrapeElementFromWebsiteTool(),
&#39;ScrapeWebsiteTool&#39;: ScrapeWebsiteTool(),
&#39;WebsiteSearchTool&#39;: WebsiteSearchTool(),
&#39;XMLSearchTool&#39;: XMLSearchTool(),
&#39;YoutubeChannelSearchTool&#39;: YoutubeChannelSearchTool(),
&#39;YoutubeVideoSearchTool&#39;: YoutubeVideoSearchTool(),
}
# Add tools from class names
for tool_class in self.tools:
if isinstance(tool_class, type) and issubclass(tool_class, BaseTool):
tool_name = tool_class.__name__
tools_dict[tool_name] = tool_class()
self.logger.debug(f&#34;Added tool: {tool_name}&#34;)
root_directory = os.getcwd()
tools_py_path = os.path.join(root_directory, &#39;tools.py&#39;)
tools_dir_path = Path(root_directory) / &#39;tools&#39;
if os.path.isfile(tools_py_path):
tools_dict.update(self.load_tools_from_module_class(tools_py_path))
self.logger.debug(&#34;tools.py exists in the root directory. Loading tools.py and skipping tools folder.&#34;)
elif tools_dir_path.is_dir():
tools_dict.update(self.load_tools_from_module_class(tools_dir_path))
self.logger.debug(&#34;tools folder exists in the root directory&#34;)
framework = self.framework or config.get(&#39;framework&#39;)
agents = {}
tasks = []
if framework == &#34;autogen&#34;:
# Load the LLM configuration dynamically
# print(self.config_list)
llm_config = {&#34;config_list&#34;: self.config_list}
if agentops_exists:
agentops.init(os.environ.get(&#34;AGENTOPS_API_KEY&#34;), tags=[&#34;autogen&#34;])
# Assuming the user proxy agent is set up as per your requirements
user_proxy = autogen.UserProxyAgent(
name=&#34;User&#34;,
human_input_mode=&#34;NEVER&#34;,
is_termination_msg=lambda x: (x.get(&#34;content&#34;) or &#34;&#34;).rstrip().rstrip(&#34;.&#34;).lower().endswith(&#34;terminate&#34;) or &#34;TERMINATE&#34; in (x.get(&#34;content&#34;) or &#34;&#34;),
code_execution_config={
&#34;work_dir&#34;: &#34;coding&#34;,
&#34;use_docker&#34;: False,
},
# additional setup for the user proxy agent
)
for role, details in config[&#39;roles&#39;].items():
agent_name = details[&#39;role&#39;].format(topic=topic).replace(&#34;{topic}&#34;, topic)
agent_goal = details[&#39;goal&#39;].format(topic=topic)
# Creating an AssistantAgent for each role dynamically
agents[role] = autogen.AssistantAgent(
name=agent_name,
llm_config=llm_config,
system_message=details[&#39;backstory&#39;].format(topic=topic)+&#34;. Must Reply \&#34;TERMINATE\&#34; in the end when everything is done.&#34;,
)
for tool in details.get(&#39;tools&#39;, []):
if tool in tools_dict:
try:
tool_class = globals()[f&#39;autogen_{type(tools_dict[tool]).__name__}&#39;]
print(f&#34;Found {tool_class.__name__} for {tool}&#34;)
except KeyError:
print(f&#34;Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.&#34;)
continue
tool_class(agents[role], user_proxy)
# Preparing tasks for initiate_chats
for task_name, task_details in details.get(&#39;tasks&#39;, {}).items():
description_filled = task_details[&#39;description&#39;].format(topic=topic)
expected_output_filled = task_details[&#39;expected_output&#39;].format(topic=topic)
chat_task = {
&#34;recipient&#34;: agents[role],
&#34;message&#34;: description_filled,
&#34;summary_method&#34;: &#34;last_msg&#34;,
# Additional fields like carryover can be added based on dependencies
}
tasks.append(chat_task)
response = user_proxy.initiate_chats(tasks)
result = &#34;### Output ###\n&#34;+response[-1].summary if hasattr(response[-1], &#39;summary&#39;) else &#34;&#34;
if agentops_exists:
agentops.end_session(&#34;Success&#34;)
else: # framework=crewai
if agentops_exists:
agentops.init(os.environ.get(&#34;AGENTOPS_API_KEY&#34;), tags=[&#34;crewai&#34;])
tasks_dict = {}
for role, details in config[&#39;roles&#39;].items():
role_filled = details[&#39;role&#39;].format(topic=topic)
goal_filled = details[&#39;goal&#39;].format(topic=topic)
backstory_filled = details[&#39;backstory&#39;].format(topic=topic)
# Adding tools to the agent if exists
agent_tools = [tools_dict[tool] for tool in details.get(&#39;tools&#39;, []) if tool in tools_dict]
llm_model = details.get(&#39;llm&#39;) # Get the llm configuration
if llm_model:
llm = PraisonAIModel(
model=llm_model.get(&#34;model&#34;, os.environ.get(&#34;MODEL_NAME&#34;, &#34;openai/gpt-4o&#34;)),
).get_model()
else:
llm = PraisonAIModel().get_model()
function_calling_llm_model = details.get(&#39;function_calling_llm&#39;)
if function_calling_llm_model:
function_calling_llm = PraisonAIModel(
model=function_calling_llm_model.get(&#34;model&#34;, os.environ.get(&#34;MODEL_NAME&#34;, &#34;openai/gpt-4o&#34;)),
).get_model()
else:
function_calling_llm = PraisonAIModel().get_model()
agent = Agent(
role=role_filled,
goal=goal_filled,
backstory=backstory_filled,
tools=agent_tools,
allow_delegation=details.get(&#39;allow_delegation&#39;, False),
llm=llm,
function_calling_llm=function_calling_llm,
max_iter=details.get(&#39;max_iter&#39;, 15),
max_rpm=details.get(&#39;max_rpm&#39;),
max_execution_time=details.get(&#39;max_execution_time&#39;),
verbose=details.get(&#39;verbose&#39;, True),
cache=details.get(&#39;cache&#39;, True),
system_template=details.get(&#39;system_template&#39;),
prompt_template=details.get(&#39;prompt_template&#39;),
response_template=details.get(&#39;response_template&#39;),
)
# Set agent callback if provided
if self.agent_callback:
agent.step_callback = self.agent_callback
agents[role] = agent
for task_name, task_details in details.get(&#39;tasks&#39;, {}).items():
description_filled = task_details[&#39;description&#39;].format(topic=topic)
expected_output_filled = task_details[&#39;expected_output&#39;].format(topic=topic)
task = Task(
description=description_filled, # Clear, concise statement of what the task entails
expected_output=expected_output_filled, # Detailed description of what task&#39;s completion looks like
agent=agent, # The agent responsible for the task
tools=task_details.get(&#39;tools&#39;, []), # Functions or capabilities the agent can utilize
async_execution=task_details.get(&#39;async_execution&#39;) if task_details.get(&#39;async_execution&#39;) is not None else False, # Execute asynchronously if set
context=[], ## TODO:
config=task_details.get(&#39;config&#39;) if task_details.get(&#39;config&#39;) is not None else {}, # Additional configuration details
output_json=task_details.get(&#39;output_json&#39;) if task_details.get(&#39;output_json&#39;) is not None else None, # Outputs a JSON object
output_pydantic=task_details.get(&#39;output_pydantic&#39;) if task_details.get(&#39;output_pydantic&#39;) is not None else None, # Outputs a Pydantic model object
output_file=task_details.get(&#39;output_file&#39;) if task_details.get(&#39;output_file&#39;) is not None else &#34;&#34;, # Saves the task output to a file
callback=task_details.get(&#39;callback&#39;) if task_details.get(&#39;callback&#39;) is not None else None, # Python callable executed with the task&#39;s output
human_input=task_details.get(&#39;human_input&#39;) if task_details.get(&#39;human_input&#39;) is not None else False, # Indicates if the task requires human feedback
create_directory=task_details.get(&#39;create_directory&#39;) if task_details.get(&#39;create_directory&#39;) is not None else False # Indicates if a directory needs to be created
)
# Set tool callback if provided
if self.task_callback:
task.callback = self.task_callback
tasks.append(task)
tasks_dict[task_name] = task
for role, details in config[&#39;roles&#39;].items():
for task_name, task_details in details.get(&#39;tasks&#39;, {}).items():
task = tasks_dict[task_name]
context_tasks = [tasks_dict[ctx] for ctx in task_details.get(&#39;context&#39;, []) if ctx in tasks_dict]
task.context = context_tasks
crew = Crew(
agents=list(agents.values()),
tasks=tasks,
verbose=2
)
self.logger.debug(&#34;Final Crew Configuration:&#34;)
self.logger.debug(f&#34;Agents: {crew.agents}&#34;)
self.logger.debug(f&#34;Tasks: {crew.tasks}&#34;)
response = crew.kickoff()
result = f&#34;### Task Output ###\n{response}&#34;
if agentops_exists:
agentops.end_session(&#34;Success&#34;)
return result</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff"><code class="name flex">
<span>def <span class="ident">generate_crew_and_kickoff</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates a crew of agents and initiates tasks based on the provided configuration.</p>
<h2 id="parameters">Parameters</h2>
<p>agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>str</code></dt>
<dd>The output of the tasks performed by the crew of agents.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified agent file does not exist.</dd>
</dl>
<p>This function first loads the agent configuration from the specified file. It then initializes the tools required for the agents based on the specified framework. If the specified framework is "autogen", it loads the LLM configuration dynamically and creates an AssistantAgent for each role in the configuration. It then adds tools to the agents if specified in the configuration. Finally, it prepares tasks for the agents based on the configuration and initiates the tasks using the crew of agents. If the specified framework is not "autogen", it creates a crew of agents and initiates tasks based on the configuration.</p></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.is_function_or_decorated"><code class="name flex">
<span>def <span class="ident">is_function_or_decorated</span></span>(<span>self, obj)</span>
</code></dt>
<dd>
<div class="desc"><p>Checks if the given object is a function or has a <strong>call</strong> method.</p>
<h2 id="parameters">Parameters</h2>
<p>obj (object): The object to be checked.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>bool</code></dt>
<dd>True if the object is a function or has a <strong>call</strong> method, False otherwise.</dd>
</dl></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.load_tools_from_module"><code class="name flex">
<span>def <span class="ident">load_tools_from_module</span></span>(<span>self, module_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads tools from a specified module path.</p>
<h2 id="parameters">Parameters</h2>
<p>module_path (str): The path to the module containing the tools.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>dict</code></dt>
<dd>A dictionary containing the names of the tools as keys and the corresponding functions or objects as values.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified module path does not exist.</dd>
</dl></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.load_tools_from_module_class"><code class="name flex">
<span>def <span class="ident">load_tools_from_module_class</span></span>(<span>self, module_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.</p>
<h2 id="parameters">Parameters</h2>
<p>module_path (str): The path to the module containing the tools.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>dict</code></dt>
<dd>A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified module path does not exist.</dd>
</dl></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.load_tools_from_package"><code class="name flex">
<span>def <span class="ident">load_tools_from_package</span></span>(<span>self, package_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads tools from a specified package path containing modules with functions or classes.</p>
<h2 id="parameters">Parameters</h2>
<p>package_path (str): The path to the package containing the tools.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>dict</code></dt>
<dd>A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified package path does not exist.</dd>
</dl>
<p>This function iterates through all the .py files in the specified package path, excluding those that start with "__". For each file, it imports the corresponding module and checks if it contains any functions or classes that can be loaded as tools. The function then returns a dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.agents_generator.disable_crewai_telemetry" href="#praisonai.agents_generator.disable_crewai_telemetry">disable_crewai_telemetry</a></code></li>
<li><code><a title="praisonai.agents_generator.noop" href="#praisonai.agents_generator.noop">noop</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.agents_generator.AgentsGenerator" href="#praisonai.agents_generator.AgentsGenerator">AgentsGenerator</a></code></h4>
<ul class="">
<li><code><a title="praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff" href="#praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff">generate_crew_and_kickoff</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.is_function_or_decorated" href="#praisonai.agents_generator.AgentsGenerator.is_function_or_decorated">is_function_or_decorated</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.load_tools_from_module" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_module">load_tools_from_module</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.load_tools_from_module_class" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_module_class">load_tools_from_module_class</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.load_tools_from_package" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_package">load_tools_from_package</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-622
View File
@@ -1,622 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.auto API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.auto</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.auto.AutoGenerator"><code class="flex name class">
<span>class <span class="ident">AutoGenerator</span></span>
<span>(</span><span>topic='Movie Story writing about AI', agent_file='test.yaml', framework='crewai', config_list: Optional[List[Dict]] = None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initialize the AutoGenerator class with the specified topic, agent file, and framework.
Note: autogen framework is different from this AutoGenerator class.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>topic</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The topic for the generated team structure. Defaults to "Movie Story writing about AI".</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The name of the YAML file to save the generated team structure. Defaults to "test.yaml".</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The framework for the generated team structure. Defaults to "crewai".</dd>
<dt><strong><code>config_list</code></strong> :&ensp;<code>Optional[List[Dict]]</code>, optional</dt>
<dd>A list containing the configuration details for the OpenAI API.
If None, it defaults to using environment variables or hardcoded values.</dd>
</dl>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>config_list</code></strong> :&ensp;<code>list</code></dt>
<dd>A list containing the configuration details for the OpenAI API.</dd>
<dt><strong><code>topic</code></strong> :&ensp;<code>str</code></dt>
<dd>The specified topic for the generated team structure.</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code></dt>
<dd>The specified name of the YAML file to save the generated team structure.</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code></dt>
<dd>The specified framework for the generated team structure.</dd>
<dt><strong><code>client</code></strong> :&ensp;<code>instructor.Client</code></dt>
<dd>An instance of the instructor.Client class initialized with the specified OpenAI API configuration.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class AutoGenerator:
def __init__(self, topic=&#34;Movie Story writing about AI&#34;, agent_file=&#34;test.yaml&#34;, framework=&#34;crewai&#34;, config_list: Optional[List[Dict]] = None):
&#34;&#34;&#34;
Initialize the AutoGenerator class with the specified topic, agent file, and framework.
Note: autogen framework is different from this AutoGenerator class.
Args:
topic (str, optional): The topic for the generated team structure. Defaults to &#34;Movie Story writing about AI&#34;.
agent_file (str, optional): The name of the YAML file to save the generated team structure. Defaults to &#34;test.yaml&#34;.
framework (str, optional): The framework for the generated team structure. Defaults to &#34;crewai&#34;.
config_list (Optional[List[Dict]], optional): A list containing the configuration details for the OpenAI API.
If None, it defaults to using environment variables or hardcoded values.
Attributes:
config_list (list): A list containing the configuration details for the OpenAI API.
topic (str): The specified topic for the generated team structure.
agent_file (str): The specified name of the YAML file to save the generated team structure.
framework (str): The specified framework for the generated team structure.
client (instructor.Client): An instance of the instructor.Client class initialized with the specified OpenAI API configuration.
&#34;&#34;&#34;
self.config_list = config_list or [
{
&#39;model&#39;: os.environ.get(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;),
&#39;base_url&#39;: os.environ.get(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;),
&#39;api_key&#39;: os.environ.get(&#34;OPENAI_API_KEY&#34;)
}
]
self.topic = topic
self.agent_file = agent_file
self.framework = framework or &#34;crewai&#34;
self.client = instructor.patch(
OpenAI(
base_url=self.config_list[0][&#39;base_url&#39;],
api_key=os.getenv(&#34;OPENAI_API_KEY&#34;),
),
mode=instructor.Mode.JSON,
)
def generate(self):
&#34;&#34;&#34;
Generates a team structure for the specified topic.
Args:
None
Returns:
str: The full path of the YAML file containing the generated team structure.
Raises:
Exception: If the generation process fails.
Usage:
generator = AutoGenerator(framework=&#34;crewai&#34;, topic=&#34;Create a movie script about Cat in Mars&#34;)
path = generator.generate()
print(path)
&#34;&#34;&#34;
response = self.client.chat.completions.create(
model=self.config_list[0][&#39;model&#39;],
response_model=TeamStructure,
max_retries=10,
messages=[
{&#34;role&#34;: &#34;system&#34;, &#34;content&#34;: &#34;You are a helpful assistant designed to output complex team structures.&#34;},
{&#34;role&#34;: &#34;user&#34;, &#34;content&#34;: self.get_user_content()}
]
)
json_data = json.loads(response.model_dump_json())
self.convert_and_save(json_data)
full_path = os.path.abspath(self.agent_file)
return full_path
def convert_and_save(self, json_data):
&#34;&#34;&#34;Converts the provided JSON data into the desired YAML format and saves it to a file.
Args:
json_data (dict): The JSON data representing the team structure.
topic (str, optional): The topic to be inserted into the YAML. Defaults to &#34;Artificial Intelligence&#34;.
agent_file (str, optional): The name of the YAML file to save. Defaults to &#34;test.yaml&#34;.
&#34;&#34;&#34;
yaml_data = {
&#34;framework&#34;: self.framework,
&#34;topic&#34;: self.topic,
&#34;roles&#34;: {},
&#34;dependencies&#34;: []
}
for role_id, role_details in json_data[&#39;roles&#39;].items():
yaml_data[&#39;roles&#39;][role_id] = {
&#34;backstory&#34;: &#34;&#34; + role_details[&#39;backstory&#39;],
&#34;goal&#34;: role_details[&#39;goal&#39;],
&#34;role&#34;: role_details[&#39;role&#39;],
&#34;tasks&#34;: {},
# &#34;tools&#34;: role_details.get(&#39;tools&#39;, []),
&#34;tools&#34;: [&#39;&#39;]
}
for task_id, task_details in role_details[&#39;tasks&#39;].items():
yaml_data[&#39;roles&#39;][role_id][&#39;tasks&#39;][task_id] = {
&#34;description&#34;: &#34;&#34; + task_details[&#39;description&#39;],
&#34;expected_output&#34;: &#34;&#34; + task_details[&#39;expected_output&#39;]
}
# Save to YAML file, maintaining the order
with open(self.agent_file, &#39;w&#39;) as f:
yaml.dump(yaml_data, f, allow_unicode=True, sort_keys=False)
def get_user_content(self):
&#34;&#34;&#34;
Generates a prompt for the OpenAI API to generate a team structure.
Args:
None
Returns:
str: The prompt for the OpenAI API.
Usage:
generator = AutoGenerator(framework=&#34;crewai&#34;, topic=&#34;Create a movie script about Cat in Mars&#34;)
prompt = generator.get_user_content()
print(prompt)
&#34;&#34;&#34;
user_content = &#34;&#34;&#34;Generate a team structure for \&#34;&#34;&#34;&#34; + self.topic + &#34;&#34;&#34;\&#34; task.
No Input data will be provided to the team.
The team will work in sequence. First role will pass the output to the next role, and so on.
The last role will generate the final output.
Think step by step.
With maximum 3 roles, each with 1 task. Include role goals, backstories, task descriptions, and expected outputs.
List of Available Tools: CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool, FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool, ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool, YoutubeVideoSearchTool.
Only use Available Tools. Do Not use any other tools.
Example Below:
Use below example to understand the structure of the output.
The final role you create should satisfy the provided task: &#34;&#34;&#34; + self.topic + &#34;&#34;&#34;.
{
&#34;roles&#34;: {
&#34;narrative_designer&#34;: {
&#34;role&#34;: &#34;Narrative Designer&#34;,
&#34;goal&#34;: &#34;Create AI storylines&#34;,
&#34;backstory&#34;: &#34;Skilled in narrative development for AI, with a focus on story resonance.&#34;,
&#34;tools&#34;: [&#34;ScrapeWebsiteTool&#34;],
&#34;tasks&#34;: {
&#34;story_concept_development&#34;: {
&#34;description&#34;: &#34;Craft a unique AI story concept with depth and engagement using concept from this page the content https://www.asthebirdfliesblog.com/posts/how-to-write-book-story-development .&#34;,
&#34;expected_output&#34;: &#34;Document with narrative arcs, character bios, and settings.&#34;
}
}
},
&#34;scriptwriter&#34;: {
&#34;role&#34;: &#34;Scriptwriter&#34;,
&#34;goal&#34;: &#34;Write scripts from AI concepts&#34;,
&#34;backstory&#34;: &#34;Expert in dialogue and script structure, translating concepts into scripts.&#34;,
&#34;tasks&#34;: {
&#34;scriptwriting_task&#34;: {
&#34;description&#34;: &#34;Turn narrative concepts into scripts, including dialogue and scenes.&#34;,
&#34;expected_output&#34;: &#34;Production-ready script with dialogue and scene details.&#34;
}
}
}
}
}
&#34;&#34;&#34;
return user_content</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.auto.AutoGenerator.convert_and_save"><code class="name flex">
<span>def <span class="ident">convert_and_save</span></span>(<span>self, json_data)</span>
</code></dt>
<dd>
<div class="desc"><p>Converts the provided JSON data into the desired YAML format and saves it to a file.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>json_data</code></strong> :&ensp;<code>dict</code></dt>
<dd>The JSON data representing the team structure.</dd>
<dt><strong><code>topic</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The topic to be inserted into the YAML. Defaults to "Artificial Intelligence".</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The name of the YAML file to save. Defaults to "test.yaml".</dd>
</dl></div>
</dd>
<dt id="praisonai.auto.AutoGenerator.generate"><code class="name flex">
<span>def <span class="ident">generate</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates a team structure for the specified topic.</p>
<h2 id="args">Args</h2>
<p>None</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>str</code></dt>
<dd>The full path of the YAML file containing the generated team structure.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>Exception</code></dt>
<dd>If the generation process fails.</dd>
</dl>
<h2 id="usage">Usage</h2>
<p>generator = AutoGenerator(framework="crewai", topic="Create a movie script about Cat in Mars")
path = generator.generate()
print(path)</p></div>
</dd>
<dt id="praisonai.auto.AutoGenerator.get_user_content"><code class="name flex">
<span>def <span class="ident">get_user_content</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates a prompt for the OpenAI API to generate a team structure.</p>
<h2 id="args">Args</h2>
<p>None</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>str</code></dt>
<dd>The prompt for the OpenAI API.</dd>
</dl>
<h2 id="usage">Usage</h2>
<p>generator = AutoGenerator(framework="crewai", topic="Create a movie script about Cat in Mars")
prompt = generator.get_user_content()
print(prompt)</p></div>
</dd>
</dl>
</dd>
<dt id="praisonai.auto.RoleDetails"><code class="flex name class">
<span>class <span class="ident">RoleDetails</span></span>
<span>(</span><span>**data: Any)</span>
</code></dt>
<dd>
<div class="desc"><p>Usage docs: <a href="https://docs.pydantic.dev/2.9/concepts/models/">https://docs.pydantic.dev/2.9/concepts/models/</a></p>
<p>A base class for creating Pydantic models.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>__class_vars__</code></strong></dt>
<dd>The names of the class variables defined on the model.</dd>
<dt><strong><code>__private_attributes__</code></strong></dt>
<dd>Metadata about the private attributes of the model.</dd>
<dt><strong><code>__signature__</code></strong></dt>
<dd>The synthesized <code>__init__</code> [<code>Signature</code>][inspect.Signature] of the model.</dd>
<dt><strong><code>__pydantic_complete__</code></strong></dt>
<dd>Whether model building is completed, or if there are still undefined fields.</dd>
<dt><strong><code>__pydantic_core_schema__</code></strong></dt>
<dd>The core schema of the model.</dd>
<dt><strong><code>__pydantic_custom_init__</code></strong></dt>
<dd>Whether the model has a custom <code>__init__</code> function.</dd>
<dt><strong><code>__pydantic_decorators__</code></strong></dt>
<dd>Metadata containing the decorators defined on the model.
This replaces <code>Model.__validators__</code> and <code>Model.__root_validators__</code> from Pydantic V1.</dd>
<dt><strong><code>__pydantic_generic_metadata__</code></strong></dt>
<dd>Metadata for generic models; contains data used for a similar purpose to
<strong>args</strong>, <strong>origin</strong>, <strong>parameters</strong> in typing-module generics. May eventually be replaced by these.</dd>
<dt><strong><code>__pydantic_parent_namespace__</code></strong></dt>
<dd>Parent namespace of the model, used for automatic rebuilding of models.</dd>
<dt><strong><code>__pydantic_post_init__</code></strong></dt>
<dd>The name of the post-init method for the model, if defined.</dd>
<dt><strong><code>__pydantic_root_model__</code></strong></dt>
<dd>Whether the model is a [<code>RootModel</code>][pydantic.root_model.RootModel].</dd>
<dt><strong><code>__pydantic_serializer__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaSerializer</code> used to dump instances of the model.</dd>
<dt><strong><code>__pydantic_validator__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaValidator</code> used to validate instances of the model.</dd>
<dt><strong><code>__pydantic_extra__</code></strong></dt>
<dd>A dictionary containing extra values, if [<code>extra</code>][pydantic.config.ConfigDict.extra]
is set to <code>'allow'</code>.</dd>
<dt><strong><code>__pydantic_fields_set__</code></strong></dt>
<dd>The names of fields explicitly set during instantiation.</dd>
<dt><strong><code>__pydantic_private__</code></strong></dt>
<dd>Values of private attributes set on the model instance.</dd>
</dl>
<p>Create a new model by parsing and validating input data from keyword arguments.</p>
<p>Raises [<code>ValidationError</code>][pydantic_core.ValidationError] if the input data cannot be
validated to form a valid model.</p>
<p><code>self</code> is explicitly positional-only to allow <code>self</code> as a field name.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class RoleDetails(BaseModel):
role: str
goal: str
backstory: str
tasks: Dict[str, TaskDetails]
tools: List[str]</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>pydantic.main.BaseModel</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="praisonai.auto.RoleDetails.backstory"><code class="name">var <span class="ident">backstory</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.goal"><code class="name">var <span class="ident">goal</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.model_computed_fields"><code class="name">var <span class="ident">model_computed_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.model_config"><code class="name">var <span class="ident">model_config</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.model_fields"><code class="name">var <span class="ident">model_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.role"><code class="name">var <span class="ident">role</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.tasks"><code class="name">var <span class="ident">tasks</span> : Dict[str, <a title="praisonai.auto.TaskDetails" href="#praisonai.auto.TaskDetails">TaskDetails</a>]</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.tools"><code class="name">var <span class="ident">tools</span> : List[str]</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
<dt id="praisonai.auto.TaskDetails"><code class="flex name class">
<span>class <span class="ident">TaskDetails</span></span>
<span>(</span><span>**data: Any)</span>
</code></dt>
<dd>
<div class="desc"><p>Usage docs: <a href="https://docs.pydantic.dev/2.9/concepts/models/">https://docs.pydantic.dev/2.9/concepts/models/</a></p>
<p>A base class for creating Pydantic models.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>__class_vars__</code></strong></dt>
<dd>The names of the class variables defined on the model.</dd>
<dt><strong><code>__private_attributes__</code></strong></dt>
<dd>Metadata about the private attributes of the model.</dd>
<dt><strong><code>__signature__</code></strong></dt>
<dd>The synthesized <code>__init__</code> [<code>Signature</code>][inspect.Signature] of the model.</dd>
<dt><strong><code>__pydantic_complete__</code></strong></dt>
<dd>Whether model building is completed, or if there are still undefined fields.</dd>
<dt><strong><code>__pydantic_core_schema__</code></strong></dt>
<dd>The core schema of the model.</dd>
<dt><strong><code>__pydantic_custom_init__</code></strong></dt>
<dd>Whether the model has a custom <code>__init__</code> function.</dd>
<dt><strong><code>__pydantic_decorators__</code></strong></dt>
<dd>Metadata containing the decorators defined on the model.
This replaces <code>Model.__validators__</code> and <code>Model.__root_validators__</code> from Pydantic V1.</dd>
<dt><strong><code>__pydantic_generic_metadata__</code></strong></dt>
<dd>Metadata for generic models; contains data used for a similar purpose to
<strong>args</strong>, <strong>origin</strong>, <strong>parameters</strong> in typing-module generics. May eventually be replaced by these.</dd>
<dt><strong><code>__pydantic_parent_namespace__</code></strong></dt>
<dd>Parent namespace of the model, used for automatic rebuilding of models.</dd>
<dt><strong><code>__pydantic_post_init__</code></strong></dt>
<dd>The name of the post-init method for the model, if defined.</dd>
<dt><strong><code>__pydantic_root_model__</code></strong></dt>
<dd>Whether the model is a [<code>RootModel</code>][pydantic.root_model.RootModel].</dd>
<dt><strong><code>__pydantic_serializer__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaSerializer</code> used to dump instances of the model.</dd>
<dt><strong><code>__pydantic_validator__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaValidator</code> used to validate instances of the model.</dd>
<dt><strong><code>__pydantic_extra__</code></strong></dt>
<dd>A dictionary containing extra values, if [<code>extra</code>][pydantic.config.ConfigDict.extra]
is set to <code>'allow'</code>.</dd>
<dt><strong><code>__pydantic_fields_set__</code></strong></dt>
<dd>The names of fields explicitly set during instantiation.</dd>
<dt><strong><code>__pydantic_private__</code></strong></dt>
<dd>Values of private attributes set on the model instance.</dd>
</dl>
<p>Create a new model by parsing and validating input data from keyword arguments.</p>
<p>Raises [<code>ValidationError</code>][pydantic_core.ValidationError] if the input data cannot be
validated to form a valid model.</p>
<p><code>self</code> is explicitly positional-only to allow <code>self</code> as a field name.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class TaskDetails(BaseModel):
description: str
expected_output: str</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>pydantic.main.BaseModel</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="praisonai.auto.TaskDetails.description"><code class="name">var <span class="ident">description</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.expected_output"><code class="name">var <span class="ident">expected_output</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.model_computed_fields"><code class="name">var <span class="ident">model_computed_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.model_config"><code class="name">var <span class="ident">model_config</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.model_fields"><code class="name">var <span class="ident">model_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
<dt id="praisonai.auto.TeamStructure"><code class="flex name class">
<span>class <span class="ident">TeamStructure</span></span>
<span>(</span><span>**data: Any)</span>
</code></dt>
<dd>
<div class="desc"><p>Usage docs: <a href="https://docs.pydantic.dev/2.9/concepts/models/">https://docs.pydantic.dev/2.9/concepts/models/</a></p>
<p>A base class for creating Pydantic models.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>__class_vars__</code></strong></dt>
<dd>The names of the class variables defined on the model.</dd>
<dt><strong><code>__private_attributes__</code></strong></dt>
<dd>Metadata about the private attributes of the model.</dd>
<dt><strong><code>__signature__</code></strong></dt>
<dd>The synthesized <code>__init__</code> [<code>Signature</code>][inspect.Signature] of the model.</dd>
<dt><strong><code>__pydantic_complete__</code></strong></dt>
<dd>Whether model building is completed, or if there are still undefined fields.</dd>
<dt><strong><code>__pydantic_core_schema__</code></strong></dt>
<dd>The core schema of the model.</dd>
<dt><strong><code>__pydantic_custom_init__</code></strong></dt>
<dd>Whether the model has a custom <code>__init__</code> function.</dd>
<dt><strong><code>__pydantic_decorators__</code></strong></dt>
<dd>Metadata containing the decorators defined on the model.
This replaces <code>Model.__validators__</code> and <code>Model.__root_validators__</code> from Pydantic V1.</dd>
<dt><strong><code>__pydantic_generic_metadata__</code></strong></dt>
<dd>Metadata for generic models; contains data used for a similar purpose to
<strong>args</strong>, <strong>origin</strong>, <strong>parameters</strong> in typing-module generics. May eventually be replaced by these.</dd>
<dt><strong><code>__pydantic_parent_namespace__</code></strong></dt>
<dd>Parent namespace of the model, used for automatic rebuilding of models.</dd>
<dt><strong><code>__pydantic_post_init__</code></strong></dt>
<dd>The name of the post-init method for the model, if defined.</dd>
<dt><strong><code>__pydantic_root_model__</code></strong></dt>
<dd>Whether the model is a [<code>RootModel</code>][pydantic.root_model.RootModel].</dd>
<dt><strong><code>__pydantic_serializer__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaSerializer</code> used to dump instances of the model.</dd>
<dt><strong><code>__pydantic_validator__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaValidator</code> used to validate instances of the model.</dd>
<dt><strong><code>__pydantic_extra__</code></strong></dt>
<dd>A dictionary containing extra values, if [<code>extra</code>][pydantic.config.ConfigDict.extra]
is set to <code>'allow'</code>.</dd>
<dt><strong><code>__pydantic_fields_set__</code></strong></dt>
<dd>The names of fields explicitly set during instantiation.</dd>
<dt><strong><code>__pydantic_private__</code></strong></dt>
<dd>Values of private attributes set on the model instance.</dd>
</dl>
<p>Create a new model by parsing and validating input data from keyword arguments.</p>
<p>Raises [<code>ValidationError</code>][pydantic_core.ValidationError] if the input data cannot be
validated to form a valid model.</p>
<p><code>self</code> is explicitly positional-only to allow <code>self</code> as a field name.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class TeamStructure(BaseModel):
roles: Dict[str, RoleDetails]</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>pydantic.main.BaseModel</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="praisonai.auto.TeamStructure.model_computed_fields"><code class="name">var <span class="ident">model_computed_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TeamStructure.model_config"><code class="name">var <span class="ident">model_config</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TeamStructure.model_fields"><code class="name">var <span class="ident">model_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TeamStructure.roles"><code class="name">var <span class="ident">roles</span> : Dict[str, <a title="praisonai.auto.RoleDetails" href="#praisonai.auto.RoleDetails">RoleDetails</a>]</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.auto.AutoGenerator" href="#praisonai.auto.AutoGenerator">AutoGenerator</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.AutoGenerator.convert_and_save" href="#praisonai.auto.AutoGenerator.convert_and_save">convert_and_save</a></code></li>
<li><code><a title="praisonai.auto.AutoGenerator.generate" href="#praisonai.auto.AutoGenerator.generate">generate</a></code></li>
<li><code><a title="praisonai.auto.AutoGenerator.get_user_content" href="#praisonai.auto.AutoGenerator.get_user_content">get_user_content</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="praisonai.auto.RoleDetails" href="#praisonai.auto.RoleDetails">RoleDetails</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.RoleDetails.backstory" href="#praisonai.auto.RoleDetails.backstory">backstory</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.goal" href="#praisonai.auto.RoleDetails.goal">goal</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.model_computed_fields" href="#praisonai.auto.RoleDetails.model_computed_fields">model_computed_fields</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.model_config" href="#praisonai.auto.RoleDetails.model_config">model_config</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.model_fields" href="#praisonai.auto.RoleDetails.model_fields">model_fields</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.role" href="#praisonai.auto.RoleDetails.role">role</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.tasks" href="#praisonai.auto.RoleDetails.tasks">tasks</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.tools" href="#praisonai.auto.RoleDetails.tools">tools</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="praisonai.auto.TaskDetails" href="#praisonai.auto.TaskDetails">TaskDetails</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.TaskDetails.description" href="#praisonai.auto.TaskDetails.description">description</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.expected_output" href="#praisonai.auto.TaskDetails.expected_output">expected_output</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.model_computed_fields" href="#praisonai.auto.TaskDetails.model_computed_fields">model_computed_fields</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.model_config" href="#praisonai.auto.TaskDetails.model_config">model_config</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.model_fields" href="#praisonai.auto.TaskDetails.model_fields">model_fields</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="praisonai.auto.TeamStructure" href="#praisonai.auto.TeamStructure">TeamStructure</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.TeamStructure.model_computed_fields" href="#praisonai.auto.TeamStructure.model_computed_fields">model_computed_fields</a></code></li>
<li><code><a title="praisonai.auto.TeamStructure.model_config" href="#praisonai.auto.TeamStructure.model_config">model_config</a></code></li>
<li><code><a title="praisonai.auto.TeamStructure.model_fields" href="#praisonai.auto.TeamStructure.model_fields">model_fields</a></code></li>
<li><code><a title="praisonai.auto.TeamStructure.roles" href="#praisonai.auto.TeamStructure.roles">roles</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-664
View File
@@ -1,664 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.cli API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.cli</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.cli.stream_subprocess"><code class="name flex">
<span>def <span class="ident">stream_subprocess</span></span>(<span>command, env=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Execute a subprocess command and stream the output to the terminal in real-time.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>command</code></strong> :&ensp;<code>list</code></dt>
<dd>A list containing the command and its arguments.</dd>
<dt><strong><code>env</code></strong> :&ensp;<code>dict</code>, optional</dt>
<dd>Environment variables for the subprocess.</dd>
</dl></div>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.cli.PraisonAI"><code class="flex name class">
<span>class <span class="ident">PraisonAI</span></span>
<span>(</span><span>agent_file='agents.yaml', framework='', auto=False, init=False, agent_yaml=None, tools=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initialize the PraisonAI object with default parameters.</p>
<h2 id="parameters">Parameters</h2>
<p>agent_file (str): The default agent file to use. Defaults to "agents.yaml".
framework (str): The default framework to use. Defaults to "crewai".
auto (bool): A flag indicating whether to enable auto mode. Defaults to False.
init (bool): A flag indicating whether to enable initialization mode. Defaults to False.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>config_list</code></strong> :&ensp;<code>list</code></dt>
<dd>A list of configuration dictionaries for the OpenAI API.</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code></dt>
<dd>The agent file to use.</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code></dt>
<dd>The framework to use.</dd>
<dt><strong><code>auto</code></strong> :&ensp;<code>bool</code></dt>
<dd>A flag indicating whether to enable auto mode.</dd>
<dt><strong><code>init</code></strong> :&ensp;<code>bool</code></dt>
<dd>A flag indicating whether to enable initialization mode.</dd>
<dt><strong><code>agent_yaml</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The content of the YAML file. Defaults to None.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class PraisonAI:
def __init__(self, agent_file=&#34;agents.yaml&#34;, framework=&#34;&#34;, auto=False, init=False, agent_yaml=None, tools=None):
&#34;&#34;&#34;
Initialize the PraisonAI object with default parameters.
Parameters:
agent_file (str): The default agent file to use. Defaults to &#34;agents.yaml&#34;.
framework (str): The default framework to use. Defaults to &#34;crewai&#34;.
auto (bool): A flag indicating whether to enable auto mode. Defaults to False.
init (bool): A flag indicating whether to enable initialization mode. Defaults to False.
Attributes:
config_list (list): A list of configuration dictionaries for the OpenAI API.
agent_file (str): The agent file to use.
framework (str): The framework to use.
auto (bool): A flag indicating whether to enable auto mode.
init (bool): A flag indicating whether to enable initialization mode.
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
&#34;&#34;&#34;
self.agent_yaml = agent_yaml
self.config_list = [
{
&#39;model&#39;: os.environ.get(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;),
&#39;base_url&#39;: os.environ.get(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;),
&#39;api_key&#39;: os.environ.get(&#34;OPENAI_API_KEY&#34;)
}
]
self.agent_file = agent_file
self.framework = framework
self.auto = auto
self.init = init
self.tools = tools or [] # Store tool class names as a list
def run(self):
&#34;&#34;&#34;
Run the PraisonAI application.
&#34;&#34;&#34;
self.main()
def main(self):
&#34;&#34;&#34;
The main function of the PraisonAI object. It parses the command-line arguments,
initializes the necessary attributes, and then calls the appropriate methods based on the
provided arguments.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
Any: Depending on the arguments provided, the function may return a result from the
AgentsGenerator, a deployment result from the CloudDeployer, or a message indicating
the successful creation of a file.
&#34;&#34;&#34;
args = self.parse_args()
if args is None:
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
return result
if args.deploy:
from .deploy import CloudDeployer
deployer = CloudDeployer()
deployer.run_commands()
return
if getattr(args, &#39;chat&#39;, False):
self.create_chainlit_chat_interface()
return
if getattr(args, &#39;code&#39;, False):
self.create_code_interface()
return
if getattr(args, &#39;realtime&#39;, False):
self.create_realtime_interface()
return
if getattr(args, &#39;call&#39;, False):
call_args = []
if args.public:
call_args.append(&#39;--public&#39;)
call_module.main(call_args)
return
if args.agent_file == &#39;train&#39;:
package_root = os.path.dirname(os.path.abspath(__file__))
config_yaml_destination = os.path.join(os.getcwd(), &#39;config.yaml&#39;)
# Create config.yaml only if it doesn&#39;t exist or --model or --dataset is provided
if not os.path.exists(config_yaml_destination) or args.model or args.dataset:
config = generate_config(
model_name=args.model,
hf_model_name=args.hf,
ollama_model_name=args.ollama,
dataset=[{
&#34;name&#34;: args.dataset
}]
)
with open(&#39;config.yaml&#39;, &#39;w&#39;) as f:
yaml.dump(config, f, default_flow_style=False, indent=2)
# Overwrite huggingface_save and ollama_save if --hf or --ollama are provided
if args.hf:
config[&#34;huggingface_save&#34;] = &#34;true&#34;
if args.ollama:
config[&#34;ollama_save&#34;] = &#34;true&#34;
if &#39;init&#39; in sys.argv:
from praisonai.setup.setup_conda_env import main as setup_conda_main
setup_conda_main()
print(&#34;All packages installed&#34;)
return
try:
result = subprocess.check_output([&#39;conda&#39;, &#39;env&#39;, &#39;list&#39;])
if &#39;praison_env&#39; in result.decode(&#39;utf-8&#39;):
print(&#34;Conda environment &#39;praison_env&#39; found.&#34;)
else:
raise subprocess.CalledProcessError(1, &#39;grep&#39;)
except subprocess.CalledProcessError:
print(&#34;Conda environment &#39;praison_env&#39; not found. Setting it up...&#34;)
from praisonai.setup.setup_conda_env import main as setup_conda_main
setup_conda_main()
print(&#34;All packages installed.&#34;)
train_args = sys.argv[2:] # Get all arguments after &#39;train&#39;
train_script_path = os.path.join(package_root, &#39;train.py&#39;)
# Set environment variables
env = os.environ.copy()
env[&#39;PYTHONUNBUFFERED&#39;] = &#39;1&#39;
stream_subprocess([&#39;conda&#39;, &#39;run&#39;, &#39;--no-capture-output&#39;, &#39;--name&#39;, &#39;praison_env&#39;, &#39;python&#39;, &#39;-u&#39;, train_script_path, &#39;train&#39;], env=env)
return
invocation_cmd = &#34;praisonai&#34;
version_string = f&#34;PraisonAI version {__version__}&#34;
self.framework = args.framework or self.framework
if args.agent_file:
if args.agent_file.startswith(&#34;tests.test&#34;): # Argument used for testing purposes. eg: python -m unittest tests.test
print(&#34;test&#34;)
else:
self.agent_file = args.agent_file
if args.auto or args.init:
temp_topic = &#39; &#39;.join(args.auto) if args.auto else &#39; &#39;.join(args.init)
self.topic = temp_topic
elif self.auto or self.init: # Use the auto attribute if args.auto is not provided
self.topic = self.auto
if args.auto or self.auto:
self.agent_file = &#34;test.yaml&#34;
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
self.agent_file = generator.generate()
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
return result
elif args.init or self.init:
self.agent_file = &#34;agents.yaml&#34;
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
self.agent_file = generator.generate()
print(&#34;File {} created successfully&#34;.format(self.agent_file))
return &#34;File {} created successfully&#34;.format(self.agent_file)
if args.ui:
if args.ui == &#34;gradio&#34;:
self.create_gradio_interface()
elif args.ui == &#34;chainlit&#34;:
self.create_chainlit_interface()
else:
# Modify below code to allow default ui
agents_generator = AgentsGenerator(
self.agent_file,
self.framework,
self.config_list,
agent_yaml=self.agent_yaml,
tools=self.tools # Pass tools to AgentsGenerator
)
result = agents_generator.generate_crew_and_kickoff()
return result
else:
agents_generator = AgentsGenerator(
self.agent_file,
self.framework,
self.config_list,
agent_yaml=self.agent_yaml,
tools=self.tools # Pass tools to AgentsGenerator
)
result = agents_generator.generate_crew_and_kickoff()
return result
def parse_args(self):
&#34;&#34;&#34;
Parse the command-line arguments for the PraisonAI CLI.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
argparse.Namespace: An object containing the parsed command-line arguments.
Raises:
argparse.ArgumentError: If the arguments provided are invalid.
Example:
&gt;&gt;&gt; args = praison_ai.parse_args()
&gt;&gt;&gt; print(args.agent_file) # Output: &#39;agents.yaml&#39;
&#34;&#34;&#34;
parser = argparse.ArgumentParser(prog=&#34;praisonai&#34;, description=&#34;praisonAI command-line interface&#34;)
parser.add_argument(&#34;--framework&#34;, choices=[&#34;crewai&#34;, &#34;autogen&#34;], help=&#34;Specify the framework&#34;)
parser.add_argument(&#34;--ui&#34;, choices=[&#34;chainlit&#34;, &#34;gradio&#34;], help=&#34;Specify the UI framework (gradio or chainlit).&#34;)
parser.add_argument(&#34;--auto&#34;, nargs=argparse.REMAINDER, help=&#34;Enable auto mode and pass arguments for it&#34;)
parser.add_argument(&#34;--init&#34;, nargs=argparse.REMAINDER, help=&#34;Enable auto mode and pass arguments for it&#34;)
parser.add_argument(&#34;agent_file&#34;, nargs=&#34;?&#34;, help=&#34;Specify the agent file&#34;)
parser.add_argument(&#34;--deploy&#34;, action=&#34;store_true&#34;, help=&#34;Deploy the application&#34;)
parser.add_argument(&#34;--model&#34;, type=str, help=&#34;Model name&#34;)
parser.add_argument(&#34;--hf&#34;, type=str, help=&#34;Hugging Face model name&#34;)
parser.add_argument(&#34;--ollama&#34;, type=str, help=&#34;Ollama model name&#34;)
parser.add_argument(&#34;--dataset&#34;, type=str, help=&#34;Dataset name for training&#34;, default=&#34;yahma/alpaca-cleaned&#34;)
parser.add_argument(&#34;--realtime&#34;, action=&#34;store_true&#34;, help=&#34;Start the realtime voice interaction interface&#34;)
parser.add_argument(&#34;--call&#34;, action=&#34;store_true&#34;, help=&#34;Start the PraisonAI Call server&#34;)
parser.add_argument(&#34;--public&#34;, action=&#34;store_true&#34;, help=&#34;Use ngrok to expose the server publicly (only with --call)&#34;)
args, unknown_args = parser.parse_known_args()
if unknown_args and unknown_args[0] == &#39;-b&#39; and unknown_args[1] == &#39;api:app&#39;:
args.agent_file = &#39;agents.yaml&#39;
if args.agent_file == &#39;api:app&#39; or args.agent_file == &#39;/app/api:app&#39;:
args.agent_file = &#39;agents.yaml&#39;
if args.agent_file == &#39;ui&#39;:
args.ui = &#39;chainlit&#39;
if args.agent_file == &#39;chat&#39;:
args.ui = &#39;chainlit&#39;
args.chat = True
if args.agent_file == &#39;code&#39;:
args.ui = &#39;chainlit&#39;
args.code = True
if args.agent_file == &#39;realtime&#39;:
args.realtime = True
if args.agent_file == &#39;call&#39;:
args.call = True
return args
def create_chainlit_chat_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for the chat application.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8084&#34;
root_path = os.path.join(os.path.expanduser(&#34;~&#34;), &#34;.praison&#34;)
os.environ[&#34;CHAINLIT_APP_ROOT&#34;] = root_path
public_folder = os.path.join(os.path.dirname(praisonai.__file__), &#39;public&#39;)
if not os.path.exists(os.path.join(root_path, &#34;public&#34;)): # Check if the folder exists in the current directory
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, &#34;public&#34;), dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
chat_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;ui&#39;, &#39;chat.py&#39;)
chainlit_run([chat_ui_path])
else:
print(&#34;ERROR: Chat UI is not installed. Please install it with &#39;pip install \&#34;praisonai\[chat]\&#34;&#39; to use the chat UI.&#34;)
def create_code_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for the code application.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8086&#34;
root_path = os.path.join(os.path.expanduser(&#34;~&#34;), &#34;.praison&#34;)
os.environ[&#34;CHAINLIT_APP_ROOT&#34;] = root_path
public_folder = os.path.join(os.path.dirname(__file__), &#39;public&#39;)
if not os.path.exists(os.path.join(root_path, &#34;public&#34;)): # Check if the folder exists in the current directory
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, &#34;public&#34;), dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
code_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;ui&#39;, &#39;code.py&#39;)
chainlit_run([code_ui_path])
else:
print(&#34;ERROR: Code UI is not installed. Please install it with &#39;pip install \&#34;praisonai\[code]\&#34;&#39; to use the code UI.&#34;)
def create_gradio_interface(self):
&#34;&#34;&#34;
Create a Gradio interface for generating agents and performing tasks.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
None: This method does not return any value. It launches the Gradio interface.
Raises:
None: This method does not raise any exceptions.
Example:
&gt;&gt;&gt; praison_ai.create_gradio_interface()
&#34;&#34;&#34;
if GRADIO_AVAILABLE:
def generate_crew_and_kickoff_interface(auto_args, framework):
&#34;&#34;&#34;
Generate a crew and kick off tasks based on the provided auto arguments and framework.
Args:
auto_args (list): Topic.
framework (str): The framework to use for generating agents.
Returns:
str: A string representing the result of generating the crew and kicking off tasks.
Raises:
None: This method does not raise any exceptions.
Example:
&gt;&gt;&gt; result = generate_crew_and_kickoff_interface(&#34;Create a movie about Cat in Mars&#34;, &#34;crewai&#34;)
&gt;&gt;&gt; print(result)
&#34;&#34;&#34;
self.framework = framework
self.agent_file = &#34;test.yaml&#34;
generator = AutoGenerator(topic=auto_args , framework=self.framework)
self.agent_file = generator.generate()
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
return result
gr.Interface(
fn=generate_crew_and_kickoff_interface,
inputs=[gr.Textbox(lines=2, label=&#34;Auto Args&#34;), gr.Dropdown(choices=[&#34;crewai&#34;, &#34;autogen&#34;], label=&#34;Framework&#34;)],
outputs=&#34;textbox&#34;,
title=&#34;Praison AI Studio&#34;,
description=&#34;Create Agents and perform tasks&#34;,
theme=&#34;default&#34;
).launch()
else:
print(&#34;ERROR: Gradio is not installed. Please install it with &#39;pip install gradio&#39; to use this feature.&#34;)
def create_chainlit_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for generating agents and performing tasks.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8082&#34;
# Get the path to the &#39;public&#39; folder within the package
public_folder = os.path.join(os.path.dirname(praisonai.__file__), &#39;public&#39;)
if not os.path.exists(&#34;public&#34;): # Check if the folder exists in the current directory
if os.path.exists(public_folder):
shutil.copytree(public_folder, &#39;public&#39;, dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
chainlit_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;chainlit_ui.py&#39;)
chainlit_run([chainlit_ui_path])
else:
print(&#34;ERROR: Chainlit is not installed. Please install it with &#39;pip install \&#34;praisonai\[ui]\&#34;&#39; to use the UI.&#34;)
def create_realtime_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for the realtime voice interaction application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8088&#34; # Ensure this port is not in use by another service
root_path = os.path.join(os.path.expanduser(&#34;~&#34;), &#34;.praison&#34;)
os.environ[&#34;CHAINLIT_APP_ROOT&#34;] = root_path
public_folder = os.path.join(os.path.dirname(praisonai.__file__), &#39;public&#39;)
if not os.path.exists(os.path.join(root_path, &#34;public&#34;)):
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, &#34;public&#34;), dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
realtime_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;ui&#39;, &#39;realtime.py&#39;)
chainlit_run([realtime_ui_path])
else:
print(&#34;ERROR: Realtime UI is not installed. Please install it with &#39;pip install \&#34;praisonai[realtime]\&#34;&#39; to use the realtime UI.&#34;)</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.cli.PraisonAI.create_chainlit_chat_interface"><code class="name flex">
<span>def <span class="ident">create_chainlit_chat_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for the chat application.</p>
<p>This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This function does not return any value. It starts the Chainlit application.</dd>
</dl></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_chainlit_interface"><code class="name flex">
<span>def <span class="ident">create_chainlit_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for generating agents and performing tasks.</p>
<p>This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This function does not return any value. It starts the Chainlit application.</dd>
</dl></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_code_interface"><code class="name flex">
<span>def <span class="ident">create_code_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for the code application.</p>
<p>This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This function does not return any value. It starts the Chainlit application.</dd>
</dl></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_gradio_interface"><code class="name flex">
<span>def <span class="ident">create_gradio_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Gradio interface for generating agents and performing tasks.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>self</code></strong> :&ensp;<code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></dt>
<dd>An instance of the PraisonAI class.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This method does not return any value. It launches the Gradio interface.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>None</code></dt>
<dd>This method does not raise any exceptions.</dd>
</dl>
<h2 id="example">Example</h2>
<pre><code class="language-python-repl">&gt;&gt;&gt; praison_ai.create_gradio_interface()
</code></pre></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_realtime_interface"><code class="name flex">
<span>def <span class="ident">create_realtime_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for the realtime voice interaction application.</p></div>
</dd>
<dt id="praisonai.cli.PraisonAI.main"><code class="name flex">
<span>def <span class="ident">main</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>The main function of the PraisonAI object. It parses the command-line arguments,
initializes the necessary attributes, and then calls the appropriate methods based on the
provided arguments.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>self</code></strong> :&ensp;<code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></dt>
<dd>An instance of the PraisonAI class.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>Any</code></dt>
<dd>Depending on the arguments provided, the function may return a result from the</dd>
</dl>
<p>AgentsGenerator, a deployment result from the CloudDeployer, or a message indicating
the successful creation of a file.</p></div>
</dd>
<dt id="praisonai.cli.PraisonAI.parse_args"><code class="name flex">
<span>def <span class="ident">parse_args</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Parse the command-line arguments for the PraisonAI CLI.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>self</code></strong> :&ensp;<code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></dt>
<dd>An instance of the PraisonAI class.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>argparse.Namespace</code></dt>
<dd>An object containing the parsed command-line arguments.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>argparse.ArgumentError</code></dt>
<dd>If the arguments provided are invalid.</dd>
</dl>
<h2 id="example">Example</h2>
<pre><code class="language-python-repl">&gt;&gt;&gt; args = praison_ai.parse_args()
&gt;&gt;&gt; print(args.agent_file) # Output: 'agents.yaml'
</code></pre></div>
</dd>
<dt id="praisonai.cli.PraisonAI.run"><code class="name flex">
<span>def <span class="ident">run</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Run the PraisonAI application.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.cli.stream_subprocess" href="#praisonai.cli.stream_subprocess">stream_subprocess</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></h4>
<ul class="">
<li><code><a title="praisonai.cli.PraisonAI.create_chainlit_chat_interface" href="#praisonai.cli.PraisonAI.create_chainlit_chat_interface">create_chainlit_chat_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_chainlit_interface" href="#praisonai.cli.PraisonAI.create_chainlit_interface">create_chainlit_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_code_interface" href="#praisonai.cli.PraisonAI.create_code_interface">create_code_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_gradio_interface" href="#praisonai.cli.PraisonAI.create_gradio_interface">create_gradio_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_realtime_interface" href="#praisonai.cli.PraisonAI.create_realtime_interface">create_realtime_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.main" href="#praisonai.cli.PraisonAI.main">main</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.parse_args" href="#praisonai.cli.PraisonAI.parse_args">parse_args</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.run" href="#praisonai.cli.PraisonAI.run">run</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-279
View File
@@ -1,279 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.deploy API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.deploy</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.deploy.CloudDeployer"><code class="flex name class">
<span>class <span class="ident">CloudDeployer</span></span>
</code></dt>
<dd>
<div class="desc"><p>A class for deploying a cloud-based application.</p>
<h2 id="attributes">Attributes</h2>
<p>None</p>
<h2 id="methods">Methods</h2>
<p><strong>init</strong>(self):
Loads environment variables from .env file or system and sets them.</p>
<p>Loads environment variables from .env file or system and sets them.</p>
<h2 id="parameters">Parameters</h2>
<p>self: An instance of the CloudDeployer class.</p>
<h2 id="returns">Returns</h2>
<p>None</p>
<h2 id="raises">Raises</h2>
<p>None</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class CloudDeployer:
&#34;&#34;&#34;
A class for deploying a cloud-based application.
Attributes:
None
Methods:
__init__(self):
Loads environment variables from .env file or system and sets them.
&#34;&#34;&#34;
def __init__(self):
&#34;&#34;&#34;
Loads environment variables from .env file or system and sets them.
Parameters:
self: An instance of the CloudDeployer class.
Returns:
None
Raises:
None
&#34;&#34;&#34;
# Load environment variables from .env file or system
load_dotenv()
self.set_environment_variables()
def create_dockerfile(self):
&#34;&#34;&#34;
Creates a Dockerfile for the application.
Parameters:
self: An instance of the CloudDeployer class.
Returns:
None
Raises:
None
This method creates a Dockerfile in the current directory with the specified content.
The Dockerfile is used to build a Docker image for the application.
The content of the Dockerfile includes instructions to use the Python 3.11-slim base image,
set the working directory to /app, copy the current directory contents into the container,
install the required Python packages (flask, praisonai, gunicorn, and markdown),
expose port 8080, and run the application using Gunicorn.
&#34;&#34;&#34;
with open(&#34;Dockerfile&#34;, &#34;w&#34;) as file:
file.write(&#34;FROM python:3.11-slim\n&#34;)
file.write(&#34;WORKDIR /app\n&#34;)
file.write(&#34;COPY . .\n&#34;)
file.write(&#34;RUN pip install flask praisonai==2.0.57 gunicorn markdown\n&#34;)
file.write(&#34;EXPOSE 8080\n&#34;)
file.write(&#39;CMD [&#34;gunicorn&#34;, &#34;-b&#34;, &#34;0.0.0.0:8080&#34;, &#34;api:app&#34;]\n&#39;)
def create_api_file(self):
&#34;&#34;&#34;
Creates an API file for the application.
Parameters:
self (CloudDeployer): An instance of the CloudDeployer class.
Returns:
None
This method creates an API file named &#34;api.py&#34; in the current directory. The file contains a basic Flask application that uses the PraisonAI library to run a simple agent and returns the output as an HTML page. The application listens on the root path (&#34;/&#34;) and uses the Markdown library to format the output.
&#34;&#34;&#34;
with open(&#34;api.py&#34;, &#34;w&#34;) as file:
file.write(&#34;from flask import Flask\n&#34;)
file.write(&#34;from praisonai import PraisonAI\n&#34;)
file.write(&#34;import markdown\n\n&#34;)
file.write(&#34;app = Flask(__name__)\n\n&#34;)
file.write(&#34;def basic():\n&#34;)
file.write(&#34; praisonai = PraisonAI(agent_file=\&#34;agents.yaml\&#34;)\n&#34;)
file.write(&#34; return praisonai.run()\n\n&#34;)
file.write(&#34;@app.route(&#39;/&#39;)\n&#34;)
file.write(&#34;def home():\n&#34;)
file.write(&#34; output = basic()\n&#34;)
file.write(&#34; html_output = markdown.markdown(output)\n&#34;)
file.write(&#34; return f&#39;&lt;html&gt;&lt;body&gt;{html_output}&lt;/body&gt;&lt;/html&gt;&#39;\n\n&#34;)
file.write(&#34;if __name__ == \&#34;__main__\&#34;:\n&#34;)
file.write(&#34; app.run(debug=True)\n&#34;)
def set_environment_variables(self):
&#34;&#34;&#34;Sets environment variables with fallback to .env values or defaults.&#34;&#34;&#34;
os.environ[&#34;OPENAI_MODEL_NAME&#34;] = os.getenv(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;)
os.environ[&#34;OPENAI_API_KEY&#34;] = os.getenv(&#34;OPENAI_API_KEY&#34;, &#34;Enter your API key&#34;)
os.environ[&#34;OPENAI_API_BASE&#34;] = os.getenv(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;)
def run_commands(self):
&#34;&#34;&#34;
Sets environment variables with fallback to .env values or defaults.
Parameters:
None
Returns:
None
Raises:
None
This method sets environment variables for the application. It uses the `os.environ` dictionary to set the following environment variables:
- `OPENAI_MODEL_NAME`: The name of the OpenAI model to use. If not specified in the .env file, it defaults to &#34;gpt-4o&#34;.
- `OPENAI_API_KEY`: The API key for accessing the OpenAI API. If not specified in the .env file, it defaults to &#34;Enter your API key&#34;.
- `OPENAI_API_BASE`: The base URL for the OpenAI API. If not specified in the .env file, it defaults to &#34;https://api.openai.com/v1&#34;.
&#34;&#34;&#34;
self.create_api_file()
self.create_dockerfile()
&#34;&#34;&#34;Runs a sequence of shell commands for deployment, continues on error.&#34;&#34;&#34;
commands = [
&#34;yes | gcloud auth configure-docker us-central1-docker.pkg.dev&#34;,
&#34;gcloud artifacts repositories create praisonai-repository --repository-format=docker --location=us-central1&#34;,
&#34;docker build --platform linux/amd64 -t gcr.io/$(gcloud config get-value project)/praisonai-app:latest .&#34;,
&#34;docker tag gcr.io/$(gcloud config get-value project)/praisonai-app:latest us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest&#34;,
&#34;docker push us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest&#34;,
&#34;gcloud run deploy praisonai-service --image us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest --platform managed --region us-central1 --allow-unauthenticated --set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE}&#34;
]
for cmd in commands:
try:
subprocess.run(cmd, shell=True, check=True)
except subprocess.CalledProcessError as e:
print(f&#34;ERROR: Command &#39;{e.cmd}&#39; failed with exit status {e.returncode}&#34;)
print(f&#34;Continuing with the next command...&#34;)</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.deploy.CloudDeployer.create_api_file"><code class="name flex">
<span>def <span class="ident">create_api_file</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Creates an API file for the application.</p>
<h2 id="parameters">Parameters</h2>
<p>self (CloudDeployer): An instance of the CloudDeployer class.</p>
<h2 id="returns">Returns</h2>
<p>None
This method creates an API file named "api.py" in the current directory. The file contains a basic Flask application that uses the PraisonAI library to run a simple agent and returns the output as an HTML page. The application listens on the root path ("/") and uses the Markdown library to format the output.</p></div>
</dd>
<dt id="praisonai.deploy.CloudDeployer.create_dockerfile"><code class="name flex">
<span>def <span class="ident">create_dockerfile</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Creates a Dockerfile for the application.</p>
<h2 id="parameters">Parameters</h2>
<p>self: An instance of the CloudDeployer class.</p>
<h2 id="returns">Returns</h2>
<p>None</p>
<h2 id="raises">Raises</h2>
<p>None
This method creates a Dockerfile in the current directory with the specified content.
The Dockerfile is used to build a Docker image for the application.
The content of the Dockerfile includes instructions to use the Python 3.11-slim base image,
set the working directory to /app, copy the current directory contents into the container,
install the required Python packages (flask, praisonai, gunicorn, and markdown),
expose port 8080, and run the application using Gunicorn.</p></div>
</dd>
<dt id="praisonai.deploy.CloudDeployer.run_commands"><code class="name flex">
<span>def <span class="ident">run_commands</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Sets environment variables with fallback to .env values or defaults.</p>
<h2 id="parameters">Parameters</h2>
<p>None</p>
<h2 id="returns">Returns</h2>
<p>None</p>
<h2 id="raises">Raises</h2>
<p>None
This method sets environment variables for the application. It uses the <code>os.environ</code> dictionary to set the following environment variables:</p>
<ul>
<li><code>OPENAI_MODEL_NAME</code>: The name of the OpenAI model to use. If not specified in the .env file, it defaults to "gpt-4o".</li>
<li><code>OPENAI_API_KEY</code>: The API key for accessing the OpenAI API. If not specified in the .env file, it defaults to "Enter your API key".</li>
<li><code>OPENAI_API_BASE</code>: The base URL for the OpenAI API. If not specified in the .env file, it defaults to "https://api.openai.com/v1".</li>
</ul></div>
</dd>
<dt id="praisonai.deploy.CloudDeployer.set_environment_variables"><code class="name flex">
<span>def <span class="ident">set_environment_variables</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Sets environment variables with fallback to .env values or defaults.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.deploy.CloudDeployer" href="#praisonai.deploy.CloudDeployer">CloudDeployer</a></code></h4>
<ul class="">
<li><code><a title="praisonai.deploy.CloudDeployer.create_api_file" href="#praisonai.deploy.CloudDeployer.create_api_file">create_api_file</a></code></li>
<li><code><a title="praisonai.deploy.CloudDeployer.create_dockerfile" href="#praisonai.deploy.CloudDeployer.create_dockerfile">create_dockerfile</a></code></li>
<li><code><a title="praisonai.deploy.CloudDeployer.run_commands" href="#praisonai.deploy.CloudDeployer.run_commands">run_commands</a></code></li>
<li><code><a title="praisonai.deploy.CloudDeployer.set_environment_variables" href="#praisonai.deploy.CloudDeployer.set_environment_variables">set_environment_variables</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
@@ -1,188 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inbuilt_tools.autogen_tools API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inbuilt_tools.autogen_tools</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_CSVSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_CodeDocsSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_DOCXSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool"><code class="name flex">
<span>def <span class="ident">autogen_DirectoryReadTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool"><code class="name flex">
<span>def <span class="ident">autogen_DirectorySearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool"><code class="name flex">
<span>def <span class="ident">autogen_FileReadTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_JSONSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_MDXSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_PDFSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_RagTool"><code class="name flex">
<span>def <span class="ident">autogen_RagTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool"><code class="name flex">
<span>def <span class="ident">autogen_ScrapeElementFromWebsiteTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool"><code class="name flex">
<span>def <span class="ident">autogen_ScrapeWebsiteTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_TXTSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_WebsiteSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_XMLSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_YoutubeChannelSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_YoutubeVideoSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.create_autogen_tool_function"><code class="name flex">
<span>def <span class="ident">create_autogen_tool_function</span></span>(<span>tool_name)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.inbuilt_tools" href="index.html">praisonai.inbuilt_tools</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool">autogen_CSVSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool">autogen_CodeDocsSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool">autogen_DOCXSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool">autogen_DirectoryReadTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool">autogen_DirectorySearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool">autogen_FileReadTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool">autogen_JSONSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool">autogen_MDXSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool">autogen_PDFSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_RagTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_RagTool">autogen_RagTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool">autogen_ScrapeElementFromWebsiteTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool">autogen_ScrapeWebsiteTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool">autogen_TXTSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool">autogen_WebsiteSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool">autogen_XMLSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool">autogen_YoutubeChannelSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool">autogen_YoutubeVideoSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.create_autogen_tool_function" href="#praisonai.inbuilt_tools.autogen_tools.create_autogen_tool_function">create_autogen_tool_function</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
@@ -1,67 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inbuilt_tools API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inbuilt_tools</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.inbuilt_tools.autogen_tools" href="autogen_tools.html">praisonai.inbuilt_tools.autogen_tools</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="../index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools" href="autogen_tools.html">praisonai.inbuilt_tools.autogen_tools</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-69
View File
@@ -1,69 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inc.config API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inc.config</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.inc.config.generate_config"><code class="name flex">
<span>def <span class="ident">generate_config</span></span>(<span>ollama_save=None, huggingface_save=None, train=None, model_name=None, hf_model_name=None, ollama_model_name=None, model_parameters=None, max_seq_length=None, load_in_4bit=None, lora_r=None, lora_target_modules=None, lora_alpha=None, lora_dropout=None, lora_bias=None, use_gradient_checkpointing=None, random_state=None, use_rslora=None, loftq_config=None, dataset=None, dataset_text_field=None, dataset_num_proc=None, packing=None, per_device_train_batch_size=None, gradient_accumulation_steps=None, warmup_steps=None, num_train_epochs=None, max_steps=None, learning_rate=None, logging_steps=None, optim=None, weight_decay=None, lr_scheduler_type=None, seed=None, output_dir=None, quantization_method=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates the configuration for PraisonAI with dynamic overrides.</p></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.inc" href="index.html">praisonai.inc</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.inc.config.generate_config" href="#praisonai.inc.config.generate_config">generate_config</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-72
View File
@@ -1,72 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inc API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inc</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.inc.config" href="config.html">praisonai.inc.config</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.inc.models" href="models.html">praisonai.inc.models</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="../index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.inc.config" href="config.html">praisonai.inc.config</a></code></li>
<li><code><a title="praisonai.inc.models" href="models.html">praisonai.inc.models</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-200
View File
@@ -1,200 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inc.models API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inc.models</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.inc.models.PraisonAIModel"><code class="flex name class">
<span>class <span class="ident">PraisonAIModel</span></span>
<span>(</span><span>model=None, api_key_var=None, base_url=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initializes the PraisonAIModel with the provided parameters or environment variables.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>model</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The name of the OpenAI model. Defaults to None.</dd>
<dt><strong><code>api_key_var</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The OpenAI API key. Defaults to None.</dd>
<dt><strong><code>base_url</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The base URL for the OpenAI API. Defaults to None.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class PraisonAIModel:
def __init__(self, model=None, api_key_var=None, base_url=None):
&#34;&#34;&#34;
Initializes the PraisonAIModel with the provided parameters or environment variables.
Args:
model (str, optional): The name of the OpenAI model. Defaults to None.
api_key_var (str, optional): The OpenAI API key. Defaults to None.
base_url (str, optional): The base URL for the OpenAI API. Defaults to None.
&#34;&#34;&#34;
self.model = model or os.getenv(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;)
if self.model.startswith(&#34;openai/&#34;):
self.api_key_var = &#34;OPENAI_API_KEY&#34;
self.base_url = base_url or &#34;https://api.openai.com/v1&#34;
self.model_name = self.model.replace(&#34;openai/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;groq/&#34;):
self.api_key_var = &#34;GROQ_API_KEY&#34;
self.base_url = base_url or &#34;https://api.groq.com/openai/v1&#34;
self.model_name = self.model.replace(&#34;groq/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;cohere/&#34;):
self.api_key_var = &#34;COHERE_API_KEY&#34;
self.base_url = &#34;&#34;
self.model_name = self.model.replace(&#34;cohere/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;ollama/&#34;):
self.api_key_var = &#34;OLLAMA_API_KEY&#34;
self.base_url = base_url or &#34;http://localhost:11434/v1&#34;
self.model_name = self.model.replace(&#34;ollama/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;anthropic/&#34;):
self.api_key_var = &#34;ANTHROPIC_API_KEY&#34;
self.base_url = &#34;&#34;
self.model_name = self.model.replace(&#34;anthropic/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;google/&#34;):
self.api_key_var = &#34;GOOGLE_API_KEY&#34;
self.base_url = &#34;&#34;
self.model_name = self.model.replace(&#34;google/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;openrouter/&#34;):
self.api_key_var = &#34;OPENROUTER_API_KEY&#34;
self.base_url = base_url or &#34;https://openrouter.ai/api/v1&#34;
self.model_name = self.model.replace(&#34;openrouter/&#34;, &#34;&#34;)
else:
self.api_key_var = api_key_var or &#34;OPENAI_API_KEY&#34;
self.base_url = base_url or os.environ.get(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;)
self.model_name = self.model
logger.debug(f&#34;Initialized PraisonAIModel with model {self.model_name}, api_key_var {self.api_key_var}, and base_url {self.base_url}&#34;)
self.api_key = os.environ.get(self.api_key_var, &#34;nokey&#34;)
def get_model(self):
&#34;&#34;&#34;
Returns an instance of the langchain Chat client with the configured parameters.
Returns:
Chat: An instance of the langchain Chat client.
&#34;&#34;&#34;
if self.model.startswith(&#34;google/&#34;):
if GOOGLE_GENAI_AVAILABLE:
return ChatGoogleGenerativeAI(
model=self.model_name,
google_api_key=self.api_key
)
else:
raise ImportError(
&#34;Required Langchain Integration &#39;langchain-google-genai&#39; not found. &#34;
&#34;Please install with &#39;pip install langchain-google-genai&#39;&#34;
)
elif self.model.startswith(&#34;cohere/&#34;):
if COHERE_AVAILABLE:
return ChatCohere(
model=self.model_name,
cohere_api_key=self.api_key,
)
else:
raise ImportError(
&#34;Required Langchain Integration &#39;langchain-cohere&#39; not found. &#34;
&#34;Please install with &#39;pip install langchain-cohere&#39;&#34;
)
elif self.model.startswith(&#34;anthropic/&#34;):
if ANTHROPIC_AVAILABLE:
return ChatAnthropic(
model=self.model_name,
anthropic_api_key=self.api_key,
)
else:
raise ImportError(
&#34;Required Langchain Integration &#39;langchain-anthropic&#39; not found. &#34;
&#34;Please install with &#39;pip install langchain-anthropic&#39;&#34;
)
elif OPENAI_AVAILABLE:
return ChatOpenAI(
model=self.model_name,
api_key=self.api_key,
base_url=self.base_url,
)
else:
raise ImportError(
&#34;Required Langchain Integration &#39;langchain-openai&#39; not found. &#34;
&#34;Please install with &#39;pip install langchain-openai&#39;&#34;
)</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.inc.models.PraisonAIModel.get_model"><code class="name flex">
<span>def <span class="ident">get_model</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Returns an instance of the langchain Chat client with the configured parameters.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>Chat</code></dt>
<dd>An instance of the langchain Chat client.</dd>
</dl></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.inc" href="index.html">praisonai.inc</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.inc.models.PraisonAIModel" href="#praisonai.inc.models.PraisonAIModel">PraisonAIModel</a></code></h4>
<ul class="">
<li><code><a title="praisonai.inc.models.PraisonAIModel.get_model" href="#praisonai.inc.models.PraisonAIModel.get_model">get_model</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-107
View File
@@ -1,107 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Package <code>praisonai</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.agents_generator" href="agents_generator.html">praisonai.agents_generator</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.auto" href="auto.html">praisonai.auto</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.cli" href="cli.html">praisonai.cli</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.deploy" href="deploy.html">praisonai.deploy</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.inbuilt_tools" href="inbuilt_tools/index.html">praisonai.inbuilt_tools</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.inc" href="inc/index.html">praisonai.inc</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.setup" href="setup/index.html">praisonai.setup</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.test" href="test.html">praisonai.test</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.ui" href="ui/index.html">praisonai.ui</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.version" href="version.html">praisonai.version</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.agents_generator" href="agents_generator.html">praisonai.agents_generator</a></code></li>
<li><code><a title="praisonai.auto" href="auto.html">praisonai.auto</a></code></li>
<li><code><a title="praisonai.cli" href="cli.html">praisonai.cli</a></code></li>
<li><code><a title="praisonai.deploy" href="deploy.html">praisonai.deploy</a></code></li>
<li><code><a title="praisonai.inbuilt_tools" href="inbuilt_tools/index.html">praisonai.inbuilt_tools</a></code></li>
<li><code><a title="praisonai.inc" href="inc/index.html">praisonai.inc</a></code></li>
<li><code><a title="praisonai.setup" href="setup/index.html">praisonai.setup</a></code></li>
<li><code><a title="praisonai.test" href="test.html">praisonai.test</a></code></li>
<li><code><a title="praisonai.ui" href="ui/index.html">praisonai.ui</a></code></li>
<li><code><a title="praisonai.version" href="version.html">praisonai.version</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-69
View File
@@ -1,69 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.setup.build API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.setup.build</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.setup.build.build"><code class="name flex">
<span>def <span class="ident">build</span></span>(<span>setup_kwargs)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.setup" href="index.html">praisonai.setup</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.setup.build.build" href="#praisonai.setup.build.build">build</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-77
View File
@@ -1,77 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.setup API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.setup</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.setup.build" href="build.html">praisonai.setup.build</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.setup.post_install" href="post_install.html">praisonai.setup.post_install</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.setup.setup_conda_env" href="setup_conda_env.html">praisonai.setup.setup_conda_env</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="../index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.setup.build" href="build.html">praisonai.setup.build</a></code></li>
<li><code><a title="praisonai.setup.post_install" href="post_install.html">praisonai.setup.post_install</a></code></li>
<li><code><a title="praisonai.setup.setup_conda_env" href="setup_conda_env.html">praisonai.setup.setup_conda_env</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
@@ -1,69 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.setup.post_install API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.setup.post_install</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.setup.post_install.main"><code class="name flex">
<span>def <span class="ident">main</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.setup" href="index.html">praisonai.setup</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.setup.post_install.main" href="#praisonai.setup.post_install.main">main</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
@@ -1,69 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.setup.setup_conda_env API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.setup.setup_conda_env</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.setup.setup_conda_env.main"><code class="name flex">
<span>def <span class="ident">main</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.setup" href="index.html">praisonai.setup</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.setup.setup_conda_env.main" href="#praisonai.setup.setup_conda_env.main">main</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-73
View File
@@ -1,73 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.test API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.test</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.test.generate_crew_and_kickoff"><code class="name flex">
<span>def <span class="ident">generate_crew_and_kickoff</span></span>(<span>agent_file)</span>
</code></dt>
<dd>
<div class="desc"><p>This function generates a crew of agents and kicks off tasks based on the configuration provided in a YAML file.</p>
<p>Parameters:
agent_file (str): The path to the YAML file containing the configuration for the agents and tasks.</p>
<p>Returns:
str: The result of the last task executed by the crew.</p></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.test.generate_crew_and_kickoff" href="#praisonai.test.generate_crew_and_kickoff">generate_crew_and_kickoff</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-428
View File
@@ -1,428 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.ui.context API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.ui.context</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.ui.context.main"><code class="name flex">
<span>def <span class="ident">main</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.ui.context.ContextGatherer"><code class="flex name class">
<span>class <span class="ident">ContextGatherer</span></span>
<span>(</span><span>directory='.', output_file='context.txt', relevant_extensions=None, max_file_size=1000000, max_tokens=900000)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class ContextGatherer:
def __init__(self, directory=&#39;.&#39;, output_file=&#39;context.txt&#39;,
relevant_extensions=None, max_file_size=1_000_000, max_tokens=900000):
self.directory = directory
self.output_file = output_file
self.relevant_extensions = relevant_extensions or [
&#39;.py&#39;, &#39;.js&#39;, &#39;.ts&#39;, &#39;.java&#39;, &#39;.rb&#39;, &#39;.php&#39;, &#39;.pl&#39;, &#39;.pm&#39;, &#39;.c&#39;, &#39;.h&#39;,
&#39;.cpp&#39;, &#39;.hpp&#39;, &#39;.cs&#39;, &#39;.vb&#39;, &#39;.swift&#39;, &#39;.kt&#39;, &#39;.m&#39;, &#39;.mm&#39;, &#39;.go&#39;, &#39;.rs&#39;,
&#39;.hs&#39;, &#39;.r&#39;, &#39;.lua&#39;, &#39;.sh&#39;, &#39;.bat&#39;, &#39;.clj&#39;, &#39;.scala&#39;, &#39;.erl&#39;, &#39;.ex&#39;,
&#39;.ml&#39;, &#39;.fs&#39;, &#39;.groovy&#39;, &#39;.jsm&#39;, &#39;.jsx&#39;, &#39;.tsx&#39;, &#39;.yaml&#39;
]
self.max_file_size = max_file_size
self.max_tokens = int(os.getenv(&#34;PRAISONAI_MAX_TOKENS&#34;, max_tokens))
self.ignore_patterns = self.get_ignore_patterns()
self.include_paths = self.get_include_paths()
self.included_files = []
def get_ignore_patterns(self):
&#34;&#34;&#34;
Loads ignore patterns from various sources, prioritizing them in
the following order:
1. .praisonignore
2. settings.yaml (under code.ignore_files)
3. PRAISONAI_IGNORE_FILES environment variable
4. .gitignore
5. Default patterns
&#34;&#34;&#34;
ignore_patterns = []
def load_from_file(filepath):
if os.path.exists(filepath):
with open(filepath, &#39;r&#39;) as f:
ignore_patterns.extend(
line.strip() for line in f
if line.strip() and not line.startswith(&#39;#&#39;)
)
# 1. Load from .praisonignore
load_from_file(os.path.join(self.directory, &#39;.praisonignore&#39;))
# 2. Load from settings.yaml
settings_path = os.path.join(self.directory, &#39;settings.yaml&#39;)
if os.path.exists(settings_path):
with open(settings_path, &#39;r&#39;) as f:
settings = yaml.safe_load(f)
if &#39;code&#39; in settings and &#39;ignore_files&#39; in settings[&#39;code&#39;]:
ignore_patterns.extend(settings[&#39;code&#39;][&#39;ignore_files&#39;])
# 3. Load from environment variable
ignore_files_env = os.getenv(&#34;PRAISONAI_IGNORE_FILES&#34;)
if ignore_files_env:
ignore_patterns.extend(ignore_files_env.split(&#34;,&#34;))
# 4. Load from .gitignore
load_from_file(os.path.join(self.directory, &#39;.gitignore&#39;))
# 5. Default patterns (only if no patterns loaded from above sources)
if not ignore_patterns:
ignore_patterns = [
&#34;.*&#34;, &#34;*.pyc&#34;, &#34;__pycache__&#34;, &#34;.git&#34;, &#34;.gitignore&#34;, &#34;.vscode&#34;,
&#34;.idea&#34;, &#34;.DS_Store&#34;, &#34;*.lock&#34;, &#34;*.pyc&#34;, &#34;.env&#34;, &#34;docs&#34;, &#34;tests&#34;,
&#34;test&#34;, &#34;tmp&#34;, &#34;temp&#34;, &#34;*.txt&#34;, &#34;*.md&#34;, &#34;*.json&#34;, &#34;*.csv&#34;, &#34;*.tsv&#34;,
&#34;public&#34;, &#34;*.sql&#34;, &#34;*.sqlite&#34;, &#34;*.db&#34;, &#34;*.db3&#34;, &#34;*.sqlite3&#34;,
&#34;*.log&#34;, &#34;*.zip&#34;, &#34;*.gz&#34;, &#34;*.tar&#34;, &#34;*.rar&#34;, &#34;*.7z&#34;, &#34;*.pdf&#34;,
&#34;*.jpg&#34;, &#34;*.jpeg&#34;, &#34;*.png&#34;, &#34;*.gif&#34;, &#34;*.svg&#34;, &#34;cookbooks&#34;,
&#34;assets&#34;, &#34;__pycache__&#34;, &#34;dist&#34;, &#34;build&#34;, &#34;node_modules&#34;, &#34;venv&#34;
]
logger.debug(f&#34;Using default ignore patterns: {ignore_patterns}&#34;)
# Modify patterns to match directories and add leading &#39;*&#39; if necessary
modified_ignore_patterns = [
&#39;*&#39; + pattern if not pattern.startswith(&#39;.&#39;) and not pattern.startswith(&#39;*&#39;) else pattern
for pattern in ignore_patterns
]
logger.debug(f&#34;Final ignore patterns: {modified_ignore_patterns}&#34;)
return modified_ignore_patterns
def get_include_paths(self):
&#34;&#34;&#34;
Loads include paths from:
1. .praisoninclude (includes ONLY files/directories listed)
2. .praisoncontext (if .praisoninclude doesn&#39;t exist, this is used
to include all other relevant files, excluding ignore patterns)
&#34;&#34;&#34;
include_paths = []
include_all = False # Flag to indicate if we need to include all files
include_file = os.path.join(self.directory, &#39;.praisoncontext&#39;)
if os.path.exists(include_file):
with open(include_file, &#39;r&#39;) as f:
include_paths.extend(
line.strip() for line in f
if line.strip() and not line.startswith(&#39;#&#39;)
)
# If .praisoncontext doesn&#39;t exist, fall back to .praisoninclude
# for including all relevant files
if not include_paths:
include_file = os.path.join(self.directory, &#39;.praisoninclude&#39;)
if os.path.exists(include_file):
with open(include_file, &#39;r&#39;) as f:
include_paths.extend(
line.strip() for line in f
if line.strip() and not line.startswith(&#39;#&#39;)
)
include_all = True # Include all files along with specified paths
return include_paths, include_all
def should_ignore(self, file_path):
&#34;&#34;&#34;
Check if a file or directory should be ignored based on patterns.
Handles both file names and directory names for more comprehensive filtering.
&#34;&#34;&#34;
relative_path = os.path.relpath(file_path, self.directory)
if relative_path.startswith(&#39;.&#39;):
return True
for pattern in self.ignore_patterns:
if fnmatch.fnmatch(relative_path, pattern) or \
fnmatch.fnmatch(os.path.basename(file_path), pattern):
return True
return False
def is_relevant_file(self, file_path):
&#34;&#34;&#34;Determine if a file is relevant for the context.&#34;&#34;&#34;
return os.path.isfile(file_path) and \
os.path.getsize(file_path) &lt;= self.max_file_size and \
any(file_path.endswith(ext) for ext in self.relevant_extensions)
def gather_context(self):
&#34;&#34;&#34;
Gather context from relevant files, respecting ignore patterns
and include options from .praisoninclude and .praisoncontext.
&#34;&#34;&#34;
context = []
total_files = 0
processed_files = 0
self.include_paths, include_all = self.get_include_paths()
def add_file_content(file_path):
&#34;&#34;&#34;Helper function to add file content to context.&#34;&#34;&#34;
try:
with open(file_path, &#39;r&#39;, encoding=&#39;utf-8&#39;) as f:
content = f.read()
context.append(
f&#34;File: {file_path}\n\n{content}\n\n{&#39;=&#39; * 50}\n&#34;
)
self.included_files.append(
Path(file_path).relative_to(self.directory)
)
except Exception as e:
logger.error(f&#34;Error reading {file_path}: {e}&#34;)
def process_path(path):
&#34;&#34;&#34;Helper function to process a single path (file or directory).&#34;&#34;&#34;
nonlocal total_files, processed_files
if os.path.isdir(path):
for root, dirs, files in os.walk(path):
total_files += len(files)
dirs[:] = [
d
for d in dirs
if not self.should_ignore(os.path.join(root, d))
]
for file in files:
file_path = os.path.join(root, file)
if not self.should_ignore(file_path) and self.is_relevant_file(file_path):
add_file_content(file_path)
processed_files += 1
print(
f&#34;\rProcessed {processed_files}/{total_files} files&#34;,
end=&#34;&#34;,
flush=True,
)
elif os.path.isfile(path) and self.is_relevant_file(path):
add_file_content(path)
processed_files += 1
print(
f&#34;\rProcessed {processed_files}/1 files&#34;,
end=&#34;&#34;,
flush=True,
)
if include_all:
# Include ALL relevant files from the entire directory
process_path(self.directory)
# Include files from .praisoninclude specifically
for include_path in self.include_paths:
full_path = os.path.join(self.directory, include_path)
process_path(full_path)
elif self.include_paths:
# Include only files specified in .praisoncontext
for include_path in self.include_paths:
full_path = os.path.join(self.directory, include_path)
process_path(full_path)
else:
# No include options, process the entire directory
process_path(self.directory)
print() # New line after progress indicator
return &#34;\n&#34;.join(context)
def count_tokens(self, text):
&#34;&#34;&#34;Count tokens using a simple whitespace-based tokenizer.&#34;&#34;&#34;
return len(text.split())
def truncate_context(self, context):
&#34;&#34;&#34;Truncate context to stay within the token limit.&#34;&#34;&#34;
tokens = context.split()
if len(tokens) &gt; self.max_tokens:
truncated_context = &#39; &#39;.join(tokens[:self.max_tokens])
logger.warning(&#34;Context truncated due to token limit.&#34;)
return truncated_context
return context
def save_context(self, context):
&#34;&#34;&#34;Save the gathered context to a file.&#34;&#34;&#34;
with open(self.output_file, &#39;w&#39;, encoding=&#39;utf-8&#39;) as f:
f.write(context)
def get_context_tree(self):
&#34;&#34;&#34;Generate a formatted tree structure of included files and folders.&#34;&#34;&#34;
tree = []
start_dir = Path(self.directory)
def add_to_tree(path, prefix=&#39;&#39;):
contents = sorted(path.iterdir())
pointers = [(&#39;└── &#39; if i == len(contents) - 1 else &#39;├── &#39;) for i in range(len(contents))]
for pointer, item in zip(pointers, contents):
rel_path = item.relative_to(start_dir)
if rel_path in self.included_files:
tree.append(f&#34;{prefix}{pointer}{rel_path}&#34;)
if item.is_dir():
add_to_tree(item, prefix + (&#39; &#39; if pointer == &#39;└── &#39; else &#39;│ &#39;))
add_to_tree(start_dir)
return &#39;\n&#39;.join(tree)
def run(self):
&#34;&#34;&#34;Execute the context gathering, truncation, and reporting.&#34;&#34;&#34;
context = self.gather_context()
context = self.truncate_context(context)
token_count = self.count_tokens(context)
print(f&#34;Context gathered successfully.&#34;)
print(f&#34;Total number of tokens (estimated): {token_count}&#34;)
# self.save_context(context)
context_tree = self.get_context_tree()
logger.debug(f&#34;Context tree:\n{context_tree}&#34;)
return context, token_count, context_tree</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.ui.context.ContextGatherer.count_tokens"><code class="name flex">
<span>def <span class="ident">count_tokens</span></span>(<span>self, text)</span>
</code></dt>
<dd>
<div class="desc"><p>Count tokens using a simple whitespace-based tokenizer.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.gather_context"><code class="name flex">
<span>def <span class="ident">gather_context</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Gather context from relevant files, respecting ignore patterns
and include options from .praisoninclude and .praisoncontext.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.get_context_tree"><code class="name flex">
<span>def <span class="ident">get_context_tree</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generate a formatted tree structure of included files and folders.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.get_ignore_patterns"><code class="name flex">
<span>def <span class="ident">get_ignore_patterns</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads ignore patterns from various sources, prioritizing them in
the following order:
1. .praisonignore
2. settings.yaml (under code.ignore_files)
3. PRAISONAI_IGNORE_FILES environment variable
4. .gitignore
5. Default patterns</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.get_include_paths"><code class="name flex">
<span>def <span class="ident">get_include_paths</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads include paths from:
1. .praisoninclude (includes ONLY files/directories listed)
2. .praisoncontext (if .praisoninclude doesn't exist, this is used
to include all other relevant files, excluding ignore patterns)</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.is_relevant_file"><code class="name flex">
<span>def <span class="ident">is_relevant_file</span></span>(<span>self, file_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Determine if a file is relevant for the context.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.run"><code class="name flex">
<span>def <span class="ident">run</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Execute the context gathering, truncation, and reporting.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.save_context"><code class="name flex">
<span>def <span class="ident">save_context</span></span>(<span>self, context)</span>
</code></dt>
<dd>
<div class="desc"><p>Save the gathered context to a file.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.should_ignore"><code class="name flex">
<span>def <span class="ident">should_ignore</span></span>(<span>self, file_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Check if a file or directory should be ignored based on patterns.
Handles both file names and directory names for more comprehensive filtering.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.truncate_context"><code class="name flex">
<span>def <span class="ident">truncate_context</span></span>(<span>self, context)</span>
</code></dt>
<dd>
<div class="desc"><p>Truncate context to stay within the token limit.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.ui" href="index.html">praisonai.ui</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.ui.context.main" href="#praisonai.ui.context.main">main</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.ui.context.ContextGatherer" href="#praisonai.ui.context.ContextGatherer">ContextGatherer</a></code></h4>
<ul class="two-column">
<li><code><a title="praisonai.ui.context.ContextGatherer.count_tokens" href="#praisonai.ui.context.ContextGatherer.count_tokens">count_tokens</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.gather_context" href="#praisonai.ui.context.ContextGatherer.gather_context">gather_context</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.get_context_tree" href="#praisonai.ui.context.ContextGatherer.get_context_tree">get_context_tree</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.get_ignore_patterns" href="#praisonai.ui.context.ContextGatherer.get_ignore_patterns">get_ignore_patterns</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.get_include_paths" href="#praisonai.ui.context.ContextGatherer.get_include_paths">get_include_paths</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.is_relevant_file" href="#praisonai.ui.context.ContextGatherer.is_relevant_file">is_relevant_file</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.run" href="#praisonai.ui.context.ContextGatherer.run">run</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.save_context" href="#praisonai.ui.context.ContextGatherer.save_context">save_context</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.should_ignore" href="#praisonai.ui.context.ContextGatherer.should_ignore">should_ignore</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.truncate_context" href="#praisonai.ui.context.ContextGatherer.truncate_context">truncate_context</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-77
View File
@@ -1,77 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.ui API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Namespace <code>praisonai.ui</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.ui.context" href="context.html">praisonai.ui.context</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.ui.realtimeclient" href="realtimeclient/index.html">praisonai.ui.realtimeclient</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.ui.sql_alchemy" href="sql_alchemy.html">praisonai.ui.sql_alchemy</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="../index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.ui.context" href="context.html">praisonai.ui.context</a></code></li>
<li><code><a title="praisonai.ui.realtimeclient" href="realtimeclient/index.html">praisonai.ui.realtimeclient</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy" href="sql_alchemy.html">praisonai.ui.sql_alchemy</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
File diff suppressed because it is too large. Load diff
-898
View File
@@ -1,898 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.ui.sql_alchemy API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.ui.sql_alchemy</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer"><code class="flex name class">
<span>class <span class="ident">SQLAlchemyDataLayer</span></span>
<span>(</span><span>conninfo: str, ssl_require: bool = False, storage_provider: Optional[chainlit.data.base.BaseStorageClient] = None, user_thread_limit: Optional[int] = 1000, show_logger: Optional[bool] = False)</span>
</code></dt>
<dd>
<div class="desc"><p>Base class for data persistence.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class SQLAlchemyDataLayer(BaseDataLayer):
def __init__(
self,
conninfo: str,
ssl_require: bool = False,
storage_provider: Optional[BaseStorageClient] = None,
user_thread_limit: Optional[int] = 1000,
show_logger: Optional[bool] = False,
):
self._conninfo = conninfo
self.user_thread_limit = user_thread_limit
self.show_logger = show_logger
ssl_args = {}
if ssl_require:
# Create an SSL context to require an SSL connection
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
ssl_args[&#34;ssl&#34;] = ssl_context
self.engine: AsyncEngine = create_async_engine(
self._conninfo, connect_args=ssl_args
)
self.async_session = sessionmaker(
bind=self.engine, expire_on_commit=False, class_=AsyncSession
) # type: ignore
if storage_provider:
self.storage_provider: Optional[BaseStorageClient] = storage_provider
if self.show_logger:
logger.info(&#34;SQLAlchemyDataLayer storage client initialized&#34;)
else:
self.storage_provider = None
logger.warn(
&#34;SQLAlchemyDataLayer storage client is not initialized and elements will not be persisted!&#34;
)
async def build_debug_url(self) -&gt; str:
return &#34;&#34;
###### SQL Helpers ######
async def execute_sql(
self, query: str, parameters: dict
) -&gt; Union[List[Dict[str, Any]], int, None]:
parameterized_query = text(query)
async with self.async_session() as session:
try:
await session.begin()
result = await session.execute(parameterized_query, parameters)
await session.commit()
if result.returns_rows:
json_result = [dict(row._mapping) for row in result.fetchall()]
clean_json_result = self.clean_result(json_result)
assert isinstance(clean_json_result, list) or isinstance(
clean_json_result, int
)
return clean_json_result
else:
return result.rowcount
except SQLAlchemyError as e:
await session.rollback()
logger.warn(f&#34;An error occurred: {e}&#34;)
return None
except Exception as e:
await session.rollback()
logger.warn(f&#34;An unexpected error occurred: {e}&#34;)
return None
async def get_current_timestamp(self) -&gt; str:
return datetime.now().isoformat() + &#34;Z&#34;
def clean_result(self, obj):
&#34;&#34;&#34;Recursively change UUID -&gt; str and serialize dictionaries&#34;&#34;&#34;
if isinstance(obj, dict):
return {k: self.clean_result(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [self.clean_result(item) for item in obj]
elif isinstance(obj, uuid.UUID):
return str(obj)
return obj
###### User ######
async def get_user(self, identifier: str) -&gt; Optional[PersistedUser]:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: get_user, identifier={identifier}&#34;)
query = &#34;SELECT * FROM users WHERE identifier = :identifier&#34;
parameters = {&#34;identifier&#34;: identifier}
result = await self.execute_sql(query=query, parameters=parameters)
if result and isinstance(result, list):
user_data = result[0]
# SQLite returns JSON as string, we most convert it. (#1137)
metadata = user_data.get(&#34;metadata&#34;, {})
if isinstance(metadata, str):
metadata = json.loads(metadata)
assert isinstance(metadata, dict)
assert isinstance(user_data[&#34;id&#34;], str)
assert isinstance(user_data[&#34;identifier&#34;], str)
assert isinstance(user_data[&#34;createdAt&#34;], str)
return PersistedUser(
id=user_data[&#34;id&#34;],
identifier=user_data[&#34;identifier&#34;],
createdAt=user_data[&#34;createdAt&#34;],
metadata=metadata,
)
return None
async def _get_user_identifer_by_id(self, user_id: str) -&gt; str:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: _get_user_identifer_by_id, user_id={user_id}&#34;)
query = &#34;SELECT identifier FROM users WHERE id = :user_id&#34;
parameters = {&#34;user_id&#34;: user_id}
result = await self.execute_sql(query=query, parameters=parameters)
assert result
assert isinstance(result, list)
return result[0][&#34;identifier&#34;]
async def _get_user_id_by_thread(self, thread_id: str) -&gt; Optional[str]:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: _get_user_id_by_thread, thread_id={thread_id}&#34;)
query = &#34;SELECT userId FROM threads WHERE id = :thread_id&#34;
parameters = {&#34;thread_id&#34;: thread_id}
result = await self.execute_sql(query=query, parameters=parameters)
if result:
assert isinstance(result, list)
return result[0][&#34;userId&#34;]
return None
async def create_user(self, user: User) -&gt; Optional[PersistedUser]:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: create_user, user_identifier={user.identifier}&#34;)
existing_user: Optional[&#34;PersistedUser&#34;] = await self.get_user(user.identifier)
user_dict: Dict[str, Any] = {
&#34;identifier&#34;: str(user.identifier),
&#34;metadata&#34;: json.dumps(user.metadata) or {},
}
if not existing_user: # create the user
if self.show_logger:
logger.info(&#34;SQLAlchemy: create_user, creating the user&#34;)
user_dict[&#34;id&#34;] = str(uuid.uuid4())
user_dict[&#34;createdAt&#34;] = await self.get_current_timestamp()
query = &#34;&#34;&#34;INSERT INTO users (&#34;id&#34;, &#34;identifier&#34;, &#34;createdAt&#34;, &#34;metadata&#34;) VALUES (:id, :identifier, :createdAt, :metadata)&#34;&#34;&#34;
await self.execute_sql(query=query, parameters=user_dict)
else: # update the user
if self.show_logger:
logger.info(&#34;SQLAlchemy: update user metadata&#34;)
query = &#34;&#34;&#34;UPDATE users SET &#34;metadata&#34; = :metadata WHERE &#34;identifier&#34; = :identifier&#34;&#34;&#34;
await self.execute_sql(
query=query, parameters=user_dict
) # We want to update the metadata
return await self.get_user(user.identifier)
###### Threads ######
async def get_thread_author(self, thread_id: str) -&gt; str:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: get_thread_author, thread_id={thread_id}&#34;)
query = &#34;&#34;&#34;SELECT &#34;userIdentifier&#34; FROM threads WHERE &#34;id&#34; = :id&#34;&#34;&#34;
parameters = {&#34;id&#34;: thread_id}
result = await self.execute_sql(query=query, parameters=parameters)
if isinstance(result, list) and result:
author_identifier = result[0].get(&#34;userIdentifier&#34;)
if author_identifier is not None:
return author_identifier
raise ValueError(f&#34;Author not found for thread_id {thread_id}&#34;)
async def get_thread(self, thread_id: str) -&gt; Optional[ThreadDict]:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: get_thread, thread_id={thread_id}&#34;)
user_threads: Optional[List[ThreadDict]] = await self.get_all_user_threads(
thread_id=thread_id
)
if user_threads:
return user_threads[0]
else:
return None
async def update_thread(
self,
thread_id: str,
name: Optional[str] = None,
user_id: Optional[str] = None,
metadata: Optional[Dict] = None,
tags: Optional[List[str]] = None,
):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: update_thread, thread_id={thread_id}&#34;)
user_identifier = None
if user_id:
user_identifier = await self._get_user_identifer_by_id(user_id)
data = {
&#34;id&#34;: thread_id,
&#34;createdAt&#34;: (
await self.get_current_timestamp() if metadata is None else None
),
&#34;name&#34;: (
name
if name is not None
else (metadata.get(&#34;name&#34;) if metadata and &#34;name&#34; in metadata else None)
),
&#34;userId&#34;: user_id,
&#34;userIdentifier&#34;: user_identifier,
&#34;tags&#34;: tags,
&#34;metadata&#34;: json.dumps(metadata) if metadata else None,
}
parameters = {
key: value for key, value in data.items() if value is not None
} # Remove keys with None values
columns = &#34;, &#34;.join(f&#39;&#34;{key}&#34;&#39; for key in parameters.keys())
values = &#34;, &#34;.join(f&#34;:{key}&#34; for key in parameters.keys())
updates = &#34;, &#34;.join(
f&#39;&#34;{key}&#34; = EXCLUDED.&#34;{key}&#34;&#39; for key in parameters.keys() if key != &#34;id&#34;
)
query = f&#34;&#34;&#34;
INSERT INTO threads ({columns})
VALUES ({values})
ON CONFLICT (&#34;id&#34;) DO UPDATE
SET {updates};
&#34;&#34;&#34;
await self.execute_sql(query=query, parameters=parameters)
async def delete_thread(self, thread_id: str):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: delete_thread, thread_id={thread_id}&#34;)
# Delete feedbacks/elements/steps/thread
feedbacks_query = &#34;&#34;&#34;DELETE FROM feedbacks WHERE &#34;forId&#34; IN (SELECT &#34;id&#34; FROM steps WHERE &#34;threadId&#34; = :id)&#34;&#34;&#34;
elements_query = &#34;&#34;&#34;DELETE FROM elements WHERE &#34;threadId&#34; = :id&#34;&#34;&#34;
steps_query = &#34;&#34;&#34;DELETE FROM steps WHERE &#34;threadId&#34; = :id&#34;&#34;&#34;
thread_query = &#34;&#34;&#34;DELETE FROM threads WHERE &#34;id&#34; = :id&#34;&#34;&#34;
parameters = {&#34;id&#34;: thread_id}
await self.execute_sql(query=feedbacks_query, parameters=parameters)
await self.execute_sql(query=elements_query, parameters=parameters)
await self.execute_sql(query=steps_query, parameters=parameters)
await self.execute_sql(query=thread_query, parameters=parameters)
async def list_threads(
self, pagination: Pagination, filters: ThreadFilter
) -&gt; PaginatedResponse:
if self.show_logger:
logger.info(
f&#34;SQLAlchemy: list_threads, pagination={pagination}, filters={filters}&#34;
)
if not filters.userId:
raise ValueError(&#34;userId is required&#34;)
all_user_threads: List[ThreadDict] = (
await self.get_all_user_threads(user_id=filters.userId) or []
)
search_keyword = filters.search.lower() if filters.search else None
feedback_value = int(filters.feedback) if filters.feedback else None
filtered_threads = []
for thread in all_user_threads:
keyword_match = True
feedback_match = True
if search_keyword or feedback_value is not None:
if search_keyword:
keyword_match = any(
search_keyword in step[&#34;output&#34;].lower()
for step in thread[&#34;steps&#34;]
if &#34;output&#34; in step
)
if feedback_value is not None:
feedback_match = False # Assume no match until found
for step in thread[&#34;steps&#34;]:
feedback = step.get(&#34;feedback&#34;)
if feedback and feedback.get(&#34;value&#34;) == feedback_value:
feedback_match = True
break
if keyword_match and feedback_match:
filtered_threads.append(thread)
start = 0
if pagination.cursor:
for i, thread in enumerate(filtered_threads):
if (
thread[&#34;id&#34;] == pagination.cursor
): # Find the start index using pagination.cursor
start = i + 1
break
end = start + pagination.first
paginated_threads = filtered_threads[start:end] or []
has_next_page = len(filtered_threads) &gt; end
start_cursor = paginated_threads[0][&#34;id&#34;] if paginated_threads else None
end_cursor = paginated_threads[-1][&#34;id&#34;] if paginated_threads else None
return PaginatedResponse(
pageInfo=PageInfo(
hasNextPage=has_next_page,
startCursor=start_cursor,
endCursor=end_cursor,
),
data=paginated_threads,
)
###### Steps ######
@queue_until_user_message()
async def create_step(self, step_dict: &#34;StepDict&#34;):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: create_step, step_id={step_dict.get(&#39;id&#39;)}&#34;)
step_dict[&#34;showInput&#34;] = (
str(step_dict.get(&#34;showInput&#34;, &#34;&#34;)).lower()
if &#34;showInput&#34; in step_dict
else None
)
parameters = {
key: value
for key, value in step_dict.items()
if value is not None and not (isinstance(value, dict) and not value)
}
parameters[&#34;metadata&#34;] = json.dumps(step_dict.get(&#34;metadata&#34;, {}))
parameters[&#34;generation&#34;] = json.dumps(step_dict.get(&#34;generation&#34;, {}))
columns = &#34;, &#34;.join(f&#39;&#34;{key}&#34;&#39; for key in parameters.keys())
values = &#34;, &#34;.join(f&#34;:{key}&#34; for key in parameters.keys())
updates = &#34;, &#34;.join(
f&#39;&#34;{key}&#34; = :{key}&#39; for key in parameters.keys() if key != &#34;id&#34;
)
query = f&#34;&#34;&#34;
INSERT INTO steps ({columns})
VALUES ({values})
ON CONFLICT (id) DO UPDATE
SET {updates};
&#34;&#34;&#34;
await self.execute_sql(query=query, parameters=parameters)
@queue_until_user_message()
async def update_step(self, step_dict: &#34;StepDict&#34;):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: update_step, step_id={step_dict.get(&#39;id&#39;)}&#34;)
await self.create_step(step_dict)
@queue_until_user_message()
async def delete_step(self, step_id: str):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: delete_step, step_id={step_id}&#34;)
# Delete feedbacks/elements/steps
feedbacks_query = &#34;&#34;&#34;DELETE FROM feedbacks WHERE &#34;forId&#34; = :id&#34;&#34;&#34;
elements_query = &#34;&#34;&#34;DELETE FROM elements WHERE &#34;forId&#34; = :id&#34;&#34;&#34;
steps_query = &#34;&#34;&#34;DELETE FROM steps WHERE &#34;id&#34; = :id&#34;&#34;&#34;
parameters = {&#34;id&#34;: step_id}
await self.execute_sql(query=feedbacks_query, parameters=parameters)
await self.execute_sql(query=elements_query, parameters=parameters)
await self.execute_sql(query=steps_query, parameters=parameters)
###### Feedback ######
async def upsert_feedback(self, feedback: Feedback) -&gt; str:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: upsert_feedback, feedback_id={feedback.id}&#34;)
feedback.id = feedback.id or str(uuid.uuid4())
feedback_dict = asdict(feedback)
parameters = {
key: value for key, value in feedback_dict.items() if value is not None
}
columns = &#34;, &#34;.join(f&#39;&#34;{key}&#34;&#39; for key in parameters.keys())
values = &#34;, &#34;.join(f&#34;:{key}&#34; for key in parameters.keys())
updates = &#34;, &#34;.join(
f&#39;&#34;{key}&#34; = :{key}&#39; for key in parameters.keys() if key != &#34;id&#34;
)
query = f&#34;&#34;&#34;
INSERT INTO feedbacks ({columns})
VALUES ({values})
ON CONFLICT (id) DO UPDATE
SET {updates};
&#34;&#34;&#34;
await self.execute_sql(query=query, parameters=parameters)
return feedback.id
async def delete_feedback(self, feedback_id: str) -&gt; bool:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: delete_feedback, feedback_id={feedback_id}&#34;)
query = &#34;&#34;&#34;DELETE FROM feedbacks WHERE &#34;id&#34; = :feedback_id&#34;&#34;&#34;
parameters = {&#34;feedback_id&#34;: feedback_id}
await self.execute_sql(query=query, parameters=parameters)
return True
###### Elements ######
async def get_element(
self, thread_id: str, element_id: str
) -&gt; Optional[&#34;ElementDict&#34;]:
if self.show_logger:
logger.info(
f&#34;SQLAlchemy: get_element, thread_id={thread_id}, element_id={element_id}&#34;
)
query = &#34;&#34;&#34;SELECT * FROM elements WHERE &#34;threadId&#34; = :thread_id AND &#34;id&#34; = :element_id&#34;&#34;&#34;
parameters = {&#34;thread_id&#34;: thread_id, &#34;element_id&#34;: element_id}
element: Union[List[Dict[str, Any]], int, None] = await self.execute_sql(
query=query, parameters=parameters
)
if isinstance(element, list) and element:
element_dict: Dict[str, Any] = element[0]
return ElementDict(
id=element_dict[&#34;id&#34;],
threadId=element_dict.get(&#34;threadId&#34;),
type=element_dict[&#34;type&#34;],
chainlitKey=element_dict.get(&#34;chainlitKey&#34;),
url=element_dict.get(&#34;url&#34;),
objectKey=element_dict.get(&#34;objectKey&#34;),
name=element_dict[&#34;name&#34;],
display=element_dict[&#34;display&#34;],
size=element_dict.get(&#34;size&#34;),
language=element_dict.get(&#34;language&#34;),
page=element_dict.get(&#34;page&#34;),
autoPlay=element_dict.get(&#34;autoPlay&#34;),
playerConfig=element_dict.get(&#34;playerConfig&#34;),
forId=element_dict.get(&#34;forId&#34;),
mime=element_dict.get(&#34;mime&#34;),
)
else:
return None
@queue_until_user_message()
async def create_element(self, element: &#34;Element&#34;):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: create_element, element_id = {element.id}&#34;)
if not self.storage_provider:
logger.warn(
&#34;SQLAlchemy: create_element error. No blob_storage_client is configured!&#34;
)
return
if not element.for_id:
return
content: Optional[Union[bytes, str]] = None
if element.path:
async with aiofiles.open(element.path, &#34;rb&#34;) as f:
content = await f.read()
elif element.url:
async with aiohttp.ClientSession() as session:
async with session.get(element.url) as response:
if response.status == 200:
content = await response.read()
else:
content = None
elif element.content:
content = element.content
else:
raise ValueError(&#34;Element url, path or content must be provided&#34;)
if content is None:
raise ValueError(&#34;Content is None, cannot upload file&#34;)
user_id: str = await self._get_user_id_by_thread(element.thread_id) or &#34;unknown&#34;
file_object_key = f&#34;{user_id}/{element.id}&#34; + (
f&#34;/{element.name}&#34; if element.name else &#34;&#34;
)
if not element.mime:
element.mime = &#34;application/octet-stream&#34;
uploaded_file = await self.storage_provider.upload_file(
object_key=file_object_key, data=content, mime=element.mime, overwrite=True
)
if not uploaded_file:
raise ValueError(
&#34;SQLAlchemy Error: create_element, Failed to persist data in storage_provider&#34;
)
element_dict: ElementDict = element.to_dict()
element_dict[&#34;url&#34;] = uploaded_file.get(&#34;url&#34;)
element_dict[&#34;objectKey&#34;] = uploaded_file.get(&#34;object_key&#34;)
element_dict_cleaned = {k: v for k, v in element_dict.items() if v is not None}
columns = &#34;, &#34;.join(f&#39;&#34;{column}&#34;&#39; for column in element_dict_cleaned.keys())
placeholders = &#34;, &#34;.join(f&#34;:{column}&#34; for column in element_dict_cleaned.keys())
query = f&#34;INSERT INTO elements ({columns}) VALUES ({placeholders})&#34;
await self.execute_sql(query=query, parameters=element_dict_cleaned)
@queue_until_user_message()
async def delete_element(self, element_id: str, thread_id: Optional[str] = None):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: delete_element, element_id={element_id}&#34;)
query = &#34;&#34;&#34;DELETE FROM elements WHERE &#34;id&#34; = :id&#34;&#34;&#34;
parameters = {&#34;id&#34;: element_id}
await self.execute_sql(query=query, parameters=parameters)
async def get_all_user_threads(
self, user_id: Optional[str] = None, thread_id: Optional[str] = None
) -&gt; Optional[List[ThreadDict]]:
&#34;&#34;&#34;Fetch all user threads up to self.user_thread_limit, or one thread by id if thread_id is provided.&#34;&#34;&#34;
if self.show_logger:
logger.info(&#34;SQLAlchemy: get_all_user_threads&#34;)
user_threads_query = &#34;&#34;&#34;
SELECT
&#34;id&#34; AS thread_id,
&#34;createdAt&#34; AS thread_createdat,
&#34;name&#34; AS thread_name,
&#34;userId&#34; AS user_id,
&#34;userIdentifier&#34; AS user_identifier,
&#34;tags&#34; AS thread_tags,
&#34;metadata&#34; AS thread_metadata
FROM threads
WHERE &#34;userId&#34; = :user_id OR &#34;id&#34; = :thread_id
ORDER BY &#34;createdAt&#34; DESC
LIMIT :limit
&#34;&#34;&#34;
user_threads = await self.execute_sql(
query=user_threads_query,
parameters={
&#34;user_id&#34;: user_id,
&#34;limit&#34;: self.user_thread_limit,
&#34;thread_id&#34;: thread_id,
},
)
if not isinstance(user_threads, list):
return None
if not user_threads:
return []
else:
thread_ids = (
&#34;(&#39;&#34;
+ &#34;&#39;,&#39;&#34;.join(map(str, [thread[&#34;thread_id&#34;] for thread in user_threads]))
+ &#34;&#39;)&#34;
)
steps_feedbacks_query = f&#34;&#34;&#34;
SELECT
s.&#34;id&#34; AS step_id,
s.&#34;name&#34; AS step_name,
s.&#34;type&#34; AS step_type,
s.&#34;threadId&#34; AS step_threadid,
s.&#34;parentId&#34; AS step_parentid,
s.&#34;streaming&#34; AS step_streaming,
s.&#34;waitForAnswer&#34; AS step_waitforanswer,
s.&#34;isError&#34; AS step_iserror,
s.&#34;metadata&#34; AS step_metadata,
s.&#34;tags&#34; AS step_tags,
s.&#34;input&#34; AS step_input,
s.&#34;output&#34; AS step_output,
s.&#34;createdAt&#34; AS step_createdat,
s.&#34;start&#34; AS step_start,
s.&#34;end&#34; AS step_end,
s.&#34;generation&#34; AS step_generation,
s.&#34;showInput&#34; AS step_showinput,
s.&#34;language&#34; AS step_language,
s.&#34;indent&#34; AS step_indent,
f.&#34;value&#34; AS feedback_value,
f.&#34;comment&#34; AS feedback_comment,
f.&#34;id&#34; AS feedback_id
FROM steps s LEFT JOIN feedbacks f ON s.&#34;id&#34; = f.&#34;forId&#34;
WHERE s.&#34;threadId&#34; IN {thread_ids}
ORDER BY s.&#34;createdAt&#34; ASC
&#34;&#34;&#34;
steps_feedbacks = await self.execute_sql(
query=steps_feedbacks_query, parameters={}
)
elements_query = f&#34;&#34;&#34;
SELECT
e.&#34;id&#34; AS element_id,
e.&#34;threadId&#34; as element_threadid,
e.&#34;type&#34; AS element_type,
e.&#34;chainlitKey&#34; AS element_chainlitkey,
e.&#34;url&#34; AS element_url,
e.&#34;objectKey&#34; as element_objectkey,
e.&#34;name&#34; AS element_name,
e.&#34;display&#34; AS element_display,
e.&#34;size&#34; AS element_size,
e.&#34;language&#34; AS element_language,
e.&#34;page&#34; AS element_page,
e.&#34;forId&#34; AS element_forid,
e.&#34;mime&#34; AS element_mime
FROM elements e
WHERE e.&#34;threadId&#34; IN {thread_ids}
&#34;&#34;&#34;
elements = await self.execute_sql(query=elements_query, parameters={})
thread_dicts = {}
for thread in user_threads:
thread_id = thread[&#34;thread_id&#34;]
if thread_id is not None:
# Ensure metadata is a dictionary
metadata = thread[&#34;thread_metadata&#34;]
if isinstance(metadata, str):
try:
metadata = json.loads(metadata)
except json.JSONDecodeError:
metadata = {}
elif metadata is None:
metadata = {}
thread_dicts[thread_id] = ThreadDict(
id=thread_id,
createdAt=thread[&#34;thread_createdat&#34;],
name=thread[&#34;thread_name&#34;],
userId=thread[&#34;user_id&#34;],
userIdentifier=thread[&#34;user_identifier&#34;],
tags=thread[&#34;thread_tags&#34;],
metadata=metadata,
steps=[],
elements=[],
)
# Process steps_feedbacks to populate the steps in the corresponding ThreadDict
if isinstance(steps_feedbacks, list):
for step_feedback in steps_feedbacks:
thread_id = step_feedback[&#34;step_threadid&#34;]
if thread_id is not None:
feedback = None
if step_feedback[&#34;feedback_value&#34;] is not None:
feedback = FeedbackDict(
forId=step_feedback[&#34;step_id&#34;],
id=step_feedback.get(&#34;feedback_id&#34;),
value=step_feedback[&#34;feedback_value&#34;],
comment=step_feedback.get(&#34;feedback_comment&#34;),
)
step_dict = StepDict(
id=step_feedback[&#34;step_id&#34;],
name=step_feedback[&#34;step_name&#34;],
type=step_feedback[&#34;step_type&#34;],
threadId=thread_id,
parentId=step_feedback.get(&#34;step_parentid&#34;),
streaming=step_feedback.get(&#34;step_streaming&#34;, False),
waitForAnswer=step_feedback.get(&#34;step_waitforanswer&#34;),
isError=step_feedback.get(&#34;step_iserror&#34;),
metadata=(
step_feedback[&#34;step_metadata&#34;]
if step_feedback.get(&#34;step_metadata&#34;) is not None
else {}
),
tags=step_feedback.get(&#34;step_tags&#34;),
input=(
step_feedback.get(&#34;step_input&#34;, &#34;&#34;)
if step_feedback.get(&#34;step_showinput&#34;)
not in [None, &#34;false&#34;]
else &#34;&#34;
),
output=step_feedback.get(&#34;step_output&#34;, &#34;&#34;),
createdAt=step_feedback.get(&#34;step_createdat&#34;),
start=step_feedback.get(&#34;step_start&#34;),
end=step_feedback.get(&#34;step_end&#34;),
generation=step_feedback.get(&#34;step_generation&#34;),
showInput=step_feedback.get(&#34;step_showinput&#34;),
language=step_feedback.get(&#34;step_language&#34;),
indent=step_feedback.get(&#34;step_indent&#34;),
feedback=feedback,
)
# Append the step to the steps list of the corresponding ThreadDict
thread_dicts[thread_id][&#34;steps&#34;].append(step_dict)
if isinstance(elements, list):
for element in elements:
thread_id = element[&#34;element_threadid&#34;]
if thread_id is not None:
element_dict = ElementDict(
id=element[&#34;element_id&#34;],
threadId=thread_id,
type=element[&#34;element_type&#34;],
chainlitKey=element.get(&#34;element_chainlitkey&#34;),
url=element.get(&#34;element_url&#34;),
objectKey=element.get(&#34;element_objectkey&#34;),
name=element[&#34;element_name&#34;],
display=element[&#34;element_display&#34;],
size=element.get(&#34;element_size&#34;),
language=element.get(&#34;element_language&#34;),
autoPlay=element.get(&#34;element_autoPlay&#34;),
playerConfig=element.get(&#34;element_playerconfig&#34;),
page=element.get(&#34;element_page&#34;),
forId=element.get(&#34;element_forid&#34;),
mime=element.get(&#34;element_mime&#34;),
)
thread_dicts[thread_id][&#34;elements&#34;].append(element_dict) # type: ignore
return list(thread_dicts.values())</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>chainlit.data.base.BaseDataLayer</li>
<li>abc.ABC</li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.build_debug_url"><code class="name flex">
<span>async def <span class="ident">build_debug_url</span></span>(<span>self) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.clean_result"><code class="name flex">
<span>def <span class="ident">clean_result</span></span>(<span>self, obj)</span>
</code></dt>
<dd>
<div class="desc"><p>Recursively change UUID -&gt; str and serialize dictionaries</p></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_element"><code class="name flex">
<span>async def <span class="ident">create_element</span></span>(<span>self, element: Element)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_step"><code class="name flex">
<span>async def <span class="ident">create_step</span></span>(<span>self, step_dict: StepDict)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_user"><code class="name flex">
<span>async def <span class="ident">create_user</span></span>(<span>self, user: chainlit.user.User) ‑> Optional[chainlit.user.PersistedUser]</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_element"><code class="name flex">
<span>async def <span class="ident">delete_element</span></span>(<span>self, element_id: str, thread_id: Optional[str] = None)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_feedback"><code class="name flex">
<span>async def <span class="ident">delete_feedback</span></span>(<span>self, feedback_id: str) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_step"><code class="name flex">
<span>async def <span class="ident">delete_step</span></span>(<span>self, step_id: str)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_thread"><code class="name flex">
<span>async def <span class="ident">delete_thread</span></span>(<span>self, thread_id: str)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.execute_sql"><code class="name flex">
<span>async def <span class="ident">execute_sql</span></span>(<span>self, query: str, parameters: dict) ‑> Union[List[Dict[str, Any]], int, ForwardRef(None)]</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_all_user_threads"><code class="name flex">
<span>async def <span class="ident">get_all_user_threads</span></span>(<span>self, user_id: Optional[str] = None, thread_id: Optional[str] = None) ‑> Optional[List[chainlit.types.ThreadDict]]</span>
</code></dt>
<dd>
<div class="desc"><p>Fetch all user threads up to self.user_thread_limit, or one thread by id if thread_id is provided.</p></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_current_timestamp"><code class="name flex">
<span>async def <span class="ident">get_current_timestamp</span></span>(<span>self) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_element"><code class="name flex">
<span>async def <span class="ident">get_element</span></span>(<span>self, thread_id: str, element_id: str) ‑> Optional[chainlit.element.ElementDict]</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread"><code class="name flex">
<span>async def <span class="ident">get_thread</span></span>(<span>self, thread_id: str) ‑> Optional[chainlit.types.ThreadDict]</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread_author"><code class="name flex">
<span>async def <span class="ident">get_thread_author</span></span>(<span>self, thread_id: str) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_user"><code class="name flex">
<span>async def <span class="ident">get_user</span></span>(<span>self, identifier: str) ‑> Optional[chainlit.user.PersistedUser]</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.list_threads"><code class="name flex">
<span>async def <span class="ident">list_threads</span></span>(<span>self, pagination: chainlit.types.Pagination, filters: chainlit.types.ThreadFilter) ‑> chainlit.types.PaginatedResponse</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_step"><code class="name flex">
<span>async def <span class="ident">update_step</span></span>(<span>self, step_dict: StepDict)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_thread"><code class="name flex">
<span>async def <span class="ident">update_thread</span></span>(<span>self, thread_id: str, name: Optional[str] = None, user_id: Optional[str] = None, metadata: Optional[Dict] = None, tags: Optional[List[str]] = None)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.upsert_feedback"><code class="name flex">
<span>async def <span class="ident">upsert_feedback</span></span>(<span>self, feedback: chainlit.types.Feedback) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.ui" href="index.html">praisonai.ui</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer">SQLAlchemyDataLayer</a></code></h4>
<ul class="">
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.build_debug_url" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.build_debug_url">build_debug_url</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.clean_result" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.clean_result">clean_result</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_element" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_element">create_element</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_step" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_step">create_step</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_user" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_user">create_user</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_element" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_element">delete_element</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_feedback" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_feedback">delete_feedback</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_step" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_step">delete_step</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_thread" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_thread">delete_thread</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.execute_sql" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.execute_sql">execute_sql</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_all_user_threads" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_all_user_threads">get_all_user_threads</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_current_timestamp" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_current_timestamp">get_current_timestamp</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_element" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_element">get_element</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread">get_thread</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread_author" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread_author">get_thread_author</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_user" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_user">get_user</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.list_threads" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.list_threads">list_threads</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_step" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_step">update_step</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_thread" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_thread">update_thread</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.upsert_feedback" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.upsert_feedback">upsert_feedback</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-55
View File
@@ -1,55 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.version API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.version</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-79
View File
@@ -1,79 +0,0 @@
---
title: "Agent Module"
description: "Documentation for the praisonaiagents.agent.agent module"
icon: "user"
---
# Module praisonaiagents.agent.agent
## Classes
### Agent
The main class representing an AI agent with specific role, goal, and capabilities.
#### Parameters
- `name: str` - Name of the agent
- `role: str` - Role of the agent
- `goal: str` - Goal the agent aims to achieve
- `backstory: str` - Background story of the agent
- `llm: str | Any | None = 'gpt-4o'` - Language model to use
- `tools: List[Any] | None = None` - List of tools available to the agent
- `function_calling_llm: Any | None = None` - LLM for function calling
- `max_iter: int = 20` - Maximum iterations
- `max_rpm: int | None = None` - Maximum requests per minute
- `max_execution_time: int | None = None` - Maximum execution time
- `memory: bool = True` - Enable memory
- `verbose: bool = True` - Enable verbose output
- `allow_delegation: bool = False` - Allow task delegation
- `step_callback: Any | None = None` - Callback for each step
- `cache: bool = True` - Enable caching
- `system_template: str | None = None` - System prompt template
- `prompt_template: str | None = None` - Prompt template
- `response_template: str | None = None` - Response template
- `allow_code_execution: bool | None = False` - Allow code execution
- `max_retry_limit: int = 2` - Maximum retry attempts
- `respect_context_window: bool = True` - Respect context window size
- `code_execution_mode: Literal['safe', 'unsafe'] = 'safe'` - Code execution mode
- `embedder_config: Dict[str, Any] | None = None` - Embedder configuration
- `knowledge_sources: List[Any] | None = None` - Knowledge sources
- `use_system_prompt: bool | None = True` - Use system prompt
- `markdown: bool = True` - Enable markdown
- `self_reflect: bool = True` - Enable self reflection
- `max_reflect: int = 3` - Maximum reflections
- `min_reflect: int = 1` - Minimum reflections
- `reflect_llm: str | None = None` - LLM for reflection
#### Methods
- `chat(self, prompt, temperature=0.2, tools=None, output_json=None)` - Chat with the agent
- `achat(self, prompt, temperature=0.2, tools=None, output_json=None)` - Async version of chat method
- `clean_json_output(self, output: str) → str` - Clean and extract JSON from response text
- `clear_history(self)` - Clear chat history
- `execute_tool(self, function_name, arguments)` - Execute a tool dynamically based on the function name and arguments
- `_achat_completion(self, response, tools)` - Async version of _chat_completion method
#### Async Support
The Agent class provides async support through the following methods:
- `achat`: Async version of the chat method for non-blocking communication
- `_achat_completion`: Internal async method for handling chat completions
Example usage:
```python
async def main():
agent = Agent(
name="AsyncAgent",
role="Async Specialist",
goal="Handle async operations",
backstory="Expert in async processing"
)
# Use async chat
result = await agent.achat(
prompt="Your prompt here",
tools=your_tools,
output_json=your_schema
)
print(result)
asyncio.run(main())
```
-113
View File
@@ -1,113 +0,0 @@
---
title: "Agents Module"
description: "Documentation for the praisonaiagents.agents.agents module"
icon: "users"
---
# Module praisonaiagents.agents.agents
## Functions
### encode_file_to_base64(file_path: str) → str
Base64-encode a file.
### process_video(video_path: str, seconds_per_frame=2)
Split video into frames (base64-encoded).
## Classes
### LoopItems
A Pydantic model for handling loop items.
#### Class Variables
- `items: List[Any]` - List of items to loop through
- `model_config` - Model configuration
### PraisonAIAgents
The main class for managing agents and tasks execution.
#### Parameters
- `agents: List[Agent]` - List of agents
- `tasks: List[Task]` - List of tasks
- `verbose: int = 0` - Verbosity level
- `completion_checker: Optional[Callable] = None` - Custom completion checker
- `max_retries: int = 5` - Maximum retry attempts
- `process: str = "sequential"` - Process type (sequential, workflow, hierarchical)
- `manager_llm: Optional[str] = None` - Language model for manager agent
#### Methods
- `add_task(self, task)` - Add a task to the crew
- `clean_json_output(self, output: str) → str` - Clean JSON output
- `clear_state(self) → None` - Clear all state values
- `default_completion_checker(self, task, agent_output)` - Default completion checker
- `execute_task(self, task_id)` - Execute a specific task
- `get_agent_details(self, agent_name)` - Get agent details
- `get_all_tasks_status(self)` - Get status of all tasks
- `get_state(self, key: str, default: Any = None) → Any` - Get a state value
- `get_task_details(self, task_id)` - Get task details
- `get_task_result(self, task_id)` - Get task result
- `get_task_status(self, task_id)` - Get task status
- `run_all_tasks(self)` - Execute tasks based on execution mode
- `run_task(self, task_id)` - Run a specific task
- `save_output_to_file(self, task, task_output)` - Save task output to file
- `set_state(self, key: str, value: Any) → None` - Set a state value
- `start(self)` - Start the crew execution
- `update_state(self, updates: Dict) → None` - Update multiple state values
#### Async Methods
- `astart(self)` - Async version of start method
- `aexecute_task(self, task_id)` - Async version of execute_task
- `arun_task(self, task_id)` - Async version of run_task
- `arun_all_tasks(self)` - Async version of run_all_tasks
#### Async Support
The PraisonAIAgents class provides comprehensive async support through the following methods:
```python
class PraisonAIAgents:
async def astart(self):
"""Async version of start method"""
await self.arun_all_tasks()
return {
"task_status": self.get_all_tasks_status(),
"task_results": self.get_task_results()
}
async def aexecute_task(self, task_id):
"""Async version of execute_task method"""
# Async task execution implementation
async def arun_task(self, task_id):
"""Async version of run_task method"""
# Async task running with retries
async def arun_all_tasks(self):
"""Async version of run_all_tasks method"""
# Async execution of all tasks
```
Example usage:
```python
async def main():
# Initialize agents and tasks
agents = PraisonAIAgents(
agents=[async_agent1, async_agent2],
tasks=[async_task1, async_task2],
process="workflow"
)
# Start async execution
result = await agents.astart()
print(result)
# Run the async workflow
asyncio.run(main())
```
#### Async Features
- Full async/await support
- Parallel task execution
- Non-blocking operations
- Efficient resource utilization
- Mixed sync/async task handling
- Async process management
@@ -1,187 +0,0 @@
---
title: "AutoAgents Module"
description: "Documentation for the praisonaiagents.agents.autoagents module"
icon: "robot"
---
# Module praisonaiagents.agents.autoagents
The AutoAgents module provides automatic creation and management of AI agents and tasks based on high-level instructions.
## Classes
### AutoAgents
The main class for automatically creating and managing AI agents and tasks.
#### Parameters
- `instructions: str` - High-level task description for the agents
- `tools: Optional[List[Any]] = None` - List of tools available to the agents
- `verbose: bool = False` - Enable detailed logging
- `process: str = "sequential"` - Process type (sequential or hierarchical)
- `manager_llm: Optional[str] = None` - Language model for manager agent
- `max_retries: int = 5` - Maximum retry attempts
- `completion_checker: Optional[Any] = None` - Custom completion checker
- `allow_code_execution: bool = False` - Allow code execution
- `memory: bool = True` - Enable agent memory
- `markdown: bool = True` - Enable markdown formatting
- `self_reflect: bool = False` - Enable agent self-reflection
- `max_reflect: int = 3` - Maximum reflection iterations
- `min_reflect: int = 1` - Minimum reflection iterations
- `llm: Optional[str] = None` - Language model for agents
- `function_calling_llm: Optional[str] = None` - Language model for tool calling
- `respect_context_window: bool = True` - Respect model context window
- `code_execution_mode: str = "safe"` - Code execution mode (safe/unsafe)
- `embedder_config: Optional[Dict[str, Any]] = None` - Embedder configuration
- `knowledge_sources: Optional[List[Any]] = None` - Knowledge sources
- `use_system_prompt: bool = True` - Use system prompts
- `cache: bool = True` - Enable caching
- `allow_delegation: bool = False` - Allow task delegation
- `step_callback: Optional[Any] = None` - Callback for each step
- `system_template: Optional[str] = None` - Custom system template
- `prompt_template: Optional[str] = None` - Custom prompt template
- `response_template: Optional[str] = None` - Custom response template
- `max_rpm: Optional[int] = None` - Maximum requests per minute
- `max_execution_time: Optional[int] = None` - Maximum execution time
- `max_iter: int = 20` - Maximum iterations
- `reflect_llm: Optional[str] = None` - Language model for reflection
- `max_agents: int = 3` - Maximum number of agents to create
#### Methods
##### start()
Start the agents synchronously.
```python
def start(self):
"""
Creates tasks based on the instructions, then starts execution.
Returns the task status and results dictionary.
"""
return super().start()
```
##### astart()
Start the agents asynchronously.
```python
async def astart(self):
"""
Async version of start() method.
Creates tasks based on the instructions, then starts execution.
Returns the task status and results dictionary.
"""
return await super().astart()
```
#### Internal Methods
##### _generate_config()
Generate the configuration for agents and tasks.
```python
def _generate_config(self) -> AutoAgentsConfig:
"""
Generate the configuration for agents and tasks based on instructions.
Returns AutoAgentsConfig object containing agent and task configurations.
"""
```
##### _create_agents_and_tasks()
Create agents and tasks from configuration.
```python
def _create_agents_and_tasks(self, config: AutoAgentsConfig) -> tuple[List[Agent], List[Task]]:
"""
Create agents and tasks based on the generated configuration.
Returns tuple of (agents, tasks).
"""
```
##### _assign_tools_to_agent()
Assign appropriate tools to an agent.
```python
def _assign_tools_to_agent(self, agent_config: AgentConfig) -> List[Any]:
"""
Assign tools to an agent based on its role and tasks.
Returns list of assigned tools.
"""
```
## Pydantic Models
### TaskConfig
Configuration for a task.
#### Attributes
- `name: str` - Task name
- `description: str` - Task description
- `expected_output: str` - Expected output description
- `tools: List[str]` - Required tools for the task
### AgentConfig
Configuration for an agent.
#### Attributes
- `name: str` - Agent name
- `role: str` - Agent role
- `goal: str` - Agent goal
- `backstory: str` - Agent backstory
- `tools: List[str]` - Required tools
- `tasks: List[TaskConfig]` - Tasks assigned to the agent
### AutoAgentsConfig
Overall configuration for AutoAgents.
#### Attributes
- `main_instruction: str` - Main instruction for the agents
- `process_type: str` - Process type (sequential/hierarchical)
- `agents: List[AgentConfig]` - List of agent configurations
## Example Usage
### Basic Usage
```python
from praisonaiagents import AutoAgents
from praisonaiagents.tools import SerperDevTool
agents = AutoAgents(
instructions="Research recent AI developments",
tools=[SerperDevTool()],
verbose=True
)
result = agents.start()
```
### Async Usage
```python
async def main():
agents = AutoAgents(
instructions="Research recent AI developments",
tools=[SerperDevTool()],
process="hierarchical"
)
result = await agents.astart()
import asyncio
asyncio.run(main())
```
### Advanced Configuration
```python
agents = AutoAgents(
instructions="Complex research task",
tools=[SerperDevTool()],
max_agents=5,
process="hierarchical",
manager_llm="gpt-4o",
memory=True,
allow_delegation=True,
max_execution_time=600,
self_reflect=True
)
```
<Note>
For optimal results, provide clear instructions and appropriate tools for your use case.
</Note>
-52
View File
@@ -1,52 +0,0 @@
---
title: "API Reference"
description: "Praison AI Agents - SDK Documentation"
icon: "code"
---
<CardGroup cols={2}>
<Card title="Agent" icon="user" href="/api/praisonaiagents/agent/agent">
Documentation for individual AI agents and their capabilities
</Card>
<Card title="Agents" icon="users" href="/api/praisonaiagents/agents/agents">
Documentation for managing multiple agents and their interactions
</Card>
<Card title="Task" icon="list-check" href="/api/praisonaiagents/task/task">
Documentation for defining and managing tasks
</Card>
<Card title="Process" icon="diagram-project" href="/api/praisonaiagents/process/process">
Documentation for handling task execution flows
</Card>
</CardGroup>
# Module praisonaiagents
## Sub-modules
* praisonaiagents.agent - Agent module for defining individual AI agents
* praisonaiagents.agents - Agents module for managing multiple agents
* praisonaiagents.task - Task module for defining and managing tasks
* praisonaiagents.process - Process module for handling task execution flows
* praisonaiagents.main - Main module containing utility functions
## Functions
### clean_triple_backticks(text: str) → str
Clean triple backticks from text output.
### display_error(message: str, console=None)
Display error messages in the console.
### display_generating(content: str = '', start_time: float | None = None)
Display generation status with optional timing information.
### display_instruction(message: str, console=None)
Display instruction messages in the console.
### display_interaction(message, response, markdown=True, generation_time=None, console=None)
Display interaction between user and agent.
### display_self_reflection(message: str, console=None)
Display agent self-reflection messages.
### display_tool_call(message: str, console=None)
Display tool call messages.
@@ -1,98 +0,0 @@
---
title: "Process Module"
description: "Documentation for the praisonaiagents.process.process module"
icon: "diagram-project"
---
# Module praisonaiagents.process.process
## Classes
### Process
The main class for handling task execution processes in different modes (sequential, hierarchical, workflow).
#### Parameters
- `tasks: Dict[str, Task]` - Dictionary of tasks to be executed
- `agents: List[Agent]` - List of available agents
- `manager_llm: Optional[str] = None` - Language model for manager agent in hierarchical process
- `verbose: bool = False` - Enable verbose logging
#### Methods
- `workflow(self)` - Execute tasks in a workflow pattern with support for loops and conditions
- `sequential(self)` - Execute tasks in sequential order
- `hierarchical(self)` - Execute tasks in hierarchical order with a manager agent
#### Async Methods
- `aworkflow(self) -> AsyncGenerator[str, None]` - Async version of workflow process
- `asequential(self) -> AsyncGenerator[str, None]` - Async version of sequential process
- `ahierarchical(self) -> AsyncGenerator[str, None]` - Async version of hierarchical process
#### Async Process Support
Each process type has an async counterpart that supports non-blocking execution:
```python
class Process:
async def aworkflow(self):
"""Async workflow process execution"""
# Async workflow implementation
async def asequential(self):
"""Async sequential process execution"""
# Async sequential implementation
async def ahierarchical(self):
"""Async hierarchical process execution"""
# Async hierarchical implementation
```
Example usage:
```python
# Create process instance
process = Process(tasks=tasks, agents=agents)
# Use async workflow
async for task_id in process.aworkflow():
# Handle task execution
if tasks[task_id].async_execution:
await handle_async_task(task_id)
else:
handle_sync_task(task_id)
```
#### Async Process Features
- Non-blocking task execution
- Parallel task processing
- Mixed sync/async task support
- Efficient resource utilization
- Async manager coordination (hierarchical)
- Dynamic task scheduling (workflow)
### LoopItems
A Pydantic model for handling loop data in workflow process.
#### Parameters
- `items: List[Any]` - List of items to be processed in a loop
## Process Types
### Sequential Process
- Tasks are executed one after another in a linear fashion
- Each task is completed before moving to the next one
- Simplest form of task execution
### Hierarchical Process
- Uses a manager agent to coordinate task execution
- Manager decides task order and agent assignments
- Provides more complex task orchestration
- Requires manager_llm parameter
- Supports dynamic agent assignment
### Workflow Process
- Supports complex task relationships
- Features:
- Task dependencies
- Conditional execution
- Loops
- Context sharing between tasks
- Maintains task state and relationships
- Handles data flow between tasks
-78
View File
@@ -1,78 +0,0 @@
---
title: "Task Module"
description: "Documentation for the praisonaiagents.task.task module"
icon: "list-check"
---
# Module praisonaiagents.task.task
## Classes
### Task
Represents a task to be executed by an agent.
#### Parameters
- `description: str` - Task description
- `expected_output: str` - Expected output description
- `agent: Agent | None = None` - Agent assigned to the task
- `name: str | None = None` - Task name
- `tools: List[Any] | None = None` - Tools available for the task
- `context: List[Task] | None = None` - Context from other tasks
- `async_execution: bool | None = False` - Enable async execution
- `config: Dict[str, Any] | None = None` - Task configuration
- `output_file: str | None = None` - Output file path
- `output_json: Type[BaseModel] | None = None` - JSON output schema
- `output_pydantic: Type[BaseModel] | None = None` - Pydantic output schema
- `callback: Any | None = None` - Task callback
- `status: str = 'not started'` - Task status
- `result: TaskOutput | None = None` - Task result
- `create_directory: bool | None = False` - Create output directory
- `id: int | None = None` - Task ID
- `images: List[str] | None = None` - Task images
- `next_tasks: List[str] | None = None` - Next tasks
- `task_type: str = 'task'` - Task type
- `condition: Dict[str, List[str]] | None = None` - Task conditions
- `is_start: bool = False` - Is start task
- `loop_state: Dict[str, str | int] | None = None` - Loop state
#### Async Support
The Task class supports asynchronous execution through the following features:
- `async_execution`: Boolean flag to enable async execution
- `callback`: Supports both sync and async callback functions
- `execute_callback`: Internal async method for handling callbacks
Example usage:
```python
from typing import Coroutine
from praisonaiagents import Task, TaskOutput
# Define an async callback
async def async_callback(output: TaskOutput):
await some_async_operation()
print(f"Processed: {output.raw}")
# Create task with async execution
task = Task(
description="Async task example",
expected_output="Async result",
async_execution=True, # Enable async execution
callback=async_callback # Async callback
)
```
#### Callback Types
The Task class supports both synchronous and asynchronous callbacks:
```python
# Type definition
callback: Optional[Union[
Callable[[TaskOutput], Any], # Sync callback
Callable[[TaskOutput], Coroutine[Any, Any, Any]] # Async callback
]]
```
#### Async Task States
- `not started`: Initial state
- `in progress`: Task is being executed
- `completed`: Task finished successfully
- `failed`: Task execution failed
-126
View File
@@ -1,126 +0,0 @@
---
title: "PraisonAI Call"
description: "Guide to PraisonAI's voice-based interaction feature enabling AI customer service through phone calls, including setup and tool integration"
icon: "phone"
---
<iframe width="560" height="315" src="https://www.youtube.com/embed/m1cwrUG2iAk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## AI Customer Service
PraisonAI Call is a feature that enables voice-based interaction with AI models through phone calls. This functionality allows users to have natural conversations with AI agents over traditional phone lines.
## Installation
### Step 1
```bash
pip install "praisonai[call]"
export OPENAI_API_KEY="enter your openai api key here"
export NGROK_AUTH_TOKEN="enter your ngrok auth token here"
praisonai call --public
```
### Step 2
Buy a number at [PraisonAI Dashboard](https://dashboard.praison.ai/)
### Step 3
Enter the Public URL in the PraisonAI Dashboard phone number field
## Features
- Make and receive phone calls with AI agents
- Natural language processing for voice interactions
- Support for multiple phone carriers and providers
- Call recording and transcription capabilities
- Integration with other PraisonAI features
## Adding Tools
1. Create a file called `tools.py`
2. Add the following code:
```python
import yfinance as yf
# Get Stock Price definition
get_stock_price_def = {
"name": "get_stock_price",
"description": "Get the current stock price for a given ticker symbol",
"parameters": {
"type": "object",
"properties": {
"ticker_symbol": {
"type": "string",
"description": "The ticker symbol of the stock (e.g., AAPL, GOOGL)"
}
},
"required": ["ticker_symbol"]
}
}
# Get Stock Price function / Tool
async def get_stock_price_handler(ticker_symbol):
try:
stock = yf.Ticker(ticker_symbol)
hist = stock.history(period="1d")
if hist.empty:
return {"error": f"No data found for ticker {ticker_symbol}"}
current_price = hist['Close'].iloc[-1] # Using -1 is safer than 0
return {"price": str(current_price)}
except Exception as e:
return {"error": str(e)}
get_stock_price = (get_stock_price_def, get_stock_price_handler)
tools = [
get_stock_price
]
```
3. ```bash
pip install yfinance
```
4. ```bash
export OPENAI_API_KEY="enter your openai api key here"
export NGROK_AUTH_TOKEN="enter your ngrok auth token here"
praisonai call --public
```
## Manage Google Calendar Events
See [Google Calendar Tools](tools/googlecalendar.md)
## Deploy
### Docker Deployment
```dockerfile
# Use an official Python runtime as a parent image
FROM python:3.11-slim
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Install PraisonAI with the 'call' extra and ensure it's the latest version
RUN pip install --no-cache-dir --upgrade "praisonai[call]"
# Expose the port the app runs on
EXPOSE 8090
# Run the application
CMD ["praisonai", "call"]
```
-432
View File
@@ -1,432 +0,0 @@
---
title: "Agents"
description: "Understanding Agents in PraisonAI"
icon: "user"
---
# Understanding Agents
Agents are the core building blocks of PraisonAI. Each agent is an autonomous AI entity with specific roles, goals, and capabilities.
```mermaid
graph LR
%% Define the main flow
Start([▶ Start]) --> Agent1
Agent1 --> Process[⚙ Process]
Process --> Agent2
Agent2 --> Output([✓ Output])
Process -.-> Agent1
%% Define subgraphs for agents and their tasks
subgraph Agent1[ ]
Task1[📋 Task]
AgentIcon1[🤖 AI Agent]
Tools1[🔧 Tools]
Task1 --- AgentIcon1
AgentIcon1 --- Tools1
end
subgraph Agent2[ ]
Task2[📋 Task]
AgentIcon2[🤖 AI Agent]
Tools2[🔧 Tools]
Task2 --- AgentIcon2
AgentIcon2 --- Tools2
end
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Start,Output,Task1,Task2 input
class Process,AgentIcon1,AgentIcon2 process
class Tools1,Tools2 tools
class Agent1,Agent2 transparent
```
## Key Components
<CardGroup cols={2}>
<Card title="Role & Goal" icon="target">
Defines the agent's purpose and objectives through role definition and specific goals
</Card>
<Card title="Capabilities" icon="toolbox">
Tools and functions available to the agent for task execution
</Card>
<Card title="Memory" icon="brain">
Context retention and learning capabilities across interactions
</Card>
<Card title="Language Model" icon="microchip">
The underlying AI model powering the agent's intelligence
</Card>
</CardGroup>
## Component Details
### Role and Goal
<Tip>
Clear role and goal definitions are crucial for optimal agent performance.
</Tip>
| Component | Description | Example |
|:----------|:------------|:--------|
| **Role** | Agent's function and expertise | Research Analyst, Code Developer |
| **Goal** | Specific objectives to achieve | Analyze market trends, Generate reports |
| **Backstory** | Contextual background | Expert with 10 years of experience |
### Capabilities
<CodeGroup>
```python Basic
agent = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
```
</CodeGroup>
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False
)
result = agents.start()
```
```python Multiple Agents
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
python app.py
```
You should see:
- Agent initialization
- Agents progress
- Final results
- Generated report
</Step>
</Steps>
## Agent Types
<CardGroup cols={3}>
<Card title="Basic Agent" icon="user" iconType="solid">
<AccordionGroup>
<Accordion title="Overview">
Perfect for straightforward tasks and direct interactions
</Accordion>
<Accordion title="Features">
- Single-purpose focus
- Direct user interaction
- Limited tool set
- Ideal for simple tasks
</Accordion>
</AccordionGroup>
</Card>
<Card title="Specialized Agent" icon="user-gear" iconType="solid">
<AccordionGroup>
<Accordion title="Overview">
Experts in specific domains with advanced capabilities
</Accordion>
<Accordion title="Features">
- Domain expertise
- Advanced capabilities
- Custom tools
- Deep knowledge base
</Accordion>
</AccordionGroup>
</Card>
<Card title="Collaborative Agent" icon="users" iconType="solid">
<AccordionGroup>
<Accordion title="Overview">
Designed for team-based operations and complex workflows
</Accordion>
<Accordion title="Features">
- Team interaction
- Task delegation
- Shared context
- Coordinated actions
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
## Best Practices
<Note>
Always implement proper error handling and resource management in your agent configurations.
</Note>
<CardGroup cols={2}>
<Card title="Agent Design" icon="compass-drafting" iconType="solid">
<Steps>
<Step title="Role Definition">
Define clear, specific roles for each agent
</Step>
<Step title="Goal Setting">
Set specific, measurable goals
</Step>
<Step title="Tool Selection">
Choose relevant tools for the task
</Step>
<Step title="Memory Setup">
Configure appropriate memory settings
</Step>
</Steps>
</Card>
<Card title="Agent Interaction" icon="network-wired" iconType="solid">
<Steps>
<Step title="Communication">
Establish clear communication protocols
</Step>
<Step title="Delegation">
Define explicit delegation rules
</Step>
<Step title="Error Handling">
Implement robust error handling
</Step>
<Step title="Resource Management">
Set up efficient resource allocation
</Step>
</Steps>
</Card>
</CardGroup>
## Async Capabilities
<CardGroup cols={1}>
<Card title="Key Features" icon="bolt" iconType="solid">
<Tabs>
<Tab title="Async Support">
```python
async def main():
agent = Agent(name="AsyncAgent")
result = await agent.aprocess_task()
```
- Full async/await support
- Non-blocking operations
- Enhanced performance
</Tab>
<Tab title="Parallel Execution">
```python
async def parallel_tasks():
tasks = [agent1.task(), agent2.task()]
results = await asyncio.gather(*tasks)
```
- Parallel task execution
- Efficient resource usage
- Improved throughput
</Tab>
<Tab title="Integration">
```python
@agent.async_tool
async def custom_tool():
async with aiohttp.ClientSession() as session:
# Async operations
pass
```
- Async tool integration
- Callback support
- Mixed sync/async operations
</Tab>
</Tabs>
</Card>
</CardGroup>
## Advanced Features
<CardGroup cols={2}>
<Card title="Memory Management" icon="brain">
- Short-term conversation memory
- Long-term knowledge retention
- Context preservation
</Card>
<Card title="Tool Integration" icon="plug">
- Custom tool development
- External API integration
- Resource access control
</Card>
</CardGroup>
## Async Support
Agents now support asynchronous operations through the following methods:
- `achat`: Async version of the chat method
- `astart`: Async version of start method
- `aexecute_task`: Async version of execute_task method
- `arun_task`: Async version of run_task method
- `arun_all_tasks`: Async version of run_all_tasks method
### Example Usage:
```python
import asyncio
from praisonaiagents import Agent, Task, PraisonAIAgents
async def main():
# Create an async agent
async_agent = Agent(
name="AsyncAgent",
role="Async Task Specialist",
goal="Perform async operations",
backstory="Expert in async operations",
tools=[async_search_tool], # Your async tool
verbose=True
)
# Create an async task
async_task = Task(
description="Perform async operation",
expected_output="Async result",
agent=async_agent,
async_execution=True # Enable async execution
)
# Create and start agents with async support
agents = PraisonAIAgents(
agents=[async_agent],
tasks=[async_task],
verbose=True
)
# Start async execution
result = await agents.astart()
print(result)
# Run the async main function
if __name__ == "__main__":
asyncio.run(main())
```
### Key Features:
- Full async/await support
- Parallel task execution
- Async tool integration
- Async callback support
- Mixed sync/async operations
## Next Steps
<CardGroup cols={2}>
<Card
title="Create Your First Agent"
icon="code"
href="/code/quickstart"
>
Follow our quickstart guide to create your first agent
</Card>
<Card
title="API Reference"
icon="book"
href="/api/praisonaiagents/agent/agent"
>
Explore the complete Agent API documentation
</Card>
</CardGroup>
-241
View File
@@ -1,241 +0,0 @@
---
title: "AI Agents with Knowledge"
sidebarTitle: "Knowledge"
description: "Learn how to create AI agents with custom knowledge bases"
icon: "book"
---
```mermaid
flowchart LR
subgraph In[Input]
PDF[PDF]
TXT[TXT]
MD[MD]
end
subgraph Router[Vector Store]
DB[(Vector DB)]
end
subgraph Out[Agents]
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
In --> Router
Router --> A1
Router --> A2
Router --> A3
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
| Feature | [Knowledge](/concepts/knowledge) | [Memory](/concepts/memory) |
|---------|--------------------------------|---------------------------|
| When Used | Pre-loaded before agent execution | Created and updated during runtime |
| Purpose | Provide static reference information | Store dynamic context and interactions |
| Storage | Read-only knowledge base | Read-write memory store |
| Persistence | Permanent until explicitly changed | Can be temporary (STM) or persistent (LTM) |
| Updates | Manual updates through knowledge files | Automatic updates during agent execution |
## Quick Start
<Steps>
<Step title="Install Package">
Install PraisonAI Agents with knowledge support:
```bash
pip install "praisonaiagents[knowledge]"
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key:
```bash
export OPENAI_API_KEY=xxxxx
```
</Step>
<Step title="Create Script">
Create a new file `app.py`:
```python
from praisonaiagents import Agent
agent = Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["small.pdf"]
)
agent.start("What is KAG in one line?")
```
</Step>
</Steps>
## Basic Usage
The simplest way to create a knowledge-based agent is without any configuration:
```python
from praisonaiagents import Agent
agent = Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["small.pdf"]
)
agent.start("What is KAG in one line?")
```
## Advanced Configuration
For more control over the knowledge base, you can specify a configuration:
```python
from praisonaiagents import Agent
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "custom_knowledge",
"path": ".praison",
}
}
}
agent = Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["small.pdf"],
knowledge_config=config
)
agent.start("What is KAG in one line?")
```
## Multi-Agent Knowledge System
For more complex scenarios, you can create a knowledge-based system with multiple agents:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
import logging
import os
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Define the configuration for the Knowledge instance
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "knowledge_test",
"path": ".praison",
}
}
}
# Create an agent with knowledge capabilities
knowledge_agent = Agent(
name="KnowledgeAgent",
role="Information Specialist",
goal="Store and retrieve knowledge efficiently",
backstory="Expert in managing and utilizing stored knowledge",
knowledge=["sample.pdf"],
knowledge_config=config,
verbose=True
)
# Define a task for the agent
knowledge_task = Task(
name="knowledge_task",
description="Who is Mervin Praison?",
expected_output="Answer to the question",
agent=knowledge_agent
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[knowledge_agent],
tasks=[knowledge_task],
process="sequential",
user_id="user1"
)
# Start execution
result = agents.start()
```
## Understanding Knowledge Configuration
<AccordionGroup>
<Accordion title="Vector Store Options">
- **Provider**: Choose between different vector store backends (e.g., "chroma")
- **Collection Name**: Name for your knowledge collection
- **Path**: Location to store the vector database
</Accordion>
<Accordion title="Supported File Types">
- PDF documents (*.pdf)
- Text files (*.txt)
- Markdown files (*.md, *.mdx)
- And more...
</Accordion>
<Accordion title="Multi-Agent Setup">
- **Role**: Define specialized roles for knowledge agents
- **Goal**: Set specific knowledge management objectives
- **Process**: Choose between sequential or parallel execution
</Accordion>
</AccordionGroup>
## Features
<CardGroup cols={2}>
<Card title="Custom Knowledge" icon="book">
Import your own documents and data as knowledge sources
</Card>
<Card title="Vector Storage" icon="database">
Efficient storage and retrieval of knowledge embeddings
</Card>
<Card title="Multiple Sources" icon="layer-group">
Combine multiple documents and file types
</Card>
<Card title="Persistent Storage" icon="hard-drive">
Save and reuse knowledge bases across sessions
</Card>
</CardGroup>
## Best Practices
1. **Document Preparation**
- Clean and well-formatted documents work best
- Break large documents into smaller chunks
- Use consistent formatting
2. **Knowledge Organization**
- Group related documents together
- Use meaningful file names
- Keep knowledge bases focused and relevant
3. **Performance Optimization**
- Monitor vector store size
- Clean up unused collections
- Use appropriate chunk sizes
4. **Multi-Agent Coordination**
- Define clear roles and responsibilities
- Set appropriate logging levels for debugging
- Use unique collection names for different agent groups
## Next Steps
- Learn about [Memory Management](/concepts/memory) for long-term recall
- Explore [Tool Integration](/concepts/tools) for enhanced capabilities
- Check out [Examples](/examples) for implementation ideas
-472
View File
@@ -1,472 +0,0 @@
---
title: "AI Agents with Memory"
sidebarTitle: "Memory"
description: "Learn how to create AI agents with memory capabilities for maintaining context and information across tasks."
icon: "brain"
---
```mermaid
flowchart TB
subgraph Memory
direction TB
STM[Short Term]
LTM[Long Term]
end
subgraph Store
direction TB
DB[(Vector DB)]
end
Input[Input] ---> Agents
subgraph Agents
direction LR
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
Agents ---> Output[Output]
Memory <--> Store
Store <--> A1
Store <--> A2
Store <--> A3
style Memory fill:#189AB4,color:#fff
style Store fill:#2E8B57,color:#fff
style Agents fill:#8B0000,color:#fff
style Input fill:#8B0000,color:#fff
style Output fill:#8B0000,color:#fff
```
| Feature | [Knowledge](/concepts/knowledge) | [Memory](/concepts/memory) |
|---------|--------------------------------|---------------------------|
| When Used | Pre-loaded before agent execution | Created and updated during runtime |
| Purpose | Provide static reference information | Store dynamic context and interactions |
| Storage | Read-only knowledge base | Read-write memory store |
| Persistence | Permanent until explicitly changed | Can be temporary (STM) or persistent (LTM) |
| Updates | Manual updates through knowledge files | Automatic updates during agent execution |
## Quick Start
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install "praisonaiagents[memory]" duckduckgo_search
```
duckduckgo_search is a tool that allows agents to search the web.
It is required for the multiple agents example shown below.
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
<CodeGroup>
```python Single Agent
from praisonaiagents.agents.agents import Agent, Task, PraisonAIAgents
# Create blog writer agent
blog_agent = Agent(
role="Blog Writer",
goal="Write a blog post about AI",
backstory="Expert at writing blog posts",
llm="gpt-4o-mini"
)
# Create blog writing task
blog_task = Task(
description="Write a blog post about AI trends",
expected_output="Well-written blog post about AI trends",
agent=blog_agent
)
# Create and start the agents with memory enabled
agents = PraisonAIAgents(
agents=[blog_agent],
tasks=[blog_task],
memory=True
)
# Start execution
result = agents.start()
print(result)
```
```python Multiple Agents
from praisonaiagents.agents.agents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import duckduckgo
# Create research agent with memory
research_agent = Agent(
role="Research Analyst",
goal="Research and document key information about topics",
backstory="Expert at analyzing and storing information in memory",
llm="gpt-4o-mini",
tools=[duckduckgo]
)
# Create blog writer agent
blog_agent = Agent(
role="Blog Writer",
goal="Write a blog post about the research",
backstory="Expert at writing blog posts",
llm="gpt-4o-mini"
)
# Create research task
research_task = Task(
description="Research and document key information about AI trends",
expected_output="Detailed research findings about AI trends",
agent=research_agent
)
# Create blog writing task
blog_task = Task(
description="Write a blog post about the research findings",
expected_output="Well-written blog post based on research",
agent=blog_agent
)
# Create and start the agents with advanced memory configuration
agents = PraisonAIAgents(
agents=[research_agent, blog_agent],
tasks=[research_task, blog_task],
memory=True
)
# Start execution
result = agents.start()
print(result)
```
</CodeGroup>
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
memory: true
roles:
researcher:
backstory: Expert at analyzing and storing information in memory.
goal: Research and document key information about topics
role: Research Analyst
llm: gpt-4o-mini
tools:
- duckduckgo
tasks:
research_task:
description: Research and document key information about topics.
expected_output: Detailed research findings.
writer:
backstory: Expert at writing blog posts.
goal: Write a blog post about the research
role: Blog Writer
llm: gpt-4o-mini
tasks:
blog_task:
description: Write a blog post about the research.
expected_output: Well-written blog post based on research.
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python
</Note>
## Understanding Memory
<Card title="What is Agent Memory?" icon="question">
Memory in AI agents enables them to:
- Maintain context across multiple tasks
- Remember previous interactions and findings
- Build upon past knowledge
- Share information between agents
- Create more coherent and contextual responses
</Card>
## Features
<CardGroup cols={2}>
<Card title="Context Retention" icon="brain">
Maintain information across multiple interactions.
</Card>
<Card title="Information Sharing" icon="share-nodes">
Share knowledge between multiple agents.
</Card>
<Card title="Long-term Storage" icon="database">
Store and retrieve information over extended periods.
</Card>
<Card title="Memory Types" icon="layer-group">
Support for different memory types (short-term, long-term).
</Card>
</CardGroup>
## Multi-Agent Memory
<Tabs>
<Tab title="Code">
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import duckduckgo
# Create first agent for research
researcher = Agent(
role="Research Analyst",
goal="Research and analyze market trends",
backstory="Expert in market research and data analysis",
tools=[duckduckgo],
verbose=True
)
# Create second agent for report writing
writer = Agent(
role="Report Writer",
goal="Create comprehensive market reports",
backstory="Expert in technical writing and report creation",
verbose=True
)
# Create research task
research_task = Task(
description="Research current market trends",
expected_output="Detailed market analysis",
agent=researcher
)
# Create writing task
report_task = Task(
description="Create a market report based on research",
expected_output="Comprehensive market report",
agent=writer
)
# Create and start the agents with memory
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[research_task, report_task],
memory=True,
process="sequential"
)
# Start execution
result = agents.start()
```
</Tab>
<Tab title="No Code">
```yaml
framework: praisonai
process: sequential
memory: true
roles:
researcher:
backstory: Expert in market research and data analysis.
goal: Research and analyze market trends
role: Research Analyst
tools:
- duckduckgo
tasks:
research_task:
description: Research current market trends.
expected_output: Detailed market analysis.
writer:
backstory: Expert in technical writing and report creation.
goal: Create comprehensive market reports
role: Report Writer
tasks:
report_task:
description: Create a market report based on research.
expected_output: Comprehensive market report.
```
</Tab>
</Tabs>
### Configuration Options
```python
# Create an agent with memory configuration
agent = Agent(
role="Research Analyst",
goal="Research and retain information",
backstory="Expert in research and analysis",
tools=[duckduckgo],
verbose=True, # Enable detailed logging
llm="gpt-4o" # Language model to use
)
# Create agents with memory options
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
memory=True, # Enable memory
memory_config={
"provider": "rag", # Use RAG for semantic search
"use_embedding": True, # Enable embeddings for better search
"short_db": ".praison/short_term.db", # Path for short-term memory
"long_db": ".praison/long_term.db", # Path for long-term memory
"rag_db_path": ".praison/chroma_db" # Path for vector database
}
)
```
## Troubleshooting
<CardGroup cols={2}>
<Card title="Memory Issues" icon="triangle-exclamation">
If memory isn't working as expected:
- Check memory configuration
- Enable verbose mode for debugging
- Verify memory provider settings
</Card>
<Card title="Context Flow" icon="code">
If context isn't being maintained:
- Review task dependencies
- Check memory configuration
- Verify agent communication
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="../features/autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="../features/mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal results, configure memory settings based on your specific use case requirements and expected interaction patterns.
</Note>
### Memory Configuration Options
The memory system in PraisonAI supports various configuration options to customize how agents store and retrieve information:
```python
memory_config = {
# Memory Provider
"provider": "rag", # Options: "rag", "mem0", "none"
"use_embedding": True, # Enable semantic search with embeddings
# Storage Paths
"short_db": ".praison/short_term.db", # Short-term memory SQLite DB
"long_db": ".praison/long_term.db", # Long-term memory SQLite DB
"rag_db_path": ".praison/chroma_db", # Vector database path
# Memory Settings
"ttl": 3600, # Time to live for memory items (in seconds)
# Optional Mem0 Config (if using mem0 provider)
"config": {
"api_key": "...", # Mem0 API key
"org_id": "...", # Organization ID
"project_id": "..." # Project ID
}
}
# Create agents with memory configuration
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
memory=True,
memory_config=memory_config
)
```
### Memory Types
PraisonAI's memory system includes several types of memory:
<CardGroup cols={2}>
<Card title="Short-term Memory" icon="bolt">
- Temporary storage for current context
- Automatically cleared between sessions
- Fast access for immediate task context
</Card>
<Card title="Long-term Memory" icon="database">
- Persistent storage for important information
- Semantic search capabilities with RAG
- Quality-based storage decisions
</Card>
</CardGroup>
### Memory Quality Control
PraisonAI includes built-in quality control for memory storage:
```python
# Example of storing with quality metrics
agents.memory.store_long_term(
text="Important information to remember",
metadata={
"task_id": "task_123",
"agent": "research_agent"
},
completeness=0.9, # How complete is the information
relevance=0.85, # How relevant to the task
clarity=0.95, # How clear and well-structured
accuracy=0.9, # How accurate is the information
weights={ # Custom weights for quality score
"completeness": 0.3,
"relevance": 0.3,
"clarity": 0.2,
"accuracy": 0.2
}
)
# Search with quality filter
results = agents.memory.search_long_term(
query="search query",
min_quality=0.8, # Only return high-quality matches
limit=5 # Maximum number of results
)
-453
View File
@@ -1,453 +0,0 @@
---
title: "Process"
description: "Understanding Process Types in PraisonAI"
icon: "diagram-project"
---
# Understanding Process Types
Process types in PraisonAI define how tasks are executed and how agents collaborate. Each process type offers different patterns for task execution and agent coordination.
## Process Types Overview
<CardGroup cols={3}>
<Card
title="Sequential Process"
icon="arrow-right"
href="/sequential-process"
>
Linear task execution in a predefined order
</Card>
<Card
title="Hierarchical Process"
icon="sitemap"
href="/hierarchical-process"
>
Manager-coordinated task execution with dynamic assignment
</Card>
<Card
title="Workflow Process"
icon="diagram-project"
href="/workflow-process"
>
Complex task flows with conditional execution and state management
</Card>
</CardGroup>
## Sequential Process
```mermaid
graph LR
Input[Input] --> A1
subgraph Agents
direction LR
A1[Agent 1] --> A2[Agent 2] --> A3[Agent 3]
end
A3 --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class A1,A2,A3 process
class Agents transparent
```
The simplest form of task execution where tasks are performed one after another.
<Card>
### Characteristics
- Linear execution flow
- Predictable order
- Simple dependency management
- Direct task progression
### Usage
```python
agents = PraisonAIAgents(
agents=[agent1, agent2],
tasks=[task1, task2, task3],
process="sequential"
)
```
</Card>
## Hierarchical Process
```mermaid
graph TB
Input[Input] --> Manager
subgraph Agents
Manager[Manager Agent]
subgraph Workers
direction LR
W1[Worker 1]
W2[Worker 2]
W3[Worker 3]
end
Manager --> W1
Manager --> W2
Manager --> W3
end
W1 --> Manager
W2 --> Manager
W3 --> Manager
Manager --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Manager,W1,W2,W3 process
class Agents,Workers transparent
```
Uses a manager agent to coordinate task execution and agent assignments.
<Card>
### Characteristics
- Manager-driven coordination
- Dynamic task assignment
- Flexible execution order
- Intelligent resource allocation
### Configuration
```python
agents = PraisonAIAgents(
agents=[manager_agent, worker_agent1, worker_agent2],
tasks=[task1, task2],
process="hierarchical",
manager_llm="gpt-4o"
)
```
</Card>
## Workflow Process
```mermaid
graph LR
Input[Input] --> Start
subgraph Workflow
direction LR
Start[Start] --> C1{Condition}
C1 --> |Yes| A1[Agent 1]
C1 --> |No| A2[Agent 2]
A1 --> Join
A2 --> Join
Join --> A3[Agent 3]
end
A3 --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef decision fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Start,A1,A2,A3,Join process
class C1 decision
class Workflow transparent
```
Advanced process type supporting complex task relationships and conditional execution.
<Card>
### Features
- Task dependencies
- Conditional branching
- Loop handling
- Context sharing
- State management
### Implementation
```python
task_workflow = {
"start_task": {
"next": ["decision_task"],
"type": "task"
},
"decision_task": {
"type": "decision",
"conditions": {
"success": ["process_task"],
"failure": ["error_task"]
}
}
}
```
</Card>
## Getting Started
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent Sequential Process
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False,
process="sequential"
)
result = agents.start()
```
```python Multiple Agents Hierarchical Process
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
</Steps>
<br /><br />
<div className="relative w-full aspect-video">
<iframe
className="absolute top-0 left-0 w-full h-full"
src="https://www.youtube.com/embed/yWTH44QPl2A"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<br />
## Advanced Features
<CardGroup cols={2}>
<Card title="State Management" icon="database" iconType="solid">
<AccordionGroup>
<Accordion title="Task State Tracking">
Monitor and manage the progress of each task in real-time
</Accordion>
<Accordion title="Context Preservation">
Maintain important information across different stages of execution
</Accordion>
<Accordion title="Data Flow Control">
Manage how data moves between tasks and agents efficiently
</Accordion>
</AccordionGroup>
</Card>
<Card title="Error Handling" icon="shield-check" iconType="solid">
<AccordionGroup>
<Accordion title="Graceful Recovery">
Automatically handle failures and continue execution
</Accordion>
<Accordion title="Alternative Paths">
Switch to backup plans when primary execution fails
</Accordion>
<Accordion title="Error Reporting">
Detailed error logs and diagnostic information
</Accordion>
</AccordionGroup>
</Card>
<Card title="Monitoring" icon="chart-line" iconType="solid">
<AccordionGroup>
<Accordion title="Progress Tracking">
Real-time visibility into task completion status
</Accordion>
<Accordion title="Performance Metrics">
Measure execution time and resource efficiency
</Accordion>
<Accordion title="Resource Usage">
Monitor system resource utilization
</Accordion>
</AccordionGroup>
</Card>
<Card title="Integration" icon="plug" iconType="solid">
<AccordionGroup>
<Accordion title="External Systems">
Connect with other services and platforms
</Accordion>
<Accordion title="API Sync">
Maintain data consistency across systems
</Accordion>
<Accordion title="Event Handling">
React to system and external events
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
## Async Processing
<Note>
All process types support asynchronous execution through async generators, enabling efficient parallel processing and non-blocking operations.
</Note>
### Core Async Methods
<CardGroup cols={3}>
<Card title="asequential" icon="arrow-right">
Async version of sequential process for non-blocking linear execution
</Card>
<Card title="aworkflow" icon="diagram-project">
Async workflow process for complex parallel task execution
</Card>
<Card title="ahierarchical" icon="sitemap">
Async hierarchical process for distributed task management
</Card>
</CardGroup>
### Process-Specific Features
<Tabs>
<Tab title="Sequential Process">
<Card>
- Tasks execute in order but don't block
- Maintains sequence while allowing async operations
- Perfect for I/O-heavy tasks
```python
async def main():
agents = PraisonAIAgents(
process="sequential",
async_mode=True
)
await agents.astart()
```
</Card>
</Tab>
<Tab title="Workflow Process">
<Card>
- Parallel execution of independent tasks
- Async branching and merging
- Dynamic task scheduling based on conditions
```python
async def main():
agents = PraisonAIAgents(
process="workflow",
async_mode=True,
parallel_tasks=True
)
await agents.astart()
```
</Card>
</Tab>
<Tab title="Hierarchical Process">
<Card>
- Async manager delegation
- Parallel subtask execution
- Dynamic worker assignment
```python
async def main():
agents = PraisonAIAgents(
process="hierarchical",
async_mode=True,
dynamic_assignment=True
)
await agents.astart()
```
</Card>
</Tab>
</Tabs>
### Key Benefits
<CardGroup cols={2}>
<Card title="Performance" icon="bolt">
- Efficient resource utilization
- Reduced waiting time
- Better throughput
</Card>
<Card title="Flexibility" icon="puzzle-piece">
- Mix sync and async tasks
- Adaptable execution patterns
- Easy scaling
</Card>
</CardGroup>
-530
View File
@@ -1,530 +0,0 @@
---
title: "Tasks"
description: "Understanding Tasks in PraisonAI"
icon: "list-check"
---
# Understanding Tasks
Tasks are units of work that agents execute. Each task has a clear goal, input requirements, and expected outputs.
```mermaid
graph LR
Input[Input] ---> Task
subgraph Task
direction LR
Role[Role]
Goal[Goal]
Story[Backstory]
Expected[Expected Output]
Role --> Goal
Goal --> Story
Story --> Expected
end
Task ---> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Role,Goal,Story,Expected process
class Task transparent
```
## Core Components
<CardGroup cols={2}>
<Card title="Task Definition" icon="file-lines">
Clear description of work to be done and expected outputs
</Card>
<Card title="Agent Assignment" icon="user-check">
Matching tasks with capable agents
</Card>
<Card title="Tool Access" icon="toolbox">
Resources available for task completion
</Card>
<Card title="Output Handling" icon="file-export">
Managing and formatting task results
</Card>
</CardGroup>
## Task Configuration
<CodeGroup>
```python Basic
task = Task(
description="Research AI trends",
expected_output="Summary report",
agent=research_agent
)
```
```python Advanced
task = Task(
description="Analyze market data",
expected_output="Detailed analysis",
agent=analyst_agent,
tools=[AnalysisTool()],
output_file="analysis.md",
async_execution=True
)
```
</CodeGroup>
# Understanding Tasks
<br />
```mermaid
graph LR
%% Task Flow Steps
Start([▶ Start]) --> TaskDef
TaskDef --> AgentAssign
AgentAssign --> Exec
Exec --> Output([✓ Output])
%% Define subgraphs for each step
subgraph TaskDef[" "]
TD_Icon[📋 Task Definition]
TD_Desc[Description & Requirements]
TD_Icon --- TD_Desc
style TD_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style TD_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
subgraph AgentAssign[" "]
AA_Icon[🤖 Agent Assignment]
AA_Desc[Matching & Delegation]
AA_Icon --- AA_Desc
style AA_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style AA_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
subgraph Exec[" "]
E_Icon[⚙️ Execution]
E_Desc[Processing & Tools]
E_Icon --- E_Desc
style E_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style E_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
%% Styling for main elements
style Start fill:#2D3047,stroke:#7C90A0,color:#fff
style Output fill:#2D3047,stroke:#7C90A0,color:#fff
%% Style for containers
style TaskDef fill:#1B1F3B,stroke:#7C90A0,color:#fff
style AgentAssign fill:#1B1F3B,stroke:#7C90A0,color:#fff
style Exec fill:#1B1F3B,stroke:#7C90A0,color:#fff
%% Global styles
classDef default fill:#2D3047,stroke:#7C90A0,color:#fff
linkStyle default stroke:#7C90A0,stroke-width:2px
```
<br /><br />
```mermaid
graph LR
%% Task States
Pending([📥 Pending]) --> InProgress([⚡ In Progress])
InProgress --> Completed([✅ Completed])
InProgress --> Failed([❌ Failed])
%% Styling
style Pending fill:#2D3047,stroke:#7C90A0,color:#fff
style InProgress fill:#5C80BC,stroke:#7C90A0,color:#fff
style Completed fill:#2D3047,stroke:#7C90A0,color:#fff
style Failed fill:#2D3047,stroke:#7C90A0,color:#fff
%% Global styles
classDef default fill:#2D3047,stroke:#7C90A0,color:#fff
linkStyle default stroke:#7C90A0,stroke-width:2px
```
## Task Types
<Steps>
<Step title="Basic Task">
Simple, single-operation tasks with clear inputs and outputs
</Step>
<Step title="Decision Task">
Tasks involving choices and conditional paths
```python
decision_task = Task(
type="decision",
conditions={
"success": ["next_task"],
"failure": ["error_task"]
}
)
```
</Step>
<Step title="Loop Task">
Repetitive operations over collections
```python
loop_task = Task(
type="loop",
items=data_list,
operation="process_item"
)
```
</Step>
</Steps>
## Task Relationships
<Warning>
Properly managing task dependencies is crucial for complex workflows. Always ensure proper context sharing and error handling.
</Warning>
### Context Sharing
```python
task_a = Task(name="research")
task_b = Task(
name="analyze",
context=[task_a] # Uses task_a's output
)
```
### Task Dependencies
| Relationship | Description | Example |
|:-------------|:------------|:--------|
| **Sequential** | Tasks run one after another | Research → Analysis → Report |
| **Parallel** | Independent tasks run simultaneously | Data Collection + Processing |
| **Conditional** | Tasks depend on previous results | Success → Next Task, Failure → Retry |
## Advanced Features
<CardGroup cols={2}>
<Card title="Output Handling" icon="file-code">
- Multiple output formats
- Structured data validation
- File system integration
</Card>
<Card title="Task Control" icon="sliders">
- Execution flow control
- Error recovery
- Progress tracking
</Card>
</CardGroup>
## Getting Started
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False
)
result = agents.start()
```
```python Multiple Agents
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
</Steps>
## Best Practices
<Note>
Design tasks to be atomic and focused. Each task should have a single, clear responsibility.
</Note>
<CardGroup cols={2}>
<Card title="Task Design Principles" icon="compass-drafting" iconType="solid">
<AccordionGroup>
<Accordion title="Clear Task Descriptions">
Write precise, unambiguous task descriptions that clearly state the task's purpose and requirements.
```python
task = Task(
description=(
"Analyze Q4 2024 sales data "
"and generate growth metrics"
),
expected_output="Sales growth report"
)
```
</Accordion>
<Accordion title="Success Criteria">
Define measurable success criteria to ensure task completion can be properly evaluated.
```python
task = Task(
success_criteria={
"format": "markdown",
"metrics": [
"growth_rate",
"revenue_change"
],
"min_confidence": 0.95
}
)
```
</Accordion>
<Accordion title="Task Dependencies">
Specify any dependencies or prerequisites for the task.
```python
task = Task(
description="Generate final report",
dependencies=[
data_collection_task,
analysis_task
],
wait_for_dependencies=True
)
```
</Accordion>
</AccordionGroup>
</Card>
<Card title="Resource Management" icon="server" iconType="solid">
<AccordionGroup>
<Accordion title="Tool Selection">
Choose appropriate tools that match your task's requirements.
```python
task = Task(
tools=[
DataAnalyzer(),
ReportGenerator(),
MetricsCalculator()
],
tool_config={
"timeout": 30,
"retry": True
}
)
```
</Accordion>
<Accordion title="Error Handling">
Implement comprehensive error management strategies.
```python
task = Task(
error_strategy="retry",
max_retries=3,
fallback_handler=handler,
error_callbacks=[
log_error,
notify_admin
]
)
```
</Accordion>
<Accordion title="Resource Limits">
Set appropriate resource constraints for optimal performance.
```python
task = Task(
memory_limit="2GB",
timeout=300,
max_concurrent=5,
cpu_priority="high",
auto_scale=True
)
```
</Accordion>
<Accordion title="Performance Monitoring">
Configure monitoring and logging for task execution.
```python
task = Task(
monitoring={
"metrics": ["duration", "memory", "cpu"],
"log_level": "INFO",
"trace_enabled": True,
"alert_threshold": 0.85
}
)
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
## Async Task Execution
<CardGroup cols={1}>
<Card title="Async Task Features" icon="bolt" iconType="solid">
<Tabs>
<Tab title="Basic Configuration">
```python
async_task = Task(
description="Perform async operation",
expected_output="Async result",
agent=async_agent,
async_execution=True, # Enable async execution
callback=async_callback # Optional async callback
)
```
- Enable async execution with `async_execution=True`
- Perfect for I/O-heavy operations
- Supports parallel task execution
</Tab>
<Tab title="Async Callbacks">
```python
async def async_callback(output: TaskOutput):
await asyncio.sleep(1) # Simulate async operation
print(f"Processed output: {output.raw}")
task = Task(
description="Task with async callback",
expected_output="Result",
agent=agent,
async_execution=True,
callback=async_callback
)
```
- Support for async callbacks
- Process results asynchronously
- Handle task completion events
</Tab>
<Tab title="Mixed Execution">
```python
# Create mixed task types
sync_task = Task(
description="Synchronous operation",
async_execution=False
)
async_task = Task(
description="Asynchronous operation",
async_execution=True
)
# Run with mixed execution
agents = PraisonAIAgents(
agents=[sync_agent, async_agent],
tasks=[sync_task, async_task]
)
result = await agents.astart()
```
- Mix sync and async tasks
- Flexible execution patterns
- Optimal resource utilization
</Tab>
</Tabs>
</Card>
</CardGroup>
<Tip>
**Pro Tip**: Use async execution for tasks that involve I/O operations (like API calls or file operations) to improve overall performance. Keep CPU-intensive tasks synchronous.
</Tip>
## Next Steps
<CardGroup cols={2}>
<Card
title="Create Tasks"
icon="plus"
href="/code/quickstart"
>
Learn how to create and configure tasks
</Card>
<Card
title="Task API"
icon="code"
href="/api/praisonaiagents/task/task"
>
Explore the complete Task API documentation
</Card>
</CardGroup>
-647
View File
@@ -1,647 +0,0 @@
---
title: "AI Agents with Tools"
sidebarTitle: "Tools"
description: "Learn how to create AI agents that can use tools to interact with external systems and perform actions."
icon: "screwdriver-wrench"
---
```mermaid
flowchart TB
subgraph Tools
direction TB
T3[Internet Search]
T1[Code Execution]
T2[Formatting]
end
Input[Input] ---> Agents
subgraph Agents
direction LR
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
Agents ---> Output[Output]
T3 --> A1
T1 --> A2
T2 --> A3
style Tools fill:#189AB4,color:#fff
style Agents fill:#8B0000,color:#fff
style Input fill:#8B0000,color:#fff
style Output fill:#8B0000,color:#fff
```
| Feature | [Knowledge](/concepts/knowledge) | [Tools](/concepts/tools) |
|---------|--------------------------------|---------------------------|
| Purpose | Static reference information | Dynamic interaction capabilities |
| Access | Read-only reference | Execute actions and commands |
| Updates | Manual through files | Real-time through tool calls |
| Storage | Knowledge base | Assigned to specific agents |
| Persistence | Permanent until changed | Available during agent execution |
## Quick Start
Tools are functions that agents can use to interact with external systems and perform actions. They are essential for creating agents that can do more than just process text.
## Creating Custom Tool
<Steps>
<Step>
Create any function that you want to use as a tool, that performs a specific task.
```python
from duckduckgo_search import DDGS
from typing import List, Dict
# Tool Implementation
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search using DuckDuckGo
Args:
query (str): The search query string
Returns:
List[Dict]: List of search results containing title, URL, and snippet
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
```
</Step>
<Step>
Assign the tool to an agent
```python
data_agent = Agent(
name="DataCollector",
role="Search Specialist",
goal="Perform internet searches to collect relevant information.",
backstory="Expert in finding and organising internet data.",
tools=[internet_search_tool], ## Add the tool to the agent i.e the function name
)
```
</Step>
</Steps>
<Card title="That's it!">
<Check>You have created a custom tool and assigned it to an agent.</Check>
</Card>
## Implementing Tools Full Code Example
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents duckduckgo-search
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent with Tool">
Create `app.py`
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from duckduckgo_search import DDGS
from typing import List, Dict
# 1. Tool Implementation
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search using DuckDuckGo
Args:
query (str): The search query string
Returns:
List[Dict]: List of search results containing title, URL, and snippet
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
# 2. Assign the tool to an agent
data_agent = Agent(
name="DataCollector",
role="Search Specialist",
goal="Perform internet searches to collect relevant information.",
backstory="Expert in finding and organising internet data.",
tools=[internet_search_tool],
self_reflect=False
)
# 3. Task Definition
collect_task = Task(
description="Perform an internet search using the query: 'AI job trends in 2024'. Return results as a list of title, URL, and snippet.",
expected_output="List of search results with titles, URLs, and snippets.",
agent=data_agent,
name="collect_data",
)
# 4. Start Agents
agents = PraisonAIAgents(
agents=[data_agent],
tasks=[collect_task],
process="sequential"
)
agents.start()
```
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install PraisonAI">
Install the core package and duckduckgo_search package:
```bash Terminal
pip install praisonai duckduckgo_search
```
</Step>
<Step title="Create Custom Tool">
<Info>
To add additional tools/features you need some coding which can be generated using ChatGPT or any LLM
</Info>
Create a new file `tools.py` with the following content:
```python
from duckduckgo_search import DDGS
from typing import List, Dict
# 1. Tool
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
```
</Step>
<Step title="Create Agent">
Create a new file `agents.yaml` with the following content:
```yaml
framework: praisonai
topic: create movie script about cat in mars
roles:
scriptwriter:
backstory: Expert in dialogue and script structure, translating concepts into
scripts.
goal: Write a movie script about a cat in Mars
role: Scriptwriter
tools:
- internet_search_tool # <-- Tool assigned to Agent here
tasks:
scriptwriting_task:
description: Turn the story concept into a production-ready movie script,
including dialogue and scene details.
expected_output: Final movie script with dialogue and scene details.
```
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
## In-build Tools in PraisonAI
<CardGroup cols={2}>
<Card title="Search Tools" icon="magnifying-glass" href="/tools/search">
Tools for searching and retrieving information from various sources
</Card>
<Card title="Python Tools" icon="python" href="/tools/python_tools">
Essential Python utilities for data manipulation and scripting
</Card>
<Card title="Spider Tools" icon="spider" href="/tools/spider_tools">
Web crawling and scraping capabilities for data extraction
</Card>
<Card title="Arxiv Tools" icon="book" href="/tools/arxiv_tools">
Access and search academic papers from arXiv repository
</Card>
<Card title="Newspaper Tools" icon="newspaper" href="/tools/newspaper_tools">
Extract and parse content from news articles and websites
</Card>
<Card title="DuckDB Tools" icon="database" href="/tools/duckdb_tools">
Fast analytical SQL database operations and queries
</Card>
<Card title="DuckDuckGo Tools" icon="duck" href="/tools/duckduckgo_tools">
Web search functionality using DuckDuckGo's API
</Card>
<Card title="Calculator Tools" icon="calculator" href="/tools/calculator_tools">
Perform mathematical calculations and conversions
</Card>
<Card title="YAML Tools" icon="file-code" href="/tools/yaml_tools">
Parse and manipulate YAML format data
</Card>
<Card title="JSON Tools" icon="brackets-curly" href="/tools/json_tools">
Handle JSON data structures and operations
</Card>
<Card title="Pandas Tools" icon="table" href="/tools/pandas_tools">
Data analysis and manipulation using Pandas
</Card>
<Card title="YFinance Tools" icon="chart-line" href="/tools/yfinance_tools">
Fetch financial market data from Yahoo Finance
</Card>
<Card title="Shell Tools" icon="terminal" href="/tools/shell_tools">
Execute shell commands and system operations
</Card>
<Card title="Wikipedia Tools" icon="book-open" href="/tools/wikipedia_tools">
Access and search Wikipedia articles and data
</Card>
<Card title="XML Tools" icon="code" href="/tools/xml_tools">
Process and manipulate XML format data
</Card>
<Card title="File Tools" icon="file" href="/tools/file_tools">
File system operations and management utilities
</Card>
<Card title="Excel Tools" icon="file-excel" href="/tools/excel_tools">
Work with Excel spreadsheets and workbooks
</Card>
<Card title="CSV Tools" icon="file-csv" href="/tools/csv_tools">
Handle CSV file operations and transformations
</Card>
</CardGroup>
## Tools Overview
<CardGroup cols={3}>
<Card
title="Search Tools"
icon="magnifying-glass"
iconType="solid"
>
Tools for searching and retrieving information from various sources
</Card>
<Card
title="File Tools"
icon="file"
iconType="solid"
>
Tools for reading, writing, and manipulating files
</Card>
<Card
title="API Tools"
icon="code"
iconType="solid"
>
Tools for interacting with external APIs and services
</Card>
</CardGroup>
## Advanced Tool Features
### Tool Configuration
<Frame>
```python
def configured_tool(
query: str,
max_results: int = 5,
timeout: int = 10
) -> List[Dict]:
"""
Example of a configurable tool
Args:
query (str): Search query
max_results (int): Maximum number of results
timeout (int): Request timeout in seconds
Returns:
List[Dict]: Search results
"""
# Tool implementation
pass
```
</Frame>
### Tool Chaining
<Frame>
```python
def chain_tools(input_data: str) -> Dict:
"""
Example of chaining multiple tools
Args:
input_data (str): Input data
Returns:
Dict: Processed results
"""
# 1. Search for data
search_results = internet_search_tool(input_data)
# 2. Process results
processed_data = process_tool(search_results)
# 3. Format output
return format_tool(processed_data)
```
</Frame>
### Tool Categories
<CardGroup cols={3}>
<Card title="Data Collection Tools">
- Web scraping
- API integration
- Database queries
</Card>
<Card title="Processing Tools">
- Data transformation
- Text analysis
- Image processing
</Card>
<Card title="Output Tools">
- File generation
- Report creation
- Data visualization
</Card>
</CardGroup>
## Tool Integration
### Adding Tools to Agents
<Frame>
```python
# Multiple tools
agent = Agent(
name="MultiTool Agent",
tools=[
internet_search_tool,
file_processing_tool,
api_integration_tool
]
)
```
</Frame>
### Tool Dependencies
<Frame>
```python
# Tool with dependencies
def advanced_tool(data: Dict) -> Dict:
"""
Tool that depends on external libraries
Args:
data (Dict): Input data
Returns:
Dict: Processed data
"""
try:
import required_library
# Tool implementation
return processed_result
except ImportError:
raise Exception("Required library not installed")
```
</Frame>
## Tool Guidelines
<CardGroup cols={2}>
<Card title="Best Practices">
1. **Type Hints**
- Use Python type hints
- Define clear input/output types
- Document complex types
2. **Documentation**
- Write clear docstrings
- Explain parameters
- Provide usage examples
3. **Error Handling**
- Handle exceptions gracefully
- Return meaningful errors
- Validate inputs
</Card>
<Card title="Tool Types">
1. **Search Tools**
- Web search
- Database queries
- Document search
2. **File Tools**
- Read/write operations
- File conversion
- Data extraction
3. **API Tools**
- REST API calls
- GraphQL queries
- Service integration
</Card>
</CardGroup>
## Best Practices Summary
<Note>
Following these best practices will help you create robust, efficient, and secure tools in PraisonAI.
</Note>
<CardGroup cols={1}>
<Card title="Design Principles" icon="compass-drafting" iconType="solid">
<AccordionGroup>
<Accordion title="Single Responsibility">
Each tool should have one clear purpose and do it well. Avoid creating tools that try to do too many things.
```python
# Good Example
def process_image(image: np.array) -> np.array:
return processed_image
# Avoid
def process_and_save_and_upload(image):
# Too many responsibilities
pass
```
</Accordion>
<Accordion title="Clear Interfaces">
Define explicit input/output types and maintain consistent parameter naming.
```python
def search_tool(
query: str,
max_results: int = 10
) -> List[Dict[str, Any]]:
"""
Search for information with clear parameters
"""
pass
```
</Accordion>
<Accordion title="Documentation">
Always include detailed docstrings and type hints.
```python
def analyze_text(
text: str,
language: str = "en"
) -> Dict[str, float]:
"""
Analyze text sentiment and emotions.
Args:
text: Input text to analyze
language: ISO language code
Returns:
Dict with sentiment scores
"""
pass
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
<br />
<CardGroup cols={1}>
<Card title="Performance Optimization" icon="bolt" iconType="solid">
<AccordionGroup>
<Accordion title="Efficient Processing">
Optimize resource usage and processing time.
```python
# Use generators for large datasets
def process_large_data():
for chunk in data_generator():
yield process_chunk(chunk)
```
</Accordion>
<Accordion title="Resource Management">
Properly handle resource allocation and cleanup.
```python
async with aiohttp.ClientSession() as session:
# Resource automatically managed
await process_data(session)
```
</Accordion>
<Accordion title="Caching">
Implement caching for frequently accessed data.
```python
@cache.memoize(timeout=300)
def expensive_operation(data: str) -> Dict:
return process_expensive(data)
```
</Accordion>
<Accordion title="Async Operations">
Use async/await for I/O-bound operations.
```python
async def fetch_data(urls: List[str]):
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, url) for url in urls]
return await asyncio.gather(*tasks)
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
<br />
<CardGroup cols={1}>
<Card title="Security Best Practices" icon="shield-check" iconType="solid">
<AccordionGroup>
<Accordion title="Input Validation">
Always validate and sanitize inputs to prevent security vulnerabilities.
```python
def process_user_input(data: str) -> str:
if not isinstance(data, str):
raise ValueError("Input must be string")
return sanitize_input(data.strip())
```
</Accordion>
<Accordion title="Rate Limiting">
Implement rate limiting for API calls to prevent abuse.
```python
@rate_limit(calls=100, period=60)
async def api_call():
return await make_request()
```
</Accordion>
<Accordion title="API Key Management">
Securely handle API keys and credentials using environment variables.
```python
# Use environment variables
api_key = os.getenv('API_KEY')
if not api_key:
raise ConfigError("API key not found")
```
</Accordion>
<Accordion title="Error Masking">
Hide sensitive information in error messages to prevent information leakage.
```python
try:
result = process_sensitive_data()
except Exception as e:
# Log detailed error internally
logger.error(f"Detailed error: {str(e)}")
# Return sanitized error to user
raise PublicError("Processing failed")
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
<br />
<Tip>
**Pro Tip**: Start with these practices from the beginning of your project. It's easier to maintain good practices than to retrofit them later.
</Tip>
-28
View File
@@ -1,28 +0,0 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'PraisonAI'
copyright = '2024, Mervin Praison'
author = 'Mervin Praison'
release = '7'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx_rtd_theme']
templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']
-14
View File
@@ -1,14 +0,0 @@
---
title: "Contributing"
description: "Guide for contributing to PraisonAI through GitHub, including forking, cloning, and submitting pull requests"
icon: "code-branch"
---
- Fork on GitHub: Use the "Fork" button on the repository page.
- Clone your fork: `git clone https://github.com/yourusername/praisonAI.git`
- Create a branch: `git checkout -b new-feature`
- Make changes and commit: `git commit -am "Add some feature"`
- Push to your fork: `git push origin new-feature`
- Submit a pull request via GitHub's web interface.
- Await feedback from project maintainers.
-35
View File
@@ -1,35 +0,0 @@
---
title: "Deploy"
description: "Guide for deploying PraisonAI to cloud platforms, with detailed instructions for Google Cloud deployment"
icon: "cloud"
---
## Google Cloud
```bash
gcloud init
gcloud services enable run.googleapis.com
gcloud services enable containerregistry.googleapis.com
gcloud services enable cloudbuild.googleapis.com
export OPENAI_MODEL_NAME="gpt-4o"
export OPENAI_API_KEY="Enter your API key"
export OPENAI_API_BASE="https://api.openai.com/v1"
yes | gcloud auth configure-docker us-central1-docker.pkg.dev
gcloud artifacts repositories create praisonai-repository --repository-format=docker --location=us-central1
PROJECT_ID=$(gcloud config get-value project)
TAG="latest"
docker build --platform linux/amd64 -t gcr.io/${PROJECT_ID}/praisonai-app:${TAG} .
docker tag gcr.io/${PROJECT_ID}/praisonai-app:${TAG} us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG}
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG}
gcloud run deploy praisonai-service \
--image us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG} \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE}
```
-66
View File
@@ -1,66 +0,0 @@
---
title: "Agents Playbook"
description: "Examples and templates for creating PraisonAI agent playbooks, from simple to detailed configurations with multiple roles and tasks"
icon: "book"
---
# Agents Playbook
## Simple Playbook Example
```yaml
framework: crewai
topic: Artificial Intelligence
roles:
screenwriter:
backstory: 'Skilled in crafting scripts with engaging dialogue about {topic}.'
goal: Create scripts from concepts.
role: Screenwriter
tasks:
scriptwriting_task:
description: 'Develop scripts with compelling characters and dialogue about {topic}.'
expected_output: 'Complete script ready for production.'
```
## Detailed Playbook Example
```yaml
framework: crewai
topic: Artificial Intelligence
roles:
movie_concept_creator:
backstory: 'Creative thinker with a deep understanding of cinematic storytelling,
capable of using AI-generated storylines to create unique and compelling movie
ideas.'
goal: Generate engaging movie concepts using AI storylines
role: Movie Concept Creator
tasks:
movie_concept_development:
description: 'Develop movie concepts from AI-generated storylines, ensuring
they are engaging and have strong narrative arcs.'
expected_output: 'Well-structured movie concept document with character
bios, settings, and plot outlines.'
screenwriter:
backstory: 'Expert in writing engaging dialogue and script structure, able to
turn movie concepts into production-ready scripts.'
goal: Write compelling scripts based on movie concepts
role: Screenwriter
tasks:
scriptwriting_task:
description: 'Turn movie concepts into polished scripts with well-developed
characters, strong dialogue, and effective scene transitions.'
expected_output: 'Production-ready script with a beginning, middle, and
end, along with character development and engaging dialogues.'
editor:
backstory: 'Adept at identifying inconsistencies, improving language usage,
and maintaining the overall flow of the script.'
goal: Refine the scripts and ensure continuity of the movie storyline
role: Editor
tasks:
editing_task:
description: 'Review, edit, and refine the scripts to ensure they are cohesive
and follow a well-structured narrative.'
expected_output: 'A polished final draft of the script with no inconsistencies,
strong character development, and effective dialogue.'
dependencies: []
```
-214
View File
@@ -1,214 +0,0 @@
---
title: "Google Colab Tools"
description: "Guide for implementing and using custom tools in PraisonAI with Google Colab, including examples of internet search and data processing tools"
icon: "wrench"
---
```
jupyter:
accelerator: GPU
colab:
gpuType: T4
kernelspec:
display_name: Python 3
name: python3
language_info:
name: python
nbformat: 4
nbformat_minor: 0
```
``` python
!pip install -Uq praisonai duckduckgo_search
```
``` python
from duckduckgo_search import DDGS
from praisonai_tools import BaseTool
class InternetSearchTool(BaseTool):
name: str = "InternetSearchTool"
description: str = "Search Internet for relevant information based on a query or latest news"
def _run(self, query: str):
ddgs = DDGS()
results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
return results
```
``` python
import os
import yaml
from praisonai import PraisonAI
from google.colab import userdata
# Example agent_yaml content
agent_yaml = """
framework: "crewai"
topic: "Space Exploration"
roles:
astronomer:
role: "Space Researcher"
goal: "Discover new insights about {topic}"
backstory: "You are a curious and dedicated astronomer with a passion for unraveling the mysteries of the cosmos."
tasks:
investigate_exoplanets:
description: "Research and compile information about exoplanets discovered in the last decade."
expected_output: "A summarized report on exoplanet discoveries, including their size, potential habitability, and distance from Earth."
tools:
- "InternetSearchTool"
"""
# Create a PraisonAI instance with the agent_yaml content
praisonai = PraisonAI(agent_yaml=agent_yaml)
# Add OPENAI_API_KEY Secrets to Google Colab on the Left Hand Side 🔑 or Enter Manually Below
os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY') or "ENTER OPENAI_API_KEY HERE"
# Run PraisonAI
result = praisonai.run()
# Print the result
print(result)
```
[2024-07-03 04:53:48][DEBUG]: == Working Agent: Space Researcher
[2024-07-03 04:53:48][INFO]: == Starting Task: Research and compile information about exoplanets discovered in the last decade.
> Entering new CrewAgentExecutor chain...
I now can give a great answer.
Final Answer:
Over the last decade, the field of exoplanet research has experienced significant advancements, leading to the discovery of thousands of exoplanets. These discoveries have been made possible through missions like NASA's Kepler and TESS (Transiting Exoplanet Survey Satellite), as well as ground-based observatories. Here is a summarized report on some of the notable exoplanet discoveries, including their size, potential habitability, and distance from Earth:
1. **Kepler-452b**
- **Size**: Approximately 1.6 times the radius of Earth
- **Potential Habitability**: Located in the habitable zone of its star, where liquid water could exist. It is often referred to as Earth's "cousin."
- **Distance from Earth**: About 1,400 light-years
2. **Proxima Centauri b**
- **Size**: About 1.17 times the mass of Earth
- **Potential Habitability**: Located in the habitable zone of Proxima Centauri, the closest star to the Sun. It has the potential to have liquid water.
- **Distance from Earth**: 4.24 light-years
3. **TRAPPIST-1 System**
- **Size**: The system includes seven Earth-sized planets
- **Potential Habitability**: Three of the planets (TRAPPIST-1e, TRAPPIST-1f, and TRAPPIST-1g) are located in the habitable zone and could potentially support liquid water.
- **Distance from Earth**: Approximately 39 light-years
4. **LHS 1140b**
- **Size**: About 1.4 times the size of Earth and 6.6 times its mass
- **Potential Habitability**: Located in the habitable zone of its star. It has a thick atmosphere and conditions that could support life.
- **Distance from Earth**: About 40 light-years
5. **Kepler-186f**
- **Size**: Similar to Earth in size
- **Potential Habitability**: The first Earth-sized planet discovered in the habitable zone of another star. It has potential for liquid water on its surface.
- **Distance from Earth**: About 500 light-years
6. **K2-18b**
- **Size**: Approximately 2.6 times the radius of Earth
- **Potential Habitability**: Located in the habitable zone of its star, with evidence of water vapor in its atmosphere.
- **Distance from Earth**: About 124 light-years
7. **GJ 357 d**
- **Size**: About 6.1 times the mass of Earth
- **Potential Habitability**: Located in the habitable zone of its star, with the potential to have liquid water on its surface.
- **Distance from Earth**: About 31 light-years
These discoveries highlight the diversity of exoplanets in terms of size, composition, and potential habitability. The search for exoplanets is crucial for understanding the potential for life beyond Earth and the formation and evolution of planetary systems. Ongoing and future missions, such as the James Webb Space Telescope, are expected to provide even more detailed information about these distant worlds.
The continuous exploration and study of exoplanets will undoubtedly lead to new insights and perhaps even the discovery of life beyond our solar system.
> Finished chain.
[2024-07-03 04:53:58][DEBUG]: == [Space Researcher] Task output: Over the last decade, the field of exoplanet research has experienced significant advancements, leading to the discovery of thousands of exoplanets. These discoveries have been made possible through missions like NASA's Kepler and TESS (Transiting Exoplanet Survey Satellite), as well as ground-based observatories. Here is a summarized report on some of the notable exoplanet discoveries, including their size, potential habitability, and distance from Earth:
1. **Kepler-452b**
- **Size**: Approximately 1.6 times the radius of Earth
- **Potential Habitability**: Located in the habitable zone of its star, where liquid water could exist. It is often referred to as Earth's "cousin."
- **Distance from Earth**: About 1,400 light-years
2. **Proxima Centauri b**
- **Size**: About 1.17 times the mass of Earth
- **Potential Habitability**: Located in the habitable zone of Proxima Centauri, the closest star to the Sun. It has the potential to have liquid water.
- **Distance from Earth**: 4.24 light-years
3. **TRAPPIST-1 System**
- **Size**: The system includes seven Earth-sized planets
- **Potential Habitability**: Three of the planets (TRAPPIST-1e, TRAPPIST-1f, and TRAPPIST-1g) are located in the habitable zone and could potentially support liquid water.
- **Distance from Earth**: Approximately 39 light-years
4. **LHS 1140b**
- **Size**: About 1.4 times the size of Earth and 6.6 times its mass
- **Potential Habitability**: Located in the habitable zone of its star. It has a thick atmosphere and conditions that could support life.
- **Distance from Earth**: About 40 light-years
5. **Kepler-186f**
- **Size**: Similar to Earth in size
- **Potential Habitability**: The first Earth-sized planet discovered in the habitable zone of another star. It has potential for liquid water on its surface.
- **Distance from Earth**: About 500 light-years
6. **K2-18b**
- **Size**: Approximately 2.6 times the radius of Earth
- **Potential Habitability**: Located in the habitable zone of its star, with evidence of water vapor in its atmosphere.
- **Distance from Earth**: About 124 light-years
7. **GJ 357 d**
- **Size**: About 6.1 times the mass of Earth
- **Potential Habitability**: Located in the habitable zone of its star, with the potential to have liquid water on its surface.
- **Distance from Earth**: About 31 light-years
These discoveries highlight the diversity of exoplanets in terms of size, composition, and potential habitability. The search for exoplanets is crucial for understanding the potential for life beyond Earth and the formation and evolution of planetary systems. Ongoing and future missions, such as the James Webb Space Telescope, are expected to provide even more detailed information about these distant worlds.
The continuous exploration and study of exoplanets will undoubtedly lead to new insights and perhaps even the discovery of life beyond our solar system.
### Task Output ###
Over the last decade, the field of exoplanet research has experienced significant advancements, leading to the discovery of thousands of exoplanets. These discoveries have been made possible through missions like NASA's Kepler and TESS (Transiting Exoplanet Survey Satellite), as well as ground-based observatories. Here is a summarized report on some of the notable exoplanet discoveries, including their size, potential habitability, and distance from Earth:
1. **Kepler-452b**
- **Size**: Approximately 1.6 times the radius of Earth
- **Potential Habitability**: Located in the habitable zone of its star, where liquid water could exist. It is often referred to as Earth's "cousin."
- **Distance from Earth**: About 1,400 light-years
2. **Proxima Centauri b**
- **Size**: About 1.17 times the mass of Earth
- **Potential Habitability**: Located in the habitable zone of Proxima Centauri, the closest star to the Sun. It has the potential to have liquid water.
- **Distance from Earth**: 4.24 light-years
3. **TRAPPIST-1 System**
- **Size**: The system includes seven Earth-sized planets
- **Potential Habitability**: Three of the planets (TRAPPIST-1e, TRAPPIST-1f, and TRAPPIST-1g) are located in the habitable zone and could potentially support liquid water.
- **Distance from Earth**: Approximately 39 light-years
4. **LHS 1140b**
- **Size**: About 1.4 times the size of Earth and 6.6 times its mass
- **Potential Habitability**: Located in the habitable zone of its star. It has a thick atmosphere and conditions that could support life.
- **Distance from Earth**: About 40 light-years
5. **Kepler-186f**
- **Size**: Similar to Earth in size
- **Potential Habitability**: The first Earth-sized planet discovered in the habitable zone of another star. It has potential for liquid water on its surface.
- **Distance from Earth**: About 500 light-years
6. **K2-18b**
- **Size**: Approximately 2.6 times the radius of Earth
- **Potential Habitability**: Located in the habitable zone of its star, with evidence of water vapor in its atmosphere.
- **Distance from Earth**: About 124 light-years
7. **GJ 357 d**
- **Size**: About 6.1 times the mass of Earth
- **Potential Habitability**: Located in the habitable zone of its star, with the potential to have liquid water on its surface.
- **Distance from Earth**: About 31 light-years
These discoveries highlight the diversity of exoplanets in terms of size, composition, and potential habitability. The search for exoplanets is crucial for understanding the potential for life beyond Earth and the formation and evolution of planetary systems. Ongoing and future missions, such as the James Webb Space Telescope, are expected to provide even more detailed information about these distant worlds.
The continuous exploration and study of exoplanets will undoubtedly lead to new insights and perhaps even the discovery of life beyond our solar system.
:::
:::
-247
View File
@@ -1,247 +0,0 @@
---
title: "Google Colab Integration"
description: "Guide for using PraisonAI in Google Colab environments, with example code and configurations for agent-based tasks"
icon: "google"
---
<CardGroup cols={2}>
<Card title="Basic PraisonAI" icon="book">
<a target="_blank" href="https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/cookbooks/praisonai-googlecolab.ipynb">
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" />
</a>
</Card>
<Card title="PraisonAI with Tools" icon="screwdriver-wrench">
<a target="_blank" href="https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/cookbooks/praisonai-tools-googlecolab.ipynb">
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" />
</a>
</Card>
</CardGroup>
```
jupyter:
accelerator: GPU
colab:
gpuType: T4
kernelspec:
display_name: Python 3
name: python3
language_info:
name: python
nbformat: 4
nbformat_minor: 0
```
``` python
!pip install -Uq praisonai
```
``` python
import os
import yaml
from praisonai import PraisonAI
from google.colab import userdata
# Example agent_yaml content
agent_yaml = """
framework: "crewai"
topic: "Space Exploration"
roles:
astronomer:
role: "Space Researcher"
goal: "Discover new insights about {topic}"
backstory: "You are a curious and dedicated astronomer with a passion for unraveling the mysteries of the cosmos."
tasks:
investigate_exoplanets:
description: "Research and compile information about exoplanets discovered in the last decade."
expected_output: "A summarized report on exoplanet discoveries, including their size, potential habitability, and distance from Earth."
"""
# Create a PraisonAI instance with the agent_yaml content
praisonai = PraisonAI(agent_yaml=agent_yaml)
# Add OPENAI_API_KEY Secrets to Google Colab on the Left Hand Side 🔑 or Enter Manually Below
os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY') or "ENTER OPENAI_API_KEY HERE"
# Run PraisonAI
result = praisonai.run()
# Print the result
print(result)
```
[2024-07-03 04:39:09][DEBUG]: == Working Agent: Space Researcher
[2024-07-03 04:39:09][INFO]: == Starting Task: Research and compile information about exoplanets discovered in the last decade.
> Entering new CrewAgentExecutor chain...
I now can give a great answer.
Final Answer:
In the last decade, the field of exoplanet research has experienced a remarkable surge in discoveries, thanks to advancements in technology and dedicated space missions such as Kepler, TESS (Transiting Exoplanet Survey Satellite), and various ground-based observatories. Here is a summarized report on some of the notable exoplanet discoveries, highlighting their size, potential habitability, and distance from Earth:
1. **Kepler-452b**
- **Size:** Approximately 60% larger in diameter than Earth.
- **Potential Habitability:** Often referred to as "Earth's Cousin," Kepler-452b orbits within the habitable zone of its star, where liquid water could exist. The planet receives a similar amount of energy from its star as Earth does from the Sun.
- **Distance from Earth:** About 1,402 light-years.
2. **Proxima Centauri b**
- **Size:** Slightly larger than Earth, with a minimum mass of 1.17 Earth masses.
- **Potential Habitability:** Located in the habitable zone of Proxima Centauri, the closest known star to the Sun. Potential for liquid water exists, but its habitability is uncertain due to stellar flare activity.
- **Distance from Earth:** 4.24 light-years.
3. **TRAPPIST-1 System**
- **Size:** The system contains seven Earth-sized planets. TRAPPIST-1e, f, and g are within the star's habitable zone.
- **Potential Habitability:** TRAPPIST-1e is considered the most promising candidate for habitability, as it has a rocky composition and is located in the middle of the habitable zone.
- **Distance from Earth:** About 39 light-years.
4. **LHS 1140 b**
- **Size:** About 1.4 times the size of Earth with a mass of around 6.6 Earth masses.
- **Potential Habitability:** Resides in the habitable zone of its red dwarf star. The planet is likely rocky and has an atmosphere that could support life.
- **Distance from Earth:** Approximately 40 light-years.
5. **K2-18b**
- **Size:** About 2.6 times the size of Earth with a mass of 8.6 Earth masses.
- **Potential Habitability:** This exoplanet lies within the habitable zone and has been detected to have water vapor in its atmosphere. It is considered one of the most promising candidates for habitability outside our solar system.
- **Distance from Earth:** Roughly 124 light-years.
6. **Gliese 667 Cc**
- **Size:** At least 4.5 times the mass of Earth.
- **Potential Habitability:** Orbits within the habitable zone of its host star, Gliese 667 C. Its orbit allows for the possibility of liquid water on its surface.
- **Distance from Earth:** About 23.62 light-years.
7. **HD 40307 g**
- **Size:** A super-Earth with at least 7 Earth masses.
- **Potential Habitability:** Located in the habitable zone of its star, this planet could potentially support liquid water and therefore life.
- **Distance from Earth:** Approximately 42 light-years.
8. **Ross 128 b**
- **Size:** Similar to Earth, with a minimum mass of 1.35 Earth masses.
- **Potential Habitability:** Orbits within the habitable zone of the relatively quiet red dwarf star Ross 128. The planet has mild temperatures that could allow for liquid water.
- **Distance from Earth:** About 11 light-years.
9. **Teegarden's Star b**
- **Size:** Comparable to Earth.
- **Potential Habitability:** Orbits within the habitable zone of Teegarden's Star, a cool red dwarf. Conditions could be suitable for liquid water.
- **Distance from Earth:** Approximately 12 light-years.
10. **Barnard's Star b**
- **Size:** A super-Earth with a mass of about 3.2 Earth masses.
- **Potential Habitability:** Located just outside the traditional habitable zone, but still within a range where liquid water could exist under certain conditions.
- **Distance from Earth:** About 6 light-years.
These discoveries highlight the diverse and intriguing nature of exoplanets found in the last decade. Each of these planets adds valuable information to our understanding of planetary formation, potential habitability, and the search for extraterrestrial life. Continued advancements in detection methods and technologies promise to further expand our knowledge in the years to come.
> Finished chain.
[2024-07-03 04:39:25][DEBUG]: == [Space Researcher] Task output: In the last decade, the field of exoplanet research has experienced a remarkable surge in discoveries, thanks to advancements in technology and dedicated space missions such as Kepler, TESS (Transiting Exoplanet Survey Satellite), and various ground-based observatories. Here is a summarized report on some of the notable exoplanet discoveries, highlighting their size, potential habitability, and distance from Earth:
1. **Kepler-452b**
- **Size:** Approximately 60% larger in diameter than Earth.
- **Potential Habitability:** Often referred to as "Earth's Cousin," Kepler-452b orbits within the habitable zone of its star, where liquid water could exist. The planet receives a similar amount of energy from its star as Earth does from the Sun.
- **Distance from Earth:** About 1,402 light-years.
2. **Proxima Centauri b**
- **Size:** Slightly larger than Earth, with a minimum mass of 1.17 Earth masses.
- **Potential Habitability:** Located in the habitable zone of Proxima Centauri, the closest known star to the Sun. Potential for liquid water exists, but its habitability is uncertain due to stellar flare activity.
- **Distance from Earth:** 4.24 light-years.
3. **TRAPPIST-1 System**
- **Size:** The system contains seven Earth-sized planets. TRAPPIST-1e, f, and g are within the star's habitable zone.
- **Potential Habitability:** TRAPPIST-1e is considered the most promising candidate for habitability, as it has a rocky composition and is located in the middle of the habitable zone.
- **Distance from Earth:** About 39 light-years.
4. **LHS 1140 b**
- **Size:** About 1.4 times the size of Earth with a mass of around 6.6 Earth masses.
- **Potential Habitability:** Resides in the habitable zone of its red dwarf star. The planet is likely rocky and has an atmosphere that could support life.
- **Distance from Earth:** Approximately 40 light-years.
5. **K2-18b**
- **Size:** About 2.6 times the size of Earth with a mass of 8.6 Earth masses.
- **Potential Habitability:** This exoplanet lies within the habitable zone and has been detected to have water vapor in its atmosphere. It is considered one of the most promising candidates for habitability outside our solar system.
- **Distance from Earth:** Roughly 124 light-years.
6. **Gliese 667 Cc**
- **Size:** At least 4.5 times the mass of Earth.
- **Potential Habitability:** Orbits within the habitable zone of its host star, Gliese 667 C. Its orbit allows for the possibility of liquid water on its surface.
- **Distance from Earth:** About 23.62 light-years.
7. **HD 40307 g**
- **Size:** A super-Earth with at least 7 Earth masses.
- **Potential Habitability:** Located in the habitable zone of its star, this planet could potentially support liquid water and therefore life.
- **Distance from Earth:** Approximately 42 light-years.
8. **Ross 128 b**
- **Size:** Similar to Earth, with a minimum mass of 1.35 Earth masses.
- **Potential Habitability:** Orbits within the habitable zone of the relatively quiet red dwarf star Ross 128. The planet has mild temperatures that could allow for liquid water.
- **Distance from Earth:** About 11 light-years.
9. **Teegarden's Star b**
- **Size:** Comparable to Earth.
- **Potential Habitability:** Orbits within the habitable zone of Teegarden's Star, a cool red dwarf. Conditions could be suitable for liquid water.
- **Distance from Earth:** Approximately 12 light-years.
10. **Barnard's Star b**
- **Size:** A super-Earth with a mass of about 3.2 Earth masses.
- **Potential Habitability:** Located just outside the traditional habitable zone, but still within a range where liquid water could exist under certain conditions.
- **Distance from Earth:** About 6 light-years.
These discoveries highlight the diverse and intriguing nature of exoplanets found in the last decade. Each of these planets adds valuable information to our understanding of planetary formation, potential habitability, and the search for extraterrestrial life. Continued advancements in detection methods and technologies promise to further expand our knowledge in the years to come.
### Task Output ###
In the last decade, the field of exoplanet research has experienced a remarkable surge in discoveries, thanks to advancements in technology and dedicated space missions such as Kepler, TESS (Transiting Exoplanet Survey Satellite), and various ground-based observatories. Here is a summarized report on some of the notable exoplanet discoveries, highlighting their size, potential habitability, and distance from Earth:
1. **Kepler-452b**
- **Size:** Approximately 60% larger in diameter than Earth.
- **Potential Habitability:** Often referred to as "Earth's Cousin," Kepler-452b orbits within the habitable zone of its star, where liquid water could exist. The planet receives a similar amount of energy from its star as Earth does from the Sun.
- **Distance from Earth:** About 1,402 light-years.
2. **Proxima Centauri b**
- **Size:** Slightly larger than Earth, with a minimum mass of 1.17 Earth masses.
- **Potential Habitability:** Located in the habitable zone of Proxima Centauri, the closest known star to the Sun. Potential for liquid water exists, but its habitability is uncertain due to stellar flare activity.
- **Distance from Earth:** 4.24 light-years.
3. **TRAPPIST-1 System**
- **Size:** The system contains seven Earth-sized planets. TRAPPIST-1e, f, and g are within the star's habitable zone.
- **Potential Habitability:** TRAPPIST-1e is considered the most promising candidate for habitability, as it has a rocky composition and is located in the middle of the habitable zone.
- **Distance from Earth:** About 39 light-years.
4. **LHS 1140 b**
- **Size:** About 1.4 times the size of Earth with a mass of around 6.6 Earth masses.
- **Potential Habitability:** Resides in the habitable zone of its red dwarf star. The planet is likely rocky and has an atmosphere that could support life.
- **Distance from Earth:** Approximately 40 light-years.
5. **K2-18b**
- **Size:** About 2.6 times the size of Earth with a mass of 8.6 Earth masses.
- **Potential Habitability:** This exoplanet lies within the habitable zone and has been detected to have water vapor in its atmosphere. It is considered one of the most promising candidates for habitability outside our solar system.
- **Distance from Earth:** Roughly 124 light-years.
6. **Gliese 667 Cc**
- **Size:** At least 4.5 times the mass of Earth.
- **Potential Habitability:** Orbits within the habitable zone of its host star, Gliese 667 C. Its orbit allows for the possibility of liquid water on its surface.
- **Distance from Earth:** About 23.62 light-years.
7. **HD 40307 g**
- **Size:** A super-Earth with at least 7 Earth masses.
- **Potential Habitability:** Located in the habitable zone of its star, this planet could potentially support liquid water and therefore life.
- **Distance from Earth:** Approximately 42 light-years.
8. **Ross 128 b**
- **Size:** Similar to Earth, with a minimum mass of 1.35 Earth masses.
- **Potential Habitability:** Orbits within the habitable zone of the relatively quiet red dwarf star Ross 128. The planet has mild temperatures that could allow for liquid water.
- **Distance from Earth:** About 11 light-years.
9. **Teegarden's Star b**
- **Size:** Comparable to Earth.
- **Potential Habitability:** Orbits within the habitable zone of Teegarden's Star, a cool red dwarf. Conditions could be suitable for liquid water.
- **Distance from Earth:** Approximately 12 light-years.
10. **Barnard's Star b**
- **Size:** A super-Earth with a mass of about 3.2 Earth masses.
- **Potential Habitability:** Located just outside the traditional habitable zone, but still within a range where liquid water could exist under certain conditions.
- **Distance from Earth:** About 6 light-years.
These discoveries highlight the diverse and intriguing nature of exoplanets found in the last decade. Each of these planets adds valuable information to our understanding of planetary formation, potential habitability, and the search for extraterrestrial life. Continued advancements in detection methods and technologies promise to further expand our knowledge in the years to come.
-75
View File
@@ -1,75 +0,0 @@
---
title: 'Local Development'
description: 'Set up local development environment with Docker and live reload'
---
## Logging
```bash
export LOGLEVEL=info
```
Advanced logging:
```bash
export LOGLEVEL=debug
```
## Local Docker Development with Live Reload
To facilitate local development with live reload, you can use Docker. Follow the steps below:
### 1. Create Dockerfile.dev
<CodeGroup>
```dockerfile Dockerfile.dev
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install flask praisonai==2.0.18 watchdog
EXPOSE 5555
ENV FLASK_ENV=development
CMD ["flask", "run", "--host=0.0.0.0"]
```
</CodeGroup>
### 2. Create docker-compose.yml
<CodeGroup>
```yaml docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- .:/app
ports:
- "5555:5555"
environment:
FLASK_ENV: development
command: flask run --host=0.0.0.0
watch:
image: alpine:latest
volumes:
- .:/app
command: sh -c "apk add --no-cache inotify-tools && while inotifywait -r -e modify,create,delete /app; do kill -HUP 1; done"
```
</CodeGroup>
### 3. Run Docker Compose
<CodeGroup>
```bash Terminal
docker-compose up
```
</CodeGroup>
This setup will allow you to develop locally with live reload, making it easier to test and iterate on your code.
-11
View File
@@ -1,11 +0,0 @@
---
title: "Test"
description: "Instructions for running and writing tests for PraisonAI components, including unit tests and test automation"
icon: "vial"
---
# Test
```bash
python -m unittest tests.test
```
Loaded 100 of 1052 files, more files were not shown because too many files have changed in this diff. Show more