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,583 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Hooks CLI Feature for PraisonAI.
|
|
3
|
+
|
|
4
|
+
Provides CLI commands for managing and testing hooks.
|
|
5
|
+
|
|
6
|
+
Commands:
|
|
7
|
+
- praisonai hooks list # List registered hooks
|
|
8
|
+
- praisonai hooks test <event> <target> # Test hooks for an event
|
|
9
|
+
- praisonai hooks validate <config> # Validate hooks configuration
|
|
10
|
+
- praisonai hooks run <command> # Run a command hook manually
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
import json
|
|
15
|
+
import asyncio
|
|
16
|
+
from typing import Optional, Dict, Any, List
|
|
17
|
+
from dataclasses import dataclass, field
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class HooksConfig:
|
|
22
|
+
"""Configuration for hooks loaded from file."""
|
|
23
|
+
hooks: List[Dict[str, Any]] = field(default_factory=list)
|
|
24
|
+
enabled: bool = True
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def from_file(cls, path: str) -> "HooksConfig":
|
|
28
|
+
"""Load hooks configuration from a JSON/YAML file."""
|
|
29
|
+
if not os.path.exists(path):
|
|
30
|
+
raise FileNotFoundError(f"Hooks config file not found: {path}")
|
|
31
|
+
|
|
32
|
+
with open(path, 'r') as f:
|
|
33
|
+
if path.endswith('.yaml') or path.endswith('.yml'):
|
|
34
|
+
try:
|
|
35
|
+
import yaml
|
|
36
|
+
data = yaml.safe_load(f)
|
|
37
|
+
except ImportError:
|
|
38
|
+
raise ImportError("PyYAML required for YAML config files")
|
|
39
|
+
else:
|
|
40
|
+
data = json.load(f)
|
|
41
|
+
|
|
42
|
+
return cls(
|
|
43
|
+
hooks=data.get('hooks', []),
|
|
44
|
+
enabled=data.get('enabled', True)
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
48
|
+
"""Convert to dictionary."""
|
|
49
|
+
return {
|
|
50
|
+
'hooks': self.hooks,
|
|
51
|
+
'enabled': self.enabled
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class HooksHandler:
|
|
56
|
+
"""
|
|
57
|
+
Handler for hooks CLI commands.
|
|
58
|
+
|
|
59
|
+
Provides functionality to:
|
|
60
|
+
- List registered hooks
|
|
61
|
+
- Test hooks with sample events
|
|
62
|
+
- Validate hook configurations
|
|
63
|
+
- Run command hooks manually
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def __init__(self, verbose: bool = False):
|
|
67
|
+
self.verbose = verbose
|
|
68
|
+
self._registry = None
|
|
69
|
+
self._runner = None
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def feature_name(self) -> str:
|
|
73
|
+
return "hooks"
|
|
74
|
+
|
|
75
|
+
def _get_registry(self):
|
|
76
|
+
"""Lazy load the hook registry."""
|
|
77
|
+
if self._registry is None:
|
|
78
|
+
from praisonaiagents.hooks import HookRegistry
|
|
79
|
+
self._registry = HookRegistry()
|
|
80
|
+
return self._registry
|
|
81
|
+
|
|
82
|
+
def _get_runner(self):
|
|
83
|
+
"""Lazy load the hook runner."""
|
|
84
|
+
if self._runner is None:
|
|
85
|
+
from praisonaiagents.hooks import HookRunner
|
|
86
|
+
self._runner = HookRunner(self._get_registry())
|
|
87
|
+
return self._runner
|
|
88
|
+
|
|
89
|
+
def list_hooks(self, format: str = "table") -> Dict[str, Any]:
|
|
90
|
+
"""
|
|
91
|
+
List all registered hooks.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
format: Output format (table, json)
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
Dictionary of hooks by event
|
|
98
|
+
"""
|
|
99
|
+
registry = self._get_registry()
|
|
100
|
+
hooks = registry.list_hooks()
|
|
101
|
+
|
|
102
|
+
if format == "json":
|
|
103
|
+
print(json.dumps(hooks, indent=2))
|
|
104
|
+
else:
|
|
105
|
+
self._print_hooks_table(hooks)
|
|
106
|
+
|
|
107
|
+
return hooks
|
|
108
|
+
|
|
109
|
+
def _print_hooks_table(self, hooks: Dict[str, List[Dict]]):
|
|
110
|
+
"""Print hooks in table format."""
|
|
111
|
+
try:
|
|
112
|
+
from rich.console import Console
|
|
113
|
+
from rich.table import Table
|
|
114
|
+
|
|
115
|
+
console = Console()
|
|
116
|
+
|
|
117
|
+
if not hooks:
|
|
118
|
+
console.print("[yellow]No hooks registered[/yellow]")
|
|
119
|
+
return
|
|
120
|
+
|
|
121
|
+
table = Table(title="Registered Hooks")
|
|
122
|
+
table.add_column("Event", style="cyan")
|
|
123
|
+
table.add_column("Name", style="green")
|
|
124
|
+
table.add_column("Type", style="blue")
|
|
125
|
+
table.add_column("Matcher", style="magenta")
|
|
126
|
+
table.add_column("Enabled", style="yellow")
|
|
127
|
+
|
|
128
|
+
for event, event_hooks in hooks.items():
|
|
129
|
+
for hook in event_hooks:
|
|
130
|
+
table.add_row(
|
|
131
|
+
event,
|
|
132
|
+
hook.get('name', 'unknown'),
|
|
133
|
+
hook.get('type', 'unknown'),
|
|
134
|
+
hook.get('matcher') or '*',
|
|
135
|
+
'✓' if hook.get('enabled', True) else '✗'
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
console.print(table)
|
|
139
|
+
except ImportError:
|
|
140
|
+
# Fallback to simple print
|
|
141
|
+
print("Registered Hooks:")
|
|
142
|
+
for event, event_hooks in hooks.items():
|
|
143
|
+
print(f"\n {event}:")
|
|
144
|
+
for hook in event_hooks:
|
|
145
|
+
print(f" - {hook.get('name', 'unknown')} ({hook.get('type', 'unknown')})")
|
|
146
|
+
|
|
147
|
+
def test_hook(
|
|
148
|
+
self,
|
|
149
|
+
event: str,
|
|
150
|
+
target: Optional[str] = None,
|
|
151
|
+
input_data: Optional[Dict[str, Any]] = None
|
|
152
|
+
) -> List[Dict[str, Any]]:
|
|
153
|
+
"""
|
|
154
|
+
Test hooks for a specific event.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
event: Event name (before_tool, after_tool, etc.)
|
|
158
|
+
target: Optional target to filter hooks (e.g., tool name)
|
|
159
|
+
input_data: Optional custom input data
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
List of hook execution results
|
|
163
|
+
"""
|
|
164
|
+
from praisonaiagents.hooks import HookEvent
|
|
165
|
+
from praisonaiagents.hooks.events import BeforeToolInput, BeforeAgentInput
|
|
166
|
+
|
|
167
|
+
# Map string to HookEvent
|
|
168
|
+
event_map = {
|
|
169
|
+
'before_tool': HookEvent.BEFORE_TOOL,
|
|
170
|
+
'after_tool': HookEvent.AFTER_TOOL,
|
|
171
|
+
'before_agent': HookEvent.BEFORE_AGENT,
|
|
172
|
+
'after_agent': HookEvent.AFTER_AGENT,
|
|
173
|
+
'session_start': HookEvent.SESSION_START,
|
|
174
|
+
'session_end': HookEvent.SESSION_END,
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
hook_event = event_map.get(event.lower())
|
|
178
|
+
if hook_event is None:
|
|
179
|
+
print(f"[red]Unknown event: {event}[/red]")
|
|
180
|
+
print(f"Available events: {', '.join(event_map.keys())}")
|
|
181
|
+
return []
|
|
182
|
+
|
|
183
|
+
# Create sample input based on event type
|
|
184
|
+
from datetime import datetime
|
|
185
|
+
timestamp = datetime.now().isoformat()
|
|
186
|
+
|
|
187
|
+
if hook_event in (HookEvent.BEFORE_TOOL, HookEvent.AFTER_TOOL):
|
|
188
|
+
sample_input = BeforeToolInput(
|
|
189
|
+
session_id="cli-test",
|
|
190
|
+
cwd=os.getcwd(),
|
|
191
|
+
event_name=event,
|
|
192
|
+
timestamp=timestamp,
|
|
193
|
+
tool_name=target or "test_tool",
|
|
194
|
+
tool_input=input_data or {"test": "data"}
|
|
195
|
+
)
|
|
196
|
+
else:
|
|
197
|
+
sample_input = BeforeAgentInput(
|
|
198
|
+
session_id="cli-test",
|
|
199
|
+
cwd=os.getcwd(),
|
|
200
|
+
event_name=event,
|
|
201
|
+
timestamp=timestamp,
|
|
202
|
+
prompt=target or "Test prompt"
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
runner = self._get_runner()
|
|
206
|
+
results = asyncio.run(runner.execute(hook_event, sample_input, target))
|
|
207
|
+
|
|
208
|
+
# Print results
|
|
209
|
+
self._print_test_results(results)
|
|
210
|
+
|
|
211
|
+
return [r.to_dict() for r in results]
|
|
212
|
+
|
|
213
|
+
def _print_test_results(self, results):
|
|
214
|
+
"""Print test results."""
|
|
215
|
+
try:
|
|
216
|
+
from rich.console import Console
|
|
217
|
+
from rich.panel import Panel
|
|
218
|
+
|
|
219
|
+
console = Console()
|
|
220
|
+
|
|
221
|
+
if not results:
|
|
222
|
+
console.print("[yellow]No hooks executed[/yellow]")
|
|
223
|
+
return
|
|
224
|
+
|
|
225
|
+
console.print(f"\n[bold]Hook Execution Results ({len(results)} hooks)[/bold]\n")
|
|
226
|
+
|
|
227
|
+
for result in results:
|
|
228
|
+
status = "[green]✓ PASSED[/green]" if result.success else "[red]✗ FAILED[/red]"
|
|
229
|
+
decision = result.output.decision if result.output else "N/A"
|
|
230
|
+
|
|
231
|
+
content = f"""
|
|
232
|
+
Hook: {result.hook_name}
|
|
233
|
+
Status: {status}
|
|
234
|
+
Decision: {decision}
|
|
235
|
+
Duration: {result.duration_ms:.2f}ms
|
|
236
|
+
"""
|
|
237
|
+
if result.error:
|
|
238
|
+
content += f"Error: {result.error}\n"
|
|
239
|
+
if result.output and result.output.reason:
|
|
240
|
+
content += f"Reason: {result.output.reason}\n"
|
|
241
|
+
|
|
242
|
+
panel_style = "green" if result.success else "red"
|
|
243
|
+
console.print(Panel(content.strip(), title=result.hook_name, border_style=panel_style))
|
|
244
|
+
except ImportError:
|
|
245
|
+
print(f"\nHook Execution Results ({len(results)} hooks):")
|
|
246
|
+
for result in results:
|
|
247
|
+
status = "PASSED" if result.success else "FAILED"
|
|
248
|
+
print(f" - {result.hook_name}: {status}")
|
|
249
|
+
|
|
250
|
+
def validate_config(self, config_path: str) -> bool:
|
|
251
|
+
"""
|
|
252
|
+
Validate a hooks configuration file.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
config_path: Path to the configuration file
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
True if valid, False otherwise
|
|
259
|
+
"""
|
|
260
|
+
try:
|
|
261
|
+
config = HooksConfig.from_file(config_path)
|
|
262
|
+
|
|
263
|
+
errors = []
|
|
264
|
+
warnings = []
|
|
265
|
+
|
|
266
|
+
for i, hook in enumerate(config.hooks):
|
|
267
|
+
# Check required fields
|
|
268
|
+
if 'event' not in hook:
|
|
269
|
+
errors.append(f"Hook {i}: missing 'event' field")
|
|
270
|
+
|
|
271
|
+
if 'command' not in hook and 'function' not in hook:
|
|
272
|
+
errors.append(f"Hook {i}: must have 'command' or 'function'")
|
|
273
|
+
|
|
274
|
+
# Check event name
|
|
275
|
+
valid_events = ['before_tool', 'after_tool', 'before_agent',
|
|
276
|
+
'after_agent', 'session_start', 'session_end']
|
|
277
|
+
if hook.get('event') and hook['event'] not in valid_events:
|
|
278
|
+
warnings.append(f"Hook {i}: unknown event '{hook['event']}'")
|
|
279
|
+
|
|
280
|
+
# Check timeout
|
|
281
|
+
if 'timeout' in hook:
|
|
282
|
+
try:
|
|
283
|
+
timeout = float(hook['timeout'])
|
|
284
|
+
if timeout <= 0:
|
|
285
|
+
warnings.append(f"Hook {i}: timeout should be positive")
|
|
286
|
+
except (ValueError, TypeError):
|
|
287
|
+
errors.append(f"Hook {i}: invalid timeout value")
|
|
288
|
+
|
|
289
|
+
# Print results
|
|
290
|
+
try:
|
|
291
|
+
from rich.console import Console
|
|
292
|
+
console = Console()
|
|
293
|
+
|
|
294
|
+
if errors:
|
|
295
|
+
console.print("[red]Validation FAILED[/red]")
|
|
296
|
+
for error in errors:
|
|
297
|
+
console.print(f" [red]✗[/red] {error}")
|
|
298
|
+
else:
|
|
299
|
+
console.print("[green]Validation PASSED[/green]")
|
|
300
|
+
|
|
301
|
+
if warnings:
|
|
302
|
+
console.print("\n[yellow]Warnings:[/yellow]")
|
|
303
|
+
for warning in warnings:
|
|
304
|
+
console.print(f" [yellow]![/yellow] {warning}")
|
|
305
|
+
|
|
306
|
+
console.print(f"\n[dim]Found {len(config.hooks)} hooks in config[/dim]")
|
|
307
|
+
except ImportError:
|
|
308
|
+
if errors:
|
|
309
|
+
print("Validation FAILED")
|
|
310
|
+
for error in errors:
|
|
311
|
+
print(f" - {error}")
|
|
312
|
+
else:
|
|
313
|
+
print("Validation PASSED")
|
|
314
|
+
|
|
315
|
+
if warnings:
|
|
316
|
+
print("\nWarnings:")
|
|
317
|
+
for warning in warnings:
|
|
318
|
+
print(f" - {warning}")
|
|
319
|
+
|
|
320
|
+
return len(errors) == 0
|
|
321
|
+
|
|
322
|
+
except FileNotFoundError as e:
|
|
323
|
+
print(f"[red]Error: {e}[/red]")
|
|
324
|
+
return False
|
|
325
|
+
except json.JSONDecodeError as e:
|
|
326
|
+
print(f"[red]Invalid JSON: {e}[/red]")
|
|
327
|
+
return False
|
|
328
|
+
except Exception as e:
|
|
329
|
+
print(f"[red]Error validating config: {e}[/red]")
|
|
330
|
+
return False
|
|
331
|
+
|
|
332
|
+
def run_command_hook(
|
|
333
|
+
self,
|
|
334
|
+
command: str,
|
|
335
|
+
event: str = "before_tool",
|
|
336
|
+
input_json: Optional[str] = None,
|
|
337
|
+
timeout: float = 60.0
|
|
338
|
+
) -> Dict[str, Any]:
|
|
339
|
+
"""
|
|
340
|
+
Run a command hook manually.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
command: Shell command to execute
|
|
344
|
+
event: Event type for the hook
|
|
345
|
+
input_json: Optional JSON input to pass to the command
|
|
346
|
+
timeout: Timeout in seconds
|
|
347
|
+
|
|
348
|
+
Returns:
|
|
349
|
+
Execution result
|
|
350
|
+
"""
|
|
351
|
+
from praisonaiagents.hooks import HookEvent, HookRegistry, HookRunner
|
|
352
|
+
from praisonaiagents.hooks.events import BeforeToolInput
|
|
353
|
+
from datetime import datetime
|
|
354
|
+
|
|
355
|
+
registry = HookRegistry()
|
|
356
|
+
registry.register_command(
|
|
357
|
+
event=HookEvent.BEFORE_TOOL,
|
|
358
|
+
command=command,
|
|
359
|
+
name="cli_test_hook",
|
|
360
|
+
timeout=timeout
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
runner = HookRunner(registry)
|
|
364
|
+
|
|
365
|
+
# Create input
|
|
366
|
+
if input_json:
|
|
367
|
+
try:
|
|
368
|
+
custom_input = json.loads(input_json)
|
|
369
|
+
except json.JSONDecodeError:
|
|
370
|
+
custom_input = {}
|
|
371
|
+
else:
|
|
372
|
+
custom_input = {}
|
|
373
|
+
|
|
374
|
+
sample_input = BeforeToolInput(
|
|
375
|
+
session_id="cli-manual",
|
|
376
|
+
cwd=os.getcwd(),
|
|
377
|
+
event_name=event,
|
|
378
|
+
timestamp=datetime.now().isoformat(),
|
|
379
|
+
tool_name=custom_input.get('tool_name', 'manual_test'),
|
|
380
|
+
tool_input=custom_input.get('tool_input', {})
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
results = asyncio.run(runner.execute(HookEvent.BEFORE_TOOL, sample_input))
|
|
384
|
+
|
|
385
|
+
if results:
|
|
386
|
+
result = results[0]
|
|
387
|
+
self._print_command_result(result)
|
|
388
|
+
return result.to_dict()
|
|
389
|
+
|
|
390
|
+
return {}
|
|
391
|
+
|
|
392
|
+
def _print_command_result(self, result):
|
|
393
|
+
"""Print command hook result."""
|
|
394
|
+
try:
|
|
395
|
+
from rich.console import Console
|
|
396
|
+
from rich.syntax import Syntax
|
|
397
|
+
|
|
398
|
+
console = Console()
|
|
399
|
+
|
|
400
|
+
console.print(f"\n[bold]Command Hook Result[/bold]")
|
|
401
|
+
console.print(f"Exit Code: {result.exit_code}")
|
|
402
|
+
console.print(f"Success: {'[green]Yes[/green]' if result.success else '[red]No[/red]'}")
|
|
403
|
+
console.print(f"Duration: {result.duration_ms:.2f}ms")
|
|
404
|
+
|
|
405
|
+
if result.stdout:
|
|
406
|
+
console.print("\n[bold]STDOUT:[/bold]")
|
|
407
|
+
console.print(result.stdout)
|
|
408
|
+
|
|
409
|
+
if result.stderr:
|
|
410
|
+
console.print("\n[bold]STDERR:[/bold]")
|
|
411
|
+
console.print(f"[red]{result.stderr}[/red]")
|
|
412
|
+
|
|
413
|
+
if result.output:
|
|
414
|
+
console.print(f"\n[bold]Decision:[/bold] {result.output.decision}")
|
|
415
|
+
if result.output.reason:
|
|
416
|
+
console.print(f"[bold]Reason:[/bold] {result.output.reason}")
|
|
417
|
+
except ImportError:
|
|
418
|
+
print(f"\nCommand Hook Result")
|
|
419
|
+
print(f"Exit Code: {result.exit_code}")
|
|
420
|
+
print(f"Success: {result.success}")
|
|
421
|
+
if result.stdout:
|
|
422
|
+
print(f"STDOUT: {result.stdout}")
|
|
423
|
+
if result.stderr:
|
|
424
|
+
print(f"STDERR: {result.stderr}")
|
|
425
|
+
|
|
426
|
+
def register_from_config(self, config_path: str) -> int:
|
|
427
|
+
"""
|
|
428
|
+
Register hooks from a configuration file.
|
|
429
|
+
|
|
430
|
+
Args:
|
|
431
|
+
config_path: Path to the configuration file
|
|
432
|
+
|
|
433
|
+
Returns:
|
|
434
|
+
Number of hooks registered
|
|
435
|
+
"""
|
|
436
|
+
from praisonaiagents.hooks import HookEvent
|
|
437
|
+
|
|
438
|
+
config = HooksConfig.from_file(config_path)
|
|
439
|
+
registry = self._get_registry()
|
|
440
|
+
|
|
441
|
+
event_map = {
|
|
442
|
+
'before_tool': HookEvent.BEFORE_TOOL,
|
|
443
|
+
'after_tool': HookEvent.AFTER_TOOL,
|
|
444
|
+
'before_agent': HookEvent.BEFORE_AGENT,
|
|
445
|
+
'after_agent': HookEvent.AFTER_AGENT,
|
|
446
|
+
'session_start': HookEvent.SESSION_START,
|
|
447
|
+
'session_end': HookEvent.SESSION_END,
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
count = 0
|
|
451
|
+
for hook in config.hooks:
|
|
452
|
+
event = event_map.get(hook.get('event', '').lower())
|
|
453
|
+
if event is None:
|
|
454
|
+
continue
|
|
455
|
+
|
|
456
|
+
if 'command' in hook:
|
|
457
|
+
registry.register_command(
|
|
458
|
+
event=event,
|
|
459
|
+
command=hook['command'],
|
|
460
|
+
name=hook.get('name'),
|
|
461
|
+
matcher=hook.get('matcher'),
|
|
462
|
+
timeout=hook.get('timeout', 60.0),
|
|
463
|
+
env=hook.get('env', {})
|
|
464
|
+
)
|
|
465
|
+
count += 1
|
|
466
|
+
|
|
467
|
+
print(f"[green]Registered {count} hooks from {config_path}[/green]")
|
|
468
|
+
return count
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
def handle_hooks_command(args: List[str], verbose: bool = False):
|
|
472
|
+
"""
|
|
473
|
+
Handle hooks CLI commands.
|
|
474
|
+
|
|
475
|
+
Usage:
|
|
476
|
+
praisonai hooks list [--format json|table]
|
|
477
|
+
praisonai hooks test <event> [target] [--input '{"key": "value"}']
|
|
478
|
+
praisonai hooks validate <config_path>
|
|
479
|
+
praisonai hooks run <command> [--event <event>] [--input <json>] [--timeout <seconds>]
|
|
480
|
+
praisonai hooks load <config_path>
|
|
481
|
+
"""
|
|
482
|
+
handler = HooksHandler(verbose=verbose)
|
|
483
|
+
|
|
484
|
+
if not args:
|
|
485
|
+
print("Usage: praisonai hooks <command> [options]")
|
|
486
|
+
print("\nCommands:")
|
|
487
|
+
print(" list List registered hooks")
|
|
488
|
+
print(" test <event> [target] Test hooks for an event")
|
|
489
|
+
print(" validate <config> Validate hooks configuration")
|
|
490
|
+
print(" run <command> Run a command hook manually")
|
|
491
|
+
print(" load <config> Load hooks from configuration file")
|
|
492
|
+
return
|
|
493
|
+
|
|
494
|
+
command = args[0]
|
|
495
|
+
|
|
496
|
+
if command == "list":
|
|
497
|
+
format_type = "table"
|
|
498
|
+
if "--format" in args:
|
|
499
|
+
idx = args.index("--format")
|
|
500
|
+
if idx + 1 < len(args):
|
|
501
|
+
format_type = args[idx + 1]
|
|
502
|
+
handler.list_hooks(format=format_type)
|
|
503
|
+
|
|
504
|
+
elif command == "test":
|
|
505
|
+
if len(args) < 2:
|
|
506
|
+
print("Usage: praisonai hooks test <event> [target] [--input <json>]")
|
|
507
|
+
return
|
|
508
|
+
|
|
509
|
+
event = args[1]
|
|
510
|
+
target = args[2] if len(args) > 2 and not args[2].startswith("--") else None
|
|
511
|
+
|
|
512
|
+
input_data = None
|
|
513
|
+
if "--input" in args:
|
|
514
|
+
idx = args.index("--input")
|
|
515
|
+
if idx + 1 < len(args):
|
|
516
|
+
try:
|
|
517
|
+
input_data = json.loads(args[idx + 1])
|
|
518
|
+
except json.JSONDecodeError:
|
|
519
|
+
print("[red]Invalid JSON input[/red]")
|
|
520
|
+
return
|
|
521
|
+
|
|
522
|
+
handler.test_hook(event, target, input_data)
|
|
523
|
+
|
|
524
|
+
elif command == "validate":
|
|
525
|
+
if len(args) < 2:
|
|
526
|
+
print("Usage: praisonai hooks validate <config_path>")
|
|
527
|
+
return
|
|
528
|
+
handler.validate_config(args[1])
|
|
529
|
+
|
|
530
|
+
elif command == "run":
|
|
531
|
+
if len(args) < 2:
|
|
532
|
+
print("Usage: praisonai hooks run <command> [--event <event>] [--input <json>] [--timeout <seconds>]")
|
|
533
|
+
return
|
|
534
|
+
|
|
535
|
+
cmd = args[1]
|
|
536
|
+
event = "before_tool"
|
|
537
|
+
input_json = None
|
|
538
|
+
timeout = 60.0
|
|
539
|
+
|
|
540
|
+
if "--event" in args:
|
|
541
|
+
idx = args.index("--event")
|
|
542
|
+
if idx + 1 < len(args):
|
|
543
|
+
event = args[idx + 1]
|
|
544
|
+
|
|
545
|
+
if "--input" in args:
|
|
546
|
+
idx = args.index("--input")
|
|
547
|
+
if idx + 1 < len(args):
|
|
548
|
+
input_json = args[idx + 1]
|
|
549
|
+
|
|
550
|
+
if "--timeout" in args:
|
|
551
|
+
idx = args.index("--timeout")
|
|
552
|
+
if idx + 1 < len(args):
|
|
553
|
+
try:
|
|
554
|
+
timeout = float(args[idx + 1])
|
|
555
|
+
except ValueError:
|
|
556
|
+
print("[red]Invalid timeout value[/red]")
|
|
557
|
+
return
|
|
558
|
+
|
|
559
|
+
handler.run_command_hook(cmd, event, input_json, timeout)
|
|
560
|
+
|
|
561
|
+
elif command == "load":
|
|
562
|
+
if len(args) < 2:
|
|
563
|
+
print("Usage: praisonai hooks load <config_path>")
|
|
564
|
+
return
|
|
565
|
+
handler.register_from_config(args[1])
|
|
566
|
+
|
|
567
|
+
elif command == "help" or command == "--help":
|
|
568
|
+
print("Hooks CLI Commands:")
|
|
569
|
+
print("\n praisonai hooks list [--format json|table]")
|
|
570
|
+
print(" List all registered hooks")
|
|
571
|
+
print("\n praisonai hooks test <event> [target] [--input <json>]")
|
|
572
|
+
print(" Test hooks for a specific event")
|
|
573
|
+
print(" Events: before_tool, after_tool, before_agent, after_agent, session_start, session_end")
|
|
574
|
+
print("\n praisonai hooks validate <config_path>")
|
|
575
|
+
print(" Validate a hooks configuration file (JSON or YAML)")
|
|
576
|
+
print("\n praisonai hooks run <command> [--event <event>] [--input <json>] [--timeout <seconds>]")
|
|
577
|
+
print(" Run a command hook manually for testing")
|
|
578
|
+
print("\n praisonai hooks load <config_path>")
|
|
579
|
+
print(" Load and register hooks from a configuration file")
|
|
580
|
+
|
|
581
|
+
else:
|
|
582
|
+
print(f"[red]Unknown command: {command}[/red]")
|
|
583
|
+
print("Use 'praisonai hooks help' for available commands")
|