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,566 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI Commands for PraisonAI TUI and Queue.
|
|
3
|
+
|
|
4
|
+
Provides Typer-based CLI commands for:
|
|
5
|
+
- praison tui - Launch interactive TUI
|
|
6
|
+
- praison run - Execute single task
|
|
7
|
+
- praison queue ls/cancel/retry/clear
|
|
8
|
+
- praison session ls/resume
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import sys
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
import typer
|
|
19
|
+
from rich.console import Console
|
|
20
|
+
from rich.table import Table
|
|
21
|
+
from rich.panel import Panel
|
|
22
|
+
TYPER_AVAILABLE = True
|
|
23
|
+
except ImportError:
|
|
24
|
+
TYPER_AVAILABLE = False
|
|
25
|
+
typer = None
|
|
26
|
+
|
|
27
|
+
console = Console() if TYPER_AVAILABLE else None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def create_tui_app():
|
|
31
|
+
"""Create the TUI CLI app."""
|
|
32
|
+
if not TYPER_AVAILABLE:
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
app = typer.Typer(
|
|
36
|
+
name="tui",
|
|
37
|
+
help="PraisonAI TUI and Queue commands",
|
|
38
|
+
no_args_is_help=True,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
@app.command("launch")
|
|
42
|
+
def tui_launch(
|
|
43
|
+
workspace: Optional[str] = typer.Option(
|
|
44
|
+
None, "--workspace", "-w",
|
|
45
|
+
help="Workspace directory"
|
|
46
|
+
),
|
|
47
|
+
session: Optional[str] = typer.Option(
|
|
48
|
+
None, "--session", "-s",
|
|
49
|
+
help="Resume session ID"
|
|
50
|
+
),
|
|
51
|
+
model: Optional[str] = typer.Option(
|
|
52
|
+
None, "--model", "-m",
|
|
53
|
+
help="Default model"
|
|
54
|
+
),
|
|
55
|
+
agent: Optional[str] = typer.Option(
|
|
56
|
+
None, "--agent", "-a",
|
|
57
|
+
help="Agent config file (YAML)"
|
|
58
|
+
),
|
|
59
|
+
no_acp: bool = typer.Option(
|
|
60
|
+
False, "--no-acp",
|
|
61
|
+
help="Disable ACP tools (file operations with plan/approve/apply)"
|
|
62
|
+
),
|
|
63
|
+
no_lsp: bool = typer.Option(
|
|
64
|
+
False, "--no-lsp",
|
|
65
|
+
help="Disable LSP tools (code intelligence: symbols, definitions)"
|
|
66
|
+
),
|
|
67
|
+
):
|
|
68
|
+
"""Launch the interactive TUI with ACP + LSP tools enabled by default."""
|
|
69
|
+
try:
|
|
70
|
+
from .app import run_tui
|
|
71
|
+
except ImportError:
|
|
72
|
+
console.print(
|
|
73
|
+
"[red]Textual is required for TUI. Install with:[/red]\n"
|
|
74
|
+
" pip install praisonai[tui]"
|
|
75
|
+
)
|
|
76
|
+
raise typer.Exit(1)
|
|
77
|
+
|
|
78
|
+
# Load agent config if provided
|
|
79
|
+
agent_config = {}
|
|
80
|
+
if agent:
|
|
81
|
+
import yaml
|
|
82
|
+
with open(agent, "r") as f:
|
|
83
|
+
agent_config = yaml.safe_load(f)
|
|
84
|
+
|
|
85
|
+
run_tui(
|
|
86
|
+
workspace=workspace,
|
|
87
|
+
session_id=session,
|
|
88
|
+
model=model,
|
|
89
|
+
agent_config=agent_config,
|
|
90
|
+
enable_acp=not no_acp,
|
|
91
|
+
enable_lsp=not no_lsp,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
return app
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def create_queue_app():
|
|
98
|
+
"""Create the queue CLI app."""
|
|
99
|
+
if not TYPER_AVAILABLE:
|
|
100
|
+
return None
|
|
101
|
+
|
|
102
|
+
app = typer.Typer(
|
|
103
|
+
name="queue",
|
|
104
|
+
help="Queue management commands",
|
|
105
|
+
no_args_is_help=True,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
@app.command("ls")
|
|
109
|
+
def queue_ls(
|
|
110
|
+
state: Optional[str] = typer.Option(
|
|
111
|
+
None, "--state", "-s",
|
|
112
|
+
help="Filter by state (queued, running, succeeded, failed, cancelled)"
|
|
113
|
+
),
|
|
114
|
+
session: Optional[str] = typer.Option(
|
|
115
|
+
None, "--session",
|
|
116
|
+
help="Filter by session ID"
|
|
117
|
+
),
|
|
118
|
+
limit: int = typer.Option(
|
|
119
|
+
20, "--limit", "-n",
|
|
120
|
+
help="Maximum number of results"
|
|
121
|
+
),
|
|
122
|
+
json_output: bool = typer.Option(
|
|
123
|
+
False, "--json", "-j",
|
|
124
|
+
help="Output as JSON"
|
|
125
|
+
),
|
|
126
|
+
):
|
|
127
|
+
"""List queued runs."""
|
|
128
|
+
from ..queue import QueuePersistence, RunState
|
|
129
|
+
|
|
130
|
+
persistence = QueuePersistence()
|
|
131
|
+
persistence.initialize()
|
|
132
|
+
|
|
133
|
+
# Parse state filter
|
|
134
|
+
state_filter = None
|
|
135
|
+
if state:
|
|
136
|
+
try:
|
|
137
|
+
state_filter = RunState(state.lower())
|
|
138
|
+
except ValueError:
|
|
139
|
+
console.print(f"[red]Invalid state: {state}[/red]")
|
|
140
|
+
raise typer.Exit(1)
|
|
141
|
+
|
|
142
|
+
runs = persistence.list_runs(
|
|
143
|
+
state=state_filter,
|
|
144
|
+
session_id=session,
|
|
145
|
+
limit=limit,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
if json_output:
|
|
149
|
+
output = [r.to_dict() for r in runs]
|
|
150
|
+
console.print(json.dumps(output, indent=2, default=str))
|
|
151
|
+
return
|
|
152
|
+
|
|
153
|
+
if not runs:
|
|
154
|
+
console.print("[dim]No runs found.[/dim]")
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
# Create table
|
|
158
|
+
table = Table(title="Queue Runs")
|
|
159
|
+
table.add_column("ID", style="cyan")
|
|
160
|
+
table.add_column("Agent", style="green")
|
|
161
|
+
table.add_column("Input", max_width=30)
|
|
162
|
+
table.add_column("State", style="yellow")
|
|
163
|
+
table.add_column("Priority")
|
|
164
|
+
table.add_column("Wait", style="dim")
|
|
165
|
+
table.add_column("Duration", style="dim")
|
|
166
|
+
|
|
167
|
+
for run in runs:
|
|
168
|
+
state_style = {
|
|
169
|
+
"queued": "yellow",
|
|
170
|
+
"running": "green",
|
|
171
|
+
"succeeded": "cyan",
|
|
172
|
+
"failed": "red",
|
|
173
|
+
"cancelled": "dim",
|
|
174
|
+
}.get(run.state.value, "")
|
|
175
|
+
|
|
176
|
+
input_preview = run.input_content[:27] + "..." if len(run.input_content) > 30 else run.input_content
|
|
177
|
+
|
|
178
|
+
table.add_row(
|
|
179
|
+
run.run_id[:8],
|
|
180
|
+
run.agent_name,
|
|
181
|
+
input_preview,
|
|
182
|
+
f"[{state_style}]{run.state.value}[/{state_style}]",
|
|
183
|
+
run.priority.name.lower(),
|
|
184
|
+
f"{run.wait_seconds:.1f}s" if run.wait_seconds else "-",
|
|
185
|
+
f"{run.duration_seconds:.1f}s" if run.duration_seconds else "-",
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
console.print(table)
|
|
189
|
+
persistence.close()
|
|
190
|
+
|
|
191
|
+
@app.command("cancel")
|
|
192
|
+
def queue_cancel(
|
|
193
|
+
run_id: str = typer.Argument(..., help="Run ID to cancel"),
|
|
194
|
+
):
|
|
195
|
+
"""Cancel a queued or running run."""
|
|
196
|
+
from ..queue import QueuePersistence, RunState
|
|
197
|
+
|
|
198
|
+
persistence = QueuePersistence()
|
|
199
|
+
persistence.initialize()
|
|
200
|
+
|
|
201
|
+
# Find the run
|
|
202
|
+
run = persistence.load_run(run_id)
|
|
203
|
+
if not run:
|
|
204
|
+
# Try partial match
|
|
205
|
+
runs = persistence.list_runs(limit=100)
|
|
206
|
+
matches = [r for r in runs if r.run_id.startswith(run_id)]
|
|
207
|
+
if len(matches) == 1:
|
|
208
|
+
run = matches[0]
|
|
209
|
+
elif len(matches) > 1:
|
|
210
|
+
console.print(f"[yellow]Multiple matches for '{run_id}':[/yellow]")
|
|
211
|
+
for r in matches:
|
|
212
|
+
console.print(f" {r.run_id}")
|
|
213
|
+
raise typer.Exit(1)
|
|
214
|
+
else:
|
|
215
|
+
console.print(f"[red]Run not found: {run_id}[/red]")
|
|
216
|
+
raise typer.Exit(1)
|
|
217
|
+
|
|
218
|
+
if run.state.is_terminal():
|
|
219
|
+
console.print(f"[yellow]Run {run.run_id[:8]} is already {run.state.value}[/yellow]")
|
|
220
|
+
raise typer.Exit(1)
|
|
221
|
+
|
|
222
|
+
# Update state
|
|
223
|
+
persistence.update_run_state(run.run_id, RunState.CANCELLED)
|
|
224
|
+
console.print(f"[green]Cancelled run: {run.run_id[:8]}[/green]")
|
|
225
|
+
persistence.close()
|
|
226
|
+
|
|
227
|
+
@app.command("retry")
|
|
228
|
+
def queue_retry(
|
|
229
|
+
run_id: str = typer.Argument(..., help="Run ID to retry"),
|
|
230
|
+
):
|
|
231
|
+
"""Retry a failed run."""
|
|
232
|
+
from ..queue import QueuePersistence, QueuedRun, RunState
|
|
233
|
+
import uuid
|
|
234
|
+
|
|
235
|
+
persistence = QueuePersistence()
|
|
236
|
+
persistence.initialize()
|
|
237
|
+
|
|
238
|
+
# Find the run
|
|
239
|
+
run = persistence.load_run(run_id)
|
|
240
|
+
if not run:
|
|
241
|
+
runs = persistence.list_runs(limit=100)
|
|
242
|
+
matches = [r for r in runs if r.run_id.startswith(run_id)]
|
|
243
|
+
if len(matches) == 1:
|
|
244
|
+
run = matches[0]
|
|
245
|
+
else:
|
|
246
|
+
console.print(f"[red]Run not found: {run_id}[/red]")
|
|
247
|
+
raise typer.Exit(1)
|
|
248
|
+
|
|
249
|
+
if run.state != RunState.FAILED:
|
|
250
|
+
console.print(f"[yellow]Can only retry failed runs (current: {run.state.value})[/yellow]")
|
|
251
|
+
raise typer.Exit(1)
|
|
252
|
+
|
|
253
|
+
if run.retry_count >= run.max_retries:
|
|
254
|
+
console.print(f"[yellow]Max retries reached ({run.retry_count}/{run.max_retries})[/yellow]")
|
|
255
|
+
raise typer.Exit(1)
|
|
256
|
+
|
|
257
|
+
# Create new run
|
|
258
|
+
new_run = QueuedRun(
|
|
259
|
+
run_id=str(uuid.uuid4())[:8],
|
|
260
|
+
agent_name=run.agent_name,
|
|
261
|
+
input_content=run.input_content,
|
|
262
|
+
state=RunState.QUEUED,
|
|
263
|
+
priority=run.priority,
|
|
264
|
+
session_id=run.session_id,
|
|
265
|
+
workspace=run.workspace,
|
|
266
|
+
retry_count=run.retry_count + 1,
|
|
267
|
+
max_retries=run.max_retries,
|
|
268
|
+
parent_run_id=run.run_id,
|
|
269
|
+
config=run.config,
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
persistence.save_run(new_run)
|
|
273
|
+
console.print(f"[green]Created retry run: {new_run.run_id} (from {run.run_id[:8]})[/green]")
|
|
274
|
+
persistence.close()
|
|
275
|
+
|
|
276
|
+
@app.command("clear")
|
|
277
|
+
def queue_clear(
|
|
278
|
+
force: bool = typer.Option(
|
|
279
|
+
False, "--force", "-f",
|
|
280
|
+
help="Skip confirmation"
|
|
281
|
+
),
|
|
282
|
+
):
|
|
283
|
+
"""Clear all queued runs."""
|
|
284
|
+
from ..queue import QueuePersistence, RunState
|
|
285
|
+
|
|
286
|
+
if not force:
|
|
287
|
+
confirm = typer.confirm("Clear all queued runs?")
|
|
288
|
+
if not confirm:
|
|
289
|
+
raise typer.Abort()
|
|
290
|
+
|
|
291
|
+
persistence = QueuePersistence()
|
|
292
|
+
persistence.initialize()
|
|
293
|
+
|
|
294
|
+
# Get queued runs
|
|
295
|
+
runs = persistence.list_runs(state=RunState.QUEUED, limit=1000)
|
|
296
|
+
|
|
297
|
+
count = 0
|
|
298
|
+
for run in runs:
|
|
299
|
+
persistence.update_run_state(run.run_id, RunState.CANCELLED)
|
|
300
|
+
count += 1
|
|
301
|
+
|
|
302
|
+
console.print(f"[green]Cleared {count} queued runs[/green]")
|
|
303
|
+
persistence.close()
|
|
304
|
+
|
|
305
|
+
@app.command("stats")
|
|
306
|
+
def queue_stats(
|
|
307
|
+
session: Optional[str] = typer.Option(
|
|
308
|
+
None, "--session",
|
|
309
|
+
help="Filter by session ID"
|
|
310
|
+
),
|
|
311
|
+
):
|
|
312
|
+
"""Show queue statistics."""
|
|
313
|
+
from ..queue import QueuePersistence
|
|
314
|
+
|
|
315
|
+
persistence = QueuePersistence()
|
|
316
|
+
persistence.initialize()
|
|
317
|
+
|
|
318
|
+
stats = persistence.get_stats(session)
|
|
319
|
+
|
|
320
|
+
console.print(Panel(
|
|
321
|
+
f"""
|
|
322
|
+
[bold]Queue Statistics[/bold]
|
|
323
|
+
|
|
324
|
+
Queued: {stats.queued_count}
|
|
325
|
+
Running: {stats.running_count}
|
|
326
|
+
Succeeded: {stats.succeeded_count}
|
|
327
|
+
Failed: {stats.failed_count}
|
|
328
|
+
Cancelled: {stats.cancelled_count}
|
|
329
|
+
|
|
330
|
+
Total Runs: {stats.total_runs}
|
|
331
|
+
Avg Wait: {stats.avg_wait_seconds:.1f}s
|
|
332
|
+
Avg Duration: {stats.avg_duration_seconds:.1f}s
|
|
333
|
+
""",
|
|
334
|
+
title="Queue Stats"
|
|
335
|
+
))
|
|
336
|
+
persistence.close()
|
|
337
|
+
|
|
338
|
+
return app
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def create_session_app():
|
|
342
|
+
"""Create the session CLI app."""
|
|
343
|
+
if not TYPER_AVAILABLE:
|
|
344
|
+
return None
|
|
345
|
+
|
|
346
|
+
app = typer.Typer(
|
|
347
|
+
name="session",
|
|
348
|
+
help="Session management commands",
|
|
349
|
+
no_args_is_help=True,
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
@app.command("ls")
|
|
353
|
+
def session_ls(
|
|
354
|
+
limit: int = typer.Option(
|
|
355
|
+
20, "--limit", "-n",
|
|
356
|
+
help="Maximum number of results"
|
|
357
|
+
),
|
|
358
|
+
):
|
|
359
|
+
"""List recent sessions."""
|
|
360
|
+
from ..queue import QueuePersistence
|
|
361
|
+
from datetime import datetime
|
|
362
|
+
|
|
363
|
+
persistence = QueuePersistence()
|
|
364
|
+
persistence.initialize()
|
|
365
|
+
|
|
366
|
+
sessions = persistence.list_sessions(limit=limit)
|
|
367
|
+
|
|
368
|
+
if not sessions:
|
|
369
|
+
console.print("[dim]No sessions found.[/dim]")
|
|
370
|
+
return
|
|
371
|
+
|
|
372
|
+
table = Table(title="Sessions")
|
|
373
|
+
table.add_column("ID", style="cyan")
|
|
374
|
+
table.add_column("User")
|
|
375
|
+
table.add_column("Created", style="dim")
|
|
376
|
+
table.add_column("Updated", style="dim")
|
|
377
|
+
|
|
378
|
+
for session in sessions:
|
|
379
|
+
created = datetime.fromtimestamp(session["created_at"]).strftime("%Y-%m-%d %H:%M")
|
|
380
|
+
updated = datetime.fromtimestamp(session["updated_at"]).strftime("%Y-%m-%d %H:%M")
|
|
381
|
+
|
|
382
|
+
table.add_row(
|
|
383
|
+
session["session_id"][:8],
|
|
384
|
+
session.get("user_id", "-"),
|
|
385
|
+
created,
|
|
386
|
+
updated,
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
console.print(table)
|
|
390
|
+
persistence.close()
|
|
391
|
+
|
|
392
|
+
@app.command("resume")
|
|
393
|
+
def session_resume(
|
|
394
|
+
session_id: str = typer.Argument(..., help="Session ID to resume"),
|
|
395
|
+
):
|
|
396
|
+
"""Resume a session in TUI."""
|
|
397
|
+
try:
|
|
398
|
+
from .app import run_tui
|
|
399
|
+
except ImportError:
|
|
400
|
+
console.print(
|
|
401
|
+
"[red]Textual is required for TUI. Install with:[/red]\n"
|
|
402
|
+
" pip install praisonai[tui]"
|
|
403
|
+
)
|
|
404
|
+
raise typer.Exit(1)
|
|
405
|
+
|
|
406
|
+
run_tui(session_id=session_id)
|
|
407
|
+
|
|
408
|
+
return app
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def create_run_command():
|
|
412
|
+
"""Create the run command."""
|
|
413
|
+
if not TYPER_AVAILABLE:
|
|
414
|
+
return None
|
|
415
|
+
|
|
416
|
+
def run_command(
|
|
417
|
+
prompt: str = typer.Argument(..., help="Prompt to execute"),
|
|
418
|
+
agent: Optional[str] = typer.Option(
|
|
419
|
+
None, "--agent", "-a",
|
|
420
|
+
help="Agent config file (YAML)"
|
|
421
|
+
),
|
|
422
|
+
model: Optional[str] = typer.Option(
|
|
423
|
+
None, "--model", "-m",
|
|
424
|
+
help="Model to use"
|
|
425
|
+
),
|
|
426
|
+
stream: bool = typer.Option(
|
|
427
|
+
True, "--stream/--no-stream",
|
|
428
|
+
help="Stream output"
|
|
429
|
+
),
|
|
430
|
+
priority: str = typer.Option(
|
|
431
|
+
"normal", "--priority", "-p",
|
|
432
|
+
help="Run priority (low, normal, high, urgent)"
|
|
433
|
+
),
|
|
434
|
+
):
|
|
435
|
+
"""Run a single agent task."""
|
|
436
|
+
from ..queue import QueueManager, QueueConfig, RunPriority
|
|
437
|
+
|
|
438
|
+
# Parse priority
|
|
439
|
+
try:
|
|
440
|
+
run_priority = RunPriority.from_string(priority)
|
|
441
|
+
except (ValueError, KeyError):
|
|
442
|
+
console.print(f"[red]Invalid priority: {priority}[/red]")
|
|
443
|
+
raise typer.Exit(1)
|
|
444
|
+
|
|
445
|
+
# Load agent config
|
|
446
|
+
agent_config = {}
|
|
447
|
+
if agent:
|
|
448
|
+
import yaml
|
|
449
|
+
with open(agent, "r") as f:
|
|
450
|
+
agent_config = yaml.safe_load(f)
|
|
451
|
+
|
|
452
|
+
# Set model
|
|
453
|
+
if model:
|
|
454
|
+
agent_config["model"] = model
|
|
455
|
+
|
|
456
|
+
async def execute():
|
|
457
|
+
output_chunks = []
|
|
458
|
+
|
|
459
|
+
async def on_output(run_id: str, chunk: str):
|
|
460
|
+
output_chunks.append(chunk)
|
|
461
|
+
if stream:
|
|
462
|
+
console.print(chunk, end="")
|
|
463
|
+
|
|
464
|
+
async def on_complete(run_id: str, run):
|
|
465
|
+
if not stream:
|
|
466
|
+
console.print(run.output_content or "".join(output_chunks))
|
|
467
|
+
|
|
468
|
+
async def on_error(run_id: str, error: Exception):
|
|
469
|
+
console.print(f"\n[red]Error: {error}[/red]")
|
|
470
|
+
|
|
471
|
+
config = QueueConfig(enable_persistence=False)
|
|
472
|
+
manager = QueueManager(
|
|
473
|
+
config=config,
|
|
474
|
+
on_output=on_output,
|
|
475
|
+
on_complete=on_complete,
|
|
476
|
+
on_error=on_error,
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
await manager.start(recover=False)
|
|
480
|
+
|
|
481
|
+
try:
|
|
482
|
+
run_id = await manager.submit(
|
|
483
|
+
input_content=prompt,
|
|
484
|
+
agent_name=agent_config.get("name", "Assistant"),
|
|
485
|
+
priority=run_priority,
|
|
486
|
+
config={"agent_config": agent_config},
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
# Wait for completion
|
|
490
|
+
while True:
|
|
491
|
+
run = manager.get_run(run_id)
|
|
492
|
+
if run and run.state.is_terminal():
|
|
493
|
+
break
|
|
494
|
+
await asyncio.sleep(0.1)
|
|
495
|
+
|
|
496
|
+
if stream:
|
|
497
|
+
console.print() # Newline after streaming
|
|
498
|
+
|
|
499
|
+
finally:
|
|
500
|
+
await manager.stop()
|
|
501
|
+
|
|
502
|
+
asyncio.run(execute())
|
|
503
|
+
|
|
504
|
+
return run_command
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
# Main CLI integration
|
|
508
|
+
def register_tui_commands(app):
|
|
509
|
+
"""Register TUI commands with the main CLI app."""
|
|
510
|
+
if not TYPER_AVAILABLE:
|
|
511
|
+
return
|
|
512
|
+
|
|
513
|
+
tui_app = create_tui_app()
|
|
514
|
+
queue_app = create_queue_app()
|
|
515
|
+
session_app = create_session_app()
|
|
516
|
+
run_cmd = create_run_command()
|
|
517
|
+
|
|
518
|
+
if tui_app:
|
|
519
|
+
app.add_typer(tui_app, name="tui")
|
|
520
|
+
if queue_app:
|
|
521
|
+
app.add_typer(queue_app, name="queue")
|
|
522
|
+
if session_app:
|
|
523
|
+
app.add_typer(session_app, name="session")
|
|
524
|
+
if run_cmd:
|
|
525
|
+
app.command("run")(run_cmd)
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
# Standalone entry point
|
|
529
|
+
def main():
|
|
530
|
+
"""Main entry point for TUI CLI."""
|
|
531
|
+
if not TYPER_AVAILABLE:
|
|
532
|
+
print("Typer is required. Install with: pip install typer")
|
|
533
|
+
sys.exit(1)
|
|
534
|
+
|
|
535
|
+
app = typer.Typer(
|
|
536
|
+
name="praison-tui",
|
|
537
|
+
help="PraisonAI TUI and Queue CLI",
|
|
538
|
+
)
|
|
539
|
+
|
|
540
|
+
register_tui_commands(app)
|
|
541
|
+
|
|
542
|
+
# Add direct tui command
|
|
543
|
+
@app.callback(invoke_without_command=True)
|
|
544
|
+
def default(
|
|
545
|
+
ctx: typer.Context,
|
|
546
|
+
workspace: Optional[str] = typer.Option(None, "--workspace", "-w"),
|
|
547
|
+
session: Optional[str] = typer.Option(None, "--session", "-s"),
|
|
548
|
+
model: Optional[str] = typer.Option(None, "--model", "-m"),
|
|
549
|
+
):
|
|
550
|
+
"""Launch TUI if no subcommand given."""
|
|
551
|
+
if ctx.invoked_subcommand is None:
|
|
552
|
+
try:
|
|
553
|
+
from .app import run_tui
|
|
554
|
+
run_tui(workspace=workspace, session_id=session, model=model)
|
|
555
|
+
except ImportError:
|
|
556
|
+
console.print(
|
|
557
|
+
"[red]Textual is required for TUI. Install with:[/red]\n"
|
|
558
|
+
" pip install praisonai[tui]"
|
|
559
|
+
)
|
|
560
|
+
raise typer.Exit(1)
|
|
561
|
+
|
|
562
|
+
app()
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
if __name__ == "__main__":
|
|
566
|
+
main()
|