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.
- praisonai_code/__init__.py +17 -0
- praisonai_code/cli/__init__.py +12 -0
- praisonai_code/cli/_forward_shim.py +10 -0
- praisonai_code/cli/_paths.py +88 -0
- praisonai_code/cli/_warnings.py +58 -0
- praisonai_code/cli/app.py +757 -0
- praisonai_code/cli/approval_backend.py +272 -0
- praisonai_code/cli/branding.py +94 -0
- praisonai_code/cli/commands/__init__.py +114 -0
- praisonai_code/cli/commands/acp.py +80 -0
- praisonai_code/cli/commands/agent.py +116 -0
- praisonai_code/cli/commands/agents.py +80 -0
- praisonai_code/cli/commands/app.py +139 -0
- praisonai_code/cli/commands/attach.py +95 -0
- praisonai_code/cli/commands/audit.py +102 -0
- praisonai_code/cli/commands/auth.py +508 -0
- praisonai_code/cli/commands/batch.py +848 -0
- praisonai_code/cli/commands/benchmark.py +286 -0
- praisonai_code/cli/commands/browser.py +299 -0
- praisonai_code/cli/commands/call.py +45 -0
- praisonai_code/cli/commands/chat.py +332 -0
- praisonai_code/cli/commands/checkpoint.py +170 -0
- praisonai_code/cli/commands/code.py +276 -0
- praisonai_code/cli/commands/command.py +114 -0
- praisonai_code/cli/commands/commit.py +47 -0
- praisonai_code/cli/commands/completion.py +333 -0
- praisonai_code/cli/commands/config.py +681 -0
- praisonai_code/cli/commands/context.py +414 -0
- praisonai_code/cli/commands/daemon.py +203 -0
- praisonai_code/cli/commands/debug.py +142 -0
- praisonai_code/cli/commands/deploy.py +71 -0
- praisonai_code/cli/commands/diag.py +55 -0
- praisonai_code/cli/commands/docs.py +1575 -0
- praisonai_code/cli/commands/doctor.py +332 -0
- praisonai_code/cli/commands/endpoints.py +51 -0
- praisonai_code/cli/commands/environment.py +179 -0
- praisonai_code/cli/commands/eval.py +131 -0
- praisonai_code/cli/commands/examples.py +953 -0
- praisonai_code/cli/commands/flow.py +436 -0
- praisonai_code/cli/commands/github.py +752 -0
- praisonai_code/cli/commands/hooks.py +74 -0
- praisonai_code/cli/commands/init.py +174 -0
- praisonai_code/cli/commands/knowledge.py +440 -0
- praisonai_code/cli/commands/langextract.py +120 -0
- praisonai_code/cli/commands/langfuse.py +984 -0
- praisonai_code/cli/commands/loop.py +211 -0
- praisonai_code/cli/commands/lsp.py +112 -0
- praisonai_code/cli/commands/managed.py +659 -0
- praisonai_code/cli/commands/mcp.py +763 -0
- praisonai_code/cli/commands/memory.py +298 -0
- praisonai_code/cli/commands/models.py +264 -0
- praisonai_code/cli/commands/n8n.py +326 -0
- praisonai_code/cli/commands/obs.py +19 -0
- praisonai_code/cli/commands/package.py +76 -0
- praisonai_code/cli/commands/paths.py +106 -0
- praisonai_code/cli/commands/permissions.py +272 -0
- praisonai_code/cli/commands/plugins.py +609 -0
- praisonai_code/cli/commands/port.py +530 -0
- praisonai_code/cli/commands/profile.py +466 -0
- praisonai_code/cli/commands/publish.py +193 -0
- praisonai_code/cli/commands/rag.py +913 -0
- praisonai_code/cli/commands/realtime.py +52 -0
- praisonai_code/cli/commands/recipe.py +684 -0
- praisonai_code/cli/commands/registry.py +59 -0
- praisonai_code/cli/commands/replay.py +830 -0
- praisonai_code/cli/commands/research.py +49 -0
- praisonai_code/cli/commands/retrieval.py +377 -0
- praisonai_code/cli/commands/rules.py +71 -0
- praisonai_code/cli/commands/run.py +1573 -0
- praisonai_code/cli/commands/sandbox.py +371 -0
- praisonai_code/cli/commands/schedule.py +529 -0
- praisonai_code/cli/commands/serve.py +690 -0
- praisonai_code/cli/commands/session.py +450 -0
- praisonai_code/cli/commands/setup.py +174 -0
- praisonai_code/cli/commands/skills.py +545 -0
- praisonai_code/cli/commands/standardise.py +711 -0
- praisonai_code/cli/commands/templates.py +54 -0
- praisonai_code/cli/commands/test.py +558 -0
- praisonai_code/cli/commands/todo.py +74 -0
- praisonai_code/cli/commands/tools.py +205 -0
- praisonai_code/cli/commands/traces.py +145 -0
- praisonai_code/cli/commands/tracker.py +852 -0
- praisonai_code/cli/commands/train.py +613 -0
- praisonai_code/cli/commands/ui.py +172 -0
- praisonai_code/cli/commands/up.py +354 -0
- praisonai_code/cli/commands/validate.py +291 -0
- praisonai_code/cli/commands/version.py +101 -0
- praisonai_code/cli/commands/workflow.py +97 -0
- praisonai_code/cli/config_loader.py +437 -0
- praisonai_code/cli/configuration/__init__.py +27 -0
- praisonai_code/cli/configuration/config.schema.json +57 -0
- praisonai_code/cli/configuration/credentials.py +446 -0
- praisonai_code/cli/configuration/loader.py +364 -0
- praisonai_code/cli/configuration/model_resolver.py +161 -0
- praisonai_code/cli/configuration/oauth.py +389 -0
- praisonai_code/cli/configuration/paths.py +224 -0
- praisonai_code/cli/configuration/resolver.py +687 -0
- praisonai_code/cli/configuration/schema.py +317 -0
- praisonai_code/cli/execution/__init__.py +99 -0
- praisonai_code/cli/execution/core.py +208 -0
- praisonai_code/cli/execution/profiler.py +898 -0
- praisonai_code/cli/execution/request.py +85 -0
- praisonai_code/cli/execution/result.py +74 -0
- praisonai_code/cli/fallback_schema.py +416 -0
- praisonai_code/cli/features/__init__.py +278 -0
- praisonai_code/cli/features/_endpoint_registry.py +64 -0
- praisonai_code/cli/features/_search_registry.py +43 -0
- praisonai_code/cli/features/acp.py +236 -0
- praisonai_code/cli/features/action_orchestrator.py +576 -0
- praisonai_code/cli/features/agent_scheduler.py +773 -0
- praisonai_code/cli/features/agent_tools.py +603 -0
- praisonai_code/cli/features/agents.py +397 -0
- praisonai_code/cli/features/at_mentions.py +471 -0
- praisonai_code/cli/features/audit_cli.py +270 -0
- praisonai_code/cli/features/auto_memory.py +182 -0
- praisonai_code/cli/features/auto_mode.py +552 -0
- praisonai_code/cli/features/autonomy_mode.py +546 -0
- praisonai_code/cli/features/background.py +356 -0
- praisonai_code/cli/features/base.py +168 -0
- praisonai_code/cli/features/benchmark.py +1462 -0
- praisonai_code/cli/features/capabilities.py +1326 -0
- praisonai_code/cli/features/checkpoints.py +345 -0
- praisonai_code/cli/features/cli_profiler.py +335 -0
- praisonai_code/cli/features/code_intelligence.py +666 -0
- praisonai_code/cli/features/compaction.py +294 -0
- praisonai_code/cli/features/compare.py +534 -0
- praisonai_code/cli/features/config_hierarchy.py +366 -0
- praisonai_code/cli/features/context_manager.py +597 -0
- praisonai_code/cli/features/cost_tracker.py +514 -0
- praisonai_code/cli/features/csv_test_runner.py +736 -0
- praisonai_code/cli/features/custom_definitions.py +790 -0
- praisonai_code/cli/features/debug.py +810 -0
- praisonai_code/cli/features/deploy.py +605 -0
- praisonai_code/cli/features/diag.py +289 -0
- praisonai_code/cli/features/display_jsonl.py +173 -0
- praisonai_code/cli/features/doctor/__init__.py +63 -0
- praisonai_code/cli/features/doctor/checks/__init__.py +29 -0
- praisonai_code/cli/features/doctor/checks/acp_checks.py +220 -0
- praisonai_code/cli/features/doctor/checks/bot_checks.py +340 -0
- praisonai_code/cli/features/doctor/checks/config_checks.py +373 -0
- praisonai_code/cli/features/doctor/checks/db_checks.py +366 -0
- praisonai_code/cli/features/doctor/checks/env_checks.py +637 -0
- praisonai_code/cli/features/doctor/checks/gateway_checks.py +387 -0
- praisonai_code/cli/features/doctor/checks/lsp_checks.py +231 -0
- praisonai_code/cli/features/doctor/checks/mcp_checks.py +367 -0
- praisonai_code/cli/features/doctor/checks/memory_checks.py +268 -0
- praisonai_code/cli/features/doctor/checks/network_checks.py +251 -0
- praisonai_code/cli/features/doctor/checks/obs_checks.py +328 -0
- praisonai_code/cli/features/doctor/checks/packaging_checks.py +422 -0
- praisonai_code/cli/features/doctor/checks/performance_checks.py +235 -0
- praisonai_code/cli/features/doctor/checks/permissions_checks.py +259 -0
- praisonai_code/cli/features/doctor/checks/runtime_checks.py +650 -0
- praisonai_code/cli/features/doctor/checks/runtime_migration_checks.py +220 -0
- praisonai_code/cli/features/doctor/checks/selftest_checks.py +322 -0
- praisonai_code/cli/features/doctor/checks/serve_checks.py +426 -0
- praisonai_code/cli/features/doctor/checks/skills_checks.py +327 -0
- praisonai_code/cli/features/doctor/checks/tools_checks.py +371 -0
- praisonai_code/cli/features/doctor/engine.py +266 -0
- praisonai_code/cli/features/doctor/formatters.py +377 -0
- praisonai_code/cli/features/doctor/handler.py +564 -0
- praisonai_code/cli/features/doctor/models.py +276 -0
- praisonai_code/cli/features/doctor/registry.py +239 -0
- praisonai_code/cli/features/endpoints.py +1016 -0
- praisonai_code/cli/features/eval.py +559 -0
- praisonai_code/cli/features/examples.py +707 -0
- praisonai_code/cli/features/external_agents.py +231 -0
- praisonai_code/cli/features/fast_context.py +410 -0
- praisonai_code/cli/features/file_history.py +320 -0
- praisonai_code/cli/features/flow_display.py +566 -0
- praisonai_code/cli/features/git_attribution.py +159 -0
- praisonai_code/cli/features/git_integration.py +651 -0
- praisonai_code/cli/features/guardrail.py +171 -0
- praisonai_code/cli/features/handoff.py +252 -0
- praisonai_code/cli/features/hooks.py +583 -0
- praisonai_code/cli/features/hybrid_workflow.py +391 -0
- praisonai_code/cli/features/image.py +384 -0
- praisonai_code/cli/features/interactive_core_headless.py +450 -0
- praisonai_code/cli/features/interactive_runtime.py +600 -0
- praisonai_code/cli/features/interactive_test_harness.py +537 -0
- praisonai_code/cli/features/interactive_tools.py +428 -0
- praisonai_code/cli/features/interactive_tui.py +603 -0
- praisonai_code/cli/features/job_workflow.py +906 -0
- praisonai_code/cli/features/jobs.py +632 -0
- praisonai_code/cli/features/knowledge.py +531 -0
- praisonai_code/cli/features/knowledge_cli.py +438 -0
- praisonai_code/cli/features/lite.py +244 -0
- praisonai_code/cli/features/logs.py +200 -0
- praisonai_code/cli/features/lsp_cli.py +225 -0
- praisonai_code/cli/features/lsp_diagnostics.py +185 -0
- praisonai_code/cli/features/mcp.py +344 -0
- praisonai_code/cli/features/message_queue.py +587 -0
- praisonai_code/cli/features/metrics.py +210 -0
- praisonai_code/cli/features/migrate.py +1329 -0
- praisonai_code/cli/features/migration_flow.py +463 -0
- praisonai_code/cli/features/migration_spec.py +276 -0
- praisonai_code/cli/features/n8n.py +703 -0
- praisonai_code/cli/features/observability.py +293 -0
- praisonai_code/cli/features/ollama.py +361 -0
- praisonai_code/cli/features/output_modes.py +155 -0
- praisonai_code/cli/features/output_style.py +273 -0
- praisonai_code/cli/features/package.py +631 -0
- praisonai_code/cli/features/performance.py +308 -0
- praisonai_code/cli/features/persistence.py +636 -0
- praisonai_code/cli/features/profiler/__init__.py +81 -0
- praisonai_code/cli/features/profiler/core.py +558 -0
- praisonai_code/cli/features/profiler/optimizations.py +652 -0
- praisonai_code/cli/features/profiler/suite.py +386 -0
- praisonai_code/cli/features/queue/__init__.py +73 -0
- praisonai_code/cli/features/queue/manager.py +435 -0
- praisonai_code/cli/features/queue/models.py +289 -0
- praisonai_code/cli/features/queue/persistence.py +564 -0
- praisonai_code/cli/features/queue/scheduler.py +529 -0
- praisonai_code/cli/features/queue/worker.py +400 -0
- praisonai_code/cli/features/recipe.py +2187 -0
- praisonai_code/cli/features/recipe_creator.py +996 -0
- praisonai_code/cli/features/recipe_optimizer.py +1364 -0
- praisonai_code/cli/features/recipe_prompts.py +226 -0
- praisonai_code/cli/features/registry.py +229 -0
- praisonai_code/cli/features/repo_map.py +860 -0
- praisonai_code/cli/features/router.py +466 -0
- praisonai_code/cli/features/safe_shell.py +427 -0
- praisonai_code/cli/features/sandbox_cli.py +283 -0
- praisonai_code/cli/features/sandbox_executor.py +536 -0
- praisonai_code/cli/features/sdk_knowledge.py +500 -0
- praisonai_code/cli/features/session.py +222 -0
- praisonai_code/cli/features/session_checkpoints.py +208 -0
- praisonai_code/cli/features/setup/__init__.py +9 -0
- praisonai_code/cli/features/setup/handler.py +355 -0
- praisonai_code/cli/features/setup/templates.py +62 -0
- praisonai_code/cli/features/skills.py +940 -0
- praisonai_code/cli/features/slash_commands.py +692 -0
- praisonai_code/cli/features/telemetry.py +179 -0
- praisonai_code/cli/features/templates.py +1390 -0
- praisonai_code/cli/features/thinking.py +343 -0
- praisonai_code/cli/features/todo.py +334 -0
- praisonai_code/cli/features/tools.py +680 -0
- praisonai_code/cli/features/tui/__init__.py +83 -0
- praisonai_code/cli/features/tui/app.py +871 -0
- praisonai_code/cli/features/tui/cli.py +580 -0
- praisonai_code/cli/features/tui/config.py +150 -0
- praisonai_code/cli/features/tui/debug.py +526 -0
- praisonai_code/cli/features/tui/events.py +99 -0
- praisonai_code/cli/features/tui/mock_provider.py +328 -0
- praisonai_code/cli/features/tui/orchestrator.py +652 -0
- praisonai_code/cli/features/tui/screens/__init__.py +50 -0
- praisonai_code/cli/features/tui/screens/help.py +157 -0
- praisonai_code/cli/features/tui/screens/main.py +568 -0
- praisonai_code/cli/features/tui/screens/queue.py +174 -0
- praisonai_code/cli/features/tui/screens/session.py +124 -0
- praisonai_code/cli/features/tui/screens/settings.py +148 -0
- praisonai_code/cli/features/tui/session_store.py +198 -0
- praisonai_code/cli/features/tui/widgets/__init__.py +56 -0
- praisonai_code/cli/features/tui/widgets/chat.py +263 -0
- praisonai_code/cli/features/tui/widgets/command_popup.py +258 -0
- praisonai_code/cli/features/tui/widgets/composer.py +292 -0
- praisonai_code/cli/features/tui/widgets/file_popup.py +207 -0
- praisonai_code/cli/features/tui/widgets/queue_panel.py +223 -0
- praisonai_code/cli/features/tui/widgets/status.py +181 -0
- praisonai_code/cli/features/tui/widgets/tool_panel.py +307 -0
- praisonai_code/cli/features/wizard.py +289 -0
- praisonai_code/cli/features/workflow.py +802 -0
- praisonai_code/cli/features/yaml_utils.py +321 -0
- praisonai_code/cli/interactive/__init__.py +48 -0
- praisonai_code/cli/interactive/async_tui.py +1218 -0
- praisonai_code/cli/interactive/config.py +139 -0
- praisonai_code/cli/interactive/core.py +618 -0
- praisonai_code/cli/interactive/events.py +131 -0
- praisonai_code/cli/interactive/frontends/__init__.py +31 -0
- praisonai_code/cli/interactive/frontends/rich_frontend.py +462 -0
- praisonai_code/cli/interactive/frontends/textual_frontend.py +157 -0
- praisonai_code/cli/interactive/praison_io.py +502 -0
- praisonai_code/cli/interactive/repl.py +297 -0
- praisonai_code/cli/interactive/split_tui.py +456 -0
- praisonai_code/cli/interactive/tui_app.py +457 -0
- praisonai_code/cli/langfuse_client.py +360 -0
- praisonai_code/cli/main.py +7421 -0
- praisonai_code/cli/output/__init__.py +25 -0
- praisonai_code/cli/output/console.py +456 -0
- praisonai_code/cli/output/event_bridge.py +191 -0
- praisonai_code/cli/schedule_cli.py +54 -0
- praisonai_code/cli/schema_provider.py +23 -0
- praisonai_code/cli/session/__init__.py +16 -0
- praisonai_code/cli/session/resume.py +148 -0
- praisonai_code/cli/session/unified.py +548 -0
- praisonai_code/cli/state/__init__.py +31 -0
- praisonai_code/cli/state/identifiers.py +161 -0
- praisonai_code/cli/state/project_sessions.py +383 -0
- praisonai_code/cli/state/sessions.py +390 -0
- praisonai_code/cli/ui/__init__.py +160 -0
- praisonai_code/cli/ui/config.py +46 -0
- praisonai_code/cli/ui/events.py +61 -0
- praisonai_code/cli/ui/mg_backend.py +342 -0
- praisonai_code/cli/ui/plain.py +133 -0
- praisonai_code/cli/ui/rich_backend.py +162 -0
- praisonai_code/cli/unified_schema.py +655 -0
- praisonai_code/cli/utils/env_utils.py +126 -0
- praisonai_code/cli/utils/project.py +131 -0
- praisonai_code/cli_backends/__init__.py +73 -0
- praisonai_code/cli_backends/claude.py +373 -0
- praisonai_code/cli_backends/registry.py +113 -0
- praisonai_code/runtime/__init__.py +36 -0
- praisonai_code/runtime/__main__.py +81 -0
- praisonai_code/runtime/client.py +131 -0
- praisonai_code/runtime/descriptor.py +209 -0
- praisonai_code/runtime/server.py +356 -0
- praisonai_code-0.0.1.dist-info/METADATA +80 -0
- praisonai_code-0.0.1.dist-info/RECORD +309 -0
- praisonai_code-0.0.1.dist-info/WHEEL +5 -0
- praisonai_code-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Research command group for PraisonAI CLI.
|
|
3
|
+
|
|
4
|
+
Provides research and analysis commands.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
app = typer.Typer(help="Research and analysis")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.callback(invoke_without_command=True)
|
|
13
|
+
def research_main(
|
|
14
|
+
ctx: typer.Context,
|
|
15
|
+
query: str = typer.Argument(None, help="Research query"),
|
|
16
|
+
model: str = typer.Option(None, "--model", "-m", help="LLM model to use"),
|
|
17
|
+
verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"),
|
|
18
|
+
output: str = typer.Option(None, "--output", "-o", help="Output file path"),
|
|
19
|
+
):
|
|
20
|
+
"""
|
|
21
|
+
Run research and analysis tasks.
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
praisonai research "What are the latest AI trends?"
|
|
25
|
+
praisonai research --model gpt-4o "Analyze market data"
|
|
26
|
+
"""
|
|
27
|
+
from praisonai.cli.main import PraisonAI
|
|
28
|
+
import sys
|
|
29
|
+
|
|
30
|
+
argv = ['research']
|
|
31
|
+
if query:
|
|
32
|
+
argv.append(query)
|
|
33
|
+
if model:
|
|
34
|
+
argv.extend(['--model', model])
|
|
35
|
+
if verbose:
|
|
36
|
+
argv.append('--verbose')
|
|
37
|
+
if output:
|
|
38
|
+
argv.extend(['--output', output])
|
|
39
|
+
|
|
40
|
+
original_argv = sys.argv
|
|
41
|
+
sys.argv = ['praisonai'] + argv
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
praison = PraisonAI()
|
|
45
|
+
praison.main()
|
|
46
|
+
except SystemExit:
|
|
47
|
+
pass
|
|
48
|
+
finally:
|
|
49
|
+
sys.argv = original_argv
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unified Retrieval CLI Commands - Agent-First Experience
|
|
3
|
+
|
|
4
|
+
This module provides the unified CLI commands for knowledge and retrieval:
|
|
5
|
+
- `praisonai index` - Index documents into knowledge base
|
|
6
|
+
- `praisonai query` - Query with structured answer and citations
|
|
7
|
+
- `praisonai chat` - Conversational interface with knowledge (handled by chat.py)
|
|
8
|
+
|
|
9
|
+
These commands replace the separate `knowledge` and `rag` command families.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import typer
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import List, Optional
|
|
15
|
+
from contextlib import contextmanager
|
|
16
|
+
import time
|
|
17
|
+
import sys
|
|
18
|
+
|
|
19
|
+
app = typer.Typer(
|
|
20
|
+
name="retrieval",
|
|
21
|
+
help="Knowledge indexing and retrieval commands",
|
|
22
|
+
no_args_is_help=True,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@contextmanager
|
|
27
|
+
def retrieval_profiler(profile: bool, profile_out: Optional[Path], profile_top: int):
|
|
28
|
+
"""Context manager for profiling retrieval operations."""
|
|
29
|
+
if not profile:
|
|
30
|
+
yield None
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
import json as json_module
|
|
34
|
+
|
|
35
|
+
start_time = time.perf_counter()
|
|
36
|
+
start_modules = set(sys.modules.keys())
|
|
37
|
+
|
|
38
|
+
profile_data = {
|
|
39
|
+
"metrics": {},
|
|
40
|
+
"modules_loaded": [],
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
import tracemalloc
|
|
45
|
+
tracemalloc.start()
|
|
46
|
+
has_tracemalloc = True
|
|
47
|
+
except ImportError:
|
|
48
|
+
has_tracemalloc = False
|
|
49
|
+
|
|
50
|
+
yield profile_data
|
|
51
|
+
|
|
52
|
+
elapsed_ms = (time.perf_counter() - start_time) * 1000
|
|
53
|
+
profile_data["metrics"]["elapsed_ms"] = elapsed_ms
|
|
54
|
+
|
|
55
|
+
if has_tracemalloc:
|
|
56
|
+
current, peak = tracemalloc.get_traced_memory()
|
|
57
|
+
tracemalloc.stop()
|
|
58
|
+
profile_data["metrics"]["peak_memory_mb"] = peak / 1024 / 1024
|
|
59
|
+
|
|
60
|
+
new_modules = set(sys.modules.keys()) - start_modules
|
|
61
|
+
profile_data["modules_loaded"] = sorted(list(new_modules))[:profile_top]
|
|
62
|
+
|
|
63
|
+
if profile_out:
|
|
64
|
+
try:
|
|
65
|
+
profile_out.parent.mkdir(parents=True, exist_ok=True)
|
|
66
|
+
with open(profile_out, "w") as f:
|
|
67
|
+
json_module.dump(profile_data, f, indent=2, default=str)
|
|
68
|
+
except Exception as e:
|
|
69
|
+
print(f"Warning: Failed to save profile: {e}")
|
|
70
|
+
|
|
71
|
+
from rich.console import Console
|
|
72
|
+
console = Console(stderr=True)
|
|
73
|
+
console.print(f"\n[dim]Profile: {elapsed_ms:.2f}ms wall time[/dim]")
|
|
74
|
+
if "peak_memory_mb" in profile_data["metrics"]:
|
|
75
|
+
console.print(f"[dim]Profile: {profile_data['metrics']['peak_memory_mb']:.2f}MB peak memory[/dim]")
|
|
76
|
+
console.print(f"[dim]Profile: {len(new_modules)} modules imported[/dim]")
|
|
77
|
+
if profile_out:
|
|
78
|
+
console.print(f"[dim]Profile saved to: {profile_out}[/dim]")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@app.command("index")
|
|
82
|
+
def index_command(
|
|
83
|
+
sources: List[str] = typer.Argument(..., help="Source files, directories, or URLs to index"),
|
|
84
|
+
collection: str = typer.Option("default", "--collection", "-c", help="Collection/knowledge base name"),
|
|
85
|
+
config: Optional[Path] = typer.Option(None, "--config", "-f", help="Config file path"),
|
|
86
|
+
verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"),
|
|
87
|
+
profile: bool = typer.Option(False, "--profile", help="Enable performance profiling"),
|
|
88
|
+
profile_out: Optional[Path] = typer.Option(None, "--profile-out", help="Save profile to JSON file"),
|
|
89
|
+
profile_top: int = typer.Option(20, "--profile-top", help="Top N items in profile"),
|
|
90
|
+
):
|
|
91
|
+
"""
|
|
92
|
+
Index documents into a knowledge base.
|
|
93
|
+
|
|
94
|
+
This is the canonical command for adding documents to a knowledge base.
|
|
95
|
+
Use `praisonai query` to get answers with citations from the indexed knowledge.
|
|
96
|
+
|
|
97
|
+
Examples:
|
|
98
|
+
praisonai index ./docs
|
|
99
|
+
praisonai index paper.pdf --collection research
|
|
100
|
+
praisonai index ./data --profile --profile-out ./profile.json
|
|
101
|
+
"""
|
|
102
|
+
from rich.console import Console
|
|
103
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
104
|
+
|
|
105
|
+
console = Console()
|
|
106
|
+
|
|
107
|
+
with retrieval_profiler(profile, profile_out, profile_top) as profile_data:
|
|
108
|
+
try:
|
|
109
|
+
from praisonaiagents.knowledge import Knowledge
|
|
110
|
+
|
|
111
|
+
knowledge_config = {
|
|
112
|
+
"vector_store": {
|
|
113
|
+
"provider": "chroma",
|
|
114
|
+
"config": {
|
|
115
|
+
"collection_name": collection,
|
|
116
|
+
"path": f"./.praison/knowledge/{collection}",
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if config and config.exists():
|
|
122
|
+
import yaml
|
|
123
|
+
with open(config) as f:
|
|
124
|
+
file_config = yaml.safe_load(f)
|
|
125
|
+
if "knowledge" in file_config:
|
|
126
|
+
knowledge_config.update(file_config["knowledge"])
|
|
127
|
+
|
|
128
|
+
knowledge = Knowledge(config=knowledge_config, verbose=verbose)
|
|
129
|
+
|
|
130
|
+
with Progress(
|
|
131
|
+
SpinnerColumn(),
|
|
132
|
+
TextColumn("[progress.description]{task.description}"),
|
|
133
|
+
console=console,
|
|
134
|
+
transient=True,
|
|
135
|
+
) as progress:
|
|
136
|
+
for source in sources:
|
|
137
|
+
task = progress.add_task(f"Indexing {source}...", total=None)
|
|
138
|
+
try:
|
|
139
|
+
result = knowledge.add(source)
|
|
140
|
+
count = len(result.get("results", [])) if isinstance(result, dict) else 0
|
|
141
|
+
console.print(f"[green]✓[/green] Indexed {source}: {count} chunks")
|
|
142
|
+
except Exception as e:
|
|
143
|
+
console.print(f"[red]✗[/red] Failed to index {source}: {e}")
|
|
144
|
+
progress.remove_task(task)
|
|
145
|
+
|
|
146
|
+
console.print(f"\n[bold green]Indexing complete![/bold green] Collection: {collection}")
|
|
147
|
+
if profile_data:
|
|
148
|
+
profile_data["command"] = "index"
|
|
149
|
+
profile_data["collection"] = collection
|
|
150
|
+
profile_data["sources"] = sources
|
|
151
|
+
|
|
152
|
+
except ImportError as e:
|
|
153
|
+
console.print(f"[red]Error:[/red] Missing dependency: {e}")
|
|
154
|
+
console.print("Install with: pip install 'praisonaiagents[knowledge]'")
|
|
155
|
+
raise typer.Exit(1)
|
|
156
|
+
except Exception as e:
|
|
157
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
158
|
+
raise typer.Exit(1)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@app.command("query")
|
|
162
|
+
def query_command(
|
|
163
|
+
question: str = typer.Argument(..., help="Question to answer"),
|
|
164
|
+
collection: str = typer.Option("default", "--collection", "-c", help="Collection to query"),
|
|
165
|
+
top_k: int = typer.Option(5, "--top-k", "-k", help="Number of results to retrieve"),
|
|
166
|
+
min_score: float = typer.Option(0.0, "--min-score", help="Minimum relevance score (0.0-1.0)"),
|
|
167
|
+
hybrid: bool = typer.Option(False, "--hybrid", help="Use hybrid retrieval (dense + keyword)"),
|
|
168
|
+
rerank: bool = typer.Option(False, "--rerank", help="Enable reranking of results"),
|
|
169
|
+
citations: bool = typer.Option(True, "--citations/--no-citations", help="Include citations"),
|
|
170
|
+
citations_mode: str = typer.Option("append", "--citations-mode", help="Citations mode: append, inline, hidden"),
|
|
171
|
+
max_context_tokens: int = typer.Option(4000, "--max-context-tokens", help="Maximum context tokens"),
|
|
172
|
+
config: Optional[Path] = typer.Option(None, "--config", "-f", help="Config file path"),
|
|
173
|
+
verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"),
|
|
174
|
+
profile: bool = typer.Option(False, "--profile", help="Enable performance profiling"),
|
|
175
|
+
profile_out: Optional[Path] = typer.Option(None, "--profile-out", help="Save profile to JSON file"),
|
|
176
|
+
profile_top: int = typer.Option(20, "--profile-top", help="Top N items in profile"),
|
|
177
|
+
):
|
|
178
|
+
"""
|
|
179
|
+
Query knowledge and get a structured answer with citations.
|
|
180
|
+
|
|
181
|
+
Uses the Agent-first retrieval pipeline with token-aware context building.
|
|
182
|
+
|
|
183
|
+
Examples:
|
|
184
|
+
praisonai query "What is the main finding?"
|
|
185
|
+
praisonai query "Summarize the document" --collection research
|
|
186
|
+
praisonai query "Key points?" --top-k 10 --no-citations
|
|
187
|
+
praisonai query "Summary?" --hybrid --rerank
|
|
188
|
+
"""
|
|
189
|
+
from rich.console import Console
|
|
190
|
+
from rich.panel import Panel
|
|
191
|
+
from rich.markdown import Markdown
|
|
192
|
+
|
|
193
|
+
console = Console()
|
|
194
|
+
|
|
195
|
+
with retrieval_profiler(profile, profile_out, profile_top) as profile_data:
|
|
196
|
+
try:
|
|
197
|
+
from praisonaiagents import Agent
|
|
198
|
+
from praisonaiagents.rag.retrieval_config import RetrievalConfig, RetrievalPolicy, CitationsMode
|
|
199
|
+
|
|
200
|
+
retrieval_config = RetrievalConfig(
|
|
201
|
+
enabled=True,
|
|
202
|
+
policy=RetrievalPolicy.ALWAYS,
|
|
203
|
+
top_k=top_k,
|
|
204
|
+
min_score=min_score,
|
|
205
|
+
max_context_tokens=max_context_tokens,
|
|
206
|
+
rerank=rerank,
|
|
207
|
+
hybrid=hybrid,
|
|
208
|
+
citations=citations,
|
|
209
|
+
citations_mode=CitationsMode(citations_mode),
|
|
210
|
+
vector_store_provider="chroma",
|
|
211
|
+
persist_path=f"./.praison/knowledge/{collection}",
|
|
212
|
+
collection_name=collection,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
if config and config.exists():
|
|
216
|
+
import yaml
|
|
217
|
+
with open(config) as f:
|
|
218
|
+
file_config = yaml.safe_load(f)
|
|
219
|
+
if "retrieval" in file_config:
|
|
220
|
+
for key, value in file_config["retrieval"].items():
|
|
221
|
+
if hasattr(retrieval_config, key):
|
|
222
|
+
setattr(retrieval_config, key, value)
|
|
223
|
+
|
|
224
|
+
agent = Agent(
|
|
225
|
+
name="QueryAgent",
|
|
226
|
+
instructions="You are a helpful assistant that answers questions based on the provided knowledge.",
|
|
227
|
+
knowledge=[], # Empty - we'll use existing indexed knowledge
|
|
228
|
+
retrieval_config=retrieval_config,
|
|
229
|
+
verbose=verbose,
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
agent._ensure_knowledge_processed = lambda: None
|
|
233
|
+
from praisonaiagents.knowledge import Knowledge
|
|
234
|
+
agent.knowledge = Knowledge(config=retrieval_config.to_knowledge_config(), verbose=verbose)
|
|
235
|
+
agent._knowledge_processed = True
|
|
236
|
+
|
|
237
|
+
if verbose:
|
|
238
|
+
strategy_str = "hybrid (dense + keyword)" if hybrid else "dense"
|
|
239
|
+
rerank_str = " with reranking" if rerank else ""
|
|
240
|
+
console.print(f"[dim]Querying collection '{collection}' using {strategy_str}{rerank_str}, top_k={top_k}...[/dim]")
|
|
241
|
+
|
|
242
|
+
result = agent.query(question)
|
|
243
|
+
|
|
244
|
+
console.print(Panel(
|
|
245
|
+
Markdown(result.answer),
|
|
246
|
+
title="[bold]Answer[/bold]",
|
|
247
|
+
border_style="green",
|
|
248
|
+
))
|
|
249
|
+
|
|
250
|
+
if citations and result.citations:
|
|
251
|
+
console.print("\n[bold]Sources:[/bold]")
|
|
252
|
+
for citation in result.citations:
|
|
253
|
+
score_str = f"[dim](score: {citation.score:.2f})[/dim]" if citation.score else ""
|
|
254
|
+
console.print(f" [{citation.id}] {citation.source} {score_str}")
|
|
255
|
+
if verbose:
|
|
256
|
+
snippet = citation.text[:200] + "..." if len(citation.text) > 200 else citation.text
|
|
257
|
+
console.print(f" [dim]{snippet}[/dim]")
|
|
258
|
+
|
|
259
|
+
if verbose and result.metadata:
|
|
260
|
+
elapsed = result.metadata.get('elapsed_seconds', 0)
|
|
261
|
+
console.print(f"\n[dim]Elapsed: {elapsed:.2f}s[/dim]")
|
|
262
|
+
|
|
263
|
+
if profile_data:
|
|
264
|
+
profile_data["command"] = "query"
|
|
265
|
+
profile_data["collection"] = collection
|
|
266
|
+
profile_data["question"] = question
|
|
267
|
+
|
|
268
|
+
except ImportError as e:
|
|
269
|
+
console.print(f"[red]Error:[/red] Missing dependency: {e}")
|
|
270
|
+
console.print("Install with: pip install 'praisonaiagents[knowledge]'")
|
|
271
|
+
raise typer.Exit(1)
|
|
272
|
+
except Exception as e:
|
|
273
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
274
|
+
if verbose:
|
|
275
|
+
import traceback
|
|
276
|
+
console.print(traceback.format_exc())
|
|
277
|
+
raise typer.Exit(1)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@app.command("search")
|
|
281
|
+
def search_command(
|
|
282
|
+
query: str = typer.Argument(..., help="Search query"),
|
|
283
|
+
collection: str = typer.Option("default", "--collection", "-c", help="Collection to search"),
|
|
284
|
+
top_k: int = typer.Option(5, "--top-k", "-k", help="Number of results to retrieve"),
|
|
285
|
+
hybrid: bool = typer.Option(False, "--hybrid", help="Use hybrid retrieval (dense + keyword)"),
|
|
286
|
+
config: Optional[Path] = typer.Option(None, "--config", "-f", help="Config file path"),
|
|
287
|
+
verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"),
|
|
288
|
+
):
|
|
289
|
+
"""
|
|
290
|
+
Search/retrieve from a knowledge base (no LLM generation).
|
|
291
|
+
|
|
292
|
+
Returns raw search results without generating an answer.
|
|
293
|
+
For answers with citations, use `praisonai query`.
|
|
294
|
+
|
|
295
|
+
Examples:
|
|
296
|
+
praisonai search "capital of France"
|
|
297
|
+
praisonai search "main findings" --collection research --top-k 10
|
|
298
|
+
"""
|
|
299
|
+
from rich.console import Console
|
|
300
|
+
from rich.table import Table
|
|
301
|
+
|
|
302
|
+
console = Console()
|
|
303
|
+
|
|
304
|
+
try:
|
|
305
|
+
from praisonaiagents.knowledge import Knowledge
|
|
306
|
+
|
|
307
|
+
knowledge_config = {
|
|
308
|
+
"vector_store": {
|
|
309
|
+
"provider": "chroma",
|
|
310
|
+
"config": {
|
|
311
|
+
"collection_name": collection,
|
|
312
|
+
"path": f"./.praison/knowledge/{collection}",
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if hybrid:
|
|
318
|
+
knowledge_config["retrieval"] = {"strategy": "hybrid"}
|
|
319
|
+
|
|
320
|
+
if config and config.exists():
|
|
321
|
+
import yaml
|
|
322
|
+
with open(config) as f:
|
|
323
|
+
file_config = yaml.safe_load(f)
|
|
324
|
+
if "knowledge" in file_config:
|
|
325
|
+
knowledge_config.update(file_config["knowledge"])
|
|
326
|
+
|
|
327
|
+
knowledge = Knowledge(config=knowledge_config, verbose=verbose)
|
|
328
|
+
|
|
329
|
+
if verbose:
|
|
330
|
+
console.print(f"[dim]Searching collection '{collection}' for: {query}[/dim]")
|
|
331
|
+
|
|
332
|
+
results = knowledge.search(query)
|
|
333
|
+
|
|
334
|
+
if not results:
|
|
335
|
+
console.print("[yellow]No results found.[/yellow]")
|
|
336
|
+
return
|
|
337
|
+
|
|
338
|
+
if isinstance(results, dict) and 'results' in results:
|
|
339
|
+
result_list = results['results']
|
|
340
|
+
elif isinstance(results, list):
|
|
341
|
+
result_list = results
|
|
342
|
+
else:
|
|
343
|
+
result_list = [results]
|
|
344
|
+
|
|
345
|
+
table = Table(title=f"Search Results ({len(result_list[:top_k])} of {len(result_list)})")
|
|
346
|
+
table.add_column("#", style="dim", width=3)
|
|
347
|
+
table.add_column("Score", width=8)
|
|
348
|
+
table.add_column("Content", overflow="fold")
|
|
349
|
+
|
|
350
|
+
for i, result in enumerate(result_list[:top_k], 1):
|
|
351
|
+
if isinstance(result, dict):
|
|
352
|
+
content = result.get('memory', result.get('text', str(result)))
|
|
353
|
+
score = result.get('score', result.get('distance', 'N/A'))
|
|
354
|
+
else:
|
|
355
|
+
content = str(result)
|
|
356
|
+
score = 'N/A'
|
|
357
|
+
|
|
358
|
+
content_preview = content[:300] + "..." if len(content) > 300 else content
|
|
359
|
+
score_str = f"{score:.3f}" if isinstance(score, float) else str(score)
|
|
360
|
+
table.add_row(str(i), score_str, content_preview)
|
|
361
|
+
|
|
362
|
+
console.print(table)
|
|
363
|
+
|
|
364
|
+
except ImportError as e:
|
|
365
|
+
console.print(f"[red]Error:[/red] Missing dependency: {e}")
|
|
366
|
+
console.print("Install with: pip install 'praisonaiagents[knowledge]'")
|
|
367
|
+
raise typer.Exit(1)
|
|
368
|
+
except Exception as e:
|
|
369
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
370
|
+
raise typer.Exit(1)
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def register_commands(main_app: typer.Typer):
|
|
374
|
+
"""Register unified retrieval commands with the main CLI app."""
|
|
375
|
+
main_app.command("index")(index_command)
|
|
376
|
+
main_app.command("query")(query_command)
|
|
377
|
+
main_app.command("search")(search_command)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Rules command group for PraisonAI CLI.
|
|
3
|
+
|
|
4
|
+
Provides rules management commands.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
app = typer.Typer(help="Rules management")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.command("list")
|
|
13
|
+
def rules_list():
|
|
14
|
+
"""List active rules."""
|
|
15
|
+
from praisonai.cli.main import PraisonAI
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
argv = ['rules', 'list']
|
|
19
|
+
|
|
20
|
+
original_argv = sys.argv
|
|
21
|
+
sys.argv = ['praisonai'] + argv
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
praison = PraisonAI()
|
|
25
|
+
praison.main()
|
|
26
|
+
except SystemExit:
|
|
27
|
+
pass
|
|
28
|
+
finally:
|
|
29
|
+
sys.argv = original_argv
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@app.command("add")
|
|
33
|
+
def rules_add(
|
|
34
|
+
rule: str = typer.Argument(..., help="Rule to add"),
|
|
35
|
+
):
|
|
36
|
+
"""Add a rule."""
|
|
37
|
+
from praisonai.cli.main import PraisonAI
|
|
38
|
+
import sys
|
|
39
|
+
|
|
40
|
+
argv = ['rules', 'add', rule]
|
|
41
|
+
|
|
42
|
+
original_argv = sys.argv
|
|
43
|
+
sys.argv = ['praisonai'] + argv
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
praison = PraisonAI()
|
|
47
|
+
praison.main()
|
|
48
|
+
except SystemExit:
|
|
49
|
+
pass
|
|
50
|
+
finally:
|
|
51
|
+
sys.argv = original_argv
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@app.command("clear")
|
|
55
|
+
def rules_clear():
|
|
56
|
+
"""Clear all rules."""
|
|
57
|
+
from praisonai.cli.main import PraisonAI
|
|
58
|
+
import sys
|
|
59
|
+
|
|
60
|
+
argv = ['rules', 'clear']
|
|
61
|
+
|
|
62
|
+
original_argv = sys.argv
|
|
63
|
+
sys.argv = ['praisonai'] + argv
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
praison = PraisonAI()
|
|
67
|
+
praison.main()
|
|
68
|
+
except SystemExit:
|
|
69
|
+
pass
|
|
70
|
+
finally:
|
|
71
|
+
sys.argv = original_argv
|