praisonai-code 0.0.1__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.
Files changed (309) hide show
  1. praisonai_code/__init__.py +17 -0
  2. praisonai_code/cli/__init__.py +12 -0
  3. praisonai_code/cli/_forward_shim.py +10 -0
  4. praisonai_code/cli/_paths.py +88 -0
  5. praisonai_code/cli/_warnings.py +58 -0
  6. praisonai_code/cli/app.py +757 -0
  7. praisonai_code/cli/approval_backend.py +272 -0
  8. praisonai_code/cli/branding.py +94 -0
  9. praisonai_code/cli/commands/__init__.py +114 -0
  10. praisonai_code/cli/commands/acp.py +80 -0
  11. praisonai_code/cli/commands/agent.py +116 -0
  12. praisonai_code/cli/commands/agents.py +80 -0
  13. praisonai_code/cli/commands/app.py +139 -0
  14. praisonai_code/cli/commands/attach.py +95 -0
  15. praisonai_code/cli/commands/audit.py +102 -0
  16. praisonai_code/cli/commands/auth.py +508 -0
  17. praisonai_code/cli/commands/batch.py +848 -0
  18. praisonai_code/cli/commands/benchmark.py +286 -0
  19. praisonai_code/cli/commands/browser.py +299 -0
  20. praisonai_code/cli/commands/call.py +45 -0
  21. praisonai_code/cli/commands/chat.py +332 -0
  22. praisonai_code/cli/commands/checkpoint.py +170 -0
  23. praisonai_code/cli/commands/code.py +276 -0
  24. praisonai_code/cli/commands/command.py +114 -0
  25. praisonai_code/cli/commands/commit.py +47 -0
  26. praisonai_code/cli/commands/completion.py +333 -0
  27. praisonai_code/cli/commands/config.py +681 -0
  28. praisonai_code/cli/commands/context.py +414 -0
  29. praisonai_code/cli/commands/daemon.py +203 -0
  30. praisonai_code/cli/commands/debug.py +142 -0
  31. praisonai_code/cli/commands/deploy.py +71 -0
  32. praisonai_code/cli/commands/diag.py +55 -0
  33. praisonai_code/cli/commands/docs.py +1575 -0
  34. praisonai_code/cli/commands/doctor.py +332 -0
  35. praisonai_code/cli/commands/endpoints.py +51 -0
  36. praisonai_code/cli/commands/environment.py +179 -0
  37. praisonai_code/cli/commands/eval.py +131 -0
  38. praisonai_code/cli/commands/examples.py +953 -0
  39. praisonai_code/cli/commands/flow.py +436 -0
  40. praisonai_code/cli/commands/github.py +752 -0
  41. praisonai_code/cli/commands/hooks.py +74 -0
  42. praisonai_code/cli/commands/init.py +174 -0
  43. praisonai_code/cli/commands/knowledge.py +440 -0
  44. praisonai_code/cli/commands/langextract.py +120 -0
  45. praisonai_code/cli/commands/langfuse.py +984 -0
  46. praisonai_code/cli/commands/loop.py +211 -0
  47. praisonai_code/cli/commands/lsp.py +112 -0
  48. praisonai_code/cli/commands/managed.py +659 -0
  49. praisonai_code/cli/commands/mcp.py +763 -0
  50. praisonai_code/cli/commands/memory.py +298 -0
  51. praisonai_code/cli/commands/models.py +264 -0
  52. praisonai_code/cli/commands/n8n.py +326 -0
  53. praisonai_code/cli/commands/obs.py +19 -0
  54. praisonai_code/cli/commands/package.py +76 -0
  55. praisonai_code/cli/commands/paths.py +106 -0
  56. praisonai_code/cli/commands/permissions.py +272 -0
  57. praisonai_code/cli/commands/plugins.py +609 -0
  58. praisonai_code/cli/commands/port.py +530 -0
  59. praisonai_code/cli/commands/profile.py +466 -0
  60. praisonai_code/cli/commands/publish.py +193 -0
  61. praisonai_code/cli/commands/rag.py +913 -0
  62. praisonai_code/cli/commands/realtime.py +52 -0
  63. praisonai_code/cli/commands/recipe.py +684 -0
  64. praisonai_code/cli/commands/registry.py +59 -0
  65. praisonai_code/cli/commands/replay.py +830 -0
  66. praisonai_code/cli/commands/research.py +49 -0
  67. praisonai_code/cli/commands/retrieval.py +377 -0
  68. praisonai_code/cli/commands/rules.py +71 -0
  69. praisonai_code/cli/commands/run.py +1573 -0
  70. praisonai_code/cli/commands/sandbox.py +371 -0
  71. praisonai_code/cli/commands/schedule.py +529 -0
  72. praisonai_code/cli/commands/serve.py +690 -0
  73. praisonai_code/cli/commands/session.py +450 -0
  74. praisonai_code/cli/commands/setup.py +174 -0
  75. praisonai_code/cli/commands/skills.py +545 -0
  76. praisonai_code/cli/commands/standardise.py +711 -0
  77. praisonai_code/cli/commands/templates.py +54 -0
  78. praisonai_code/cli/commands/test.py +558 -0
  79. praisonai_code/cli/commands/todo.py +74 -0
  80. praisonai_code/cli/commands/tools.py +205 -0
  81. praisonai_code/cli/commands/traces.py +145 -0
  82. praisonai_code/cli/commands/tracker.py +852 -0
  83. praisonai_code/cli/commands/train.py +613 -0
  84. praisonai_code/cli/commands/ui.py +172 -0
  85. praisonai_code/cli/commands/up.py +354 -0
  86. praisonai_code/cli/commands/validate.py +291 -0
  87. praisonai_code/cli/commands/version.py +101 -0
  88. praisonai_code/cli/commands/workflow.py +97 -0
  89. praisonai_code/cli/config_loader.py +437 -0
  90. praisonai_code/cli/configuration/__init__.py +27 -0
  91. praisonai_code/cli/configuration/config.schema.json +57 -0
  92. praisonai_code/cli/configuration/credentials.py +446 -0
  93. praisonai_code/cli/configuration/loader.py +364 -0
  94. praisonai_code/cli/configuration/model_resolver.py +161 -0
  95. praisonai_code/cli/configuration/oauth.py +389 -0
  96. praisonai_code/cli/configuration/paths.py +224 -0
  97. praisonai_code/cli/configuration/resolver.py +687 -0
  98. praisonai_code/cli/configuration/schema.py +317 -0
  99. praisonai_code/cli/execution/__init__.py +99 -0
  100. praisonai_code/cli/execution/core.py +208 -0
  101. praisonai_code/cli/execution/profiler.py +898 -0
  102. praisonai_code/cli/execution/request.py +85 -0
  103. praisonai_code/cli/execution/result.py +74 -0
  104. praisonai_code/cli/fallback_schema.py +416 -0
  105. praisonai_code/cli/features/__init__.py +278 -0
  106. praisonai_code/cli/features/_endpoint_registry.py +64 -0
  107. praisonai_code/cli/features/_search_registry.py +43 -0
  108. praisonai_code/cli/features/acp.py +236 -0
  109. praisonai_code/cli/features/action_orchestrator.py +576 -0
  110. praisonai_code/cli/features/agent_scheduler.py +773 -0
  111. praisonai_code/cli/features/agent_tools.py +603 -0
  112. praisonai_code/cli/features/agents.py +397 -0
  113. praisonai_code/cli/features/at_mentions.py +471 -0
  114. praisonai_code/cli/features/audit_cli.py +270 -0
  115. praisonai_code/cli/features/auto_memory.py +182 -0
  116. praisonai_code/cli/features/auto_mode.py +552 -0
  117. praisonai_code/cli/features/autonomy_mode.py +546 -0
  118. praisonai_code/cli/features/background.py +356 -0
  119. praisonai_code/cli/features/base.py +168 -0
  120. praisonai_code/cli/features/benchmark.py +1462 -0
  121. praisonai_code/cli/features/capabilities.py +1326 -0
  122. praisonai_code/cli/features/checkpoints.py +345 -0
  123. praisonai_code/cli/features/cli_profiler.py +335 -0
  124. praisonai_code/cli/features/code_intelligence.py +666 -0
  125. praisonai_code/cli/features/compaction.py +294 -0
  126. praisonai_code/cli/features/compare.py +534 -0
  127. praisonai_code/cli/features/config_hierarchy.py +366 -0
  128. praisonai_code/cli/features/context_manager.py +597 -0
  129. praisonai_code/cli/features/cost_tracker.py +514 -0
  130. praisonai_code/cli/features/csv_test_runner.py +736 -0
  131. praisonai_code/cli/features/custom_definitions.py +790 -0
  132. praisonai_code/cli/features/debug.py +810 -0
  133. praisonai_code/cli/features/deploy.py +605 -0
  134. praisonai_code/cli/features/diag.py +289 -0
  135. praisonai_code/cli/features/display_jsonl.py +173 -0
  136. praisonai_code/cli/features/doctor/__init__.py +63 -0
  137. praisonai_code/cli/features/doctor/checks/__init__.py +29 -0
  138. praisonai_code/cli/features/doctor/checks/acp_checks.py +220 -0
  139. praisonai_code/cli/features/doctor/checks/bot_checks.py +340 -0
  140. praisonai_code/cli/features/doctor/checks/config_checks.py +373 -0
  141. praisonai_code/cli/features/doctor/checks/db_checks.py +366 -0
  142. praisonai_code/cli/features/doctor/checks/env_checks.py +637 -0
  143. praisonai_code/cli/features/doctor/checks/gateway_checks.py +387 -0
  144. praisonai_code/cli/features/doctor/checks/lsp_checks.py +231 -0
  145. praisonai_code/cli/features/doctor/checks/mcp_checks.py +367 -0
  146. praisonai_code/cli/features/doctor/checks/memory_checks.py +268 -0
  147. praisonai_code/cli/features/doctor/checks/network_checks.py +251 -0
  148. praisonai_code/cli/features/doctor/checks/obs_checks.py +328 -0
  149. praisonai_code/cli/features/doctor/checks/packaging_checks.py +422 -0
  150. praisonai_code/cli/features/doctor/checks/performance_checks.py +235 -0
  151. praisonai_code/cli/features/doctor/checks/permissions_checks.py +259 -0
  152. praisonai_code/cli/features/doctor/checks/runtime_checks.py +650 -0
  153. praisonai_code/cli/features/doctor/checks/runtime_migration_checks.py +220 -0
  154. praisonai_code/cli/features/doctor/checks/selftest_checks.py +322 -0
  155. praisonai_code/cli/features/doctor/checks/serve_checks.py +426 -0
  156. praisonai_code/cli/features/doctor/checks/skills_checks.py +327 -0
  157. praisonai_code/cli/features/doctor/checks/tools_checks.py +371 -0
  158. praisonai_code/cli/features/doctor/engine.py +266 -0
  159. praisonai_code/cli/features/doctor/formatters.py +377 -0
  160. praisonai_code/cli/features/doctor/handler.py +564 -0
  161. praisonai_code/cli/features/doctor/models.py +276 -0
  162. praisonai_code/cli/features/doctor/registry.py +239 -0
  163. praisonai_code/cli/features/endpoints.py +1016 -0
  164. praisonai_code/cli/features/eval.py +559 -0
  165. praisonai_code/cli/features/examples.py +707 -0
  166. praisonai_code/cli/features/external_agents.py +231 -0
  167. praisonai_code/cli/features/fast_context.py +410 -0
  168. praisonai_code/cli/features/file_history.py +320 -0
  169. praisonai_code/cli/features/flow_display.py +566 -0
  170. praisonai_code/cli/features/git_attribution.py +159 -0
  171. praisonai_code/cli/features/git_integration.py +651 -0
  172. praisonai_code/cli/features/guardrail.py +171 -0
  173. praisonai_code/cli/features/handoff.py +252 -0
  174. praisonai_code/cli/features/hooks.py +583 -0
  175. praisonai_code/cli/features/hybrid_workflow.py +391 -0
  176. praisonai_code/cli/features/image.py +384 -0
  177. praisonai_code/cli/features/interactive_core_headless.py +450 -0
  178. praisonai_code/cli/features/interactive_runtime.py +600 -0
  179. praisonai_code/cli/features/interactive_test_harness.py +537 -0
  180. praisonai_code/cli/features/interactive_tools.py +428 -0
  181. praisonai_code/cli/features/interactive_tui.py +603 -0
  182. praisonai_code/cli/features/job_workflow.py +906 -0
  183. praisonai_code/cli/features/jobs.py +632 -0
  184. praisonai_code/cli/features/knowledge.py +531 -0
  185. praisonai_code/cli/features/knowledge_cli.py +438 -0
  186. praisonai_code/cli/features/lite.py +244 -0
  187. praisonai_code/cli/features/logs.py +200 -0
  188. praisonai_code/cli/features/lsp_cli.py +225 -0
  189. praisonai_code/cli/features/lsp_diagnostics.py +185 -0
  190. praisonai_code/cli/features/mcp.py +344 -0
  191. praisonai_code/cli/features/message_queue.py +587 -0
  192. praisonai_code/cli/features/metrics.py +210 -0
  193. praisonai_code/cli/features/migrate.py +1329 -0
  194. praisonai_code/cli/features/migration_flow.py +463 -0
  195. praisonai_code/cli/features/migration_spec.py +276 -0
  196. praisonai_code/cli/features/n8n.py +703 -0
  197. praisonai_code/cli/features/observability.py +293 -0
  198. praisonai_code/cli/features/ollama.py +361 -0
  199. praisonai_code/cli/features/output_modes.py +155 -0
  200. praisonai_code/cli/features/output_style.py +273 -0
  201. praisonai_code/cli/features/package.py +631 -0
  202. praisonai_code/cli/features/performance.py +308 -0
  203. praisonai_code/cli/features/persistence.py +636 -0
  204. praisonai_code/cli/features/profiler/__init__.py +81 -0
  205. praisonai_code/cli/features/profiler/core.py +558 -0
  206. praisonai_code/cli/features/profiler/optimizations.py +652 -0
  207. praisonai_code/cli/features/profiler/suite.py +386 -0
  208. praisonai_code/cli/features/queue/__init__.py +73 -0
  209. praisonai_code/cli/features/queue/manager.py +435 -0
  210. praisonai_code/cli/features/queue/models.py +289 -0
  211. praisonai_code/cli/features/queue/persistence.py +564 -0
  212. praisonai_code/cli/features/queue/scheduler.py +529 -0
  213. praisonai_code/cli/features/queue/worker.py +400 -0
  214. praisonai_code/cli/features/recipe.py +2187 -0
  215. praisonai_code/cli/features/recipe_creator.py +996 -0
  216. praisonai_code/cli/features/recipe_optimizer.py +1364 -0
  217. praisonai_code/cli/features/recipe_prompts.py +226 -0
  218. praisonai_code/cli/features/registry.py +229 -0
  219. praisonai_code/cli/features/repo_map.py +860 -0
  220. praisonai_code/cli/features/router.py +466 -0
  221. praisonai_code/cli/features/safe_shell.py +427 -0
  222. praisonai_code/cli/features/sandbox_cli.py +283 -0
  223. praisonai_code/cli/features/sandbox_executor.py +536 -0
  224. praisonai_code/cli/features/sdk_knowledge.py +500 -0
  225. praisonai_code/cli/features/session.py +222 -0
  226. praisonai_code/cli/features/session_checkpoints.py +208 -0
  227. praisonai_code/cli/features/setup/__init__.py +9 -0
  228. praisonai_code/cli/features/setup/handler.py +355 -0
  229. praisonai_code/cli/features/setup/templates.py +62 -0
  230. praisonai_code/cli/features/skills.py +940 -0
  231. praisonai_code/cli/features/slash_commands.py +692 -0
  232. praisonai_code/cli/features/telemetry.py +179 -0
  233. praisonai_code/cli/features/templates.py +1390 -0
  234. praisonai_code/cli/features/thinking.py +343 -0
  235. praisonai_code/cli/features/todo.py +334 -0
  236. praisonai_code/cli/features/tools.py +680 -0
  237. praisonai_code/cli/features/tui/__init__.py +83 -0
  238. praisonai_code/cli/features/tui/app.py +871 -0
  239. praisonai_code/cli/features/tui/cli.py +580 -0
  240. praisonai_code/cli/features/tui/config.py +150 -0
  241. praisonai_code/cli/features/tui/debug.py +526 -0
  242. praisonai_code/cli/features/tui/events.py +99 -0
  243. praisonai_code/cli/features/tui/mock_provider.py +328 -0
  244. praisonai_code/cli/features/tui/orchestrator.py +652 -0
  245. praisonai_code/cli/features/tui/screens/__init__.py +50 -0
  246. praisonai_code/cli/features/tui/screens/help.py +157 -0
  247. praisonai_code/cli/features/tui/screens/main.py +568 -0
  248. praisonai_code/cli/features/tui/screens/queue.py +174 -0
  249. praisonai_code/cli/features/tui/screens/session.py +124 -0
  250. praisonai_code/cli/features/tui/screens/settings.py +148 -0
  251. praisonai_code/cli/features/tui/session_store.py +198 -0
  252. praisonai_code/cli/features/tui/widgets/__init__.py +56 -0
  253. praisonai_code/cli/features/tui/widgets/chat.py +263 -0
  254. praisonai_code/cli/features/tui/widgets/command_popup.py +258 -0
  255. praisonai_code/cli/features/tui/widgets/composer.py +292 -0
  256. praisonai_code/cli/features/tui/widgets/file_popup.py +207 -0
  257. praisonai_code/cli/features/tui/widgets/queue_panel.py +223 -0
  258. praisonai_code/cli/features/tui/widgets/status.py +181 -0
  259. praisonai_code/cli/features/tui/widgets/tool_panel.py +307 -0
  260. praisonai_code/cli/features/wizard.py +289 -0
  261. praisonai_code/cli/features/workflow.py +802 -0
  262. praisonai_code/cli/features/yaml_utils.py +321 -0
  263. praisonai_code/cli/interactive/__init__.py +48 -0
  264. praisonai_code/cli/interactive/async_tui.py +1218 -0
  265. praisonai_code/cli/interactive/config.py +139 -0
  266. praisonai_code/cli/interactive/core.py +618 -0
  267. praisonai_code/cli/interactive/events.py +131 -0
  268. praisonai_code/cli/interactive/frontends/__init__.py +31 -0
  269. praisonai_code/cli/interactive/frontends/rich_frontend.py +462 -0
  270. praisonai_code/cli/interactive/frontends/textual_frontend.py +157 -0
  271. praisonai_code/cli/interactive/praison_io.py +502 -0
  272. praisonai_code/cli/interactive/repl.py +297 -0
  273. praisonai_code/cli/interactive/split_tui.py +456 -0
  274. praisonai_code/cli/interactive/tui_app.py +457 -0
  275. praisonai_code/cli/langfuse_client.py +360 -0
  276. praisonai_code/cli/main.py +7421 -0
  277. praisonai_code/cli/output/__init__.py +25 -0
  278. praisonai_code/cli/output/console.py +456 -0
  279. praisonai_code/cli/output/event_bridge.py +191 -0
  280. praisonai_code/cli/schedule_cli.py +54 -0
  281. praisonai_code/cli/schema_provider.py +23 -0
  282. praisonai_code/cli/session/__init__.py +16 -0
  283. praisonai_code/cli/session/resume.py +148 -0
  284. praisonai_code/cli/session/unified.py +548 -0
  285. praisonai_code/cli/state/__init__.py +31 -0
  286. praisonai_code/cli/state/identifiers.py +161 -0
  287. praisonai_code/cli/state/project_sessions.py +383 -0
  288. praisonai_code/cli/state/sessions.py +390 -0
  289. praisonai_code/cli/ui/__init__.py +160 -0
  290. praisonai_code/cli/ui/config.py +46 -0
  291. praisonai_code/cli/ui/events.py +61 -0
  292. praisonai_code/cli/ui/mg_backend.py +342 -0
  293. praisonai_code/cli/ui/plain.py +133 -0
  294. praisonai_code/cli/ui/rich_backend.py +162 -0
  295. praisonai_code/cli/unified_schema.py +655 -0
  296. praisonai_code/cli/utils/env_utils.py +126 -0
  297. praisonai_code/cli/utils/project.py +131 -0
  298. praisonai_code/cli_backends/__init__.py +73 -0
  299. praisonai_code/cli_backends/claude.py +373 -0
  300. praisonai_code/cli_backends/registry.py +113 -0
  301. praisonai_code/runtime/__init__.py +36 -0
  302. praisonai_code/runtime/__main__.py +81 -0
  303. praisonai_code/runtime/client.py +131 -0
  304. praisonai_code/runtime/descriptor.py +209 -0
  305. praisonai_code/runtime/server.py +356 -0
  306. praisonai_code-0.0.1.dist-info/METADATA +80 -0
  307. praisonai_code-0.0.1.dist-info/RECORD +309 -0
  308. praisonai_code-0.0.1.dist-info/WHEEL +5 -0
  309. praisonai_code-0.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,205 @@
1
+ """
2
+ Tools command group for PraisonAI CLI.
3
+
4
+ Provides tool management commands including:
5
+ - List available tools from all sources
6
+ - Validate YAML tool references
7
+ - Show tool information
8
+ """
9
+
10
+ from typing import Optional
11
+
12
+ import typer
13
+ from rich.console import Console
14
+ from rich.table import Table
15
+
16
+ app = typer.Typer(help="Tool management and discovery")
17
+ console = Console()
18
+
19
+
20
+ @app.command("list")
21
+ def tools_list(
22
+ source: Optional[str] = typer.Option(
23
+ None, "--source", "-s",
24
+ help="Filter by source: builtin, local, external, registered"
25
+ ),
26
+ verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed info"),
27
+ ):
28
+ """List all available tools that can be used in YAML files.
29
+
30
+ Shows tools from:
31
+ - Built-in tools (praisonaiagents.tools)
32
+ - Local tools.py (if present)
33
+ - External tools (praisonai-tools package)
34
+ - Registered/entry-point tools (core registry plugins)
35
+ """
36
+ from praisonai.tool_resolver import ToolResolver
37
+
38
+ resolver = ToolResolver()
39
+ available = resolver.list_available()
40
+ sources = resolver.list_available_sources()
41
+
42
+ if not available:
43
+ console.print("[yellow]No tools available.[/yellow]")
44
+ return
45
+
46
+ # Categorize tools by their authoritative resolution source (not by
47
+ # substring matching on the description, which may come from a docstring).
48
+ builtin_tools = {}
49
+ local_tools = {}
50
+ external_tools = {}
51
+ registered_tools = {}
52
+ bucket = {
53
+ "local": local_tools,
54
+ "external": external_tools,
55
+ "registered": registered_tools,
56
+ "builtin": builtin_tools,
57
+ }
58
+ for name, desc in available.items():
59
+ bucket.get(sources.get(name, "builtin"), builtin_tools)[name] = desc
60
+
61
+ # Filter by source if specified
62
+ if source == "builtin":
63
+ available = builtin_tools
64
+ elif source == "local":
65
+ available = local_tools
66
+ elif source == "external":
67
+ available = external_tools
68
+ elif source == "registered":
69
+ available = registered_tools
70
+
71
+ # Create table
72
+ table = Table(title="Available Tools", show_header=True, header_style="bold cyan")
73
+ table.add_column("Tool Name", style="green")
74
+ table.add_column("Source", style="blue")
75
+ if verbose:
76
+ table.add_column("Description", style="dim")
77
+
78
+ # Add rows
79
+ for name in sorted(available.keys()):
80
+ desc = available[name]
81
+ src = sources.get(name, "builtin")
82
+
83
+ if verbose:
84
+ table.add_row(name, src, desc[:60] + "..." if len(desc) > 60 else desc)
85
+ else:
86
+ table.add_row(name, src)
87
+
88
+ console.print(table)
89
+ console.print(f"\n[dim]Total: {len(available)} tools[/dim]")
90
+
91
+ if not source:
92
+ console.print(f"[dim] Built-in: {len(builtin_tools)} | Local: {len(local_tools)} | External: {len(external_tools)} | Registered: {len(registered_tools)}[/dim]")
93
+
94
+
95
+ @app.command("validate")
96
+ def tools_validate(
97
+ yaml_file: str = typer.Argument("agents.yaml", help="YAML file to validate"),
98
+ ):
99
+ """Validate that all tools in a YAML file can be resolved.
100
+
101
+ Checks that every tool name in the YAML can be found in:
102
+ - Local tools.py
103
+ - Built-in tools (praisonaiagents.tools)
104
+ - External tools (praisonai-tools)
105
+ """
106
+ import yaml
107
+ from pathlib import Path
108
+ from praisonai.tool_resolver import ToolResolver
109
+
110
+ yaml_path = Path(yaml_file)
111
+ if not yaml_path.exists():
112
+ console.print(f"[red]Error: File not found: {yaml_file}[/red]")
113
+ raise typer.Exit(1)
114
+
115
+ try:
116
+ with open(yaml_path) as f:
117
+ config = yaml.safe_load(f)
118
+ except Exception as e:
119
+ console.print(f"[red]Error parsing YAML: {e}[/red]")
120
+ raise typer.Exit(1)
121
+
122
+ resolver = ToolResolver()
123
+ missing = resolver.validate_yaml_tools(config)
124
+
125
+ if not missing:
126
+ console.print(f"[green]✓ All tools in {yaml_file} are valid![/green]")
127
+
128
+ # Show which tools were found
129
+ roles = config.get('roles', config.get('agents', {}))
130
+ all_tools = set()
131
+ for role_config in roles.values():
132
+ if isinstance(role_config, dict):
133
+ all_tools.update(role_config.get('tools', []))
134
+
135
+ if all_tools:
136
+ console.print(f"[dim]Tools found: {', '.join(sorted(all_tools))}[/dim]")
137
+ else:
138
+ console.print(f"[red]✗ Missing tools in {yaml_file}:[/red]")
139
+ for tool in missing:
140
+ console.print(f" [red]• {tool}[/red]")
141
+
142
+ console.print("\n[yellow]Hint: Run 'praisonai tools list' to see available tools.[/yellow]")
143
+ raise typer.Exit(1)
144
+
145
+
146
+ @app.command("info")
147
+ def tools_info(
148
+ name: str = typer.Argument(..., help="Tool name"),
149
+ ):
150
+ """Show detailed information about a tool."""
151
+ from praisonai.tool_resolver import ToolResolver
152
+
153
+ resolver = ToolResolver()
154
+ tool = resolver.resolve(name)
155
+
156
+ if tool is None:
157
+ console.print(f"[red]Tool '{name}' not found.[/red]")
158
+ console.print("[yellow]Hint: Run 'praisonai tools list' to see available tools.[/yellow]")
159
+ raise typer.Exit(1)
160
+
161
+ console.print(f"\n[bold green]{name}[/bold green]")
162
+ console.print("-" * 40)
163
+
164
+ # Get docstring
165
+ doc = getattr(tool, '__doc__', None)
166
+ if doc:
167
+ console.print(f"[dim]{doc}[/dim]")
168
+
169
+ # Get signature if possible
170
+ import inspect
171
+ try:
172
+ sig = inspect.signature(tool)
173
+ console.print(f"\n[cyan]Signature:[/cyan] {name}{sig}")
174
+ except (ValueError, TypeError):
175
+ pass
176
+
177
+ # Show source (authoritative, matches runtime resolution precedence)
178
+ sources = resolver.list_available_sources()
179
+ if name in sources:
180
+ labels = {
181
+ "local": "Local tools.py",
182
+ "external": "praisonai-tools package",
183
+ "registered": "Registered/entry-point tool (registry)",
184
+ "builtin": "praisonaiagents.tools (built-in)",
185
+ }
186
+ console.print(f"\n[blue]Source:[/blue] {labels.get(sources[name], labels['builtin'])}")
187
+
188
+
189
+ @app.command("test")
190
+ def tools_test(
191
+ name: str = typer.Argument(..., help="Tool name to test"),
192
+ ):
193
+ """Test a tool with a simple invocation."""
194
+ from praisonai.tool_resolver import ToolResolver
195
+
196
+ resolver = ToolResolver()
197
+ tool = resolver.resolve(name)
198
+
199
+ if tool is None:
200
+ console.print(f"[red]Tool '{name}' not found.[/red]")
201
+ raise typer.Exit(1)
202
+
203
+ console.print(f"[green]✓ Tool '{name}' resolved successfully![/green]")
204
+ console.print(f"[dim]Type: {type(tool).__name__}[/dim]")
205
+ console.print(f"[dim]Callable: {callable(tool)}[/dim]")
@@ -0,0 +1,145 @@
1
+ """
2
+ Traces command group for PraisonAI CLI.
3
+
4
+ Provides trace collection management:
5
+ - traces enable: Enable trace collection
6
+ - traces disable: Disable trace collection
7
+ - traces status: Show current status
8
+ - traces list: List recent traces
9
+ """
10
+
11
+ from typing import Optional
12
+
13
+ import typer
14
+
15
+ from ..configuration.loader import get_config_loader
16
+ from ..output.console import get_output_controller
17
+
18
+ app = typer.Typer(help="Trace collection management")
19
+
20
+
21
+ @app.command("enable")
22
+ def traces_enable(
23
+ endpoint: Optional[str] = typer.Option(
24
+ None,
25
+ "--endpoint",
26
+ "-e",
27
+ help="Trace endpoint URL",
28
+ ),
29
+ sample_rate: float = typer.Option(
30
+ 1.0,
31
+ "--sample-rate",
32
+ "-r",
33
+ help="Sample rate (0.0 to 1.0)",
34
+ ),
35
+ ):
36
+ """Enable trace collection."""
37
+ output = get_output_controller()
38
+ loader = get_config_loader()
39
+
40
+ loader.set("traces.enabled", True)
41
+ if endpoint:
42
+ loader.set("traces.endpoint", endpoint)
43
+ if sample_rate != 1.0:
44
+ loader.set("traces.sample_rate", sample_rate)
45
+
46
+ if output.is_json_mode:
47
+ output.print_json({
48
+ "traces_enabled": True,
49
+ "endpoint": endpoint,
50
+ "sample_rate": sample_rate,
51
+ })
52
+ else:
53
+ output.print_success("Trace collection enabled")
54
+ if endpoint:
55
+ output.print(f" Endpoint: {endpoint}")
56
+ output.print(f" Sample rate: {sample_rate}")
57
+
58
+
59
+ @app.command("disable")
60
+ def traces_disable():
61
+ """Disable trace collection."""
62
+ output = get_output_controller()
63
+ loader = get_config_loader()
64
+
65
+ loader.set("traces.enabled", False)
66
+
67
+ if output.is_json_mode:
68
+ output.print_json({"traces_enabled": False})
69
+ else:
70
+ output.print_success("Trace collection disabled")
71
+
72
+
73
+ @app.command("status")
74
+ def traces_status():
75
+ """Show trace collection status."""
76
+ output = get_output_controller()
77
+ loader = get_config_loader()
78
+
79
+ enabled = loader.get("traces.enabled", False)
80
+ endpoint = loader.get("traces.endpoint")
81
+ sample_rate = loader.get("traces.sample_rate", 1.0)
82
+
83
+ if output.is_json_mode:
84
+ output.print_json({
85
+ "enabled": enabled,
86
+ "endpoint": endpoint,
87
+ "sample_rate": sample_rate,
88
+ })
89
+ else:
90
+ status = "✅ Enabled" if enabled else "❌ Disabled"
91
+ output.print_panel(
92
+ f"Status: {status}\n"
93
+ f"Endpoint: {endpoint or 'Not configured'}\n"
94
+ f"Sample Rate: {sample_rate}",
95
+ title="Trace Collection Status"
96
+ )
97
+
98
+
99
+ @app.command("list")
100
+ def traces_list(
101
+ limit: int = typer.Option(
102
+ 20,
103
+ "--limit",
104
+ "-n",
105
+ help="Maximum number of traces to show",
106
+ ),
107
+ ):
108
+ """List recent traces."""
109
+ output = get_output_controller()
110
+
111
+ from ..configuration.paths import get_traces_dir
112
+
113
+ traces_dir = get_traces_dir()
114
+
115
+ if not traces_dir.exists():
116
+ if output.is_json_mode:
117
+ output.print_json({"traces": []})
118
+ else:
119
+ output.print_info("No traces found")
120
+ return
121
+
122
+ traces = []
123
+ for trace_file in sorted(traces_dir.iterdir(), reverse=True)[:limit]:
124
+ if trace_file.is_file() and trace_file.suffix == ".json":
125
+ traces.append({
126
+ "name": trace_file.stem,
127
+ "size": trace_file.stat().st_size,
128
+ "modified": trace_file.stat().st_mtime,
129
+ })
130
+
131
+ if output.is_json_mode:
132
+ output.print_json({"traces": traces})
133
+ else:
134
+ if not traces:
135
+ output.print_info("No traces found")
136
+ return
137
+
138
+ headers = ["Name", "Size", "Modified"]
139
+ rows = []
140
+ for t in traces:
141
+ from datetime import datetime
142
+ modified = datetime.fromtimestamp(t["modified"]).strftime("%Y-%m-%d %H:%M")
143
+ rows.append([t["name"], f"{t['size']} bytes", modified])
144
+
145
+ output.print_table(headers, rows, title="Recent Traces")