nvidia-nat 1.2.0rc5__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.
- aiq/agent/__init__.py +0 -0
- aiq/agent/base.py +239 -0
- aiq/agent/dual_node.py +67 -0
- aiq/agent/react_agent/__init__.py +0 -0
- aiq/agent/react_agent/agent.py +355 -0
- aiq/agent/react_agent/output_parser.py +104 -0
- aiq/agent/react_agent/prompt.py +41 -0
- aiq/agent/react_agent/register.py +149 -0
- aiq/agent/reasoning_agent/__init__.py +0 -0
- aiq/agent/reasoning_agent/reasoning_agent.py +225 -0
- aiq/agent/register.py +23 -0
- aiq/agent/rewoo_agent/__init__.py +0 -0
- aiq/agent/rewoo_agent/agent.py +411 -0
- aiq/agent/rewoo_agent/prompt.py +108 -0
- aiq/agent/rewoo_agent/register.py +158 -0
- aiq/agent/tool_calling_agent/__init__.py +0 -0
- aiq/agent/tool_calling_agent/agent.py +119 -0
- aiq/agent/tool_calling_agent/register.py +106 -0
- aiq/authentication/__init__.py +14 -0
- aiq/authentication/api_key/__init__.py +14 -0
- aiq/authentication/api_key/api_key_auth_provider.py +96 -0
- aiq/authentication/api_key/api_key_auth_provider_config.py +124 -0
- aiq/authentication/api_key/register.py +26 -0
- aiq/authentication/exceptions/__init__.py +14 -0
- aiq/authentication/exceptions/api_key_exceptions.py +38 -0
- aiq/authentication/http_basic_auth/__init__.py +0 -0
- aiq/authentication/http_basic_auth/http_basic_auth_provider.py +81 -0
- aiq/authentication/http_basic_auth/register.py +30 -0
- aiq/authentication/interfaces.py +93 -0
- aiq/authentication/oauth2/__init__.py +14 -0
- aiq/authentication/oauth2/oauth2_auth_code_flow_provider.py +107 -0
- aiq/authentication/oauth2/oauth2_auth_code_flow_provider_config.py +39 -0
- aiq/authentication/oauth2/register.py +25 -0
- aiq/authentication/register.py +21 -0
- aiq/builder/__init__.py +0 -0
- aiq/builder/builder.py +285 -0
- aiq/builder/component_utils.py +316 -0
- aiq/builder/context.py +264 -0
- aiq/builder/embedder.py +24 -0
- aiq/builder/eval_builder.py +161 -0
- aiq/builder/evaluator.py +29 -0
- aiq/builder/framework_enum.py +24 -0
- aiq/builder/front_end.py +73 -0
- aiq/builder/function.py +344 -0
- aiq/builder/function_base.py +380 -0
- aiq/builder/function_info.py +627 -0
- aiq/builder/intermediate_step_manager.py +174 -0
- aiq/builder/llm.py +25 -0
- aiq/builder/retriever.py +25 -0
- aiq/builder/user_interaction_manager.py +74 -0
- aiq/builder/workflow.py +148 -0
- aiq/builder/workflow_builder.py +1117 -0
- aiq/cli/__init__.py +14 -0
- aiq/cli/cli_utils/__init__.py +0 -0
- aiq/cli/cli_utils/config_override.py +231 -0
- aiq/cli/cli_utils/validation.py +37 -0
- aiq/cli/commands/__init__.py +0 -0
- aiq/cli/commands/configure/__init__.py +0 -0
- aiq/cli/commands/configure/channel/__init__.py +0 -0
- aiq/cli/commands/configure/channel/add.py +28 -0
- aiq/cli/commands/configure/channel/channel.py +36 -0
- aiq/cli/commands/configure/channel/remove.py +30 -0
- aiq/cli/commands/configure/channel/update.py +30 -0
- aiq/cli/commands/configure/configure.py +33 -0
- aiq/cli/commands/evaluate.py +139 -0
- aiq/cli/commands/info/__init__.py +14 -0
- aiq/cli/commands/info/info.py +39 -0
- aiq/cli/commands/info/list_channels.py +32 -0
- aiq/cli/commands/info/list_components.py +129 -0
- aiq/cli/commands/info/list_mcp.py +213 -0
- aiq/cli/commands/registry/__init__.py +14 -0
- aiq/cli/commands/registry/publish.py +88 -0
- aiq/cli/commands/registry/pull.py +118 -0
- aiq/cli/commands/registry/registry.py +38 -0
- aiq/cli/commands/registry/remove.py +108 -0
- aiq/cli/commands/registry/search.py +155 -0
- aiq/cli/commands/sizing/__init__.py +14 -0
- aiq/cli/commands/sizing/calc.py +297 -0
- aiq/cli/commands/sizing/sizing.py +27 -0
- aiq/cli/commands/start.py +246 -0
- aiq/cli/commands/uninstall.py +81 -0
- aiq/cli/commands/validate.py +47 -0
- aiq/cli/commands/workflow/__init__.py +14 -0
- aiq/cli/commands/workflow/templates/__init__.py.j2 +0 -0
- aiq/cli/commands/workflow/templates/config.yml.j2 +16 -0
- aiq/cli/commands/workflow/templates/pyproject.toml.j2 +22 -0
- aiq/cli/commands/workflow/templates/register.py.j2 +5 -0
- aiq/cli/commands/workflow/templates/workflow.py.j2 +36 -0
- aiq/cli/commands/workflow/workflow.py +37 -0
- aiq/cli/commands/workflow/workflow_commands.py +313 -0
- aiq/cli/entrypoint.py +135 -0
- aiq/cli/main.py +44 -0
- aiq/cli/register_workflow.py +488 -0
- aiq/cli/type_registry.py +1000 -0
- aiq/data_models/__init__.py +14 -0
- aiq/data_models/api_server.py +694 -0
- aiq/data_models/authentication.py +231 -0
- aiq/data_models/common.py +171 -0
- aiq/data_models/component.py +54 -0
- aiq/data_models/component_ref.py +168 -0
- aiq/data_models/config.py +406 -0
- aiq/data_models/dataset_handler.py +123 -0
- aiq/data_models/discovery_metadata.py +335 -0
- aiq/data_models/embedder.py +27 -0
- aiq/data_models/evaluate.py +127 -0
- aiq/data_models/evaluator.py +26 -0
- aiq/data_models/front_end.py +26 -0
- aiq/data_models/function.py +30 -0
- aiq/data_models/function_dependencies.py +72 -0
- aiq/data_models/interactive.py +246 -0
- aiq/data_models/intermediate_step.py +302 -0
- aiq/data_models/invocation_node.py +38 -0
- aiq/data_models/llm.py +27 -0
- aiq/data_models/logging.py +26 -0
- aiq/data_models/memory.py +27 -0
- aiq/data_models/object_store.py +44 -0
- aiq/data_models/profiler.py +54 -0
- aiq/data_models/registry_handler.py +26 -0
- aiq/data_models/retriever.py +30 -0
- aiq/data_models/retry_mixin.py +35 -0
- aiq/data_models/span.py +187 -0
- aiq/data_models/step_adaptor.py +64 -0
- aiq/data_models/streaming.py +33 -0
- aiq/data_models/swe_bench_model.py +54 -0
- aiq/data_models/telemetry_exporter.py +26 -0
- aiq/data_models/ttc_strategy.py +30 -0
- aiq/embedder/__init__.py +0 -0
- aiq/embedder/langchain_client.py +41 -0
- aiq/embedder/nim_embedder.py +59 -0
- aiq/embedder/openai_embedder.py +43 -0
- aiq/embedder/register.py +24 -0
- aiq/eval/__init__.py +14 -0
- aiq/eval/config.py +60 -0
- aiq/eval/dataset_handler/__init__.py +0 -0
- aiq/eval/dataset_handler/dataset_downloader.py +106 -0
- aiq/eval/dataset_handler/dataset_filter.py +52 -0
- aiq/eval/dataset_handler/dataset_handler.py +254 -0
- aiq/eval/evaluate.py +506 -0
- aiq/eval/evaluator/__init__.py +14 -0
- aiq/eval/evaluator/base_evaluator.py +73 -0
- aiq/eval/evaluator/evaluator_model.py +45 -0
- aiq/eval/intermediate_step_adapter.py +99 -0
- aiq/eval/rag_evaluator/__init__.py +0 -0
- aiq/eval/rag_evaluator/evaluate.py +178 -0
- aiq/eval/rag_evaluator/register.py +143 -0
- aiq/eval/register.py +23 -0
- aiq/eval/remote_workflow.py +133 -0
- aiq/eval/runners/__init__.py +14 -0
- aiq/eval/runners/config.py +39 -0
- aiq/eval/runners/multi_eval_runner.py +54 -0
- aiq/eval/runtime_event_subscriber.py +52 -0
- aiq/eval/swe_bench_evaluator/__init__.py +0 -0
- aiq/eval/swe_bench_evaluator/evaluate.py +215 -0
- aiq/eval/swe_bench_evaluator/register.py +36 -0
- aiq/eval/trajectory_evaluator/__init__.py +0 -0
- aiq/eval/trajectory_evaluator/evaluate.py +75 -0
- aiq/eval/trajectory_evaluator/register.py +40 -0
- aiq/eval/tunable_rag_evaluator/__init__.py +0 -0
- aiq/eval/tunable_rag_evaluator/evaluate.py +245 -0
- aiq/eval/tunable_rag_evaluator/register.py +52 -0
- aiq/eval/usage_stats.py +41 -0
- aiq/eval/utils/__init__.py +0 -0
- aiq/eval/utils/output_uploader.py +140 -0
- aiq/eval/utils/tqdm_position_registry.py +40 -0
- aiq/eval/utils/weave_eval.py +184 -0
- aiq/experimental/__init__.py +0 -0
- aiq/experimental/decorators/__init__.py +0 -0
- aiq/experimental/decorators/experimental_warning_decorator.py +130 -0
- aiq/experimental/test_time_compute/__init__.py +0 -0
- aiq/experimental/test_time_compute/editing/__init__.py +0 -0
- aiq/experimental/test_time_compute/editing/iterative_plan_refinement_editor.py +147 -0
- aiq/experimental/test_time_compute/editing/llm_as_a_judge_editor.py +204 -0
- aiq/experimental/test_time_compute/editing/motivation_aware_summarization.py +107 -0
- aiq/experimental/test_time_compute/functions/__init__.py +0 -0
- aiq/experimental/test_time_compute/functions/execute_score_select_function.py +105 -0
- aiq/experimental/test_time_compute/functions/its_tool_orchestration_function.py +205 -0
- aiq/experimental/test_time_compute/functions/its_tool_wrapper_function.py +146 -0
- aiq/experimental/test_time_compute/functions/plan_select_execute_function.py +224 -0
- aiq/experimental/test_time_compute/models/__init__.py +0 -0
- aiq/experimental/test_time_compute/models/editor_config.py +132 -0
- aiq/experimental/test_time_compute/models/scoring_config.py +112 -0
- aiq/experimental/test_time_compute/models/search_config.py +120 -0
- aiq/experimental/test_time_compute/models/selection_config.py +154 -0
- aiq/experimental/test_time_compute/models/stage_enums.py +43 -0
- aiq/experimental/test_time_compute/models/strategy_base.py +66 -0
- aiq/experimental/test_time_compute/models/tool_use_config.py +41 -0
- aiq/experimental/test_time_compute/models/ttc_item.py +48 -0
- aiq/experimental/test_time_compute/register.py +36 -0
- aiq/experimental/test_time_compute/scoring/__init__.py +0 -0
- aiq/experimental/test_time_compute/scoring/llm_based_agent_scorer.py +168 -0
- aiq/experimental/test_time_compute/scoring/llm_based_plan_scorer.py +168 -0
- aiq/experimental/test_time_compute/scoring/motivation_aware_scorer.py +111 -0
- aiq/experimental/test_time_compute/search/__init__.py +0 -0
- aiq/experimental/test_time_compute/search/multi_llm_planner.py +128 -0
- aiq/experimental/test_time_compute/search/multi_query_retrieval_search.py +122 -0
- aiq/experimental/test_time_compute/search/single_shot_multi_plan_planner.py +128 -0
- aiq/experimental/test_time_compute/selection/__init__.py +0 -0
- aiq/experimental/test_time_compute/selection/best_of_n_selector.py +63 -0
- aiq/experimental/test_time_compute/selection/llm_based_agent_output_selector.py +131 -0
- aiq/experimental/test_time_compute/selection/llm_based_output_merging_selector.py +159 -0
- aiq/experimental/test_time_compute/selection/llm_based_plan_selector.py +128 -0
- aiq/experimental/test_time_compute/selection/threshold_selector.py +58 -0
- aiq/front_ends/__init__.py +14 -0
- aiq/front_ends/console/__init__.py +14 -0
- aiq/front_ends/console/authentication_flow_handler.py +233 -0
- aiq/front_ends/console/console_front_end_config.py +32 -0
- aiq/front_ends/console/console_front_end_plugin.py +96 -0
- aiq/front_ends/console/register.py +25 -0
- aiq/front_ends/cron/__init__.py +14 -0
- aiq/front_ends/fastapi/__init__.py +14 -0
- aiq/front_ends/fastapi/auth_flow_handlers/__init__.py +0 -0
- aiq/front_ends/fastapi/auth_flow_handlers/http_flow_handler.py +27 -0
- aiq/front_ends/fastapi/auth_flow_handlers/websocket_flow_handler.py +107 -0
- aiq/front_ends/fastapi/fastapi_front_end_config.py +234 -0
- aiq/front_ends/fastapi/fastapi_front_end_controller.py +68 -0
- aiq/front_ends/fastapi/fastapi_front_end_plugin.py +116 -0
- aiq/front_ends/fastapi/fastapi_front_end_plugin_worker.py +1092 -0
- aiq/front_ends/fastapi/html_snippets/__init__.py +14 -0
- aiq/front_ends/fastapi/html_snippets/auth_code_grant_success.py +35 -0
- aiq/front_ends/fastapi/intermediate_steps_subscriber.py +80 -0
- aiq/front_ends/fastapi/job_store.py +183 -0
- aiq/front_ends/fastapi/main.py +72 -0
- aiq/front_ends/fastapi/message_handler.py +298 -0
- aiq/front_ends/fastapi/message_validator.py +345 -0
- aiq/front_ends/fastapi/register.py +25 -0
- aiq/front_ends/fastapi/response_helpers.py +195 -0
- aiq/front_ends/fastapi/step_adaptor.py +321 -0
- aiq/front_ends/mcp/__init__.py +14 -0
- aiq/front_ends/mcp/mcp_front_end_config.py +32 -0
- aiq/front_ends/mcp/mcp_front_end_plugin.py +93 -0
- aiq/front_ends/mcp/register.py +27 -0
- aiq/front_ends/mcp/tool_converter.py +242 -0
- aiq/front_ends/register.py +22 -0
- aiq/front_ends/simple_base/__init__.py +14 -0
- aiq/front_ends/simple_base/simple_front_end_plugin_base.py +54 -0
- aiq/llm/__init__.py +0 -0
- aiq/llm/aws_bedrock_llm.py +57 -0
- aiq/llm/nim_llm.py +46 -0
- aiq/llm/openai_llm.py +46 -0
- aiq/llm/register.py +23 -0
- aiq/llm/utils/__init__.py +14 -0
- aiq/llm/utils/env_config_value.py +94 -0
- aiq/llm/utils/error.py +17 -0
- aiq/memory/__init__.py +20 -0
- aiq/memory/interfaces.py +183 -0
- aiq/memory/models.py +112 -0
- aiq/meta/module_to_distro.json +3 -0
- aiq/meta/pypi.md +58 -0
- aiq/object_store/__init__.py +20 -0
- aiq/object_store/in_memory_object_store.py +76 -0
- aiq/object_store/interfaces.py +84 -0
- aiq/object_store/models.py +36 -0
- aiq/object_store/register.py +20 -0
- aiq/observability/__init__.py +14 -0
- aiq/observability/exporter/__init__.py +14 -0
- aiq/observability/exporter/base_exporter.py +449 -0
- aiq/observability/exporter/exporter.py +78 -0
- aiq/observability/exporter/file_exporter.py +33 -0
- aiq/observability/exporter/processing_exporter.py +322 -0
- aiq/observability/exporter/raw_exporter.py +52 -0
- aiq/observability/exporter/span_exporter.py +265 -0
- aiq/observability/exporter_manager.py +335 -0
- aiq/observability/mixin/__init__.py +14 -0
- aiq/observability/mixin/batch_config_mixin.py +26 -0
- aiq/observability/mixin/collector_config_mixin.py +23 -0
- aiq/observability/mixin/file_mixin.py +288 -0
- aiq/observability/mixin/file_mode.py +23 -0
- aiq/observability/mixin/resource_conflict_mixin.py +134 -0
- aiq/observability/mixin/serialize_mixin.py +61 -0
- aiq/observability/mixin/type_introspection_mixin.py +183 -0
- aiq/observability/processor/__init__.py +14 -0
- aiq/observability/processor/batching_processor.py +310 -0
- aiq/observability/processor/callback_processor.py +42 -0
- aiq/observability/processor/intermediate_step_serializer.py +28 -0
- aiq/observability/processor/processor.py +71 -0
- aiq/observability/register.py +96 -0
- aiq/observability/utils/__init__.py +14 -0
- aiq/observability/utils/dict_utils.py +236 -0
- aiq/observability/utils/time_utils.py +31 -0
- aiq/plugins/.namespace +1 -0
- aiq/profiler/__init__.py +0 -0
- aiq/profiler/calc/__init__.py +14 -0
- aiq/profiler/calc/calc_runner.py +627 -0
- aiq/profiler/calc/calculations.py +288 -0
- aiq/profiler/calc/data_models.py +188 -0
- aiq/profiler/calc/plot.py +345 -0
- aiq/profiler/callbacks/__init__.py +0 -0
- aiq/profiler/callbacks/agno_callback_handler.py +295 -0
- aiq/profiler/callbacks/base_callback_class.py +20 -0
- aiq/profiler/callbacks/langchain_callback_handler.py +290 -0
- aiq/profiler/callbacks/llama_index_callback_handler.py +205 -0
- aiq/profiler/callbacks/semantic_kernel_callback_handler.py +238 -0
- aiq/profiler/callbacks/token_usage_base_model.py +27 -0
- aiq/profiler/data_frame_row.py +51 -0
- aiq/profiler/data_models.py +24 -0
- aiq/profiler/decorators/__init__.py +0 -0
- aiq/profiler/decorators/framework_wrapper.py +131 -0
- aiq/profiler/decorators/function_tracking.py +254 -0
- aiq/profiler/forecasting/__init__.py +0 -0
- aiq/profiler/forecasting/config.py +18 -0
- aiq/profiler/forecasting/model_trainer.py +75 -0
- aiq/profiler/forecasting/models/__init__.py +22 -0
- aiq/profiler/forecasting/models/forecasting_base_model.py +40 -0
- aiq/profiler/forecasting/models/linear_model.py +196 -0
- aiq/profiler/forecasting/models/random_forest_regressor.py +268 -0
- aiq/profiler/inference_metrics_model.py +28 -0
- aiq/profiler/inference_optimization/__init__.py +0 -0
- aiq/profiler/inference_optimization/bottleneck_analysis/__init__.py +0 -0
- aiq/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +460 -0
- aiq/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +258 -0
- aiq/profiler/inference_optimization/data_models.py +386 -0
- aiq/profiler/inference_optimization/experimental/__init__.py +0 -0
- aiq/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +468 -0
- aiq/profiler/inference_optimization/experimental/prefix_span_analysis.py +405 -0
- aiq/profiler/inference_optimization/llm_metrics.py +212 -0
- aiq/profiler/inference_optimization/prompt_caching.py +163 -0
- aiq/profiler/inference_optimization/token_uniqueness.py +107 -0
- aiq/profiler/inference_optimization/workflow_runtimes.py +72 -0
- aiq/profiler/intermediate_property_adapter.py +102 -0
- aiq/profiler/profile_runner.py +473 -0
- aiq/profiler/utils.py +184 -0
- aiq/registry_handlers/__init__.py +0 -0
- aiq/registry_handlers/local/__init__.py +0 -0
- aiq/registry_handlers/local/local_handler.py +176 -0
- aiq/registry_handlers/local/register_local.py +37 -0
- aiq/registry_handlers/metadata_factory.py +60 -0
- aiq/registry_handlers/package_utils.py +567 -0
- aiq/registry_handlers/pypi/__init__.py +0 -0
- aiq/registry_handlers/pypi/pypi_handler.py +251 -0
- aiq/registry_handlers/pypi/register_pypi.py +40 -0
- aiq/registry_handlers/register.py +21 -0
- aiq/registry_handlers/registry_handler_base.py +157 -0
- aiq/registry_handlers/rest/__init__.py +0 -0
- aiq/registry_handlers/rest/register_rest.py +56 -0
- aiq/registry_handlers/rest/rest_handler.py +237 -0
- aiq/registry_handlers/schemas/__init__.py +0 -0
- aiq/registry_handlers/schemas/headers.py +42 -0
- aiq/registry_handlers/schemas/package.py +68 -0
- aiq/registry_handlers/schemas/publish.py +63 -0
- aiq/registry_handlers/schemas/pull.py +82 -0
- aiq/registry_handlers/schemas/remove.py +36 -0
- aiq/registry_handlers/schemas/search.py +91 -0
- aiq/registry_handlers/schemas/status.py +47 -0
- aiq/retriever/__init__.py +0 -0
- aiq/retriever/interface.py +37 -0
- aiq/retriever/milvus/__init__.py +14 -0
- aiq/retriever/milvus/register.py +81 -0
- aiq/retriever/milvus/retriever.py +228 -0
- aiq/retriever/models.py +74 -0
- aiq/retriever/nemo_retriever/__init__.py +14 -0
- aiq/retriever/nemo_retriever/register.py +60 -0
- aiq/retriever/nemo_retriever/retriever.py +190 -0
- aiq/retriever/register.py +22 -0
- aiq/runtime/__init__.py +14 -0
- aiq/runtime/loader.py +215 -0
- aiq/runtime/runner.py +190 -0
- aiq/runtime/session.py +158 -0
- aiq/runtime/user_metadata.py +130 -0
- aiq/settings/__init__.py +0 -0
- aiq/settings/global_settings.py +318 -0
- aiq/test/.namespace +1 -0
- aiq/tool/__init__.py +0 -0
- aiq/tool/chat_completion.py +74 -0
- aiq/tool/code_execution/README.md +151 -0
- aiq/tool/code_execution/__init__.py +0 -0
- aiq/tool/code_execution/code_sandbox.py +267 -0
- aiq/tool/code_execution/local_sandbox/.gitignore +1 -0
- aiq/tool/code_execution/local_sandbox/Dockerfile.sandbox +60 -0
- aiq/tool/code_execution/local_sandbox/__init__.py +13 -0
- aiq/tool/code_execution/local_sandbox/local_sandbox_server.py +198 -0
- aiq/tool/code_execution/local_sandbox/sandbox.requirements.txt +6 -0
- aiq/tool/code_execution/local_sandbox/start_local_sandbox.sh +50 -0
- aiq/tool/code_execution/register.py +74 -0
- aiq/tool/code_execution/test_code_execution_sandbox.py +414 -0
- aiq/tool/code_execution/utils.py +100 -0
- aiq/tool/datetime_tools.py +42 -0
- aiq/tool/document_search.py +141 -0
- aiq/tool/github_tools/__init__.py +0 -0
- aiq/tool/github_tools/create_github_commit.py +133 -0
- aiq/tool/github_tools/create_github_issue.py +87 -0
- aiq/tool/github_tools/create_github_pr.py +106 -0
- aiq/tool/github_tools/get_github_file.py +106 -0
- aiq/tool/github_tools/get_github_issue.py +166 -0
- aiq/tool/github_tools/get_github_pr.py +256 -0
- aiq/tool/github_tools/update_github_issue.py +100 -0
- aiq/tool/mcp/__init__.py +14 -0
- aiq/tool/mcp/exceptions.py +142 -0
- aiq/tool/mcp/mcp_client.py +255 -0
- aiq/tool/mcp/mcp_tool.py +96 -0
- aiq/tool/memory_tools/__init__.py +0 -0
- aiq/tool/memory_tools/add_memory_tool.py +79 -0
- aiq/tool/memory_tools/delete_memory_tool.py +67 -0
- aiq/tool/memory_tools/get_memory_tool.py +72 -0
- aiq/tool/nvidia_rag.py +95 -0
- aiq/tool/register.py +38 -0
- aiq/tool/retriever.py +89 -0
- aiq/tool/server_tools.py +66 -0
- aiq/utils/__init__.py +0 -0
- aiq/utils/data_models/__init__.py +0 -0
- aiq/utils/data_models/schema_validator.py +58 -0
- aiq/utils/debugging_utils.py +43 -0
- aiq/utils/dump_distro_mapping.py +32 -0
- aiq/utils/exception_handlers/__init__.py +0 -0
- aiq/utils/exception_handlers/automatic_retries.py +289 -0
- aiq/utils/exception_handlers/mcp.py +211 -0
- aiq/utils/exception_handlers/schemas.py +114 -0
- aiq/utils/io/__init__.py +0 -0
- aiq/utils/io/model_processing.py +28 -0
- aiq/utils/io/yaml_tools.py +119 -0
- aiq/utils/log_utils.py +37 -0
- aiq/utils/metadata_utils.py +74 -0
- aiq/utils/optional_imports.py +142 -0
- aiq/utils/producer_consumer_queue.py +178 -0
- aiq/utils/reactive/__init__.py +0 -0
- aiq/utils/reactive/base/__init__.py +0 -0
- aiq/utils/reactive/base/observable_base.py +65 -0
- aiq/utils/reactive/base/observer_base.py +55 -0
- aiq/utils/reactive/base/subject_base.py +79 -0
- aiq/utils/reactive/observable.py +59 -0
- aiq/utils/reactive/observer.py +76 -0
- aiq/utils/reactive/subject.py +131 -0
- aiq/utils/reactive/subscription.py +49 -0
- aiq/utils/settings/__init__.py +0 -0
- aiq/utils/settings/global_settings.py +197 -0
- aiq/utils/string_utils.py +38 -0
- aiq/utils/type_converter.py +290 -0
- aiq/utils/type_utils.py +484 -0
- aiq/utils/url_utils.py +27 -0
- nvidia_nat-1.2.0rc5.dist-info/METADATA +363 -0
- nvidia_nat-1.2.0rc5.dist-info/RECORD +435 -0
- nvidia_nat-1.2.0rc5.dist-info/WHEEL +5 -0
- nvidia_nat-1.2.0rc5.dist-info/entry_points.txt +20 -0
- nvidia_nat-1.2.0rc5.dist-info/licenses/LICENSE-3rd-party.txt +3686 -0
- nvidia_nat-1.2.0rc5.dist-info/licenses/LICENSE.md +201 -0
- nvidia_nat-1.2.0rc5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
import os.path
|
|
18
|
+
import shutil
|
|
19
|
+
import subprocess
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from urllib.parse import urlparse
|
|
22
|
+
|
|
23
|
+
import click
|
|
24
|
+
from jinja2 import Environment
|
|
25
|
+
from jinja2 import FileSystemLoader
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AIQPackageError(Exception):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_repo_root():
|
|
35
|
+
return find_package_root("aiqtoolkit")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _get_module_name(workflow_name: str):
|
|
39
|
+
return workflow_name.replace("-", "_")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _generate_valid_classname(class_name: str):
|
|
43
|
+
return class_name.replace('_', ' ').replace('-', ' ').title().replace(' ', '')
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def find_package_root(package_name: str) -> Path | None:
|
|
47
|
+
"""
|
|
48
|
+
Find the root directory for a python package installed with the "editable" option.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
package_name: The python package name as it appears when importing it into a python script
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Posix path pointing to the package root
|
|
55
|
+
"""
|
|
56
|
+
import json
|
|
57
|
+
from importlib.metadata import Distribution
|
|
58
|
+
from importlib.metadata import PackageNotFoundError
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
dist_info = Distribution.from_name(package_name)
|
|
62
|
+
direct_url = dist_info.read_text("direct_url.json")
|
|
63
|
+
if not direct_url:
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
info = json.loads(direct_url)
|
|
68
|
+
except json.JSONDecodeError:
|
|
69
|
+
logger.error("Malformed direct_url.json for package: %s", package_name)
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
if not info.get("dir_info", {}).get("editable"):
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
# Parse URL
|
|
76
|
+
url = info.get("url", "")
|
|
77
|
+
parsed_url = urlparse(url)
|
|
78
|
+
|
|
79
|
+
if parsed_url.scheme != "file":
|
|
80
|
+
logger.error("Invalid URL scheme in direct_url.json: %s", url)
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
package_root = Path(parsed_url.path).resolve()
|
|
84
|
+
|
|
85
|
+
# Ensure the path exists and is within an allowed base directory
|
|
86
|
+
if not package_root.exists() or not package_root.is_dir():
|
|
87
|
+
logger.error("Package root does not exist: %s", package_root)
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
return package_root
|
|
91
|
+
|
|
92
|
+
except TypeError:
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
except PackageNotFoundError as e:
|
|
96
|
+
raise AIQPackageError(f"Package {package_name} is not installed") from e
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def get_workflow_path_from_name(workflow_name: str):
|
|
100
|
+
"""
|
|
101
|
+
Look up the location of an installed AIQ Toolkit workflow and retrieve the root directory of the installed workflow.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
workflow_name: The name of the workflow.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
Path object for the workflow's root directory.
|
|
108
|
+
"""
|
|
109
|
+
# Get the module name as a valid package name.
|
|
110
|
+
try:
|
|
111
|
+
module_name = _get_module_name(workflow_name)
|
|
112
|
+
package_root = find_package_root(module_name)
|
|
113
|
+
return package_root
|
|
114
|
+
|
|
115
|
+
except AIQPackageError as e:
|
|
116
|
+
logger.info("Unable to get the directory path for %s: %s", workflow_name, e)
|
|
117
|
+
return None
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@click.command()
|
|
121
|
+
@click.argument('workflow_name')
|
|
122
|
+
@click.option('--install/--no-install', default=True, help="Whether to install the workflow package immediately.")
|
|
123
|
+
@click.option(
|
|
124
|
+
"--workflow-dir",
|
|
125
|
+
default=".",
|
|
126
|
+
help="Output directory for saving the created workflow. A new folder with the workflow name will be created "
|
|
127
|
+
"within. Defaults to the present working directory.")
|
|
128
|
+
@click.option(
|
|
129
|
+
"--description",
|
|
130
|
+
default="AIQ Toolkit function template. Please update the description.",
|
|
131
|
+
help="""A description of the component being created. Will be used to populate the docstring and will describe the
|
|
132
|
+
component when inspecting installed components using 'aiq info component'""")
|
|
133
|
+
# pylint: disable=missing-param-doc
|
|
134
|
+
def create_command(workflow_name: str, install: bool, workflow_dir: str, description: str):
|
|
135
|
+
"""
|
|
136
|
+
Create a new AIQ Toolkit workflow using templates.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
workflow_name (str): The name of the new workflow.
|
|
140
|
+
install (bool): Whether to install the workflow package immediately.
|
|
141
|
+
workflow_dir (str): The directory to create the workflow package.
|
|
142
|
+
description (str): Description to pre-popluate the workflow docstring.
|
|
143
|
+
"""
|
|
144
|
+
try:
|
|
145
|
+
# Get the repository root
|
|
146
|
+
try:
|
|
147
|
+
repo_root = get_repo_root()
|
|
148
|
+
except AIQPackageError:
|
|
149
|
+
repo_root = None
|
|
150
|
+
|
|
151
|
+
# Get the absolute path for the output directory
|
|
152
|
+
if not os.path.isabs(workflow_dir):
|
|
153
|
+
workflow_dir = os.path.abspath(workflow_dir)
|
|
154
|
+
|
|
155
|
+
if not os.path.exists(workflow_dir):
|
|
156
|
+
raise ValueError(f"Invalid workflow directory specified. {workflow_dir} does not exist.")
|
|
157
|
+
|
|
158
|
+
# Define paths
|
|
159
|
+
template_dir = Path(__file__).parent / 'templates'
|
|
160
|
+
new_workflow_dir = Path(workflow_dir) / workflow_name
|
|
161
|
+
package_name = _get_module_name(workflow_name)
|
|
162
|
+
rel_path_to_repo_root = "" if not repo_root else os.path.relpath(repo_root, new_workflow_dir)
|
|
163
|
+
|
|
164
|
+
# Check if the workflow already exists
|
|
165
|
+
if new_workflow_dir.exists():
|
|
166
|
+
click.echo(f"Workflow '{workflow_name}' already exists.")
|
|
167
|
+
return
|
|
168
|
+
|
|
169
|
+
# Create directory structure
|
|
170
|
+
(new_workflow_dir / 'src' / package_name).mkdir(parents=True)
|
|
171
|
+
# Create config directory
|
|
172
|
+
(new_workflow_dir / 'src' / package_name / 'configs').mkdir(parents=True)
|
|
173
|
+
# Create package level configs directory
|
|
174
|
+
(new_workflow_dir / 'configs').mkdir(parents=True)
|
|
175
|
+
|
|
176
|
+
# Initialize Jinja2 environment
|
|
177
|
+
env = Environment(loader=FileSystemLoader(str(template_dir)))
|
|
178
|
+
editable = get_repo_root() is not None
|
|
179
|
+
|
|
180
|
+
if editable:
|
|
181
|
+
install_cmd = ['uv', 'pip', 'install', '-e', str(new_workflow_dir)]
|
|
182
|
+
else:
|
|
183
|
+
install_cmd = ['pip', 'install', '-e', str(new_workflow_dir)]
|
|
184
|
+
|
|
185
|
+
# List of templates and their destinations
|
|
186
|
+
files_to_render = {
|
|
187
|
+
'pyproject.toml.j2': new_workflow_dir / 'pyproject.toml',
|
|
188
|
+
'register.py.j2': new_workflow_dir / 'src' / package_name / 'register.py',
|
|
189
|
+
'workflow.py.j2': new_workflow_dir / 'src' / package_name / f'{workflow_name}_function.py',
|
|
190
|
+
'__init__.py.j2': new_workflow_dir / 'src' / package_name / '__init__.py',
|
|
191
|
+
'config.yml.j2': new_workflow_dir / 'src' / package_name / 'configs' / 'config.yml',
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
# Render templates
|
|
195
|
+
context = {
|
|
196
|
+
'editable': editable,
|
|
197
|
+
'workflow_name': workflow_name,
|
|
198
|
+
'python_safe_workflow_name': workflow_name.replace("-", "_"),
|
|
199
|
+
'package_name': package_name,
|
|
200
|
+
'rel_path_to_repo_root': rel_path_to_repo_root,
|
|
201
|
+
'workflow_class_name': f"{_generate_valid_classname(workflow_name)}FunctionConfig",
|
|
202
|
+
'workflow_description': description
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
for template_name, output_path in files_to_render.items():
|
|
206
|
+
template = env.get_template(template_name)
|
|
207
|
+
content = template.render(context)
|
|
208
|
+
with open(output_path, 'w', encoding="utf-8") as f:
|
|
209
|
+
f.write(content)
|
|
210
|
+
|
|
211
|
+
# Create symlink for config.yml
|
|
212
|
+
config_source = new_workflow_dir / 'src' / package_name / 'configs' / 'config.yml'
|
|
213
|
+
config_link = new_workflow_dir / 'configs' / 'config.yml'
|
|
214
|
+
os.symlink(config_source, config_link)
|
|
215
|
+
|
|
216
|
+
if install:
|
|
217
|
+
# Install the new package without changing directories
|
|
218
|
+
click.echo(f"Installing workflow '{workflow_name}'...")
|
|
219
|
+
result = subprocess.run(install_cmd, capture_output=True, text=True, check=True)
|
|
220
|
+
|
|
221
|
+
if result.returncode != 0:
|
|
222
|
+
click.echo(f"An error occurred during installation:\n{result.stderr}")
|
|
223
|
+
return
|
|
224
|
+
|
|
225
|
+
click.echo(f"Workflow '{workflow_name}' installed successfully.")
|
|
226
|
+
|
|
227
|
+
click.echo(f"Workflow '{workflow_name}' created successfully in '{new_workflow_dir}'.")
|
|
228
|
+
except Exception as e:
|
|
229
|
+
logger.exception("An error occurred while creating the workflow: %s", e, exc_info=True)
|
|
230
|
+
click.echo(f"An error occurred while creating the workflow: {e}")
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@click.command()
|
|
234
|
+
@click.argument('workflow_name')
|
|
235
|
+
def reinstall_command(workflow_name):
|
|
236
|
+
"""
|
|
237
|
+
Reinstall an AIQ Toolkit workflow to update dependencies and code changes.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
workflow_name (str): The name of the workflow to reinstall.
|
|
241
|
+
"""
|
|
242
|
+
try:
|
|
243
|
+
editable = get_repo_root() is not None
|
|
244
|
+
|
|
245
|
+
workflow_dir = get_workflow_path_from_name(workflow_name)
|
|
246
|
+
if not workflow_dir or not workflow_dir.exists():
|
|
247
|
+
click.echo(f"Workflow '{workflow_name}' does not exist.")
|
|
248
|
+
return
|
|
249
|
+
|
|
250
|
+
# Reinstall the package without changing directories
|
|
251
|
+
click.echo(f"Reinstalling workflow '{workflow_name}'...")
|
|
252
|
+
if editable:
|
|
253
|
+
reinstall_cmd = ['uv', 'pip', 'install', '-e', str(workflow_dir)]
|
|
254
|
+
else:
|
|
255
|
+
reinstall_cmd = ['pip', 'install', '-e', str(workflow_dir)]
|
|
256
|
+
|
|
257
|
+
result = subprocess.run(reinstall_cmd, capture_output=True, text=True, check=True)
|
|
258
|
+
|
|
259
|
+
if result.returncode != 0:
|
|
260
|
+
click.echo(f"An error occurred during installation:\n{result.stderr}")
|
|
261
|
+
return
|
|
262
|
+
|
|
263
|
+
click.echo(f"Workflow '{workflow_name}' reinstalled successfully.")
|
|
264
|
+
except Exception as e:
|
|
265
|
+
logger.exception("An error occurred while reinstalling the workflow: %s", e, exc_info=True)
|
|
266
|
+
click.echo(f"An error occurred while reinstalling the workflow: {e}")
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
@click.command()
|
|
270
|
+
@click.argument('workflow_name')
|
|
271
|
+
def delete_command(workflow_name: str):
|
|
272
|
+
"""
|
|
273
|
+
Delete an AIQ Toolkit workflow and uninstall its package.
|
|
274
|
+
|
|
275
|
+
Args:
|
|
276
|
+
workflow_name (str): The name of the workflow to delete.
|
|
277
|
+
"""
|
|
278
|
+
try:
|
|
279
|
+
if not click.confirm(f"Are you sure you want to delete the workflow '{workflow_name}'?"):
|
|
280
|
+
click.echo("Workflow deletion cancelled.")
|
|
281
|
+
return
|
|
282
|
+
editable = get_repo_root() is not None
|
|
283
|
+
|
|
284
|
+
workflow_dir = get_workflow_path_from_name(workflow_name)
|
|
285
|
+
package_name = _get_module_name(workflow_name)
|
|
286
|
+
|
|
287
|
+
if editable:
|
|
288
|
+
uninstall_cmd = ['uv', 'pip', 'uninstall', package_name]
|
|
289
|
+
else:
|
|
290
|
+
uninstall_cmd = ['pip', 'uninstall', '-y', package_name]
|
|
291
|
+
|
|
292
|
+
# Uninstall the package
|
|
293
|
+
click.echo(f"Uninstalling workflow '{workflow_name}' package...")
|
|
294
|
+
result = subprocess.run(uninstall_cmd, capture_output=True, text=True, check=True)
|
|
295
|
+
|
|
296
|
+
if result.returncode != 0:
|
|
297
|
+
click.echo(f"An error occurred during uninstallation:\n{result.stderr}")
|
|
298
|
+
return
|
|
299
|
+
click.echo(
|
|
300
|
+
f"Workflow '{workflow_name}' (package '{package_name}') successfully uninstalled from python environment")
|
|
301
|
+
|
|
302
|
+
if not workflow_dir or not workflow_dir.exists():
|
|
303
|
+
click.echo(f"Unable to locate local files for {workflow_name}. Nothing will be deleted.")
|
|
304
|
+
return
|
|
305
|
+
|
|
306
|
+
# Remove the workflow directory
|
|
307
|
+
click.echo(f"Deleting workflow directory '{workflow_dir}'...")
|
|
308
|
+
shutil.rmtree(workflow_dir)
|
|
309
|
+
|
|
310
|
+
click.echo(f"Workflow '{workflow_name}' deleted successfully.")
|
|
311
|
+
except Exception as e:
|
|
312
|
+
logger.exception("An error occurred while deleting the workflow: %s", e, exc_info=True)
|
|
313
|
+
click.echo(f"An error occurred while deleting the workflow: {e}")
|
aiq/cli/entrypoint.py
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
17
|
+
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
|
18
|
+
#
|
|
19
|
+
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
|
20
|
+
# property and proprietary rights in and to this material, related
|
|
21
|
+
# documentation and any modifications thereto. Any use, reproduction,
|
|
22
|
+
# disclosure or distribution of this material and related documentation
|
|
23
|
+
# without an express license agreement from NVIDIA CORPORATION or
|
|
24
|
+
# its affiliates is strictly prohibited.
|
|
25
|
+
|
|
26
|
+
import logging
|
|
27
|
+
import sys
|
|
28
|
+
import time
|
|
29
|
+
|
|
30
|
+
import click
|
|
31
|
+
import nest_asyncio
|
|
32
|
+
|
|
33
|
+
from .commands.configure.configure import configure_command
|
|
34
|
+
from .commands.evaluate import eval_command
|
|
35
|
+
from .commands.info.info import info_command
|
|
36
|
+
from .commands.registry.registry import registry_command
|
|
37
|
+
from .commands.sizing.sizing import sizing
|
|
38
|
+
from .commands.start import start_command
|
|
39
|
+
from .commands.uninstall import uninstall_command
|
|
40
|
+
from .commands.validate import validate_command
|
|
41
|
+
from .commands.workflow.workflow import workflow_command
|
|
42
|
+
|
|
43
|
+
# Apply at the beginning of the file to avoid issues with asyncio
|
|
44
|
+
nest_asyncio.apply()
|
|
45
|
+
|
|
46
|
+
# Define log level choices
|
|
47
|
+
LOG_LEVELS = {
|
|
48
|
+
'DEBUG': logging.DEBUG,
|
|
49
|
+
'INFO': logging.INFO,
|
|
50
|
+
'WARNING': logging.WARNING,
|
|
51
|
+
'ERROR': logging.ERROR,
|
|
52
|
+
'CRITICAL': logging.CRITICAL
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def setup_logging(log_level: str):
|
|
57
|
+
"""Configure logging with the specified level"""
|
|
58
|
+
numeric_level = LOG_LEVELS.get(log_level.upper(), logging.INFO)
|
|
59
|
+
logging.basicConfig(level=numeric_level, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
60
|
+
return numeric_level
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def get_version():
|
|
64
|
+
from importlib.metadata import PackageNotFoundError
|
|
65
|
+
from importlib.metadata import version
|
|
66
|
+
try:
|
|
67
|
+
# Use the distro name to get the version
|
|
68
|
+
return version("aiqtoolkit")
|
|
69
|
+
except PackageNotFoundError:
|
|
70
|
+
return "unknown"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@click.group(name="aiq", chain=False, invoke_without_command=True, no_args_is_help=True)
|
|
74
|
+
@click.version_option(version=get_version())
|
|
75
|
+
@click.option('--log-level',
|
|
76
|
+
type=click.Choice(LOG_LEVELS.keys(), case_sensitive=False),
|
|
77
|
+
default='INFO',
|
|
78
|
+
help='Set the logging level')
|
|
79
|
+
@click.pass_context
|
|
80
|
+
def cli(ctx: click.Context, log_level: str):
|
|
81
|
+
"""Main entrypoint for the AIQ Toolkit CLI"""
|
|
82
|
+
|
|
83
|
+
ctx_dict = ctx.ensure_object(dict)
|
|
84
|
+
|
|
85
|
+
# Setup logging
|
|
86
|
+
numeric_level = setup_logging(log_level)
|
|
87
|
+
|
|
88
|
+
aiq_logger = logging.getLogger("aiq")
|
|
89
|
+
aiq_logger.setLevel(numeric_level)
|
|
90
|
+
|
|
91
|
+
logger = logging.getLogger(__package__)
|
|
92
|
+
|
|
93
|
+
# Set the parent logger for all of the llm examples to use morpheus so we can take advantage of configure_logging
|
|
94
|
+
logger.parent = aiq_logger
|
|
95
|
+
logger.setLevel(numeric_level)
|
|
96
|
+
|
|
97
|
+
ctx_dict["start_time"] = time.time()
|
|
98
|
+
ctx_dict["log_level"] = log_level
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
cli.add_command(configure_command, name="configure")
|
|
102
|
+
cli.add_command(eval_command, name="eval")
|
|
103
|
+
cli.add_command(info_command, name="info")
|
|
104
|
+
cli.add_command(registry_command, name="registry")
|
|
105
|
+
cli.add_command(start_command, name="start")
|
|
106
|
+
cli.add_command(uninstall_command, name="uninstall")
|
|
107
|
+
cli.add_command(validate_command, name="validate")
|
|
108
|
+
cli.add_command(workflow_command, name="workflow")
|
|
109
|
+
cli.add_command(sizing, name="sizing")
|
|
110
|
+
|
|
111
|
+
# Aliases
|
|
112
|
+
cli.add_command(start_command.get_command(None, "console"), name="run") # type: ignore
|
|
113
|
+
cli.add_command(start_command.get_command(None, "fastapi"), name="serve") # type: ignore
|
|
114
|
+
cli.add_command(start_command.get_command(None, "mcp"), name="mcp")
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@cli.result_callback()
|
|
118
|
+
@click.pass_context
|
|
119
|
+
def after_pipeline(ctx: click.Context, pipeline_start_time: float, *_, **__):
|
|
120
|
+
logger = logging.getLogger(__name__)
|
|
121
|
+
|
|
122
|
+
end_time = time.time()
|
|
123
|
+
|
|
124
|
+
ctx_dict = ctx.ensure_object(dict)
|
|
125
|
+
|
|
126
|
+
start_time = ctx_dict["start_time"]
|
|
127
|
+
|
|
128
|
+
# Reset the terminal colors, not using print to avoid an additional newline
|
|
129
|
+
for stream in (sys.stdout, sys.stderr):
|
|
130
|
+
stream.write("\x1b[0m")
|
|
131
|
+
|
|
132
|
+
logger.debug("Total time: %.2f sec", end_time - start_time)
|
|
133
|
+
|
|
134
|
+
if (pipeline_start_time is not None):
|
|
135
|
+
logger.debug("Pipeline runtime: %.2f sec", end_time - pipeline_start_time)
|
aiq/cli/main.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
17
|
+
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
|
|
18
|
+
#
|
|
19
|
+
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
|
|
20
|
+
# property and proprietary rights in and to this material, related
|
|
21
|
+
# documentation and any modifications thereto. Any use, reproduction,
|
|
22
|
+
# disclosure or distribution of this material and related documentation
|
|
23
|
+
# without an express license agreement from NVIDIA CORPORATION or
|
|
24
|
+
# its affiliates is strictly prohibited.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# The purpose of this function is to allow loading the current directory as a module. This allows relative imports and
|
|
28
|
+
# more specifically `..common` to function correctly
|
|
29
|
+
def run_cli():
|
|
30
|
+
import os
|
|
31
|
+
import sys
|
|
32
|
+
|
|
33
|
+
parent_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
|
34
|
+
|
|
35
|
+
if (parent_dir not in sys.path):
|
|
36
|
+
sys.path.append(parent_dir)
|
|
37
|
+
|
|
38
|
+
from aiq.cli.entrypoint import cli
|
|
39
|
+
|
|
40
|
+
cli(obj={}, auto_envvar_prefix='AIQ', show_default=True, prog_name="aiq")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
if __name__ == '__main__':
|
|
44
|
+
run_cli()
|