praisonAI 2.3.64__tar.gz → 2.3.65__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. {praisonai-2.3.64 → praisonai-2.3.65}/PKG-INFO +23 -24
  2. {praisonai-2.3.64 → praisonai-2.3.65}/PraisonAI.egg-info/PKG-INFO +23 -24
  3. {praisonai-2.3.64 → praisonai-2.3.65}/PraisonAI.egg-info/SOURCES.txt +3 -0
  4. {praisonai-2.3.64 → praisonai-2.3.65}/README.md +22 -23
  5. praisonai-2.3.65/praisonai/cli/features/agent_scheduler.py +182 -0
  6. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/main.py +10 -1
  7. praisonai-2.3.65/praisonai/cli/schedule_cli.py +54 -0
  8. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/deploy.py +1 -1
  9. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/scheduler/agent_scheduler.py +97 -0
  10. praisonai-2.3.65/praisonai/scheduler/yaml_loader.py +197 -0
  11. praisonai-2.3.65/praisonai/version.py +1 -0
  12. praisonai-2.3.64/praisonai/version.py +0 -1
  13. {praisonai-2.3.64 → praisonai-2.3.65}/PraisonAI.egg-info/dependency_links.txt +0 -0
  14. {praisonai-2.3.64 → praisonai-2.3.65}/PraisonAI.egg-info/entry_points.txt +0 -0
  15. {praisonai-2.3.64 → praisonai-2.3.65}/PraisonAI.egg-info/requires.txt +0 -0
  16. {praisonai-2.3.64 → praisonai-2.3.65}/PraisonAI.egg-info/top_level.txt +0 -0
  17. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/__init__.py +0 -0
  18. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/__main__.py +0 -0
  19. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/agent_scheduler.py +0 -0
  20. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/agents_generator.py +0 -0
  21. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/api/call.py +0 -0
  22. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/auto.py +0 -0
  23. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/chainlit_ui.py +0 -0
  24. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/__init__.py +0 -0
  25. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/__init__.py +0 -0
  26. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/at_mentions.py +0 -0
  27. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/auto_memory.py +0 -0
  28. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/autonomy_mode.py +0 -0
  29. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/base.py +0 -0
  30. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/cost_tracker.py +0 -0
  31. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/external_agents.py +0 -0
  32. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/fast_context.py +0 -0
  33. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/flow_display.py +0 -0
  34. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/git_integration.py +0 -0
  35. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/guardrail.py +0 -0
  36. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/handoff.py +0 -0
  37. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/image.py +0 -0
  38. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/interactive_tui.py +0 -0
  39. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/knowledge.py +0 -0
  40. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/mcp.py +0 -0
  41. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/message_queue.py +0 -0
  42. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/metrics.py +0 -0
  43. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/n8n.py +0 -0
  44. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/repo_map.py +0 -0
  45. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/router.py +0 -0
  46. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/sandbox_executor.py +0 -0
  47. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/session.py +0 -0
  48. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/slash_commands.py +0 -0
  49. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/telemetry.py +0 -0
  50. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/todo.py +0 -0
  51. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/tools.py +0 -0
  52. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/cli/features/workflow.py +0 -0
  53. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/__init__.py +0 -0
  54. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/agent_tools.py +0 -0
  55. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/diff/__init__.py +0 -0
  56. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/diff/diff_strategy.py +0 -0
  57. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/tools/__init__.py +0 -0
  58. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/tools/apply_diff.py +0 -0
  59. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/tools/execute_command.py +0 -0
  60. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/tools/list_files.py +0 -0
  61. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/tools/read_file.py +0 -0
  62. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/tools/search_replace.py +0 -0
  63. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/tools/write_file.py +0 -0
  64. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/utils/__init__.py +0 -0
  65. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/utils/file_utils.py +0 -0
  66. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/utils/ignore_utils.py +0 -0
  67. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/code/utils/text_utils.py +0 -0
  68. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/inbuilt_tools/__init__.py +0 -0
  69. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/inbuilt_tools/autogen_tools.py +0 -0
  70. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/inc/__init__.py +0 -0
  71. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/inc/config.py +0 -0
  72. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/inc/models.py +0 -0
  73. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/integrations/__init__.py +0 -0
  74. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/integrations/base.py +0 -0
  75. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/integrations/claude_code.py +0 -0
  76. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/integrations/codex_cli.py +0 -0
  77. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/integrations/cursor_cli.py +0 -0
  78. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/integrations/gemini_cli.py +0 -0
  79. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/profiler.py +0 -0
  80. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/scheduler/__init__.py +0 -0
  81. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/scheduler/base.py +0 -0
  82. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/scheduler.py +0 -0
  83. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/setup/__init__.py +0 -0
  84. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/setup/build.py +0 -0
  85. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/setup/post_install.py +0 -0
  86. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/setup/setup_conda_env.py +0 -0
  87. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/setup.py +0 -0
  88. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/test.py +0 -0
  89. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/train.py +0 -0
  90. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/train_vision.py +0 -0
  91. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/agents.py +0 -0
  92. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/callbacks.py +0 -0
  93. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/chat.py +0 -0
  94. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/code.py +0 -0
  95. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/colab.py +0 -0
  96. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/colab_chainlit.py +0 -0
  97. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/components/aicoder.py +0 -0
  98. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/context.py +0 -0
  99. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/database_config.py +0 -0
  100. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/db.py +0 -0
  101. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/realtime.py +0 -0
  102. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/realtimeclient/__init__.py +0 -0
  103. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/realtimeclient/tools.py +0 -0
  104. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/ui/sql_alchemy.py +0 -0
  105. {praisonai-2.3.64 → praisonai-2.3.65}/praisonai/upload_vision.py +0 -0
  106. {praisonai-2.3.64 → praisonai-2.3.65}/pyproject.toml +0 -0
  107. {praisonai-2.3.64 → praisonai-2.3.65}/setup.cfg +0 -0
  108. {praisonai-2.3.64 → praisonai-2.3.65}/tests/test.py +0 -0
  109. {praisonai-2.3.64 → praisonai-2.3.65}/tests/test_agents_playbook.py +0 -0
  110. {praisonai-2.3.64 → praisonai-2.3.65}/tests/test_approval_system.py +0 -0
  111. {praisonai-2.3.64 → praisonai-2.3.65}/tests/test_basic.py +0 -0
  112. {praisonai-2.3.64 → praisonai-2.3.65}/tests/test_cli_features.py +0 -0
  113. {praisonai-2.3.64 → praisonai-2.3.65}/tests/test_custom_tools_fix.py +0 -0
  114. {praisonai-2.3.64 → praisonai-2.3.65}/tests/test_double_api_fix.py +0 -0
  115. {praisonai-2.3.64 → praisonai-2.3.65}/tests/test_n8n_integration.py +0 -0
  116. {praisonai-2.3.64 → praisonai-2.3.65}/tests/test_phase2_refactor.py +0 -0
  117. {praisonai-2.3.64 → praisonai-2.3.65}/tests/test_runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PraisonAI
3
- Version: 2.3.64
3
+ Version: 2.3.65
4
4
  Summary: PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration.
5
5
  Author: Mervin Praison
6
6
  License: MIT
@@ -364,9 +364,7 @@ npm install praisonai
364
364
  | ↳ Git Integration | [Example](examples/python/cli/git_integration_example.py) | [📖](https://docs.praison.ai/docs/cli/git-integration) |
365
365
  | ↳ Sandbox Execution | [Example](examples/python/cli/sandbox_execution_example.py) | [📖](https://docs.praison.ai/docs/cli/sandbox-execution) |
366
366
  | **⏰ 24/7 Scheduling** | | |
367
- | ↳ Agent Scheduler | [Example](examples/python/scheduled_agents/news_checker_live.py) | [📖](https://docs.praison.ai/scheduler/overview) |
368
- | ↳ Scheduled News Checker | [Example](examples/python/scheduled_agents/news_checker_agent.py) | [📖](https://docs.praison.ai/scheduler/examples) |
369
- | ↳ Simple Scheduler Test | [Example](examples/python/scheduled_agents/simple_test.py) | [📖](https://docs.praison.ai/scheduler/quickstart) |
367
+ | ↳ Agent Scheduler | [Example](examples/python/scheduled_agents/news_checker_live.py) | [📖](https://docs.praison.ai/docs/cli/scheduler) |
370
368
 
371
369
  ---
372
370
 
@@ -1345,32 +1343,33 @@ praisonai "Complex task" --metrics --planning
1345
1343
 
1346
1344
  ### Scheduler CLI:
1347
1345
  ```bash
1348
- # Schedule an agent to run periodically (24/7 operation)
1349
- praisonai schedule --interval hourly --task "Check latest AI news"
1346
+ # Schedule an agent using agents.yaml
1347
+ praisonai schedule agents.yaml
1350
1348
 
1351
- # Schedule with custom interval (every 30 minutes)
1352
- praisonai schedule --interval "*/30m" --task "Monitor system status"
1349
+ # Override interval from CLI
1350
+ praisonai schedule agents.yaml --interval "*/30m"
1353
1351
 
1354
- # Schedule with YAML config
1355
- praisonai schedule --config scheduler_config.yaml
1352
+ # With verbose logging
1353
+ praisonai schedule agents.yaml --verbose
1354
+ ```
1356
1355
 
1357
- # Schedule with immediate execution
1358
- praisonai schedule --interval daily --task "Generate report" --run-now
1356
+ **agents.yaml with schedule:**
1357
+ ```yaml
1358
+ framework: praisonai
1359
1359
 
1360
- # Schedule with retry configuration
1361
- praisonai schedule --interval "*/6h" --task "Collect data" --max-retries 5
1360
+ agents:
1361
+ - name: "AI News Monitor"
1362
+ instructions: "Search and summarize AI news"
1363
+ tools:
1364
+ - search_tool
1362
1365
 
1363
- # View scheduler help
1364
- praisonai schedule --help
1365
- ```
1366
+ task: "Search for latest AI news"
1366
1367
 
1367
- **Scheduler Intervals:**
1368
- - `hourly` - Every hour
1369
- - `daily` - Every 24 hours
1370
- - `*/30m` - Every 30 minutes
1371
- - `*/6h` - Every 6 hours
1372
- - `*/5s` - Every 5 seconds (for testing)
1373
- - `3600` - Custom seconds
1368
+ schedule:
1369
+ interval: "hourly" # hourly, daily, */30m, */6h
1370
+ max_retries: 3
1371
+ run_immediately: true
1372
+ ```
1374
1373
 
1375
1374
  ### Image Processing CLI:
1376
1375
  ```bash
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PraisonAI
3
- Version: 2.3.64
3
+ Version: 2.3.65
4
4
  Summary: PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration.
5
5
  Author: Mervin Praison
6
6
  License: MIT
@@ -364,9 +364,7 @@ npm install praisonai
364
364
  | ↳ Git Integration | [Example](examples/python/cli/git_integration_example.py) | [📖](https://docs.praison.ai/docs/cli/git-integration) |
365
365
  | ↳ Sandbox Execution | [Example](examples/python/cli/sandbox_execution_example.py) | [📖](https://docs.praison.ai/docs/cli/sandbox-execution) |
366
366
  | **⏰ 24/7 Scheduling** | | |
367
- | ↳ Agent Scheduler | [Example](examples/python/scheduled_agents/news_checker_live.py) | [📖](https://docs.praison.ai/scheduler/overview) |
368
- | ↳ Scheduled News Checker | [Example](examples/python/scheduled_agents/news_checker_agent.py) | [📖](https://docs.praison.ai/scheduler/examples) |
369
- | ↳ Simple Scheduler Test | [Example](examples/python/scheduled_agents/simple_test.py) | [📖](https://docs.praison.ai/scheduler/quickstart) |
367
+ | ↳ Agent Scheduler | [Example](examples/python/scheduled_agents/news_checker_live.py) | [📖](https://docs.praison.ai/docs/cli/scheduler) |
370
368
 
371
369
  ---
372
370
 
@@ -1345,32 +1343,33 @@ praisonai "Complex task" --metrics --planning
1345
1343
 
1346
1344
  ### Scheduler CLI:
1347
1345
  ```bash
1348
- # Schedule an agent to run periodically (24/7 operation)
1349
- praisonai schedule --interval hourly --task "Check latest AI news"
1346
+ # Schedule an agent using agents.yaml
1347
+ praisonai schedule agents.yaml
1350
1348
 
1351
- # Schedule with custom interval (every 30 minutes)
1352
- praisonai schedule --interval "*/30m" --task "Monitor system status"
1349
+ # Override interval from CLI
1350
+ praisonai schedule agents.yaml --interval "*/30m"
1353
1351
 
1354
- # Schedule with YAML config
1355
- praisonai schedule --config scheduler_config.yaml
1352
+ # With verbose logging
1353
+ praisonai schedule agents.yaml --verbose
1354
+ ```
1356
1355
 
1357
- # Schedule with immediate execution
1358
- praisonai schedule --interval daily --task "Generate report" --run-now
1356
+ **agents.yaml with schedule:**
1357
+ ```yaml
1358
+ framework: praisonai
1359
1359
 
1360
- # Schedule with retry configuration
1361
- praisonai schedule --interval "*/6h" --task "Collect data" --max-retries 5
1360
+ agents:
1361
+ - name: "AI News Monitor"
1362
+ instructions: "Search and summarize AI news"
1363
+ tools:
1364
+ - search_tool
1362
1365
 
1363
- # View scheduler help
1364
- praisonai schedule --help
1365
- ```
1366
+ task: "Search for latest AI news"
1366
1367
 
1367
- **Scheduler Intervals:**
1368
- - `hourly` - Every hour
1369
- - `daily` - Every 24 hours
1370
- - `*/30m` - Every 30 minutes
1371
- - `*/6h` - Every 6 hours
1372
- - `*/5s` - Every 5 seconds (for testing)
1373
- - `3600` - Custom seconds
1368
+ schedule:
1369
+ interval: "hourly" # hourly, daily, */30m, */6h
1370
+ max_retries: 3
1371
+ run_immediately: true
1372
+ ```
1374
1373
 
1375
1374
  ### Image Processing CLI:
1376
1375
  ```bash
@@ -24,7 +24,9 @@ praisonai/version.py
24
24
  praisonai/api/call.py
25
25
  praisonai/cli/__init__.py
26
26
  praisonai/cli/main.py
27
+ praisonai/cli/schedule_cli.py
27
28
  praisonai/cli/features/__init__.py
29
+ praisonai/cli/features/agent_scheduler.py
28
30
  praisonai/cli/features/at_mentions.py
29
31
  praisonai/cli/features/auto_memory.py
30
32
  praisonai/cli/features/autonomy_mode.py
@@ -81,6 +83,7 @@ praisonai/integrations/gemini_cli.py
81
83
  praisonai/scheduler/__init__.py
82
84
  praisonai/scheduler/agent_scheduler.py
83
85
  praisonai/scheduler/base.py
86
+ praisonai/scheduler/yaml_loader.py
84
87
  praisonai/setup/__init__.py
85
88
  praisonai/setup/build.py
86
89
  praisonai/setup/post_install.py
@@ -267,9 +267,7 @@ npm install praisonai
267
267
  | ↳ Git Integration | [Example](examples/python/cli/git_integration_example.py) | [📖](https://docs.praison.ai/docs/cli/git-integration) |
268
268
  | ↳ Sandbox Execution | [Example](examples/python/cli/sandbox_execution_example.py) | [📖](https://docs.praison.ai/docs/cli/sandbox-execution) |
269
269
  | **⏰ 24/7 Scheduling** | | |
270
- | ↳ Agent Scheduler | [Example](examples/python/scheduled_agents/news_checker_live.py) | [📖](https://docs.praison.ai/scheduler/overview) |
271
- | ↳ Scheduled News Checker | [Example](examples/python/scheduled_agents/news_checker_agent.py) | [📖](https://docs.praison.ai/scheduler/examples) |
272
- | ↳ Simple Scheduler Test | [Example](examples/python/scheduled_agents/simple_test.py) | [📖](https://docs.praison.ai/scheduler/quickstart) |
270
+ | ↳ Agent Scheduler | [Example](examples/python/scheduled_agents/news_checker_live.py) | [📖](https://docs.praison.ai/docs/cli/scheduler) |
273
271
 
274
272
  ---
275
273
 
@@ -1248,32 +1246,33 @@ praisonai "Complex task" --metrics --planning
1248
1246
 
1249
1247
  ### Scheduler CLI:
1250
1248
  ```bash
1251
- # Schedule an agent to run periodically (24/7 operation)
1252
- praisonai schedule --interval hourly --task "Check latest AI news"
1249
+ # Schedule an agent using agents.yaml
1250
+ praisonai schedule agents.yaml
1253
1251
 
1254
- # Schedule with custom interval (every 30 minutes)
1255
- praisonai schedule --interval "*/30m" --task "Monitor system status"
1252
+ # Override interval from CLI
1253
+ praisonai schedule agents.yaml --interval "*/30m"
1256
1254
 
1257
- # Schedule with YAML config
1258
- praisonai schedule --config scheduler_config.yaml
1255
+ # With verbose logging
1256
+ praisonai schedule agents.yaml --verbose
1257
+ ```
1259
1258
 
1260
- # Schedule with immediate execution
1261
- praisonai schedule --interval daily --task "Generate report" --run-now
1259
+ **agents.yaml with schedule:**
1260
+ ```yaml
1261
+ framework: praisonai
1262
1262
 
1263
- # Schedule with retry configuration
1264
- praisonai schedule --interval "*/6h" --task "Collect data" --max-retries 5
1263
+ agents:
1264
+ - name: "AI News Monitor"
1265
+ instructions: "Search and summarize AI news"
1266
+ tools:
1267
+ - search_tool
1265
1268
 
1266
- # View scheduler help
1267
- praisonai schedule --help
1268
- ```
1269
+ task: "Search for latest AI news"
1269
1270
 
1270
- **Scheduler Intervals:**
1271
- - `hourly` - Every hour
1272
- - `daily` - Every 24 hours
1273
- - `*/30m` - Every 30 minutes
1274
- - `*/6h` - Every 6 hours
1275
- - `*/5s` - Every 5 seconds (for testing)
1276
- - `3600` - Custom seconds
1271
+ schedule:
1272
+ interval: "hourly" # hourly, daily, */30m, */6h
1273
+ max_retries: 3
1274
+ run_immediately: true
1275
+ ```
1277
1276
 
1278
1277
  ### Image Processing CLI:
1279
1278
  ```bash
@@ -0,0 +1,182 @@
1
+ """
2
+ Agent Scheduler CLI Feature.
3
+
4
+ Provides CLI commands for scheduling agents to run 24/7 at regular intervals.
5
+ """
6
+
7
+ import logging
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ class AgentSchedulerHandler:
13
+ """Handler for agent scheduler CLI commands."""
14
+
15
+ @staticmethod
16
+ def handle_schedule_command(args) -> int:
17
+ """
18
+ Handle the schedule command for running agents periodically.
19
+
20
+ Args:
21
+ args: Parsed command-line arguments
22
+
23
+ Returns:
24
+ Exit code (0 for success, 1 for error)
25
+ """
26
+ try:
27
+ from praisonai.scheduler import AgentScheduler
28
+ except ImportError:
29
+ print("Error: praisonai.scheduler module not found")
30
+ print("Please ensure PraisonAI is properly installed")
31
+ return 1
32
+
33
+ # Get YAML file path (default to agents.yaml)
34
+ yaml_path = getattr(args, 'schedule_yaml', None) or 'agents.yaml'
35
+
36
+ # Get overrides from CLI
37
+ interval_override = getattr(args, 'schedule_interval', None)
38
+ max_retries_override = getattr(args, 'schedule_max_retries', None)
39
+ verbose = getattr(args, 'verbose', False)
40
+
41
+ # Set up logging
42
+ if verbose:
43
+ logging.basicConfig(
44
+ level=logging.INFO,
45
+ format='[%(asctime)s] %(levelname)s - %(message)s',
46
+ datefmt='%Y-%m-%d %H:%M:%S'
47
+ )
48
+
49
+ try:
50
+ # Create scheduler from YAML
51
+ print(f"🤖 Loading agent configuration from: {yaml_path}")
52
+ scheduler = AgentScheduler.from_yaml(
53
+ yaml_path=yaml_path,
54
+ interval_override=interval_override,
55
+ max_retries_override=max_retries_override
56
+ )
57
+
58
+ # Display configuration
59
+ agent_name = getattr(scheduler.agent, 'name', 'Agent')
60
+ print(f"\n{'='*60}")
61
+ print(f"🤖 Starting 24/7 {agent_name}")
62
+ print(f"{'='*60}")
63
+ print(f"Task: {scheduler.task[:80]}{'...' if len(scheduler.task) > 80 else ''}")
64
+
65
+ # Get schedule info
66
+ schedule_config = scheduler._yaml_schedule_config
67
+ interval = interval_override or schedule_config.get('interval', 'hourly')
68
+ max_retries = max_retries_override or schedule_config.get('max_retries', 3)
69
+
70
+ print(f"Schedule: {interval}")
71
+ print(f"Max Retries: {max_retries}")
72
+ print(f"{'='*60}\n")
73
+
74
+ # Start scheduler
75
+ print("⏰ Starting scheduler... (Press Ctrl+C to stop)\n")
76
+ scheduler.start_from_yaml_config()
77
+
78
+ # Keep running until interrupted
79
+ try:
80
+ while scheduler.is_running:
81
+ import time
82
+ time.sleep(1)
83
+ except KeyboardInterrupt:
84
+ print("\n\n🛑 Stopping scheduler...")
85
+ scheduler.stop()
86
+
87
+ # Display final stats
88
+ stats = scheduler.get_stats()
89
+ print("\n📊 Final Statistics:")
90
+ print(f" Total Executions: {stats['total_executions']}")
91
+ print(f" Successful: {stats['successful_executions']}")
92
+ print(f" Failed: {stats['failed_executions']}")
93
+ print(f" Success Rate: {stats['success_rate']:.1f}%")
94
+ print("\n✅ Agent stopped successfully\n")
95
+
96
+ return 0
97
+
98
+ except FileNotFoundError as e:
99
+ print(f"❌ Error: {e}")
100
+ print(f"\nMake sure {yaml_path} exists in the current directory.")
101
+ print("\nExample agents.yaml structure:")
102
+ print("""
103
+ framework: praisonai
104
+
105
+ agents:
106
+ - name: "AI News Monitor"
107
+ role: "News Analyst"
108
+ instructions: "Search and summarize AI news"
109
+ tools:
110
+ - search_tool
111
+
112
+ task: "Search for latest AI news"
113
+
114
+ schedule:
115
+ interval: "hourly"
116
+ max_retries: 3
117
+ run_immediately: true
118
+ """)
119
+ return 1
120
+
121
+ except ValueError as e:
122
+ print(f"❌ Configuration Error: {e}")
123
+ return 1
124
+
125
+ except Exception as e:
126
+ print(f"❌ Error: {e}")
127
+ if verbose:
128
+ import traceback
129
+ traceback.print_exc()
130
+ return 1
131
+
132
+ @staticmethod
133
+ def add_schedule_arguments(subparsers):
134
+ """
135
+ Add schedule subcommand and arguments to parser.
136
+
137
+ Args:
138
+ subparsers: Subparsers object from argparse
139
+ """
140
+ schedule_parser = subparsers.add_parser(
141
+ 'schedule',
142
+ help='Schedule an agent to run continuously at regular intervals'
143
+ )
144
+
145
+ schedule_parser.add_argument(
146
+ 'schedule_yaml',
147
+ nargs='?',
148
+ default='agents.yaml',
149
+ help='Path to agents.yaml file (default: agents.yaml)'
150
+ )
151
+
152
+ schedule_parser.add_argument(
153
+ '--interval',
154
+ dest='schedule_interval',
155
+ type=str,
156
+ help='Override schedule interval (e.g., "hourly", "*/30m", "daily")'
157
+ )
158
+
159
+ schedule_parser.add_argument(
160
+ '--max-retries',
161
+ dest='schedule_max_retries',
162
+ type=int,
163
+ help='Override maximum retry attempts (default: from YAML or 3)'
164
+ )
165
+
166
+ schedule_parser.add_argument(
167
+ '--verbose', '-v',
168
+ action='store_true',
169
+ help='Enable verbose logging'
170
+ )
171
+
172
+ schedule_parser.set_defaults(func=AgentSchedulerHandler.handle_schedule_command)
173
+
174
+
175
+ def setup_scheduler_cli(subparsers):
176
+ """
177
+ Setup scheduler CLI commands.
178
+
179
+ Args:
180
+ subparsers: Subparsers object from argparse
181
+ """
182
+ AgentSchedulerHandler.add_schedule_arguments(subparsers)
@@ -223,7 +223,12 @@ class PraisonAI:
223
223
  file_input = self.read_file_if_provided(getattr(args, 'file', None))
224
224
 
225
225
  if args.command:
226
- if args.command.startswith("tests.test") or args.command.startswith("tests/test"): # Argument used for testing purposes
226
+ # Handle schedule command
227
+ if args.command == "schedule":
228
+ from praisonai.cli.features.agent_scheduler import AgentSchedulerHandler
229
+ exit_code = AgentSchedulerHandler.handle_schedule_command(args)
230
+ sys.exit(exit_code)
231
+ elif args.command.startswith("tests.test") or args.command.startswith("tests/test"): # Argument used for testing purposes
227
232
  print("test")
228
233
  return "test"
229
234
  else:
@@ -710,6 +715,10 @@ class PraisonAI:
710
715
  parser.add_argument("--external-agent", type=str, choices=["claude", "gemini", "codex", "cursor"],
711
716
  help="Use external AI CLI tool (claude, gemini, codex, cursor)")
712
717
 
718
+ # Agent Scheduler - for schedule command
719
+ parser.add_argument("--interval", dest="schedule_interval", type=str, help="Schedule interval (e.g., 'hourly', '*/30m', 'daily')")
720
+ parser.add_argument("--max-retries", dest="schedule_max_retries", type=int, help="Maximum retry attempts for scheduled execution")
721
+
713
722
  # If we're in a test environment, parse with empty args to avoid pytest interference
714
723
  if in_test_env:
715
724
  args, unknown_args = parser.parse_known_args([])
@@ -0,0 +1,54 @@
1
+ """
2
+ Simple CLI entry point for praisonai schedule command.
3
+
4
+ This provides a standalone entry point that can be called from main.py
5
+ """
6
+
7
+ import sys
8
+ from praisonai.cli.features.agent_scheduler import AgentSchedulerHandler
9
+
10
+
11
+ def main():
12
+ """Main entry point for schedule CLI command."""
13
+ import argparse
14
+
15
+ parser = argparse.ArgumentParser(
16
+ description='Schedule an agent to run continuously at regular intervals'
17
+ )
18
+
19
+ parser.add_argument(
20
+ 'schedule_yaml',
21
+ nargs='?',
22
+ default='agents.yaml',
23
+ help='Path to agents.yaml file (default: agents.yaml)'
24
+ )
25
+
26
+ parser.add_argument(
27
+ '--interval',
28
+ dest='schedule_interval',
29
+ type=str,
30
+ help='Override schedule interval (e.g., "hourly", "*/30m", "daily")'
31
+ )
32
+
33
+ parser.add_argument(
34
+ '--max-retries',
35
+ dest='schedule_max_retries',
36
+ type=int,
37
+ help='Override maximum retry attempts (default: from YAML or 3)'
38
+ )
39
+
40
+ parser.add_argument(
41
+ '--verbose', '-v',
42
+ action='store_true',
43
+ help='Enable verbose logging'
44
+ )
45
+
46
+ args = parser.parse_args()
47
+
48
+ # Call the handler
49
+ exit_code = AgentSchedulerHandler.handle_schedule_command(args)
50
+ sys.exit(exit_code)
51
+
52
+
53
+ if __name__ == '__main__':
54
+ main()
@@ -57,7 +57,7 @@ class CloudDeployer:
57
57
  file.write("FROM python:3.11-slim\n")
58
58
  file.write("WORKDIR /app\n")
59
59
  file.write("COPY . .\n")
60
- file.write("RUN pip install flask praisonai==2.3.64 gunicorn markdown\n")
60
+ file.write("RUN pip install flask praisonai==2.3.65 gunicorn markdown\n")
61
61
  file.write("EXPOSE 8080\n")
62
62
  file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
63
63
 
@@ -230,6 +230,103 @@ class AgentScheduler:
230
230
  except Exception as e:
231
231
  logger.error(f"One-time execution failed: {e}")
232
232
  raise
233
+
234
+ @classmethod
235
+ def from_yaml(
236
+ cls,
237
+ yaml_path: str,
238
+ interval_override: Optional[str] = None,
239
+ max_retries_override: Optional[int] = None,
240
+ on_success: Optional[Callable] = None,
241
+ on_failure: Optional[Callable] = None
242
+ ) -> 'AgentScheduler':
243
+ """
244
+ Create AgentScheduler from agents.yaml file.
245
+
246
+ Args:
247
+ yaml_path: Path to agents.yaml file
248
+ interval_override: Override schedule interval from YAML
249
+ max_retries_override: Override max_retries from YAML
250
+ on_success: Callback function on successful execution
251
+ on_failure: Callback function on failed execution
252
+
253
+ Returns:
254
+ Configured AgentScheduler instance
255
+
256
+ Example:
257
+ scheduler = AgentScheduler.from_yaml("agents.yaml")
258
+ scheduler.start()
259
+
260
+ Example agents.yaml:
261
+ framework: praisonai
262
+
263
+ agents:
264
+ - name: "AI News Monitor"
265
+ role: "News Analyst"
266
+ instructions: "Search and summarize AI news"
267
+ tools:
268
+ - search_tool
269
+
270
+ task: "Search for latest AI news"
271
+
272
+ schedule:
273
+ interval: "hourly"
274
+ max_retries: 3
275
+ run_immediately: true
276
+ """
277
+ from .yaml_loader import load_agent_yaml_with_schedule, create_agent_from_config
278
+
279
+ # Load configuration from YAML
280
+ agent_config, schedule_config = load_agent_yaml_with_schedule(yaml_path)
281
+
282
+ # Create agent from config
283
+ agent = create_agent_from_config(agent_config)
284
+
285
+ # Get task
286
+ task = agent_config.get('task', '')
287
+ if not task:
288
+ raise ValueError("No task specified in YAML file")
289
+
290
+ # Create scheduler
291
+ scheduler = cls(
292
+ agent=agent,
293
+ task=task,
294
+ config=agent_config,
295
+ on_success=on_success,
296
+ on_failure=on_failure
297
+ )
298
+
299
+ # Store schedule config for auto-start
300
+ scheduler._yaml_schedule_config = schedule_config
301
+ scheduler._interval_override = interval_override
302
+ scheduler._max_retries_override = max_retries_override
303
+
304
+ return scheduler
305
+
306
+ def start_from_yaml_config(self) -> bool:
307
+ """
308
+ Start scheduler using configuration from YAML file.
309
+
310
+ Must be called after from_yaml() class method.
311
+
312
+ Returns:
313
+ True if scheduler started successfully
314
+ """
315
+ if not hasattr(self, '_yaml_schedule_config'):
316
+ raise RuntimeError("start_from_yaml_config() can only be called after from_yaml()")
317
+
318
+ schedule_config = self._yaml_schedule_config
319
+
320
+ # Use overrides if provided, otherwise use YAML config
321
+ interval = self._interval_override or schedule_config.get('interval', 'hourly')
322
+ max_retries = self._max_retries_override or schedule_config.get('max_retries', 3)
323
+ run_immediately = schedule_config.get('run_immediately', False)
324
+
325
+ return self.start(
326
+ schedule_expr=interval,
327
+ max_retries=max_retries,
328
+ run_immediately=run_immediately
329
+ )
233
330
 
234
331
 
235
332
  def create_agent_scheduler(
@@ -0,0 +1,197 @@
1
+ """
2
+ YAML loader for agent scheduler configuration.
3
+
4
+ Loads agent and schedule configuration from agents.yaml files.
5
+ """
6
+
7
+ import yaml
8
+ import logging
9
+ from typing import Dict, Any, Tuple
10
+ from pathlib import Path
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ def load_agent_yaml_with_schedule(yaml_path: str) -> Tuple[Dict[str, Any], Dict[str, Any]]:
16
+ """
17
+ Load agents.yaml file and extract agent and schedule configuration.
18
+
19
+ Args:
20
+ yaml_path: Path to agents.yaml file
21
+
22
+ Returns:
23
+ Tuple of (agent_config, schedule_config)
24
+
25
+ Raises:
26
+ FileNotFoundError: If YAML file doesn't exist
27
+ ValueError: If YAML is invalid or missing required fields
28
+
29
+ Example YAML structure:
30
+ framework: praisonai
31
+
32
+ agents:
33
+ - name: "AI News Monitor"
34
+ role: "News Analyst"
35
+ goal: "Monitor AI news"
36
+ instructions: "Search and summarize"
37
+ tools:
38
+ - search_tool
39
+ verbose: true
40
+
41
+ task: "Search for latest AI news"
42
+
43
+ schedule:
44
+ interval: "hourly"
45
+ max_retries: 3
46
+ run_immediately: true
47
+ """
48
+ yaml_path = Path(yaml_path)
49
+
50
+ if not yaml_path.exists():
51
+ raise FileNotFoundError(f"YAML file not found: {yaml_path}")
52
+
53
+ try:
54
+ with open(yaml_path, 'r') as f:
55
+ config = yaml.safe_load(f)
56
+ except yaml.YAMLError as e:
57
+ raise ValueError(f"Invalid YAML file: {e}")
58
+
59
+ if not config:
60
+ raise ValueError("Empty YAML file")
61
+
62
+ # Extract agent configuration
63
+ agent_config = {}
64
+
65
+ # Get agents list (can be single agent or multiple)
66
+ agents = config.get('agents', [])
67
+ if not agents:
68
+ raise ValueError("No agents defined in YAML file")
69
+
70
+ # Use first agent for scheduling (can be extended for multi-agent later)
71
+ if isinstance(agents, list):
72
+ agent_config = agents[0]
73
+ else:
74
+ agent_config = agents
75
+
76
+ # Get task
77
+ task = config.get('task', '')
78
+ if not task:
79
+ # Try to get from agent's tasks
80
+ if 'tasks' in agent_config and agent_config['tasks']:
81
+ first_task = list(agent_config['tasks'].values())[0]
82
+ task = first_task.get('description', '')
83
+
84
+ agent_config['task'] = task
85
+
86
+ # Get framework (default to praisonai)
87
+ agent_config['framework'] = config.get('framework', 'praisonai')
88
+
89
+ # Extract schedule configuration (optional)
90
+ schedule_config = config.get('schedule', {})
91
+
92
+ # Set defaults for schedule if not provided
93
+ if not schedule_config:
94
+ schedule_config = {
95
+ 'interval': 'hourly',
96
+ 'max_retries': 3,
97
+ 'run_immediately': False
98
+ }
99
+ else:
100
+ # Ensure required fields have defaults
101
+ schedule_config.setdefault('interval', 'hourly')
102
+ schedule_config.setdefault('max_retries', 3)
103
+ schedule_config.setdefault('run_immediately', False)
104
+
105
+ logger.info(f"Loaded agent '{agent_config.get('name', 'Unknown')}' with schedule interval '{schedule_config['interval']}'")
106
+
107
+ return agent_config, schedule_config
108
+
109
+
110
+ def create_agent_from_config(agent_config: Dict[str, Any]) -> Any:
111
+ """
112
+ Create a PraisonAI Agent instance from configuration.
113
+
114
+ Args:
115
+ agent_config: Agent configuration dictionary
116
+
117
+ Returns:
118
+ Agent instance
119
+
120
+ Raises:
121
+ ImportError: If praisonaiagents is not installed
122
+ """
123
+ try:
124
+ from praisonaiagents import Agent
125
+ except ImportError:
126
+ raise ImportError("praisonaiagents package is required. Install with: pip install praisonaiagents")
127
+
128
+ # Extract agent parameters
129
+ name = agent_config.get('name', 'Scheduled Agent')
130
+ role = agent_config.get('role', '')
131
+ goal = agent_config.get('goal', '')
132
+ instructions = agent_config.get('instructions', agent_config.get('backstory', ''))
133
+ verbose = agent_config.get('verbose', False)
134
+
135
+ # Handle tools
136
+ tools = []
137
+ tool_names = agent_config.get('tools', [])
138
+
139
+ if tool_names:
140
+ # Try to import tools
141
+ for tool_name in tool_names:
142
+ try:
143
+ # Try common tool imports
144
+ if tool_name == 'search_tool' or tool_name == 'InternetSearchTool':
145
+ try:
146
+ from tools import search_tool
147
+ tools.append(search_tool)
148
+ except ImportError:
149
+ logger.warning(f"Could not import {tool_name}, skipping")
150
+ # Add more tool imports as needed
151
+ except Exception as e:
152
+ logger.warning(f"Error loading tool {tool_name}: {e}")
153
+
154
+ # Create agent
155
+ agent = Agent(
156
+ name=name,
157
+ role=role,
158
+ goal=goal,
159
+ instructions=instructions,
160
+ tools=tools,
161
+ verbose=verbose
162
+ )
163
+
164
+ return agent
165
+
166
+
167
+ def validate_schedule_config(schedule_config: Dict[str, Any]) -> None:
168
+ """
169
+ Validate schedule configuration.
170
+
171
+ Args:
172
+ schedule_config: Schedule configuration dictionary
173
+
174
+ Raises:
175
+ ValueError: If configuration is invalid
176
+ """
177
+ required_fields = ['interval']
178
+ for field in required_fields:
179
+ if field not in schedule_config:
180
+ raise ValueError(f"Missing required schedule field: {field}")
181
+
182
+ # Validate interval format
183
+ interval = schedule_config['interval']
184
+ valid_intervals = ['hourly', 'daily']
185
+
186
+ if interval not in valid_intervals:
187
+ # Check if it's a custom format (*/Nm, */Nh, */Ns, or plain number)
188
+ if not (interval.startswith('*/') or interval.isdigit()):
189
+ raise ValueError(
190
+ f"Invalid interval format: {interval}. "
191
+ f"Use 'hourly', 'daily', '*/30m', '*/6h', or seconds as number"
192
+ )
193
+
194
+ # Validate max_retries
195
+ max_retries = schedule_config.get('max_retries', 3)
196
+ if not isinstance(max_retries, int) or max_retries < 0:
197
+ raise ValueError(f"max_retries must be a non-negative integer, got: {max_retries}")
@@ -0,0 +1 @@
1
+ __version__ = "2.3.65"
@@ -1 +0,0 @@
1
- __version__ = "2.3.64"
File without changes
File without changes
File without changes
File without changes
File without changes