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
|
+
Flow Display Handler for CLI.
|
|
3
|
+
|
|
4
|
+
Shows a visual flow diagram of the workflow WITHOUT executing it.
|
|
5
|
+
Usage: praisonai agents.yaml --flow-display
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any, Dict, Tuple
|
|
9
|
+
from .base import FlagHandler
|
|
10
|
+
import os
|
|
11
|
+
import yaml
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FlowDisplayHandler(FlagHandler):
|
|
15
|
+
"""
|
|
16
|
+
Handler for --flow-display flag.
|
|
17
|
+
|
|
18
|
+
Shows a visual flow diagram/chart of agents and tasks WITHOUT executing.
|
|
19
|
+
This allows users to preview the workflow structure before running it.
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
praisonai agents.yaml --flow-display
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, verbose: bool = False):
|
|
26
|
+
super().__init__(verbose)
|
|
27
|
+
self._console = None
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def feature_name(self) -> str:
|
|
31
|
+
return "flow_display"
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def flag_name(self) -> str:
|
|
35
|
+
return "flow-display"
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def flag_help(self) -> str:
|
|
39
|
+
return "Show workflow flow diagram without executing"
|
|
40
|
+
|
|
41
|
+
def _get_console(self):
|
|
42
|
+
"""Get or create Rich Console."""
|
|
43
|
+
if self._console is None:
|
|
44
|
+
try:
|
|
45
|
+
from rich.console import Console
|
|
46
|
+
self._console = Console()
|
|
47
|
+
except ImportError:
|
|
48
|
+
pass
|
|
49
|
+
return self._console
|
|
50
|
+
|
|
51
|
+
def check_dependencies(self) -> Tuple[bool, str]:
|
|
52
|
+
"""Check if Rich is available."""
|
|
53
|
+
try:
|
|
54
|
+
import importlib.util
|
|
55
|
+
rich_available = importlib.util.find_spec("rich") is not None
|
|
56
|
+
if not rich_available:
|
|
57
|
+
return False, "rich not installed. Install with: pip install rich"
|
|
58
|
+
return True, ""
|
|
59
|
+
except ImportError:
|
|
60
|
+
return False, "rich not installed. Install with: pip install rich"
|
|
61
|
+
|
|
62
|
+
def apply_to_agent_config(self, config: Dict[str, Any], flag_value: Any) -> Dict[str, Any]:
|
|
63
|
+
"""Apply flow display configuration."""
|
|
64
|
+
if flag_value:
|
|
65
|
+
config['flow_display'] = True
|
|
66
|
+
return config
|
|
67
|
+
|
|
68
|
+
def display_flow_diagram(self, yaml_file: str, show_footer: bool = True) -> bool:
|
|
69
|
+
"""
|
|
70
|
+
Display a visual flow diagram of the workflow from YAML file.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
yaml_file: Path to the agents.yaml file
|
|
74
|
+
show_footer: Whether to show the "run without --flow-display" footer
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
True if displayed successfully, False otherwise
|
|
78
|
+
"""
|
|
79
|
+
console = self._get_console()
|
|
80
|
+
if not console:
|
|
81
|
+
print("Rich library not available for flow display")
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
# Load YAML config
|
|
85
|
+
try:
|
|
86
|
+
if not os.path.exists(yaml_file):
|
|
87
|
+
console.print(f"[red]Error: File not found: {yaml_file}[/red]")
|
|
88
|
+
return False
|
|
89
|
+
|
|
90
|
+
with open(yaml_file, 'r') as f:
|
|
91
|
+
config = yaml.safe_load(f)
|
|
92
|
+
except Exception as e:
|
|
93
|
+
console.print(f"[red]Error loading YAML: {e}[/red]")
|
|
94
|
+
return False
|
|
95
|
+
|
|
96
|
+
# Detect YAML format: 'roles' (old) or 'agents'+'steps' (new workflow)
|
|
97
|
+
has_roles = 'roles' in config and config['roles']
|
|
98
|
+
has_agents = 'agents' in config and config['agents']
|
|
99
|
+
has_steps = 'steps' in config and config['steps']
|
|
100
|
+
|
|
101
|
+
if not has_roles and not has_agents:
|
|
102
|
+
console.print("[red]Error: Invalid YAML format. No 'roles' or 'agents' found.[/red]")
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
from rich.panel import Panel
|
|
107
|
+
from rich.table import Table
|
|
108
|
+
from rich.text import Text
|
|
109
|
+
from rich import box
|
|
110
|
+
|
|
111
|
+
# Determine format type
|
|
112
|
+
is_workflow_format = has_agents and has_steps
|
|
113
|
+
|
|
114
|
+
# Extract workflow info based on format
|
|
115
|
+
if is_workflow_format:
|
|
116
|
+
name = config.get('name', 'Workflow')
|
|
117
|
+
description = config.get('description', '')
|
|
118
|
+
framework = config.get('framework', 'praisonai')
|
|
119
|
+
workflow_config = config.get('workflow', {})
|
|
120
|
+
memory = workflow_config.get('memory_config', {}).get('persist', False)
|
|
121
|
+
num_agents = len(config['agents'])
|
|
122
|
+
num_steps = len(config['steps'])
|
|
123
|
+
else:
|
|
124
|
+
name = config.get('topic', 'Workflow')
|
|
125
|
+
description = ''
|
|
126
|
+
framework = config.get('framework', 'praisonai')
|
|
127
|
+
process = config.get('process', 'sequential')
|
|
128
|
+
memory = config.get('memory', False)
|
|
129
|
+
num_agents = len(config['roles'])
|
|
130
|
+
num_steps = sum(len(details.get('tasks', {})) for details in config['roles'].values())
|
|
131
|
+
|
|
132
|
+
# Build the flow diagram
|
|
133
|
+
console.print()
|
|
134
|
+
|
|
135
|
+
# === HEADER ===
|
|
136
|
+
header = Text()
|
|
137
|
+
header.append("📊 WORKFLOW FLOW DIAGRAM\n", style="bold cyan")
|
|
138
|
+
header.append("─" * 40, style="dim")
|
|
139
|
+
|
|
140
|
+
header_panel = Panel(
|
|
141
|
+
header,
|
|
142
|
+
border_style="cyan",
|
|
143
|
+
box=box.DOUBLE_EDGE,
|
|
144
|
+
padding=(0, 2)
|
|
145
|
+
)
|
|
146
|
+
console.print(header_panel)
|
|
147
|
+
|
|
148
|
+
# === WORKFLOW INFO ===
|
|
149
|
+
info_table = Table(show_header=False, box=None, padding=(0, 2))
|
|
150
|
+
info_table.add_column("Key", style="bold yellow")
|
|
151
|
+
info_table.add_column("Value", style="white")
|
|
152
|
+
|
|
153
|
+
info_table.add_row("📋 Name:", name)
|
|
154
|
+
if description:
|
|
155
|
+
info_table.add_row("📝 Description:", description)
|
|
156
|
+
|
|
157
|
+
# Show input if present ('input' is canonical, 'topic' is alias)
|
|
158
|
+
workflow_input = config.get('input', config.get('topic', ''))
|
|
159
|
+
if workflow_input:
|
|
160
|
+
info_table.add_row("💬 Input:", workflow_input)
|
|
161
|
+
|
|
162
|
+
info_table.add_row("⚙️ Framework:", framework)
|
|
163
|
+
|
|
164
|
+
if is_workflow_format:
|
|
165
|
+
info_table.add_row("🔄 Format:", "WORKFLOW (steps-based)")
|
|
166
|
+
planning = workflow_config.get('planning', False)
|
|
167
|
+
info_table.add_row("🧠 Planning:", "✅ Enabled" if planning else "❌ Disabled")
|
|
168
|
+
else:
|
|
169
|
+
info_table.add_row("🔄 Process:", process.upper())
|
|
170
|
+
|
|
171
|
+
info_table.add_row("💾 Memory:", "✅ Enabled" if memory else "❌ Disabled")
|
|
172
|
+
info_table.add_row("👥 Agents:", str(num_agents))
|
|
173
|
+
info_table.add_row("📝 Steps:", str(num_steps))
|
|
174
|
+
|
|
175
|
+
console.print(Panel(info_table, title="[bold white]Workflow Configuration[/bold white]",
|
|
176
|
+
border_style="blue", box=box.ROUNDED))
|
|
177
|
+
console.print()
|
|
178
|
+
|
|
179
|
+
# === FLOW DIAGRAM ===
|
|
180
|
+
if is_workflow_format:
|
|
181
|
+
self._display_steps_flow(console, config)
|
|
182
|
+
else:
|
|
183
|
+
process = config.get('process', 'sequential')
|
|
184
|
+
if process == 'sequential':
|
|
185
|
+
self._display_sequential_flow(console, config)
|
|
186
|
+
elif process == 'hierarchical':
|
|
187
|
+
self._display_hierarchical_flow(console, config)
|
|
188
|
+
else:
|
|
189
|
+
self._display_sequential_flow(console, config)
|
|
190
|
+
|
|
191
|
+
# === DETAILED AGENT INFO ===
|
|
192
|
+
console.print()
|
|
193
|
+
if is_workflow_format:
|
|
194
|
+
self._display_workflow_agent_details(console, config)
|
|
195
|
+
else:
|
|
196
|
+
self._display_agent_details(console, config)
|
|
197
|
+
|
|
198
|
+
# === FOOTER ===
|
|
199
|
+
if show_footer:
|
|
200
|
+
console.print()
|
|
201
|
+
footer = Text()
|
|
202
|
+
footer.append("💡 ", style="bold")
|
|
203
|
+
footer.append("To execute this workflow, run without --flow-display flag", style="dim italic")
|
|
204
|
+
console.print(Panel(footer, border_style="dim", box=box.ROUNDED))
|
|
205
|
+
console.print()
|
|
206
|
+
|
|
207
|
+
return True
|
|
208
|
+
|
|
209
|
+
except ImportError as e:
|
|
210
|
+
console.print(f"[red]Error: Rich components not available: {e}[/red]")
|
|
211
|
+
return False
|
|
212
|
+
|
|
213
|
+
def _display_sequential_flow(self, console, config: Dict):
|
|
214
|
+
"""Display sequential flow diagram."""
|
|
215
|
+
from rich.panel import Panel
|
|
216
|
+
from rich.text import Text
|
|
217
|
+
from rich import box
|
|
218
|
+
|
|
219
|
+
roles = list(config['roles'].items())
|
|
220
|
+
|
|
221
|
+
# Box width (content area)
|
|
222
|
+
BOX_WIDTH = 36
|
|
223
|
+
|
|
224
|
+
def pad_line(content: str, width: int = BOX_WIDTH) -> str:
|
|
225
|
+
"""Pad content to fixed width."""
|
|
226
|
+
padding = width - len(content)
|
|
227
|
+
if padding > 0:
|
|
228
|
+
return content + " " * padding
|
|
229
|
+
return content[:width]
|
|
230
|
+
|
|
231
|
+
flow_text = Text()
|
|
232
|
+
flow_text.append(" SEQUENTIAL EXECUTION FLOW\n\n", style="bold magenta")
|
|
233
|
+
|
|
234
|
+
for i, (role_key, details) in enumerate(roles):
|
|
235
|
+
role_name = details.get('role', role_key)
|
|
236
|
+
tasks = list(details.get('tasks', {}).keys())
|
|
237
|
+
|
|
238
|
+
# Agent box
|
|
239
|
+
if i == 0:
|
|
240
|
+
flow_text.append(" ┌── START ──┐\n", style="green")
|
|
241
|
+
flow_text.append(" │\n", style="dim")
|
|
242
|
+
flow_text.append(" ▼\n", style="dim")
|
|
243
|
+
|
|
244
|
+
# Agent node
|
|
245
|
+
flow_text.append(" ╔════════════════════════════════════╗\n", style="cyan")
|
|
246
|
+
line = f" Agent {i+1}: {role_name}"
|
|
247
|
+
flow_text.append(f" ║{pad_line(line)}║\n", style="cyan")
|
|
248
|
+
|
|
249
|
+
# Tasks
|
|
250
|
+
for task in tasks:
|
|
251
|
+
line = f" -> {task}"
|
|
252
|
+
flow_text.append(f" ║{pad_line(line)}║\n", style="dim white")
|
|
253
|
+
|
|
254
|
+
flow_text.append(" ╚════════════════════════════════════╝\n", style="cyan")
|
|
255
|
+
|
|
256
|
+
# Arrow to next
|
|
257
|
+
if i < len(roles) - 1:
|
|
258
|
+
flow_text.append(" │\n", style="dim")
|
|
259
|
+
flow_text.append(" output\n", style="dim italic")
|
|
260
|
+
flow_text.append(" ▼\n", style="dim")
|
|
261
|
+
else:
|
|
262
|
+
flow_text.append(" │\n", style="dim")
|
|
263
|
+
flow_text.append(" ▼\n", style="dim")
|
|
264
|
+
flow_text.append(" └── END ────┘\n", style="red")
|
|
265
|
+
|
|
266
|
+
console.print(Panel(flow_text, border_style="magenta", box=box.DOUBLE_EDGE,
|
|
267
|
+
title="[bold white]Execution Flow[/bold white]"))
|
|
268
|
+
|
|
269
|
+
def _display_hierarchical_flow(self, console, config: Dict):
|
|
270
|
+
"""Display hierarchical flow diagram."""
|
|
271
|
+
from rich.panel import Panel
|
|
272
|
+
from rich.text import Text
|
|
273
|
+
from rich import box
|
|
274
|
+
|
|
275
|
+
manager_llm = config.get('manager_llm', 'default')
|
|
276
|
+
|
|
277
|
+
flow_text = Text()
|
|
278
|
+
flow_text.append("👑 HIERARCHICAL EXECUTION FLOW\n\n", style="bold magenta")
|
|
279
|
+
|
|
280
|
+
# Manager at top
|
|
281
|
+
flow_text.append(" ┌──────────────────────┐\n", style="yellow")
|
|
282
|
+
flow_text.append(" │ 👑 MANAGER AGENT │\n", style="bold yellow")
|
|
283
|
+
flow_text.append(f" │ LLM: {manager_llm:<14}│\n", style="dim yellow")
|
|
284
|
+
flow_text.append(" └──────────┬───────────┘\n", style="yellow")
|
|
285
|
+
flow_text.append(" │\n", style="dim")
|
|
286
|
+
flow_text.append(" ┌──────────┴───────────┐\n", style="dim")
|
|
287
|
+
flow_text.append(" │ delegates to │\n", style="dim italic")
|
|
288
|
+
flow_text.append(" └──────────┬───────────┘\n", style="dim")
|
|
289
|
+
|
|
290
|
+
roles = list(config['roles'].items())
|
|
291
|
+
num_agents = len(roles)
|
|
292
|
+
|
|
293
|
+
# Draw branches
|
|
294
|
+
if num_agents > 0:
|
|
295
|
+
branch_line = " "
|
|
296
|
+
for i in range(num_agents):
|
|
297
|
+
if i == 0:
|
|
298
|
+
branch_line += "┌" + "─" * 8
|
|
299
|
+
elif i == num_agents - 1:
|
|
300
|
+
branch_line += "┬" + "─" * 8 + "┐"
|
|
301
|
+
else:
|
|
302
|
+
branch_line += "┬" + "─" * 8
|
|
303
|
+
flow_text.append(branch_line + "\n", style="dim")
|
|
304
|
+
|
|
305
|
+
# Agent boxes
|
|
306
|
+
for i, (role_key, details) in enumerate(roles):
|
|
307
|
+
flow_text.append("\n ╔═══════════════╗", style="cyan")
|
|
308
|
+
flow_text.append("\n")
|
|
309
|
+
|
|
310
|
+
for i, (role_key, details) in enumerate(roles):
|
|
311
|
+
role_name = details.get('role', role_key)[:12]
|
|
312
|
+
flow_text.append(f" ║ 🤖 {role_name:<10} ║", style="cyan")
|
|
313
|
+
flow_text.append("\n")
|
|
314
|
+
|
|
315
|
+
for i, (role_key, details) in enumerate(roles):
|
|
316
|
+
flow_text.append(" ╚═══════════════╝", style="cyan")
|
|
317
|
+
flow_text.append("\n")
|
|
318
|
+
|
|
319
|
+
console.print(Panel(flow_text, border_style="magenta", box=box.DOUBLE_EDGE,
|
|
320
|
+
title="[bold white]Execution Flow[/bold white]"))
|
|
321
|
+
|
|
322
|
+
def _display_agent_details(self, console, config: Dict):
|
|
323
|
+
"""Display detailed agent information."""
|
|
324
|
+
from rich.table import Table
|
|
325
|
+
from rich import box
|
|
326
|
+
|
|
327
|
+
table = Table(
|
|
328
|
+
title="[bold cyan]📋 Agent & Task Details[/bold cyan]",
|
|
329
|
+
box=box.ROUNDED,
|
|
330
|
+
show_header=True,
|
|
331
|
+
header_style="bold magenta",
|
|
332
|
+
border_style="blue",
|
|
333
|
+
padding=(0, 1),
|
|
334
|
+
expand=True
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
table.add_column("#", style="dim", width=3, justify="center")
|
|
338
|
+
table.add_column("Agent", style="bold yellow", min_width=15)
|
|
339
|
+
table.add_column("Role", style="cyan", min_width=15)
|
|
340
|
+
table.add_column("Goal", style="white", min_width=25, overflow="fold")
|
|
341
|
+
table.add_column("Tasks", style="green", min_width=20)
|
|
342
|
+
table.add_column("Tools", style="magenta", min_width=15)
|
|
343
|
+
|
|
344
|
+
for i, (role_key, details) in enumerate(config['roles'].items(), 1):
|
|
345
|
+
role_name = details.get('role', role_key)
|
|
346
|
+
goal = details.get('goal', '-')
|
|
347
|
+
if len(goal) > 50:
|
|
348
|
+
goal = goal[:47] + "..."
|
|
349
|
+
|
|
350
|
+
tasks = list(details.get('tasks', {}).keys())
|
|
351
|
+
tasks_str = "\n".join(f"• {t}" for t in tasks) if tasks else "-"
|
|
352
|
+
|
|
353
|
+
tools = details.get('tools', [])
|
|
354
|
+
tools_str = ", ".join(t for t in tools if t) if tools else "-"
|
|
355
|
+
|
|
356
|
+
table.add_row(
|
|
357
|
+
str(i),
|
|
358
|
+
role_name,
|
|
359
|
+
role_key,
|
|
360
|
+
goal,
|
|
361
|
+
tasks_str,
|
|
362
|
+
tools_str
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
console.print(table)
|
|
366
|
+
|
|
367
|
+
def _display_steps_flow(self, console, config: Dict):
|
|
368
|
+
"""Display steps-based workflow flow diagram."""
|
|
369
|
+
from rich.panel import Panel
|
|
370
|
+
from rich.text import Text
|
|
371
|
+
from rich import box
|
|
372
|
+
|
|
373
|
+
steps = config.get('steps', [])
|
|
374
|
+
agents = config.get('agents', {})
|
|
375
|
+
|
|
376
|
+
# Box width (content area)
|
|
377
|
+
BOX_WIDTH = 36
|
|
378
|
+
|
|
379
|
+
def pad_line(content: str, width: int = BOX_WIDTH) -> str:
|
|
380
|
+
"""Pad content to fixed width, accounting for emoji width."""
|
|
381
|
+
# Emojis typically take 2 character widths
|
|
382
|
+
emoji_count = sum(1 for c in content if ord(c) > 0x1F300)
|
|
383
|
+
actual_len = len(content) + emoji_count # Add extra for emoji width
|
|
384
|
+
padding = width - actual_len
|
|
385
|
+
if padding > 0:
|
|
386
|
+
return content + " " * padding
|
|
387
|
+
return content[:width]
|
|
388
|
+
|
|
389
|
+
flow_text = Text()
|
|
390
|
+
flow_text.append(" STEPS-BASED EXECUTION FLOW\n\n", style="bold magenta")
|
|
391
|
+
|
|
392
|
+
flow_text.append(" ┌── START ──┐\n", style="green")
|
|
393
|
+
flow_text.append(" │\n", style="dim")
|
|
394
|
+
flow_text.append(" ▼\n", style="dim")
|
|
395
|
+
|
|
396
|
+
for i, step in enumerate(steps):
|
|
397
|
+
# Determine step type
|
|
398
|
+
agent_key = step.get('agent', '')
|
|
399
|
+
step_name = step.get('name', '')
|
|
400
|
+
|
|
401
|
+
# Check for special step types
|
|
402
|
+
has_route = 'route' in step
|
|
403
|
+
has_parallel = 'parallel' in step
|
|
404
|
+
has_loop = 'loop' in step
|
|
405
|
+
has_repeat = 'repeat' in step
|
|
406
|
+
|
|
407
|
+
if has_route:
|
|
408
|
+
# Route step
|
|
409
|
+
flow_text.append(" ╔════════════════════════════════════╗\n", style="yellow")
|
|
410
|
+
line = f" ROUTE: {step_name or 'routing'}"
|
|
411
|
+
flow_text.append(f" ║{pad_line(line)}║\n", style="yellow")
|
|
412
|
+
|
|
413
|
+
routes = step['route']
|
|
414
|
+
for route_name, route_agents in routes.items():
|
|
415
|
+
agents_str = ", ".join(route_agents) if isinstance(route_agents, list) else str(route_agents)
|
|
416
|
+
line = f" -> {route_name}: {agents_str}"
|
|
417
|
+
flow_text.append(f" ║{pad_line(line)}║\n", style="yellow")
|
|
418
|
+
|
|
419
|
+
flow_text.append(" ╚════════════════════════════════════╝\n", style="yellow")
|
|
420
|
+
|
|
421
|
+
elif has_parallel:
|
|
422
|
+
# Parallel step
|
|
423
|
+
flow_text.append(" ╔════════════════════════════════════╗\n", style="green")
|
|
424
|
+
line = f" PARALLEL: {step_name or 'parallel'}"
|
|
425
|
+
flow_text.append(f" ║{pad_line(line)}║\n", style="green")
|
|
426
|
+
|
|
427
|
+
for p_step in step['parallel']:
|
|
428
|
+
p_agent = p_step.get('agent', '?')
|
|
429
|
+
line = f" |-- {p_agent}"
|
|
430
|
+
flow_text.append(f" ║{pad_line(line)}║\n", style="green")
|
|
431
|
+
|
|
432
|
+
flow_text.append(" ╚════════════════════════════════════╝\n", style="green")
|
|
433
|
+
|
|
434
|
+
else:
|
|
435
|
+
# Regular agent step
|
|
436
|
+
agent_info = agents.get(agent_key, {})
|
|
437
|
+
agent_name = agent_info.get('name', agent_key)
|
|
438
|
+
|
|
439
|
+
flow_text.append(" ╔════════════════════════════════════╗\n", style="cyan")
|
|
440
|
+
line = f" Step {i+1}: {agent_name}"
|
|
441
|
+
flow_text.append(f" ║{pad_line(line)}║\n", style="cyan")
|
|
442
|
+
|
|
443
|
+
# Show modifiers
|
|
444
|
+
if has_loop:
|
|
445
|
+
loop_over = step['loop'].get('over', '?')
|
|
446
|
+
line = f" [loop over: {loop_over}]"
|
|
447
|
+
flow_text.append(f" ║{pad_line(line)}║\n", style="dim magenta")
|
|
448
|
+
|
|
449
|
+
if has_repeat:
|
|
450
|
+
until = step['repeat'].get('until', '?')
|
|
451
|
+
max_iter = step['repeat'].get('max_iterations', '?')
|
|
452
|
+
line = f" [repeat until: {until} max:{max_iter}]"
|
|
453
|
+
flow_text.append(f" ║{pad_line(line)}║\n", style="dim magenta")
|
|
454
|
+
|
|
455
|
+
flow_text.append(" ╚════════════════════════════════════╝\n", style="cyan")
|
|
456
|
+
|
|
457
|
+
# Arrow to next
|
|
458
|
+
if i < len(steps) - 1:
|
|
459
|
+
flow_text.append(" │\n", style="dim")
|
|
460
|
+
flow_text.append(" ▼\n", style="dim")
|
|
461
|
+
|
|
462
|
+
flow_text.append(" │\n", style="dim")
|
|
463
|
+
flow_text.append(" ▼\n", style="dim")
|
|
464
|
+
flow_text.append(" └── END ────┘\n", style="red")
|
|
465
|
+
|
|
466
|
+
console.print(Panel(flow_text, border_style="magenta", box=box.DOUBLE_EDGE,
|
|
467
|
+
title="[bold white]Execution Flow[/bold white]"))
|
|
468
|
+
|
|
469
|
+
def _display_workflow_agent_details(self, console, config: Dict):
|
|
470
|
+
"""Display detailed agent information for workflow format."""
|
|
471
|
+
from rich.table import Table
|
|
472
|
+
from rich import box
|
|
473
|
+
|
|
474
|
+
table = Table(
|
|
475
|
+
title="[bold cyan]📋 Agent Details[/bold cyan]",
|
|
476
|
+
box=box.ROUNDED,
|
|
477
|
+
show_header=True,
|
|
478
|
+
header_style="bold magenta",
|
|
479
|
+
border_style="blue",
|
|
480
|
+
padding=(0, 1),
|
|
481
|
+
expand=True
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
table.add_column("#", style="dim", width=3, justify="center")
|
|
485
|
+
table.add_column("Agent Key", style="bold yellow", min_width=15)
|
|
486
|
+
table.add_column("Name", style="cyan", min_width=15)
|
|
487
|
+
table.add_column("Role", style="white", min_width=20)
|
|
488
|
+
table.add_column("Goal", style="green", min_width=25, overflow="fold")
|
|
489
|
+
|
|
490
|
+
for i, (agent_key, details) in enumerate(config['agents'].items(), 1):
|
|
491
|
+
name = details.get('name', agent_key)
|
|
492
|
+
role = details.get('role', '-')
|
|
493
|
+
goal = details.get('goal', '-')
|
|
494
|
+
if len(goal) > 40:
|
|
495
|
+
goal = goal[:37] + "..."
|
|
496
|
+
|
|
497
|
+
table.add_row(
|
|
498
|
+
str(i),
|
|
499
|
+
agent_key,
|
|
500
|
+
name,
|
|
501
|
+
role,
|
|
502
|
+
goal
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
console.print(table)
|
|
506
|
+
|
|
507
|
+
def display_workflow_start(self, workflow_name: str, agents: list) -> None:
|
|
508
|
+
"""
|
|
509
|
+
Display workflow start message.
|
|
510
|
+
|
|
511
|
+
Args:
|
|
512
|
+
workflow_name: Name of the workflow being started
|
|
513
|
+
agents: List of agent names in the workflow
|
|
514
|
+
"""
|
|
515
|
+
console = self._get_console()
|
|
516
|
+
if console:
|
|
517
|
+
try:
|
|
518
|
+
from rich.panel import Panel
|
|
519
|
+
from rich import box
|
|
520
|
+
|
|
521
|
+
agents_str = ", ".join(agents) if agents else "No agents"
|
|
522
|
+
content = f"🚀 Starting: {workflow_name}\n👥 Agents: {agents_str}"
|
|
523
|
+
console.print(Panel(content, title="[bold cyan]Workflow Started[/bold cyan]",
|
|
524
|
+
border_style="cyan", box=box.ROUNDED))
|
|
525
|
+
except ImportError:
|
|
526
|
+
print(f"Starting workflow: {workflow_name} with agents: {agents}")
|
|
527
|
+
|
|
528
|
+
def display_workflow_end(self, success: bool = True) -> None:
|
|
529
|
+
"""
|
|
530
|
+
Display workflow end message.
|
|
531
|
+
|
|
532
|
+
Args:
|
|
533
|
+
success: Whether the workflow completed successfully
|
|
534
|
+
"""
|
|
535
|
+
console = self._get_console()
|
|
536
|
+
if console:
|
|
537
|
+
try:
|
|
538
|
+
from rich.panel import Panel
|
|
539
|
+
from rich import box
|
|
540
|
+
|
|
541
|
+
if success:
|
|
542
|
+
content = "✅ Workflow completed successfully"
|
|
543
|
+
style = "green"
|
|
544
|
+
else:
|
|
545
|
+
content = "❌ Workflow failed"
|
|
546
|
+
style = "red"
|
|
547
|
+
|
|
548
|
+
console.print(Panel(content, title=f"[bold {style}]Workflow Ended[/bold {style}]",
|
|
549
|
+
border_style=style, box=box.ROUNDED))
|
|
550
|
+
except ImportError:
|
|
551
|
+
status = "successfully" if success else "with errors"
|
|
552
|
+
print(f"Workflow ended {status}")
|
|
553
|
+
|
|
554
|
+
def execute(self, yaml_file: str = None, **kwargs) -> bool:
|
|
555
|
+
"""
|
|
556
|
+
Execute flow display - shows diagram without running workflow.
|
|
557
|
+
|
|
558
|
+
Args:
|
|
559
|
+
yaml_file: Path to the YAML file
|
|
560
|
+
|
|
561
|
+
Returns:
|
|
562
|
+
True if displayed successfully
|
|
563
|
+
"""
|
|
564
|
+
if yaml_file:
|
|
565
|
+
return self.display_flow_diagram(yaml_file)
|
|
566
|
+
return False
|