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,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")
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Version command group for PraisonAI CLI.
|
|
3
|
+
|
|
4
|
+
Provides version information:
|
|
5
|
+
- version show: Show version
|
|
6
|
+
- version check: Check for updates
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from ..output.console import get_output_controller
|
|
12
|
+
|
|
13
|
+
app = typer.Typer(help="Version information")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@app.command("show")
|
|
17
|
+
def version_show():
|
|
18
|
+
"""Show version information."""
|
|
19
|
+
output = get_output_controller()
|
|
20
|
+
|
|
21
|
+
from praisonai.version import __version__
|
|
22
|
+
|
|
23
|
+
# Try to get additional version info
|
|
24
|
+
versions = {
|
|
25
|
+
"praisonai": __version__,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# Check praisonaiagents version
|
|
29
|
+
try:
|
|
30
|
+
import praisonaiagents
|
|
31
|
+
versions["praisonaiagents"] = getattr(praisonaiagents, "__version__", "unknown")
|
|
32
|
+
except ImportError:
|
|
33
|
+
versions["praisonaiagents"] = "not installed"
|
|
34
|
+
|
|
35
|
+
# Check Python version
|
|
36
|
+
import sys
|
|
37
|
+
versions["python"] = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
|
|
38
|
+
|
|
39
|
+
if output.is_json_mode:
|
|
40
|
+
output.print_json(versions)
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
output.print_panel(
|
|
44
|
+
f"PraisonAI: {versions['praisonai']}\n"
|
|
45
|
+
f"PraisonAI Agents: {versions['praisonaiagents']}\n"
|
|
46
|
+
f"Python: {versions['python']}",
|
|
47
|
+
title="Version Information"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@app.command("check")
|
|
52
|
+
def version_check():
|
|
53
|
+
"""Check for updates."""
|
|
54
|
+
output = get_output_controller()
|
|
55
|
+
|
|
56
|
+
from praisonai.version import __version__
|
|
57
|
+
|
|
58
|
+
output.print_info("Checking for updates...")
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
import urllib.request
|
|
62
|
+
import json
|
|
63
|
+
|
|
64
|
+
url = "https://pypi.org/pypi/praisonai/json"
|
|
65
|
+
with urllib.request.urlopen(url, timeout=5) as response:
|
|
66
|
+
data = json.loads(response.read().decode())
|
|
67
|
+
latest = data["info"]["version"]
|
|
68
|
+
|
|
69
|
+
if output.is_json_mode:
|
|
70
|
+
output.print_json({
|
|
71
|
+
"current": __version__,
|
|
72
|
+
"latest": latest,
|
|
73
|
+
"update_available": latest != __version__,
|
|
74
|
+
})
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
if latest != __version__:
|
|
78
|
+
output.print_warning(
|
|
79
|
+
f"Update available: {__version__} → {latest}\n"
|
|
80
|
+
f"Run: pip install --upgrade praisonai"
|
|
81
|
+
)
|
|
82
|
+
else:
|
|
83
|
+
output.print_success(f"You are using the latest version ({__version__})")
|
|
84
|
+
|
|
85
|
+
except Exception as e:
|
|
86
|
+
if output.is_json_mode:
|
|
87
|
+
output.print_json({
|
|
88
|
+
"current": __version__,
|
|
89
|
+
"latest": None,
|
|
90
|
+
"error": str(e),
|
|
91
|
+
})
|
|
92
|
+
else:
|
|
93
|
+
output.print_error(f"Failed to check for updates: {e}")
|
|
94
|
+
output.print(f"Current version: {__version__}")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@app.callback(invoke_without_command=True)
|
|
98
|
+
def version_callback(ctx: typer.Context):
|
|
99
|
+
"""Show version (default behavior)."""
|
|
100
|
+
if ctx.invoked_subcommand is None:
|
|
101
|
+
version_show()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PraisonAI CLI Configuration Module.
|
|
3
|
+
|
|
4
|
+
Provides configuration management with TOML support and precedence handling.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .loader import ConfigLoader, get_config
|
|
8
|
+
from .schema import ConfigSchema
|
|
9
|
+
from .paths import get_config_paths, get_user_config_path, get_project_config_path
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
'ConfigLoader',
|
|
13
|
+
'ConfigSchema',
|
|
14
|
+
'get_config',
|
|
15
|
+
'get_config_paths',
|
|
16
|
+
'get_user_config_path',
|
|
17
|
+
'get_project_config_path',
|
|
18
|
+
]
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration loader for PraisonAI CLI.
|
|
3
|
+
|
|
4
|
+
Handles loading, merging, and saving configuration with precedence.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import threading
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any, Dict, Optional
|
|
11
|
+
|
|
12
|
+
from .paths import (
|
|
13
|
+
get_config_paths,
|
|
14
|
+
get_user_config_path,
|
|
15
|
+
get_project_config_path,
|
|
16
|
+
get_env_prefix,
|
|
17
|
+
ensure_config_dirs,
|
|
18
|
+
)
|
|
19
|
+
from .schema import ConfigSchema, DEFAULT_CONFIG
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Thread-safe config cache
|
|
23
|
+
_config_lock = threading.Lock()
|
|
24
|
+
_config_cache: Optional[ConfigSchema] = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _load_toml(path: Path) -> Dict[str, Any]:
|
|
28
|
+
"""Load a TOML file."""
|
|
29
|
+
try:
|
|
30
|
+
# Try tomllib (Python 3.11+) first
|
|
31
|
+
import tomllib
|
|
32
|
+
with open(path, "rb") as f:
|
|
33
|
+
return tomllib.load(f)
|
|
34
|
+
except ImportError:
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
# Fall back to tomli
|
|
39
|
+
import tomli
|
|
40
|
+
with open(path, "rb") as f:
|
|
41
|
+
return tomli.load(f)
|
|
42
|
+
except ImportError:
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
# Last resort: basic TOML parsing
|
|
46
|
+
return _basic_toml_parse(path)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _basic_toml_parse(path: Path) -> Dict[str, Any]:
|
|
50
|
+
"""Basic TOML parser for simple configs."""
|
|
51
|
+
result: Dict[str, Any] = {}
|
|
52
|
+
current_section: Optional[str] = None
|
|
53
|
+
|
|
54
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
55
|
+
for line in f:
|
|
56
|
+
line = line.strip()
|
|
57
|
+
if not line or line.startswith("#"):
|
|
58
|
+
continue
|
|
59
|
+
|
|
60
|
+
if line.startswith("[") and line.endswith("]"):
|
|
61
|
+
current_section = line[1:-1]
|
|
62
|
+
if current_section not in result:
|
|
63
|
+
result[current_section] = {}
|
|
64
|
+
elif "=" in line:
|
|
65
|
+
key, value = line.split("=", 1)
|
|
66
|
+
key = key.strip()
|
|
67
|
+
value = value.strip()
|
|
68
|
+
|
|
69
|
+
# Parse value
|
|
70
|
+
if value.lower() == "true":
|
|
71
|
+
parsed_value = True
|
|
72
|
+
elif value.lower() == "false":
|
|
73
|
+
parsed_value = False
|
|
74
|
+
elif value.startswith('"') and value.endswith('"'):
|
|
75
|
+
parsed_value = value[1:-1]
|
|
76
|
+
elif value.startswith("'") and value.endswith("'"):
|
|
77
|
+
parsed_value = value[1:-1]
|
|
78
|
+
else:
|
|
79
|
+
try:
|
|
80
|
+
parsed_value = int(value)
|
|
81
|
+
except ValueError:
|
|
82
|
+
try:
|
|
83
|
+
parsed_value = float(value)
|
|
84
|
+
except ValueError:
|
|
85
|
+
parsed_value = value
|
|
86
|
+
|
|
87
|
+
if current_section:
|
|
88
|
+
result[current_section][key] = parsed_value
|
|
89
|
+
else:
|
|
90
|
+
result[key] = parsed_value
|
|
91
|
+
|
|
92
|
+
return result
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _save_toml(path: Path, data: Dict[str, Any]) -> None:
|
|
96
|
+
"""Save data to a TOML file."""
|
|
97
|
+
try:
|
|
98
|
+
import tomli_w
|
|
99
|
+
with open(path, "wb") as f:
|
|
100
|
+
tomli_w.dump(data, f)
|
|
101
|
+
return
|
|
102
|
+
except ImportError:
|
|
103
|
+
pass
|
|
104
|
+
|
|
105
|
+
# Fall back to basic TOML writing
|
|
106
|
+
_basic_toml_write(path, data)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _basic_toml_write(path: Path, data: Dict[str, Any]) -> None:
|
|
110
|
+
"""Basic TOML writer."""
|
|
111
|
+
lines = []
|
|
112
|
+
|
|
113
|
+
# Write top-level keys first
|
|
114
|
+
for key, value in data.items():
|
|
115
|
+
if not isinstance(value, dict):
|
|
116
|
+
lines.append(f"{key} = {_format_toml_value(value)}")
|
|
117
|
+
|
|
118
|
+
# Write sections
|
|
119
|
+
for key, value in data.items():
|
|
120
|
+
if isinstance(value, dict):
|
|
121
|
+
lines.append(f"\n[{key}]")
|
|
122
|
+
for sub_key, sub_value in value.items():
|
|
123
|
+
if not isinstance(sub_value, dict):
|
|
124
|
+
lines.append(f"{sub_key} = {_format_toml_value(sub_value)}")
|
|
125
|
+
else:
|
|
126
|
+
# Nested section
|
|
127
|
+
lines.append(f"\n[{key}.{sub_key}]")
|
|
128
|
+
for nested_key, nested_value in sub_value.items():
|
|
129
|
+
lines.append(f"{nested_key} = {_format_toml_value(nested_value)}")
|
|
130
|
+
|
|
131
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
132
|
+
with open(path, "w", encoding="utf-8") as f:
|
|
133
|
+
f.write("\n".join(lines) + "\n")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _format_toml_value(value: Any) -> str:
|
|
137
|
+
"""Format a value for TOML."""
|
|
138
|
+
if isinstance(value, bool):
|
|
139
|
+
return "true" if value else "false"
|
|
140
|
+
elif isinstance(value, str):
|
|
141
|
+
return f'"{value}"'
|
|
142
|
+
elif isinstance(value, (int, float)):
|
|
143
|
+
return str(value)
|
|
144
|
+
elif isinstance(value, list):
|
|
145
|
+
items = ", ".join(_format_toml_value(v) for v in value)
|
|
146
|
+
return f"[{items}]"
|
|
147
|
+
else:
|
|
148
|
+
return f'"{value}"'
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _merge_dicts(base: Dict[str, Any], override: Dict[str, Any]) -> Dict[str, Any]:
|
|
152
|
+
"""Deep merge two dictionaries."""
|
|
153
|
+
result = base.copy()
|
|
154
|
+
for key, value in override.items():
|
|
155
|
+
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
|
|
156
|
+
result[key] = _merge_dicts(result[key], value)
|
|
157
|
+
else:
|
|
158
|
+
result[key] = value
|
|
159
|
+
return result
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _get_env_overrides() -> Dict[str, Any]:
|
|
163
|
+
"""Get configuration overrides from environment variables."""
|
|
164
|
+
prefix = get_env_prefix()
|
|
165
|
+
overrides: Dict[str, Any] = {}
|
|
166
|
+
|
|
167
|
+
for key, value in os.environ.items():
|
|
168
|
+
if not key.startswith(prefix):
|
|
169
|
+
continue
|
|
170
|
+
|
|
171
|
+
# Convert PRAISONAI_OUTPUT_FORMAT to output.format
|
|
172
|
+
config_key = key[len(prefix):].lower()
|
|
173
|
+
parts = config_key.split("_")
|
|
174
|
+
|
|
175
|
+
# Parse value
|
|
176
|
+
if value.lower() == "true":
|
|
177
|
+
parsed_value = True
|
|
178
|
+
elif value.lower() == "false":
|
|
179
|
+
parsed_value = False
|
|
180
|
+
else:
|
|
181
|
+
try:
|
|
182
|
+
parsed_value = int(value)
|
|
183
|
+
except ValueError:
|
|
184
|
+
try:
|
|
185
|
+
parsed_value = float(value)
|
|
186
|
+
except ValueError:
|
|
187
|
+
parsed_value = value
|
|
188
|
+
|
|
189
|
+
# Build nested dict
|
|
190
|
+
if len(parts) >= 2:
|
|
191
|
+
section = parts[0]
|
|
192
|
+
sub_key = "_".join(parts[1:])
|
|
193
|
+
if section not in overrides:
|
|
194
|
+
overrides[section] = {}
|
|
195
|
+
overrides[section][sub_key] = parsed_value
|
|
196
|
+
else:
|
|
197
|
+
overrides[config_key] = parsed_value
|
|
198
|
+
|
|
199
|
+
return overrides
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def _get_dotted_value(data: Dict[str, Any], key: str) -> Any:
|
|
203
|
+
"""Get a value using dotted key notation."""
|
|
204
|
+
parts = key.split(".")
|
|
205
|
+
current = data
|
|
206
|
+
for part in parts:
|
|
207
|
+
if isinstance(current, dict) and part in current:
|
|
208
|
+
current = current[part]
|
|
209
|
+
else:
|
|
210
|
+
return None
|
|
211
|
+
return current
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _set_dotted_value(data: Dict[str, Any], key: str, value: Any) -> None:
|
|
215
|
+
"""Set a value using dotted key notation."""
|
|
216
|
+
parts = key.split(".")
|
|
217
|
+
current = data
|
|
218
|
+
for part in parts[:-1]:
|
|
219
|
+
if part not in current:
|
|
220
|
+
current[part] = {}
|
|
221
|
+
current = current[part]
|
|
222
|
+
current[parts[-1]] = value
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class ConfigLoader:
|
|
226
|
+
"""
|
|
227
|
+
Configuration loader with precedence handling.
|
|
228
|
+
|
|
229
|
+
Precedence (highest to lowest):
|
|
230
|
+
1. CLI flags (not handled here)
|
|
231
|
+
2. Environment variables (PRAISONAI_*)
|
|
232
|
+
3. Project config (.praison/config.toml)
|
|
233
|
+
4. User config (~/.praison/config.toml)
|
|
234
|
+
5. Defaults
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
def __init__(self, project_root: Optional[Path] = None):
|
|
238
|
+
self.project_root = project_root or Path.cwd()
|
|
239
|
+
self._config: Optional[ConfigSchema] = None
|
|
240
|
+
self._raw_config: Dict[str, Any] = {}
|
|
241
|
+
|
|
242
|
+
def load(self, force_reload: bool = False) -> ConfigSchema:
|
|
243
|
+
"""Load configuration with precedence."""
|
|
244
|
+
if self._config is not None and not force_reload:
|
|
245
|
+
return self._config
|
|
246
|
+
|
|
247
|
+
# Start with defaults
|
|
248
|
+
merged = DEFAULT_CONFIG.to_dict()
|
|
249
|
+
|
|
250
|
+
# Load config files in reverse precedence order
|
|
251
|
+
config_paths = get_config_paths(self.project_root)
|
|
252
|
+
for path in reversed(config_paths):
|
|
253
|
+
try:
|
|
254
|
+
file_config = _load_toml(path)
|
|
255
|
+
merged = _merge_dicts(merged, file_config)
|
|
256
|
+
except Exception:
|
|
257
|
+
pass # Skip invalid files
|
|
258
|
+
|
|
259
|
+
# Apply environment overrides
|
|
260
|
+
env_overrides = _get_env_overrides()
|
|
261
|
+
merged = _merge_dicts(merged, env_overrides)
|
|
262
|
+
|
|
263
|
+
self._raw_config = merged
|
|
264
|
+
self._config = ConfigSchema.from_dict(merged)
|
|
265
|
+
return self._config
|
|
266
|
+
|
|
267
|
+
def get(self, key: str, default: Any = None) -> Any:
|
|
268
|
+
"""Get a configuration value using dotted key notation."""
|
|
269
|
+
self.load()
|
|
270
|
+
value = _get_dotted_value(self._raw_config, key)
|
|
271
|
+
return value if value is not None else default
|
|
272
|
+
|
|
273
|
+
def set(self, key: str, value: Any, scope: str = "user") -> None:
|
|
274
|
+
"""
|
|
275
|
+
Set a configuration value.
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
key: Dotted key notation (e.g., "output.format")
|
|
279
|
+
value: Value to set
|
|
280
|
+
scope: "user" or "project"
|
|
281
|
+
"""
|
|
282
|
+
if scope == "project":
|
|
283
|
+
config_path = get_project_config_path(self.project_root)
|
|
284
|
+
else:
|
|
285
|
+
config_path = get_user_config_path()
|
|
286
|
+
|
|
287
|
+
# Load existing config or create empty
|
|
288
|
+
if config_path.exists():
|
|
289
|
+
try:
|
|
290
|
+
existing = _load_toml(config_path)
|
|
291
|
+
except Exception:
|
|
292
|
+
existing = {}
|
|
293
|
+
else:
|
|
294
|
+
existing = {}
|
|
295
|
+
|
|
296
|
+
# Set the value
|
|
297
|
+
_set_dotted_value(existing, key, value)
|
|
298
|
+
|
|
299
|
+
# Ensure directory exists
|
|
300
|
+
ensure_config_dirs()
|
|
301
|
+
if scope == "project":
|
|
302
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
303
|
+
|
|
304
|
+
# Save
|
|
305
|
+
_save_toml(config_path, existing)
|
|
306
|
+
|
|
307
|
+
# Reload
|
|
308
|
+
self.load(force_reload=True)
|
|
309
|
+
|
|
310
|
+
def reset(self, scope: str = "user") -> None:
|
|
311
|
+
"""Reset configuration to defaults."""
|
|
312
|
+
if scope == "project":
|
|
313
|
+
config_path = get_project_config_path(self.project_root)
|
|
314
|
+
else:
|
|
315
|
+
config_path = get_user_config_path()
|
|
316
|
+
|
|
317
|
+
if config_path.exists():
|
|
318
|
+
config_path.unlink()
|
|
319
|
+
|
|
320
|
+
self.load(force_reload=True)
|
|
321
|
+
|
|
322
|
+
def list_all(self) -> Dict[str, Any]:
|
|
323
|
+
"""List all configuration values."""
|
|
324
|
+
self.load()
|
|
325
|
+
return self._raw_config.copy()
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
# Global config loader
|
|
329
|
+
_global_loader: Optional[ConfigLoader] = None
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def get_config(project_root: Optional[Path] = None) -> ConfigSchema:
|
|
333
|
+
"""Get the global configuration."""
|
|
334
|
+
global _global_loader, _config_cache
|
|
335
|
+
|
|
336
|
+
with _config_lock:
|
|
337
|
+
if _global_loader is None or project_root is not None:
|
|
338
|
+
_global_loader = ConfigLoader(project_root)
|
|
339
|
+
|
|
340
|
+
if _config_cache is None:
|
|
341
|
+
_config_cache = _global_loader.load()
|
|
342
|
+
|
|
343
|
+
return _config_cache
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def get_config_loader(project_root: Optional[Path] = None) -> ConfigLoader:
|
|
347
|
+
"""Get the global config loader."""
|
|
348
|
+
global _global_loader
|
|
349
|
+
|
|
350
|
+
with _config_lock:
|
|
351
|
+
if _global_loader is None or project_root is not None:
|
|
352
|
+
_global_loader = ConfigLoader(project_root)
|
|
353
|
+
return _global_loader
|