PraisonAI 3.0.0__py3-none-any.whl
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.
- praisonai/__init__.py +54 -0
- praisonai/__main__.py +15 -0
- praisonai/acp/__init__.py +54 -0
- praisonai/acp/config.py +159 -0
- praisonai/acp/server.py +587 -0
- praisonai/acp/session.py +219 -0
- praisonai/adapters/__init__.py +50 -0
- praisonai/adapters/readers.py +395 -0
- praisonai/adapters/rerankers.py +315 -0
- praisonai/adapters/retrievers.py +394 -0
- praisonai/adapters/vector_stores.py +409 -0
- praisonai/agent_scheduler.py +337 -0
- praisonai/agents_generator.py +903 -0
- praisonai/api/call.py +292 -0
- praisonai/auto.py +1197 -0
- praisonai/capabilities/__init__.py +275 -0
- praisonai/capabilities/a2a.py +140 -0
- praisonai/capabilities/assistants.py +283 -0
- praisonai/capabilities/audio.py +320 -0
- praisonai/capabilities/batches.py +469 -0
- praisonai/capabilities/completions.py +336 -0
- praisonai/capabilities/container_files.py +155 -0
- praisonai/capabilities/containers.py +93 -0
- praisonai/capabilities/embeddings.py +158 -0
- praisonai/capabilities/files.py +467 -0
- praisonai/capabilities/fine_tuning.py +293 -0
- praisonai/capabilities/guardrails.py +182 -0
- praisonai/capabilities/images.py +330 -0
- praisonai/capabilities/mcp.py +190 -0
- praisonai/capabilities/messages.py +270 -0
- praisonai/capabilities/moderations.py +154 -0
- praisonai/capabilities/ocr.py +217 -0
- praisonai/capabilities/passthrough.py +204 -0
- praisonai/capabilities/rag.py +207 -0
- praisonai/capabilities/realtime.py +160 -0
- praisonai/capabilities/rerank.py +165 -0
- praisonai/capabilities/responses.py +266 -0
- praisonai/capabilities/search.py +109 -0
- praisonai/capabilities/skills.py +133 -0
- praisonai/capabilities/vector_store_files.py +334 -0
- praisonai/capabilities/vector_stores.py +304 -0
- praisonai/capabilities/videos.py +141 -0
- praisonai/chainlit_ui.py +304 -0
- praisonai/chat/__init__.py +106 -0
- praisonai/chat/app.py +125 -0
- praisonai/cli/__init__.py +26 -0
- praisonai/cli/app.py +213 -0
- praisonai/cli/commands/__init__.py +75 -0
- praisonai/cli/commands/acp.py +70 -0
- praisonai/cli/commands/completion.py +333 -0
- praisonai/cli/commands/config.py +166 -0
- praisonai/cli/commands/debug.py +142 -0
- praisonai/cli/commands/diag.py +55 -0
- praisonai/cli/commands/doctor.py +166 -0
- praisonai/cli/commands/environment.py +179 -0
- praisonai/cli/commands/lsp.py +112 -0
- praisonai/cli/commands/mcp.py +210 -0
- praisonai/cli/commands/profile.py +457 -0
- praisonai/cli/commands/run.py +228 -0
- praisonai/cli/commands/schedule.py +150 -0
- praisonai/cli/commands/serve.py +97 -0
- praisonai/cli/commands/session.py +212 -0
- praisonai/cli/commands/traces.py +145 -0
- praisonai/cli/commands/version.py +101 -0
- praisonai/cli/configuration/__init__.py +18 -0
- praisonai/cli/configuration/loader.py +353 -0
- praisonai/cli/configuration/paths.py +114 -0
- praisonai/cli/configuration/schema.py +164 -0
- praisonai/cli/features/__init__.py +268 -0
- praisonai/cli/features/acp.py +236 -0
- praisonai/cli/features/action_orchestrator.py +546 -0
- praisonai/cli/features/agent_scheduler.py +773 -0
- praisonai/cli/features/agent_tools.py +474 -0
- praisonai/cli/features/agents.py +375 -0
- praisonai/cli/features/at_mentions.py +471 -0
- praisonai/cli/features/auto_memory.py +182 -0
- praisonai/cli/features/autonomy_mode.py +490 -0
- praisonai/cli/features/background.py +356 -0
- praisonai/cli/features/base.py +168 -0
- praisonai/cli/features/capabilities.py +1326 -0
- praisonai/cli/features/checkpoints.py +338 -0
- praisonai/cli/features/code_intelligence.py +652 -0
- praisonai/cli/features/compaction.py +294 -0
- praisonai/cli/features/compare.py +534 -0
- praisonai/cli/features/cost_tracker.py +514 -0
- praisonai/cli/features/debug.py +810 -0
- praisonai/cli/features/deploy.py +517 -0
- praisonai/cli/features/diag.py +289 -0
- praisonai/cli/features/doctor/__init__.py +63 -0
- praisonai/cli/features/doctor/checks/__init__.py +24 -0
- praisonai/cli/features/doctor/checks/acp_checks.py +240 -0
- praisonai/cli/features/doctor/checks/config_checks.py +366 -0
- praisonai/cli/features/doctor/checks/db_checks.py +366 -0
- praisonai/cli/features/doctor/checks/env_checks.py +543 -0
- praisonai/cli/features/doctor/checks/lsp_checks.py +199 -0
- praisonai/cli/features/doctor/checks/mcp_checks.py +349 -0
- praisonai/cli/features/doctor/checks/memory_checks.py +268 -0
- praisonai/cli/features/doctor/checks/network_checks.py +251 -0
- praisonai/cli/features/doctor/checks/obs_checks.py +328 -0
- praisonai/cli/features/doctor/checks/performance_checks.py +235 -0
- praisonai/cli/features/doctor/checks/permissions_checks.py +259 -0
- praisonai/cli/features/doctor/checks/selftest_checks.py +322 -0
- praisonai/cli/features/doctor/checks/serve_checks.py +426 -0
- praisonai/cli/features/doctor/checks/skills_checks.py +231 -0
- praisonai/cli/features/doctor/checks/tools_checks.py +371 -0
- praisonai/cli/features/doctor/engine.py +266 -0
- praisonai/cli/features/doctor/formatters.py +310 -0
- praisonai/cli/features/doctor/handler.py +397 -0
- praisonai/cli/features/doctor/models.py +264 -0
- praisonai/cli/features/doctor/registry.py +239 -0
- praisonai/cli/features/endpoints.py +1019 -0
- praisonai/cli/features/eval.py +560 -0
- praisonai/cli/features/external_agents.py +231 -0
- praisonai/cli/features/fast_context.py +410 -0
- praisonai/cli/features/flow_display.py +566 -0
- praisonai/cli/features/git_integration.py +651 -0
- praisonai/cli/features/guardrail.py +171 -0
- praisonai/cli/features/handoff.py +185 -0
- praisonai/cli/features/hooks.py +583 -0
- praisonai/cli/features/image.py +384 -0
- praisonai/cli/features/interactive_runtime.py +585 -0
- praisonai/cli/features/interactive_tools.py +380 -0
- praisonai/cli/features/interactive_tui.py +603 -0
- praisonai/cli/features/jobs.py +632 -0
- praisonai/cli/features/knowledge.py +531 -0
- praisonai/cli/features/lite.py +244 -0
- praisonai/cli/features/lsp_cli.py +225 -0
- praisonai/cli/features/mcp.py +169 -0
- praisonai/cli/features/message_queue.py +587 -0
- praisonai/cli/features/metrics.py +211 -0
- praisonai/cli/features/n8n.py +673 -0
- praisonai/cli/features/observability.py +293 -0
- praisonai/cli/features/ollama.py +361 -0
- praisonai/cli/features/output_style.py +273 -0
- praisonai/cli/features/package.py +631 -0
- praisonai/cli/features/performance.py +308 -0
- praisonai/cli/features/persistence.py +636 -0
- praisonai/cli/features/profile.py +226 -0
- praisonai/cli/features/profiler/__init__.py +81 -0
- praisonai/cli/features/profiler/core.py +558 -0
- praisonai/cli/features/profiler/optimizations.py +652 -0
- praisonai/cli/features/profiler/suite.py +386 -0
- praisonai/cli/features/profiling.py +350 -0
- praisonai/cli/features/queue/__init__.py +73 -0
- praisonai/cli/features/queue/manager.py +395 -0
- praisonai/cli/features/queue/models.py +286 -0
- praisonai/cli/features/queue/persistence.py +564 -0
- praisonai/cli/features/queue/scheduler.py +484 -0
- praisonai/cli/features/queue/worker.py +372 -0
- praisonai/cli/features/recipe.py +1723 -0
- praisonai/cli/features/recipes.py +449 -0
- praisonai/cli/features/registry.py +229 -0
- praisonai/cli/features/repo_map.py +860 -0
- praisonai/cli/features/router.py +466 -0
- praisonai/cli/features/sandbox_executor.py +515 -0
- praisonai/cli/features/serve.py +829 -0
- praisonai/cli/features/session.py +222 -0
- praisonai/cli/features/skills.py +856 -0
- praisonai/cli/features/slash_commands.py +650 -0
- praisonai/cli/features/telemetry.py +179 -0
- praisonai/cli/features/templates.py +1384 -0
- praisonai/cli/features/thinking.py +305 -0
- praisonai/cli/features/todo.py +334 -0
- praisonai/cli/features/tools.py +680 -0
- praisonai/cli/features/tui/__init__.py +83 -0
- praisonai/cli/features/tui/app.py +580 -0
- praisonai/cli/features/tui/cli.py +566 -0
- praisonai/cli/features/tui/debug.py +511 -0
- praisonai/cli/features/tui/events.py +99 -0
- praisonai/cli/features/tui/mock_provider.py +328 -0
- praisonai/cli/features/tui/orchestrator.py +652 -0
- praisonai/cli/features/tui/screens/__init__.py +50 -0
- praisonai/cli/features/tui/screens/main.py +245 -0
- praisonai/cli/features/tui/screens/queue.py +174 -0
- praisonai/cli/features/tui/screens/session.py +124 -0
- praisonai/cli/features/tui/screens/settings.py +148 -0
- praisonai/cli/features/tui/widgets/__init__.py +56 -0
- praisonai/cli/features/tui/widgets/chat.py +261 -0
- praisonai/cli/features/tui/widgets/composer.py +224 -0
- praisonai/cli/features/tui/widgets/queue_panel.py +200 -0
- praisonai/cli/features/tui/widgets/status.py +167 -0
- praisonai/cli/features/tui/widgets/tool_panel.py +248 -0
- praisonai/cli/features/workflow.py +720 -0
- praisonai/cli/legacy.py +236 -0
- praisonai/cli/main.py +5559 -0
- praisonai/cli/schedule_cli.py +54 -0
- praisonai/cli/state/__init__.py +31 -0
- praisonai/cli/state/identifiers.py +161 -0
- praisonai/cli/state/sessions.py +313 -0
- praisonai/code/__init__.py +93 -0
- praisonai/code/agent_tools.py +344 -0
- praisonai/code/diff/__init__.py +21 -0
- praisonai/code/diff/diff_strategy.py +432 -0
- praisonai/code/tools/__init__.py +27 -0
- praisonai/code/tools/apply_diff.py +221 -0
- praisonai/code/tools/execute_command.py +275 -0
- praisonai/code/tools/list_files.py +274 -0
- praisonai/code/tools/read_file.py +206 -0
- praisonai/code/tools/search_replace.py +248 -0
- praisonai/code/tools/write_file.py +217 -0
- praisonai/code/utils/__init__.py +46 -0
- praisonai/code/utils/file_utils.py +307 -0
- praisonai/code/utils/ignore_utils.py +308 -0
- praisonai/code/utils/text_utils.py +276 -0
- praisonai/db/__init__.py +64 -0
- praisonai/db/adapter.py +531 -0
- praisonai/deploy/__init__.py +62 -0
- praisonai/deploy/api.py +231 -0
- praisonai/deploy/docker.py +454 -0
- praisonai/deploy/doctor.py +367 -0
- praisonai/deploy/main.py +327 -0
- praisonai/deploy/models.py +179 -0
- praisonai/deploy/providers/__init__.py +33 -0
- praisonai/deploy/providers/aws.py +331 -0
- praisonai/deploy/providers/azure.py +358 -0
- praisonai/deploy/providers/base.py +101 -0
- praisonai/deploy/providers/gcp.py +314 -0
- praisonai/deploy/schema.py +208 -0
- praisonai/deploy.py +185 -0
- praisonai/endpoints/__init__.py +53 -0
- praisonai/endpoints/a2u_server.py +410 -0
- praisonai/endpoints/discovery.py +165 -0
- praisonai/endpoints/providers/__init__.py +28 -0
- praisonai/endpoints/providers/a2a.py +253 -0
- praisonai/endpoints/providers/a2u.py +208 -0
- praisonai/endpoints/providers/agents_api.py +171 -0
- praisonai/endpoints/providers/base.py +231 -0
- praisonai/endpoints/providers/mcp.py +263 -0
- praisonai/endpoints/providers/recipe.py +206 -0
- praisonai/endpoints/providers/tools_mcp.py +150 -0
- praisonai/endpoints/registry.py +131 -0
- praisonai/endpoints/server.py +161 -0
- praisonai/inbuilt_tools/__init__.py +24 -0
- praisonai/inbuilt_tools/autogen_tools.py +117 -0
- praisonai/inc/__init__.py +2 -0
- praisonai/inc/config.py +96 -0
- praisonai/inc/models.py +155 -0
- praisonai/integrations/__init__.py +56 -0
- praisonai/integrations/base.py +303 -0
- praisonai/integrations/claude_code.py +270 -0
- praisonai/integrations/codex_cli.py +255 -0
- praisonai/integrations/cursor_cli.py +195 -0
- praisonai/integrations/gemini_cli.py +222 -0
- praisonai/jobs/__init__.py +67 -0
- praisonai/jobs/executor.py +425 -0
- praisonai/jobs/models.py +230 -0
- praisonai/jobs/router.py +314 -0
- praisonai/jobs/server.py +186 -0
- praisonai/jobs/store.py +203 -0
- praisonai/llm/__init__.py +66 -0
- praisonai/llm/registry.py +382 -0
- praisonai/mcp_server/__init__.py +152 -0
- praisonai/mcp_server/adapters/__init__.py +74 -0
- praisonai/mcp_server/adapters/agents.py +128 -0
- praisonai/mcp_server/adapters/capabilities.py +168 -0
- praisonai/mcp_server/adapters/cli_tools.py +568 -0
- praisonai/mcp_server/adapters/extended_capabilities.py +462 -0
- praisonai/mcp_server/adapters/knowledge.py +93 -0
- praisonai/mcp_server/adapters/memory.py +104 -0
- praisonai/mcp_server/adapters/prompts.py +306 -0
- praisonai/mcp_server/adapters/resources.py +124 -0
- praisonai/mcp_server/adapters/tools_bridge.py +280 -0
- praisonai/mcp_server/auth/__init__.py +48 -0
- praisonai/mcp_server/auth/api_key.py +291 -0
- praisonai/mcp_server/auth/oauth.py +460 -0
- praisonai/mcp_server/auth/oidc.py +289 -0
- praisonai/mcp_server/auth/scopes.py +260 -0
- praisonai/mcp_server/cli.py +852 -0
- praisonai/mcp_server/elicitation.py +445 -0
- praisonai/mcp_server/icons.py +302 -0
- praisonai/mcp_server/recipe_adapter.py +573 -0
- praisonai/mcp_server/recipe_cli.py +824 -0
- praisonai/mcp_server/registry.py +703 -0
- praisonai/mcp_server/sampling.py +422 -0
- praisonai/mcp_server/server.py +490 -0
- praisonai/mcp_server/tasks.py +443 -0
- praisonai/mcp_server/transports/__init__.py +18 -0
- praisonai/mcp_server/transports/http_stream.py +376 -0
- praisonai/mcp_server/transports/stdio.py +132 -0
- praisonai/persistence/__init__.py +84 -0
- praisonai/persistence/config.py +238 -0
- praisonai/persistence/conversation/__init__.py +25 -0
- praisonai/persistence/conversation/async_mysql.py +427 -0
- praisonai/persistence/conversation/async_postgres.py +410 -0
- praisonai/persistence/conversation/async_sqlite.py +371 -0
- praisonai/persistence/conversation/base.py +151 -0
- praisonai/persistence/conversation/json_store.py +250 -0
- praisonai/persistence/conversation/mysql.py +387 -0
- praisonai/persistence/conversation/postgres.py +401 -0
- praisonai/persistence/conversation/singlestore.py +240 -0
- praisonai/persistence/conversation/sqlite.py +341 -0
- praisonai/persistence/conversation/supabase.py +203 -0
- praisonai/persistence/conversation/surrealdb.py +287 -0
- praisonai/persistence/factory.py +301 -0
- praisonai/persistence/hooks/__init__.py +18 -0
- praisonai/persistence/hooks/agent_hooks.py +297 -0
- praisonai/persistence/knowledge/__init__.py +26 -0
- praisonai/persistence/knowledge/base.py +144 -0
- praisonai/persistence/knowledge/cassandra.py +232 -0
- praisonai/persistence/knowledge/chroma.py +295 -0
- praisonai/persistence/knowledge/clickhouse.py +242 -0
- praisonai/persistence/knowledge/cosmosdb_vector.py +438 -0
- praisonai/persistence/knowledge/couchbase.py +286 -0
- praisonai/persistence/knowledge/lancedb.py +216 -0
- praisonai/persistence/knowledge/langchain_adapter.py +291 -0
- praisonai/persistence/knowledge/lightrag_adapter.py +212 -0
- praisonai/persistence/knowledge/llamaindex_adapter.py +256 -0
- praisonai/persistence/knowledge/milvus.py +277 -0
- praisonai/persistence/knowledge/mongodb_vector.py +306 -0
- praisonai/persistence/knowledge/pgvector.py +335 -0
- praisonai/persistence/knowledge/pinecone.py +253 -0
- praisonai/persistence/knowledge/qdrant.py +301 -0
- praisonai/persistence/knowledge/redis_vector.py +291 -0
- praisonai/persistence/knowledge/singlestore_vector.py +299 -0
- praisonai/persistence/knowledge/surrealdb_vector.py +309 -0
- praisonai/persistence/knowledge/upstash_vector.py +266 -0
- praisonai/persistence/knowledge/weaviate.py +223 -0
- praisonai/persistence/migrations/__init__.py +10 -0
- praisonai/persistence/migrations/manager.py +251 -0
- praisonai/persistence/orchestrator.py +406 -0
- praisonai/persistence/state/__init__.py +21 -0
- praisonai/persistence/state/async_mongodb.py +200 -0
- praisonai/persistence/state/base.py +107 -0
- praisonai/persistence/state/dynamodb.py +226 -0
- praisonai/persistence/state/firestore.py +175 -0
- praisonai/persistence/state/gcs.py +155 -0
- praisonai/persistence/state/memory.py +245 -0
- praisonai/persistence/state/mongodb.py +158 -0
- praisonai/persistence/state/redis.py +190 -0
- praisonai/persistence/state/upstash.py +144 -0
- praisonai/persistence/tests/__init__.py +3 -0
- praisonai/persistence/tests/test_all_backends.py +633 -0
- praisonai/profiler.py +1214 -0
- praisonai/recipe/__init__.py +134 -0
- praisonai/recipe/bridge.py +278 -0
- praisonai/recipe/core.py +893 -0
- praisonai/recipe/exceptions.py +54 -0
- praisonai/recipe/history.py +402 -0
- praisonai/recipe/models.py +266 -0
- praisonai/recipe/operations.py +440 -0
- praisonai/recipe/policy.py +422 -0
- praisonai/recipe/registry.py +849 -0
- praisonai/recipe/runtime.py +214 -0
- praisonai/recipe/security.py +711 -0
- praisonai/recipe/serve.py +859 -0
- praisonai/recipe/server.py +613 -0
- praisonai/scheduler/__init__.py +45 -0
- praisonai/scheduler/agent_scheduler.py +552 -0
- praisonai/scheduler/base.py +124 -0
- praisonai/scheduler/daemon_manager.py +225 -0
- praisonai/scheduler/state_manager.py +155 -0
- praisonai/scheduler/yaml_loader.py +193 -0
- praisonai/scheduler.py +194 -0
- praisonai/setup/__init__.py +1 -0
- praisonai/setup/build.py +21 -0
- praisonai/setup/post_install.py +23 -0
- praisonai/setup/setup_conda_env.py +25 -0
- praisonai/setup.py +16 -0
- praisonai/templates/__init__.py +116 -0
- praisonai/templates/cache.py +364 -0
- praisonai/templates/dependency_checker.py +358 -0
- praisonai/templates/discovery.py +391 -0
- praisonai/templates/loader.py +564 -0
- praisonai/templates/registry.py +511 -0
- praisonai/templates/resolver.py +206 -0
- praisonai/templates/security.py +327 -0
- praisonai/templates/tool_override.py +498 -0
- praisonai/templates/tools_doctor.py +256 -0
- praisonai/test.py +105 -0
- praisonai/train.py +562 -0
- praisonai/train_vision.py +306 -0
- praisonai/ui/agents.py +824 -0
- praisonai/ui/callbacks.py +57 -0
- praisonai/ui/chainlit_compat.py +246 -0
- praisonai/ui/chat.py +532 -0
- praisonai/ui/code.py +717 -0
- praisonai/ui/colab.py +474 -0
- praisonai/ui/colab_chainlit.py +81 -0
- praisonai/ui/components/aicoder.py +284 -0
- praisonai/ui/context.py +283 -0
- praisonai/ui/database_config.py +56 -0
- praisonai/ui/db.py +294 -0
- praisonai/ui/realtime.py +488 -0
- praisonai/ui/realtimeclient/__init__.py +756 -0
- praisonai/ui/realtimeclient/tools.py +242 -0
- praisonai/ui/sql_alchemy.py +710 -0
- praisonai/upload_vision.py +140 -0
- praisonai/version.py +1 -0
- praisonai-3.0.0.dist-info/METADATA +3493 -0
- praisonai-3.0.0.dist-info/RECORD +393 -0
- praisonai-3.0.0.dist-info/WHEEL +5 -0
- praisonai-3.0.0.dist-info/entry_points.txt +4 -0
- praisonai-3.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Background Agents CLI Feature for PraisonAI.
|
|
3
|
+
|
|
4
|
+
Provides CLI commands for managing background agent tasks.
|
|
5
|
+
|
|
6
|
+
Commands:
|
|
7
|
+
- praisonai background list # List background tasks
|
|
8
|
+
- praisonai background status <id> # Get task status
|
|
9
|
+
- praisonai background cancel <id> # Cancel a task
|
|
10
|
+
- praisonai background clear # Clear completed tasks
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import asyncio
|
|
14
|
+
from typing import Optional, List
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BackgroundHandler:
|
|
18
|
+
"""
|
|
19
|
+
Handler for background CLI commands.
|
|
20
|
+
|
|
21
|
+
Provides functionality to:
|
|
22
|
+
- List running and completed background tasks
|
|
23
|
+
- Check task status
|
|
24
|
+
- Cancel running tasks
|
|
25
|
+
- Clear completed tasks
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, verbose: bool = False):
|
|
29
|
+
self.verbose = verbose
|
|
30
|
+
self._runner = None
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def feature_name(self) -> str:
|
|
34
|
+
return "background"
|
|
35
|
+
|
|
36
|
+
async def _get_runner(self):
|
|
37
|
+
"""Lazy load the background runner."""
|
|
38
|
+
if self._runner is None:
|
|
39
|
+
from praisonaiagents.background import BackgroundRunner
|
|
40
|
+
self._runner = BackgroundRunner()
|
|
41
|
+
return self._runner
|
|
42
|
+
|
|
43
|
+
async def list_tasks(self, status: Optional[str] = None) -> List[dict]:
|
|
44
|
+
"""
|
|
45
|
+
List all background tasks.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
status: Optional status filter (pending, running, completed, failed)
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
List of task dictionaries
|
|
52
|
+
"""
|
|
53
|
+
runner = await self._get_runner()
|
|
54
|
+
|
|
55
|
+
status_enum = None
|
|
56
|
+
if status:
|
|
57
|
+
from praisonaiagents.background import TaskStatus
|
|
58
|
+
status_map = {
|
|
59
|
+
"pending": TaskStatus.PENDING,
|
|
60
|
+
"running": TaskStatus.RUNNING,
|
|
61
|
+
"completed": TaskStatus.COMPLETED,
|
|
62
|
+
"failed": TaskStatus.FAILED,
|
|
63
|
+
"cancelled": TaskStatus.CANCELLED
|
|
64
|
+
}
|
|
65
|
+
status_enum = status_map.get(status.lower())
|
|
66
|
+
|
|
67
|
+
tasks = runner.list_tasks(status=status_enum)
|
|
68
|
+
|
|
69
|
+
self._print_tasks_table(tasks)
|
|
70
|
+
return tasks
|
|
71
|
+
|
|
72
|
+
def _print_tasks_table(self, tasks: List[dict]):
|
|
73
|
+
"""Print tasks in table format."""
|
|
74
|
+
try:
|
|
75
|
+
from rich.console import Console
|
|
76
|
+
from rich.table import Table
|
|
77
|
+
|
|
78
|
+
console = Console()
|
|
79
|
+
|
|
80
|
+
if not tasks:
|
|
81
|
+
console.print("[yellow]No background tasks[/yellow]")
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
table = Table(title="Background Tasks")
|
|
85
|
+
table.add_column("ID", style="cyan")
|
|
86
|
+
table.add_column("Name", style="green")
|
|
87
|
+
table.add_column("Status", style="yellow")
|
|
88
|
+
table.add_column("Progress", style="blue")
|
|
89
|
+
table.add_column("Duration", style="magenta")
|
|
90
|
+
|
|
91
|
+
for task in tasks:
|
|
92
|
+
status = task.get("status", "unknown")
|
|
93
|
+
status_color = {
|
|
94
|
+
"pending": "dim",
|
|
95
|
+
"running": "yellow",
|
|
96
|
+
"completed": "green",
|
|
97
|
+
"failed": "red",
|
|
98
|
+
"cancelled": "dim"
|
|
99
|
+
}.get(status, "white")
|
|
100
|
+
|
|
101
|
+
progress = f"{task.get('progress', 0) * 100:.0f}%"
|
|
102
|
+
duration = task.get("duration_seconds")
|
|
103
|
+
duration_str = f"{duration:.1f}s" if duration else "-"
|
|
104
|
+
|
|
105
|
+
table.add_row(
|
|
106
|
+
task.get("id", "?"),
|
|
107
|
+
task.get("name", "unnamed"),
|
|
108
|
+
f"[{status_color}]{status}[/{status_color}]",
|
|
109
|
+
progress,
|
|
110
|
+
duration_str
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
console.print(table)
|
|
114
|
+
except ImportError:
|
|
115
|
+
print("Background Tasks:")
|
|
116
|
+
for task in tasks:
|
|
117
|
+
print(f" {task.get('id')} - {task.get('name')} ({task.get('status')})")
|
|
118
|
+
|
|
119
|
+
async def get_status(self, task_id: str) -> Optional[dict]:
|
|
120
|
+
"""
|
|
121
|
+
Get status of a specific task.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
task_id: Task ID
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
Task dictionary or None
|
|
128
|
+
"""
|
|
129
|
+
runner = await self._get_runner()
|
|
130
|
+
task = runner.get_task(task_id)
|
|
131
|
+
|
|
132
|
+
if task is None:
|
|
133
|
+
self._print_error(f"Task not found: {task_id}")
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
task_dict = task.to_dict()
|
|
137
|
+
self._print_task_details(task_dict)
|
|
138
|
+
return task_dict
|
|
139
|
+
|
|
140
|
+
def _print_task_details(self, task: dict):
|
|
141
|
+
"""Print detailed task information."""
|
|
142
|
+
try:
|
|
143
|
+
from rich.console import Console
|
|
144
|
+
from rich.panel import Panel
|
|
145
|
+
|
|
146
|
+
console = Console()
|
|
147
|
+
|
|
148
|
+
status = task.get("status", "unknown")
|
|
149
|
+
status_color = {
|
|
150
|
+
"pending": "dim",
|
|
151
|
+
"running": "yellow",
|
|
152
|
+
"completed": "green",
|
|
153
|
+
"failed": "red",
|
|
154
|
+
"cancelled": "dim"
|
|
155
|
+
}.get(status, "white")
|
|
156
|
+
|
|
157
|
+
content = f"""
|
|
158
|
+
[bold]ID:[/bold] {task.get('id')}
|
|
159
|
+
[bold]Name:[/bold] {task.get('name')}
|
|
160
|
+
[bold]Status:[/bold] [{status_color}]{status}[/{status_color}]
|
|
161
|
+
[bold]Progress:[/bold] {task.get('progress', 0) * 100:.0f}%
|
|
162
|
+
[bold]Created:[/bold] {task.get('created_at')}
|
|
163
|
+
[bold]Started:[/bold] {task.get('started_at') or '-'}
|
|
164
|
+
[bold]Completed:[/bold] {task.get('completed_at') or '-'}
|
|
165
|
+
[bold]Duration:[/bold] {task.get('duration_seconds', 0):.2f}s
|
|
166
|
+
"""
|
|
167
|
+
if task.get("error"):
|
|
168
|
+
content += f"[bold]Error:[/bold] [red]{task.get('error')}[/red]\n"
|
|
169
|
+
|
|
170
|
+
if task.get("result"):
|
|
171
|
+
result_str = str(task.get("result"))[:200]
|
|
172
|
+
content += f"[bold]Result:[/bold] {result_str}\n"
|
|
173
|
+
|
|
174
|
+
console.print(Panel(content.strip(), title=f"Task: {task.get('name')}"))
|
|
175
|
+
except ImportError:
|
|
176
|
+
print(f"Task: {task.get('name')}")
|
|
177
|
+
print(f" ID: {task.get('id')}")
|
|
178
|
+
print(f" Status: {task.get('status')}")
|
|
179
|
+
print(f" Progress: {task.get('progress', 0) * 100:.0f}%")
|
|
180
|
+
|
|
181
|
+
async def cancel_task(self, task_id: str) -> bool:
|
|
182
|
+
"""
|
|
183
|
+
Cancel a running task.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
task_id: Task ID to cancel
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
True if cancelled
|
|
190
|
+
"""
|
|
191
|
+
runner = await self._get_runner()
|
|
192
|
+
result = await runner.cancel_task(task_id)
|
|
193
|
+
|
|
194
|
+
if result:
|
|
195
|
+
self._print_success(f"Task cancelled: {task_id}")
|
|
196
|
+
else:
|
|
197
|
+
self._print_error(f"Could not cancel task: {task_id}")
|
|
198
|
+
|
|
199
|
+
return result
|
|
200
|
+
|
|
201
|
+
async def clear_completed(self) -> int:
|
|
202
|
+
"""
|
|
203
|
+
Clear all completed tasks.
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
Number of tasks cleared
|
|
207
|
+
"""
|
|
208
|
+
runner = await self._get_runner()
|
|
209
|
+
count = len([t for t in runner.tasks if t.is_completed])
|
|
210
|
+
runner.clear_completed()
|
|
211
|
+
|
|
212
|
+
self._print_success(f"Cleared {count} completed tasks")
|
|
213
|
+
return count
|
|
214
|
+
|
|
215
|
+
def _print_success(self, message: str):
|
|
216
|
+
"""Print success message."""
|
|
217
|
+
try:
|
|
218
|
+
from rich.console import Console
|
|
219
|
+
Console().print(f"[green]✓[/green] {message}")
|
|
220
|
+
except ImportError:
|
|
221
|
+
print(f"✓ {message}")
|
|
222
|
+
|
|
223
|
+
def _print_error(self, message: str):
|
|
224
|
+
"""Print error message."""
|
|
225
|
+
try:
|
|
226
|
+
from rich.console import Console
|
|
227
|
+
Console().print(f"[red]✗[/red] {message}")
|
|
228
|
+
except ImportError:
|
|
229
|
+
print(f"✗ {message}")
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def handle_background_command(args: List[str], verbose: bool = False):
|
|
233
|
+
"""
|
|
234
|
+
Handle background CLI commands.
|
|
235
|
+
|
|
236
|
+
Usage:
|
|
237
|
+
praisonai background list [--status <status>] [--json] [--page N] [--page-size N]
|
|
238
|
+
praisonai background status <task_id> [--json]
|
|
239
|
+
praisonai background cancel <task_id> [--json]
|
|
240
|
+
praisonai background clear [--all] [--older-than SEC] [--json]
|
|
241
|
+
praisonai background submit --recipe <name> [--input JSON] [--session-id ID] [--timeout SEC] [--json]
|
|
242
|
+
"""
|
|
243
|
+
import argparse
|
|
244
|
+
import json
|
|
245
|
+
|
|
246
|
+
parser = argparse.ArgumentParser(prog="praisonai background", description="Manage background tasks")
|
|
247
|
+
subparsers = parser.add_subparsers(dest="subcommand", help="Available commands")
|
|
248
|
+
|
|
249
|
+
# List command
|
|
250
|
+
list_parser = subparsers.add_parser("list", help="List background tasks")
|
|
251
|
+
list_parser.add_argument("--status", choices=["pending", "running", "completed", "failed", "cancelled"], help="Filter by status")
|
|
252
|
+
list_parser.add_argument("--json", dest="output_json", action="store_true", help="Output JSON")
|
|
253
|
+
list_parser.add_argument("--page", type=int, default=1, help="Page number")
|
|
254
|
+
list_parser.add_argument("--page-size", type=int, default=20, help="Tasks per page")
|
|
255
|
+
|
|
256
|
+
# Status command
|
|
257
|
+
status_parser = subparsers.add_parser("status", help="Get task status")
|
|
258
|
+
status_parser.add_argument("task_id", help="Task ID")
|
|
259
|
+
status_parser.add_argument("--json", dest="output_json", action="store_true", help="Output JSON")
|
|
260
|
+
|
|
261
|
+
# Cancel command
|
|
262
|
+
cancel_parser = subparsers.add_parser("cancel", help="Cancel a task")
|
|
263
|
+
cancel_parser.add_argument("task_id", help="Task ID")
|
|
264
|
+
cancel_parser.add_argument("--json", dest="output_json", action="store_true", help="Output JSON")
|
|
265
|
+
|
|
266
|
+
# Clear command
|
|
267
|
+
clear_parser = subparsers.add_parser("clear", help="Clear completed tasks")
|
|
268
|
+
clear_parser.add_argument("--all", action="store_true", help="Clear all tasks including running")
|
|
269
|
+
clear_parser.add_argument("--older-than", type=int, help="Clear tasks older than N seconds")
|
|
270
|
+
clear_parser.add_argument("--json", dest="output_json", action="store_true", help="Output JSON")
|
|
271
|
+
|
|
272
|
+
# Submit command (NEW - for recipe background submission)
|
|
273
|
+
submit_parser = subparsers.add_parser("submit", help="Submit a recipe as background task")
|
|
274
|
+
submit_parser.add_argument("--recipe", required=True, dest="recipe_name", help="Recipe name to execute")
|
|
275
|
+
submit_parser.add_argument("--input", "-i", dest="input_data", help="Input data as JSON string")
|
|
276
|
+
submit_parser.add_argument("--config", "-c", help="Config overrides as JSON string")
|
|
277
|
+
submit_parser.add_argument("--session-id", "-s", help="Session ID for conversation continuity")
|
|
278
|
+
submit_parser.add_argument("--timeout", type=int, default=300, help="Timeout in seconds (default: 300)")
|
|
279
|
+
submit_parser.add_argument("--json", dest="output_json", action="store_true", help="Output JSON")
|
|
280
|
+
|
|
281
|
+
if not args:
|
|
282
|
+
parser.print_help()
|
|
283
|
+
return
|
|
284
|
+
|
|
285
|
+
# Handle legacy help
|
|
286
|
+
if args[0] in ["help", "--help", "-h"]:
|
|
287
|
+
parser.print_help()
|
|
288
|
+
return
|
|
289
|
+
|
|
290
|
+
parsed = parser.parse_args(args)
|
|
291
|
+
|
|
292
|
+
if not parsed.subcommand:
|
|
293
|
+
parser.print_help()
|
|
294
|
+
return
|
|
295
|
+
|
|
296
|
+
handler = BackgroundHandler(verbose=verbose)
|
|
297
|
+
|
|
298
|
+
try:
|
|
299
|
+
if parsed.subcommand == "list":
|
|
300
|
+
asyncio.run(handler.list_tasks(status=parsed.status))
|
|
301
|
+
|
|
302
|
+
elif parsed.subcommand == "status":
|
|
303
|
+
asyncio.run(handler.get_status(parsed.task_id))
|
|
304
|
+
|
|
305
|
+
elif parsed.subcommand == "cancel":
|
|
306
|
+
asyncio.run(handler.cancel_task(parsed.task_id))
|
|
307
|
+
|
|
308
|
+
elif parsed.subcommand == "clear":
|
|
309
|
+
asyncio.run(handler.clear_completed())
|
|
310
|
+
|
|
311
|
+
elif parsed.subcommand == "submit":
|
|
312
|
+
# Parse input and config
|
|
313
|
+
input_data = None
|
|
314
|
+
if parsed.input_data:
|
|
315
|
+
try:
|
|
316
|
+
input_data = json.loads(parsed.input_data)
|
|
317
|
+
except json.JSONDecodeError:
|
|
318
|
+
input_data = {"input": parsed.input_data}
|
|
319
|
+
|
|
320
|
+
config = None
|
|
321
|
+
if parsed.config:
|
|
322
|
+
try:
|
|
323
|
+
config = json.loads(parsed.config)
|
|
324
|
+
except json.JSONDecodeError:
|
|
325
|
+
print("Error: --config must be valid JSON")
|
|
326
|
+
return
|
|
327
|
+
|
|
328
|
+
# Submit recipe as background task
|
|
329
|
+
from praisonai.recipe.operations import run_background
|
|
330
|
+
|
|
331
|
+
task = run_background(
|
|
332
|
+
parsed.recipe_name,
|
|
333
|
+
input=input_data,
|
|
334
|
+
config=config,
|
|
335
|
+
session_id=parsed.session_id,
|
|
336
|
+
timeout_sec=parsed.timeout,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
if parsed.output_json:
|
|
340
|
+
print(json.dumps({
|
|
341
|
+
"ok": True,
|
|
342
|
+
"task_id": task.task_id,
|
|
343
|
+
"recipe": task.recipe_name,
|
|
344
|
+
"session_id": task.session_id,
|
|
345
|
+
}))
|
|
346
|
+
else:
|
|
347
|
+
print(f"✓ Recipe '{parsed.recipe_name}' submitted to background")
|
|
348
|
+
print(f" Task ID: {task.task_id}")
|
|
349
|
+
print(f" Session: {task.session_id}")
|
|
350
|
+
print(f"\nCheck status with: praisonai background status {task.task_id}")
|
|
351
|
+
|
|
352
|
+
except Exception as e:
|
|
353
|
+
if getattr(parsed, 'output_json', False):
|
|
354
|
+
print(json.dumps({"ok": False, "error": str(e)}))
|
|
355
|
+
else:
|
|
356
|
+
print(f"✗ Error: {e}")
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base handler class for CLI features.
|
|
3
|
+
|
|
4
|
+
All CLI feature handlers inherit from this base class to ensure
|
|
5
|
+
consistent interface and behavior.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from typing import Any, Dict, List
|
|
10
|
+
import logging
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BaseHandler(ABC):
|
|
16
|
+
"""
|
|
17
|
+
Base class for all CLI feature handlers.
|
|
18
|
+
|
|
19
|
+
Provides common functionality and interface for feature handlers.
|
|
20
|
+
Each handler is responsible for a specific CLI feature.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, verbose: bool = False):
|
|
24
|
+
"""
|
|
25
|
+
Initialize the handler.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
verbose: Enable verbose output
|
|
29
|
+
"""
|
|
30
|
+
self.verbose = verbose
|
|
31
|
+
self._initialized = False
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def feature_name(self) -> str:
|
|
36
|
+
"""Return the name of this feature."""
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def is_available(self) -> bool:
|
|
41
|
+
"""Check if the feature dependencies are available."""
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
def log(self, message: str, level: str = "info"):
|
|
45
|
+
"""Log a message if verbose mode is enabled."""
|
|
46
|
+
if self.verbose:
|
|
47
|
+
getattr(logger, level)(f"[{self.feature_name}] {message}")
|
|
48
|
+
|
|
49
|
+
def print_status(self, message: str, status: str = "info"):
|
|
50
|
+
"""Print a status message with color coding."""
|
|
51
|
+
from rich import print as rprint
|
|
52
|
+
|
|
53
|
+
colors = {
|
|
54
|
+
"info": "cyan",
|
|
55
|
+
"success": "green",
|
|
56
|
+
"warning": "yellow",
|
|
57
|
+
"error": "red"
|
|
58
|
+
}
|
|
59
|
+
color = colors.get(status, "white")
|
|
60
|
+
rprint(f"[{color}]{message}[/{color}]")
|
|
61
|
+
|
|
62
|
+
def check_dependencies(self) -> tuple[bool, str]:
|
|
63
|
+
"""
|
|
64
|
+
Check if required dependencies are installed.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Tuple of (available, error_message)
|
|
68
|
+
"""
|
|
69
|
+
return True, ""
|
|
70
|
+
|
|
71
|
+
@abstractmethod
|
|
72
|
+
def execute(self, *args, **kwargs) -> Any:
|
|
73
|
+
"""
|
|
74
|
+
Execute the feature's main functionality.
|
|
75
|
+
|
|
76
|
+
This method must be implemented by each handler.
|
|
77
|
+
"""
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class CommandHandler(BaseHandler):
|
|
82
|
+
"""
|
|
83
|
+
Base class for CLI command handlers (e.g., 'praisonai knowledge').
|
|
84
|
+
|
|
85
|
+
Command handlers process subcommands like:
|
|
86
|
+
- praisonai <command> <action> [args]
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
@abstractmethod
|
|
90
|
+
def get_actions(self) -> List[str]:
|
|
91
|
+
"""Return list of supported actions for this command."""
|
|
92
|
+
pass
|
|
93
|
+
|
|
94
|
+
def get_help_text(self) -> str:
|
|
95
|
+
"""Return help text for this command."""
|
|
96
|
+
return f"Available actions: {', '.join(self.get_actions())}"
|
|
97
|
+
|
|
98
|
+
def execute(self, action: str, action_args: List[str], **kwargs) -> Any:
|
|
99
|
+
"""
|
|
100
|
+
Execute a command action.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
action: The action to perform
|
|
104
|
+
action_args: Arguments for the action
|
|
105
|
+
**kwargs: Additional keyword arguments
|
|
106
|
+
"""
|
|
107
|
+
if action == 'help' or action == '--help':
|
|
108
|
+
self.print_help()
|
|
109
|
+
return
|
|
110
|
+
|
|
111
|
+
method_name = f"action_{action.replace('-', '_')}"
|
|
112
|
+
if hasattr(self, method_name):
|
|
113
|
+
return getattr(self, method_name)(action_args, **kwargs)
|
|
114
|
+
else:
|
|
115
|
+
self.print_status(f"Unknown action: {action}", "error")
|
|
116
|
+
self.print_help()
|
|
117
|
+
|
|
118
|
+
def print_help(self):
|
|
119
|
+
"""Print help for this command."""
|
|
120
|
+
from rich import print as rprint
|
|
121
|
+
rprint(f"[bold]{self.feature_name.title()} Commands:[/bold]")
|
|
122
|
+
rprint(self.get_help_text())
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class FlagHandler(BaseHandler):
|
|
126
|
+
"""
|
|
127
|
+
Base class for CLI flag handlers (e.g., '--guardrail').
|
|
128
|
+
|
|
129
|
+
Flag handlers modify agent behavior or add functionality
|
|
130
|
+
when a specific flag is provided.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
@abstractmethod
|
|
135
|
+
def flag_name(self) -> str:
|
|
136
|
+
"""Return the flag name (without --)."""
|
|
137
|
+
pass
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def flag_help(self) -> str:
|
|
141
|
+
"""Return help text for this flag."""
|
|
142
|
+
return f"Enable {self.feature_name}"
|
|
143
|
+
|
|
144
|
+
def apply_to_agent_config(self, config: Dict[str, Any], flag_value: Any) -> Dict[str, Any]:
|
|
145
|
+
"""
|
|
146
|
+
Apply this flag's configuration to an agent config.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
config: The agent configuration dictionary
|
|
150
|
+
flag_value: The value of the flag
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
Modified agent configuration
|
|
154
|
+
"""
|
|
155
|
+
return config
|
|
156
|
+
|
|
157
|
+
def post_process_result(self, result: Any, flag_value: Any) -> Any:
|
|
158
|
+
"""
|
|
159
|
+
Post-process the agent result.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
result: The agent's output
|
|
163
|
+
flag_value: The value of the flag
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
Processed result
|
|
167
|
+
"""
|
|
168
|
+
return result
|