praisonAI 2.3.63__tar.gz → 2.3.64__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 (114) hide show
  1. {praisonai-2.3.63 → praisonai-2.3.64}/PKG-INFO +34 -1
  2. {praisonai-2.3.63 → praisonai-2.3.64}/PraisonAI.egg-info/PKG-INFO +34 -1
  3. {praisonai-2.3.63 → praisonai-2.3.64}/PraisonAI.egg-info/SOURCES.txt +4 -0
  4. {praisonai-2.3.63 → praisonai-2.3.64}/README.md +33 -0
  5. praisonai-2.3.64/praisonai/agent_scheduler.py +337 -0
  6. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/deploy.py +1 -1
  7. praisonai-2.3.64/praisonai/scheduler/__init__.py +36 -0
  8. praisonai-2.3.64/praisonai/scheduler/agent_scheduler.py +251 -0
  9. praisonai-2.3.64/praisonai/scheduler/base.py +124 -0
  10. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/scheduler.py +22 -43
  11. praisonai-2.3.64/praisonai/version.py +1 -0
  12. praisonai-2.3.63/praisonai/version.py +0 -1
  13. {praisonai-2.3.63 → praisonai-2.3.64}/PraisonAI.egg-info/dependency_links.txt +0 -0
  14. {praisonai-2.3.63 → praisonai-2.3.64}/PraisonAI.egg-info/entry_points.txt +0 -0
  15. {praisonai-2.3.63 → praisonai-2.3.64}/PraisonAI.egg-info/requires.txt +0 -0
  16. {praisonai-2.3.63 → praisonai-2.3.64}/PraisonAI.egg-info/top_level.txt +0 -0
  17. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/__init__.py +0 -0
  18. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/__main__.py +0 -0
  19. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/agents_generator.py +0 -0
  20. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/api/call.py +0 -0
  21. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/auto.py +0 -0
  22. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/chainlit_ui.py +0 -0
  23. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/__init__.py +0 -0
  24. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/__init__.py +0 -0
  25. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/at_mentions.py +0 -0
  26. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/auto_memory.py +0 -0
  27. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/autonomy_mode.py +0 -0
  28. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/base.py +0 -0
  29. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/cost_tracker.py +0 -0
  30. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/external_agents.py +0 -0
  31. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/fast_context.py +0 -0
  32. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/flow_display.py +0 -0
  33. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/git_integration.py +0 -0
  34. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/guardrail.py +0 -0
  35. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/handoff.py +0 -0
  36. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/image.py +0 -0
  37. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/interactive_tui.py +0 -0
  38. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/knowledge.py +0 -0
  39. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/mcp.py +0 -0
  40. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/message_queue.py +0 -0
  41. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/metrics.py +0 -0
  42. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/n8n.py +0 -0
  43. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/repo_map.py +0 -0
  44. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/router.py +0 -0
  45. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/sandbox_executor.py +0 -0
  46. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/session.py +0 -0
  47. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/slash_commands.py +0 -0
  48. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/telemetry.py +0 -0
  49. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/todo.py +0 -0
  50. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/tools.py +0 -0
  51. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/features/workflow.py +0 -0
  52. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/cli/main.py +0 -0
  53. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/__init__.py +0 -0
  54. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/agent_tools.py +0 -0
  55. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/diff/__init__.py +0 -0
  56. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/diff/diff_strategy.py +0 -0
  57. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/tools/__init__.py +0 -0
  58. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/tools/apply_diff.py +0 -0
  59. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/tools/execute_command.py +0 -0
  60. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/tools/list_files.py +0 -0
  61. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/tools/read_file.py +0 -0
  62. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/tools/search_replace.py +0 -0
  63. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/tools/write_file.py +0 -0
  64. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/utils/__init__.py +0 -0
  65. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/utils/file_utils.py +0 -0
  66. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/utils/ignore_utils.py +0 -0
  67. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/code/utils/text_utils.py +0 -0
  68. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/inbuilt_tools/__init__.py +0 -0
  69. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/inbuilt_tools/autogen_tools.py +0 -0
  70. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/inc/__init__.py +0 -0
  71. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/inc/config.py +0 -0
  72. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/inc/models.py +0 -0
  73. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/integrations/__init__.py +0 -0
  74. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/integrations/base.py +0 -0
  75. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/integrations/claude_code.py +0 -0
  76. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/integrations/codex_cli.py +0 -0
  77. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/integrations/cursor_cli.py +0 -0
  78. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/integrations/gemini_cli.py +0 -0
  79. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/profiler.py +0 -0
  80. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/setup/__init__.py +0 -0
  81. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/setup/build.py +0 -0
  82. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/setup/post_install.py +0 -0
  83. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/setup/setup_conda_env.py +0 -0
  84. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/setup.py +0 -0
  85. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/test.py +0 -0
  86. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/train.py +0 -0
  87. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/train_vision.py +0 -0
  88. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/agents.py +0 -0
  89. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/callbacks.py +0 -0
  90. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/chat.py +0 -0
  91. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/code.py +0 -0
  92. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/colab.py +0 -0
  93. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/colab_chainlit.py +0 -0
  94. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/components/aicoder.py +0 -0
  95. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/context.py +0 -0
  96. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/database_config.py +0 -0
  97. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/db.py +0 -0
  98. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/realtime.py +0 -0
  99. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/realtimeclient/__init__.py +0 -0
  100. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/realtimeclient/tools.py +0 -0
  101. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/ui/sql_alchemy.py +0 -0
  102. {praisonai-2.3.63 → praisonai-2.3.64}/praisonai/upload_vision.py +0 -0
  103. {praisonai-2.3.63 → praisonai-2.3.64}/pyproject.toml +0 -0
  104. {praisonai-2.3.63 → praisonai-2.3.64}/setup.cfg +0 -0
  105. {praisonai-2.3.63 → praisonai-2.3.64}/tests/test.py +0 -0
  106. {praisonai-2.3.63 → praisonai-2.3.64}/tests/test_agents_playbook.py +0 -0
  107. {praisonai-2.3.63 → praisonai-2.3.64}/tests/test_approval_system.py +0 -0
  108. {praisonai-2.3.63 → praisonai-2.3.64}/tests/test_basic.py +0 -0
  109. {praisonai-2.3.63 → praisonai-2.3.64}/tests/test_cli_features.py +0 -0
  110. {praisonai-2.3.63 → praisonai-2.3.64}/tests/test_custom_tools_fix.py +0 -0
  111. {praisonai-2.3.63 → praisonai-2.3.64}/tests/test_double_api_fix.py +0 -0
  112. {praisonai-2.3.63 → praisonai-2.3.64}/tests/test_n8n_integration.py +0 -0
  113. {praisonai-2.3.63 → praisonai-2.3.64}/tests/test_phase2_refactor.py +0 -0
  114. {praisonai-2.3.63 → praisonai-2.3.64}/tests/test_runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PraisonAI
3
- Version: 2.3.63
3
+ Version: 2.3.64
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
@@ -363,6 +363,10 @@ npm install praisonai
363
363
  | ↳ Interactive TUI | [Example](examples/python/cli/interactive_tui_example.py) | [📖](https://docs.praison.ai/docs/cli/interactive-tui) |
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
+ | **⏰ 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) |
366
370
 
367
371
  ---
368
372
 
@@ -1339,6 +1343,35 @@ praisonai "Analyze this data" --metrics
1339
1343
  praisonai "Complex task" --metrics --planning
1340
1344
  ```
1341
1345
 
1346
+ ### Scheduler CLI:
1347
+ ```bash
1348
+ # Schedule an agent to run periodically (24/7 operation)
1349
+ praisonai schedule --interval hourly --task "Check latest AI news"
1350
+
1351
+ # Schedule with custom interval (every 30 minutes)
1352
+ praisonai schedule --interval "*/30m" --task "Monitor system status"
1353
+
1354
+ # Schedule with YAML config
1355
+ praisonai schedule --config scheduler_config.yaml
1356
+
1357
+ # Schedule with immediate execution
1358
+ praisonai schedule --interval daily --task "Generate report" --run-now
1359
+
1360
+ # Schedule with retry configuration
1361
+ praisonai schedule --interval "*/6h" --task "Collect data" --max-retries 5
1362
+
1363
+ # View scheduler help
1364
+ praisonai schedule --help
1365
+ ```
1366
+
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
1374
+
1342
1375
  ### Image Processing CLI:
1343
1376
  ```bash
1344
1377
  # Process images with vision-based tasks
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PraisonAI
3
- Version: 2.3.63
3
+ Version: 2.3.64
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
@@ -363,6 +363,10 @@ npm install praisonai
363
363
  | ↳ Interactive TUI | [Example](examples/python/cli/interactive_tui_example.py) | [📖](https://docs.praison.ai/docs/cli/interactive-tui) |
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
+ | **⏰ 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) |
366
370
 
367
371
  ---
368
372
 
@@ -1339,6 +1343,35 @@ praisonai "Analyze this data" --metrics
1339
1343
  praisonai "Complex task" --metrics --planning
1340
1344
  ```
1341
1345
 
1346
+ ### Scheduler CLI:
1347
+ ```bash
1348
+ # Schedule an agent to run periodically (24/7 operation)
1349
+ praisonai schedule --interval hourly --task "Check latest AI news"
1350
+
1351
+ # Schedule with custom interval (every 30 minutes)
1352
+ praisonai schedule --interval "*/30m" --task "Monitor system status"
1353
+
1354
+ # Schedule with YAML config
1355
+ praisonai schedule --config scheduler_config.yaml
1356
+
1357
+ # Schedule with immediate execution
1358
+ praisonai schedule --interval daily --task "Generate report" --run-now
1359
+
1360
+ # Schedule with retry configuration
1361
+ praisonai schedule --interval "*/6h" --task "Collect data" --max-retries 5
1362
+
1363
+ # View scheduler help
1364
+ praisonai schedule --help
1365
+ ```
1366
+
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
1374
+
1342
1375
  ### Image Processing CLI:
1343
1376
  ```bash
1344
1377
  # Process images with vision-based tasks
@@ -8,6 +8,7 @@ PraisonAI.egg-info/requires.txt
8
8
  PraisonAI.egg-info/top_level.txt
9
9
  praisonai/__init__.py
10
10
  praisonai/__main__.py
11
+ praisonai/agent_scheduler.py
11
12
  praisonai/agents_generator.py
12
13
  praisonai/auto.py
13
14
  praisonai/chainlit_ui.py
@@ -77,6 +78,9 @@ praisonai/integrations/claude_code.py
77
78
  praisonai/integrations/codex_cli.py
78
79
  praisonai/integrations/cursor_cli.py
79
80
  praisonai/integrations/gemini_cli.py
81
+ praisonai/scheduler/__init__.py
82
+ praisonai/scheduler/agent_scheduler.py
83
+ praisonai/scheduler/base.py
80
84
  praisonai/setup/__init__.py
81
85
  praisonai/setup/build.py
82
86
  praisonai/setup/post_install.py
@@ -266,6 +266,10 @@ npm install praisonai
266
266
  | ↳ Interactive TUI | [Example](examples/python/cli/interactive_tui_example.py) | [📖](https://docs.praison.ai/docs/cli/interactive-tui) |
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
+ | **⏰ 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) |
269
273
 
270
274
  ---
271
275
 
@@ -1242,6 +1246,35 @@ praisonai "Analyze this data" --metrics
1242
1246
  praisonai "Complex task" --metrics --planning
1243
1247
  ```
1244
1248
 
1249
+ ### Scheduler CLI:
1250
+ ```bash
1251
+ # Schedule an agent to run periodically (24/7 operation)
1252
+ praisonai schedule --interval hourly --task "Check latest AI news"
1253
+
1254
+ # Schedule with custom interval (every 30 minutes)
1255
+ praisonai schedule --interval "*/30m" --task "Monitor system status"
1256
+
1257
+ # Schedule with YAML config
1258
+ praisonai schedule --config scheduler_config.yaml
1259
+
1260
+ # Schedule with immediate execution
1261
+ praisonai schedule --interval daily --task "Generate report" --run-now
1262
+
1263
+ # Schedule with retry configuration
1264
+ praisonai schedule --interval "*/6h" --task "Collect data" --max-retries 5
1265
+
1266
+ # View scheduler help
1267
+ praisonai schedule --help
1268
+ ```
1269
+
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
1277
+
1245
1278
  ### Image Processing CLI:
1246
1279
  ```bash
1247
1280
  # Process images with vision-based tasks
@@ -0,0 +1,337 @@
1
+ """
2
+ Agent Scheduler for PraisonAI - Run agents periodically 24/7.
3
+
4
+ This module provides scheduling capabilities for running PraisonAI agents
5
+ at regular intervals, enabling 24/7 autonomous agent operations.
6
+
7
+ Example:
8
+ # Run news checker every hour
9
+ from praisonai.agent_scheduler import AgentScheduler
10
+ from praisonai_agents import Agent
11
+
12
+ agent = Agent(
13
+ name="NewsChecker",
14
+ instructions="Check latest AI news and summarize",
15
+ tools=[search_tool]
16
+ )
17
+
18
+ scheduler = AgentScheduler(agent, task="Check latest AI news")
19
+ scheduler.start(schedule_expr="hourly")
20
+ """
21
+
22
+ import threading
23
+ import time
24
+ import logging
25
+ from datetime import datetime
26
+ from typing import Optional, Dict, Any, Callable
27
+ from abc import ABC, abstractmethod
28
+
29
+ logger = logging.getLogger(__name__)
30
+
31
+
32
+ class ScheduleParser:
33
+ """Parse schedule expressions into intervals."""
34
+
35
+ @staticmethod
36
+ def parse(schedule_expr: str) -> int:
37
+ """
38
+ Parse schedule expression and return interval in seconds.
39
+
40
+ Supported formats:
41
+ - "daily" -> 86400 seconds
42
+ - "hourly" -> 3600 seconds
43
+ - "*/30m" -> 1800 seconds (every 30 minutes)
44
+ - "*/1h" -> 3600 seconds (every 1 hour)
45
+ - "60" -> 60 seconds (plain number)
46
+
47
+ Args:
48
+ schedule_expr: Schedule expression string
49
+
50
+ Returns:
51
+ Interval in seconds
52
+
53
+ Raises:
54
+ ValueError: If schedule format is not supported
55
+ """
56
+ schedule_expr = schedule_expr.strip().lower()
57
+
58
+ if schedule_expr == "daily":
59
+ return 86400
60
+ elif schedule_expr == "hourly":
61
+ return 3600
62
+ elif schedule_expr.isdigit():
63
+ return int(schedule_expr)
64
+ elif schedule_expr.startswith("*/"):
65
+ interval_part = schedule_expr[2:]
66
+ if interval_part.endswith("m"):
67
+ minutes = int(interval_part[:-1])
68
+ return minutes * 60
69
+ elif interval_part.endswith("h"):
70
+ hours = int(interval_part[:-1])
71
+ return hours * 3600
72
+ elif interval_part.endswith("s"):
73
+ return int(interval_part[:-1])
74
+ else:
75
+ return int(interval_part)
76
+ else:
77
+ raise ValueError(f"Unsupported schedule format: {schedule_expr}")
78
+
79
+
80
+ class AgentExecutorInterface(ABC):
81
+ """Abstract interface for agent execution."""
82
+
83
+ @abstractmethod
84
+ def execute(self, task: str) -> Any:
85
+ """Execute the agent with given task."""
86
+ pass
87
+
88
+
89
+ class PraisonAgentExecutor(AgentExecutorInterface):
90
+ """Executor for PraisonAI agents."""
91
+
92
+ def __init__(self, agent):
93
+ """
94
+ Initialize executor with a PraisonAI agent.
95
+
96
+ Args:
97
+ agent: PraisonAI Agent instance
98
+ """
99
+ self.agent = agent
100
+
101
+ def execute(self, task: str) -> Any:
102
+ """
103
+ Execute the agent with given task.
104
+
105
+ Args:
106
+ task: Task description for the agent
107
+
108
+ Returns:
109
+ Agent execution result
110
+ """
111
+ try:
112
+ result = self.agent.start(task)
113
+ return result
114
+ except Exception as e:
115
+ logger.error(f"Agent execution failed: {e}")
116
+ raise
117
+
118
+
119
+ class AgentScheduler:
120
+ """
121
+ Scheduler for running PraisonAI agents periodically.
122
+
123
+ Features:
124
+ - Interval-based scheduling (hourly, daily, custom)
125
+ - Thread-safe operation
126
+ - Automatic retry on failure
127
+ - Execution logging and monitoring
128
+ - Graceful shutdown
129
+
130
+ Example:
131
+ scheduler = AgentScheduler(agent, task="Check news")
132
+ scheduler.start(schedule_expr="hourly", max_retries=3)
133
+ # Agent runs every hour automatically
134
+ scheduler.stop() # Stop when needed
135
+ """
136
+
137
+ def __init__(
138
+ self,
139
+ agent,
140
+ task: str,
141
+ config: Optional[Dict[str, Any]] = None,
142
+ on_success: Optional[Callable] = None,
143
+ on_failure: Optional[Callable] = None
144
+ ):
145
+ """
146
+ Initialize agent scheduler.
147
+
148
+ Args:
149
+ agent: PraisonAI Agent instance
150
+ task: Task description to execute
151
+ config: Optional configuration dict
152
+ on_success: Callback function on successful execution
153
+ on_failure: Callback function on failed execution
154
+ """
155
+ self.agent = agent
156
+ self.task = task
157
+ self.config = config or {}
158
+ self.on_success = on_success
159
+ self.on_failure = on_failure
160
+
161
+ self.is_running = False
162
+ self._stop_event = threading.Event()
163
+ self._thread = None
164
+ self._executor = PraisonAgentExecutor(agent)
165
+ self._execution_count = 0
166
+ self._success_count = 0
167
+ self._failure_count = 0
168
+
169
+ def start(
170
+ self,
171
+ schedule_expr: str,
172
+ max_retries: int = 3,
173
+ run_immediately: bool = False
174
+ ) -> bool:
175
+ """
176
+ Start scheduled agent execution.
177
+
178
+ Args:
179
+ schedule_expr: Schedule expression (e.g., "hourly", "*/1h", "3600")
180
+ max_retries: Maximum retry attempts on failure
181
+ run_immediately: If True, run agent immediately before starting schedule
182
+
183
+ Returns:
184
+ True if scheduler started successfully
185
+ """
186
+ if self.is_running:
187
+ logger.warning("Scheduler is already running")
188
+ return False
189
+
190
+ try:
191
+ interval = ScheduleParser.parse(schedule_expr)
192
+ self.is_running = True
193
+ self._stop_event.clear()
194
+
195
+ logger.info(f"Starting agent scheduler: {self.agent.name if hasattr(self.agent, 'name') else 'Agent'}")
196
+ logger.info(f"Task: {self.task}")
197
+ logger.info(f"Schedule: {schedule_expr} ({interval}s interval)")
198
+ logger.info(f"Max retries: {max_retries}")
199
+
200
+ # Run immediately if requested
201
+ if run_immediately:
202
+ logger.info("Running agent immediately before starting schedule...")
203
+ self._execute_with_retry(max_retries)
204
+
205
+ self._thread = threading.Thread(
206
+ target=self._run_schedule,
207
+ args=(interval, max_retries),
208
+ daemon=True
209
+ )
210
+ self._thread.start()
211
+
212
+ logger.info("Agent scheduler started successfully")
213
+ return True
214
+
215
+ except Exception as e:
216
+ logger.error(f"Failed to start scheduler: {e}")
217
+ self.is_running = False
218
+ return False
219
+
220
+ def stop(self) -> bool:
221
+ """
222
+ Stop the scheduler gracefully.
223
+
224
+ Returns:
225
+ True if stopped successfully
226
+ """
227
+ if not self.is_running:
228
+ logger.info("Scheduler is not running")
229
+ return True
230
+
231
+ logger.info("Stopping agent scheduler...")
232
+ self._stop_event.set()
233
+
234
+ if self._thread and self._thread.is_alive():
235
+ self._thread.join(timeout=10)
236
+
237
+ self.is_running = False
238
+ logger.info("Agent scheduler stopped")
239
+ logger.info(f"Execution stats - Total: {self._execution_count}, Success: {self._success_count}, Failed: {self._failure_count}")
240
+ return True
241
+
242
+ def get_stats(self) -> Dict[str, Any]:
243
+ """
244
+ Get execution statistics.
245
+
246
+ Returns:
247
+ Dictionary with execution stats
248
+ """
249
+ return {
250
+ "is_running": self.is_running,
251
+ "total_executions": self._execution_count,
252
+ "successful_executions": self._success_count,
253
+ "failed_executions": self._failure_count,
254
+ "success_rate": (self._success_count / self._execution_count * 100) if self._execution_count > 0 else 0
255
+ }
256
+
257
+ def _run_schedule(self, interval: int, max_retries: int):
258
+ """Internal method to run scheduled agent executions."""
259
+ while not self._stop_event.is_set():
260
+ logger.info(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Starting scheduled agent execution")
261
+
262
+ self._execute_with_retry(max_retries)
263
+
264
+ # Wait for next scheduled time
265
+ logger.info(f"Next execution in {interval} seconds ({interval/3600:.1f} hours)")
266
+ self._stop_event.wait(interval)
267
+
268
+ def _execute_with_retry(self, max_retries: int):
269
+ """Execute agent with retry logic."""
270
+ self._execution_count += 1
271
+ success = False
272
+
273
+ for attempt in range(max_retries):
274
+ try:
275
+ logger.info(f"Attempt {attempt + 1}/{max_retries}")
276
+ result = self._executor.execute(self.task)
277
+
278
+ logger.info(f"Agent execution successful on attempt {attempt + 1}")
279
+ logger.info(f"Result: {result}")
280
+
281
+ self._success_count += 1
282
+ success = True
283
+
284
+ if self.on_success:
285
+ self.on_success(result)
286
+
287
+ break
288
+
289
+ except Exception as e:
290
+ logger.error(f"Agent execution failed on attempt {attempt + 1}: {e}")
291
+
292
+ if attempt < max_retries - 1:
293
+ wait_time = 30 * (attempt + 1) # Exponential backoff
294
+ logger.info(f"Waiting {wait_time}s before retry...")
295
+ time.sleep(wait_time)
296
+
297
+ if not success:
298
+ self._failure_count += 1
299
+ logger.error(f"Agent execution failed after {max_retries} attempts")
300
+
301
+ if self.on_failure:
302
+ self.on_failure(f"Failed after {max_retries} attempts")
303
+
304
+ def execute_once(self) -> Any:
305
+ """
306
+ Execute agent immediately (one-time execution).
307
+
308
+ Returns:
309
+ Agent execution result
310
+ """
311
+ logger.info("Executing agent once")
312
+ try:
313
+ result = self._executor.execute(self.task)
314
+ logger.info(f"One-time execution successful: {result}")
315
+ return result
316
+ except Exception as e:
317
+ logger.error(f"One-time execution failed: {e}")
318
+ raise
319
+
320
+
321
+ def create_agent_scheduler(
322
+ agent,
323
+ task: str,
324
+ config: Optional[Dict[str, Any]] = None
325
+ ) -> AgentScheduler:
326
+ """
327
+ Factory function to create agent scheduler.
328
+
329
+ Args:
330
+ agent: PraisonAI Agent instance
331
+ task: Task description
332
+ config: Optional configuration
333
+
334
+ Returns:
335
+ Configured AgentScheduler instance
336
+ """
337
+ return AgentScheduler(agent, task, config)
@@ -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.63 gunicorn markdown\n")
60
+ file.write("RUN pip install flask praisonai==2.3.64 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
 
@@ -0,0 +1,36 @@
1
+ """
2
+ PraisonAI Scheduler Module
3
+
4
+ This module provides scheduling capabilities for running agents and deployments
5
+ at regular intervals, enabling 24/7 autonomous operations.
6
+
7
+ Components:
8
+ - ScheduleParser: Parse schedule expressions (hourly, daily, */30m, etc.)
9
+ - ExecutorInterface: Abstract interface for executors
10
+ - AgentScheduler: Schedule agent execution at regular intervals
11
+ - DeploymentScheduler: Schedule deployment operations
12
+ """
13
+
14
+ from .base import ScheduleParser, ExecutorInterface, PraisonAgentExecutor
15
+
16
+ __all__ = [
17
+ 'ScheduleParser',
18
+ 'ExecutorInterface',
19
+ 'PraisonAgentExecutor',
20
+ ]
21
+
22
+ # Lazy imports for modules that will be created later
23
+ def __getattr__(name):
24
+ if name == 'AgentScheduler':
25
+ from .agent_scheduler import AgentScheduler
26
+ return AgentScheduler
27
+ elif name == 'create_agent_scheduler':
28
+ from .agent_scheduler import create_agent_scheduler
29
+ return create_agent_scheduler
30
+ elif name == 'DeploymentScheduler':
31
+ from .deployment_scheduler import DeploymentScheduler
32
+ return DeploymentScheduler
33
+ elif name == 'create_deployment_scheduler':
34
+ from .deployment_scheduler import create_deployment_scheduler
35
+ return create_deployment_scheduler
36
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")