nvidia-nat 1.4.0a20251112__py3-none-any.whl → 1.4.0a20260113__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/__init__.py +1 -1
- nat/{front_ends/mcp → agent/auto_memory_wrapper}/__init__.py +1 -1
- nat/agent/auto_memory_wrapper/agent.py +278 -0
- nat/agent/auto_memory_wrapper/register.py +227 -0
- nat/agent/auto_memory_wrapper/state.py +30 -0
- nat/agent/base.py +1 -1
- nat/agent/dual_node.py +1 -1
- nat/agent/prompt_optimizer/prompt.py +1 -1
- nat/agent/prompt_optimizer/register.py +1 -1
- nat/agent/react_agent/agent.py +16 -9
- nat/agent/react_agent/output_parser.py +2 -2
- nat/agent/react_agent/prompt.py +3 -2
- nat/agent/react_agent/register.py +2 -2
- nat/agent/react_agent/register_per_user_agent.py +104 -0
- nat/agent/reasoning_agent/reasoning_agent.py +1 -1
- nat/agent/register.py +3 -1
- nat/agent/responses_api_agent/__init__.py +1 -1
- nat/agent/responses_api_agent/register.py +1 -1
- nat/agent/rewoo_agent/agent.py +9 -4
- nat/agent/rewoo_agent/prompt.py +1 -1
- nat/agent/rewoo_agent/register.py +1 -1
- nat/agent/tool_calling_agent/agent.py +5 -4
- nat/agent/tool_calling_agent/register.py +1 -1
- nat/authentication/__init__.py +1 -1
- nat/authentication/api_key/__init__.py +1 -1
- nat/authentication/api_key/api_key_auth_provider.py +1 -1
- nat/authentication/api_key/api_key_auth_provider_config.py +22 -7
- nat/authentication/api_key/register.py +1 -1
- nat/authentication/credential_validator/__init__.py +1 -1
- nat/authentication/credential_validator/bearer_token_validator.py +1 -1
- nat/authentication/exceptions/__init__.py +1 -1
- nat/authentication/exceptions/api_key_exceptions.py +1 -1
- nat/authentication/http_basic_auth/http_basic_auth_provider.py +1 -1
- nat/authentication/http_basic_auth/register.py +1 -1
- nat/authentication/interfaces.py +1 -1
- nat/authentication/oauth2/__init__.py +1 -1
- nat/authentication/oauth2/oauth2_auth_code_flow_provider.py +1 -1
- nat/authentication/oauth2/oauth2_auth_code_flow_provider_config.py +1 -1
- nat/authentication/oauth2/oauth2_resource_server_config.py +1 -1
- nat/authentication/oauth2/register.py +1 -1
- nat/authentication/register.py +1 -1
- nat/builder/builder.py +563 -1
- nat/builder/child_builder.py +385 -0
- nat/builder/component_utils.py +34 -4
- nat/builder/context.py +34 -1
- nat/builder/embedder.py +1 -1
- nat/builder/eval_builder.py +19 -7
- nat/builder/evaluator.py +1 -1
- nat/builder/framework_enum.py +3 -1
- nat/builder/front_end.py +1 -1
- nat/builder/function.py +113 -5
- nat/builder/function_base.py +1 -1
- nat/builder/function_info.py +1 -1
- nat/builder/intermediate_step_manager.py +1 -1
- nat/builder/llm.py +1 -1
- nat/builder/per_user_workflow_builder.py +843 -0
- nat/builder/retriever.py +1 -1
- nat/builder/sync_builder.py +571 -0
- nat/builder/user_interaction_manager.py +1 -1
- nat/builder/workflow.py +5 -3
- nat/builder/workflow_builder.py +619 -378
- nat/cli/__init__.py +1 -1
- nat/cli/cli_utils/config_override.py +1 -1
- nat/cli/cli_utils/validation.py +32 -1
- nat/cli/commands/configure/channel/add.py +1 -1
- nat/cli/commands/configure/channel/channel.py +1 -1
- nat/cli/commands/configure/channel/remove.py +1 -1
- nat/cli/commands/configure/channel/update.py +1 -1
- nat/cli/commands/configure/configure.py +1 -1
- nat/cli/commands/evaluate.py +87 -13
- nat/cli/commands/finetune.py +132 -0
- nat/cli/commands/info/__init__.py +1 -1
- nat/cli/commands/info/info.py +1 -1
- nat/cli/commands/info/list_channels.py +1 -1
- nat/cli/commands/info/list_components.py +1 -1
- nat/cli/commands/object_store/__init__.py +1 -1
- nat/cli/commands/object_store/object_store.py +1 -1
- nat/cli/commands/optimize.py +1 -1
- nat/cli/commands/{mcp → red_teaming}/__init__.py +1 -1
- nat/cli/commands/red_teaming/red_teaming.py +138 -0
- nat/cli/commands/red_teaming/red_teaming_utils.py +73 -0
- nat/cli/commands/registry/__init__.py +1 -1
- nat/cli/commands/registry/publish.py +1 -1
- nat/cli/commands/registry/pull.py +1 -1
- nat/cli/commands/registry/registry.py +1 -1
- nat/cli/commands/registry/remove.py +1 -1
- nat/cli/commands/registry/search.py +1 -1
- nat/cli/commands/sizing/__init__.py +1 -1
- nat/cli/commands/sizing/calc.py +1 -1
- nat/cli/commands/sizing/sizing.py +1 -1
- nat/cli/commands/start.py +1 -1
- nat/cli/commands/uninstall.py +1 -1
- nat/cli/commands/validate.py +1 -1
- nat/cli/commands/workflow/__init__.py +1 -1
- nat/cli/commands/workflow/workflow.py +1 -1
- nat/cli/commands/workflow/workflow_commands.py +3 -2
- nat/cli/entrypoint.py +15 -37
- nat/cli/main.py +2 -2
- nat/cli/plugin_loader.py +69 -0
- nat/cli/register_workflow.py +233 -5
- nat/cli/type_registry.py +237 -3
- nat/control_flow/register.py +1 -1
- nat/control_flow/router_agent/agent.py +1 -1
- nat/control_flow/router_agent/prompt.py +1 -1
- nat/control_flow/router_agent/register.py +1 -1
- nat/control_flow/sequential_executor.py +28 -7
- nat/data_models/__init__.py +1 -1
- nat/data_models/agent.py +1 -1
- nat/data_models/api_server.py +38 -3
- nat/data_models/authentication.py +1 -1
- nat/data_models/common.py +1 -1
- nat/data_models/component.py +9 -1
- nat/data_models/component_ref.py +45 -1
- nat/data_models/config.py +78 -1
- nat/data_models/dataset_handler.py +15 -2
- nat/data_models/discovery_metadata.py +1 -1
- nat/data_models/embedder.py +1 -1
- nat/data_models/evaluate.py +6 -1
- nat/data_models/evaluator.py +1 -1
- nat/data_models/finetuning.py +260 -0
- nat/data_models/front_end.py +1 -1
- nat/data_models/function.py +15 -2
- nat/data_models/function_dependencies.py +1 -1
- nat/data_models/gated_field_mixin.py +1 -1
- nat/data_models/interactive.py +1 -1
- nat/data_models/intermediate_step.py +29 -2
- nat/data_models/invocation_node.py +1 -1
- nat/data_models/llm.py +1 -1
- nat/data_models/logging.py +1 -1
- nat/data_models/memory.py +1 -1
- nat/data_models/middleware.py +37 -0
- nat/data_models/object_store.py +1 -1
- nat/data_models/openai_mcp.py +1 -1
- nat/data_models/optimizable.py +1 -1
- nat/data_models/optimizer.py +1 -1
- nat/data_models/profiler.py +1 -1
- nat/data_models/registry_handler.py +1 -1
- nat/data_models/retriever.py +1 -1
- nat/data_models/retry_mixin.py +1 -1
- nat/data_models/runtime_enum.py +26 -0
- nat/data_models/span.py +1 -1
- nat/data_models/step_adaptor.py +1 -1
- nat/data_models/streaming.py +1 -1
- nat/data_models/swe_bench_model.py +1 -1
- nat/data_models/telemetry_exporter.py +1 -1
- nat/data_models/thinking_mixin.py +1 -1
- nat/data_models/ttc_strategy.py +1 -1
- nat/embedder/azure_openai_embedder.py +1 -1
- nat/embedder/nim_embedder.py +1 -1
- nat/embedder/openai_embedder.py +1 -1
- nat/embedder/register.py +1 -1
- nat/eval/__init__.py +1 -1
- nat/eval/config.py +8 -1
- nat/eval/dataset_handler/dataset_downloader.py +1 -1
- nat/eval/dataset_handler/dataset_filter.py +1 -1
- nat/eval/dataset_handler/dataset_handler.py +4 -2
- nat/eval/evaluate.py +226 -81
- nat/eval/evaluator/__init__.py +1 -1
- nat/eval/evaluator/base_evaluator.py +2 -2
- nat/eval/evaluator/evaluator_model.py +3 -2
- nat/eval/intermediate_step_adapter.py +1 -1
- nat/eval/llm_validator.py +336 -0
- nat/eval/rag_evaluator/evaluate.py +17 -10
- nat/eval/rag_evaluator/register.py +1 -1
- nat/eval/red_teaming_evaluator/__init__.py +14 -0
- nat/eval/red_teaming_evaluator/data_models.py +66 -0
- nat/eval/red_teaming_evaluator/evaluate.py +327 -0
- nat/eval/red_teaming_evaluator/filter_conditions.py +75 -0
- nat/eval/red_teaming_evaluator/register.py +55 -0
- nat/eval/register.py +2 -1
- nat/eval/remote_workflow.py +1 -1
- nat/eval/runners/__init__.py +1 -1
- nat/eval/runners/config.py +1 -1
- nat/eval/runners/multi_eval_runner.py +1 -1
- nat/eval/runners/red_teaming_runner/__init__.py +24 -0
- nat/eval/runners/red_teaming_runner/config.py +282 -0
- nat/eval/runners/red_teaming_runner/report_utils.py +707 -0
- nat/eval/runners/red_teaming_runner/runner.py +867 -0
- nat/eval/runtime_evaluator/__init__.py +1 -1
- nat/eval/runtime_evaluator/evaluate.py +1 -1
- nat/eval/runtime_evaluator/register.py +1 -1
- nat/eval/runtime_event_subscriber.py +1 -1
- nat/eval/swe_bench_evaluator/evaluate.py +1 -1
- nat/eval/swe_bench_evaluator/register.py +1 -1
- nat/eval/trajectory_evaluator/evaluate.py +2 -2
- nat/eval/trajectory_evaluator/register.py +1 -1
- nat/eval/tunable_rag_evaluator/evaluate.py +5 -5
- nat/eval/tunable_rag_evaluator/register.py +1 -1
- nat/eval/usage_stats.py +1 -1
- nat/eval/utils/eval_trace_ctx.py +1 -1
- nat/eval/utils/output_uploader.py +1 -1
- nat/eval/utils/tqdm_position_registry.py +1 -1
- nat/eval/utils/weave_eval.py +1 -1
- nat/experimental/decorators/experimental_warning_decorator.py +1 -1
- nat/experimental/test_time_compute/editing/iterative_plan_refinement_editor.py +1 -1
- nat/experimental/test_time_compute/editing/llm_as_a_judge_editor.py +1 -1
- nat/experimental/test_time_compute/editing/motivation_aware_summarization.py +1 -1
- nat/experimental/test_time_compute/functions/execute_score_select_function.py +1 -1
- nat/experimental/test_time_compute/functions/multi_llm_judge_function.py +88 -0
- nat/experimental/test_time_compute/functions/plan_select_execute_function.py +1 -1
- nat/experimental/test_time_compute/functions/ttc_tool_orchestration_function.py +1 -1
- nat/experimental/test_time_compute/functions/ttc_tool_wrapper_function.py +1 -1
- nat/experimental/test_time_compute/models/editor_config.py +1 -1
- nat/experimental/test_time_compute/models/scoring_config.py +1 -1
- nat/experimental/test_time_compute/models/search_config.py +20 -2
- nat/experimental/test_time_compute/models/selection_config.py +33 -2
- nat/experimental/test_time_compute/models/stage_enums.py +1 -1
- nat/experimental/test_time_compute/models/strategy_base.py +1 -1
- nat/experimental/test_time_compute/models/tool_use_config.py +1 -1
- nat/experimental/test_time_compute/models/ttc_item.py +1 -1
- nat/experimental/test_time_compute/register.py +4 -1
- nat/experimental/test_time_compute/scoring/llm_based_agent_scorer.py +1 -1
- nat/experimental/test_time_compute/scoring/llm_based_plan_scorer.py +1 -1
- nat/experimental/test_time_compute/scoring/motivation_aware_scorer.py +1 -1
- nat/experimental/test_time_compute/search/multi_llm_generation.py +115 -0
- nat/experimental/test_time_compute/search/multi_llm_planner.py +1 -1
- nat/experimental/test_time_compute/search/multi_query_retrieval_search.py +1 -1
- nat/experimental/test_time_compute/search/single_shot_multi_plan_planner.py +1 -1
- nat/experimental/test_time_compute/selection/best_of_n_selector.py +1 -1
- nat/experimental/test_time_compute/selection/llm_based_agent_output_selector.py +1 -1
- nat/experimental/test_time_compute/selection/llm_based_output_merging_selector.py +1 -1
- nat/experimental/test_time_compute/selection/llm_based_plan_selector.py +1 -1
- nat/experimental/test_time_compute/selection/llm_judge_selection.py +127 -0
- nat/experimental/test_time_compute/selection/threshold_selector.py +1 -1
- nat/finetuning/__init__.py +24 -0
- nat/finetuning/finetuning_runtime.py +143 -0
- nat/finetuning/interfaces/__init__.py +24 -0
- nat/finetuning/interfaces/finetuning_runner.py +261 -0
- nat/finetuning/interfaces/trainer_adapter.py +103 -0
- nat/finetuning/interfaces/trajectory_builder.py +115 -0
- nat/finetuning/utils/__init__.py +15 -0
- nat/finetuning/utils/parsers/__init__.py +15 -0
- nat/finetuning/utils/parsers/adk_parser.py +141 -0
- nat/finetuning/utils/parsers/base_parser.py +238 -0
- nat/finetuning/utils/parsers/common.py +91 -0
- nat/finetuning/utils/parsers/langchain_parser.py +267 -0
- nat/finetuning/utils/parsers/llama_index_parser.py +218 -0
- nat/front_ends/__init__.py +1 -1
- nat/front_ends/console/__init__.py +1 -1
- nat/front_ends/console/authentication_flow_handler.py +1 -1
- nat/front_ends/console/console_front_end_config.py +4 -1
- nat/front_ends/console/console_front_end_plugin.py +5 -4
- nat/front_ends/console/register.py +1 -1
- nat/front_ends/cron/__init__.py +1 -1
- nat/front_ends/fastapi/__init__.py +1 -1
- nat/front_ends/fastapi/async_job.py +128 -0
- nat/front_ends/fastapi/auth_flow_handlers/http_flow_handler.py +1 -1
- nat/front_ends/fastapi/auth_flow_handlers/websocket_flow_handler.py +13 -9
- nat/front_ends/fastapi/dask_client_mixin.py +1 -1
- nat/front_ends/fastapi/fastapi_front_end_config.py +23 -1
- nat/front_ends/fastapi/fastapi_front_end_controller.py +1 -1
- nat/front_ends/fastapi/fastapi_front_end_plugin.py +25 -30
- nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py +318 -59
- nat/front_ends/fastapi/html_snippets/__init__.py +1 -1
- nat/front_ends/fastapi/html_snippets/auth_code_grant_success.py +1 -1
- nat/front_ends/fastapi/intermediate_steps_subscriber.py +12 -1
- nat/front_ends/fastapi/job_store.py +23 -11
- nat/front_ends/fastapi/main.py +1 -1
- nat/front_ends/fastapi/message_handler.py +27 -4
- nat/front_ends/fastapi/message_validator.py +54 -2
- nat/front_ends/fastapi/register.py +1 -1
- nat/front_ends/fastapi/response_helpers.py +16 -15
- nat/front_ends/fastapi/step_adaptor.py +1 -1
- nat/front_ends/fastapi/utils.py +1 -1
- nat/front_ends/register.py +1 -2
- nat/front_ends/simple_base/__init__.py +1 -1
- nat/front_ends/simple_base/simple_front_end_plugin_base.py +6 -4
- nat/llm/aws_bedrock_llm.py +1 -1
- nat/llm/azure_openai_llm.py +10 -1
- nat/llm/dynamo_llm.py +363 -0
- nat/llm/huggingface_llm.py +177 -0
- nat/llm/litellm_llm.py +1 -1
- nat/llm/nim_llm.py +1 -1
- nat/llm/openai_llm.py +1 -1
- nat/llm/register.py +3 -1
- nat/llm/utils/__init__.py +1 -1
- nat/llm/utils/env_config_value.py +1 -1
- nat/llm/utils/error.py +1 -1
- nat/llm/utils/thinking.py +1 -1
- nat/memory/__init__.py +1 -1
- nat/memory/interfaces.py +1 -1
- nat/memory/models.py +1 -1
- nat/meta/pypi.md +1 -1
- nat/middleware/__init__.py +35 -0
- nat/middleware/cache/__init__.py +14 -0
- nat/middleware/cache/cache_middleware.py +253 -0
- nat/middleware/cache/cache_middleware_config.py +44 -0
- nat/middleware/cache/register.py +33 -0
- nat/middleware/defense/__init__.py +14 -0
- nat/middleware/defense/defense_middleware.py +362 -0
- nat/middleware/defense/defense_middleware_content_guard.py +455 -0
- nat/middleware/defense/defense_middleware_data_models.py +91 -0
- nat/middleware/defense/defense_middleware_output_verifier.py +440 -0
- nat/middleware/defense/defense_middleware_pii.py +356 -0
- nat/middleware/defense/register.py +82 -0
- nat/middleware/dynamic/__init__.py +14 -0
- nat/middleware/dynamic/dynamic_function_middleware.py +962 -0
- nat/middleware/dynamic/dynamic_middleware_config.py +132 -0
- nat/middleware/dynamic/register.py +34 -0
- nat/middleware/function_middleware.py +370 -0
- nat/middleware/logging/__init__.py +14 -0
- nat/middleware/logging/logging_middleware.py +67 -0
- nat/middleware/logging/logging_middleware_config.py +28 -0
- nat/middleware/logging/register.py +33 -0
- nat/middleware/middleware.py +298 -0
- nat/middleware/red_teaming/__init__.py +14 -0
- nat/middleware/red_teaming/red_teaming_middleware.py +344 -0
- nat/middleware/red_teaming/red_teaming_middleware_config.py +112 -0
- nat/middleware/red_teaming/register.py +47 -0
- nat/middleware/register.py +22 -0
- nat/middleware/utils/__init__.py +14 -0
- nat/middleware/utils/workflow_inventory.py +155 -0
- nat/object_store/__init__.py +1 -1
- nat/object_store/in_memory_object_store.py +1 -1
- nat/object_store/interfaces.py +1 -1
- nat/object_store/models.py +1 -1
- nat/object_store/register.py +1 -1
- nat/observability/__init__.py +1 -1
- nat/observability/exporter/__init__.py +1 -1
- nat/observability/exporter/base_exporter.py +1 -1
- nat/observability/exporter/exporter.py +1 -1
- nat/observability/exporter/file_exporter.py +1 -1
- nat/observability/exporter/processing_exporter.py +1 -1
- nat/observability/exporter/raw_exporter.py +1 -1
- nat/observability/exporter/span_exporter.py +7 -1
- nat/observability/exporter_manager.py +1 -1
- nat/observability/mixin/__init__.py +1 -1
- nat/observability/mixin/batch_config_mixin.py +1 -1
- nat/observability/mixin/collector_config_mixin.py +1 -1
- nat/observability/mixin/file_mixin.py +1 -1
- nat/observability/mixin/file_mode.py +1 -1
- nat/observability/mixin/redaction_config_mixin.py +1 -1
- nat/observability/mixin/resource_conflict_mixin.py +1 -1
- nat/observability/mixin/serialize_mixin.py +1 -1
- nat/observability/mixin/tagging_config_mixin.py +1 -1
- nat/observability/mixin/type_introspection_mixin.py +1 -1
- nat/observability/processor/__init__.py +1 -1
- nat/observability/processor/batching_processor.py +1 -1
- nat/observability/processor/callback_processor.py +1 -1
- nat/observability/processor/falsy_batch_filter_processor.py +1 -1
- nat/observability/processor/intermediate_step_serializer.py +1 -1
- nat/observability/processor/processor.py +1 -1
- nat/observability/processor/processor_factory.py +1 -1
- nat/observability/processor/redaction/__init__.py +1 -1
- nat/observability/processor/redaction/contextual_redaction_processor.py +1 -1
- nat/observability/processor/redaction/contextual_span_redaction_processor.py +1 -1
- nat/observability/processor/redaction/redaction_processor.py +1 -1
- nat/observability/processor/redaction/span_header_redaction_processor.py +1 -1
- nat/observability/processor/span_tagging_processor.py +1 -1
- nat/observability/register.py +1 -1
- nat/observability/utils/__init__.py +1 -1
- nat/observability/utils/dict_utils.py +1 -1
- nat/observability/utils/time_utils.py +1 -1
- nat/profiler/calc/__init__.py +1 -1
- nat/profiler/calc/calc_runner.py +3 -3
- nat/profiler/calc/calculations.py +1 -1
- nat/profiler/calc/data_models.py +1 -1
- nat/profiler/calc/plot.py +30 -3
- nat/profiler/callbacks/agno_callback_handler.py +1 -1
- nat/profiler/callbacks/base_callback_class.py +1 -1
- nat/profiler/callbacks/langchain_callback_handler.py +33 -3
- nat/profiler/callbacks/llama_index_callback_handler.py +13 -10
- nat/profiler/callbacks/semantic_kernel_callback_handler.py +1 -1
- nat/profiler/callbacks/token_usage_base_model.py +1 -1
- nat/profiler/data_frame_row.py +1 -1
- nat/profiler/data_models.py +1 -1
- nat/profiler/decorators/framework_wrapper.py +32 -1
- nat/profiler/decorators/function_tracking.py +1 -1
- nat/profiler/forecasting/config.py +1 -1
- nat/profiler/forecasting/model_trainer.py +1 -1
- nat/profiler/forecasting/models/__init__.py +1 -1
- nat/profiler/forecasting/models/forecasting_base_model.py +1 -1
- nat/profiler/forecasting/models/linear_model.py +1 -1
- nat/profiler/forecasting/models/random_forest_regressor.py +1 -1
- nat/profiler/inference_metrics_model.py +1 -1
- nat/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +1 -1
- nat/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +1 -1
- nat/profiler/inference_optimization/data_models.py +1 -1
- nat/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +1 -1
- nat/profiler/inference_optimization/experimental/prefix_span_analysis.py +1 -1
- nat/profiler/inference_optimization/llm_metrics.py +1 -1
- nat/profiler/inference_optimization/prompt_caching.py +1 -1
- nat/profiler/inference_optimization/token_uniqueness.py +1 -1
- nat/profiler/inference_optimization/workflow_runtimes.py +1 -1
- nat/profiler/intermediate_property_adapter.py +1 -1
- nat/profiler/parameter_optimization/optimizable_utils.py +1 -1
- nat/profiler/parameter_optimization/optimizer_runtime.py +1 -1
- nat/profiler/parameter_optimization/parameter_optimizer.py +1 -1
- nat/profiler/parameter_optimization/parameter_selection.py +1 -1
- nat/profiler/parameter_optimization/pareto_visualizer.py +1 -1
- nat/profiler/parameter_optimization/prompt_optimizer.py +1 -1
- nat/profiler/parameter_optimization/update_helpers.py +1 -1
- nat/profiler/profile_runner.py +1 -1
- nat/profiler/utils.py +1 -1
- nat/registry_handlers/local/local_handler.py +1 -1
- nat/registry_handlers/local/register_local.py +1 -1
- nat/registry_handlers/metadata_factory.py +1 -1
- nat/registry_handlers/package_utils.py +1 -1
- nat/registry_handlers/pypi/pypi_handler.py +1 -1
- nat/registry_handlers/pypi/register_pypi.py +1 -1
- nat/registry_handlers/register.py +1 -1
- nat/registry_handlers/registry_handler_base.py +1 -1
- nat/registry_handlers/rest/register_rest.py +1 -1
- nat/registry_handlers/rest/rest_handler.py +1 -1
- nat/registry_handlers/schemas/headers.py +1 -1
- nat/registry_handlers/schemas/package.py +1 -1
- nat/registry_handlers/schemas/publish.py +1 -1
- nat/registry_handlers/schemas/pull.py +1 -1
- nat/registry_handlers/schemas/remove.py +1 -1
- nat/registry_handlers/schemas/search.py +1 -1
- nat/registry_handlers/schemas/status.py +1 -1
- nat/retriever/interface.py +1 -1
- nat/retriever/milvus/__init__.py +1 -1
- nat/retriever/milvus/register.py +12 -4
- nat/retriever/milvus/retriever.py +103 -41
- nat/retriever/models.py +1 -1
- nat/retriever/nemo_retriever/__init__.py +1 -1
- nat/retriever/nemo_retriever/register.py +1 -1
- nat/retriever/nemo_retriever/retriever.py +5 -5
- nat/retriever/register.py +1 -1
- nat/runtime/__init__.py +1 -1
- nat/runtime/loader.py +10 -3
- nat/runtime/metrics.py +180 -0
- nat/runtime/runner.py +13 -6
- nat/runtime/session.py +458 -32
- nat/runtime/user_metadata.py +1 -1
- nat/settings/global_settings.py +1 -1
- nat/tool/chat_completion.py +1 -1
- nat/tool/code_execution/README.md +1 -1
- nat/tool/code_execution/code_sandbox.py +2 -2
- nat/tool/code_execution/local_sandbox/Dockerfile.sandbox +1 -1
- nat/tool/code_execution/local_sandbox/__init__.py +1 -1
- nat/tool/code_execution/local_sandbox/local_sandbox_server.py +1 -1
- nat/tool/code_execution/local_sandbox/start_local_sandbox.sh +1 -1
- nat/tool/code_execution/register.py +1 -1
- nat/tool/code_execution/utils.py +1 -1
- nat/tool/datetime_tools.py +1 -1
- nat/tool/document_search.py +1 -1
- nat/tool/github_tools.py +1 -1
- nat/tool/memory_tools/add_memory_tool.py +1 -1
- nat/tool/memory_tools/delete_memory_tool.py +1 -1
- nat/tool/memory_tools/get_memory_tool.py +1 -1
- nat/tool/nvidia_rag.py +2 -2
- nat/tool/register.py +1 -1
- nat/tool/retriever.py +1 -1
- nat/tool/server_tools.py +1 -1
- nat/utils/__init__.py +8 -5
- nat/utils/callable_utils.py +1 -1
- nat/utils/data_models/schema_validator.py +1 -1
- nat/utils/debugging_utils.py +1 -1
- nat/utils/decorators.py +1 -1
- nat/utils/dump_distro_mapping.py +1 -1
- nat/utils/exception_handlers/automatic_retries.py +3 -3
- nat/utils/exception_handlers/schemas.py +1 -1
- nat/utils/io/model_processing.py +1 -1
- nat/utils/io/supress_logs.py +33 -0
- nat/utils/io/yaml_tools.py +1 -1
- nat/utils/log_levels.py +1 -1
- nat/utils/log_utils.py +13 -1
- nat/utils/metadata_utils.py +1 -1
- nat/utils/optional_imports.py +1 -1
- nat/utils/producer_consumer_queue.py +1 -1
- nat/utils/reactive/base/observable_base.py +1 -1
- nat/utils/reactive/base/observer_base.py +1 -1
- nat/utils/reactive/base/subject_base.py +1 -1
- nat/utils/reactive/observable.py +1 -1
- nat/utils/reactive/observer.py +1 -1
- nat/utils/reactive/subject.py +1 -1
- nat/utils/reactive/subscription.py +1 -1
- nat/utils/responses_api.py +1 -1
- nat/utils/settings/global_settings.py +1 -1
- nat/utils/string_utils.py +1 -1
- nat/utils/type_converter.py +18 -5
- nat/utils/type_utils.py +1 -1
- nat/utils/url_utils.py +1 -1
- {nvidia_nat-1.4.0a20251112.dist-info → nvidia_nat-1.4.0a20260113.dist-info}/METADATA +46 -15
- nvidia_nat-1.4.0a20260113.dist-info/RECORD +547 -0
- nvidia_nat-1.4.0a20260113.dist-info/entry_points.txt +38 -0
- nat/cli/commands/mcp/mcp.py +0 -986
- nat/front_ends/mcp/introspection_token_verifier.py +0 -73
- nat/front_ends/mcp/mcp_front_end_config.py +0 -109
- nat/front_ends/mcp/mcp_front_end_plugin.py +0 -151
- nat/front_ends/mcp/mcp_front_end_plugin_worker.py +0 -362
- nat/front_ends/mcp/memory_profiler.py +0 -320
- nat/front_ends/mcp/register.py +0 -27
- nat/front_ends/mcp/tool_converter.py +0 -321
- nvidia_nat-1.4.0a20251112.dist-info/RECORD +0 -481
- nvidia_nat-1.4.0a20251112.dist-info/entry_points.txt +0 -22
- {nvidia_nat-1.4.0a20251112.dist-info → nvidia_nat-1.4.0a20260113.dist-info}/WHEEL +0 -0
- {nvidia_nat-1.4.0a20251112.dist-info → nvidia_nat-1.4.0a20260113.dist-info}/licenses/LICENSE-3rd-party.txt +0 -0
- {nvidia_nat-1.4.0a20251112.dist-info → nvidia_nat-1.4.0a20260113.dist-info}/licenses/LICENSE.md +0 -0
- {nvidia_nat-1.4.0a20251112.dist-info → nvidia_nat-1.4.0a20260113.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
nat/retriever/interface.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
nat/retriever/milvus/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
nat/retriever/milvus/register.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -48,6 +48,7 @@ class MilvusRetrieverConfig(RetrieverBaseConfig, name="milvus_retriever"):
|
|
|
48
48
|
description: str | None = Field(default=None,
|
|
49
49
|
description="If present it will be used as the tool description",
|
|
50
50
|
alias="collection_description")
|
|
51
|
+
use_async_client: bool = Field(default=False, description="Use AsyncMilvusClient for async I/O operations. ")
|
|
51
52
|
|
|
52
53
|
|
|
53
54
|
@register_retriever_provider(config_type=MilvusRetrieverConfig)
|
|
@@ -58,13 +59,20 @@ async def milvus_retriever(retriever_config: MilvusRetrieverConfig, builder: Bui
|
|
|
58
59
|
|
|
59
60
|
@register_retriever_client(config_type=MilvusRetrieverConfig, wrapper_type=None)
|
|
60
61
|
async def milvus_retriever_client(config: MilvusRetrieverConfig, builder: Builder):
|
|
61
|
-
from pymilvus import MilvusClient
|
|
62
|
-
|
|
63
62
|
from nat.retriever.milvus.retriever import MilvusRetriever
|
|
64
63
|
|
|
65
64
|
embedder = await builder.get_embedder(embedder_name=config.embedding_model, wrapper_type=LLMFrameworkEnum.LANGCHAIN)
|
|
66
65
|
|
|
67
|
-
|
|
66
|
+
# Create Milvus client based on use_async_client flag
|
|
67
|
+
if config.use_async_client:
|
|
68
|
+
from pymilvus import AsyncMilvusClient
|
|
69
|
+
|
|
70
|
+
milvus_client = AsyncMilvusClient(uri=str(config.uri), **config.connection_args)
|
|
71
|
+
else:
|
|
72
|
+
from pymilvus import MilvusClient
|
|
73
|
+
|
|
74
|
+
milvus_client = MilvusClient(uri=str(config.uri), **config.connection_args)
|
|
75
|
+
|
|
68
76
|
retriever = MilvusRetriever(
|
|
69
77
|
client=milvus_client,
|
|
70
78
|
embedder=embedder,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -13,13 +13,18 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
import inspect
|
|
16
17
|
import logging
|
|
17
18
|
from functools import partial
|
|
19
|
+
from typing import TYPE_CHECKING
|
|
18
20
|
|
|
19
21
|
from langchain_core.embeddings import Embeddings
|
|
20
|
-
from pymilvus import MilvusClient
|
|
21
22
|
from pymilvus.client.abstract import Hit
|
|
22
23
|
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from pymilvus import AsyncMilvusClient
|
|
26
|
+
from pymilvus import MilvusClient
|
|
27
|
+
|
|
23
28
|
from nat.retriever.interface import Retriever
|
|
24
29
|
from nat.retriever.models import Document
|
|
25
30
|
from nat.retriever.models import RetrieverError
|
|
@@ -39,20 +44,27 @@ class MilvusRetriever(Retriever):
|
|
|
39
44
|
|
|
40
45
|
def __init__(
|
|
41
46
|
self,
|
|
42
|
-
client: MilvusClient,
|
|
47
|
+
client: "MilvusClient | AsyncMilvusClient",
|
|
43
48
|
embedder: Embeddings,
|
|
44
49
|
content_field: str = "text",
|
|
45
50
|
use_iterator: bool = False,
|
|
46
51
|
) -> None:
|
|
47
52
|
"""
|
|
48
|
-
Initialize the Milvus Retriever using a preconfigured MilvusClient
|
|
53
|
+
Initialize the Milvus Retriever using a preconfigured MilvusClient or AsyncMilvusClient
|
|
49
54
|
|
|
50
55
|
Args:
|
|
51
|
-
client (MilvusClient): Preinstantiate pymilvus.MilvusClient object.
|
|
52
56
|
"""
|
|
53
|
-
self._client = client
|
|
57
|
+
self._client: MilvusClient | AsyncMilvusClient = client
|
|
54
58
|
self._embedder = embedder
|
|
55
59
|
|
|
60
|
+
# Detect if client is async by inspecting method capabilities
|
|
61
|
+
search_method = getattr(client, "search", None)
|
|
62
|
+
list_collections_method = getattr(client, "list_collections", None)
|
|
63
|
+
self._is_async = any(
|
|
64
|
+
inspect.iscoroutinefunction(method) for method in (search_method, list_collections_method)
|
|
65
|
+
if method is not None)
|
|
66
|
+
logger.info("Initialized Milvus Retriever with %s client", "async" if self._is_async else "sync")
|
|
67
|
+
|
|
56
68
|
if use_iterator and "search_iterator" not in dir(self._client):
|
|
57
69
|
raise ValueError("This version of the pymilvus.MilvusClient does not support the search iterator.")
|
|
58
70
|
|
|
@@ -60,7 +72,7 @@ class MilvusRetriever(Retriever):
|
|
|
60
72
|
self._default_params = None
|
|
61
73
|
self._bound_params = []
|
|
62
74
|
self.content_field = content_field
|
|
63
|
-
logger.info("
|
|
75
|
+
logger.info("Milvus Retriever using %s for search.", self._search_func.__name__)
|
|
64
76
|
|
|
65
77
|
def bind(self, **kwargs) -> None:
|
|
66
78
|
"""
|
|
@@ -81,8 +93,13 @@ class MilvusRetriever(Retriever):
|
|
|
81
93
|
"""
|
|
82
94
|
return [param for param in ["query", "collection_name", "top_k", "filters"] if param not in self._bound_params]
|
|
83
95
|
|
|
84
|
-
def _validate_collection(self, collection_name: str) -> bool:
|
|
85
|
-
|
|
96
|
+
async def _validate_collection(self, collection_name: str) -> bool:
|
|
97
|
+
"""Validate that a collection exists."""
|
|
98
|
+
if self._is_async:
|
|
99
|
+
collections = await self._client.list_collections()
|
|
100
|
+
else:
|
|
101
|
+
collections = self._client.list_collections()
|
|
102
|
+
return collection_name in collections
|
|
86
103
|
|
|
87
104
|
async def search(self, query: str, **kwargs):
|
|
88
105
|
return await self._search_func(query=query, **kwargs)
|
|
@@ -108,39 +125,64 @@ class MilvusRetriever(Retriever):
|
|
|
108
125
|
collection_name,
|
|
109
126
|
top_k)
|
|
110
127
|
|
|
111
|
-
if not self._validate_collection(collection_name):
|
|
128
|
+
if not await self._validate_collection(collection_name):
|
|
112
129
|
raise CollectionNotFoundError(f"Collection: {collection_name} does not exist")
|
|
113
130
|
|
|
114
131
|
# If no output fields are specified, return all of them
|
|
115
132
|
if not output_fields:
|
|
116
|
-
|
|
133
|
+
if self._is_async:
|
|
134
|
+
collection_schema = await self._client.describe_collection(collection_name)
|
|
135
|
+
else:
|
|
136
|
+
collection_schema = self._client.describe_collection(collection_name)
|
|
117
137
|
output_fields = [
|
|
118
138
|
field["name"] for field in collection_schema.get("fields") if field["name"] != vector_field_name
|
|
119
139
|
]
|
|
120
140
|
|
|
121
|
-
search_vector = self._embedder.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
141
|
+
search_vector = await self._embedder.aembed_query(query)
|
|
142
|
+
|
|
143
|
+
# Create search iterator
|
|
144
|
+
if self._is_async:
|
|
145
|
+
search_iterator = await self._client.search_iterator(
|
|
146
|
+
collection_name=collection_name,
|
|
147
|
+
data=[search_vector],
|
|
148
|
+
batch_size=kwargs.get("batch_size", 1000),
|
|
149
|
+
filter=filters,
|
|
150
|
+
limit=top_k,
|
|
151
|
+
output_fields=output_fields,
|
|
152
|
+
search_params=search_params if search_params else {"metric_type": "L2"},
|
|
153
|
+
timeout=timeout,
|
|
154
|
+
anns_field=vector_field_name,
|
|
155
|
+
round_decimal=kwargs.get("round_decimal", -1),
|
|
156
|
+
partition_names=kwargs.get("partition_names", None),
|
|
157
|
+
)
|
|
158
|
+
else:
|
|
159
|
+
search_iterator = self._client.search_iterator(
|
|
160
|
+
collection_name=collection_name,
|
|
161
|
+
data=[search_vector],
|
|
162
|
+
batch_size=kwargs.get("batch_size", 1000),
|
|
163
|
+
filter=filters,
|
|
164
|
+
limit=top_k,
|
|
165
|
+
output_fields=output_fields,
|
|
166
|
+
search_params=search_params if search_params else {"metric_type": "L2"},
|
|
167
|
+
timeout=timeout,
|
|
168
|
+
anns_field=vector_field_name,
|
|
169
|
+
round_decimal=kwargs.get("round_decimal", -1),
|
|
170
|
+
partition_names=kwargs.get("partition_names", None),
|
|
171
|
+
)
|
|
136
172
|
|
|
137
173
|
results = []
|
|
138
174
|
try:
|
|
139
175
|
while True:
|
|
140
|
-
|
|
176
|
+
if self._is_async:
|
|
177
|
+
_res = await search_iterator.next()
|
|
178
|
+
else:
|
|
179
|
+
_res = search_iterator.next()
|
|
141
180
|
res = _res.get_res()
|
|
142
181
|
if len(_res) == 0:
|
|
143
|
-
|
|
182
|
+
if self._is_async:
|
|
183
|
+
await search_iterator.close()
|
|
184
|
+
else:
|
|
185
|
+
search_iterator.close()
|
|
144
186
|
break
|
|
145
187
|
|
|
146
188
|
if distance_cutoff and res[0][-1].distance > distance_cutoff:
|
|
@@ -176,10 +218,16 @@ class MilvusRetriever(Retriever):
|
|
|
176
218
|
collection_name,
|
|
177
219
|
top_k)
|
|
178
220
|
|
|
179
|
-
if not self._validate_collection(collection_name):
|
|
221
|
+
if not await self._validate_collection(collection_name):
|
|
180
222
|
raise CollectionNotFoundError(f"Collection: {collection_name} does not exist")
|
|
181
223
|
|
|
182
|
-
|
|
224
|
+
# Get collection schema
|
|
225
|
+
if self._is_async:
|
|
226
|
+
collection_schema = await self._client.describe_collection(collection_name)
|
|
227
|
+
else:
|
|
228
|
+
collection_schema = self._client.describe_collection(collection_name)
|
|
229
|
+
|
|
230
|
+
available_fields = [v.get("name") for v in collection_schema.get("fields", [])]
|
|
183
231
|
|
|
184
232
|
if self.content_field not in available_fields:
|
|
185
233
|
raise ValueError(f"The specified content field: {self.content_field} is not part of the schema.")
|
|
@@ -194,17 +242,31 @@ class MilvusRetriever(Retriever):
|
|
|
194
242
|
if self.content_field not in output_fields:
|
|
195
243
|
output_fields.append(self.content_field)
|
|
196
244
|
|
|
197
|
-
search_vector = self._embedder.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
245
|
+
search_vector = await self._embedder.aembed_query(query)
|
|
246
|
+
|
|
247
|
+
# Perform search
|
|
248
|
+
if self._is_async:
|
|
249
|
+
res = await self._client.search(
|
|
250
|
+
collection_name=collection_name,
|
|
251
|
+
data=[search_vector],
|
|
252
|
+
filter=filters,
|
|
253
|
+
output_fields=output_fields,
|
|
254
|
+
search_params=search_params if search_params else {"metric_type": "L2"},
|
|
255
|
+
timeout=timeout,
|
|
256
|
+
anns_field=vector_field_name,
|
|
257
|
+
limit=top_k,
|
|
258
|
+
)
|
|
259
|
+
else:
|
|
260
|
+
res = self._client.search(
|
|
261
|
+
collection_name=collection_name,
|
|
262
|
+
data=[search_vector],
|
|
263
|
+
filter=filters,
|
|
264
|
+
output_fields=output_fields,
|
|
265
|
+
search_params=search_params if search_params else {"metric_type": "L2"},
|
|
266
|
+
timeout=timeout,
|
|
267
|
+
anns_field=vector_field_name,
|
|
268
|
+
limit=top_k,
|
|
269
|
+
)
|
|
208
270
|
|
|
209
271
|
return _wrap_milvus_results(res[0], content_field=self.content_field)
|
|
210
272
|
|
nat/retriever/models.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -68,10 +68,10 @@ class NemoRetriever(Retriever):
|
|
|
68
68
|
|
|
69
69
|
def bind(self, **kwargs) -> None:
|
|
70
70
|
"""
|
|
71
|
-
Bind default values to the search method. Cannot bind the
|
|
71
|
+
Bind default values to the search method. Cannot bind the ``query`` parameter.
|
|
72
72
|
|
|
73
73
|
Args:
|
|
74
|
-
|
|
74
|
+
kwargs: Key value pairs corresponding to the default values of search parameters.
|
|
75
75
|
"""
|
|
76
76
|
if "query" in kwargs:
|
|
77
77
|
kwargs = {k: v for k, v in kwargs.items() if k != "query"}
|
|
@@ -87,7 +87,7 @@ class NemoRetriever(Retriever):
|
|
|
87
87
|
|
|
88
88
|
async def get_collections(self, client) -> list[Collection]:
|
|
89
89
|
"""
|
|
90
|
-
Get a list of all available collections as pydantic
|
|
90
|
+
Get a list of all available collections as pydantic Collection objects.
|
|
91
91
|
"""
|
|
92
92
|
collection_response = await client.get(urljoin(self.base_url, "/v1/collections"))
|
|
93
93
|
collection_response.raise_for_status()
|
|
@@ -102,7 +102,7 @@ class NemoRetriever(Retriever):
|
|
|
102
102
|
|
|
103
103
|
async def get_collection_by_name(self, collection_name, client) -> Collection:
|
|
104
104
|
"""
|
|
105
|
-
Retrieve a collection using
|
|
105
|
+
Retrieve a collection using its name. Will return the first collection found if the name is ambiguous.
|
|
106
106
|
"""
|
|
107
107
|
collections = await self.get_collections(client)
|
|
108
108
|
if (collection := next((c for c in collections if c.name == collection_name), None)) is None:
|
nat/retriever/register.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2024-
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
nat/runtime/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2024-
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
nat/runtime/loader.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2024-
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -112,9 +112,16 @@ async def load_workflow(config_file: StrPath, max_concurrency: int = -1):
|
|
|
112
112
|
config = load_config(config_file)
|
|
113
113
|
|
|
114
114
|
# Must yield the workflow function otherwise it cleans up
|
|
115
|
-
async with WorkflowBuilder.from_config(config=config) as
|
|
115
|
+
async with WorkflowBuilder.from_config(config=config) as builder:
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
session_manager = await SessionManager.create(config=config,
|
|
118
|
+
shared_builder=builder,
|
|
119
|
+
max_concurrency=max_concurrency)
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
yield session_manager
|
|
123
|
+
finally:
|
|
124
|
+
await session_manager.shutdown()
|
|
118
125
|
|
|
119
126
|
|
|
120
127
|
@lru_cache
|
nat/runtime/metrics.py
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, 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
|
+
"""Per-user workflow resource usage monitoring models and collector."""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import logging
|
|
20
|
+
from datetime import datetime
|
|
21
|
+
from typing import TYPE_CHECKING
|
|
22
|
+
|
|
23
|
+
from pydantic import BaseModel
|
|
24
|
+
from pydantic import Field
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from nat.runtime.session import SessionManager
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class PerUserSessionMetrics(BaseModel):
|
|
33
|
+
"""Session lifecycle metrics for a per-user workflow."""
|
|
34
|
+
|
|
35
|
+
created_at: datetime = Field(description="When the per-user workflow was created")
|
|
36
|
+
last_activity: datetime = Field(description="Last time the workflow was accessed")
|
|
37
|
+
ref_count: int = Field(ge=0, description="Current number of active references (in-flight requests)")
|
|
38
|
+
is_active: bool = Field(description="Whether the workflow is currently being used")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class PerUserRequestMetrics(BaseModel):
|
|
42
|
+
"""Request-level metrics for a per-user workflow."""
|
|
43
|
+
|
|
44
|
+
total_requests: int = Field(ge=0, default=0, description="Total number of requests processed")
|
|
45
|
+
active_requests: int = Field(ge=0, default=0, description="Number of currently active requests")
|
|
46
|
+
avg_latency_ms: float = Field(ge=0, default=0.0, description="Average request latency in milliseconds")
|
|
47
|
+
error_count: int = Field(ge=0, default=0, description="Total number of failed requests")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class PerUserMemoryMetrics(BaseModel):
|
|
51
|
+
"""Memory/resource count metrics for a per-user workflow."""
|
|
52
|
+
|
|
53
|
+
per_user_functions_count: int = Field(ge=0, default=0, description="Number of per-user functions built")
|
|
54
|
+
per_user_function_groups_count: int = Field(ge=0, default=0, description="Number of per-user function groups built")
|
|
55
|
+
exit_stack_size: int = Field(ge=0, default=0, description="Number of resources in the async exit stack")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class PerUserResourceUsage(BaseModel):
|
|
59
|
+
"""Combined resource usage metrics for a single per-user workflow."""
|
|
60
|
+
|
|
61
|
+
user_id: str = Field(description="The user identifier")
|
|
62
|
+
session: PerUserSessionMetrics = Field(description="Session lifecycle metrics")
|
|
63
|
+
requests: PerUserRequestMetrics = Field(description="Request-level metrics")
|
|
64
|
+
memory: PerUserMemoryMetrics = Field(description="Memory/resource count metrics")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class PerUserMonitorResponse(BaseModel):
|
|
68
|
+
"""Response model for the /monitor/users endpoint."""
|
|
69
|
+
|
|
70
|
+
timestamp: datetime = Field(default_factory=datetime.now, description="When the metrics were collected")
|
|
71
|
+
total_active_users: int = Field(ge=0, description="Number of users with active per-user workflows")
|
|
72
|
+
users: list[PerUserResourceUsage] = Field(default_factory=list, description="Per-user resource usage details")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class PerUserMetricsCollector:
|
|
76
|
+
"""Collector for per-user workflow metrics.
|
|
77
|
+
|
|
78
|
+
This class aggregates metrics from SessionManager's per-user builders
|
|
79
|
+
and provides methods to collect metrics for individual users or all users.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
def __init__(self, session_manager: SessionManager):
|
|
83
|
+
"""Initialize the collector with a SessionManager reference.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
session_manager: The SessionManager instance to collect metrics from
|
|
87
|
+
"""
|
|
88
|
+
self._session_manager = session_manager
|
|
89
|
+
|
|
90
|
+
async def collect_user_metrics(self, user_id: str) -> PerUserResourceUsage | None:
|
|
91
|
+
"""Collect metrics for a specific user.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
user_id: The user identifier to collect metrics for
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
PerUserResourceUsage if user exists, None otherwise
|
|
98
|
+
"""
|
|
99
|
+
async with self._session_manager._per_user_builders_lock:
|
|
100
|
+
if user_id not in self._session_manager._per_user_builders:
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
builder_info = self._session_manager._per_user_builders[user_id]
|
|
104
|
+
return self._build_user_metrics(user_id, builder_info)
|
|
105
|
+
|
|
106
|
+
async def collect_all_metrics(self) -> PerUserMonitorResponse:
|
|
107
|
+
"""Collect metrics for all active per-user workflows.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
PerUserMonitorResponse with all user metrics
|
|
111
|
+
"""
|
|
112
|
+
users: list[PerUserResourceUsage] = []
|
|
113
|
+
|
|
114
|
+
async with self._session_manager._per_user_builders_lock:
|
|
115
|
+
for user_id, builder_info in self._session_manager._per_user_builders.items():
|
|
116
|
+
try:
|
|
117
|
+
user_metrics = self._build_user_metrics(user_id, builder_info)
|
|
118
|
+
users.append(user_metrics)
|
|
119
|
+
except Exception:
|
|
120
|
+
logger.exception("Failed to collect metrics for user %s", user_id)
|
|
121
|
+
|
|
122
|
+
return PerUserMonitorResponse(
|
|
123
|
+
timestamp=datetime.now(),
|
|
124
|
+
total_active_users=len(users),
|
|
125
|
+
users=users,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def _build_user_metrics(self, user_id: str, builder_info) -> PerUserResourceUsage:
|
|
129
|
+
"""Build metrics for a single user from builder info.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
user_id: The user identifier
|
|
133
|
+
builder_info: The PerUserBuilderInfo instance
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
PerUserResourceUsage with all metrics
|
|
137
|
+
"""
|
|
138
|
+
# Session metrics
|
|
139
|
+
session_metrics = PerUserSessionMetrics(
|
|
140
|
+
created_at=builder_info.created_at,
|
|
141
|
+
last_activity=builder_info.last_activity,
|
|
142
|
+
ref_count=builder_info.ref_count,
|
|
143
|
+
is_active=builder_info.ref_count > 0,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# Request metrics
|
|
147
|
+
avg_latency = (builder_info.total_latency_ms /
|
|
148
|
+
builder_info.total_requests if builder_info.total_requests > 0 else 0.0)
|
|
149
|
+
|
|
150
|
+
request_metrics = PerUserRequestMetrics(
|
|
151
|
+
total_requests=builder_info.total_requests,
|
|
152
|
+
active_requests=builder_info.ref_count,
|
|
153
|
+
avg_latency_ms=round(avg_latency, 2),
|
|
154
|
+
error_count=builder_info.error_count,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# Memory/resource count metrics from the builder
|
|
158
|
+
builder = builder_info.builder
|
|
159
|
+
per_user_functions_count = len(builder._per_user_functions)
|
|
160
|
+
per_user_function_groups_count = len(builder._per_user_function_groups)
|
|
161
|
+
|
|
162
|
+
# Count resources in exit stack (if accessible)
|
|
163
|
+
exit_stack = getattr(builder, '_exit_stack', None)
|
|
164
|
+
if exit_stack and hasattr(exit_stack, '_exit_callbacks'):
|
|
165
|
+
exit_stack_size = len(exit_stack._exit_callbacks)
|
|
166
|
+
else:
|
|
167
|
+
exit_stack_size = 0
|
|
168
|
+
|
|
169
|
+
memory_metrics = PerUserMemoryMetrics(
|
|
170
|
+
per_user_functions_count=per_user_functions_count,
|
|
171
|
+
per_user_function_groups_count=per_user_function_groups_count,
|
|
172
|
+
exit_stack_size=exit_stack_size,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
return PerUserResourceUsage(
|
|
176
|
+
user_id=user_id,
|
|
177
|
+
session=session_metrics,
|
|
178
|
+
requests=request_metrics,
|
|
179
|
+
memory=memory_metrics,
|
|
180
|
+
)
|
nat/runtime/runner.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2024-
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
2
|
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -26,16 +26,13 @@ from nat.data_models.intermediate_step import IntermediateStepType
|
|
|
26
26
|
from nat.data_models.intermediate_step import StreamEventData
|
|
27
27
|
from nat.data_models.intermediate_step import TraceMetadata
|
|
28
28
|
from nat.data_models.invocation_node import InvocationNode
|
|
29
|
+
from nat.data_models.runtime_enum import RuntimeTypeEnum
|
|
29
30
|
from nat.observability.exporter_manager import ExporterManager
|
|
30
31
|
from nat.utils.reactive.subject import Subject
|
|
31
32
|
|
|
32
33
|
logger = logging.getLogger(__name__)
|
|
33
34
|
|
|
34
35
|
|
|
35
|
-
class UserManagerBase:
|
|
36
|
-
pass
|
|
37
|
-
|
|
38
|
-
|
|
39
36
|
class RunnerState(Enum):
|
|
40
37
|
UNINITIALIZED = 0
|
|
41
38
|
INITIALIZED = 1
|
|
@@ -53,7 +50,8 @@ class Runner:
|
|
|
53
50
|
input_message: typing.Any,
|
|
54
51
|
entry_fn: Function,
|
|
55
52
|
context_state: ContextState,
|
|
56
|
-
exporter_manager: ExporterManager
|
|
53
|
+
exporter_manager: ExporterManager,
|
|
54
|
+
runtime_type: RuntimeTypeEnum = RuntimeTypeEnum.RUN_OR_SERVE):
|
|
57
55
|
"""
|
|
58
56
|
The Runner class is used to run a workflow. It handles converting input and output data types and running the
|
|
59
57
|
workflow with the specified concurrency.
|
|
@@ -68,6 +66,8 @@ class Runner:
|
|
|
68
66
|
The context state to use
|
|
69
67
|
exporter_manager : ExporterManager
|
|
70
68
|
The exporter manager to use
|
|
69
|
+
runtime_type : RuntimeTypeEnum
|
|
70
|
+
The runtime type (RUN_OR_SERVE, EVALUATE, OTHER)
|
|
71
71
|
"""
|
|
72
72
|
|
|
73
73
|
if (entry_fn is None):
|
|
@@ -86,6 +86,9 @@ class Runner:
|
|
|
86
86
|
|
|
87
87
|
self._exporter_manager = exporter_manager
|
|
88
88
|
|
|
89
|
+
self._runtime_type = runtime_type
|
|
90
|
+
self._runtime_type_token = None
|
|
91
|
+
|
|
89
92
|
@property
|
|
90
93
|
def context(self) -> Context:
|
|
91
94
|
return self._context
|
|
@@ -105,6 +108,8 @@ class Runner:
|
|
|
105
108
|
function_id="root",
|
|
106
109
|
))
|
|
107
110
|
|
|
111
|
+
self._runtime_type_token = self._context_state.runtime_type.set(self._runtime_type)
|
|
112
|
+
|
|
108
113
|
if (self._state == RunnerState.UNINITIALIZED):
|
|
109
114
|
self._state = RunnerState.INITIALIZED
|
|
110
115
|
else:
|
|
@@ -119,6 +124,8 @@ class Runner:
|
|
|
119
124
|
|
|
120
125
|
self._context_state.input_message.reset(self._input_message_token)
|
|
121
126
|
|
|
127
|
+
self._context_state.runtime_type.reset(self._runtime_type_token)
|
|
128
|
+
|
|
122
129
|
if (self._state not in (RunnerState.COMPLETED, RunnerState.FAILED)):
|
|
123
130
|
raise ValueError("Cannot exit the context without completing the workflow")
|
|
124
131
|
|